From 489fdb2ac9ef6ea7a5af4ce172377d359451eba3 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Mon, 10 Jan 2022 00:47:32 -0500 Subject: [PATCH] d2_tiny: more optimization --- demos/l/d2/Makefile | 3 +- demos/l/d2/d2.s | 17 ++-- demos/l/d2/interrupt_handler.s | 11 ++- demos/l/d2/mockingboard_init.s | 138 ++++++++++++++++++++++++++ demos/l/d2/mockingboard_setup.s | 170 +++----------------------------- demos/l/d2/text_to_tiny.c | 10 +- demos/l/d2/tracker_init.s | 30 ++++++ demos/l/d2/zp.inc | 10 +- 8 files changed, 209 insertions(+), 180 deletions(-) create mode 100644 demos/l/d2/mockingboard_init.s create mode 100644 demos/l/d2/tracker_init.s diff --git a/demos/l/d2/Makefile b/demos/l/d2/Makefile index d1d265a6..764ce054 100644 --- a/demos/l/d2/Makefile +++ b/demos/l/d2/Makefile @@ -52,7 +52,8 @@ D2: d2.o d2.o: d2.s \ zp.inc hardware.inc \ mA2E_2.s \ - interrupt_handler.s mockingboard_setup.s + interrupt_handler.s mockingboard_setup.s mockingboard_init.s \ + tracker_init.s ca65 -o d2.o d2.s -l d2.lst #### diff --git a/demos/l/d2/d2.s b/demos/l/d2/d2.s index bc5b77c7..4a17e8cc 100644 --- a/demos/l/d2/d2.s +++ b/demos/l/d2/d2.s @@ -9,13 +9,15 @@ ; 466 bytes -- original from D2 demo ; 436 bytes -- left channel only ; 427 bytes -- optimize init a bit +; 426 bytes -- terminate init with $FF rather than extra $00 +; 424 bytes -- move inits to zero together +; 414 bytes -- update ay output to write all registers d2: ;=================== ; music Player Setup - lda #peasant_song @@ -23,9 +25,13 @@ d2: ; assume mockingboard in slot#4 - ; TODO: inline? + ; inline mockingboard_init - jsr mockingboard_init +.include "mockingboard_init.s" + +.include "tracker_init.s" + + ; start the music playing cli @@ -41,14 +47,13 @@ bob: its_over: sei lda #$3f - ldx #7 - jsr ay3_write_reg + sta AY_REGS+7 + jsr ay3_write_regs stuck_forever: bne stuck_forever - ; music .include "mA2E_2.s" .include "interrupt_handler.s" diff --git a/demos/l/d2/interrupt_handler.s b/demos/l/d2/interrupt_handler.s index 8158f9c5..0c1e17b7 100644 --- a/demos/l/d2/interrupt_handler.s +++ b/demos/l/d2/interrupt_handler.s @@ -19,7 +19,7 @@ interrupt_handler: php ; save status flags - cld ; clear decimal mode + cld ; clear decimal mode FIXME pha ; save A ; 3 ; A is saved in $45 by firmware txa @@ -90,10 +90,11 @@ note_only: tax lda frequency_lookup_low,X - sty y_smc+1 + sty y_smc+1 ; backup Y out_smc: ldx #$00 - jsr ay3_write_reg ; trashes A/Y + sta AY_REGS,X +; jsr ay3_write_regs ; trashes A/Y ; set coarse note A ; hack: if octave=0 (C2) then coarse=1 @@ -111,8 +112,8 @@ blah1: blah0: lda #0 blah_blah: - - jsr ay3_write_reg ; trashes A/Y + sta AY_REGS,X + jsr ay3_write_regs ; trashes A/X/Y y_smc: ldy #0 diff --git a/demos/l/d2/mockingboard_init.s b/demos/l/d2/mockingboard_init.s new file mode 100644 index 00000000..2d1acc64 --- /dev/null +++ b/demos/l/d2/mockingboard_init.s @@ -0,0 +1,138 @@ +; Mockingboad programming: +; + Has two 6522 I/O chips connected to two AY-3-8910 chips +; + Optionally has some speech chips controlled via the outport on the AY +; + Often in slot 4 +; TODO: how to auto-detect? +; References used: +; http://macgui.com/usenet/?group=2&id=8366 +; 6522 Data Sheet +; AY-3-8910 Data Sheet + +;======================== +; Mockingboard card +; Essentially two 6522s hooked to the Apple II bus +; Connected to AY-3-8910 chips +; PA0-PA7 on 6522 connected to DA0-DA7 on AY +; PB0 on 6522 connected to BC1 +; PB1 on 6522 connected to BDIR +; PB2 on 6522 connected to RESET + + +; left speaker +MOCK_6522_ORB1 = $C400 ; 6522 #1 port b data +MOCK_6522_ORA1 = $C401 ; 6522 #1 port a data +MOCK_6522_DDRB1 = $C402 ; 6522 #1 data direction port B +MOCK_6522_DDRA1 = $C403 ; 6522 #1 data direction port A +MOCK_6522_T1CL = $C404 ; 6522 #1 t1 low order latches +MOCK_6522_T1CH = $C405 ; 6522 #1 t1 high order counter +MOCK_6522_T1LL = $C406 ; 6522 #1 t1 low order latches +MOCK_6522_T1LH = $C407 ; 6522 #1 t1 high order latches +MOCK_6522_T2CL = $C408 ; 6522 #1 t2 low order latches +MOCK_6522_T2CH = $C409 ; 6522 #1 t2 high order counters +MOCK_6522_SR = $C40A ; 6522 #1 shift register +MOCK_6522_ACR = $C40B ; 6522 #1 auxilliary control register +MOCK_6522_PCR = $C40C ; 6522 #1 peripheral control register +MOCK_6522_IFR = $C40D ; 6522 #1 interrupt flag register +MOCK_6522_IER = $C40E ; 6522 #1 interrupt enable register +MOCK_6522_ORANH = $C40F ; 6522 #1 port a data no handshake + + +; right speaker +MOCK_6522_ORB2 = $C480 ; 6522 #2 port b data +MOCK_6522_ORA2 = $C481 ; 6522 #2 port a data +MOCK_6522_DDRB2 = $C482 ; 6522 #2 data direction port B +MOCK_6522_DDRA2 = $C483 ; 6522 #2 data direction port A + +; AY-3-8910 commands on port B +; RESET BDIR BC1 +MOCK_AY_RESET = $0 ; 0 0 0 +MOCK_AY_INACTIVE = $4 ; 1 0 0 +MOCK_AY_READ = $5 ; 1 0 1 +MOCK_AY_WRITE = $6 ; 1 1 0 +MOCK_AY_LATCH_ADDR = $7 ; 1 1 1 + + + ;======================== + ;======================== + ; Mockingboard Init + ;======================== + ;======================== + ; Left channel only + +mockingboard_init: + + sei ; disable interrupts, is this necessary? + + ;========================= + ; Setup Interrupt Handler + ;========================= + + ; NOTE: we don't support IIc as it's a hack + ; traditionally Mockingboard on IIc was rare + + ;======================== + ; set up interrupt + ; Vector address goes to 0x3fe/0x3ff + + lda #interrupt_handler + sta $03ff + + + + ;========================= + ; Initialize the 6522s + ; Reset Left AY-3-8910 + ;=========================== + + ; entries=10 + ; 14 + 2*entries = 34 bytes + ; to beat = 46 bytes + + ldy #0 +init_it_loop: + lda init_values,Y ; 3 + ldx init_addresses,Y ; 3 + bmi doneit ; 2 + iny ; 1 + sta $c400,X ; 3 + bne init_it_loop ; 2 +doneit: + + +init_registers_to_zero: + ldx #13 + lda #0 + sta SONG_OFFSET ; also init song stuff + sta SONG_COUNTDOWN +init_loop: + sta AY_REGS,X + dex + bne init_loop + + jsr ay3_write_regs + + +.if 0 + ; 24 bytes + 13 bytes = 37 bytes +init_loop: + txa + tay + lda (SONG_L),Y + jsr ay3_write_reg ; trashes Y + dex + bne init_loop + + ; update SONG_L to point past the init + lda SONG_L + clc + adc #14 + sta SONG_L + bcc no_oflo + inc SONG_H +no_oflo: + +.endif + + diff --git a/demos/l/d2/mockingboard_setup.s b/demos/l/d2/mockingboard_setup.s index 43a87998..e6f4e15b 100644 --- a/demos/l/d2/mockingboard_setup.s +++ b/demos/l/d2/mockingboard_setup.s @@ -1,170 +1,20 @@ -; Mockingboad programming: -; + Has two 6522 I/O chips connected to two AY-3-8910 chips -; + Optionally has some speech chips controlled via the outport on the AY -; + Often in slot 4 -; TODO: how to auto-detect? -; References used: -; http://macgui.com/usenet/?group=2&id=8366 -; 6522 Data Sheet -; AY-3-8910 Data Sheet - -;======================== -; Mockingboard card -; Essentially two 6522s hooked to the Apple II bus -; Connected to AY-3-8910 chips -; PA0-PA7 on 6522 connected to DA0-DA7 on AY -; PB0 on 6522 connected to BC1 -; PB1 on 6522 connected to BDIR -; PB2 on 6522 connected to RESET - - -; left speaker -MOCK_6522_ORB1 = $C400 ; 6522 #1 port b data -MOCK_6522_ORA1 = $C401 ; 6522 #1 port a data -MOCK_6522_DDRB1 = $C402 ; 6522 #1 data direction port B -MOCK_6522_DDRA1 = $C403 ; 6522 #1 data direction port A -MOCK_6522_T1CL = $C404 ; 6522 #1 t1 low order latches -MOCK_6522_T1CH = $C405 ; 6522 #1 t1 high order counter -MOCK_6522_T1LL = $C406 ; 6522 #1 t1 low order latches -MOCK_6522_T1LH = $C407 ; 6522 #1 t1 high order latches -MOCK_6522_T2CL = $C408 ; 6522 #1 t2 low order latches -MOCK_6522_T2CH = $C409 ; 6522 #1 t2 high order counters -MOCK_6522_SR = $C40A ; 6522 #1 shift register -MOCK_6522_ACR = $C40B ; 6522 #1 auxilliary control register -MOCK_6522_PCR = $C40C ; 6522 #1 peripheral control register -MOCK_6522_IFR = $C40D ; 6522 #1 interrupt flag register -MOCK_6522_IER = $C40E ; 6522 #1 interrupt enable register -MOCK_6522_ORANH = $C40F ; 6522 #1 port a data no handshake - - -; right speaker -MOCK_6522_ORB2 = $C480 ; 6522 #2 port b data -MOCK_6522_ORA2 = $C481 ; 6522 #2 port a data -MOCK_6522_DDRB2 = $C482 ; 6522 #2 data direction port B -MOCK_6522_DDRA2 = $C483 ; 6522 #2 data direction port A - -; AY-3-8910 commands on port B -; RESET BDIR BC1 -MOCK_AY_RESET = $0 ; 0 0 0 -MOCK_AY_INACTIVE = $4 ; 1 0 0 -MOCK_AY_READ = $5 ; 1 0 1 -MOCK_AY_WRITE = $6 ; 1 1 0 -MOCK_AY_LATCH_ADDR = $7 ; 1 1 1 - - - ;======================== - ;======================== - ; Mockingboard Init - ;======================== - ;======================== - ; Left channel only - -mockingboard_init: - - sei ; disable interrupts, is this necessary? - - ;========================= - ; Setup Interrupt Handler - ;========================= - - ; NOTE: we don't support IIc as it's a hack - ; traditionally Mockingboard on IIc was rare - - ;======================== - ; set up interrupt - ; Vector address goes to 0x3fe/0x3ff - - lda #interrupt_handler - sta $03ff - - - - ;========================= - ; Initialize the 6522s - ; Reset Left AY-3-8910 - ;=========================== - - ; entries=10 - ; 14 + 2*entries = 34 bytes - ; to beat = 46 bytes - - ldy #0 -init_it_loop: - lda init_values,Y ; 3 - ldx init_addresses,Y ; 3 - bmi doneit ; 2 - iny ; 1 - sta $c400,X ; 3 - bne init_it_loop ; 2 -doneit: - - - -init_registers: - - ; init song data - - lda #0 - sta SONG_OFFSET - sta SONG_COUNTDOWN - - ; read 14 bytes from beginning of song to init - - ldx #13 -init_loop: -init_smc: - txa - tay - lda (SONG_L),Y - jsr ay3_write_reg ; trashes Y - dex - bne init_loop - - ; update SONG_L to point past the init - lda SONG_L - clc - adc #14 - sta SONG_L - bcc no_oflo - inc SONG_H -no_oflo: - - ; create Frequency Table - ldx #11 -make_freq_loop: - sec - lda frequency_lookup_low,X - ror - sta frequency_lookup_low+16,X - lsr - sta frequency_lookup_low+32,X - lsr - sta frequency_lookup_low+48,X - - dex - bpl make_freq_loop - - inx - stx frequency_lookup_low+28 - - rts - ;===================== ;===================== ;===================== - ; ay3 write reg + ; ay3 write regs ;===================== ;===================== ;===================== - ; writes to one chip + ; write all 13 registers ; address in X ; data in A -ay3_write_reg: - pha +ay3_write_regs: + + ldx #13 +ay3_write_reg_loop: + lda #MOCK_AY_LATCH_ADDR ; latch_address for PB1 ; 2 ldy #MOCK_AY_INACTIVE ; go inactive ; 2 @@ -172,14 +22,16 @@ ay3_write_reg: sta MOCK_6522_ORB1 ; latch_address on PB1 ; 4 sty MOCK_6522_ORB1 ; 4 - pla - ; value + lda $70,X sta MOCK_6522_ORA1 ; put value on PA1 ; 4 lda #MOCK_AY_WRITE ; ; 2 sta MOCK_6522_ORB1 ; write on PB1 ; 4 sty MOCK_6522_ORB1 ; 4 + dex + bpl ay3_write_reg_loop + rts diff --git a/demos/l/d2/text_to_tiny.c b/demos/l/d2/text_to_tiny.c index 516b6677..17458978 100644 --- a/demos/l/d2/text_to_tiny.c +++ b/demos/l/d2/text_to_tiny.c @@ -292,11 +292,11 @@ int main(int argc, char **argv) { printf("peasant_song:\n"); printf("; register init\n"); -printf("\t.byte $00,$00,$00,$00,$00,$00 ; $00: A/B/C fine/coarse\n"); -printf("\t.byte $00 ; $06\n"); -printf("\t.byte $38 ; $07 mixer (ABC on)\n"); -printf("\t.byte $0E,$0C,$0C ; $08 volume A/B/C\n"); -printf("\t.byte $00,$00,$00,$00 ; $09\n"); +//printf("\t.byte $00,$00,$00,$00,$00,$00 ; $00: A/B/C fine/coarse\n"); +//printf("\t.byte $00 ; $06\n"); +//printf("\t.byte $38 ; $07 mixer (ABC on)\n"); +//printf("\t.byte $0E,$0C,$0C ; $08 volume A/B/C\n"); +//printf("\t.byte $00,$00,$00,$00 ; $09\n"); printf("\n"); while(1) { diff --git a/demos/l/d2/tracker_init.s b/demos/l/d2/tracker_init.s new file mode 100644 index 00000000..1b727c58 --- /dev/null +++ b/demos/l/d2/tracker_init.s @@ -0,0 +1,30 @@ + +tracker_init: + + ; create Frequency Table + ldx #11 +make_freq_loop: + sec + lda frequency_lookup_low,X + ror + sta frequency_lookup_low+16,X + lsr + sta frequency_lookup_low+32,X + lsr + sta frequency_lookup_low+48,X + + dex + bpl make_freq_loop + + inx + stx frequency_lookup_low+28 + + ; setup initial ay-3-8910 values (this depends on song) + + lda #$38 + sta AY_REGS+7 ; $07 mixer (ABC on) + lda #$0E + sta AY_REGS+8 ; $08 volume A + lda #$0C + sta AY_REGS+9 ; $09 volume B + sta AY_REGS+10 ; $0A volume C diff --git a/demos/l/d2/zp.inc b/demos/l/d2/zp.inc index 57a4ad60..e7e741da 100644 --- a/demos/l/d2/zp.inc +++ b/demos/l/d2/zp.inc @@ -9,10 +9,12 @@ GBASH = $27 BASL = $28 BASH = $29 -SONG_L = $70 -SONG_H = $71 -SONG_OFFSET = $72 -SONG_COUNTDOWN = $73 +AY_REGS = $70 + +SONG_L = $80 +SONG_H = $81 +SONG_OFFSET = $82 +SONG_COUNTDOWN = $83 OUR_ROT = $A5