diff options
author | Juan J. Martinez <jjm@usebox.net> | 2023-05-15 12:31:46 +0100 |
---|---|---|
committer | Juan J. Martinez <jjm@usebox.net> | 2023-05-18 12:19:16 +0100 |
commit | 06f50ed77949cee495a1d8d98fec16648a5c8ea9 (patch) | |
tree | 6a138f6692c32f66cc98b9331dbc7d57e5b35543 /example.asm | |
parent | ccf1ea4a34a789da326a321589c2757e5b1d749c (diff) | |
download | tr8vm-sound-opl3.tar.gz tr8vm-sound-opl3.zip |
Added OPL3 supportsound-opl3
Diffstat (limited to 'example.asm')
-rw-r--r-- | example.asm | 262 |
1 files changed, 251 insertions, 11 deletions
diff --git a/example.asm b/example.asm index 992823f..468db3a 100644 --- a/example.asm +++ b/example.asm @@ -7,7 +7,8 @@ .equ INT_VECT 0xff00 ; setup an int handler so we - ; can use the frame int to sync + ; can use the frame interrupt to sync + ; and play sounds in background ld a, >INT_VECT ld x, <INT_VECT ld b, <int_handler @@ -81,8 +82,10 @@ update_done: pop b jmp loop - ; make the sprite change direction - ; in: [a : x] inc* +; +; Make the sprite change direction and queue a sound +; +; in: [a : x] inc* turn: ; 1 -> -1 ; -1 -> 1 @@ -96,11 +99,23 @@ turn: inc b and b, 15 ld [sp + 2], b - ret + ; play an effect when we turn + ; alternating two sounds + + ld x, <effect + ld a, >effect + ld y, [a : x] + xor y, 3 + ld [a : x], y + + call sound_queue_effect + ret - ; fill frame-buffer - ; in: reg b color +; +; fill frame-buffer +; +; in: reg b color fill_screen: ld a, 0xbf ld x, 0 @@ -116,11 +131,10 @@ fill_loop: jmp fill_loop ret -int_handler: - iret - - ; draw sprite - ; in: coordinates in px, py +; +; Draw the sprite +; +; in: coordinates in px, py draw_sprite: ; blitter in settings mode ld x, 128 @@ -167,3 +181,229 @@ incy: py: .db 64 +effect: + .db 1 + +; +; Our int handler plays / stops sounds +; +int_handler: + push a + push b + push x + push y + call sound_play + pop y + pop x + pop b + pop a + iret + +; +; Queue a sound effect to be played +; +; in: y sound index (1 based) +sound_queue_effect: + ; can't be interrupted + sif + + ld a, >sound_efx + ld x, <sound_efx + dec y + ld b, y + add y, y + add y, b + add x, y + bo + inc a + + ; effect addr + ld b, >sound_queue + ld y, <sound_queue + push x + ld x, [a : x] + ld [b : y], x + pop x + inc x + bo + inc a + inc y + bo + inc b + push x + ld x, [a : x] + ld [b : y], x + pop x + + inc x + bo + inc a + ; x has length + ld x, [a : x] + + ; current is 0 + inc y + bo + inc b + ld a, 0 + ld [b : y], a + + ; length + inc y + bo + inc b + ld [b : y], x + + cif + ret + +; +; Plays sound in our queue +; +; To be run from the interrupt handler. Can't play effects which data is at 0x0000. +; It is very simple and uses only channel 0. +; +sound_play: + ld b, >sound_queue + ld y, <sound_queue + + ; check we have a valid addr in the queue (not 0x0000) + ld x, [b : y] + inc y + bo + inc b + ld a, [b : y] + cmp a, 0 + bnz + jmp sound_play_has_addr + cmp x, 0 + bz + ret + +sound_play_has_addr: + push a + + inc y + bo + inc b + + ; is already playing? + ld a, [b : y] + cmp a, 0 + bz + jmp sound_play_start + + ; the sound is active + pop a + ld a, [b : y] + + ; another frame + inc a + ld [b : y], a + + inc y + bo + inc b + + ; is the end? + ld x, [b : y] + cmp x, a + bnc + ret + + ; no active sound now: set addr to 0x0000 + ld b, >sound_queue + ld y, <sound_queue + ld x, 0 + ld [b : y], x + inc y + bo + inc b + ld [b : y], x + + ; stop the sound + ld b, 0xc0 + ld y, 0xb0 + port b, y + + ld b, 0xc1 + ld y, 0x11 + port b, y + ret + +sound_play_start: + ; we start playing + inc a + ld [b : y], a + + pop a + ; a : x has the effect addr + +sound_loop: + ld y, [a : x] + cmp y, 0xff + bz + ret + + ld b, 0xc0 + port b, y + + inc x + bo + inc a + + ld y, [a : x] + + ld b, 0xc1 + port b, y + + inc x + bo + inc a + + jmp sound_loop + +sound_queue: + ; effect addr, current frame count, length + .ds 4, 0 + +sound_efx: + ; addr to the instrument data + .dw sound_efx_data0 + ; length in frames + .db 2 + .dw sound_efx_data1 + .db 2 + +sound_efx_data0: + ; register, value + .db 0x20, 0x01 + .db 0x40, 0x10 + .db 0x60, 0xF0 + .db 0x80, 0x77 + .db 0xA0, 0x81 + .db 0x23, 0x01 + .db 0x43, 0x00 + .db 0x63, 0xF0 + .db 0x83, 0x77 + .db 0xe0, 0x03 + .db 0xB0, 0x31 + ; end of sequence marker + .db 0xff + +sound_efx_data1: + ; register, value + .db 0x20, 0x01 + .db 0x40, 0x10 + .db 0x60, 0xF0 + .db 0x80, 0x77 + .db 0xA0, 0xb0 + .db 0x23, 0x01 + .db 0x43, 0x00 + .db 0x63, 0xF0 + .db 0x83, 0x77 + .db 0xe0, 0x03 + .db 0xB0, 0x31 + ; end of sequence marker + .db 0xff + |