- Tech Member: Tech Members
- Active Posts:
- 28 (0.01 per day)
- Most Active In:
- Engineering & Reverse Engineering (22 posts)
- 24-February 08
- Profile Views:
- Last Active:
- Apr 17 2013 08:52 AM
- Member Title:
- Get a load of this!!
- 24 years old
- September 3, 1988
- Mendoza, Argentina
- My career. The music, I love make and heard music. Play the guitar. The reverse engineering of whatever that catch my atention.
- Sonic Z. The Z DOESN'T means nothing.
- National Flag:
Posts I've Made
30 June 2010 - 05:59 PMI toke the time to fully research the 68K SMPS like 2 years ago (but for lazyness I never published my discoveries), so I can say that some of your notes are a bit inaccurate. The real channels distribution is:CODEF040-F07F PCM
F220-F24F SFX FM3
F250-F27F SFX FM4
F280-F2AF SFX FM5
F2B0-F2DF SFX PSG1
F2E0-F30F SFX PSG2
F310-F33F SFX PSG3
F340-F36F SFX FM4 (only used by waterfall, I believe)
F370-F39F SFX PSG (set each time a SFX uses the Noise channel)
F3A0-F??? Mirror of the musica data (not sure about the SFX data) when the Extra Life music is being played.
And the structure of each channel is:CODE00 = bitfield (explained down) (byte)
01 = channel identifier (6,0,1,2,4,5,6 for the DAC/FM1,2,3,4,5,6 respectively; 80,A0,C0,E0 for the PSG1,2,3,Noise respectively) (byte)
02 = particular tempo modifier (byte)
04 = current offset (long)
08 = pitch (byte)
09 = volumen (byte)
0A = channel configuration (stereo/AMS/FMS) (byte)
0B = instrument/voice (byte)
0C = offset adder for the current PSG voice (byte)
0D = return counter. determines in what adress INSIDE THE CHANNEL is the return offset used by the flag E3. 30 is at the end of channel (should NOT execute a return), 2E is 2 bytes before the end of the channel, etc (byte)
0E = counter of the current note duration (byte)
0F = current note duration (byte)
10 = current frequency (word)
12 = counter of the current note filler (byte)
13 = current note filler (byte)
14 = offset of parameters of the last used modulation (long)
18 = wait time until the modulation starts (byte)
19 = modulation speed (byte)
1A = how much the frequency change per modulation step (signed byte)
1B = maximun amplitude of modulation (byte)
1C = the adder who modifies the current frequency to produce the modulation (word)
1E = RAW LSB to be added at the frequency (flag E1) (byte)
1F = Feedback/Algorithm of the current instrument (FM); kind of sound produce by the Noise channel (if PSG,flag F3) (byte)
20 = particular offset of the instruments (only used by the SFX FM) (long)
And the bitfield in the header means this:CODEBit 0: Reduntant/Without usage
Bit 1: 0: There is a note. 1: There is a rest
Bit 2: (For FM/PSG) 0: Nothing playing over this channel. 1: A high priority sound (a SFX) is over this channel.
(For DAC): 0: Fade In/Out to the last music is inactive. 1: Fade In/Out to the last music is active (flag E4)
Bit 3: 0: Modulation inactive. 1: Modulation active
Bit 4: 0: The Key Off event ocurrs. 1: The Key Off event DOESN'T ocurrs (Key On during the whole note) (flag E7)
Bit 5: Reduntant/Without usage
Bit 6: Reduntant/Without usage
Bit 7: 0: This channel is inactive. 1: This channel is active.
27 April 2010 - 03:48 PMThe Z80 driver in Sonic 1 resamples the existing timpani sample if the number is above $87. This is done using special entries in the DAC table. For what it's worth you probably shouldn't be modifying the Sonic 1 DAC driver if you want something truly general purpose. Use jman2050's driver or write a new DAC driver instead.
Wrong. The "special cases" are handled by the M68K, specifically by the routine loc_71CAC. It looks something like this:
Syntax Highlighted Code: ASM
btst #3,d0 ; it's a special timpani?
bne.s loc_71CAC ; if yes, branch...
move.b d0,($A01FFF).l ; writes the sample's number into the Z80 RAM
rts ; leave...
subi.b #$88,d0 ; adjusts to the correct number
move.b Timpani_Pitches(pc,d0.w),d0 ; loads the modified pitch for the timpani
move.b d0,($A000EA).l ; modifies the pitch
move.b #$83,($A01FFF).l ; plays the normal timpani
rts ; leave...
; End of function Sound_PlayDAC
Timpani_Pitches: dc.b $12, $15, $1C, $1D, $FF, $FF
In other words, the engine just modifies the current pitch asociated to the (unique) timpani entry in the DAC table in the Z80 code. You only need to cut off the lines above to erase that restriction...
22 April 2010 - 07:17 PMThen it's easy: just find where the effects are handled, set a flag in RAM, then clear it when a new song is played.
Or even easier, check the location $FFF1F1. If the value is $E0, you have the NOISE. Whatever else (I think it's $C0), it's the PSG 3. Aditionally, the bit 7 at $FFF040 controlls if the DAC channel is activated or not. The same bit at $FFF160 do the same function for the FM6. Understandable?
17 February 2010 - 10:00 AMExists any information of the music format used in the Sonic Advance series?
04 February 2010 - 06:28 PMBoth are right. Here is the commented part of SMPS code that manages the atenuation(sub_72926 in whatever disassembly):
Syntax Highlighted Code: ASM
DoPSGInstrument: ; XREF: Sound_PlayPSG
tst.b $B(a5) ; is zero the current instrument?
beq.w locret_7298A ; if yes, branch...
DoPSGInstrument_2: ; XREF: Sound_PlayPSG
move.b 9(a5),d6 ; load the volume
move.b $B(a5),d0 ; load the number of instrument
beq.s PSG_ChgVolume ; is zero (again)?. If yes, branch...
movea.l (Go_PSGIndex).l,a0 ; loads the PSG instruments offset
lsl.w #2,d0 ; get the fixed index
movea.l (a0,d0.w),a0 ; load the current offset of the instrument
move.b $C(a5),d0 ; load the instrument's counter
move.b (a0,d0.w),d0 ; load the modifier byte
addq.b #1,$C(a5) ; augment the counter
btst #7,d0 ; is a negative value?
beq.s loc_72960 ; if not, branch...
cmpi.b #$80,d0 ; is specificly $80?
beq.s LoopPSGInstrument ; if yes branch...
add.w d0,d6 ; modifies the volume
cmpi.b #$10,d6 ; is it higher than the maximun (phisically, the lowest) PSG volume?
bcs.s PSG_ChgVolume ; if not, branch...
moveq #$F,d6 ; set the maximun (lower) volume
; End of function DoPSGInstrument
LoopPSGInstrument: ; XREF: DoPSGInstrument
subq.b #1,$C(a5) ; decreases the counter (loops it at the last byte)
Mairtrus hasn't added any friends yet.