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