Expand the music index to start at $00 instead of $80
From Sonic Retro
(Original guide by HPZMan)
(S2 addition by Clownacy)
Note for Sonic 1: If you’re going to use all sound slots in Sonic 1, refer to this guide here for a newer method. - JGMR
Here's a easy way on how to use all slots from $00 to $FF on the Sonic 1 M68K Sound Driver and Sonic 2 Z80 Sound Driver.
Sonic 1
Some notes:
- After the changes, the addresses $FFFFFFFC and $FFFFFFFD will be used. Technically, it aren't new slots. Instead of this, it is a duplication from the slots $80 using a unique different index.
Slots $00 to $7F
Make a search for PlaySound:. You will see this:
PlaySound:
move.b d0,($FFFFF00A).w
rts
Change to this:
PlaySound:
cmpi.b #$7F,d0
ble.s ChkSounds00to7F
jmp NormalSoundRequest
ChkSounds00to7F:
cmpi.b #$01,d0
bge.s LoadSlots00to7F
jmp NormalSoundRequest
LoadSlots00to7F:
add.b #$80,d0; Add $80 to get slot to starts at $81
move.b #$01,($FFFFFFFC).w; Move $01 to $FFFFFC to make sound driver to load the secound index
NormalSoundRequest:
move.b d0,($FFFFF00A).w
rts
Make a search for PlaySound_Special:
You can see this:
PlaySound_Special:
move.b d0,($FFFFF00B).w
rts
Change to this:
PlaySound_Special:
cmpi.b #$7F,d0
ble.s ChkSounds00to7F_Special
jmp NormalSoundRequest_Special
ChkSounds00to7F_Special:
cmpi.b #$01,d0
bge.s LoadSlots00to7F_Special
jmp NormalSoundRequest_Special
LoadSlots00to7F_Special:
add.b #$80,d0; Add $80 to get slot to starts at $81
move.b #$01,($FFFFFFFC).w; Move $01 to $FFFFFC to make the sound driver to load the secound index
NormalSoundRequest_Special:
move.b d0,($FFFFF00B).w
rts
Search for loc_7202C:, you will see this:
loc_7202C:
jsr sub_725CA(pc)
movea.l (off_719A0).l,a4
subi.b #$81,d7
move.b (a4,d7.w),$29(a6)
movea.l (Go_MusicIndex).l,a4
Change to this:
loc_7202C:
jsr sub_725CA(pc)
movea.l (off_719A0).l,a4
subi.b #$81,d7
move.b (a4,d7.w),$29(a6)
movea.l (Go_MusicIndex).l,a4
cmpi.b #$01,($FFFFFFFD).w
bne.s CheckSounds00to80
movea.l (Go_MusicIndexFF).l,a4
jmp NormalIndexLoad
CheckSounds00to80:
cmpi.b #$01,($FFFFFFFC).w
bne.s NormalIndexLoad
movea.l (Go_MusicIndex00).l,a4
NormalIndexLoad:
clr.w ($FFFFFFFC).w
Search for Go_MusicIndex:, you can see this:
Go_MusicIndex: dc.l MusicIndex; XREF: Sound_81to9F
Below the Go_MusicIndex: code, add this:
Go_MusicIndex00: dc.l MusicIndex00
Go_MusicIndexFF: dc.l MusicIndexFF
Slots $E5 to $FF
Search for Sound_ChkValue:, you will see this:
Sound_ChkValue:; XREF: sub_71B4C
moveq #0,d7
move.b 9(a6),d7
beq.w Sound_E4
bpl.s locret_71F8C
move.b #$80,9(a6); reset music flag
cmpi.b #$9F,d7
bls.w Sound_81to9F; music $81-$9F
cmpi.b #$A0,d7
bcs.w locret_71F8C
cmpi.b #$CF,d7
bls.w Sound_A0toCF; sound $A0-$CF
cmpi.b #$D0,d7
bcs.w locret_71F8C
cmpi.b #$E0,d7
bcs.w Sound_D0toDF; sound $D0-$DF
cmpi.b #$E4,d7
bls.s Sound_E0toE4; sound $E0-$E4
locret_71F8C:
rts
Change to this:
Sound_ChkValue:; XREF: sub_71B4C
moveq #0,d7
move.b 9(a6),d7
beq.w Sound_E4
bpl.s locret_71F8C
move.b #$80,9(a6); reset music flag
cmpi.b #$01,($FFFFFFFC).w
bne.s Load81to9F
jmp Sound_ChkValueFor00
Load81to9F:
cmpi.b #$9F,d7
bls.w Sound_81to9F; music $81-$9F
ContinueSound_ChkValue:
cmpi.b #$A0,d7
bcs.w locret_71F8C
cmpi.b #$CF,d7
bls.w Sound_A0toCF; sound $A0-$CF
cmpi.b #$D0,d7
bcs.w locret_71F8C
cmpi.b #$E0,d7
bcs.w Sound_D0toDF; sound $D0-$DF
cmpi.b #$E4,d7
bls.s Sound_E0toE4; sound $E0-$E4
cmpi.b #$FF,d7
bls.w Sound_E5toFF
locret_71F8C:
rts
Search for Sound_81to9F: and above Sound_81to9F, add this:
Sound_ChkValueFor00:
cmpi.b #$FF,d7; $FF = Last slot for musics in index $00 - $7F ($FF = $7F)
bls.w Sound_81to9F
rts
Sound_E5toFF:
move.b #$01,($FFFFFFFD).w
sub.b #$64,d7
Inserting new songs
Now you just need to create the pointers for the songs at the index, and include them! To do it for the songs $01 to $7F, create in some place a index called MusicIndex00:. The index have to work like this:
MusicIndex00:
dc.l Music01; Music for slot $01
dc.l Music02; Music for slot $02
......
To the songs $E5 to $FF, create in some place a index called MusicIndexFF. The index have to work like this:
MusicIndexFF:
dc.l MusicE5; Music for slot $E5
dc.l MusicE6; Music for slot $E6
......
Making the Sound Test values to start at $00
Search for loc_3550:, you will see this:
addi.w #$80,d0
Remove or comment this line.
Make a search for LevelSelect:, below from this you can see:
addi.w #$80,d0
Remove or comment this line.
Search for LevSel_Right:, above it you will see this:
bcc.s LevSel_Right
moveq #$4F,d0; if sound test moves below 0, set to $4F
Change or comment these lines.
Search for LevSel_Refresh2:, above it you will see this:
cmpi.w #$50,d0
bcs.s LevSel_Refresh2
moveq #0,d0; if sound test moves above $4F, set to 0
Remove or comment these lines.
Fixing possible problems with sound effects and songs
Go to SoundTypes:, you can see this:
SoundTypes: dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $80
dc.b $70, $70, $70, $70, $70, $70, $70, $70, $70, $68, $70, $70, $70, $60, $70, $70
dc.b $60, $70, $60, $70, $70, $70, $70, $70, $70, $70, $70, $70, $70, $70, $7F, $60
dc.b $70, $70, $70, $70, $70, $70, $70, $70, $70, $70, $70, $70, $70, $70, $70, $80
dc.b $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $90
dc.b $90, $90, $90, $90
Change to this:
SoundTypes: dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
dc.b $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90, $90
It should fix possible problems on play songs/sound effects and will not interfere the original songs and sound effects.
Optional - Putting the default Sonic 1 songs at the $0X slots index
Go to the index for songs $8X, MusicIndex.
Copy the pointers from it, remove them and paste it at the begin from the $0X slot index MusicIndex00.
Done.
Sonic 2
Relocating the silence value
Open s2.sounddriver.asm, and go to zUpdateEverything. There, you'll find this:
; Apparently if this is 80h, it does not play anything new,
; otherwise it cues up the next play (flag from 68K for new item)
ld a, (zQueueToPlay)
cp 80h
call nz,zPlaySoundByIndex ; If not 80h, we need to play something new!
As you can tell by the comments, you need to change the cp's value from 80h to 0. But wait! It's better to use an 'or a', which does the same thing, but is faster and smaller. Doing that will give you this:
; Apparently if this is 00h, it does not play anything new,
; otherwise it cues up the next play (flag from 68K for new item)
ld a, (zQueueToPlay)
or a
call nz,zPlaySoundByIndex ; If not 00h, we need to play something new!
Next up, zCycleQueue. Here, we face the same problem: a 'cp 80h'. Again, change it to an 'or a'.
zPlaySoundByIndex. This one's interesting. Here, you can see how, if sound 00h were to be played, the driver would reset itself. This is likely part of its initialisation process, where, initially, sound 00h would technically be queued. We'll have to remove this, but this shouldn't be an issue, as the same reset code is branched to at the Z80's Entry Point. This check is just a leftover from the original Sonic 1 driver, and is now redundant.
Just remove everything until 'ld (ix+8),80h'. Also, change the '80h' in this instruction to '0'. However, if you don't intend for your music IDs to start at 01h, the ID immediately after the silence value, then you'll want to keep the 'cp MusID__First' and 'ret c' instructions, in order to prevent crashes when invalid sounds are played.
zPlaySegaSound. This features a little optimisation we'll have to deal with: instead of a straightforward 'cp 80h', 80h is moved to a register, and that register is used instead. Understandable, since a low cycle count is a necessity for PCM streaming. In fact, a 'cp r' is just as small and just as fast as an 'or a'.
There are two instances of 'ld c,80h', the second one is what we're looking for. Again, you could just move 0 to the register, but while we can't optimise the loop itself, we can slightly optimise the code that sets up the loop. So, remove this instruction. Inside the loop, you'll find 'cp c'. Change this to 'or a'.
zClearTrackPlaybackMem. Here, zQueueToPlay is set to 80h. We don't want that, so change 'ld a,80h' into 'xor a'. Again, instead of 'ld a,0', we're using a smaller and faster way of doing the same thing. Do this at zInitMusicPlayback, also.
That's all for s2.sounddriver.asm. Now, onto s2.asm.
Got to sndDriverInput, and find 'cmpi.b #$80,8(a1)'. Change it to 'tst.b 8(a1)'.
And with that, you're done. As you've seen earlier, even before making the silence sound occupy it, sound 00h was unusable, so in merging the two, we've also freed up a sound ID. Bonus! Now you're free to move your sound IDs to occupy the >80h range of slots, and you don't have to worry about sound 80h, so you can have a song or an SFX occupy it with no ill effects!
But we're not done yet. If you're going to extend your sound IDs into the >80h range, then you'll likely want your sound tests to cover that range, too.
Extending the sound tests
We'll start with the level select's sound test. Go to LevSelControls_CheckLR and remove these two lines:
bcc.s +
moveq #$7F,d0
Then remove these three:
cmpi.w #$80,d0
blo.s +
moveq #0,d0
Then change this...
btst #button_A,d1
beq.s +
addi.b #$10,d0
andi.b #$7F,d0
+
...into this:
btst #button_A,d1
beq.s +
addi.b #$10,d0
bcc.s +
moveq #0,d0
+
And remove this:
addi.w #$80,d0
That's that sound test done. Onto the options menu's sound test.
Go to OptionScreen_Controls, and change this...
btst #button_A,d0
beq.s +
addi.b #$10,d2
cmp.b d3,d2
bls.s +
moveq #0,d2
+
...into this:
cmpi.b #2,(Options_menu_box).w
bne.s + ; rts
btst #button_A,d0
beq.s +
addi.b #$10,d2
bcc.s +
moveq #0,d2
+
Under that, remove this:
addi.w #$80,d0
Then go to OptionScreen_Choices, and change this...
dc.l ($80-1)<<24
...into:
dc.l $FF<<24
Conclusion
With that, we've removed the obstacle of the silence value's placement, freed up a sound ID, optimised the driver's code a little (in both size and speed), and extended the sound tests. All that's left to do is lift the '20h music files per bank' cap.
|Expand the music index to start at $00 instead of $80]]