ds: play cycle-accurate sound

1200 cycles is a bit much though :(
This commit is contained in:
Vince Weaver 2019-10-14 15:13:44 -04:00
parent 59ffdab85e
commit bb605fe988
5 changed files with 270 additions and 9 deletions

View File

@ -51,6 +51,7 @@ musictest.o: musictest.s \
zp.inc hardware.inc \
appleII_intro.s font.s \
pt3_lib_init.s pt3_lib_core.s pt3_lib_mockingboard.s \
pt3_lib_play_frame.s \
interrupt_handler.s \
dya_space_demo2.pt3
ca65 -o musictest.o musictest.s -l musictest.lst

View File

@ -159,8 +159,9 @@ page1_loop: ; delay 115+(7 loop)+4 (bit)+4(extra)
; -1174
; -7 (keypress)
; -3 (jump)
; -1182 (play_music)
; =====
; 3365
; 2183
jsr do_nothing ; 6
@ -412,6 +413,9 @@ intro_wipe_done:
jmp appleii_done
no_keypress2:
jsr play_frame_compressed ; 6+1176
jmp display_loop ; 3
appleii_done:
@ -422,16 +426,13 @@ appleii_done:
;=================================
; do nothing
;=================================
; and take 3365-12 = 3353 cycles to do it
; and take 2183-12 = 2171 cycles to do it
do_nothing:
; Try X=6 Y=93 cycles=3349R4
; Try X=5 Y=70 cycles=2171
nop
nop
ldy #93 ; 2
loop1: ldx #6 ; 2
ldy #70 ; 2
loop1: ldx #5 ; 2
loop2: dex ; 2
bne loop2 ; 2nt/3
dey ; 2

View File

@ -18,6 +18,13 @@ demosplash2019:
jsr clear_ay_both
jsr pt3_init_song
;====================================
; generate 4 patterns worth of music
; at address $9000
; lda #1
; sta LOOP
@ -134,7 +141,7 @@ wait_until_keypressed:
.include "pt3_lib_init.s"
.include "pt3_lib_mockingboard.s"
.include "interrupt_handler.s"
.include "pt3_lib_play_frame.s"
PT3_LOC = song

View File

@ -0,0 +1,251 @@
; ZZ points to offset from pointer
;0 $9000,$9100,$9200 = A Low (reg0)
;1 $9300,$9400,$9500 = A high (reg1) B high (reg3)
;2 $9600,$9700,$9800 = B Low (reg2)
;3 $9900,$9A00,$9B00 = C Low (reg4)
;4 $9C00,$9D00,$9E00 = C high (reg5), Envelope Shape (r13)
;5 $9F00,$A000,$A100 = Noise (r6), bit7 = don't change envelope
;6 $A200,$A300,$A400 = Enable (r7)
;7 $A500,$A600,$A700 = A amp (r8), bit 5 of r8,r9,r10
;8 $A800,$A900,$AA00 = B/C amp (r9/r10)
;9 $AB00,$AC00,$AD00 = ENV low (r11)
;a $AE00,$AF00,$B000 = ENV high (r12)
; 3+ 72 + 72 + 83 + 74 + 72 + 77 + 19 + 70 + 74 + 72 +
; 77 + 14 + 82 + 85 + 72 + 72 + 8 + 72 + 6 = 1176
play_frame_compressed:
ldy FRAME_OFFSET ; 3
; Register 0: A fine
ldx #0 ; 2
r0_smc:
lda $9000,Y ; 4+
jsr play_mb_write ; 6+60
;======
; 72
; Register 2: B fine
ldx #2 ; 2
r2_smc:
lda $9600,Y ; 4+
jsr play_mb_write ; 6+60
;======
; 72
; Register 1: A coarse
ldx #1 ; 2
r1_smc:
lda $9300,Y ; 4+
pha ; 3
lsr ; 2
lsr ; 2
lsr ; 2
lsr ; 2
jsr play_mb_write ; 6+60
;======
; 83
; Register 3: B low
ldx #3 ; 2
pla ; 4
and #$f ; 2
jsr play_mb_write ; 6+60
;======
; 74
; Register 4: C fine
ldx #4 ; 2
r4_smc:
lda $9900,Y ; 4+
jsr play_mb_write ; 6+60
;=======
; 72
; Register 5: C coarse
ldx #5 ; 2
r5_smc:
lda $9C00,Y ; 4+
pha ; 3
and #$f ; 2
jsr play_mb_write ; 6+60
;========
; 77
; Register 13: E type
pla ; 4
lsr ; 2
lsr ; 2
lsr ; 2
lsr ; 2
r13_smc:
ldx $9F00,Y ; check for env update ; 4
bmi skip_envelope_write ; 3
;============
; 19
; -1
ldx #13 ; 2
jsr play_mb_write ; 6+60
jmp done_envelope_write ; 3
;=====
; 70
skip_envelope_write:
; KILL CYCLES... Need to kill 70
; delay 25+a (so 70-2-25=43)
lda #43 ; 2
jsr delay_a ; 25+43
;======
; 70
done_envelope_write:
; Register 6: Noise
ldx #6 ; 2
r6_smc:
lda $9F00,Y ; 4+
and #$1f ; 2
jsr play_mb_write ; 6+60
;=======
; 74
; Register 7: Enable
ldx #7 ; 2
r7_smc:
lda $A200,Y ; 4+
jsr play_mb_write ; 6+60
;========
; 72
; Register 8: a-amp
ldx #8 ; 2
r8_smc:
lda $A500,Y ; 4+
pha ; 3
and #$1f ; 2
jsr play_mb_write ; 6+60
;=======
; 77
pla ; 4
lsr ; 2
sta AY_REGISTERS ; 3
lsr ; 2
sta AY_REGISTERS+1 ; 3
;====
; 14
; Register 9: b-amp
ldx #9 ; 2
r9_smc:
lda $A800,Y ; 4+
pha ; 3
and #$f ; 2
ora AY_REGISTERS ; 3
and #$1f ; 2
jsr play_mb_write ; 6+60
;=======
; 82
; Register 10: c-amp
ldx #10 ; 2
pla ; 4
lsr ; 2
lsr ; 2
lsr ; 2
lsr ; 2
ora AY_REGISTERS+1 ; 3
and #$1f ; 2
jsr play_mb_write ; 6+60
;======
; 85
; Register 11: E fine
ldx #11 ; 2
r11_smc:
lda $AB00,Y ; 4+
jsr play_mb_write ; 6+60
;======
; 72
; Register 12: E coarse
ldx #12 ; 2
r12_smc:
lda $AE00,Y ; 4+
jsr play_mb_write ; 6+60
;======
; 72
; incrememnt offset
; wrap to next
iny ; 2
sty FRAME_OFFSET ; 3
beq frame_wrap ; 3
;==========
; 8
no_frame_wrap:
; -1
; delay 72+1-3=70
lda #43 ; 70-2-25=43
jsr delay_a
jmp done_frame_wrap ; 3
frame_wrap:
inc r0_smc+2 ; 6
inc r1_smc+2 ; 6
inc r2_smc+2 ; 6
inc r4_smc+2 ; 6
inc r5_smc+2 ; 6
inc r13_smc+2 ; 6
inc r6_smc+2 ; 6
inc r7_smc+2 ; 6
inc r8_smc+2 ; 6
inc r9_smc+2 ; 6
inc r11_smc+2 ; 6
inc r12_smc+2 ; 6
;=====
; 72
done_frame_wrap:
rts ; 6
;========================
; 28+26+6= 60
play_mb_write:
; address
stx MOCK_6522_ORA1 ; put address on PA1 ; 4
stx MOCK_6522_ORA2 ; put address on PA2 ; 4
ldy #MOCK_AY_LATCH_ADDR ; latch_address for PB1 ; 2
sty MOCK_6522_ORB1 ; latch_address on PB1 ; 4
sty MOCK_6522_ORB2 ; latch_address on PB2 ; 4
ldy #MOCK_AY_INACTIVE ; go inactive ; 2
sty MOCK_6522_ORB1 ; 4
sty MOCK_6522_ORB2 ; 4
;===========
; 28
; value
sta MOCK_6522_ORA1 ; put value on PA1 ; 4
sta MOCK_6522_ORA2 ; put value on PA2 ; 4
lda #MOCK_AY_WRITE ; ; 2
sta MOCK_6522_ORB1 ; write on PB1 ; 4
sta MOCK_6522_ORB2 ; write on PB2 ; 4
sty MOCK_6522_ORB1 ; 4
sty MOCK_6522_ORB2 ; 4
;===========
; 26
rts ; 6

View File

@ -58,6 +58,7 @@ YADD = $6F
ZERO = $B0
WASTE_CYCLES = $B1
FOREVER_OFFSET = $B2
FRAME_OFFSET = $B3
FRAMEL = $60
FRAMEH = $61