Compare commits

...

3 commits

Author SHA1 Message Date
wbcbz7 347ca2f9a6 fix R7 write 2025-08-14 19:33:16 +07:00
wbcbz7 0f6da89826 AY stream parser bug fixes 2025-08-14 18:55:57 +07:00
wbcbz7 da8baeb549 follow-up, fix assembler errors 2025-08-14 16:49:54 +07:00
2 changed files with 139 additions and 167 deletions

View file

@ -31,82 +31,38 @@ start:
ld i, a ld i, a
im 2 im 2
; prefill register buffer to prevent crashes
ld hl, reg_buffer
ldi [hl], 0x2F : ldi [hl], 0xFF
ldi [hl], 0x2D : ldi [hl], 0xFF
ld [hl], -1
; enable interrupts ; enable interrupts
ei ei
.loop: .loop:
halt halt
ld a, 1 : out (0xfe), a
; output OPN registers ld bc, 0xFFFD
; TODO ld de, 0x00C0
ld hl, test_dump ld a, 0b11111000
out (c), a
ld hl, reg_buffer
call player.reg_out call player.reg_out
di ld a, 2 : out (0xfe), a
halt ld a, 0b11111001
ld b, 0xFF
; draw VU meters out (c), a
.base = 0x4000 + 2048*2 + 32*6 + 19 inc hl
ld bc, .base + 0 ; 10 call player.reg_out
call vumeter.draw_0 ; 17 ld a, 3 : out (0xfe), a
.vu0 equ $-2 ld iy, reg_buffer
ld bc, .base + 2 ; 10 call player.play_tick
call vumeter.draw_0 ; 17 xor a : out (0xfe), a
.vu1 equ $-2
ld bc, .base + 4 ; 10
call vumeter.draw_0 ; 17
.vu2 equ $-2
ld bc, .base + 7 ; 10
call vumeter.draw_0 ; 17
.vu3 equ $-2
ld bc, .base + 9 ; 10
call vumeter.draw_0 ; 17
.vu4 equ $-2
ld bc, .base + 11 ; 10
call vumeter.draw_0 ; 17
.vu5 equ $-2
; and jump to next frame ; and jump to next frame
xor a : ld bc, 0x7FFD : out (c), a ; map fast page to fix 128k AY ports contention xor a : ld bc, 0x7FFD : out (c), a ; map fast page to fix 128k AY ports contention
jp .loop jp .loop
test_dump:
db 0x2F, 0xFF ; prescaler reg
db 0x2D, 0xFF ; prescaler reg
db 0x30, 0x01
db 0x34, 0x21
db 0x38, 0x52
db 0x3C, 0x02
db 0x40, 0x32
db 0x44, 0x17
db 0x48, 0x1C
db 0x4C, 0x03
db 0x50, 0x1F
db 0x54, 0x1F
db 0x58, 0x1F
db 0x5C, 0x1F
db 0x60, 0x08
db 0x64, 0x0C
db 0x68, 0x11
db 0x6C, 0x09
db 0x70, 0x00
db 0x74, 0x00
db 0x78, 0x01
db 0x7C, 0x00
db 0x80, 0xC0
db 0x84, 0xB1
db 0x88, 0x52
db 0x8C, 0xF4
db 0x90, 0x00
db 0x94, 0x00
db 0x98, 0x00
db 0x9C, 0x00
db 0xB0, 0x28
db 0x28, 0x00
db 0xA4, 0x0C
db 0xA0, 0xA3
db 0x28, 0xF0
db -1
; ---------------------------------------------------- ; ----------------------------------------------------
; vu meters ; vu meters
; orig by natt, rewritten by me ; orig by natt, rewritten by me
@ -197,6 +153,25 @@ vumeter:
; player include ; player include
include "player.asm" include "player.asm"
; music include
music_p0_ch4:
incbin "ay_env/ay_env_ch4.bin"
music_p0_ch5:
incbin "ay_env/ay_env_ch5.bin"
music_p0_ch6:
incbin "ay_env/ay_env_ch6.bin"
music_p0_ch7:
incbin "ay_env/ay_env_ch7.bin"
music_p0_ch12:
incbin "ay_env/ay_env_ch12.bin"
music_p0_ch13:
incbin "ay_env/ay_env_ch13.bin"
music_p0_ch14:
incbin "ay_env/ay_env_ch14.bin"
music_p0_ch15:
incbin "ay_env/ay_env_ch15.bin"
code_end code_end
; ------------------------------------------------- ; -------------------------------------------------
@ -205,7 +180,6 @@ code_end
emptytap "page0.tap" emptytap "page0.tap"
org 0xC000 org 0xC000
align 256 align 256
;incbin "!music/200_percent_partyfinal.2.6.psg.packed"
savetap "page0.tap",CODE,"page0",0xC000,$-0xC000 savetap "page0.tap",CODE,"page0",0xC000,$-0xC000

View file

@ -46,18 +46,18 @@ player_channels:
channel_struct_t 0, 0 channel_struct_t 0, 0
channel_struct_t 0, 0 channel_struct_t 0, 0
channel_struct_t 0, 0 channel_struct_t 0, 0
channel_struct_t 2, music_p0_ch4
channel_struct_t 2, music_p0_ch5
channel_struct_t 2, music_p0_ch6
channel_struct_t 2, music_p0_ch7
channel_struct_t 0, 0 channel_struct_t 0, 0
channel_struct_t 0, 0 channel_struct_t 0, 0
channel_struct_t 0, 0 channel_struct_t 0, 0
channel_struct_t 0, 0 channel_struct_t 0, 0
channel_struct_t 0, 0 channel_struct_t 2, music_p0_ch12
channel_struct_t 0, 0 channel_struct_t 2, music_p0_ch13
channel_struct_t 0, 0 channel_struct_t 2, music_p0_ch14
channel_struct_t 0, 0 channel_struct_t 2, music_p0_ch15
channel_struct_t 0, 0
channel_struct_t 0, 0
channel_struct_t 0, 0
channel_struct_t 0, 0
player_struct player_struct_t player_channels+(channel_struct_t*(3+0)+channel_struct_t.reg_extch3_fhi), player_channels+(channel_struct_t*(3+8)+channel_struct_t.reg_extch3_fhi) player_struct player_struct_t player_channels+(channel_struct_t*(3+0)+channel_struct_t.reg_extch3_fhi), player_channels+(channel_struct_t*(3+8)+channel_struct_t.reg_extch3_fhi)
@ -70,14 +70,11 @@ player_struct player_struct_t player_channels+(channel_struct_t*(3+0)+channel_
; ----------------------------- ; -----------------------------
; ----------------------------- ; -----------------------------
; OPN register dump output ; OPN register dump output
; in: HL - registers in (reg:data) byte pairs, reg==0xFF - return ; in:
; BC = 0xFFFD
; DE = 0x00C0 ; 0xFFBF compensated for outi
; HL - registers in (reg:data) byte pairs, reg==0xFF - return
reg_out: reg_out:
ld bc, 0xFFFD
ld de, 0x00C0 ; 0xFFBF compensated for outi
; select 1st chip
ld a, 0b11111000
out (c), a
.loop: .loop:
ld b, d ld b, d
ld a, [hl] ld a, [hl]
@ -158,12 +155,12 @@ set_delay:
ret ret
.int12: .int12:
ld a, [hl] : inc hl : and 0x0F : ld d, a ldi a, [hl] : and 0x0F : ld d, a
ld e, [hl] : inc hl ldi e, [hl]
ret ret
.short: .short:
ld a, [hl] : and 0x0F : inc a : ld e, a : ld d, 0 ldi a, [hl] : and 0x0F : inc a : ld e, a : ld d, 0
ret ret
; ------------------------------------------ ; ------------------------------------------
@ -186,7 +183,7 @@ parse_ay_channel_stream:
; if (mask & OPM_AYTONE_CMD00_PERIOD_LOW) opn_write_reg(chip_index, 0 + (ch<<1), *data++); ; if (mask & OPM_AYTONE_CMD00_PERIOD_LOW) opn_write_reg(chip_index, 0 + (ch<<1), *data++);
bit OPM_AYTONE_CMD00_PERIOD_LOW_BIT, b bit OPM_AYTONE_CMD00_PERIOD_LOW_BIT, b
jp nz, 1f jp z, 1f
ld a, [player_struct.channel_idx] ld a, [player_struct.channel_idx]
add a add a
ldi [iy], a ldi [iy], a
@ -196,7 +193,7 @@ parse_ay_channel_stream:
1: 1:
; if (mask & OPM_AYTONE_CMD00_EOF) endOfFrame = true; ; if (mask & OPM_AYTONE_CMD00_EOF) endOfFrame = true;
bit OPM_AYTONE_CMD00_EOF_BIT, b bit OPM_AYTONE_CMD00_EOF_BIT, b
jp nz, 1f jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
@ -222,7 +219,7 @@ parse_ay_channel_stream:
; if (mask & OPM_AYTONE_CMD80_PERIOD_LOW) opn_write_reg(chip_index, 0 + (ch << 1), *data++); ; if (mask & OPM_AYTONE_CMD80_PERIOD_LOW) opn_write_reg(chip_index, 0 + (ch << 1), *data++);
bit OPM_AYTONE_CMD80_PERIOD_LOW_BIT, b bit OPM_AYTONE_CMD80_PERIOD_LOW_BIT, b
jp nz, 1f jp z, 1f
dec a dec a
ldi [iy], a ldi [iy], a
ldi a, [hl] ldi a, [hl]
@ -231,7 +228,7 @@ parse_ay_channel_stream:
; if (mask & OPM_AYTONE_CMD00_EOF) endOfFrame = true; ; if (mask & OPM_AYTONE_CMD00_EOF) endOfFrame = true;
bit OPM_AYTONE_CMD80_EOF_BIT, b bit OPM_AYTONE_CMD80_EOF_BIT, b
jp nz, 1f jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
@ -248,26 +245,26 @@ parse_ay_channel_stream:
push de, hl, ix push de, hl, ix
; ctx->ssg_r7[chip_index] &= ~(((1 << 3) | (1 << 0)) << ch); ; ctx->ssg_r7[chip_index] &= ~(((1 << 3) | (1 << 0)) << ch);
ld a, [player_struct.chip_idx] : ld e, a ld a, [player_struct.chip_idx] : ld e, a : ld d, 0
ld d, 0
ld ix, player_struct.ssg_r7 ld ix, player_struct.ssg_r7
add ix, de ; ix = ctx->ssg_r7[chip_index] add ix, de ; ix = ctx->ssg_r7[chip_index]
ld a, [player_struct.channel_idx] : ld e, a ld a, [player_struct.channel_idx] : ld e, a
ld hl, .mask_channel ld hl, .mask_channel
add hl, de add hl, de
ld a, [ix] : and [hl] ; a = ctx->ssg_r7[chip_index] &= ~(((1 << 3) | (1 << 0)) << ch); ld a, [ix] : and [hl] : exa ; a = ctx->ssg_r7[chip_index] &= ~(((1 << 3) | (1 << 0)) << ch);
srl e : srl e sla e : sla e
ld a, b : and 3 : add e : ld e, a
ld hl, .mask_lookup ld hl, .mask_lookup
add hl, de add hl, de
or [hl] : ld [ix], a ; ctx->ssg_r7[chip_index] |= (mask_lookup[mask & 3] << ch); exa : or [hl] : ld [ix], a ; ctx->ssg_r7[chip_index] |= (mask_lookup[mask & 3] << ch);
pop hl, de, ix pop ix, hl, de
; if (mask & OPM_AYTONE_MASK_EOF) endOfFrame = true; ; if (mask & OPM_AYTONE_MASK_EOF) endOfFrame = true;
bit OPM_AYTONE_MASK_EOF_BIT, b bit OPM_AYTONE_MASK_EOF_BIT, b
jp nz, 1f jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
@ -309,7 +306,7 @@ parse_ay_envnoise_stream:
; if (mask & OPM_AYENV_CMD00_PERIOD_LOW) opn_write_reg(chip_index, 11, *data++); ; if (mask & OPM_AYENV_CMD00_PERIOD_LOW) opn_write_reg(chip_index, 11, *data++);
bit OPM_AYENV_CMD00_PERIOD_LOW_BIT, b bit OPM_AYENV_CMD00_PERIOD_LOW_BIT, b
jp nz, 1f jp z, 1f
ldi [iy], 11 ldi [iy], 11
ldi a, [hl] ldi a, [hl]
ldi [iy], a ldi [iy], a
@ -317,7 +314,7 @@ parse_ay_envnoise_stream:
; if (mask & OPM_AYENV_CMD00_EOF) endOfFrame = true; ; if (mask & OPM_AYENV_CMD00_EOF) endOfFrame = true;
bit OPM_AYENV_CMD00_EOF_BIT, b bit OPM_AYENV_CMD00_EOF_BIT, b
jp nz, 1f jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
@ -337,7 +334,7 @@ parse_ay_envnoise_stream:
; if (mask & OPM_AYENV_CMD80_PERIOD_LOW) opn_write_reg(chip_index, 11, *data++); ; if (mask & OPM_AYENV_CMD80_PERIOD_LOW) opn_write_reg(chip_index, 11, *data++);
bit OPM_AYENV_CMD80_PERIOD_LOW_BIT, b bit OPM_AYENV_CMD80_PERIOD_LOW_BIT, b
jp nz, 1f jp z, 1f
ldi [iy], 11 ldi [iy], 11
ldi a, [hl] ldi a, [hl]
ldi [iy], a ldi [iy], a
@ -345,7 +342,7 @@ parse_ay_envnoise_stream:
; if (mask & OPM_AYENV_CMD80_EOF) endOfFrame = true; ; if (mask & OPM_AYENV_CMD80_EOF) endOfFrame = true;
bit OPM_AYENV_CMD80_EOF_BIT, b bit OPM_AYENV_CMD80_EOF_BIT, b
jp nz, 1f jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
@ -360,21 +357,21 @@ parse_ay_envnoise_stream:
inc hl inc hl
; if (mask & OPM_AYENV_CMDF0_PERIOD_LOW) opn_write_reg(chip_index, 11, *data++); ; if (mask & OPM_AYENV_CMDF0_PERIOD_LOW) opn_write_reg(chip_index, 11, *data++);
bit OPM_AYENV_CMDF0_PERIOD_LOW_BIT, b bit OPM_AYENV_CMDF0_PERIOD_LOW_BIT, b
jp nz, 1f jp z, 1f
ldi [iy], 11 ldi [iy], 11
ldi a, [hl] ldi a, [hl]
ldi [iy], a ldi [iy], a
1: 1:
; if (mask & OPM_AYENV_CMDF0_PERIOD_HIGH) opn_write_reg(chip_index, 12, *data++); ; if (mask & OPM_AYENV_CMDF0_PERIOD_HIGH) opn_write_reg(chip_index, 12, *data++);
bit OPM_AYENV_CMDF0_PERIOD_HIGH_BIT, b bit OPM_AYENV_CMDF0_PERIOD_HIGH_BIT, b
jp nz, 1f jp z, 1f
ldi [iy], 12 ldi [iy], 12
ldi a, [hl] ldi a, [hl]
ldi [iy], a ldi [iy], a
1: 1:
; if (mask & OPM_AYENV_CMDF0_EOF) endOfFrame = true; ; if (mask & OPM_AYENV_CMDF0_EOF) endOfFrame = true;
bit OPM_AYENV_CMDF0_EOF_BIT, b bit OPM_AYENV_CMDF0_EOF_BIT, b
jp nz, 1f jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
@ -382,6 +379,7 @@ parse_ay_envnoise_stream:
ret ret
.not_period: .not_period:
and a ; clear carry
ret ret
; parse FM control stream ; parse FM control stream
@ -395,27 +393,27 @@ parse_fm_control_stream:
inc hl inc hl
;if (mask & OPM_CTRL_CMD80_REG25) opn_write_reg(chip_index, 0x25, *data++); ;if (mask & OPM_CTRL_CMD80_REG25) opn_write_reg(chip_index, 0x25, *data++);
bit OPM_CTRL_CMD80_REG25_BIT, b bit OPM_CTRL_CMD80_REG25_BIT, b
jp nz, 1f jp z, 1f
ldi [iy], 0x25 : ldi a, [hl] : ldi [iy], a ldi [iy], 0x25 : ldi a, [hl] : ldi [iy], a
1: 1:
;if (mask & OPM_CTRL_CMD80_REG24) opn_write_reg(chip_index, 0x24, *data++); ;if (mask & OPM_CTRL_CMD80_REG24) opn_write_reg(chip_index, 0x24, *data++);
bit OPM_CTRL_CMD80_REG24_BIT, b bit OPM_CTRL_CMD80_REG24_BIT, b
jp nz, 1f jp z, 1f
ldi [iy], 0x24 : ldi a, [hl] : ldi [iy], a ldi [iy], 0x24 : ldi a, [hl] : ldi [iy], a
1: 1:
;if (mask & OPM_CTRL_CMD80_REG27) opn_write_reg(chip_index, 0x27, *data++); ;if (mask & OPM_CTRL_CMD80_REG27) opn_write_reg(chip_index, 0x27, *data++);
bit OPM_CTRL_CMD80_REG27_BIT, b bit OPM_CTRL_CMD80_REG27_BIT, b
jp nz, 1f jp z, 1f
ldi [iy], 0x27 : ldi a, [hl] : ldi [iy], a ldi [iy], 0x27 : ldi a, [hl] : ldi [iy], a
1: 1:
;if (mask & OPM_CTRL_CMD80_REG22) opn_write_reg(chip_index, 0x22, *data++); ;if (mask & OPM_CTRL_CMD80_REG22) opn_write_reg(chip_index, 0x22, *data++);
bit OPM_CTRL_CMD80_REG25_BIT, b bit OPM_CTRL_CMD80_REG25_BIT, b
jp nz, 1f jp z, 1f
ldi [iy], 0x22 : ldi a, [hl] : ldi [iy], a ldi [iy], 0x22 : ldi a, [hl] : ldi [iy], a
1: 1:
;if (mask & OPM_CTRL_CMD80_EOF) endOfFrame = true; ;if (mask & OPM_CTRL_CMD80_EOF) endOfFrame = true;
bit OPM_CTRL_CMD80_EOF_BIT, b bit OPM_CTRL_CMD80_EOF_BIT, b
jp nz, 1f jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
scf scf
@ -430,7 +428,7 @@ parse_fm_control_stream:
; extract extch3 offset ; extract extch3 offset
push hl push hl
ld a, [player_struct.chip_idx] : add a : ld e, a : ld d, 0 ld a, [player_struct.chip_idx] : add a : ld e, a : ld d, 0
ld hl, player_struct.ch3_ofs_ch0 : add hl, de ld hl, player_struct.ch3_ofs_chip0 : add hl, de
ld e, [hl] : inc hl : ld d, [hl] ; de - channel 3 extch3 block ld e, [hl] : inc hl : ld d, [hl] ; de - channel 3 extch3 block
pop hl pop hl
@ -440,11 +438,11 @@ parse_fm_control_stream:
; opn_write_reg(chip_index, 0xA9, *data++); ; opn_write_reg(chip_index, 0xA9, *data++);
; } ; }
bit OPM_CTRL_EXTCH3_OP1_HIGH_BIT, b bit OPM_CTRL_EXTCH3_OP1_HIGH_BIT, b
jp nz, 1f jp z, 1f
ld a, [hl] : ld [de], a : inc hl ld a, [hl] : ld [de], a : inc hl
1: 1:
bit OPM_CTRL_EXTCH3_OP1_LOW_BIT, b bit OPM_CTRL_EXTCH3_OP1_LOW_BIT, b
jp nz, 1f jp z, 1f
ldi [iy], 0xAD : ld a, [de] : ldi [iy], a ldi [iy], 0xAD : ld a, [de] : ldi [iy], a
ldi [iy], 0xA9 : ldi a, [hl] : ldi [iy], a ldi [iy], 0xA9 : ldi a, [hl] : ldi [iy], a
1: 1:
@ -455,11 +453,11 @@ parse_fm_control_stream:
; opn_write_reg(chip_index, 0xA8, *data++); ; opn_write_reg(chip_index, 0xA8, *data++);
; } ; }
bit OPM_CTRL_EXTCH3_OP2_HIGH_BIT, b bit OPM_CTRL_EXTCH3_OP2_HIGH_BIT, b
jp nz, 1f jp z, 1f
ld a, [hl] : ld [de], a : inc hl ld a, [hl] : ld [de], a : inc hl
1: 1:
bit OPM_CTRL_EXTCH3_OP2_LOW_BIT, b bit OPM_CTRL_EXTCH3_OP2_LOW_BIT, b
jp nz, 1f jp z, 1f
ldi [iy], 0xAC : ld a, [de] : ldi [iy], a ldi [iy], 0xAC : ld a, [de] : ldi [iy], a
ldi [iy], 0xA8 : ldi a, [hl] : ldi [iy], a ldi [iy], 0xA8 : ldi a, [hl] : ldi [iy], a
1: 1:
@ -470,32 +468,28 @@ parse_fm_control_stream:
; opn_write_reg(chip_index, 0xAE, ctx->extch3_block[chip_index][2]); ; opn_write_reg(chip_index, 0xAE, ctx->extch3_block[chip_index][2]);
; opn_write_reg(chip_index, 0xAA, *data++); ; opn_write_reg(chip_index, 0xAA, *data++);
; } ; }
bit OPM_CTRL_EXTCH3_OP3_HIGH, b bit OPM_CTRL_EXTCH3_OP3_HIGH_BIT, b
jp nz, 1f jp z, 1f
ld a, [hl] : ld [de], a : inc hl ld a, [hl] : ld [de], a : inc hl
1: 1:
bit OPM_CTRL_EXTCH3_OP3_LOW, b bit OPM_CTRL_EXTCH3_OP3_LOW_BIT, b
jp nz, 1f jp z, 1f
ldi [iy], 0xAE : ld a, [de] : ldi [iy], a ldi [iy], 0xAE : ld a, [de] : ldi [iy], a
ldi [iy], 0xAA : ldi a, [hl] : ldi [iy], a ldi [iy], 0xAA : ldi a, [hl] : ldi [iy], a
1: 1:
; if (mask & OPM_CTRL_EXTCH3_EOF) endOfFrame = true; ; if (mask & OPM_CTRL_EXTCH3_EOF) endOfFrame = true;
bit OPM_CTRL_EXTCH3_EOF, b bit OPM_CTRL_EXTCH3_EOF_BIT, b
jp nz, 1f jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
scf scf
ret ret
.not_extch3: .not_extch3:
and a ; clear carry
ret ret
; c - channel offset
macro FM_STREAM_EMIT bit_ofs, regbase
endm
; parse FM channel stream ; parse FM channel stream
; HL - stream data, IX- channel context, IY - register buffer, CF - do next op ; HL - stream data, IX- channel context, IY - register buffer, CF - do next op
parse_fm_channel_stream: parse_fm_channel_stream:
@ -506,30 +500,31 @@ parse_fm_channel_stream:
inc hl inc hl
; int regbase = (ch & 3) + ((mask & OPM_FM_CMD00_OP_MASK) >> 2); ; int regbase = (ch & 3) + ((mask & OPM_FM_CMD00_OP_MASK) >> 2);
ld a, [player_struct.channel_idx] : ld c, a
ld a, b : and OPM_FM_CMD00_OP_MASK : rrca : rrca ld a, b : and OPM_FM_CMD00_OP_MASK : rrca : rrca
ld c, [player_struct.channel_idx] : or c : ld c, a or c : ld c, a
;if (mask & OPM_FM_CMD00_REG50) opn_write_reg(chip_index, 0x50 + regbase, *data++); ;if (mask & OPM_FM_CMD00_REG50) opn_write_reg(chip_index, 0x50 + regbase, *data++);
bit OPM_FM_CMD00_REG50_BIT, b bit OPM_FM_CMD00_REG50_BIT, b
jp nz, 1f jp z, 1f
ld a, 0x50 : add c : ldi [iy], a ld a, 0x50 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a ldi a, [hl] : ld [iy], a
1: 1:
;if (mask & OPM_FM_CMD00_REG60) opn_write_reg(chip_index, 0x60 + regbase, *data++); ;if (mask & OPM_FM_CMD00_REG60) opn_write_reg(chip_index, 0x60 + regbase, *data++);
bit OPM_FM_CMD00_REG60_BIT, b bit OPM_FM_CMD00_REG60_BIT, b
jp nz, 1f jp z, 1f
ld a, 0x60 : add c : ldi [iy], a ld a, 0x60 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a ldi a, [hl] : ld [iy], a
1: 1:
;if (mask & OPM_FM_CMD00_REG70) opn_write_reg(chip_index, 0x70 + regbase, *data++); ;if (mask & OPM_FM_CMD00_REG70) opn_write_reg(chip_index, 0x70 + regbase, *data++);
bit OPM_FM_CMD00_REG70_BIT, b bit OPM_FM_CMD00_REG70_BIT, b
jp nz, 1f jp z, 1f
ld a, 0x70 : add c : ldi [iy], a ld a, 0x70 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a ldi a, [hl] : ld [iy], a
1: 1:
;if (mask & OPM_FM_CMD00_REG80) opn_write_reg(chip_index, 0x80 + regbase, *data++); ;if (mask & OPM_FM_CMD00_REG80) opn_write_reg(chip_index, 0x80 + regbase, *data++);
bit OPM_FM_CMD00_REG80_BIT, b bit OPM_FM_CMD00_REG80_BIT, b
jp nz, 1f jp z, 1f
ld a, 0x80 : add c : ldi [iy], a ld a, 0x80 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a ldi a, [hl] : ld [iy], a
1: 1:
@ -544,30 +539,31 @@ parse_fm_channel_stream:
; multplier\TL\SSG-EG ; multplier\TL\SSG-EG
inc hl inc hl
; int regbase = (ch & 3) + ((mask & OPM_FM_CMD40_OP_MASK) >> 2); ; int regbase = (ch & 3) + ((mask & OPM_FM_CMD40_OP_MASK) >> 2);
ld a, [player_struct.channel_idx] : ld c, a
ld a, b : and OPM_FM_CMD40_OP_MASK : rrca : rrca ld a, b : and OPM_FM_CMD40_OP_MASK : rrca : rrca
ld c, [player_struct.channel_idx] : or c : ld c, a or c : ld c, a
;if (mask & OPM_FM_CMD40_REG30) opn_write_reg(chip_index, 0x30 + regbase, *data++); ;if (mask & OPM_FM_CMD40_REG30) opn_write_reg(chip_index, 0x30 + regbase, *data++);
bit OPM_FM_CMD40_REG30_BIT, b bit OPM_FM_CMD40_REG30_BIT, b
jp nz, 1f jp z, 1f
ld a, 0x30 : add c : ldi [iy], a ld a, 0x30 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a ldi a, [hl] : ld [iy], a
1: 1:
;if (mask & OPM_FM_CMD40_REG40) opn_write_reg(chip_index, 0x40 + regbase, *data++); ;if (mask & OPM_FM_CMD40_REG40) opn_write_reg(chip_index, 0x40 + regbase, *data++);
bit OPM_FM_CMD40_REG40_BIT, b bit OPM_FM_CMD40_REG40_BIT, b
jp nz, 1f jp z, 1f
ld a, 0x40 : add c : ldi [iy], a ld a, 0x40 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a ldi a, [hl] : ld [iy], a
1: 1:
;if (mask & OPM_FM_CMD40_REG90) opn_write_reg(chip_index, 0x90 + regbase, *data++); ;if (mask & OPM_FM_CMD40_REG90) opn_write_reg(chip_index, 0x90 + regbase, *data++);
bit OPM_FM_CMD40_REG90_BIT, b bit OPM_FM_CMD40_REG90_BIT, b
jp nz, 1f jp z, 1f
ld a, 0x90 : add c : ldi [iy], a ld a, 0x90 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a ldi a, [hl] : ld [iy], a
1: 1:
;if (mask & OPM_FM_CMD40_EOF) endOfFrame = true; ;if (mask & OPM_FM_CMD40_EOF) endOfFrame = true;
bit OPM_FM_CMD40_EOF_BIT, b bit OPM_FM_CMD40_EOF_BIT, b
jp nz, 1f jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
scf scf
@ -579,39 +575,39 @@ parse_fm_channel_stream:
jp nz, .not_freq_fb_pan jp nz, .not_freq_fb_pan
inc hl inc hl
ld c, [player_struct.channel_idx] ld a, [player_struct.channel_idx] : ld c, a
; if (mask & OPM_FM_CMD80_REGA4) chctx->block = *data++; ; if (mask & OPM_FM_CMD80_REGA4) chctx->block = *data++;
bit OPM_FM_CMD80_REGA4_BIT, b bit OPM_FM_CMD80_REGA4_BIT, b
jp nz, 1f jp z, 1f
ldi a, [hl] : ld [ix + channel_context_t.reg_fhi], a ldi a, [hl] : ld [ix + channel_struct_t.reg_fhi], a
1: 1:
; if (mask & OPM_FM_CMD80_REGA0) { ; if (mask & OPM_FM_CMD80_REGA0) {
; opn_write_reg(chip_index, 0xA4 + ch, chctx->block); ; opn_write_reg(chip_index, 0xA4 + ch, chctx->block);
; opn_write_reg(chip_index, 0xA0 + ch, *data++); ; opn_write_reg(chip_index, 0xA0 + ch, *data++);
; } ; }
bit OPM_FM_CMD80_REGA0_BIT, b bit OPM_FM_CMD80_REGA0_BIT, b
jp nz, 1f jp z, 1f
ld a, 0xA4 : add c : ldi [iy], a ld a, 0xA4 : add c : ldi [iy], a
ld a, [ix + channel_context_t.reg_fhi] : ldi [iy], a ld a, [ix + channel_struct_t.reg_fhi] : ldi [iy], a
ld a, 0xA0 : add c : ldi [iy], a ld a, 0xA0 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a ldi a, [hl] : ld [iy], a
1: 1:
; if (mask & OPM_FM_CMD80_REGB0) opn_write_reg(chip_index, 0xB0 + ch, *data++); ; if (mask & OPM_FM_CMD80_REGB0) opn_write_reg(chip_index, 0xB0 + ch, *data++);
bit OPM_FM_CMD80_REGB0_BIT, b bit OPM_FM_CMD80_REGB0_BIT, b
jp nz, 1f jp z, 1f
ld a, 0xb0 : add c : ldi [iy], a ld a, 0xb0 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a ldi a, [hl] : ld [iy], a
1: 1:
; if (mask & OPM_FM_CMD80_REGB4) opn_write_reg(chip_index, 0xB4 + ch, *data++); ; if (mask & OPM_FM_CMD80_REGB4) opn_write_reg(chip_index, 0xB4 + ch, *data++);
bit OPM_FM_CMD80_REGB4_BIT, b bit OPM_FM_CMD80_REGB4_BIT, b
jp nz, 1f jp z, 1f
ld a, 0xb4 : add c : ldi [iy], a ld a, 0xb4 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a ldi a, [hl] : ld [iy], a
1: 1:
; if (mask & OPM_FM_CMD80_EOF) endOfFrame = true; ; if (mask & OPM_FM_CMD80_EOF) endOfFrame = true;
bit OPM_FM_CMD80_EOF_BIT, b bit OPM_FM_CMD80_EOF_BIT, b
jp nz, 1f jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
scf scf
@ -623,22 +619,24 @@ parse_fm_channel_stream:
jp nz, .not_key jp nz, .not_key
; opn_write_reg(chip_index, 0x28, ((mask & OPM_FM_CMDA0_OP_MASK) << 4) + ch); ; opn_write_reg(chip_index, 0x28, ((mask & OPM_FM_CMDA0_OP_MASK) << 4) + ch);
ld c, [player_struct.channel_idx] ld a, [player_struct.channel_idx] : ld c, a
ld a, b : and OPM_FM_CMDA0_OP_MASK ld a, b : and OPM_FM_CMDA0_OP_MASK
add a, a : add a, a : add a, a : add a, a : add a, c add a, a : add a, a : add a, a : add a, a : add a, c
ldi [iy], 0x28 : ldi [iy], a ldi [iy], 0x28 : ldi [iy], a
1: 1:
; if (mask & OPM_FM_CMDA0_EOF) endOfFrame = true; ; if (mask & OPM_FM_CMDA0_EOF) endOfFrame = true;
bit OPM_FM_CMDA0_EOF_BIT, b bit OPM_FM_CMDA0_EOF_BIT, b
jp nz, 1f jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
scf scf
ret ret
.not_key: .not_key:
and a ; clear carry
ret ret
; --------------------------------
; parse channel stream ; parse channel stream
; in: IX - stream struct, IY - register buffer, BC - stream parser procedure, A - channel index ; in: IX - stream struct, IY - register buffer, BC - stream parser procedure, A - channel index
parse_stream: parse_stream:
@ -646,15 +644,15 @@ parse_stream:
xor a : ld [player_struct.end_of_frame], a xor a : ld [player_struct.end_of_frame], a
; if (--chctx->stream.delay == 0) { ; if (--chctx->stream.delay == 0) {
ld de, [ix+channel_struct_t.frames_to_play] ld de, [ix+channel_struct_t.delay]
dec de dec de
ld [ix+channel_struct_t.frames_to_play], de ld [ix+channel_struct_t.delay], de
ld a, d ld a, d
or e or e
ret z ret nz
; save proc ptr ; save proc ptr
ld bc, .proc ld [.proc], bc
; load stream pointer ; load stream pointer
ld a, [ix+channel_struct_t.page] ld a, [ix+channel_struct_t.page]
@ -666,9 +664,16 @@ parse_stream:
.tok_loop: .tok_loop:
ld a, [player_struct.end_of_frame] : and a : jp nz, .end_of_frame ld a, [player_struct.end_of_frame] : and a : jp nz, .end_of_frame
; common tokens
ld a, [hl]
cp OPM_STREAM_END
jp z, .tok_end_of_stream
cp OPM_STREAM_END_FRAME
jp z, .tok_end_of_frame
; call stream parser proc ; call stream parser proc
call 0 ; :grins: call 0 ; :grins:
.proc .proc equ $-2
jp c, .tok_loop ; token handled jp c, .tok_loop ; token handled
; handle common tokens ; handle common tokens
@ -694,16 +699,10 @@ parse_stream:
ld e, a : ld d, 0 : ld [ix + channel_struct_t.frames_to_play], de ld e, a : ld d, 0 : ld [ix + channel_struct_t.frames_to_play], de
jp .tok_loop jp .tok_loop
.not_backref .not_backref:
ld a, b
cp OPM_STREAM_END
jp z, .tok_end_of_stream
cp OPM_STREAM_END_FRAME
jp z, .tok_end_of_frame
; then it's most likely an delay ; then it's most likely an delay
call set_delay call set_delay
ld [ix + channel_struct_t.delay], de ld [ix + channel_struct_t.reload], de
; fetch next token until it's end of frame ; fetch next token until it's end of frame
jp .tok_loop jp .tok_loop
@ -718,8 +717,8 @@ parse_stream:
.end_of_frame: .end_of_frame:
; chctx->stream.delay = chctx->stream.reload; ; chctx->stream.delay = chctx->stream.reload;
ld de, [ix + channel_struct_t.delay] ld de, [ix + channel_struct_t.reload]
ld [ix + channel_struct_t.reload], de ld [ix + channel_struct_t.delay], de
; // decrement samples to play counter ; // decrement samples to play counter
; if (--chctx->stream.samples_to_play == 0) { ; if (--chctx->stream.samples_to_play == 0) {
@ -786,33 +785,32 @@ play_tick:
ld a, [player_struct.ssg_r7 + 0] ld a, [player_struct.ssg_r7 + 0]
ldi [iy], a ldi [iy], a
; select 2nd chip ; terminate list
ldi [iy], 0b11111000 ldi [iy], -1
ldi [iy], 0xFF
; chip_index = 1; ; chip_index = 1;
ld a, 1 : ld [player_struct.chip_idx], a ld a, 1 : ld [player_struct.chip_idx], a
; opmplay_parse_stream(ctx, ctx->channels + 4, 0, opmplay_parse_ay_channel_stream); ; opmplay_parse_stream(ctx, ctx->channels + 4, 0, opmplay_parse_ay_channel_stream);
ld ix, player_channels + (channel_struct_t * 4) ld ix, player_channels + (channel_struct_t * 12)
ld bc, parse_ay_channel_stream ld bc, parse_ay_channel_stream
ld a, 0 : ld [player_struct.channel_idx], a ld a, 0 : ld [player_struct.channel_idx], a
call parse_stream call parse_stream
; opmplay_parse_stream(ctx, ctx->channels + 5, 1, opmplay_parse_ay_channel_stream); ; opmplay_parse_stream(ctx, ctx->channels + 5, 1, opmplay_parse_ay_channel_stream);
ld ix, player_channels + (channel_struct_t * 5) ld ix, player_channels + (channel_struct_t * 13)
ld bc, parse_ay_channel_stream ld bc, parse_ay_channel_stream
ld a, 1 : ld [player_struct.channel_idx], a ld a, 1 : ld [player_struct.channel_idx], a
call parse_stream call parse_stream
; opmplay_parse_stream(ctx, ctx->channels + 6, 2, opmplay_parse_ay_channel_stream); ; opmplay_parse_stream(ctx, ctx->channels + 6, 2, opmplay_parse_ay_channel_stream);
ld ix, player_channels + (channel_struct_t * 6) ld ix, player_channels + (channel_struct_t * 14)
ld bc, parse_ay_channel_stream ld bc, parse_ay_channel_stream
ld a, 2 : ld [player_struct.channel_idx], a ld a, 2 : ld [player_struct.channel_idx], a
call parse_stream call parse_stream
; opmplay_parse_stream(ctx, ctx->channels + 7, 0, opmplay_parse_ay_channel_stream); ; opmplay_parse_stream(ctx, ctx->channels + 7, 0, opmplay_parse_ay_channel_stream);
ld ix, player_channels + (channel_struct_t * 7) ld ix, player_channels + (channel_struct_t * 15)
ld bc, parse_ay_envnoise_stream ld bc, parse_ay_envnoise_stream
call parse_stream call parse_stream