Actions

SCHG How-to

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

From Sonic Retro

(forgot a z)
(added step 2)
Line 13: Line 13:
 
*A utitily to extract .7z files. I'd Recommend 7Zip.
 
*A utitily to extract .7z files. I'd Recommend 7Zip.
  
==Step 2: Removing the Sonic 1 Sound Driver==
+
==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:
  
 +
<syntaxhighlight lang="asm">
 +
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
 +
</syntaxhighlight>
 +
 +
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, W
  
==Step 3: Inserting the Sonic 3K Sound Driver==
+
==Step 4: Inserting the Sonic 3K Sound Driver==
 
After you have removed the Sonic 1 Sound Driver, Locate the SoundDriverLoad Routine.
 
After you have removed the Sonic 1 Sound Driver, Locate the SoundDriverLoad Routine.
 
The routine will look like this:
 
The routine will look like this:
Line 76: Line 264:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==Step 4: Modifying Build.bat==
+
==Step 5: Modifying Build.bat==
==Step 5: Changing SFX==
+
==Step 6: Changing SFX==
==Step 6: Fixing Music==
+
==Step 7: Fixing Music==
 
==Known Issues==
 
==Known Issues==
 
Some of the Known Issues with this guide are:
 
Some of the Known Issues with this guide are:

Revision as of 15:17, 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, W

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
  • tba

Conclusion