Research / Sonic 2 / The Sonic music hacking guide The Sonic music hacking guide:*Created by Tweaker on May 25 2005.* *Thanks to Saxman and fuzzbuzz.* *Corrected by Sonic Hachelle-Bee.* 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 explanation 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 (program counter). 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: Let's 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 musics. 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.
Knuckles Chaotix:In Knuckles Chaotix, this format is slightly different to accomodate to the 32x's hardware. I have listed it below.
Understanding the header is essential for 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.
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.
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.
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 between 00 and 7F is positive, and values between 80 and FF are negative. Here's an example: Let's say that you wanted to go back 9 bytes to locate some music data in Sonic 1. Sonic 1 uses relative pointers, so let's use a signed value. With signed bytes, 0000 is the lowest value you can have. So FFFF would be -1, FFFE 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 0000 and subtract 9 bytes in hex from it. This leaves me with FFF7. If you wanted to go forward 9 bytes, you would take 0000 and add 9 to it (while keeping it 16-bit), which would be 0009. 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 - TDZ 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 This adds to $E8000: 25 - F88E - Title This adds to $2D8000: 26 - E587 - Sonic 3 credits These add to $E0000: 27 - DD4B - Game/Time over 28 - DFA6 - Continue 29 - E3C0 - Bonus screen These add to $E8000: 2A - FD4B - Extra life 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 - Sonic 3 countdown These add $E0000: 32 - FCDE - Sonic & Knuckles outro DC - C104 - Sonic & Knuckles credits Ristar:Music Pointers (32-bit): $C852A Music Locations: $CDBF4 - Flora 1 [shooting ristar] $CEA0E - Scorch 1 [busy flare] $CF6B6 - Flora 2 bgm [dancing leaves] $D05F6 - Pre boss [concentration] $D0774 - Sonata 1 (initial bgm) [intension] $D0AC6 - Sonata 1 (1st metronome) $D0E7C - Sonata 1 (2nd metronome) $D1218 - Sonata 1 (final metronome) $D1520 - Sonata 2 [on parade] $D1E88 - Automaton 2 [lock up] $D2C38 - Freon 1 [ring rink] $D36DC - Undertow 2 [break silence] $D4346 - Boss [crazy kings] $D4DBE - Scorch 2 [under magma] $D5A0A - Undertow 1 [splash down] $D6752 - Freon 2 [ice scream] $D732C - Ending 2 [next cruise] $D7E4E - Sonata 1 (mini boss) [du di du da] $D81E8 - Intro 1 [ebony force] $D858C - Bonus [ready...GO!] $D8D80 - Intro 2/ Title [pray pray play!] $D97EC - Bonus (preview) [formation lap] $D997A - Continue screen $D9CFC - Greedy [theme of kaiser] $DAA66 - Automaton 1 [crying world] $DAFB2 - Ending 1 [star humming] $DC422 - Sonata 1 (initial bgm) [intension] *MID ROUND??* $DC69A - round clear 2 [beyond space] $DCF66 - round clear 1 [lets go] $DD240 - area clear [go ahead] $DD5C8 - game over [game over .. fuu] $DD7EC - defeated Greedy, before imploding cutscene $DD978 - Sonata 1 (mini boss 3 note intro) $DDA1E - "Sega" music MJ's Moonwalker:Music Pointers (32-bit): $600A4 Back | Printer friendly 2. Sprites and objects sound effects >> |