Actions

SCHG How-to

SCHG How-to:Port Flamewing's Sonic 3 & Knuckles Sound Driver

From Sonic Retro

(Original guide by KZG4)

NOTE: This guide is heavily incomplete and will not work in its current state. If you want to port the Sonic 3 sound driver into Sonic 1, please refer to this guide here. For Sonic 2, go here. These guides should be complete and more up to date. - JGMR

Step 1: Resources

First you need the following:


Step 2: Setup

Make a new .asm files called 'Macros.asm' and include it in your disasm's "_inc" folder. Put this code in the file:

; ---------------------------------------------------------------------------
; Align and pad
; input: length to align to, value to use as padding (default is 0)
; ---------------------------------------------------------------------------

align:	macro
	if (narg=1)
	dcb.b \1-(*%\1),0
	else
	dcb.b \1-(*%\1),\2
	endc
	endm

; ---------------------------------------------------------------------------
; Set a VRAM address via the VDP control port.
; input: 16-bit VRAM address, control port (default is ($C00004).l)
; ---------------------------------------------------------------------------

locVRAM:	macro loc,controlport
		if (narg=1)
		move.l	#($40000000+((loc&$3FFF)<<16)+((loc&$C000)>>14)),($C00004).l
		else
		move.l	#($40000000+((loc&$3FFF)<<16)+((loc&$C000)>>14)),controlport
		endc
		endm

; ---------------------------------------------------------------------------
; DMA copy data from 68K (ROM/RAM) to the VRAM
; input: source, length, destination
; ---------------------------------------------------------------------------

writeVRAM:	macro
		lea	(vdp_control_port).l,a5
		move.l	#$94000000+(((\2>>1)&$FF00)<<8)+$9300+((\2>>1)&$FF),(a5)
		move.l	#$96000000+(((\1>>1)&$FF00)<<8)+$9500+((\1>>1)&$FF),(a5)
		move.w	#$9700+((((\1>>1)&$FF0000)>>16)&$7F),(a5)
		move.w	#$4000+(\3&$3FFF),(a5)
		move.w	#$80+((\3&$C000)>>14),(v_vdp_buffer2).w
		move.w	(v_vdp_buffer2).w,(a5)
		endm

; ---------------------------------------------------------------------------
; DMA copy data from 68K (ROM/RAM) to the CRAM
; input: source, length, destination
; ---------------------------------------------------------------------------

writeCRAM:	macro
		lea	(vdp_control_port).l,a5
		move.l	#$94000000+(((\2>>1)&$FF00)<<8)+$9300+((\2>>1)&$FF),(a5)
		move.l	#$96000000+(((\1>>1)&$FF00)<<8)+$9500+((\1>>1)&$FF),(a5)
		move.w	#$9700+((((\1>>1)&$FF0000)>>16)&$7F),(a5)
		move.w	#$C000+(\3&$3FFF),(a5)
		move.w	#$80+((\3&$C000)>>14),(v_vdp_buffer2).w
		move.w	(v_vdp_buffer2).w,(a5)
		endm
; ---------------------------------------------------------------------------
; stop the Z80
; ---------------------------------------------------------------------------

stopZ80:	macro
		move.w	#$100,($A11100).l
@wait:	btst	#0,($A11100).l
		bne.s	@wait
		endm
; ---------------------------------------------------------------------------
; wait for Z80 to stop
; ---------------------------------------------------------------------------

waitZ80:	macro
	@wait:	btst	#0,($A11100).l
		bne.s	@wait
		endm
		
stopZ80a:	macro
		move.w	#$100,($A11100).l
		endm
; ---------------------------------------------------------------------------
; reset the Z80
; ---------------------------------------------------------------------------

resetZ80:	macro
		move.w	#$100,($A11200).l
		endm

resetZ80a:	macro
		move.w	#0,($A11200).l
		endm

; ---------------------------------------------------------------------------
; start the Z80
; ---------------------------------------------------------------------------

startZ80:	macro
		move.w	#0,($A11100).l
		endm

; ---------------------------------------------------------------------------
; disable interrupts
; ---------------------------------------------------------------------------

disable_ints:	macro
		move	#$2700,sr
		endm

; ---------------------------------------------------------------------------
; enable interrupts
; ---------------------------------------------------------------------------

enable_ints:	macro
		move	#$2300,sr
		endm

; ---------------------------------------------------------------------------
; play a sound effect or music
; input: track, terminate routine (leave blank to not terminate)
; ---------------------------------------------------------------------------

music:		macro track,terminate
		move.w	#track,d0
		if (narg=1)
		jsr	(PlaySound).l
		else
		jmp	(PlaySound).l
		endc
		endm

sfx:		macro track,terminate
		move.w	#track,d0
		if (narg=1)
		jsr	(PlaySound_Special).l
		else
		jmp	(PlaySound_Special).l
		endc
		endm

This code adds some macros that the S3K driver uses.

Now, at the top of your disasm (before StartOfROM:) add this:

                include	'_inc/Macros.asm'

This will include the macros into the code.

Now, find loc_b5e. It should look like this:

loc_B5E:				; XREF: loc_B88
		jsr	sub_71B4C

Replace it with this:

loc_B5E:				; XREF: loc_B88
		nop

Next, find loc_119E. It should look like this:

loc_119E:				; XREF: PalToCRAM
		clr.b	($FFFFF64F).w
		movem.l	d0-a6,-(sp)
		bsr.w	Demo_Time
		jsr	sub_71B4C
		movem.l	(sp)+,d0-a6
		rte

Replace it with this:

loc_119E:				; XREF: PalToCRAM
		clr.b	($FFFFF64F).w
		movem.l	d0-a6,-(sp)
		jsr	Demo_Time
		nop
loc_4862:                               ; CODE XREF: ROM:00004846�j
		movem.l	(sp)+,d0-a6
		rte		
; End of function PalToCRAM

Step 3: Removing the Sonic 1 Sound Driver

First, We need to locate the label "Go_SoundTypes:" in Sonic1.asm Delete all the code from Go_SoundTypes: until EndOfRom:

Then, Empty out the "sound" folder in your disasm. Replace it's contents with the contents of the S3K Driver zip.

Step 4: Inserting the Sonic 3K Sound Driver

After you have removed the Sonic 1 Sound Driver, Locate the SoundDriverLoad Routine. The routine will look like 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
		rts	
; End of function SoundDriverLoad

Now, replace this routine with this:

SoundDriverLoad:            ; XREF: GameClrRAM; TitleScreen
LoadZ80drv:
		nop
		stopZ80a
		resetZ80
		lea	(RomEndLoc).l,a0
		move.l	(a0),d0
		addq.l	#1,d0
		movea.l	d0,a0
		lea	($A00000).l,a1
		jsr   KosDec
 		lea	(DriverResetData).l,a0
		lea	($A01C1A).l,a1									; z80 ram start of variables (A01C00 in older version)
		move.w	#DriverResetDataEnd-DriverResetData,d0

DriverResetDataLoadLoop:
		move.b	(a0)+,(a1)+
		dbf	d0,DriverResetDataLoadLoop
	        btst	#0,($C00005).l	; check video mode
		sne		($A01C8C).l          					; set PAL mode flag

		resetZ80a
		nop
		nop	
		nop	
		nop	
		resetZ80
		startZ80
		rts
; End of function SoundDriverLoad
 
DriverResetData:
		dc.b	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DriverResetDataEnd:

Locate "Playsound:". It and the routines surrounding it should look like this:

; ---------------------------------------------------------------------------
; Subroutine to	play a sound or	music track
; ---------------------------------------------------------------------------

; ||||||||||||||| S U B	R O U T	I N E |||||||||||||||||||||||||||||||||||||||


PlaySound:
		move.b	d0,($FFFFF00A).w
		rts	
; End of function PlaySound

; ---------------------------------------------------------------------------
; Subroutine to	play a special sound/music (E0-E4)
;
; E0 - Fade out
; E1 - Sega
; E2 - Speed up
; E3 - Normal speed
; E4 - Stop
; ---------------------------------------------------------------------------

; ||||||||||||||| S U B	R O U T	I N E |||||||||||||||||||||||||||||||||||||||


PlaySound_Special:
		move.b	d0,($FFFFF00B).w
		rts	
; End of function PlaySound_Special

; ===========================================================================
; ---------------------------------------------------------------------------
; Unused sound/music subroutine
; ---------------------------------------------------------------------------

PlaySound_Unk:
		move.b	d0,($FFFFF00C).w
		rts

Replace all of those routines with these:

; ---------------------------------------------------------------------------
; Z80 Driver PlaySound
; ---------------------------------------------------------------------------


PlaySound:
		stopZ80
		move.b	d0,($A01C94).l
		startZ80
		rts
; End of function PlaySound


; ---------------------------------------------------------------------------
; Unused sound/music subroutine
; ---------------------------------------------------------------------------
 
PlaySound_Unk:
		nop
; ---------------------------------------------------------------------------
; Subroutine to	play a special sound/music (FB-FF)
; ---------------------------------------------------------------------------

PlaySound_Special:
		stopZ80
		cmp.b	($A01C95).l,d0
		beq.s	PlaySound_Special1
		tst.b	($A01C95).l
		bne.s	PlaySound_Special0
		move.b	d0,($A01C95).l
		startZ80
		rts

PlaySound_Special0:
		move.b	d0,($A01C96).l

PlaySound_Special1:
		startZ80

SkipPlaySound_Special:
		rts
; End of function PlaySound_Special
 
; ---------------------------------------------------------------------------
; Subroutine to change the music tempo
; ---------------------------------------------------------------------------

SetTempo:
		stopZ80
		move.b	D0,($A01C92).l
		startZ80
		rts

Add the contents of BuildToolsS1S3K.zip into the sound folder of your disasm.

Step 5: Modifying Build.bat

Now, we need to modify build.bat to build both the s3k driver and the main game code.

It will normally look like this:

@echo off
rem include.exe sonic1.asm s1comb.asm

REM ::: automatic recompression of data - disabled by default because it's slow
REM ::: remove "REM" from the lines below to re-enable it
REM derecmp.exe nc artnem_u artnem
REM derecmp.exe kc artkos_u artkos
REM derecmp.exe ec mapeni_u mapeni
REM derecmp.exe ec map16_u map16
REM derecmp.exe kc map256_u map256
REM derecmp.exe ec sslay_u sslayout

rem snasm68k.exe -emax 0 -p -o ae- s1comb.asm, s1built.bin
asm68k /o op+ /o os+ /o ow+ /o oz+ /o oaq+ /o osq+ /o omq+ /p /o ae- sonic1.asm, s1built.bin
rompad.exe s1built.bin 255 0
fixheadr.exe s1built.bin
pause

Replace the contents with this:

@echo off
asm68k /k /o op+ /o os+ /o ow+ /o oz+ /o oaq+ /o osq+ /o omq+ /p /o ae- sonic1.asm, s1built.bin >errors.txt, sonic1.lst

cd Sound
build.bat

cd ..

rem rompad.exe s1built.bin 255 0
rem fixheadr.exe s1built.bin
pause

Now the rom will build correctly.

Step 6: Changing SFX

SFX and music Will not play correctly due to the sounds not being at the same values as Sonic 1. This is easy to fix. Go into "Z80 Sound Driver.asm" In your "sound" folder. Locate this:

SEGA_PCM:	binclude "Sound/Sega PCM.bin"
SEGA_PCM_End
		even
Sound_33:	include "Sound/SFX/33.asm"
Sound_34:	include "Sound/SFX/34.asm"
Sound_35:	include "Sound/SFX/35.asm"
Sound_36:	include "Sound/SFX/36.asm"
Sound_37:	include "Sound/SFX/37.asm"
Sound_38:	include "Sound/SFX/38.asm"
Sound_39:	include "Sound/SFX/39.asm"
Sound_3A:	include "Sound/SFX/3A.asm"
Sound_3B:	include "Sound/SFX/3B.asm"
Sound_3C:	include "Sound/SFX/3C.asm"
Sound_3D:	include "Sound/SFX/3D.asm"
Sound_3E:	include "Sound/SFX/3E.asm"
Sound_3F:	include "Sound/SFX/3F.asm"
Sound_40:	include "Sound/SFX/40.asm"
Sound_41:	include "Sound/SFX/41.asm"
Sound_42:	include "Sound/SFX/42.asm"
Sound_43:	include "Sound/SFX/43.asm"
Sound_44:	include "Sound/SFX/44.asm"
Sound_45:	include "Sound/SFX/45.asm"
Sound_46:	include "Sound/SFX/46.asm"
Sound_47:	include "Sound/SFX/47.asm"
Sound_48:	include "Sound/SFX/48.asm"
Sound_49:	include "Sound/SFX/49.asm"
Sound_4A:	include "Sound/SFX/4A.asm"
Sound_4B:	include "Sound/SFX/4B.asm"
Sound_4C:	include "Sound/SFX/4C.asm"
Sound_4D:	include "Sound/SFX/4D.asm"
Sound_4E:	include "Sound/SFX/4E.asm"
Sound_4F:	include "Sound/SFX/4F.asm"
Sound_50:	include "Sound/SFX/50.asm"
Sound_51:	include "Sound/SFX/51.asm"
Sound_52:	include "Sound/SFX/52.asm"
Sound_53:	include "Sound/SFX/53.asm"
Sound_54:	include "Sound/SFX/54.asm"
Sound_55:	include "Sound/SFX/55.asm"
Sound_56:	include "Sound/SFX/56.asm"
Sound_57:	include "Sound/SFX/57.asm"
Sound_58:	include "Sound/SFX/58.asm"
Sound_59:	include "Sound/SFX/59.asm"
Sound_5A:	include "Sound/SFX/5A.asm"
Sound_5B:	include "Sound/SFX/5B.asm"
Sound_5C:	include "Sound/SFX/5C.asm"
Sound_5D:	include "Sound/SFX/5D.asm"
Sound_5E:	include "Sound/SFX/5E.asm"
Sound_5F:	include "Sound/SFX/5F.asm"
Sound_60:	include "Sound/SFX/60.asm"
Sound_61:	include "Sound/SFX/61.asm"
Sound_62:	include "Sound/SFX/62.asm"
Sound_63:	include "Sound/SFX/63.asm"
Sound_64:	include "Sound/SFX/64.asm"
Sound_65:	include "Sound/SFX/65.asm"
Sound_66:	include "Sound/SFX/66.asm"
Sound_67:	include "Sound/SFX/67.asm"
Sound_68:	include "Sound/SFX/68.asm"
Sound_69:	include "Sound/SFX/69.asm"
Sound_6A:	include "Sound/SFX/6A.asm"
Sound_6B:	include "Sound/SFX/6B.asm"
Sound_6C:	include "Sound/SFX/6C.asm"
Sound_6D:	include "Sound/SFX/6D.asm"
Sound_6E:	include "Sound/SFX/6E.asm"
Sound_6F:	include "Sound/SFX/6F.asm"
Sound_70:	include "Sound/SFX/70.asm"
Sound_71:	include "Sound/SFX/71.asm"
Sound_72:	include "Sound/SFX/72.asm"
Sound_73:	include "Sound/SFX/73.asm"
Sound_74:	include "Sound/SFX/74.asm"
Sound_75:	include "Sound/SFX/75.asm"
Sound_76:	include "Sound/SFX/76.asm"
Sound_77:	include "Sound/SFX/77.asm"
Sound_78:	include "Sound/SFX/78.asm"
Sound_79:	include "Sound/SFX/79.asm"
Sound_7A:	include "Sound/SFX/7A.asm"
Sound_7B:	include "Sound/SFX/7B.asm"
Sound_7C:	include "Sound/SFX/7C.asm"
Sound_7D:	include "Sound/SFX/7D.asm"
Sound_7E:	include "Sound/SFX/7E.asm"
Sound_7F:	include "Sound/SFX/7F.asm"
Sound_80:	include "Sound/SFX/80.asm"
Sound_81:	include "Sound/SFX/81.asm"
Sound_82:	include "Sound/SFX/82.asm"
Sound_83:	include "Sound/SFX/83.asm"
Sound_84:	include "Sound/SFX/84.asm"
Sound_85:	include "Sound/SFX/85.asm"
Sound_86:	include "Sound/SFX/86.asm"
Sound_87:	include "Sound/SFX/87.asm"
Sound_88:	include "Sound/SFX/88.asm"
Sound_89:	include "Sound/SFX/89.asm"
Sound_8A:	include "Sound/SFX/8A.asm"
Sound_8B:	include "Sound/SFX/8B.asm"
Sound_8C:	include "Sound/SFX/8C.asm"
Sound_8D:	include "Sound/SFX/8D.asm"
Sound_8E:	include "Sound/SFX/8E.asm"
Sound_8F:	include "Sound/SFX/8F.asm"
Sound_90:	include "Sound/SFX/90.asm"
Sound_91:	include "Sound/SFX/91.asm"
Sound_92:	include "Sound/SFX/92.asm"
Sound_93:	include "Sound/SFX/93.asm"
Sound_94:	include "Sound/SFX/94.asm"
Sound_95:	include "Sound/SFX/95.asm"
Sound_96:	include "Sound/SFX/96.asm"
Sound_97:	include "Sound/SFX/97.asm"
Sound_98:	include "Sound/SFX/98.asm"
Sound_99:	include "Sound/SFX/99.asm"
Sound_9A:	include "Sound/SFX/9A.asm"
Sound_9B:	include "Sound/SFX/9B.asm"
Sound_9C:	include "Sound/SFX/9C.asm"
Sound_9D:	include "Sound/SFX/9D.asm"
Sound_9E:	include "Sound/SFX/9E.asm"
Sound_9F:	include "Sound/SFX/9F.asm"
Sound_A0:	include "Sound/SFX/A0.asm"
Sound_A1:	include "Sound/SFX/A1.asm"
Sound_A2:	include "Sound/SFX/A2.asm"
Sound_A3:	include "Sound/SFX/A3.asm"
Sound_A4:	include "Sound/SFX/A4.asm"
Sound_A5:	include "Sound/SFX/A5.asm"
Sound_A6:	include "Sound/SFX/A6.asm"
Sound_A7:	include "Sound/SFX/A7.asm"
Sound_A8:	include "Sound/SFX/A8.asm"
Sound_A9:	include "Sound/SFX/A9.asm"
Sound_AA:	include "Sound/SFX/AA.asm"
Sound_AB:	include "Sound/SFX/AB.asm"
Sound_AC:	include "Sound/SFX/AC.asm"
Sound_AD:	include "Sound/SFX/AD.asm"
Sound_AE:	include "Sound/SFX/AE.asm"
Sound_AF:	include "Sound/SFX/AF.asm"
Sound_B0:	include "Sound/SFX/B0.asm"
Sound_B1:	include "Sound/SFX/B1.asm"
Sound_B2:	include "Sound/SFX/B2.asm"
Sound_B3:	include "Sound/SFX/B3.asm"
Sound_B4:	include "Sound/SFX/B4.asm"
Sound_B5:	include "Sound/SFX/B5.asm"
Sound_B6:	include "Sound/SFX/B6.asm"
Sound_B7:	include "Sound/SFX/B7.asm"
Sound_B8:	include "Sound/SFX/B8.asm"
Sound_B9:	include "Sound/SFX/B9.asm"
Sound_BA:	include "Sound/SFX/BA.asm"
Sound_BB:	include "Sound/SFX/BB.asm"
Sound_BC:	include "Sound/SFX/BC.asm"
Sound_BD:	include "Sound/SFX/BD.asm"
Sound_BE:	include "Sound/SFX/BE.asm"
Sound_BF:	include "Sound/SFX/BF.asm"
Sound_C0:	include "Sound/SFX/C0.asm"
Sound_C1:	include "Sound/SFX/C1.asm"
Sound_C2:	include "Sound/SFX/C2.asm"
Sound_C3:	include "Sound/SFX/C3.asm"
Sound_C4:	include "Sound/SFX/C4.asm"
Sound_C5:	include "Sound/SFX/C5.asm"
Sound_C6:	include "Sound/SFX/C6.asm"
Sound_C7:	include "Sound/SFX/C7.asm"
Sound_C8:	include "Sound/SFX/C8.asm"
Sound_C9:	include "Sound/SFX/C9.asm"
Sound_CA:	include "Sound/SFX/CA.asm"
Sound_CB:	include "Sound/SFX/CB.asm"
Sound_CC:	include "Sound/SFX/CC.asm"
Sound_CD:	include "Sound/SFX/CD.asm"
Sound_CE:	include "Sound/SFX/CE.asm"
Sound_CF:	include "Sound/SFX/CF.asm"
Sound_D0:	include "Sound/SFX/D0.asm"
Sound_D1:	include "Sound/SFX/D1.asm"
Sound_D2:	include "Sound/SFX/D2.asm"
Sound_D3:	include "Sound/SFX/D3.asm"
Sound_D4:	include "Sound/SFX/D4.asm"
Sound_D5:	include "Sound/SFX/D5.asm"
Sound_D6:	include "Sound/SFX/D6.asm"
Sound_D7:	include "Sound/SFX/D7.asm"
Sound_D8:	include "Sound/SFX/D8.asm"
Sound_D9:	include "Sound/SFX/D9.asm"
Sound_DA:	include "Sound/SFX/DA.asm"
Sound_DB:	include "Sound/SFX/DB.asm"

	finishBank

Replace It with this:

SEGA_PCM:	binclude "Sound/Sega PCM.bin"
SEGA_PCM_End
		even
Sound_33:	include "SK/SFX/33.asm"
Sound_34:	include "SK/SFX/34.asm"
Sound_35:	include "SK/SFX/35.asm"
Sound_36:	include "SK/SFX/36.asm"
Sound_37:	include "SK/SFX/37.asm"
Sound_38:	include "SK/SFX/38.asm"
Sound_39:	include "SK/SFX/39.asm"
Sound_3A:	include "SK/SFX/3A.asm"
Sound_3B:	include "SK/SFX/3B.asm"
Sound_3C:	include "SK/SFX/3C.asm"
Sound_3D:	include "SK/SFX/3D.asm"
Sound_3E:	include "SK/SFX/3E.asm"
Sound_3F:	include "SK/SFX/3F.asm"
Sound_40:	include "SK/SFX/40.asm"
Sound_41:	include "SK/SFX/41.asm"
Sound_42:	include "SK/SFX/42.asm"
Sound_43:	include "SK/SFX/43.asm"
Sound_44:	include "SK/SFX/44.asm"
Sound_45:	include "SK/SFX/45.asm"
Sound_46:	include "SK/SFX/46.asm"
Sound_47:	include "SK/SFX/47.asm"
Sound_48:	include "SK/SFX/48.asm"
Sound_49:	include "SK/SFX/49.asm"
Sound_4A:	include "SK/SFX/4A.asm"
Sound_4B:	include "SK/SFX/4B.asm"
Sound_4C:	include "SK/SFX/4C.asm"
Sound_4D:	include "SK/SFX/4D.asm"
Sound_4E:	include "SK/SFX/4E.asm"
Sound_4F:	include "SK/SFX/4F.asm"
Sound_50:	include "SK/SFX/50.asm"
Sound_51:	include "SK/SFX/51.asm"
Sound_52:	include "SK/SFX/52.asm"
Sound_53:	include "SK/SFX/53.asm"
Sound_54:	include "SK/SFX/54.asm"
Sound_55:	include "SK/SFX/55.asm"
Sound_56:	include "SK/SFX/56.asm"
Sound_57:	include "SK/SFX/57.asm"
Sound_58:	include "SK/SFX/58.asm"
Sound_59:	include "SK/SFX/59.asm"
Sound_5A:	include "SK/SFX/5A.asm"
Sound_5B:	include "SK/SFX/5B.asm"
Sound_5C:	include "SK/SFX/5C.asm"
Sound_5D:	include "SK/SFX/5D.asm"
Sound_5E:	include "SK/SFX/5E.asm"
Sound_5F:	include "SK/SFX/5F.asm"
Sound_60:	include "SK/SFX/60.asm"
Sound_61:	include "SK/SFX/61.asm"
Sound_62:	include "SK/SFX/62.asm"
Sound_63:	include "SK/SFX/63.asm"
Sound_64:	include "SK/SFX/64.asm"
Sound_65:	include "SK/SFX/65.asm"
Sound_66:	include "SK/SFX/66.asm"
Sound_67:	include "SK/SFX/67.asm"
Sound_68:	include "SK/SFX/68.asm"
Sound_69:	include "SK/SFX/69.asm"
Sound_6A:	include "SK/SFX/6A.asm"
Sound_6B:	include "SK/SFX/6B.asm"
Sound_6C:	include "SK/SFX/6C.asm"
Sound_6D:	include "SK/SFX/6D.asm"
Sound_6E:	include "SK/SFX/6E.asm"
Sound_6F:	include "S1/SFX/sndAB.asm"
Sound_70:	include "SK/SFX/70.asm"
Sound_71:	include "SK/SFX/71.asm"
Sound_72:	include "SK/SFX/72.asm"
Sound_73:	include "SK/SFX/73.asm"
Sound_74:	include "SK/SFX/74.asm"
Sound_75:	include "SK/SFX/75.asm"
Sound_76:	include "SK/SFX/76.asm"
Sound_77:	include "SK/SFX/77.asm"
Sound_78:	include "SK/SFX/78.asm"
Sound_79:	include "SK/SFX/79.asm"
Sound_7A:	include "SK/SFX/7A.asm"
Sound_7B:	include "SK/SFX/7B.asm"
Sound_7C:	include "SK/SFX/7C.asm"
Sound_7D:	include "SK/SFX/7D.asm"
Sound_7E:	include "SK/SFX/7E.asm"
Sound_7F:	include "SK/SFX/7F.asm"
Sound_80:	include "SK/SFX/80.asm"
Sound_81:	include "SK/SFX/81.asm"
Sound_82:	include "SK/SFX/82.asm"
Sound_83:	include "SK/SFX/83.asm"
Sound_84:	include "SK/SFX/84.asm"
Sound_85:	include "SK/SFX/85.asm"
Sound_86:	include "SK/SFX/86.asm"
Sound_87:	include "SK/SFX/87.asm"
Sound_88:	include "SK/SFX/88.asm"
Sound_89:	include "SK/SFX/89.asm"
Sound_8A:	include "SK/SFX/8A.asm"
Sound_8B:	include "SK/SFX/8B.asm"
Sound_8C:	include "SK/SFX/8C.asm"
Sound_8D:	include "SK/SFX/8D.asm"
Sound_8E:	include "SK/SFX/8E.asm"
Sound_8F:	include "SK/SFX/8F.asm"
Sound_90:	include "SK/SFX/90.asm"
Sound_91:	include "SK/SFX/91.asm"
Sound_92:	include "SK/SFX/92.asm"
Sound_93:	include "SK/SFX/93.asm"
Sound_94:	include "SK/SFX/94.asm"
Sound_95:	include "SK/SFX/95.asm"
Sound_96:	include "SK/SFX/96.asm"
Sound_97:	include "SK/SFX/97.asm"
Sound_98:	include "SK/SFX/98.asm"
Sound_99:	include "SK/SFX/99.asm"
Sound_9A:	include "SK/SFX/9A.asm"
Sound_9B:	include "SK/SFX/9B.asm"
Sound_9C:	include "SK/SFX/9C.asm"
Sound_9D:	include "SK/SFX/9D.asm"
Sound_9E:	include "SK/SFX/9E.asm"
Sound_9F:	include "SK/SFX/9F.asm"
Sound_A0:	include	"S1/SFX/SndA0 - Jump.asm"
		even
Sound_A1:	include	"S1/SFX/SndA1 - Lamppost.asm"
		even
Sound_A2:	include	"S1/SFX/SndA2.asm"
		even
Sound_A3:	include	"S1/SFX/SndA3 - Death.asm"
		even
Sound_A4:	include	"S1/SFX/SndA4 - Skid.asm"
		even
Sound_A5:	include	"S1/SFX/SndA5.asm"
		even
Sound_A6:	include	"S1/SFX/SndA6 - Hit Spikes.asm"
		even
Sound_A7:	include	"SK/SFX/SndA7.asm"
		even
Sound_A8:	include	"S1/SFX/SndA8 - SS Goal.asm"
		even
Sound_A9:	include	"S1/SFX/SndA9 - SS Item.asm"
		even
Sound_AA:	include	"S1/SFX/SndAA - Splash.asm"
		even
Sound_AB:	include	"SK/SFX/AB.asm"
		even
Sound_AC:	include	"S1/SFX/SndAC - Hit Boss.asm"
		even
Sound_AD:	include	"S1/SFX/SndAD - Get Bubble.asm"
		even
Sound_AE:	include	"S1/SFX/SndAE - Fireball.asm"
		even
Sound_AF:	include	"S1/SFX/SndAF - Shield.asm"
		even
Sound_B0:	include	"S1/SFX/SndB0 - Saw.asm"
		even
Sound_B1:	include	"S1/SFX/SndB1 - Electric.asm"
		even
Sound_B2:	include	"S1/SFX/SndB2 - Drown Death.asm"
		even
Sound_B3:	include	"S1/SFX/SndB3 - Flamethrower.asm"
		even
Sound_B4:	include	"S1/SFX/SndB4 - Bumper.asm"
		even
Sound_B5:	include	"S1/SFX/SndB5 - Ring.asm"
		even
Sound_B6:	include	"S1/SFX/SndB6 - Spikes Move.asm"
		even
Sound_B7:	include	"S1/SFX/SndB7 - Rumbling.asm"
		even
Sound_B8:	include	"S1/SFX/SndB8.asm"
		even
Sound_B9:	include	"S1/SFX/SndB9 - Collapse.asm"
		even
Sound_BA:	include	"S1/SFX/SndBA - SS Glass.asm"
		even
Sound_BB:	include	"S1/SFX/SndBB - Door.asm"
		even
Sound_BC:	include	"S1/SFX/SndBC - Teleport.asm"
		even
Sound_BD:	include	"S1/SFX/SndBD - ChainStomp.asm"
		even
Sound_BE:	include	"S1/SFX/SndBE - Roll.asm"
		even
Sound_BF:	include	"S1/SFX/SndBF - Get Continue.asm"
		even
Sound_C0:	include	"S1/SFX/SndC0 - Basaran Flap.asm"
		even
Sound_C1:	include	"S1/SFX/SndC1 - Break Item.asm"
		even
Sound_C2:	include	"S1/SFX/SndC2 - Drown Warning.asm"
		even
Sound_C3:	include	"S1/SFX/SndC3 - Giant Ring.asm"
		even
Sound_C4:	include	"S1/SFX/SndC4 - Bomb.asm"
		even
Sound_C5:	include	"S1/SFX/SndC5 - Cash Register.asm"
		even
Sound_C6:	include	"S1/SFX/SndC6 - Ring Loss.asm"
		even
Sound_C7:	include	"S1/SFX/SndC7 - Chain Rising.asm"
		even
Sound_C8:	include	"S1/SFX/SndC8 - Burning.asm"
		even
Sound_C9:	include	"S1/SFX/SndC9 - Hidden Bonus.asm"
		even
Sound_CA:	include	"S1/SFX/SndCA - Enter SS.asm"
		even
Sound_CB:	include	"S1/SFX/SndCB - Wall Smash.asm"
		even
Sound_CC:	include	"S1/SFX/SndCC - Spring.asm"
		even
Sound_CD:	include	"S1/SFX/SndCD - Switch.asm"
		even
Sound_CE:	include	"S1/SFX/SndCE - Ring Left Speaker.asm"
		even
Sound_CF:	include	"S1/SFX/SndCF - Signpost.asm"
		even
Sound_D0:	include "SK/SFX/D0.asm"
Sound_D1:	include "SK/SFX/D1.asm"
Sound_D2:	include "SK/SFX/D2.asm"
Sound_D3:	include "SK/SFX/D3.asm"
Sound_D4:	include "SK/SFX/D4.asm"
Sound_D5:	include "SK/SFX/D5.asm"
Sound_D6:	include "SK/SFX/D6.asm"
Sound_D7:	include "SK/SFX/D7.asm"
Sound_D8:	include "SK/SFX/D8.asm"
Sound_D9:	include "SK/SFX/D9.asm"
Sound_DA:	include "SK/SFX/DA.asm"
Sound_DB:	include "SK/SFX/DB.asm"
	finishBank

Go to "Obj49_PlaySnd:", and change the routine to this:

Obj49_PlaySnd:				; XREF: Obj49_Index
		move.b	($FFFFFE0F).w,d0
		andi.b	#$3F,d0
		move.w	8(a0),d0
		andi.w	#$FF80,d0
		move.w	($FFFFF700).w,d1
		subi.w	#$80,d1
		andi.w	#$FF80,d1
		sub.w	d1,d0
		cmpi.w	#$280,d0
		bhi.w	DeleteObject
		rts

To fix the pushing sfx, go to "loc_C294:" and locate

                move.w	#$A7,d0
                jsr	(PlaySound_Special).l ;	play pushing sound

Replace it with this:

                move.w	#$69,d0
                jsr	(PlaySound_Special).l ;	play pushing sound

Go to "Obj2E_ChkShield:" and "Obj2E_RingSound:". Change "PlaySound" to "PlaySound_Special"

Step 7: Fixing Music

Find "MusicList:" in sonic1.asm. It should look like this:

MusicList:	incbin	misc\muslist1.bin
		even

Replace it with this:

MusicList:	dc.b	$01, $02, $03, $04, $05, $06, $07, 0
                even

To fix the speed shoes, go to "Obj2E_ChkShoes:" Once there, replace these lines of code:

                move.w	#$E2,d0
                jmp	(PlaySound).l	; Speed	up the music

With these lines of code:

                moveq   #8,d0
                jmp (SetTempo).l

Now go to "Obj01_ChkShoes:" Replace these lines of code:

                move.w	#$E3,d0
                jmp	(PlaySound).l	; run music at normal speed

With these:

                moveq   #0,d0
                jmp (SetTempo).l

To fix the Title Screen music, Go To "Title_LoadText:" and locate

                move.b	#$8A,d0		; play title screen music
		bsr.w	PlaySound_Special

Replace it with this:

                move.b	#$25,d0		; play title screen music
		bsr.w	PlaySound

To fix the invinvibility music, go to "Obj2E_ChkInvinc:" and locate

                move.w	#$87,d0
		jmp	(PlaySound).l	; play invincibility music

Replace it with this:

                move.w	#$08,d0
		jmp	(PlaySound).l	; play invincibility music

To fix the boss music, go to every instance of:

                move.w	#$8C,d0
		bsr.w	PlaySound	; play boss music

Replace it with this:

                move.w	#$2E,d0
		bsr.w	PlaySound	; play boss music

To fix the collect music, go to "Obj09_NoEmer:" and find this:

		move.w	#$93,d0
		jsr	(PlaySound_Special).l ;	play emerald music

Replace it with this:

                move.w	#$2B,d0
		jsr	(PlaySound).l ;	play emerald music

Step 8: Fixing includes for S3K Sound Driver

Find every instance of this in "Z80 Sound Driver.asm":

DACBINCLUDE "Sound/DAC/

and remove "sound/" Then, find this:

	include "Sound/_smps2asm_inc.asm"

and replace it with this:

	include "_smps2asm_inc.asm"

Conclusion

Congrats! Now you have ported the Flamewing S3K driver to your Sonic 1 hack!

Known Issues with the Sonic 1 guide

Some of the Known Issues with this guide are:

  • PlaySound and PlaySound_Special cannot be used interchangeably! Use PlaySound only for music, and use PlaySound_Special only for SFX!
  • Pausing during gameplay does not stop music
  • There is a DAC bug in AIZ1's Music
  • Continuous SFX from S1 are bugged

Credits

  • Kurk (me): Main Guide, Code.
  • Ralakimus: Helping with converting the guide for the most recent version of Flamewing's S3K Driver, and made a better stopZ80 macro.
  • Natsumi: Helping with bugfixing PlaySound
  • Flamewing: Making his S3K driver and smps2asm.
  • Crash: Porting the Flamewing S3K driver to S1 with a similar method, which helped me while writing this
  • Alriightyman: Made a guide to do this but for Sonic 2, which helped me while writing this
  • Clownancy: Fixed S1 SFX from Clone Driver v2
  • Valley Bell: Isolating the Sonic 1 sound driver, which helped me locate what parts of the S1 sound driver to remove
  • Kram1024: Making the original Sonic 3 sound driver in Sonic 1 guide.
SCHG How-To Guide: Sonic the Hedgehog (16-bit)
Fixing Bugs
Fix Demo Playback | Fix a Race Condition with Pattern Load Cues | Fix the SEGA Sound | Display the Press Start Button Text | Fix the Level Select Menu | Fix the Hidden Points Bug | Fix Accidental Deletion of Scattered Rings | Fix Ring Timers | Fix the Walk-Jump Bug | Correct Drowning Bugs | Fix the Death Boundary Bug | Fix the Camera Follow Bug | Fix Song Restoration Bugs | Fix the HUD Blinking | Fix the Level Select Graphics Bug | Fix a remember sprite related bug
Changing Design Choices
Change Spike Behavior | Collide with Water After Being Hurt | Fix Special Stage Jumping Physics | Improve the Fade In\Fade Out Progression Routines | Fix Scattered Rings' Underwater Physics | Remove the Speed Cap | Port the REV01 Background Effects | Port Sonic 2's Level Art Loader | Retain Rings Between Acts | Add Sonic 2 (Simon Wai Prototype) Level Select | Improve ObjectMove Subroutines | Add Sonic 2 Level Select | Collide with Water After Being Hurt | Smooth Out Rotation in Special Stages
Adding Features
Add Spin Dash ( Part 1 (GitHub)/(Hivebrain) / Part 2 / Part 3 / Part 4 ) | Add Eggman Monitor | Add Super Sonic | Add Extended Camera | Add the Air Roll | Add 6-Button Support
Sound Features
Expand the Sound Index | Play Different Songs Per Act | Port Sonic 2 Final Sound Driver | Port Sonic 3's Sound Driver | Change The SEGA Sound | Correct PAL Music Tempo
Extending the Game
Load Chunks From ROM | Add Extra Characters | Make an Alternative Title Screen | Use Dynamic Tilesets | Make GHZ Load Alternate Art | Make Ending Load Alternate Art | Add a New Zone | Set Up the Goggle Monitor | Add New Moves | Add a Dynamic Collision System | Dynamic Special Stage Walls System | Extend Sprite Mappings and Art Limit | Enigma Credits | Use Dynamic Palettes
Miscellaneous
Convert the Hivebrain 2005 Disassembly to ASM68K
Split Disassembly Guides
Set Up a Split Disassembly | Basic Level Editing | Basic Art Editing | Basic ASM Editing (Spin Dash)