Actions

SCHG How-to

Difference between revisions of "SCHG How-to:Port Flamewing's Sonic 3 & Knuckles Sound Driver"

From Sonic Retro

m (credits)
m
Line 276: Line 276:
  
 
=Credits=
 
=Credits=
[[User:KZG4|Kurk]] (me): Main Guide, Code.
+
*[[User:KZG4|Kurk]] (me): Main Guide, Code.
[[User:Flamewing|Flamewing]]: Making his S3K driver and smps2asm.  
+
*[[User:Flamewing|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
+
*Crash: Porting the Flamewing S3K driver to S1 with a similar method, which helped me while writing this
[[User:Alriightyman|Alriightyman]]: Made a guide to do this but for Sonic 2, which helped me while writing this
+
*[[User:Alriightyman|Alriightyman]]: Made a guide to do this but for Sonic 2, which helped me while writing this
[[User:Clownacy|Clownancy]]: Fixed S1 SFX from Clone Driver v2
+
*[[User:Clownacy|Clownancy]]: Fixed S1 SFX from Clone Driver v2
[[User:ValleyBell|Valley Bell]]: Isolating the Sonic 1 Sound Driver, which helped me locate what parts of the S1 sound driver to remove
+
*[[User:ValleyBell|Valley Bell]]: Isolating the Sonic 1 sound driver, which helped me locate what parts of the S1 sound driver to remove
 +
*[[User:Kram1024|Kram1024]]: Making the original Sonic 3 sound driver in Sonic 1 guide.

Revision as of 15:27, 12 May 2020

(Original guide by KZG4)

Many people have been using the older Sonic 3 and Knuckles sound driver port made by Kram1024 many years ago. I decided to try and port over Flamewing's improved Sonic 3 and Knuckles sound driver so people that intend to port over a Z80 based sound driver will be able to use a newer one.

Note

This guide is meant for a fresh install. I have not made this in order for the user to copy this over a disasm with Port Sonic 3 Sound Driver Part 1 applied onto it. I have not tested it so I have no idea if adding this guide over it will work.

Step 1: Resources

First you need the following:

Step 2: Setup

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

SonicControl	equ	$FFFFF602
Joypad		equ	$FFFFF604

Held		equ	0
Press		equ	1

iStart		equ 	7
iA		equ 	6
iC		equ 	5
iB		equ 	4
iRight		equ 	3
iLeft		equ 	2
iDown		equ 	1
iUp		equ 	0

MaskStart		equ 	1<<7
MaskA		equ 	1<<6
MaskC		equ 	1<<5
MaskB		equ 	1<<4
MaskRight		equ 	1<<3
MaskLeft		equ 	1<<2
MaskDown		equ 	1<<1
MaskUp		equ 	1

; =============================================================
; Macro to check button presses
; Arguments:	1 - buttons to check
;		2 - bitfield to check
; -------------------------------------------------------------
tpress	macro
	move.b	(\2+1),d0
	andi.b	#\1,d0
	endm

; =============================================================
; Macro to check if buttons are held
; Arguments:	1 - buttons to check
;		2 - bitfield to check
; -------------------------------------------------------------
theld	macro
	move.b	\2,d0
	andi.b	#\1,d0
	endm


; ---------------------------------------------------------------------------
; 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, along with controller macros that you may find helpful.

Step 3: Removing the Sonic 1 Sound Driver

First, We need to locate

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	($A01C8A).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		($A01C02).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:

Step 5: Modifying Build.bat

Step 6: Changing SFX

Step 7: Fixing Music

Known Issues

Some of the Known Issues with this guide are:

  • Pushing SFX is broken
  • Point SFX is broken
  • Pausing during gameplay does not stop music

Conclusion

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

Credits

  • Kurk (me): Main Guide, Code.
  • 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.