Compare commits

..

No commits in common. "347ca2f9a661db8cb793c1a00d936acd48fd034e" and "641bde75e50bbb227caf56083d57d6c523173732" have entirely different histories.

2 changed files with 167 additions and 139 deletions

View file

@ -31,38 +31,82 @@ 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
ld bc, 0xFFFD ; output OPN registers
ld de, 0x00C0 ; TODO
ld a, 0b11111000 ld hl, test_dump
out (c), a
ld hl, reg_buffer
call player.reg_out call player.reg_out
ld a, 2 : out (0xfe), a di
ld a, 0b11111001 halt
ld b, 0xFF
out (c), a ; draw VU meters
inc hl .base = 0x4000 + 2048*2 + 32*6 + 19
call player.reg_out ld bc, .base + 0 ; 10
ld a, 3 : out (0xfe), a call vumeter.draw_0 ; 17
ld iy, reg_buffer .vu0 equ $-2
call player.play_tick ld bc, .base + 2 ; 10
xor a : out (0xfe), a 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
; 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
@ -153,25 +197,6 @@ 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
; ------------------------------------------------- ; -------------------------------------------------
@ -180,6 +205,7 @@ 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 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
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,11 +70,14 @@ player_struct player_struct_t player_channels+(channel_struct_t*(3+0)+channel_
; ----------------------------- ; -----------------------------
; ----------------------------- ; -----------------------------
; OPN register dump output ; OPN register dump output
; in: ; in: HL - registers in (reg:data) byte pairs, reg==0xFF - return
; 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]
@ -155,12 +158,12 @@ set_delay:
ret ret
.int12: .int12:
ldi a, [hl] : and 0x0F : ld d, a ld a, [hl] : inc hl : and 0x0F : ld d, a
ldi e, [hl] ld e, [hl] : inc hl
ret ret
.short: .short:
ldi a, [hl] : and 0x0F : inc a : ld e, a : ld d, 0 ld a, [hl] : and 0x0F : inc a : ld e, a : ld d, 0
ret ret
; ------------------------------------------ ; ------------------------------------------
@ -183,7 +186,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 z, 1f jp nz, 1f
ld a, [player_struct.channel_idx] ld a, [player_struct.channel_idx]
add a add a
ldi [iy], a ldi [iy], a
@ -193,7 +196,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 z, 1f jp nz, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
@ -219,7 +222,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 z, 1f jp nz, 1f
dec a dec a
ldi [iy], a ldi [iy], a
ldi a, [hl] ldi a, [hl]
@ -228,7 +231,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 z, 1f jp nz, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
@ -245,26 +248,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 d, 0 ld a, [player_struct.chip_idx] : ld e, a
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] : exa ; a = ctx->ssg_r7[chip_index] &= ~(((1 << 3) | (1 << 0)) << ch); ld a, [ix] : and [hl] ; a = ctx->ssg_r7[chip_index] &= ~(((1 << 3) | (1 << 0)) << ch);
sla e : sla e srl e : srl 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
exa : or [hl] : ld [ix], a ; ctx->ssg_r7[chip_index] |= (mask_lookup[mask & 3] << ch); or [hl] : ld [ix], a ; ctx->ssg_r7[chip_index] |= (mask_lookup[mask & 3] << ch);
pop ix, hl, de pop hl, de, ix
; 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 z, 1f jp nz, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
@ -306,7 +309,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 z, 1f jp nz, 1f
ldi [iy], 11 ldi [iy], 11
ldi a, [hl] ldi a, [hl]
ldi [iy], a ldi [iy], a
@ -314,7 +317,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 z, 1f jp nz, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
@ -334,7 +337,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 z, 1f jp nz, 1f
ldi [iy], 11 ldi [iy], 11
ldi a, [hl] ldi a, [hl]
ldi [iy], a ldi [iy], a
@ -342,7 +345,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 z, 1f jp nz, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
@ -357,21 +360,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 z, 1f jp nz, 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 z, 1f jp nz, 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 z, 1f jp nz, 1f
ld a, b : ld [player_struct.end_of_frame], a ld a, b : ld [player_struct.end_of_frame], a
1: 1:
@ -379,7 +382,6 @@ parse_ay_envnoise_stream:
ret ret
.not_period: .not_period:
and a ; clear carry
ret ret
; parse FM control stream ; parse FM control stream
@ -393,27 +395,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 z, 1f jp nz, 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 z, 1f jp nz, 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 z, 1f jp nz, 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 z, 1f jp nz, 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 z, 1f jp nz, 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
@ -428,7 +430,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_chip0 : add hl, de ld hl, player_struct.ch3_ofs_ch0 : 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
@ -438,11 +440,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 z, 1f jp nz, 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 z, 1f jp nz, 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:
@ -453,11 +455,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 z, 1f jp nz, 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 z, 1f jp nz, 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:
@ -468,28 +470,32 @@ 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_BIT, b bit OPM_CTRL_EXTCH3_OP3_HIGH, b
jp z, 1f jp nz, 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_BIT, b bit OPM_CTRL_EXTCH3_OP3_LOW, b
jp z, 1f jp nz, 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_BIT, b bit OPM_CTRL_EXTCH3_EOF, b
jp z, 1f jp nz, 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:
@ -500,31 +506,30 @@ 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
or c : ld c, a ld c, [player_struct.channel_idx] : 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 z, 1f jp nz, 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 z, 1f jp nz, 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 z, 1f jp nz, 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 z, 1f jp nz, 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:
@ -539,31 +544,30 @@ 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
or c : ld c, a ld c, [player_struct.channel_idx] : 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 z, 1f jp nz, 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 z, 1f jp nz, 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 z, 1f jp nz, 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 z, 1f jp nz, 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
@ -575,39 +579,39 @@ parse_fm_channel_stream:
jp nz, .not_freq_fb_pan jp nz, .not_freq_fb_pan
inc hl inc hl
ld a, [player_struct.channel_idx] : ld c, a ld c, [player_struct.channel_idx]
; 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 z, 1f jp nz, 1f
ldi a, [hl] : ld [ix + channel_struct_t.reg_fhi], a ldi a, [hl] : ld [ix + channel_context_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 z, 1f jp nz, 1f
ld a, 0xA4 : add c : ldi [iy], a ld a, 0xA4 : add c : ldi [iy], a
ld a, [ix + channel_struct_t.reg_fhi] : ldi [iy], a ld a, [ix + channel_context_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 z, 1f jp nz, 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 z, 1f jp nz, 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 z, 1f jp nz, 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
@ -619,24 +623,22 @@ 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 a, [player_struct.channel_idx] : ld c, a ld c, [player_struct.channel_idx]
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 z, 1f jp nz, 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:
@ -644,15 +646,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.delay] ld de, [ix+channel_struct_t.frames_to_play]
dec de dec de
ld [ix+channel_struct_t.delay], de ld [ix+channel_struct_t.frames_to_play], de
ld a, d ld a, d
or e or e
ret nz ret z
; save proc ptr ; save proc ptr
ld [.proc], bc ld bc, .proc
; load stream pointer ; load stream pointer
ld a, [ix+channel_struct_t.page] ld a, [ix+channel_struct_t.page]
@ -664,16 +666,9 @@ 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 equ $-2 .proc
jp c, .tok_loop ; token handled jp c, .tok_loop ; token handled
; handle common tokens ; handle common tokens
@ -699,10 +694,16 @@ 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.reload], de ld [ix + channel_struct_t.delay], 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
@ -717,8 +718,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.reload] ld de, [ix + channel_struct_t.delay]
ld [ix + channel_struct_t.delay], de ld [ix + channel_struct_t.reload], 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) {
@ -785,32 +786,33 @@ play_tick:
ld a, [player_struct.ssg_r7 + 0] ld a, [player_struct.ssg_r7 + 0]
ldi [iy], a ldi [iy], a
; terminate list ; select 2nd chip
ldi [iy], -1 ldi [iy], 0b11111000
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 * 12) ld ix, player_channels + (channel_struct_t * 4)
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 * 13) ld ix, player_channels + (channel_struct_t * 5)
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 * 14) ld ix, player_channels + (channel_struct_t * 6)
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 * 15) ld ix, player_channels + (channel_struct_t * 7)
ld bc, parse_ay_envnoise_stream ld bc, parse_ay_envnoise_stream
call parse_stream call parse_stream