Actions

SCHG How-to

Difference between revisions of "Fix the SEGA Sound"

From Sonic Retro

(Completely revamped the fix because I'm tired of having people ask me why the old one didn't work on asm68k)
m (Fixed tabbing)
Line 16: Line 16:
  
 
with this:
 
with this:
<asm>Sound_E1:                 ; XREF: Sound_ExIndex
+
<asm>Sound_E1:   ; XREF: Sound_ExIndex  
          lea     (SegaPCM).l,a2             ; Load the SEGA PCM sample into a2. It's important that we use a2 since a0 and a1 are going to be used up ahead when reading the joypad ports
+
  jsr (PlayPCM_68K).l
          move.l     #$6978,d3             ; Load the size of the SEGA PCM sample into d3
+
  addq.w #4,sp
          move.b     #$2A,($A04000).l       ; $A04000 = $2A -> Write to DAC channel    
+
  rts  
PlayPCM_Loop:    
+
          move.b     (a2)+,($A04001).l         ; Write the PCM data (contained in a2) to $A04001 (YM2612 register D0)
+
PlayPCM_68K:
          move.w     #$14,d0                 ; Write the pitch ($14 in this case) to d0
+
lea (SegaPCM).l,a2 ; Load the SEGA PCM sample into a2. It's important that we use a2 since a0 and a1 are going to be used up ahead when reading the joypad ports  
          dbf     d0,*                 ; Decrement d0; jump to itself if not 0. (for pitch control, avoids playing the sample too fast)   
+
move.l #$6978,d3 ; Load the size of the SEGA PCM sample into d3  
          sub.l     #1,d3               ; Subtract 1 from the PCM sample size
+
move.b #$2A,($A04000).l ; $A04000 = $2A -> Write to DAC channel  
          beq.s     return_PlayPCM             ; If d3 = 0, we finished playing the PCM sample, so stop playing, leave this loop, and unfreeze the 68K
+
PlayPCM_Loop:  
          lea     ($FFFFF604).w,a0         ; address where JoyPad states are written
+
move.b (a2)+,($A04001).l ; Write the PCM data (contained in a2) to $A04001 (YM2612 register D0)  
          lea     ($A10003).l,a1             ; address where JoyPad states are read from
+
move.w #$14,d0 ; Write the pitch ($14 in this case) to d0  
          jsr     (Joypad_Read).w             ; Read only the first joypad port. It's important that we do NOT do the two ports, we don't have the cycles for that
+
dbf d0,* ; Decrement d0; jump to itself if not 0. (for pitch control, avoids playing the sample too fast)   
          btst     #7,($FFFFF604).w       ; Check for Start button
+
sub.l #1,d3 ; Subtract 1 from the PCM sample size  
          bne.s     return_PlayPCM             ; If start is pressed, stop playing, leave this loop, and unfreeze the 68K
+
beq.s return_PlayPCM ; If d3 = 0, we finished playing the PCM sample, so stop playing, leave this loop, and unfreeze the 68K  
          bra.s     PlayPCM_Loop             ; Otherwise, continue playing PCM sample
+
lea ($FFFFF604).w,a0 ; address where JoyPad states are written  
return_PlayPCM:
+
lea ($A10003).l,a1 ; address where JoyPad states are read from  
          addq.w    #4,sp
+
jsr (sub_112A).w ; Read only the first joypad port. It's important that we do NOT do the two ports, we don't have the cycles for that  
          rts</asm>
+
btst #7,($FFFFF604).w ; Check for Start button  
 +
bne.s return_PlayPCM ; If start is pressed, stop playing, leave this loop, and unfreeze the 68K  
 +
bra.s PlayPCM_Loop ; Otherwise, continue playing PCM sample  
 +
return_PlayPCM:  
 +
rts</asm>
 
[[Category:SCHG How-tos]]
 
[[Category:SCHG How-tos]]

Revision as of 07:43, 16 February 2008

Let's fix a problem that causes a great deal of pain to anyone adding code to Sonic 1: The SEGA sound.

So go to Sound_E1, and replace this: <asm>Sound_E1: ; XREF: Sound_ExIndex move.b #$88,($A01FFF).l move.w #0,($A11100).l ; start the Z80 move.w #$11,d1 loc_71FC0: move.w #-1,d0 loc_71FC4: nop dbf d0,loc_71FC4 dbf d1,loc_71FC0 addq.w #4,sp rts</asm>

with this: <asm>Sound_E1:  ; XREF: Sound_ExIndex jsr (PlayPCM_68K).l addq.w #4,sp rts

PlayPCM_68K: lea (SegaPCM).l,a2 ; Load the SEGA PCM sample into a2. It's important that we use a2 since a0 and a1 are going to be used up ahead when reading the joypad ports move.l #$6978,d3 ; Load the size of the SEGA PCM sample into d3 move.b #$2A,($A04000).l ; $A04000 = $2A -> Write to DAC channel PlayPCM_Loop: move.b (a2)+,($A04001).l ; Write the PCM data (contained in a2) to $A04001 (YM2612 register D0) move.w #$14,d0 ; Write the pitch ($14 in this case) to d0 dbf d0,* ; Decrement d0; jump to itself if not 0. (for pitch control, avoids playing the sample too fast) sub.l #1,d3 ; Subtract 1 from the PCM sample size beq.s return_PlayPCM ; If d3 = 0, we finished playing the PCM sample, so stop playing, leave this loop, and unfreeze the 68K lea ($FFFFF604).w,a0 ; address where JoyPad states are written lea ($A10003).l,a1 ; address where JoyPad states are read from jsr (sub_112A).w ; Read only the first joypad port. It's important that we do NOT do the two ports, we don't have the cycles for that btst #7,($FFFFF604).w ; Check for Start button bne.s return_PlayPCM ; If start is pressed, stop playing, leave this loop, and unfreeze the 68K bra.s PlayPCM_Loop ; Otherwise, continue playing PCM sample return_PlayPCM: rts</asm>