General topic
The Sonic music hacking guide
Created by Tweaker on May 25 2005.
Thanks to Saxman and fuzzbuzz.
This guide will teach even the complete clueless individual how to edit
the music in the Sonic the Hedgehog games for the Sega Mega Drive. Be
warned however: You must have at least basic hex knowledge. If you have
no idea what hex is, then I suggest you steer clear of this guide and
figure things out first.
Update history
March 29 2005: Initial release.
April 22 2005: Updated Chaotix info. Also added explaination on Sonic 2
Final pointer format and corrected a few bits of incorrect info. Turns
out you CAN use 6 FM channels and the DAC at the same time, thanks to
the music engine.
May 24 2005: Updated with even more Sonic 2 final info. Also added
music pointer locations for Ristar and Micheal Jackson's Moonwalker.
Pointer format
First off, what is a pointer? Well, a pointer is a set of hexadecimal
values that point to a location in the ROM (or, in other cases, RAM.
More advanced stuff there though). There are different types of
pointers.
Some are part of an offset index. These kinds of data pointers are
usually 16-bits (2 bytes) long and are determined by adding the pointer
value to the current location in the ROM. So if one offset index added
to 80000, and a pointer read 0890, then it is reading offset 80890,
which would be the location of the data it is looking for.
Other pointers are very basic. 32-bit pointers are the easiest to deal
with. They are big endian when dealing with the Megadrive and define
the exact location using four bytes. So let's use the previous example.
Our location was 80890. The pointer appears as "00 08 08 90". Couldn't
be any simpler.
The pointer format in the Sonic games music differs from game to game.
I will list the pointer format for each incarnation of the music
engine. Follow along.
Sonic 1, Ristar, and Moonwalker:
These pointers are relatively easy to deal with. These pointers are
like the offset index pointers talked about earlier. They are relative
16-bit pointers that add the pointer value to the current location in
the ROM. Here is an example.
Lets say that the music data started at EC000. Now, our voice pointer
says 0180. So, from EC000 we add 180 to the value, making the location
of the voice data at EC180. You see? That is simple. There are some
other things to note about these pointers that I will mention later
that have to do with coordination flags.
Sonic 2 Beta, 3, Crackers, Chaotix and 3D:
These pointers are also pretty easy to deal with, once you understand
their format. These pointers are also 16-bit, but they are absolute
pointers. This means that they add to a specified location, which is
usually even. Now, what you must understand is that these pointers are
little endian, because the sound driver runs on the Z80. Little endian
simply means that the bytes are swapped. A good example would be if a
location was 8180 (big endian) for voice data, the pointer would read
8081 (little endian). This may seem confusing at first, but I will
explain further.
You see, these pointers always read "8000", regardless of the starting
location. So if the starting location of the music was C0000 for one
song, and the starting location of another was C8000, the resulting
pointer would still be 0080. You see, 8000 bytes is one music bank. So
when 8000 bytes are used up by the first bank of music data, the second
set of music pointers will add to that second bank location. So if the
first bank's location was C0000, and the second was C8000, then the
first set of pointers would add to C0000, and the second to C8000. Not
too complicated. So lets break things down now.
Lets say the voice pointer for one song was F289. Since these are
little endian, swap the bytes. This makes 89F2. Now, lets say that the
current bank adds to C8000. So we can deduce that the location of the
voice data is C89F2. You get it now? It is easier to find things with
these pointers, but it becomes a bit of a problem if you are porting
music, since you have to either put the music in its "original"
location or fix all the pointers in the song.
Sonic 2 Final:
All pointers add to a certain constant, including those in coordination
flags. This constant is 1380. With these pointers, 1380 acts as zero.
So lets say that the voice pointer reads 1915. Since 1380 is zero, we
would subtract 1380 from 1915 and we get the distance away from the
beginning of the song that the voice data is. Essentially the pointers
in Sonic 2 Beta, but with a different constant. Note that each song is
treated as it's own bank, and the beginning of the song is the
beginning of the bank, while the end of the song is the end of the
bank.
Exceptions: Credits music is uncompressed, unlike all the other music.
Uses the S2B pointer format. So do the pointers to the music data
itself at F8000.
Header format
Sonic 1, Sonic 2, Sonic 3, Sonic & Knuckles, Sonic 3D Blast, and
Sonic Crackers:
All pointers in this section differ according to the game you are
hacking. Remember, relative for Sonic 1, Ristar, and Moonwalker, and
absolute little endian for the others. The music header format listed
is a universal format used in all the major Megadrive Sonic games,
including Sonic 1, Sonic 2, Sonic 3, Sonic & Knuckles, Sonic 3D
Blast, and Sonic Crackers.
Bytes 00 & 01: Voice pointer. This points to the location of the
voice data, or instruments in the song.
Bytes 02 & 03: Channel setup. This is usually 0603, and means there
are 5 FM channels, 1 DAC, and 3 PSG channels. Changing these bytes will
either make the header larger or smaller, depending on what you change
them to. If you want to use the 6th FM channel, the 6th FM channel will
be located after the 5th FM channel modifier. The same applies if you
decide to use the 4th PSG channel. It will be located right after the
two redundant bytes after the 3rd PSG modifier.
Bytes 04 & 05: Tempo modifier. First byte is the dividing timing,
and the second is the main tempo modifier. Change the second byte to
make the music faster or slower.
Bytes 06 & 07: DAC pointer. This points to the drums you hear in
the music. In Chaotix, this points to the PWM channel used instead of
the DAC channel. Treat them as the same for now.
Bytes 0A & 0B: Dunno. They seem to be redundant.
Bytes 0C & 0D: FM channel 1 pointer. It points to FM channel 1.
Bytes 0E & 0F: FM channel 1 modifier. First byte modifies pitch,
and second byte modifies volume (same for all).
Bytes 10 & 11: FM channel 2 pointer.
Bytes 12 & 13: FM channel 2 modifier.
Bytes 14 & 15: FM channel 3 pointer
Bytes 16 & 17: FM channel 3 modifier.
Bytes 18 & 19: FM channel 4 pointer.
Bytes 1A & 1B: FM channel 4 modifier.
Bytes 1C & 1D: FM channel 5 pointer.
Bytes 1E & 1F: FM channel 5 modifier.
Bytes 20 & 21: PSG channel 1 pointer.
Bytes 22 & 23: PSG channel 1 modifier.
Bytes 24 & 25: Redundant. Does nothing.
Bytes 26 & 27: PSG channel 2 pointer.
Bytes 28 & 29: PSG channel 2 modifier.
Bytes 2A & 2B: Redundant. Does nothing.
Bytes 2C & 2D: PSG channel 3 pointer.
Bytes 2E & 2F: PSG channel 3 modifier.
Bytes 30 & 31: Redundant. Does nothing.
Knuckles Chaotix:
In Knuckles Chaotix, this format is slightly different to accomodate to
the 32x's hardware. I have listed it below.
Bytes 00 & 01: Voice pointer. This points to the location of the
voice data, or instruments in the song.
Bytes 02 & 03: Channel setup. This is usually 0603, and means there
are 6 FM channels, and 3 PSG channels. Changing these bytes will either
make the header larger or smaller, depending on what you change them
to. If you decide to use the 4th PSG channel, It will be located right
after the redundant two bytes after the PSG 3 modifier. Following that
will be the PWM pointers.
Bytes 04 & 05: Tempo modifier. First byte is the dividing timing,
and the second is the main tempo modifier. Change the second byte to
make the music faster or slower.
Bytes 06 & 07: FM channel 1 pointer. It points to FM channel 1.
Bytes 08 & 09: FM channel 1 modifier. First byte modifies pitch,
and second byte modifies volume (same for all).
Bytes 0A & 0B: FM channel 2 pointer.
Bytes 0C & 0D: FM channel 2 modifier.
Bytes 0E & 0F: FM channel 3 pointer
Bytes 10 & 11: FM channel 3 modifier.
Bytes 12 & 13: FM channel 4 pointer.
Bytes 14 & 15: FM channel 4 modifier.
Bytes 16 & 17: FM channel 5 pointer.
Bytes 18 & 19: FM channel 5 modifier.
Bytes 1A & 1B: FM channel 6 pointer.
Bytes 1C & 1D: FM channel 6 modifier.
Bytes 1E & 1F: PSG channel 1 pointer.
Bytes 20 & 21: PSG channel 1 modifier.
Bytes 22 & 23: Redundant. Does nothing.
Bytes 24 & 25: PSG channel 2 pointer.
Bytes 26 & 27: PSG channel 2 modifier.
Bytes 28 & 29: Redundant. Does nothing.
Bytes 2A & 2B: PSG channel 3 pointer.
Bytes 2C & 2D: PSG channel 3 modifier.
Bytes 2E & 2F: Redundant. Does nothing.
Bytes 30 & 31: PWM channel 1 pointer
Bytes 32 & 33: Redundant. Does nothing.
Bytes 34 & 35: PWM channel 2 pointer
Bytes 36 & 37: Redundant. Does nothing.
Bytes 38 & 39: PWM channel 3 pointer
Bytes 3A & 3B: Redundant. Does nothing.
Bytes 3C & 3D: PWM channel 3 pointer
Bytes 3E & 3F: Redundant. Does nothing.
Understanding the header is essential to editing music. This is the
basis of basic music editing, such as pitch and tempo editing. Once you
understand the pointers and the header, then you are ready to start
learning more advanced things.
Voice editing
Voices are the instruments that you hear playing in the music throught
the FM channels. To edit them correctly, you need to know FM synthesis.
Voice swapping is easy enough though. A voice is 19 hex bytes, and has
no header. It is raw data that gives info to the YM2612 FM chip in the
Megadrive to give the desired sound output. The format of a voice is as
follows.
Byte 00: Feedback (next 3 bits) / Algorithm (lower 3 bits)
Byte 01: Detune of operator 4 (nybble 1) / Coarse-frequency of operator
4 (nybble 2)
Byte 02: Detune of operator 3 (nybble 1) / Coarse-frequency of operator
3 (nybble 2)
Byte 03: Detune of operator 2 (nybble 1) / Coarse-frequency of operator
2 (nybble 2)
Byte 04: Detune of operator 1 (nybble 1) / Coarse-frequency of operator
1 (nybble 2)
Byte 05: [RS] of operator 4 (upper 2 bits) / Attack rate [AR] of
operator 4 (lower 5 bits)
Byte 06: [RS] of operator 3 (upper 2 bits) / Attack rate [AR] of
operator 3 (lower 5 bits)
Byte 07: [RS] of operator 2 (upper 2 bits) / Attack rate [AR] of
operator 2 (lower 5 bits)
Byte 08: [RS] of operator 1 (upper 2 bits) / Attack rate [AR] of
operator 1 (lower 5 bits)
Byte 09: [AM] of operator 4 / First decay rate [D1R] of operator 4
(lower 5 bits)
Byte 0A: [AM] of operator 3 / First decay rate [D1R] of operator 3
(lower 5 bits)
Byte 0B: [AM] of operator 2 / First decay rate [D1R] of operator 2
(lower 5 bits)
Byte 0C: [AM] of operator 1 / First decay rate [D1R] of operator 1
(lower 5 bits)
Byte 0D: Second decay rate [D2R] of operator 4 (00-14)
Byte 0E: Second decay rate [D2R] of operator 3 (00-14)
Byte 0F: Second decay rate [D2R] of operator 2 (00-14)
Byte 10: Second decay rate [D2R] of operator 1 (00-14)
Byte 11: First decay level [D1L] of operator 4 (nybble 1) / Release
rate [RR] of operator 4 (nybble 2)
Byte 12: First decay level [D1L] of operator 3 (nybble 1) / Release
rate [RR] of operator 3 (nybble 2)
Byte 13: First decay level [D1L] of operator 2 (nybble 1) / Release
rate [RR] of operator 2 (nybble 2)
Byte 14: First decay level [D1L] of operator 1 (nybble 1) / Release
rate [RR] of operator 1 (nybble 2)
Byte 15: Output level of operator 4
Byte 16: Output level of operator 3
Byte 17: Output level of operator 2
Byte 18: Output level of operator 1
So to swap voices, select the voice you want and copy those 19 hex
bytes onto another voice to hear your changes in game.
Note editing
The way the music is set up in the Sonic games is similar to how music
is structured in a MIDI file. Here are some values that will help you
directly edit notation data in the music.
00-7F: Note duration (How long a note is held for)
80-DF: Notes (80 is a rest)
E0-FF: Coordination flags
Now, the DAC channel uses values starting with 81 (As with FM and PSG,
80 is used as a rest) to define the DAC drum sample that is played.
Here are the sample definitions for a few games. Expect this section to
be updated with more soon.
Sonic 1:
81: Kick
82: Snare
83: Timpani
84: Noise
85: Noise
86: Silent
87 or higher: Sega sound
Sonic 2 Beta:
81: Kick
82: Snare
83: Clap
84: Scratch
85: Timpani
86: Tom
Sonic 2 Final:
81: Kick
82: Snare
83: Clap
84: Scratch
85: Timpani
86: Tom
91: Bongo
Sonic Crackers:
81: Kick
82: Snare
83: Tom
84: Tom
85: Tom
86: Voice sample "Lets go!"
87: Voice sample "Hey!"
88: Beep/screech
For DAC samples, any value beyond 86 in Sonic 2 will contain variations
of Tom up to value 8A. 8A starts variations of Timpani, which goes up
to around 8F, which is a copy of the clap. I forget what 90 is, but 91
is a bongo, used in MCZ 2P music. This bongo is not in Sonic 2 Beta.
The Timpani definitions are the same for both Sonic 1 and 2, so go
wild.
Coordination flags
Coordination flags alter the music in real time. They are what tell the
game to jump from one part of the song to another and to set up the
channels. They are also what makes the music loop in the games. They
are complicated, and it is recommended that you understand the YM2612
more before messing with them.
The coordination flags differ from game to game. They are the same in
Sonic 1 and 2, but different in the others. For now, I will only give
the flags for Sonic 1 and 2. Not all of them are known, but a majority
are.
E0xx - panning, AMS, FMS
. . . . xx - Value
. . . . . Bit 7 - Left Channel status
. . . . . Bit 6 - Right Channel Status
. . . . . Bit 5-4 - AMS
. . . . . Bit 3 - 0
. . . . . Bit 2-0 - FMS
E6xx - Change channel volume with xx
. . . . xx - Signed Value
E7xx - prevent next note from attacking
E8xx - set note fill amount to xx
E9xx - add xx to channel key
EAxx - set music tempo to xx
EBxx - Change Tempo Modifier to xx for ALL channels
ECxx - Change channel volume by xx
. . . . xx - Signed Value
EE - Something with Voice Selection
EFxx - set voice selection to xx
F0wwxxyyzz - modulation
. . . . ww - Wait for ww period of time before modulation starts
. . . . xx - Modulation Speed
. . . . yy - Modulation change per Mod. Step
. . . . zz - Number of steps in modulation
F1 - Turn on modulation
F2 - stop the track
F4 - Turn off modulation
F5xx - Store xx into the voice storage
F6yyyy - jump to position yyyy
F7xxyyyy - repeat xx times at position yyyy before moving on
F8yyyy - jump to position yyyy (keep previous position in memory for
returning)
F9 - return
Now, you will notice that some of these flags speak of a signed value.
Signed values have the capability to be positive or negative. What
makes a hexadecimal value signed? Bit number 7, the first bit on the
left, will be 1 for negative and 0 for positive. So, a hexadecimal
value that is 00-7F is positive, and values 80-FF are negative. Here's
an example:
Lets say that you wanted to go back 9 bytes to locate some music data
in Sonic 1. Sonic 1 uses relative pointers, so lets use a signed value.
With signed bytes, FFFF is the lowest value you can have. FFFF
resembles zero. So FFFE would be -1, FFFD would be -2, etc. Signed
values are used to locate data before the current location. So if I
wanted to locate data that was 9 bytes back from my current location, I
would take FFFF and subtract 9 bytes in hex from it. This leaves me
with FFF6. If you wanted to go forward 9 bytes, you would take FFFF and
add 9 to it (while keeping it 16-bit), which would be 0008. This is
confusing, and kinda advanced, but if you plan on learning 68k ASM at
all, it's something you have to know.
Game specifics
Sonic 2:
Master Playlist:
Sonic 2 has a special Master playlist that defines what music ID plays
in what slot. All values for music subtract 1 from the value. So to
change Track 81 to Track 82, change 80 to 81. 80 is 81, 81 is 82, etc.
These values go up to slot 9F, or 1F in the final version of the game.
The locations are as follows.
Master Playlist in Sonic 2 Beta: ECE9F
Master Playlist in Sonic 2 Final: ECF36
As said before, track 81 is represented by 80, 82 is reresented by 81,
etc. If you see an FF, skip it and move on to the next byte. This
master playlist is only in Sonic 2 as far as I know. If I find it in
any other games, I will update this section.
Music Compression:
In Sonic 2 Final, there is a compression applied to all music data in
the game except for the credits. This format has been dubbed the Saxman
compression, named after the person who cracked the format. I will not
note how to manually decompress this format -- Refer to Saxman's
hacking guide to do so. The music can be decompressed by using Magus'
Sega Data Compressor. Refer to the pointer format to edit the music
properly.
Music locations
Now that you know all the basics, you can start editing music. Here are
some locations for various games that will help. You can use the music
pointers to locate the music data for now, but I may document the
locations of each individual track in the future.
Sonic 1:
Music Pointers: 71A9C
Sound Effect Pointers: 78B44
Sonic 2 Beta:
Music Pointers (These add to F0000, for 98-9F): F0000
Music Pointers (These add to F8000): F8000
Sonic 2 Final:
Music Pointers (These add to F8000): F8000
Music Pointers (These add to F8000 and are for 98-9F, excluding
continue): F802A
Continue music pointer (This adds to F0000): F0000
Sound Effect Pointers (These add to F8000): FEE91
Sonic Crackers:
Music Pointers: 0633F
Track 81: 10000
Track 82: 1088C
Track 83: 10BDA
Track 84: 11210
Track 85: 1172B
Track 86: 11B10
Sonic 3:
Music Pointers (These add to C8000): E761A
Music Pointers (These add to D0000): E762E
Music Pointers (These add to D8000): E7652
Sonic 3D:
Music Pointers (These add to C0000): D3233
Music Pointers (These add to C8000): D3245
Music Pointers (These add to D0000): D325D
Sound Effect Pointers (These add to D8000): D3297
Knuckles Chaotix:
Music pointers (These add to 40000): $76AE9
Music pointers (These add to 48000): $76B05
Music pointers (These add to 50000): $76B33
Sonic & Knuckles:
Music Pointers: F793E
Specifics...
These add to 2C8000:
01 - 8000 - AIZ1
02 - 9B6D - AIZ2
03 - B0BC - HZ1
04 - C0C6 - HZ2
05 - D364 - MGZ1
06 - D97B - MGZ2
07 - E48F - CNZ1
08 - DDA9 - CNZ2
These add to E8000:
09 - 8000 - FBZ1
0A - 8597 - FBZ2
These add to 2D0000:
0B - 86AA - IZ1
0C - 8000 - IZ2
0D - 9345 - LBZ1
0E - 8DC8 - LBZ2
These add to E8000:
0F - 8AFF - MHZ1
10 - 9106 - MHZ2
11 - 9688 - SZ1
12 - 9CF2 - SZ2
13 - A2E5 - LRZ1
14 - ACF3 - LRZ2
15 - BE80 - SSZ
16 - C2B4 - DEZ1
17 - C79F - DEZ2
18 - CBB1 - Act 1 Boss
19 - CEE1 - Robotnik Boss
1A - D3DD - Doomsday
1B - DCC0 - Rolling Jump Bonus Stage
1C - E223 - Special Stage
1D - EABB - Slot Machine Bonus Stage
This adds to 2D8000:
1E - 8AE8 - Gum Ball Machine Bonus Stage
This adds to E8000:
1F - F5A3 - Knuckles Theme
These add to 2D8000:
20 - 99F7 - Azure Lake
21 - A4FD - Baloon Park
22 - B0EC - Desert Palace
23 - C324 - Chrome Gadget
24 - DA47 - Endless Mine
These add to E8000:
25 - F88E - Title
This adds to 2D8000:
26 - E587 - S3 credits
These add to E0000:
27 - DD4B - Game/Time Over
28 - DFA6 - Continue
29 - E3C0 - Bonus Screen
These add to E8000:
2A - FD4B - 1UP
2B - FE75 - Chaos Emerald
This adds to E0000:
2C - E574 - Invincible
This adds to 2D8000:
2D - F5E4 - Competition Menu
This adds to E8000:
2E - CBB1 - Act 1 Boss (same as 18)
These add to E0000:
2F - E7AF - Menu
30 - F74C - Final Boss
This adds to 2D8000:
31 - FABE - S3 countdown
These add E0000:
32 - FCDE - S&K outro
DC - C104 - S&K credits
Ristar:
Music Pointers (32-bit): C852A
Music Locations:
000CDBF4 - Flora 1 [shooting ristar]
000CEA0E - Scorch 1 [busy flare]
000CF6B6 - Flora 2 bgm [dancing leaves]
000D05F6 - Pre boss [concentration]
000D0774 - Sonata 1 (initial bgm) [intension]
000D0AC6 - Sonata 1 (1st metronome)
000D0E7C - Sonata 1 (2nd metronome)
000D1218 - Sonata 1 (final metronome)
000D1520 - Sonata 2 [on parade]
000D1E88 - Automaton 2 [lock up]
000D2C38 - Freon 1 [ring rink]
000D36DC - Undertow 2 [break silence]
000D4346 - Boss [crazy kings]
000D4DBE - Scorch 2 [under magma]
000D5A0A - Undertow 1 [splash down]
000D6752 - Freon 2 [ice scream]
000D732C - Ending 2 [next cruise]
000D7E4E - Sonata 1 (mini boss) [du di du da]
000D81E8 - Intro 1 [ebony force]
000D858C - Bonus [ready...GO!]
000D8D80 - Intro 2/ Title [pray pray play!]
000D97EC - Bonus (preview) [formation lap]
000D997A - Continue Screen
000D9CFC - Greedy [theme of kaiser]
000DAA66 - Automaton 1 [crying world]
000DAFB2 - Ending 1 [star humming]
000DC422 - Sonata 1 (initial bgm) [intension] *MID ROUND??*
000DC69A - round clear 2 [beyond space]
000DCF66 - round clear 1 [lets go]
000DD240 - area clear [go ahead]
000DD5C8 - game over [game over .. fuu]
000DD7EC - defeated Greedy, before imploding cutscene
000DD978 - Sonata 1 (mini boss 3 note intro)
000DDA1E - "Sega" music
MJ's Moonwalker:
Music Pointers (32-bit): 600A4
Back to the main page
Table of contents