585 lines
29 KiB
NASM
585 lines
29 KiB
NASM
; ============================================================================
|
||
; cmdblocks.asm — VGM-format command blocks for chip init/silence
|
||
;
|
||
; Compiled with sjasmplus → raw binary 16KB, appended as plugin page 5.
|
||
;
|
||
; Each block contains standard VGM opcodes identical to those in .vgm files:
|
||
; 0x5E rr vv — OPL3 bank 0 write
|
||
; 0x5F rr vv — OPL3 bank 1 write
|
||
; 0x55 rr vv — YM2203 write (also used for MultiSound control regs 0xF0+)
|
||
; 0xA0 rr vv — AY8910 write (bit7 of rr = chip 2)
|
||
; 0xBD rr vv — SAA1099 write (bit7 of rr = chip 2)
|
||
; 0x66 — end of block
|
||
;
|
||
; The standard vgm_fill_buffer() parses these blocks in cmdblk_mode,
|
||
; converting VGM opcodes to ISR commands exactly as it does for .vgm data.
|
||
; This eliminates the need for a separate command copier — budget counting,
|
||
; buffer overflow protection and command parsing all come for free.
|
||
;
|
||
; NOTE on SAA clock: MultiSound intercepts AY reg select 0xF0-0xFF on
|
||
; port 0xFFFD for hardware control. VGM opcode 0xA0 strips bit7 of
|
||
; the register byte for chip selection, so 0xA0 CANNOT send regs >= 0x80
|
||
; to chip 1. We use YM2203 opcode 0x55 instead — it sends the register
|
||
; byte raw to 0xFFFD, which MultiSound intercepts correctly.
|
||
;
|
||
; Layout:
|
||
; 0xC000 : pointer table (uint16 × N) — absolute addresses of blocks
|
||
; 0xC000+N*2.. : block data (variable-length VGM commands, 3 bytes each)
|
||
;
|
||
; Usage from C:
|
||
; wc_mngc_pl(CMDBLK_PAGE);
|
||
; vgm_read_ptr = ((uint16_t*)0xC000)[blk_idx];
|
||
; vgm_cmdblk_mode = 1; vgm_song_ended = 0;
|
||
; vgm_fill_buffer(buf_idx);
|
||
; vgm_cmdblk_mode = 0;
|
||
;
|
||
; Assembled with: sjasmplus asm\cmdblocks.asm
|
||
; → SAVEBIN "build/cmdblocks.bin", #C000, #4000
|
||
; ============================================================================
|
||
|
||
DEVICE NOSLOT64K
|
||
ORG #C000
|
||
|
||
; ── VGM opcodes ─────────────────────────────────────────────────────
|
||
VGM_OPL_B0 EQU #5E ; OPL3 bank 0: 5E rr vv
|
||
VGM_OPL_B1 EQU #5F ; OPL3 bank 1: 5F rr vv
|
||
VGM_YM2203 EQU #55 ; YM2203 SSG+FM chip 1: 55 rr vv
|
||
VGM_YM2203_2 EQU #A5 ; YM2203 SSG+FM chip 2: A5 rr vv
|
||
VGM_AY EQU #A0 ; AY8910: A0 rr vv (bit7 = chip 2)
|
||
VGM_SAA EQU #BD ; SAA1099: BD rr vv (bit7 = chip 2)
|
||
VGM_OPL4 EQU #D0 ; YMF278B (OPL4): D0 pp rr vv (pp = port 0/1/2)
|
||
VGM_END EQU #66 ; End of data
|
||
|
||
; ── Macros (each emits standard VGM bytes, 3 bytes per command) ─────
|
||
|
||
MACRO opl3_bank0 addr, val
|
||
db VGM_OPL_B0, addr, val
|
||
ENDM
|
||
|
||
MACRO opl3_bank1 addr, val
|
||
db VGM_OPL_B1, addr, val
|
||
ENDM
|
||
|
||
MACRO ym2203_write reg, val
|
||
db VGM_YM2203, reg, val
|
||
ENDM
|
||
|
||
MACRO ym2203_2_write reg, val
|
||
db VGM_YM2203_2, reg, val
|
||
ENDM
|
||
|
||
MACRO ay_write reg, val
|
||
db VGM_AY, reg, val
|
||
ENDM
|
||
|
||
MACRO ay2_write reg, val
|
||
db VGM_AY, reg | #80, val
|
||
ENDM
|
||
|
||
MACRO saa_write reg, val
|
||
db VGM_SAA, reg, val
|
||
ENDM
|
||
|
||
MACRO saa2_write reg, val
|
||
db VGM_SAA, reg | #80, val
|
||
ENDM
|
||
|
||
MACRO opl4_wave_write reg, val
|
||
db VGM_OPL4, #02, reg, val
|
||
ENDM
|
||
|
||
MACRO blk_end
|
||
db VGM_END
|
||
ENDM
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; Pointer table (indices = CMDBLK_xxx from vgm.h)
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
ptr_table:
|
||
dw blk_init_opl3 ; 0 = CMDBLK_INIT_OPL3
|
||
dw blk_init_opl2 ; 1 = CMDBLK_INIT_OPL2
|
||
dw blk_silence_opl ; 2 = CMDBLK_SILENCE_OPL
|
||
dw blk_silence_ay ; 3 = CMDBLK_SILENCE_AY
|
||
dw blk_silence_ay2 ; 4 = CMDBLK_SILENCE_AY2
|
||
dw blk_silence_saa ; 5 = CMDBLK_SILENCE_SAA
|
||
dw blk_silence_saa2 ; 6 = CMDBLK_SILENCE_SAA2
|
||
dw blk_saa_clock_on ; 7 = CMDBLK_SAA_CLK_ON
|
||
dw blk_saa_clock_off ; 8 = CMDBLK_SAA_CLK_OFF
|
||
dw blk_silence_ym2203 ; 9 = CMDBLK_SILENCE_YM2203
|
||
dw blk_silence_ym2203_2 ; 10 = CMDBLK_SILENCE_YM2203_2
|
||
dw blk_saa_init ; 11 = CMDBLK_SAA_INIT
|
||
dw blk_saa2_init ; 12 = CMDBLK_SAA2_INIT
|
||
dw blk_init_opl4 ; 13 = CMDBLK_INIT_OPL4
|
||
dw blk_silence_wave ; 14 = CMDBLK_SILENCE_WAVE
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; CMDBLK_INIT_OPL3 — OPL3 init (NEW=1, clean state)
|
||
;
|
||
; OPL3 NEW=1 enables full OPL3 register set. 4-op connections are
|
||
; cleared (reg 0x104=0) to avoid leftover pairing from a previous
|
||
; track. Test/WSE register 0x01 is zeroed — OPL3 does not use WSE;
|
||
; waveform select is implicit via E0-F5 registers.
|
||
;
|
||
; VGM stream: 5F 05 01 5F 04 00 5E 01 00 66
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
blk_init_opl3:
|
||
opl3_bank1 #05, #01 ; VGM: 5F 05 01 — OPL3 NEW=1
|
||
opl3_bank1 #04, #00 ; VGM: 5F 04 00 — 4-op OFF (clean)
|
||
opl3_bank0 #01, #00 ; VGM: 5E 01 00 — Test/WSE=0
|
||
blk_end
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; CMDBLK_INIT_OPL4 — YMF278B (OPL4, ZXM-MoonSound) init: NEW=1 + NEW2=1
|
||
;
|
||
; Как CMDBLK_INIT_OPL3 (NEW=1, L/R через C0-C8), но дополнительно взводит
|
||
; бит NEW2 (бит 1 регистра Bank1 #05). На реальном чипе YMF278B этот бит
|
||
; обязателен — без него чип игнорирует любые записи в wave-часть (порты
|
||
; #7E/#7F), т.е. VGM-команды 0xD0 с портом 2 останутся немы.
|
||
;
|
||
; VGM stream: 5F 05 03 5F 04 00 5E 01 00 66
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
blk_init_opl4:
|
||
opl3_bank1 #05, #03 ; VGM: 5F 05 03 — NEW=1 + NEW2=1 (разблокировать wave)
|
||
opl3_bank1 #04, #00 ; VGM: 5F 04 00 — 4-op OFF (clean)
|
||
opl3_bank0 #01, #00 ; VGM: 5E 01 00 — Test/WSE=0
|
||
opl4_wave_write #02, #10 ; WT headers 384-511 from 0x200000,
|
||
; memory access OFF (sound generation mode)
|
||
blk_end
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; CMDBLK_INIT_OPL2 — OPL2 compat init (NEW=0, clean state)
|
||
;
|
||
; Forces OPL2 compatibility mode. Critically: 0x104=0 clears any
|
||
; residual 4-op state that would persist after an OPL3 track (the
|
||
; most common cause of OPL2 artifacts). Test/WSE register = 0.
|
||
;
|
||
; VGM stream: 5F 05 00 5F 04 00 5E 01 00 66
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
blk_init_opl2:
|
||
opl3_bank1 #05, #00 ; VGM: 5F 05 00 — OPL3 NEW=0 (OPL2)
|
||
opl3_bank1 #04, #00 ; VGM: 5F 04 00 — 4-op OFF (clean)
|
||
opl3_bank0 #01, #00 ; VGM: 5E 01 00 — Test/WSE=0
|
||
blk_end
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; CMDBLK_SILENCE_OPL — Full OPL3 silence (both banks)
|
||
;
|
||
; VGM stream (55 commands):
|
||
; 5E B0..B8 00 × 9 Key Off Bank 0 (ch 0-8)
|
||
; 5F B0..B8 00 × 9 Key Off Bank 1 (ch 0-8)
|
||
; 5E 4x 3F ×18 TL max Bank 0 (18 operators)
|
||
; 5F 4x 3F ×18 TL max Bank 1 (18 operators)
|
||
; 5E BD 00 Percussion Off
|
||
; 66 End
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
blk_silence_opl:
|
||
; ── Key Off: Bank 0 — VGM: 5E B0..B8 00 ──
|
||
opl3_bank0 #B0, #00
|
||
opl3_bank0 #B1, #00
|
||
opl3_bank0 #B2, #00
|
||
opl3_bank0 #B3, #00
|
||
opl3_bank0 #B4, #00
|
||
opl3_bank0 #B5, #00
|
||
opl3_bank0 #B6, #00
|
||
opl3_bank0 #B7, #00
|
||
opl3_bank0 #B8, #00
|
||
; ── Key Off: Bank 1 — VGM: 5F B0..B8 00 ──
|
||
opl3_bank1 #B0, #00
|
||
opl3_bank1 #B1, #00
|
||
opl3_bank1 #B2, #00
|
||
opl3_bank1 #B3, #00
|
||
opl3_bank1 #B4, #00
|
||
opl3_bank1 #B5, #00
|
||
opl3_bank1 #B6, #00
|
||
opl3_bank1 #B7, #00
|
||
opl3_bank1 #B8, #00
|
||
; ── TL max: Bank 0 — VGM: 5E {40-45,48-4D,50-55} 3F ──
|
||
opl3_bank0 #40, #3F
|
||
opl3_bank0 #41, #3F
|
||
opl3_bank0 #42, #3F
|
||
opl3_bank0 #43, #3F
|
||
opl3_bank0 #44, #3F
|
||
opl3_bank0 #45, #3F
|
||
opl3_bank0 #48, #3F
|
||
opl3_bank0 #49, #3F
|
||
opl3_bank0 #4A, #3F
|
||
opl3_bank0 #4B, #3F
|
||
opl3_bank0 #4C, #3F
|
||
opl3_bank0 #4D, #3F
|
||
opl3_bank0 #50, #3F
|
||
opl3_bank0 #51, #3F
|
||
opl3_bank0 #52, #3F
|
||
opl3_bank0 #53, #3F
|
||
opl3_bank0 #54, #3F
|
||
opl3_bank0 #55, #3F
|
||
; ── TL max: Bank 1 — VGM: 5F {40-45,48-4D,50-55} 3F ──
|
||
opl3_bank1 #40, #3F
|
||
opl3_bank1 #41, #3F
|
||
opl3_bank1 #42, #3F
|
||
opl3_bank1 #43, #3F
|
||
opl3_bank1 #44, #3F
|
||
opl3_bank1 #45, #3F
|
||
opl3_bank1 #48, #3F
|
||
opl3_bank1 #49, #3F
|
||
opl3_bank1 #4A, #3F
|
||
opl3_bank1 #4B, #3F
|
||
opl3_bank1 #4C, #3F
|
||
opl3_bank1 #4D, #3F
|
||
opl3_bank1 #50, #3F
|
||
opl3_bank1 #51, #3F
|
||
opl3_bank1 #52, #3F
|
||
opl3_bank1 #53, #3F
|
||
opl3_bank1 #54, #3F
|
||
opl3_bank1 #55, #3F
|
||
; ── Waveform reset: Bank 0 — VGM: 5E {E0-E5,E8-ED,F0-F5} 00 ──
|
||
; Clears non-sine waveforms that linger between tracks.
|
||
; Critical for clean OPL2 playback after OPL3 usage.
|
||
opl3_bank0 #E0, #00
|
||
opl3_bank0 #E1, #00
|
||
opl3_bank0 #E2, #00
|
||
opl3_bank0 #E3, #00
|
||
opl3_bank0 #E4, #00
|
||
opl3_bank0 #E5, #00
|
||
opl3_bank0 #E8, #00
|
||
opl3_bank0 #E9, #00
|
||
opl3_bank0 #EA, #00
|
||
opl3_bank0 #EB, #00
|
||
opl3_bank0 #EC, #00
|
||
opl3_bank0 #ED, #00
|
||
opl3_bank0 #F0, #00
|
||
opl3_bank0 #F1, #00
|
||
opl3_bank0 #F2, #00
|
||
opl3_bank0 #F3, #00
|
||
opl3_bank0 #F4, #00
|
||
opl3_bank0 #F5, #00
|
||
; ── Waveform reset: Bank 1 — VGM: 5F {E0-E5,E8-ED,F0-F5} 00 ──
|
||
opl3_bank1 #E0, #00
|
||
opl3_bank1 #E1, #00
|
||
opl3_bank1 #E2, #00
|
||
opl3_bank1 #E3, #00
|
||
opl3_bank1 #E4, #00
|
||
opl3_bank1 #E5, #00
|
||
opl3_bank1 #E8, #00
|
||
opl3_bank1 #E9, #00
|
||
opl3_bank1 #EA, #00
|
||
opl3_bank1 #EB, #00
|
||
opl3_bank1 #EC, #00
|
||
opl3_bank1 #ED, #00
|
||
opl3_bank1 #F0, #00
|
||
opl3_bank1 #F1, #00
|
||
opl3_bank1 #F2, #00
|
||
opl3_bank1 #F3, #00
|
||
opl3_bank1 #F4, #00
|
||
opl3_bank1 #F5, #00
|
||
; ── Percussion Off — VGM: 5E BD 00 ──
|
||
opl3_bank0 #BD, #00
|
||
blk_end
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; CMDBLK_SILENCE_WAVE — YMF278B (OPL4) wave-часть silence, 24 канала
|
||
;
|
||
; CMDBLK_SILENCE_OPL глушит только FM-банки (0x5E/0x5F) — wave-каналы
|
||
; (табличный синтез, до 24 голосов) им не затрагиваются и продолжают
|
||
; звучать после выхода из плеера. Для каждого канала N (0-23):
|
||
; рег. (0x68+N), data=0x40 — Key Off + Damp (бит7:6=01, форсированный
|
||
; быстрый спад огибающей, EG_DMP)
|
||
; рег. (0x50+N), data=0xFF — TL=0x7F (макс. затухание) + LD=1
|
||
; (мгновенно, без интерполяции громкости)
|
||
; Оба варианта дублируют друг друга (как KeyOff+TL max у FM-банков) —
|
||
; гарантия тишины независимо от состояния огибающей канала.
|
||
;
|
||
; VGM stream: D0 02 68 40 ... D0 02 7F 40 (Key Off+Damp, 24 канала)
|
||
; D0 02 50 FF ... D0 02 67 FF (TL max, 24 канала)
|
||
; 66
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
blk_silence_wave:
|
||
opl4_wave_write #68, #40
|
||
opl4_wave_write #69, #40
|
||
opl4_wave_write #6A, #40
|
||
opl4_wave_write #6B, #40
|
||
opl4_wave_write #6C, #40
|
||
opl4_wave_write #6D, #40
|
||
opl4_wave_write #6E, #40
|
||
opl4_wave_write #6F, #40
|
||
opl4_wave_write #70, #40
|
||
opl4_wave_write #71, #40
|
||
opl4_wave_write #72, #40
|
||
opl4_wave_write #73, #40
|
||
opl4_wave_write #74, #40
|
||
opl4_wave_write #75, #40
|
||
opl4_wave_write #76, #40
|
||
opl4_wave_write #77, #40
|
||
opl4_wave_write #78, #40
|
||
opl4_wave_write #79, #40
|
||
opl4_wave_write #7A, #40
|
||
opl4_wave_write #7B, #40
|
||
opl4_wave_write #7C, #40
|
||
opl4_wave_write #7D, #40
|
||
opl4_wave_write #7E, #40
|
||
opl4_wave_write #7F, #40
|
||
opl4_wave_write #50, #FF
|
||
opl4_wave_write #51, #FF
|
||
opl4_wave_write #52, #FF
|
||
opl4_wave_write #53, #FF
|
||
opl4_wave_write #54, #FF
|
||
opl4_wave_write #55, #FF
|
||
opl4_wave_write #56, #FF
|
||
opl4_wave_write #57, #FF
|
||
opl4_wave_write #58, #FF
|
||
opl4_wave_write #59, #FF
|
||
opl4_wave_write #5A, #FF
|
||
opl4_wave_write #5B, #FF
|
||
opl4_wave_write #5C, #FF
|
||
opl4_wave_write #5D, #FF
|
||
opl4_wave_write #5E, #FF
|
||
opl4_wave_write #5F, #FF
|
||
opl4_wave_write #60, #FF
|
||
opl4_wave_write #61, #FF
|
||
opl4_wave_write #62, #FF
|
||
opl4_wave_write #63, #FF
|
||
opl4_wave_write #64, #FF
|
||
opl4_wave_write #65, #FF
|
||
opl4_wave_write #66, #FF
|
||
opl4_wave_write #67, #FF
|
||
blk_end
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; CMDBLK_SILENCE_AY — Silence AY8910 chip 1
|
||
;
|
||
; VGM stream:
|
||
; A0 07 3F Mixer: all tone+noise off
|
||
; A0 08 00 Volume A = 0
|
||
; A0 09 00 Volume B = 0
|
||
; A0 0A 00 Volume C = 0
|
||
; 66 End
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
blk_silence_ay:
|
||
ay_write 7, #3F ; VGM: A0 07 3F
|
||
ay_write 8, #00 ; VGM: A0 08 00
|
||
ay_write 9, #00 ; VGM: A0 09 00
|
||
ay_write 10, #00 ; VGM: A0 0A 00
|
||
blk_end
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; CMDBLK_SILENCE_AY2 — Silence AY8910 chip 2 (TurboSound)
|
||
;
|
||
; VGM stream (bit7 = chip 2):
|
||
; A0 87 3F Mixer off
|
||
; A0 88 00 Volume A = 0
|
||
; A0 89 00 Volume B = 0
|
||
; A0 8A 00 Volume C = 0
|
||
; 66 End
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
blk_silence_ay2:
|
||
ay2_write 7, #3F ; VGM: A0 87 3F
|
||
ay2_write 8, #00 ; VGM: A0 88 00
|
||
ay2_write 9, #00 ; VGM: A0 89 00
|
||
ay2_write 10, #00 ; VGM: A0 8A 00
|
||
blk_end
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; CMDBLK_SILENCE_SAA — Silence SAA1099 chip 1
|
||
;
|
||
; VGM stream:
|
||
; BD 1C 02 Reset all (sound gen + internal state)
|
||
; BD 1C 00 Sound enable off
|
||
; BD 00..05 00 Amplitude ch 0-5 = 0
|
||
; 66 End
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
blk_silence_saa:
|
||
saa_write #1C, #02 ; VGM: BD 1C 02 — Reset all
|
||
saa_write #1C, #00 ; VGM: BD 1C 00 — Sound enable off
|
||
saa_write #00, #00 ; VGM: BD 00 00 — Amp ch0 = 0
|
||
saa_write #01, #00 ; VGM: BD 01 00 — Amp ch1 = 0
|
||
saa_write #02, #00 ; VGM: BD 02 00 — Amp ch2 = 0
|
||
saa_write #03, #00 ; VGM: BD 03 00 — Amp ch3 = 0
|
||
saa_write #04, #00 ; VGM: BD 04 00 — Amp ch4 = 0
|
||
saa_write #05, #00 ; VGM: BD 05 00 — Amp ch5 = 0
|
||
blk_end
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; CMDBLK_SILENCE_SAA2 — Silence SAA1099 chip 2
|
||
;
|
||
; VGM stream (bit7 = chip 2):
|
||
; BD 9C 02 Reset all
|
||
; BD 9C 00 Sound enable off
|
||
; BD 80..85 00 Amplitude ch 0-5 = 0
|
||
; 66 End
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
blk_silence_saa2:
|
||
saa2_write #1C, #02 ; VGM: BD 9C 02 — Reset all
|
||
saa2_write #1C, #00 ; VGM: BD 9C 00 — Sound enable off
|
||
saa2_write #00, #00 ; VGM: BD 80 00 — Amp ch0 = 0
|
||
saa2_write #01, #00 ; VGM: BD 81 00 — Amp ch1 = 0
|
||
saa2_write #02, #00 ; VGM: BD 82 00 — Amp ch2 = 0
|
||
saa2_write #03, #00 ; VGM: BD 83 00 — Amp ch3 = 0
|
||
saa2_write #04, #00 ; VGM: BD 84 00 — Amp ch4 = 0
|
||
saa2_write #05, #00 ; VGM: BD 85 00 — Amp ch5 = 0
|
||
blk_end
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; CMDBLK_SAA_CLK_ON — Enable SAA1099 + FM clock (MultiSound)
|
||
;
|
||
; Uses YM2203 opcode (0x55) so that register 0xF3 is sent raw to 0xFFFD.
|
||
; AY opcode 0xA0 would strip bit7 for chip selection → can't reach 0xF3.
|
||
; MultiSound intercepts reg select 0xF0-0xFF for hardware control.
|
||
; bit0=1(YM2) bit1=1(normal) bit2=0(FM ON) bit3=0(SAA ON)
|
||
;
|
||
; VGM stream: 55 F3 00 66
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
blk_saa_clock_on:
|
||
ym2203_write #F3, #00 ; VGM: 55 F3 00 — SAA+FM clock ON
|
||
blk_end
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; CMDBLK_SAA_CLK_OFF — Disable SAA1099 + FM clock (MultiSound)
|
||
;
|
||
; VGM stream: 55 FF 00 66
|
||
; bit2=1(FM OFF) bit3=1(SAA OFF)
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
blk_saa_clock_off:
|
||
ym2203_write #FF, #00 ; VGM: 55 FF 00 — SAA+FM clock OFF
|
||
blk_end
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; CMDBLK_SILENCE_YM2203 — Silence YM2203 (SSG + FM) + reset prescaler
|
||
;
|
||
; Prescaler reset (reg 0x2D, write-only, value ignored):
|
||
; 55 2D 00 Reset prescaler → defaults: /6 FM, /4 SSG
|
||
; Prevents state leak from tracks that set /3+/2 via 0x2E.
|
||
; SSG (AY-compatible):
|
||
; 55 07 3F Mixer: all tone+noise off
|
||
; 55 08 00 SSG Volume A = 0
|
||
; 55 09 00 SSG Volume B = 0
|
||
; 55 0A 00 SSG Volume C = 0
|
||
; FM — Key Off all 3 channels:
|
||
; 55 28 00 Key Off ch 0
|
||
; 55 28 01 Key Off ch 1
|
||
; 55 28 02 Key Off ch 2
|
||
; FM — TL max (0x7F) all 12 operators:
|
||
; 55 40..42 7F slot 1 (M1): ch 0,1,2
|
||
; 55 44..46 7F slot 3 (C1): ch 0,1,2
|
||
; 55 48..4A 7F slot 2 (M2): ch 0,1,2
|
||
; 55 4C..4E 7F slot 4 (C2): ch 0,1,2
|
||
; Total: 20 VGM commands + end = 61 bytes
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
blk_silence_ym2203:
|
||
; ── SSG silence — VGM: 55 rr vv ──
|
||
ym2203_write 7, #3F ; VGM: 55 07 3F — Mixer off
|
||
ym2203_write 8, #00 ; VGM: 55 08 00 — SSG Vol A = 0
|
||
ym2203_write 9, #00 ; VGM: 55 09 00 — SSG Vol B = 0
|
||
ym2203_write 10, #00 ; VGM: 55 0A 00 — SSG Vol C = 0
|
||
; ── FM Key Off — VGM: 55 28 xx ──
|
||
ym2203_write #28, #00 ; VGM: 55 28 00 — Key Off ch 0
|
||
ym2203_write #28, #01 ; VGM: 55 28 01 — Key Off ch 1
|
||
ym2203_write #28, #02 ; VGM: 55 28 02 — Key Off ch 2
|
||
; ── FM TL max — VGM: 55 4x 7F ──
|
||
ym2203_write #40, #7F ; VGM: 55 40 7F — TL slot1 ch0
|
||
ym2203_write #41, #7F ; VGM: 55 41 7F — TL slot1 ch1
|
||
ym2203_write #42, #7F ; VGM: 55 42 7F — TL slot1 ch2
|
||
ym2203_write #44, #7F ; VGM: 55 44 7F — TL slot3 ch0
|
||
ym2203_write #45, #7F ; VGM: 55 45 7F — TL slot3 ch1
|
||
ym2203_write #46, #7F ; VGM: 55 46 7F — TL slot3 ch2
|
||
ym2203_write #48, #7F ; VGM: 55 48 7F — TL slot2 ch0
|
||
ym2203_write #49, #7F ; VGM: 55 49 7F — TL slot2 ch1
|
||
ym2203_write #4A, #7F ; VGM: 55 4A 7F — TL slot2 ch2
|
||
ym2203_write #4C, #7F ; VGM: 55 4C 7F — TL slot4 ch0
|
||
ym2203_write #4D, #7F ; VGM: 55 4D 7F — TL slot4 ch1
|
||
ym2203_write #4E, #7F ; VGM: 55 4E 7F — TL slot4 ch2
|
||
|
||
; ── Prescaler reset — VGM: 55 2D 00 ──
|
||
ym2203_write #2F, #01 ; VGM: 55 2D 00
|
||
ym2203_write #2D, #01 ; VGM: A5 2E 00
|
||
|
||
blk_end
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; CMDBLK_SILENCE_YM2203_2 — Silence YM2203 chip 2 (TurboSound)
|
||
;
|
||
; Uses VGM opcode 0xA5 (dual chip: 0x55 → 0xA5) → vgm_fill_buffer
|
||
; generates CMD_WRITE_AY2 which selects chip 2 via isr_ms_ctrl.
|
||
;
|
||
; Prescaler reset:
|
||
; A5 2D 00 Reset prescaler → defaults: /6 FM, /4 SSG
|
||
; SSG (chip 2):
|
||
; A5 07 3F Mixer: all tone+noise off
|
||
; A5 08 00 SSG Volume A = 0
|
||
; A5 09 00 SSG Volume B = 0
|
||
; A5 0A 00 SSG Volume C = 0
|
||
; FM — Key Off all 3 channels (chip 2):
|
||
; A5 28 00 Key Off ch 0
|
||
; A5 28 01 Key Off ch 1
|
||
; A5 28 02 Key Off ch 2
|
||
; FM — TL max (0x7F) all 12 operators (chip 2):
|
||
; A5 40..42 7F slot 1 (M1): ch 0,1,2
|
||
; A5 44..46 7F slot 3 (C1): ch 0,1,2
|
||
; A5 48..4A 7F slot 2 (M2): ch 0,1,2
|
||
; A5 4C..4E 7F slot 4 (C2): ch 0,1,2
|
||
; Total: 20 VGM commands + end = 61 bytes
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
blk_silence_ym2203_2:
|
||
; ── SSG silence (chip 2) — VGM: A5 rr vv ──
|
||
ym2203_2_write 7, #3F ; VGM: A5 07 3F — Mixer off
|
||
ym2203_2_write 8, #00 ; VGM: A5 08 00 — SSG Vol A = 0
|
||
ym2203_2_write 9, #00 ; VGM: A5 09 00 — SSG Vol B = 0
|
||
ym2203_2_write 10, #00 ; VGM: A5 0A 00 — SSG Vol C = 0
|
||
; ── FM Key Off (chip 2) — VGM: A5 28 xx ──
|
||
ym2203_2_write #28, #00 ; VGM: A5 28 00 — Key Off ch 0
|
||
ym2203_2_write #28, #01 ; VGM: A5 28 01 — Key Off ch 1
|
||
ym2203_2_write #28, #02 ; VGM: A5 28 02 — Key Off ch 2
|
||
; ── FM TL max (chip 2) — VGM: A5 4x 7F ──
|
||
ym2203_2_write #40, #7F ; VGM: A5 40 7F — TL slot1 ch0
|
||
ym2203_2_write #41, #7F ; VGM: A5 41 7F — TL slot1 ch1
|
||
ym2203_2_write #42, #7F ; VGM: A5 42 7F — TL slot1 ch2
|
||
ym2203_2_write #44, #7F ; VGM: A5 44 7F — TL slot3 ch0
|
||
ym2203_2_write #45, #7F ; VGM: A5 45 7F — TL slot3 ch1
|
||
ym2203_2_write #46, #7F ; VGM: A5 46 7F — TL slot3 ch2
|
||
ym2203_2_write #48, #7F ; VGM: A5 48 7F — TL slot2 ch0
|
||
ym2203_2_write #49, #7F ; VGM: A5 49 7F — TL slot2 ch1
|
||
ym2203_2_write #4A, #7F ; VGM: A5 4A 7F — TL slot2 ch2
|
||
ym2203_2_write #4C, #7F ; VGM: A5 4C 7F — TL slot4 ch0
|
||
ym2203_2_write #4D, #7F ; VGM: A5 4D 7F — TL slot4 ch1
|
||
ym2203_2_write #4E, #7F ; VGM: A5 4E 7F — TL slot4 ch2
|
||
|
||
; ── Prescaler reset (chip 2) — VGM: A5 2D 00 ──
|
||
; ── Prescaler reset — VGM: 55 2D 00 ──
|
||
ym2203_2_write #2F, #01 ; VGM: 55 2D 00
|
||
ym2203_2_write #2D, #01 ; VGM: A5 2E 00
|
||
|
||
blk_end
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; CMDBLK_SAA_INIT — SAA1099 chip 1 Sound Enable ON
|
||
;
|
||
; Writes reg 0x1C = 0x01 to chip 0 (Sound Enable ON).
|
||
; Parsed via cmdblk → fb_is_vgm==0 → bypasses saa_mode filter.
|
||
;
|
||
; VGM stream: BD 1C 01 66
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
blk_saa_init:
|
||
saa_write #1C, #01 ; VGM: BD 1C 01 — Sound Enable ON (chip 0)
|
||
blk_end
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; CMDBLK_SAA2_INIT — SAA1099 chip 2 Sound Enable ON (+ clock enable)
|
||
;
|
||
; Writes reg 0x1C|0x80 = 0x9C to chip 1 (bit7 selects chip 1).
|
||
; In HDL: address write 0x9C → saa_reg_is_1c=1, then data 0x01 with
|
||
; d[0]=1 triggers saa2_clk_en (one-way clock enable for chip 2).
|
||
; Parsed via cmdblk → fb_is_vgm==0 → bypasses saa_mode filter.
|
||
;
|
||
; VGM stream: BD 9C 01 66
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
blk_saa2_init:
|
||
saa2_write #1C, #01 ; VGM: BD 9C 01 — Sound Enable ON (chip 1 + clk)
|
||
blk_end
|
||
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
; Padding to 16 KB
|
||
; ═══════════════════════════════════════════════════════════════════════
|
||
IF $ < #10000
|
||
ds #10000 - $, #00
|
||
ENDIF
|
||
|
||
SAVEBIN "build/cmdblocks.bin", #C000, #4000
|