diff --git a/Makefile b/Makefile index 86d0922..531a88f 100644 --- a/Makefile +++ b/Makefile @@ -8,14 +8,28 @@ all : sample0.xex \ # reminder: $< is input # $@ is output -%.s : %.jpg dither-image.js +%.s : %.jpg dither-image.js gif.sh mp4.sh node dither-image.js $< $@ +chickens.s : chickens.wav pack-wav.js + node pack-wav.js $< $@ + +dubstep.wav.s : dubstep.wav pack-wav.js + node pack-wav.js $< $@ + +dubstep.wav : Dubstep_Loop_by_WinnieTheMoog.ogg + ffmpeg -i "Dubstep_Loop_by_WinnieTheMoog.ogg" \ + -t 2.0 \ + -acodec pcm_u8 \ + -ac 1 \ + -ar 15704 \ + -y $@ + %.o : %.s ca65 -v -t atari -o $@ $< -%.xex : %.o dither4.o atari-asm-xex.cfg - ld65 -v -C ./atari-asm-xex.cfg -o $@ dither4.o $< +%.xex : %.o dither4.o dubstep.wav.o atari-asm-xex.cfg + ld65 -v -C ./atari-asm-xex.cfg -o $@ dither4.o dubstep.wav.o $< clean : rm -f *.o @@ -24,3 +38,9 @@ clean : rm -f fruit.s mapclock.s sailboat.s sunset.s train404.s rm -f potato.s selfie.s kitty.s meme.s rm -f *.xex + rm -f chickens.s + rm -f chickens.o + rm -f dubstep.wav + rm -f dubstep.wav.[so] + +.dummy: sample0.s sample1.s sample2.s sample3.s sample4.s sample5.s sample6.s chickens.s diff --git a/dither4.s b/dither4.s index fd4c0ec..bbdb96c 100644 --- a/dither4.s +++ b/dither4.s @@ -26,6 +26,7 @@ sample_ptrl = $84 sample_ptrh = $85 sample_ptr = sample_ptrl scanline = $86 +audiotemp = $87 frame_counter = $89 ;height = 160 @@ -39,6 +40,9 @@ scanline_max = (lines_per_frame - scanline_offset) / 2 .data +.import audio_samples +.import audio_samples_end + .import frame1_top .import frame1_bottom .import frame1_palette1_even @@ -49,11 +53,41 @@ scanline_max = (lines_per_frame - scanline_offset) / 2 .import frame1_palette3_odd .import displaylist +audio_high_byte: + .scope + .macro byteseq val + .repeat 16 + .byte val | $10 + .endrep + .endmacro + byteseq $0 + byteseq $1 + byteseq $2 + byteseq $3 + byteseq $4 + byteseq $5 + byteseq $7 + byteseq $8 + byteseq $9 + byteseq $a + byteseq $b + byteseq $c + byteseq $d + byteseq $e + byteseq $f + .endscope + .code .export start .proc start + ; Set up the audio sample buffer + lda #.lobyte(audio_samples) + sta sample_ptrl + lda #.hibyte(audio_samples) + sta sample_ptrh + ; Disable display DMA lda #$00 sta DMACTL @@ -95,6 +129,12 @@ wait_loop: ldy VCOUNT ; 4 cycles bne wait_loop ; 2 cycles + .macro audio_prep + ; Y is VCOUNT at entry + lda (sample_ptr),y ; 5/6 cyc + sta audiotemp ; 3 cyc + .endmacro + .macro inner_scanline frame_offset, line_offset ; Y should be VCOUNT at entry ; it'll fire on unused lines, but harmlessly @@ -119,6 +159,51 @@ wait_loop: sty COLPF2 ; 4 .endmacro + .macro audio_play_raw + ;ldy VCOUNT ; set on entry + lda (sample_ptr),y ; 5/6 cyc + sta AUDC1 ; 4 cyc + .endmacro + + .macro audio_play_lo + lda audiotemp ; 3 cyc + and #$0f ; 2 cyc + ora #$10 ; 2 cyc + sta AUDC1 ; 4 cyc + .endmacro + + .macro audio_play_hi ; 12 cycles + ldy audiotemp ; 3 cyc + lda audio_high_byte,y ; 5 cyc + sta AUDC1 ; 4 cyc + .endmacro + + .macro audio_inc + ; 22 cycles + lda sample_ptrl ; 3 cyc + clc ; 2 cyc + adc #131 ; 2 cyc + sta sample_ptrl ; 3 cyc + lda sample_ptrh ; 3 cyc + adc #0 ; 2 cyc + sta sample_ptrh ; 3 cyc + cmp #.hibyte(audio_samples_end) ; 2 cyc + bmi audio_cont ; 2 cyc + + sta WSYNC + + ; 10 cycles, optional + lda #.lobyte(audio_samples) ; 2 + sta sample_ptrl ; 3 + lda #.hibyte(audio_samples) ; 2 + sta sample_ptrh ; 3 + + sta WSYNC + ldy VCOUNT ; 4 cycles + + audio_cont: + .endmacro + .macro run_frame frame_offset .scope ; each scanline is 228 color clocks @@ -130,12 +215,16 @@ wait_loop: inner_scanline frame_offset, 0 ; 23-26 cycles before break, 12 cycles after ldy scanline ; 3 cycles + audio_play_raw ; 8-10 cycles + inner_scanline frame_offset, 128 ; 23-26 cycles before break, 12 cycles after ; pair cleanup: 6 cycles ldy VCOUNT ; 4 cycles bne each_scanline_pair ; 2 cycles + audio_inc ; 22-32 cycles + ; frame cleanup: 11 cycles lda frame_counter ; 3 cycles eor #1 ; 2 cycles