AY stream parser bug fixes

This commit is contained in:
wbcbz7 2025-08-14 18:55:57 +07:00
parent da8baeb549
commit 0f6da89826
2 changed files with 96 additions and 129 deletions

View file

@ -31,82 +31,26 @@ start:
ld i, a
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
ei
.loop:
halt
; output OPN registers
; TODO
ld hl, test_dump
call player.reg_out
di
halt
; draw VU meters
.base = 0x4000 + 2048*2 + 32*6 + 19
ld bc, .base + 0 ; 10
call vumeter.draw_0 ; 17
.vu0 equ $-2
ld bc, .base + 2 ; 10
call vumeter.draw_0 ; 17
.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
ld a, 1 : out (0xfe), a
call player.reg_out
ld a, 2 : out (0xfe), a
call player.play_tick
xor a : out (0xfe), a
; and jump to next frame
xor a : ld bc, 0x7FFD : out (c), a ; map fast page to fix 128k AY ports contention
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
; orig by natt, rewritten by me
@ -197,6 +141,25 @@ vumeter:
; player include
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
; -------------------------------------------------
@ -205,7 +168,6 @@ code_end
emptytap "page0.tap"
org 0xC000
align 256
;incbin "!music/200_percent_partyfinal.2.6.psg.packed"
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 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 0, 0
channel_struct_t 0, 0
channel_struct_t 0, 0
channel_struct_t 2, music_p0_ch12
channel_struct_t 2, music_p0_ch13
channel_struct_t 2, music_p0_ch14
channel_struct_t 2, music_p0_ch15
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)
@ -158,12 +158,12 @@ set_delay:
ret
.int12:
ld a, [hl] : inc hl : and 0x0F : ld d, a
ld e, [hl] : inc hl
ldi a, [hl] : and 0x0F : ld d, a
ldi e, [hl]
ret
.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
; ------------------------------------------
@ -186,7 +186,7 @@ parse_ay_channel_stream:
; if (mask & OPM_AYTONE_CMD00_PERIOD_LOW) opn_write_reg(chip_index, 0 + (ch<<1), *data++);
bit OPM_AYTONE_CMD00_PERIOD_LOW_BIT, b
jp nz, 1f
jp z, 1f
ld a, [player_struct.channel_idx]
add a
ldi [iy], a
@ -196,7 +196,7 @@ parse_ay_channel_stream:
1:
; if (mask & OPM_AYTONE_CMD00_EOF) endOfFrame = true;
bit OPM_AYTONE_CMD00_EOF_BIT, b
jp nz, 1f
jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a
1:
@ -222,7 +222,7 @@ parse_ay_channel_stream:
; if (mask & OPM_AYTONE_CMD80_PERIOD_LOW) opn_write_reg(chip_index, 0 + (ch << 1), *data++);
bit OPM_AYTONE_CMD80_PERIOD_LOW_BIT, b
jp nz, 1f
jp z, 1f
dec a
ldi [iy], a
ldi a, [hl]
@ -231,7 +231,7 @@ parse_ay_channel_stream:
; if (mask & OPM_AYTONE_CMD00_EOF) endOfFrame = true;
bit OPM_AYTONE_CMD80_EOF_BIT, b
jp nz, 1f
jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a
1:
@ -256,18 +256,19 @@ parse_ay_channel_stream:
ld a, [player_struct.channel_idx] : ld e, a
ld hl, .mask_channel
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
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;
bit OPM_AYTONE_MASK_EOF_BIT, b
jp nz, 1f
jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a
1:
@ -309,7 +310,7 @@ parse_ay_envnoise_stream:
; if (mask & OPM_AYENV_CMD00_PERIOD_LOW) opn_write_reg(chip_index, 11, *data++);
bit OPM_AYENV_CMD00_PERIOD_LOW_BIT, b
jp nz, 1f
jp z, 1f
ldi [iy], 11
ldi a, [hl]
ldi [iy], a
@ -317,7 +318,7 @@ parse_ay_envnoise_stream:
; if (mask & OPM_AYENV_CMD00_EOF) endOfFrame = true;
bit OPM_AYENV_CMD00_EOF_BIT, b
jp nz, 1f
jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a
1:
@ -337,7 +338,7 @@ parse_ay_envnoise_stream:
; if (mask & OPM_AYENV_CMD80_PERIOD_LOW) opn_write_reg(chip_index, 11, *data++);
bit OPM_AYENV_CMD80_PERIOD_LOW_BIT, b
jp nz, 1f
jp z, 1f
ldi [iy], 11
ldi a, [hl]
ldi [iy], a
@ -345,7 +346,7 @@ parse_ay_envnoise_stream:
; if (mask & OPM_AYENV_CMD80_EOF) endOfFrame = true;
bit OPM_AYENV_CMD80_EOF_BIT, b
jp nz, 1f
jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a
1:
@ -360,21 +361,21 @@ parse_ay_envnoise_stream:
inc hl
; if (mask & OPM_AYENV_CMDF0_PERIOD_LOW) opn_write_reg(chip_index, 11, *data++);
bit OPM_AYENV_CMDF0_PERIOD_LOW_BIT, b
jp nz, 1f
jp z, 1f
ldi [iy], 11
ldi a, [hl]
ldi [iy], a
1:
; if (mask & OPM_AYENV_CMDF0_PERIOD_HIGH) opn_write_reg(chip_index, 12, *data++);
bit OPM_AYENV_CMDF0_PERIOD_HIGH_BIT, b
jp nz, 1f
jp z, 1f
ldi [iy], 12
ldi a, [hl]
ldi [iy], a
1:
; if (mask & OPM_AYENV_CMDF0_EOF) endOfFrame = true;
bit OPM_AYENV_CMDF0_EOF_BIT, b
jp nz, 1f
jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a
1:
@ -382,6 +383,7 @@ parse_ay_envnoise_stream:
ret
.not_period:
and a ; clear carry
ret
; parse FM control stream
@ -395,27 +397,27 @@ parse_fm_control_stream:
inc hl
;if (mask & OPM_CTRL_CMD80_REG25) opn_write_reg(chip_index, 0x25, *data++);
bit OPM_CTRL_CMD80_REG25_BIT, b
jp nz, 1f
jp z, 1f
ldi [iy], 0x25 : ldi a, [hl] : ldi [iy], a
1:
;if (mask & OPM_CTRL_CMD80_REG24) opn_write_reg(chip_index, 0x24, *data++);
bit OPM_CTRL_CMD80_REG24_BIT, b
jp nz, 1f
jp z, 1f
ldi [iy], 0x24 : ldi a, [hl] : ldi [iy], a
1:
;if (mask & OPM_CTRL_CMD80_REG27) opn_write_reg(chip_index, 0x27, *data++);
bit OPM_CTRL_CMD80_REG27_BIT, b
jp nz, 1f
jp z, 1f
ldi [iy], 0x27 : ldi a, [hl] : ldi [iy], a
1:
;if (mask & OPM_CTRL_CMD80_REG22) opn_write_reg(chip_index, 0x22, *data++);
bit OPM_CTRL_CMD80_REG25_BIT, b
jp nz, 1f
jp z, 1f
ldi [iy], 0x22 : ldi a, [hl] : ldi [iy], a
1:
;if (mask & OPM_CTRL_CMD80_EOF) endOfFrame = true;
bit OPM_CTRL_CMD80_EOF_BIT, b
jp nz, 1f
jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a
1:
scf
@ -440,11 +442,11 @@ parse_fm_control_stream:
; opn_write_reg(chip_index, 0xA9, *data++);
; }
bit OPM_CTRL_EXTCH3_OP1_HIGH_BIT, b
jp nz, 1f
jp z, 1f
ld a, [hl] : ld [de], a : inc hl
1:
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], 0xA9 : ldi a, [hl] : ldi [iy], a
1:
@ -455,11 +457,11 @@ parse_fm_control_stream:
; opn_write_reg(chip_index, 0xA8, *data++);
; }
bit OPM_CTRL_EXTCH3_OP2_HIGH_BIT, b
jp nz, 1f
jp z, 1f
ld a, [hl] : ld [de], a : inc hl
1:
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], 0xA8 : ldi a, [hl] : ldi [iy], a
1:
@ -471,24 +473,25 @@ parse_fm_control_stream:
; opn_write_reg(chip_index, 0xAA, *data++);
; }
bit OPM_CTRL_EXTCH3_OP3_HIGH_BIT, b
jp nz, 1f
jp z, 1f
ld a, [hl] : ld [de], a : inc hl
1:
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], 0xAA : ldi a, [hl] : ldi [iy], a
1:
; if (mask & OPM_CTRL_EXTCH3_EOF) endOfFrame = true;
bit OPM_CTRL_EXTCH3_EOF_BIT, b
jp nz, 1f
jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a
1:
scf
ret
.not_extch3:
and a ; clear carry
ret
; parse FM channel stream
@ -507,25 +510,25 @@ parse_fm_channel_stream:
;if (mask & OPM_FM_CMD00_REG50) opn_write_reg(chip_index, 0x50 + regbase, *data++);
bit OPM_FM_CMD00_REG50_BIT, b
jp nz, 1f
jp z, 1f
ld a, 0x50 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a
1:
;if (mask & OPM_FM_CMD00_REG60) opn_write_reg(chip_index, 0x60 + regbase, *data++);
bit OPM_FM_CMD00_REG60_BIT, b
jp nz, 1f
jp z, 1f
ld a, 0x60 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a
1:
;if (mask & OPM_FM_CMD00_REG70) opn_write_reg(chip_index, 0x70 + regbase, *data++);
bit OPM_FM_CMD00_REG70_BIT, b
jp nz, 1f
jp z, 1f
ld a, 0x70 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a
1:
;if (mask & OPM_FM_CMD00_REG80) opn_write_reg(chip_index, 0x80 + regbase, *data++);
bit OPM_FM_CMD00_REG80_BIT, b
jp nz, 1f
jp z, 1f
ld a, 0x80 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a
1:
@ -546,25 +549,25 @@ parse_fm_channel_stream:
;if (mask & OPM_FM_CMD40_REG30) opn_write_reg(chip_index, 0x30 + regbase, *data++);
bit OPM_FM_CMD40_REG30_BIT, b
jp nz, 1f
jp z, 1f
ld a, 0x30 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a
1:
;if (mask & OPM_FM_CMD40_REG40) opn_write_reg(chip_index, 0x40 + regbase, *data++);
bit OPM_FM_CMD40_REG40_BIT, b
jp nz, 1f
jp z, 1f
ld a, 0x40 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a
1:
;if (mask & OPM_FM_CMD40_REG90) opn_write_reg(chip_index, 0x90 + regbase, *data++);
bit OPM_FM_CMD40_REG90_BIT, b
jp nz, 1f
jp z, 1f
ld a, 0x90 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a
1:
;if (mask & OPM_FM_CMD40_EOF) endOfFrame = true;
bit OPM_FM_CMD40_EOF_BIT, b
jp nz, 1f
jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a
1:
scf
@ -580,7 +583,7 @@ parse_fm_channel_stream:
; if (mask & OPM_FM_CMD80_REGA4) chctx->block = *data++;
bit OPM_FM_CMD80_REGA4_BIT, b
jp nz, 1f
jp z, 1f
ldi a, [hl] : ld [ix + channel_struct_t.reg_fhi], a
1:
; if (mask & OPM_FM_CMD80_REGA0) {
@ -588,7 +591,7 @@ parse_fm_channel_stream:
; opn_write_reg(chip_index, 0xA0 + ch, *data++);
; }
bit OPM_FM_CMD80_REGA0_BIT, b
jp nz, 1f
jp z, 1f
ld a, 0xA4 : add c : ldi [iy], a
ld a, [ix + channel_struct_t.reg_fhi] : ldi [iy], a
ld a, 0xA0 : add c : ldi [iy], a
@ -596,19 +599,19 @@ parse_fm_channel_stream:
1:
; if (mask & OPM_FM_CMD80_REGB0) opn_write_reg(chip_index, 0xB0 + ch, *data++);
bit OPM_FM_CMD80_REGB0_BIT, b
jp nz, 1f
jp z, 1f
ld a, 0xb0 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a
1:
; if (mask & OPM_FM_CMD80_REGB4) opn_write_reg(chip_index, 0xB4 + ch, *data++);
bit OPM_FM_CMD80_REGB4_BIT, b
jp nz, 1f
jp z, 1f
ld a, 0xb4 : add c : ldi [iy], a
ldi a, [hl] : ld [iy], a
1:
; if (mask & OPM_FM_CMD80_EOF) endOfFrame = true;
bit OPM_FM_CMD80_EOF_BIT, b
jp nz, 1f
jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a
1:
scf
@ -627,15 +630,17 @@ parse_fm_channel_stream:
1:
; if (mask & OPM_FM_CMDA0_EOF) endOfFrame = true;
bit OPM_FM_CMDA0_EOF_BIT, b
jp nz, 1f
jp z, 1f
ld a, b : ld [player_struct.end_of_frame], a
1:
scf
ret
.not_key:
and a ; clear carry
ret
; --------------------------------
; parse channel stream
; in: IX - stream struct, IY - register buffer, BC - stream parser procedure, A - channel index
parse_stream:
@ -643,15 +648,15 @@ parse_stream:
xor a : ld [player_struct.end_of_frame], a
; if (--chctx->stream.delay == 0) {
ld de, [ix+channel_struct_t.frames_to_play]
ld de, [ix+channel_struct_t.delay]
dec de
ld [ix+channel_struct_t.frames_to_play], de
ld [ix+channel_struct_t.delay], de
ld a, d
or e
ret z
ret nz
; save proc ptr
ld bc, .proc
ld [.proc], bc
; load stream pointer
ld a, [ix+channel_struct_t.page]
@ -665,7 +670,7 @@ parse_stream:
; call stream parser proc
call 0 ; :grins:
.proc
.proc equ $-2
jp c, .tok_loop ; token handled
; handle common tokens
@ -700,7 +705,7 @@ parse_stream:
; then it's most likely an 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
jp .tok_loop
@ -715,8 +720,8 @@ parse_stream:
.end_of_frame:
; chctx->stream.delay = chctx->stream.reload;
ld de, [ix + channel_struct_t.delay]
ld [ix + channel_struct_t.reload], de
ld de, [ix + channel_struct_t.reload]
ld [ix + channel_struct_t.delay], de
; // decrement samples to play counter
; if (--chctx->stream.samples_to_play == 0) {