Over the past few weeks, I've been optimizing the Z80 driver (now it's 3x faster) and finding other various ways to improve the sound quality. The playback quality is pretty much perfect now, and the driver can also support a file up to 22050Hz now.
Here's a test demo of the new, improved driver:
Link to Test Demo
EDIT: Link fixed.
EDIT 2: Just found this out; sound doesn't work in Gens. Would someone be willing to test if this works on real hardware?
Music list for the demo, in a fancy code box that preserves formatting:
PCMDriverLoad: ; XREF: GameClrRAM; TitleScreen move.w #0,($A11200).l move.w #$100,($A11100).l move.w #$100,($A11200).l WaitForZ80_2: btst #0,($A11100).l bne WaitForZ80_2 lea (Z802),a0 lea ($A00000).l,a1 move.W #Z802End-Z802,d1 LoadDriver: move.b (a0)+,(a1)+ dbf d1,LoadDriver move.b #$01,($FFFFFFFC).w rts Z802: incbin sound\PCMD.bin Z802End:
This is the code that actually loads the new PCM driver. It also incbin's the PCM driver (I'm assuming here that you put it in the sound folder of the split disassembly, and didn't change the name), and sets a special driver byte at $FFFFFFFC (this will be needed later).
Step 3:
Find the SoundDriverLoad subroutine, and replace it with this:
SoundDriverLoad: ; XREF: GameClrRAM; TitleScreen nop move.w #$100,($A11100).l ; stop the Z80 move.w #$100,($A11200).l ; reset the Z80 lea (Kos_Z80).l,a0 ; load sound driver lea ($A00000).l,a1 bsr.w KosDec ; decompress move.w #0,($A11200).l nop nop nop nop move.w #$100,($A11200).l ; reset the Z80 move.w #0,($A11100).l ; start the Z80 move.b #$00,($FFFFFFFC).w rts
The only new thing here is the line of code at the end that sets the driver flag to 0. So when the driver flag is 0, the regular S1 drum driver is in use, but when the driver flag is 1, the new PCM driver is in use.
Step 4:
Find the subroutine labeled "sub_71B4C", and replace it with this.
sub_71B4C: ; XREF: loc_B10; PalToCRAM cmpi.b #$01,($FFFFFFFC).w beq.s loc_71B82 move.w #$100,($A11100).l ; stop the Z80 loc_71B5A: btst #0,($A11100).l bne.s loc_71B5A move.b ($A01FFD).l,d0 btst #7,d0 bra.s loc_71B82 move.w #0,($A11100).l ; start the Z80 bra.s sub_71B4C
This is what we needed the driver flag for. Without this subroutine, the regular S1 drum driver won't play, but it's unnecessary to the new PCM driver, and also decreases the quality of the new PCM driver without this modification (since it stops the Z80). However, it's changed so that if the new PCM driver is in use, it'll skip stopping the Z80, preserving the quality of the music.
Step 5:
Find the subroutine labeled "Sound_81to9F", and add this code to the beginning:
; --------------------------------------------------------------------------- PlayMusic81: jsr Sound_E4 jsr PCMDriverLoad move.w #$100,($A11100).l ;Stop the Z80 WaitZ80_81: btst #0,($A11100).l bne WaitZ80_81 ;Wait for z80 to stop move.b #1,($a00039).l ;turn the driver on move.b #(((Music81+$34)&0xFF0000)>>16),($a0003c).l ;location - $__xxxx move.b #(((Music81+$34)&0xFF00)>>8),($a0003b).l ;location - $xx__xx move.b #((Music81+$34)&0xFF),($a0003a).l ;location - $xxxx__ move.b #(((Music82-Music81)&0xFF0000)>>16),($a0003f).l ;length - $__xxxx move.b #(((Music82-Music81)&0xFF00)>>8),($a0003e).l ;length - $xx__xx move.b #((Music82-Music81)&0xFF),($a0003d).l ;length - $xxxx__ move.b #$0C,($a00046).l ;sample rate (00=22050Hz, 05=16000Hz, 0C=11025Hz, 15=8000Hz) move.b #$01,($a0004A).l ;looping flag ($00=no,$01=yes) move.w #$0,($A11100).l ;Start the Z80 rts ; ---------------------------------------------------------------------------
This is the code that would actually play song $81. From the comments, you should be able to pretty much tell what it does. (Just in case you can't figure out, (Music82-Music81) equals the length of Music81.) You need to do one final thing to get it to play:
Add this at the beginning of Sound_81to9F:
Sound_81to9F: ; XREF: Sound_ChkValue cmpi.b #$81,d7 beq.l PlayMusic81 jmp Continue8129F nop ; --------------------------------------------------------------------------- PlayMusic81: jsr Sound_E4 jsr PCMDriverLoad move.w #$100,($A11100).l ;Stop the Z80 WaitZ80_81: btst #0,($A11100).l bne WaitZ80_81 ;Wait for z80 to halt move.b #1,($a00039).l ;turn the wav playing script on move.b #(((Music81+$34)&0xFF0000)>>16),($a0003c).l ;addr - $__xxxx move.b #(((Music81+$34)&0xFF00)>>8),($a0003b).l ;addr - $xx__xx move.b #((Music81+$34)&0xFF),($a0003a).l ;addr - $xxxx__ move.b #(((Music82-Music81)&0xFF0000)>>16),($a0003f).l ;addr - $__xxxx move.b #(((Music82-Music81)&0xFF00)>>8),($a0003e).l ;addr - $xx__xx move.b #((Music82-Music81)&0xFF),($a0003d).l ;addr - $xxxx__ move.b #$0C,($a00046).l ;sample rate (00=22050Hz, 05=16000Hz, 0C=11025Hz, 15=8000Hz) move.b #$01,($a0004A).l ;looping flag ($00=no,$01=yes) move.w #$0,($A11100).l ;Start the Z80 rts ; --------------------------------------------------------------------------- Continue8129F: jsr SoundDriverLoad cmpi.b #$88,d7 ; is "extra life" music played? bne.s loc_72024 ; if not, branch
Let's say that, in your split disassembly, music82.bin was also a wav file, and you wanted it to play too. Then the subroutine would look like this:
Sound_81to9F: ; XREF: Sound_ChkValue cmpi.b #$81,d7 beq.l PlayMusic81 cmpi.b #$82,d7 beq.l PlayMusic82 jmp Continue8129F nop ; --------------------------------------------------------------------------- PlayMusic81: jsr Sound_E4 jsr PCMDriverLoad move.w #$100,($A11100).l ;Stop the Z80 WaitZ80_81: btst #0,($A11100).l bne WaitZ80_81 ;Wait for z80 to halt move.b #1,($a00039).l ;turn the wav playing script on move.b #(((Music81+$34)&0xFF0000)>>16),($a0003c).l ;addr - $__xxxx move.b #(((Music81+$34)&0xFF00)>>8),($a0003b).l ;addr - $xx__xx move.b #((Music81+$34)&0xFF),($a0003a).l ;addr - $xxxx__ move.b #(((Music82-Music81)&0xFF0000)>>16),($a0003f).l ;addr - $__xxxx move.b #(((Music82-Music81)&0xFF00)>>8),($a0003e).l ;addr - $xx__xx move.b #((Music82-Music81)&0xFF),($a0003d).l ;addr - $xxxx__ move.b #$0C,($a00046).l ;sample rate (00=22050Hz, 05=16000Hz, 0C=11025Hz, 15=8000Hz) move.b #$01,($a0004A).l ;looping flag ($00=no,$01=yes) move.w #$0,($A11100).l ;Start the Z80 rts ; --------------------------------------------------------------------------- ; --------------------------------------------------------------------------- PlayMusic82: jsr Sound_E4 jsr PCMDriverLoad move.w #$100,($A11100).l ;Stop the Z80 WaitZ80_82: btst #0,($A11100).l bne WaitZ80_82 ;Wait for z80 to halt move.b #1,($a00039).l ;turn the wav playing script on move.b #(((Music82+$34)&0xFF0000)>>16),($a0003c).l ;addr - $__xxxx move.b #(((Music82+$34)&0xFF00)>>8),($a0003b).l ;addr - $xx__xx move.b #((Music82+$34)&0xFF),($a0003a).l ;addr - $xxxx__ move.b #(((Music83-Music82)&0xFF0000)>>16),($a0003f).l ;addr - $__xxxx move.b #(((Music83-Music82)&0xFF00)>>8),($a0003e).l ;addr - $xx__xx move.b #((Music83-Music82)&0xFF),($a0003d).l ;addr - $xxxx__ move.b #$0C,($a00046).l ;sample rate (00=22050Hz, 05=16000Hz, 0C=11025Hz, 15=8000Hz) move.b #$01,($a0004A).l ;looping flag ($00=no,$01=yes) move.w #$0,($A11100).l ;Start the Z80 rts ; --------------------------------------------------------------------------- Continue8129F: jsr SoundDriverLoad cmpi.b #$88,d7 ; is "extra life" music played? bne.s loc_72024 ; if not, branch
Hopefully you understood all of that...as I've said many times, I'm not good at explaining things. If you have any questions about this, just ask. =P
====================
tl;dr: You can put WAVs in for your level music now. You'll have to read the whole post to see how.

