Note: Read further down for more fixes, and I recommend going here for even more fixes. You've probably read Clownacy's post on making Sonic 2's Sound Driver Good, but some people may prefer the Sonic 1 Driver due to its flexibility. Well, here's how you can improve it in various ways. Please note this is designed with my AS disassembly, which can be found here. Optimizing WriteFMI/WriteFMII Spoiler Wow both this and Clownacy's guide both start with optimizing WriteFMI/WriteFMII... interesting... Sonic 1 seems to be using a modified (early?) 68K Type 1b driver. One of its weird oddities is that the "WriteFMI" and "WriteFMII" instructions are really unoptimized. So why not optimize it? In s1.sounddriver.asm at WriteFMI: you'll see this monstrosity of nature. Code (Text): WriteFMI: ; XREF: loc_71E6A move.b ($A04000).l,d2 btst #7,d2 bne.s WriteFMI move.b d0,($A04000).l nop nop nop loc_72746: move.b ($A04000).l,d2 btst #7,d2 bne.s loc_72746 move.b d1,($A04001).l rts ; End of function WriteFMI ; =========================================================================== loc_7275A: ; XREF: WriteFMIorII move.b 1(a5),d2 bclr #2,d2 add.b d2,d0 ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| ; Stangely, this is the type 1a version with some nops added. ; sub_72764: WriteFMII: ; XREF: loc_71E6A; Sound_ChkValue; sub_7256A; WriteFMII move.b ($A04000).l,d2 btst #7,d2 bne.s WriteFMII move.b d0,($A04002).l nop nop nop loc_7277C: move.b ($A04000).l,d2 btst #7,d2 bne.s loc_7277C move.b d1,($A04003).l rts ; End of function WriteFMII Remove all those "nops." Now we might've saved some space, but we can take this further. Replace the above code with this: Code (Text): WriteFMI: ; XREF: loc_71E6A lea ($A04000).l,a0 - btst #7,(a0) bne.s - move.b d0,(a0) - btst #7,(a0) bne.s - move.b d1,1(a0) rts ; End of function WriteFMI ; =========================================================================== loc_7275A: ; XREF: WriteFMIorII move.b 1(a5),d2 bclr #2,d2 add.b d2,d0 ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| ; sub_72764: WriteFMII: ; XREF: loc_71E6A; Sound_ChkValue; sub_7256A; WriteFMII lea ($A04000).l,a0 - btst #7,(a0) bne.s - move.b d0,2(a0) - btst #7,(a0) bne.s - move.b d1,3(a0) rts ; End of function WriteFMII This is from Golden Axe II (minus the "nop"), which also uses the Type 1b driver. And there we go, we just optimized the driver a bit! Remove Sega Z80 Code Spoiler This should only be done if you've followed this guide. Because the Sega PCM is now being played on the 68k side, the Z80 code is useless now. In z80.asm, find this piece of code: Code (Text): ld a,zmake68kBank(SegaPCM)&1 ; least significant bit from ROM bank ID ld (zBankRegister),a ; Latch it to bank register, initializing bank switch ld b,8 ; Number of bits to latch to ROM bank ld a,zmake68kBank(SegaPCM)>>1 ; Bank ID without the least significant bit Delete it since it's no-longer needed. Not far below, you'll find this: Code (Text): cp 6 ; Is the sample 87h or higher? jp nc,zPlay_SegaPCM ; If yes, branch Delete it too. Finally, delete all of zPlay_SegaPCM. Fix the Third Sound Queue Spoiler In Sonic 1 there's a third unused sound-queue. Why is it unused? It's because a bug in the Sound Driver prevents it from working. Might as-well fix it. At loc_71BB2 change the "tst.w $A(a6)" to a long-word. Then at InitMusicPlayback change "move.w $A(a6),d5" a long-word. Finally right below that you'll see "move.w d5,$A(a6)," change that to a long-word too. Remove Bizzare Checks Spoiler At "PlaySoundByIndex" you'll see this: Code (Text): PlaySoundByIndex: moveq #0,d7 move.b 9(a6),d7 beq.w StopSoundAndMusic bpl.s locret_71F8C move.b #$80,9(a6) ; reset music flag cmpi.b #MusID__End+$B,d7 bls.w PlayMusic ; music $81-$9F cmpi.b #SndID__First,d7 ; is it after MusID__End but before SndID__First? (redundant) bcs.w locret_71F8C cmpi.b #SndID__End,d7 bls.w PlaySound_CheckRing ; sound $A0-$CF cmpi.b #SpeSndID__First,d7 ; is it after SndID__End but before SpecSndID__First? (redundant) bcs.w locret_71F8C cmpi.b #SpeSndID__End+$F,d7 bcs.w PlaySound_CheckWaterfall ; sound $D0-$DF cmpi.b #CmdID__End,d7 bls.s PlaySound_Effects ; sound $E0-$E4 locret_71F8C: rts Change it to this: Code (Text): moveq #0,d7 move.b 9(a6),d7 beq.w StopSoundAndMusic bpl.s locret_71F8C move.b #$80,9(a6) ; reset music flag cmpi.b #MusID__End+$B,d7 bls.w PlayMusic ; music $81-$9F bcs.w locret_71F8C cmpi.b #SndID__End,d7 bls.w PlaySound_CheckRing ; sound $A0-$CF bcs.w locret_71F8C cmpi.b #SpeSndID__End+$F,d7 bcs.w PlaySound_CheckWaterfall ; sound $D0-$DF cmpi.b #CmdID__End,d7 bls.s PlaySound_Effects ; sound $E0-$E4 locret_71F8C: rts For some reason the developers added checks to see if there's any slots between $9F-$A0, and $CF-$D0, which is impossible. Add PlaySound_Local from Sonic 2 Spoiler In Sonic 2, a special function which makes a sound play ONLY, if an object's on-screen. Thankfully this is pretty easy to add. Above PlaySound, add this: Code (Text): ; --------------------------------------------------------------------------- ; Subroutine to play a sound or music track if on-screen ; --------------------------------------------------------------------------- ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| PlaySound_Local: tst.b 1(a0) bpl.s + Then, right before the "rts" in PlaySound, add a +. EDIT: Updated labels
While these changes are nice and all, honestly, I disagree with this "making the driver good", as it only applies a few speed optimizations and a bug fix here and there. The Sonic 1 sound driver is pretty much filled to the brim with silly bugs and oddities that should be fixed in order to be qualified as at least decent, in my opinion. See this for a taste.
Possibly mostly with its music, considering Music Tracks aren't in banks, meaning music can be added easily.
Fading Not Clearing All Variables Spoiler As documented in the Github disassembly, $E4 doesn't clear the last 10 bytes of the track data. To fix this, at StopSoundAndMusic, change this line: Code (Text): move.w #$E3,d0 To this: Code (Text): move.w #$F3,d0 SendPSGNoteOff Bug Spoiler If InitMusicPlayback doesn't clear all the channels, there's a chance that random noises will be played. To fix this, right above locret_729B4, add these lines: Code (Text): cmpi.b #$DF,d0 ; Are stopping PSG3? bne.s locret_729B4 move.b #$FF,($C00011).l ; If so, stop noise channel while we're at it This code were backported from the S3K driver, which fixed the issue. Halted Volume Updates Spoiler There's a issue that prevents future volume updates, which can break fading. To fix this at VolEnvHold, change these lines: Code (Text): subq.b #1,$C(a5) rts To this: Code (Text): subq.b #1,$C(a5) subq.b #1,$C(a5) jsr loc_7292E These were also backported from the S3K driver. EDIT: Updated labels.