l_oliveira
Professional
As the title says, I spent a while thinking of how making this work.
CPS1Q and CPS2 use a 16 byte array to send sound codes and Q-SOUND through the first 16 bytes of the shared RAM area.
example:
code 0x0ff0 => 0f ff 00 00 00 ff 00 xx 00 00 00 00 00 ff ff ff
xx let 68k side know if anything is playing. on this 00 when mute. On this particular case 0x10 is put there during playback and 0x00 when no sound is being played.
0xC00F is used as an acknowledge flag. 68k doesn't send commands if it doesn toggle.
Probably is used to stop the game from trying to send commands if the Z80 ceases responding.
CAPCOM ZN1 and ZN2 games (ZN is actually the name SONY gave to the board, not CAPCOM) use a single byte I/O port on the Z80,
sending four bytes of data (/NMI is fired once each byte is sent).
code 0x0ff0 => 0xff 0x00 0x0f 0xf0
So, once I figured out why it was sending four bytes, making a breakthrough was trivial.
I came up with this solution: (FYI, this is Star Gladiator 2 Q-SOUND rom)
CPS1Q and CPS2 use a 16 byte array to send sound codes and Q-SOUND through the first 16 bytes of the shared RAM area.
example:
code 0x0ff0 => 0f ff 00 00 00 ff 00 xx 00 00 00 00 00 ff ff ff
xx let 68k side know if anything is playing. on this 00 when mute. On this particular case 0x10 is put there during playback and 0x00 when no sound is being played.
0xC00F is used as an acknowledge flag. 68k doesn't send commands if it doesn toggle.
Probably is used to stop the game from trying to send commands if the Z80 ceases responding.
CAPCOM ZN1 and ZN2 games (ZN is actually the name SONY gave to the board, not CAPCOM) use a single byte I/O port on the Z80,
sending four bytes of data (/NMI is fired once each byte is sent).
code 0x0ff0 => 0xff 0x00 0x0f 0xf0
So, once I figured out why it was sending four bytes, making a breakthrough was trivial.
I came up with this solution: (FYI, this is Star Gladiator 2 Q-SOUND rom)
Code:
0000: F3 di
0001: ED 56 im 1
0003: 31 FF FF ld sp,$FFFF
0006: 21 00 F0 ld hl,$F000
0009: 11 01 F0 ld de,$F001
000C: 01 FF 0F ld bc,$0FFF
000F: 36 00 ld (hl),$00
0011: ED B0 ldir
0013: 3E 77 ld a,$77 ; flags "z80 alive"
0015: 32 FF CF ld ($CFFF),a ; for the 68k
0018: C3 9A 00 jp $009A ; jump to original init
<snip>
0038: F3 di ; standard Q-SOUND interrupt routine
0039: 08 ex af,af'
003A: D9 exx
003B: 21 00 F0 ld hl,$F000
003E: 34 inc (hl)
003F: 7E ld a,(hl)
0040: E6 03 and $03
0042: 28 0F jr z,$0053
0044: 0F rrca
0045: 30 06 jr nc,$004D
0047: 21 01 F0 ld hl,$F001
004A: 34 inc (hl)
004B: 18 0A jr $0057
004D: 21 03 F0 ld hl,$F003
0050: 34 inc (hl)
0051: 18 04 jr $0057
0053: 21 02 F0 ld hl,$F002
0056: 34 inc (hl)
0057: C3 00 3A jp $3A00 ; this replaces "ex af,af'/exx/ei/ret" with a jump to the added code
<snip>
3A00: 3A FD CF ld a,($CFFD) ; 68k writes 0x88 here (shared RAM)
3A03: FE 88 cp $88
3A05: C2 3C 3A jp nz,$3A3C ; if not 0x88 don't check for sound codes
3A08: 3A 0F C0 ld a,($C00F) ; now playing flag
3A0B: 3C inc a
3A0C: CA 31 3A jp z,$3A31
3A0F: 3E FF ld a,$FF ; first sound code byte (fixed)
3A11: 32 30 F0 ld ($F030),a
3A14: CD 40 3A call $3A40 ; send it
3A17: 3E 00 ld a,$00 ; second sound code byte (fixed)
3A19: 32 30 F0 ld ($F030),a
3A1C: CD 40 3A call $3A40 ; send it
3A1F: 3A 00 C0 ld a,($C000) ; third sound code byte (from 68K)
3A22: 32 30 F0 ld ($F030),a
3A25: CD 40 3A call $3A40 ; send it
3A28: 3A 01 C0 ld a,($C001) ; fourth sound code byte (from 68k)
3A2B: 32 30 F0 ld ($F030),a
3A2E: CD 40 3A call $3A40 ; send it
3A31: 3E FF ld a,$FF
3A33: 32 0F C0 ld ($C00F),a
3A36: 3A FE CF ld a,($CFFE)
3A39: 32 04 F0 ld ($F004),a
3A3C: 08 ex af,af'
3A3D: D9 exx
3A3E: FB ei
3A3F: C9 ret
3A40: 21 15 F0 ld hl,$F015 ; original NMI routine refactored for this purpose
3A43: 3A 17 F0 ld a,($F017) ; push/pop and retn removed
3A46: 86 add a,(hl)
3A47: 26 00 ld h,$00
3A49: 6F ld l,a
3A4A: 01 00 F1 ld bc,$F100
3A4D: 09 add hl,bc
3A4E: 3A 30 F0 ld a,($F030) ; original instruction here 'ld a,(c)' changed to this. original was I/O port 0
3A51: 77 ld (hl),a
3A52: 21 17 F0 ld hl,$F017
3A55: 34 inc (hl)
3A56: 7E ld a,(hl)
3A57: FE 02 cp $02
3A59: 38 12 jr c,$3A6D
3A5B: 36 00 ld (hl),$00
3A5D: 3A 15 F0 ld a,($F015)
3A60: C6 02 add a,$02
3A62: 47 ld b,a
3A63: C6 02 add a,$02
3A65: 30 02 jr nc,$3A69
3A67: 06 00 ld b,$00
3A69: 78 ld a,b
3A6A: 32 15 F0 ld ($F015),a
3A6D: C9 ret