Actions

SCHG

Difference between revisions of "Music Hacking"

From Sonic Retro

(Knuckles' Chaotix)
m (Text replacement - "Djbrayster" to "Djbrayster")
(20 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 +
{{SMPSHackingNav}}
 +
 
==Original Credits==
 
==Original Credits==
Guide originally created by [[Tweaker]] on May 25 2005.
+
Guide originally created by [[User:Tweaker|Tweaker]] on May 25 2005.
  
 
Thanks to:
 
Thanks to:
* [[saxman]]
+
* [[User:Saxman|saxman]]
 
* [[fuzzbuzz]]  
 
* [[fuzzbuzz]]  
 
* [[Erik JS]]
 
* [[Erik JS]]
* [[Djbrayster]]
+
* [[User:Djbrayster|Djbrayster]]
* [[Heran Bago]]
+
* [[User:Heran Bago|Heran Bago]]
* [[SGR]]
+
* [[User:SGR|SGR]]
* [[Tweaker]]
+
* [[User:Tweaker|Tweaker]]
  
 
==Prologue==
 
==Prologue==
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. It's also recommended that you read and save a copy of [http://web.archive.org/web/20080623092652/http://www.smspower.org/maxim/docs/ym2612/index.html the YM2612 technical documentation] and maybe [http://web.archive.org/web/20080623092652/http://www.smspower.org/maxim/docs/SN76489.txt the PSG documentation] so that you can more easily understand how the voices and coordination flags work.
+
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. It's also recommended that you read and save a copy of [http://www.smspower.org/maxim/Documents/YM2612 the YM2612 technical documentation] and maybe [http://www.smspower.org/Development/SN76489 the PSG documentation] so that you can more easily understand how the voices and coordination flags work.
  
 
==Update history==
 
==Update history==
Line 35: Line 37:
 
Anyway, I finally got the realtime music editing section done. Savestate locations and Z80 RAM equivalents are listed, with explanations on how to tinker with music, even while it’s still playing. Also added locations for a shitload of games, mostly from my notes. I also added more to the music porting section. And once again, various corrections and such... I can't be arsed to keep track of what I change anymore, so bleh. =P
 
Anyway, I finally got the realtime music editing section done. Savestate locations and Z80 RAM equivalents are listed, with explanations on how to tinker with music, even while it’s still playing. Also added locations for a shitload of games, mostly from my notes. I also added more to the music porting section. And once again, various corrections and such... I can't be arsed to keep track of what I change anymore, so bleh. =P
  
==Pointer format==
+
* August 22 2011: updated by kram1024, flamewing and others with all the new info discovered recently about smps by flamewing's most recent disasm of the s&k driver.
Pointers, as they pertain to SMPS, are values used to locate data at any point in the file. In the context of music editing, pointers will be used to locate the start of each channel's notation data; in addition, they are also used to branch to certain portions of data within the actual data through the use of [[SCHG:Music Hacking#Coordination Flags|coordination flags]]. This section in particular will describe the format used in the song headers and within the branching flags--F6, F7, and F8, respectively.
 
 
 
===68k SMPS===
 
====Header====
 
Pointers in the header of a song are 16-bits (two bytes) and work relative to the beginning of the song file. For example, when working with a standalone piece of SMPS data, if the voice pointer reads '''0180''', you would go to offset $180 within the file to locate the voice data.
 
 
 
If you're working with a song inside a full compiled ROM, the process is similar--simply take the offset where the song data starts and add the voice pointer's value to calculate the offset of the data. So, for example, if your music is at offset $E8900 in the ROM, you'd take the voice pointer value--in this case, $180--and you'd add it to the offset in order to locate the data. In this particular instance, $E8A80 would be the resulting offset, and subsequently the location of the voice data in the song.
 
 
 
This pointer format applies to all pointers within the header of a piece of SMPS data.
 
 
 
===Coordination Flags===
 
In contrast to Z80 SMPS, the pointer format in branching coordination flags differs slightly. As before, each pointer is two bytes, but this time pointers are relative to the start of the pointer--''not'' the start of the song file. To clarify, if you were using the format of the F7 flag--'''F7 xx yy zzzz'''--the pointer would be relative to the offset in the file where '''zzzz''' is stored.
 
 
 
Pointers in coordination flags use signed relative values to locate data both after and before the current location. To do this, there is an imposed limit of about $8000 bytes in either direction on how far one single flag can branch in the song. When dealing with these flags, a value of '''FFFF''' acts as zero; in other words, a pointer value of '''FFFF''' would branch to the current location--nowhere.
 
 
 
To branch ahead of the current location, one would increase the value beyond '''FFFF''' to jump ahead. So, for example, if our pointer was '''0298''', we would be branching ahead $299 bytes from our current location. Assuming the current location is $E8000, this branch would be locating data at offset $E8299. A general formula you could use in order to calculate the length of positive branches quickly would be to increase a pointer value by $1--this would help you get into the mindset of locating data more adeptly.
 
 
 
To branch ''before'' the current location, one would decrease the value beyond '''FFFF''' to jump back. So, for example, if our pointer was '''FFE8''', we would be branching $17 bytes before the current location. Assuming our current location is, once again, $E8000, this branch would be locating data at offset $E7FE9. The easiest way to calculate the length of a negative branch would be to take the pointer value and subtract it from '''FFFF'''. In our previous example, subtracting '''FFE8''' from '''FFFF''' gives a result of $17.
 
 
 
68k SMPS is unique in that each song is literally self-contained--a song can be stored at any offset within a ROM and the relative nature of the pointers will always locate data properly. This is a significant advantage over the Z80 variant of the engine, which requires all data to be at absolute offsets within a data bank.
 
 
 
<u>'''Points of note:'''</u>
 
* ''[[Ristar]]'''s coordination flag pointers have $1 added to them, compared to the pointers in other 68k SMPS games. If you want to convert between the two, just add or subtract $1 thusly.
 
* Some 68k SMPS games use the ''Sonic 3''-style coordination flags.
 
 
 
===Z80 SMPS===
 
Z80 SMPS differs from its 68k counterpart in a few different ways.
 
 
 
First and foremost, unlike 68k SMPS, the same pointer format is used in both the coordination flags ''and'' the header. All pointers are stored in little-endian format due to the nature of the processor; in other words, the byte order is reversed. If a pointer reads '''7880''', you should mentally parse it as referring to bank offset '''8078'''.
 
 
 
Secondly, pointers are absolute instead of relative, but are only absolute in terms of the current Z80 data bank. Pointer values will ''always'' start with a value of '''8000''', regardless of whether or not the bank itself is stored at an offset that contains 8000 as part of the address; this is so the music can be properly located in the context of the Z80 bank. So, for example, if the current Z80 bank is at offset $70000, a pointer value of '''7880''' (which, when swapped, becomes '''8078''') would be locating data at offset $70078.
 
 
 
When dealing with standalone Z80 SMPS files, it is required that you first make note of the starting offset of the song within its respective Z80 bank before you can properly calculate pointer values within the song. So, for example, if a song is located at offset $F0900 in the ROM, your starting offset for the song will be '''8900'''. To calculate relative offsets within the file where data is stored, subtract the starting offset from your pointer value. So, for example, if our DAC pointer reads value '''508E''' (which after swapping the bytes becomes '''8E50'''), the relative offset of our DAC notation within the file will be offset $550, or $550 bytes from the start of the song file.
 
 
 
This process is relatively simpler for the SMPS variant used in the SMS version of Sonic 2; since all music data is contained in bank 2 ($8000-$FFFF), simply convert the pointer to big endian and use that as your absolute address in the ROM.
 
 
 
In addition to within Z80 SMPS data, this format is also used to locate data within a game's music pointer index.
 
 
 
===Sonic 2 Final/Mega Man: Wily Wars===
 
''[[Sonic 2]]'' is a special case amongst games that use the Z80 SMPS engine in that its music is compressed to individual files in the [[saxman compression]], which are subsequently parsed within Z80 RAM.
 
 
 
In contrast to normal Z80 SMPS music, the only difference is that compressed music in ''Sonic 2'' always has a starting offset of '''1380'''. All operations regarding the calculation of offsets from pointers remains the same. It is, however, worth noting that not ''all'' music in ''Sonic 2'' is compressed; exceptions are noted as such later on in the guide.
 
 
 
Mega Man: Wily Wars stores songs uncompressed, but also has music copied to Z80 RAM. The starting offset for this game is always '''$1002'''.
 
 
 
==Header format==
 
===Mega Drive SMPS===
 
 
 
All pointers in this section differ according to the game you are editing. Remember, relative pointers for 68k SMPS, and absolute little endian pointers for Z80 SMPS. The music header format listed is a universal format used in all incarnations of the SMPS engine except for ''Knuckles' Chaotix'', which uses a slightly modified version to accommodate for the extra sound hardware (the PWM sound channels).
 
 
 
{| class="prettytable"
 
! Byte offset||Description
 
|-
 
| $00-$01
 
| Voice pointer. This points to the location of the voice data, or instruments, in the song.
 
|-
 
| $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 PSG noise channel. It will be located right after the instrument modifier for the 3rd PSG modifier.
 
|-
 
| $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, and change the first byte to determine the range of tempo values you can achieve. The higher the divider, the slower the tempo can be.
 
|-
 
| $06-$07
 
| DAC pointer. This channel is generally used for the drums you hear in the music, though it can be used to play any type of DAC sample available for use.
 
|-
 
| $08-$09
 
| Unused.
 
|-
 
| $0A-$0B
 
| FM channel 1 pointer. It points to FM channel 1.
 
|-
 
| $0C-$0D
 
| FM channel 1 modifier. First byte modifies pitch, and second byte modifies volume (same for all).
 
* NOTE: Volume works "backwards" - the lower the value, the higher the volume.
 
|-
 
| $0E-$0F
 
| FM channel 2 pointer.
 
|-
 
| $10-$11
 
| FM channel 2 modifier
 
|-
 
| $12-$13
 
| FM channel 3 pointer.
 
|-
 
| $14-$15
 
| FM channel 3 modifier.
 
|-
 
| $16-$17
 
| FM channel 4 pointer.
 
|-
 
| $18-$19
 
| FM channel 4 modifier.
 
|-
 
| $1A-$1B
 
| FM channel 5 pointer.
 
|-
 
| $1C-$1D
 
| FM channel 5 modifier.
 
|-
 
| $1E-$1F
 
| PSG channel 1 pointer.
 
|-
 
| $20-$21
 
| PSG channel 1 modifier.
 
|-
 
| $22-$23
 
| Current PSG 1 instrument. First byte is redundant. Change the value to change the sound of the PSG tone produced.
 
|-
 
| $24-$25
 
| PSG channel 2 pointer.
 
|-
 
| $26-$27
 
| PSG channel 2 modifier.
 
|-
 
| $28-$29
 
| Current PSG 2 instrument.
 
|-
 
| $2A-$2B
 
| PSG channel 3 pointer.
 
|-
 
| $2C-$2D
 
| PSG channel 3 modifier.
 
|-
 
| $2E-$2F
 
| Current PSG 3 Instrument.
 
|}
 
 
 
===32X SMPS===
 
The format for the SMPS music header is slightly different to accommodate for the 32x's extra sound hardware.
 
 
 
{| class="prettytable"
 
!Word offset||Description
 
|-
 
| $00-$01
 
| Voice pointer.
 
|-
 
| $02-$03
 
| Channel setup.
 
|-
 
| $04-$05
 
| Tempo modifier.
 
|-
 
| $06-$07
 
| FM channel 1 pointer.
 
|-
 
| $08-$09
 
| FM channel 1 modifier.
 
|-
 
| $0A-$0B
 
| FM channel 2 pointer.
 
|-
 
| $0C-$0D
 
| FM channel 2 modifier.
 
|-
 
| $0E-$0F
 
| FM channel 3 pointer.
 
|-
 
| $10-$11
 
| FM channel 3 modifier.
 
|-
 
| $12-$13
 
| FM channel 4 pointer.
 
|-
 
| $14-$15
 
| FM channel 4 modifier.
 
|-
 
| $16-$17
 
| FM channel 5 pointer.
 
|-
 
| $18-$19
 
| FM channel 5 modifier.
 
|-
 
| $1A-$1B
 
| FM channel 6 pointer.
 
|-
 
| $1C-$1D
 
| FM channel 6 modifier.
 
|-
 
| $1E-$1F
 
| PSG channel 1 pointer.
 
|-
 
| $20-$21
 
| PSG channel 1 modifier.
 
|-
 
| $22-$23
 
| Current PSG 1 instrument.
 
|-
 
| $24-$25
 
| PSG channel 2 pointer.
 
|-
 
| $26-$27
 
| PSG channel 2 modifier.
 
|-
 
| $28-$29
 
| Current PSG 2 instrument.
 
|-
 
| $2A-$2B
 
| PSG channel 3 pointer.
 
|-
 
| $2C-$2D
 
| PSG channel 3 modifier.
 
|-
 
| $2E-$2F
 
| Current PSG 3 instrument.
 
|-
 
| $30-$31
 
| PWM channel 1 pointer. This will point to one of the four available PWM channels used for percussion and other samples that can be played in the song. It works exactly like DAC, except there are more channels available for use.
 
|-
 
| $32-$33
 
| PWM channel 1 modifier. Unlike DAC, the pitch and volume of a PWM channel ''can'' be changed, and in the same way as any other melodic sound channel. However, the volume byte will work by output strength, and not resistance--in other words, the higher the value, the louder the sample.
 
|-
 
| $34-$35
 
| PWM channel 2 pointer.
 
|-
 
| $36-$37
 
| PWM channel 2 modifier.
 
|-
 
| $38-$39
 
| PWM channel 3 pointer.
 
|-
 
| $3A-$3B
 
| PWM channel 3 modifier.
 
|-
 
| $3C-$3D
 
| PWM channel 4 pointer.
 
|-
 
| $3E-$3F
 
| PWM channel 4 modifier.
 
|}
 
 
 
===Master System/Game Gear SMPS===
 
Since the SMS only has 4 PSG channels (3 tone, 1 noise), the header format is changed to accomodate this.
 
 
 
{| class="prettytable"
 
!Word offset||Description
 
|-
 
| $00-$01
 
| Unknown - pointer to PSG envelope data?
 
|-
 
| $02-$03
 
| Channel setup. Only the first byte is used, and it can range from $01 to $04.
 
|-
 
| $04-$05
 
| Tempo modifier.
 
|-
 
| $06-$07
 
| PSG channel 1 pointer.
 
|-
 
| $08-$09
 
| PSG channel 1 modifier.
 
|-
 
| $0A-$0B
 
| PSG channel 2 pointer.
 
|-
 
| $0C-$0D
 
| PSG channel 2 modifier.
 
|-
 
| $0E-$0F
 
| PSG channel 3 pointer.
 
|-
 
| $10-$11
 
| PSG channel 3 modifier.
 
|-
 
| $12-$13
 
| PSG channel 4 pointer. Channel 4 is always the noise channel.
 
|-
 
| $14-$15
 
| PSG channel 4 modifier.
 
|}
 
 
 
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.
 
 
 
===Sega CD SMPS ("SMPS-PCM")===
 
Since SMPS-PCM runs on a CPU that can only access the Sega CD's PCM chip which hooks into a global sample bank (for each SMPS program on disc), the header is different:
 
 
 
{| class="prettytable"
 
!Offset||Size||Description
 
|-
 
| $00
 
| Word
 
| 0 - as SMPS grabs sample data from its own bank
 
|-
 
| $02
 
| Byte
 
| Channel setup. Usually 8 or 9.
 
|-
 
| $03
 
| Byte
 
| 0 - only one sound source is used.
 
|-
 
| $04-$05
 
| Byte, byte
 
| Tempo modifier; see above.
 
|-
 
| $06, $0A, $0E, etc.
 
| Word
 
| PCM channel n pointer
 
|-
 
| $08, $0C, $10, etc.
 
| Byte
 
| 0
 
|-
 
| $09, $0D, $11, etc.
 
| Byte
 
| PCM channel n modifier. The signed value is added to the note value grabbed from the song; so if this is $FD (-$3) and the note byte in the song data is $93, it is treated as if it was a byte $90 instead. Coordination flag $FB changes this later.
 
|-
 
|}
 
 
 
==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. Swapping and copying voices is a simple copy-paste job. A voice is $19 hex bytes, and has no header. It is raw data that gives information to the [[YM2612]] FM chip in the Megadrive to give the desired sound output. The format of a voice is as follows.
 
 
 
{| class="prettytable"
 
! rowspan="2" | Offset
 
! rowspan="2" | Description
 
! colspan="3" | Register
 
|-
 
! Ch.1/3||Ch.2/4||Ch.3/6
 
|-
 
| $0
 
| Feedback (next 3 bits) / Algorithm (lower 3 bits)
 
| B0 || B1 || B2
 
|-
 
| $1
 
| Detune of operator 1 (nybble 1) / Coarse-frequency multiplier [MULT] of operator 1 (nybble 2)
 
| 30 || 31 || 32
 
|-
 
| $2
 
| Detune of operator 3 (nybble 1) / Coarse-frequency multiplier [MULT] of operator 3 (nybble 2)
 
| 38 || 39 || 3A
 
|-
 
| $3
 
| Detune of operator 2 (nybble 1) / Coarse-frequency multiplier [MULT] of operator 2 (nybble 2)
 
| 34 || 35 || 36
 
|-
 
| $4
 
| Detune of operator 4 (nybble 1) / Coarse-frequency multiplier [MULT] of operator 4 (nybble 2)
 
| 3C || 3D || 3E
 
|-
 
| $5
 
| Rate scaling [RS] of operator 1 (upper 2 bits) / Attack rate [AR] of operator 1 (lower 5 bits)
 
| 50 || 51 || 52
 
|-
 
| $6
 
| Rate scaling [RS] of operator 3 (upper 2 bits) / Attack rate [AR] of operator 3 (lower 5 bits)
 
| 58 || 59 || 5A
 
|-
 
| $7
 
| Rate scaling [RS] of operator 2 (upper 2 bits) / Attack rate [AR] of operator 2 (lower 5 bits)
 
| 54 || 55 || 56
 
|-
 
| $8
 
| Rate scaling [RS] of operator 4 (upper 2 bits) / Attack rate [AR] of operator 4 (lower 5 bits)
 
| 5C || 5D || 5E
 
|-
 
| $9
 
| LFO enabled [AM] for operator 1 / First decay rate [D1R/DR] of operator 1 (lower 5 bits)
 
| 60 || 61 || 62
 
|-
 
| $A
 
| LFO enabled [AM] for operator 3 / First decay rate [D1R/DR] of operator 3 (lower 5 bits)
 
| 68 || 69 || 6A
 
|-
 
| $B
 
| LFO enabled [AM] for operator 2 / First decay rate [D1R/DR] of operator 2 (lower 5 bits)
 
| 64 || 65 || 66
 
|-
 
| $C
 
| LFO enabled [AM] for operator 4 / First decay rate [D1R/DR] of operator 4 (lower 5 bits)
 
| 6C || 6D || 6E
 
|-
 
| $D
 
| Second decay rate/sustain rate [D2R/SR] of operator 1
 
| 70 || 71 || 72
 
|-
 
| $E
 
| Second decay rate/sustain rate [D2R/SR] of operator 3
 
| 78 || 79 || 7A
 
|-
 
| $F
 
| Second decay rate/sustain rate [D2R/SR] of operator 2
 
| 74 || 75 || 76
 
|-
 
| $10
 
| Second decay rate/sustain rate [D2R/SR] of operator 4
 
| 7C || 7D || 7E
 
|-
 
| $11
 
| First decay level/start level [D1L/SL] of operator 1 (nybble 1) / Release rate [RR] of operator 1 (nybble 2)
 
| 80 || 81 || 82
 
|-
 
| $12
 
| First decay level/start level [D1L/SL] of operator 3 (nybble 1) / Release rate [RR] of operator 3 (nybble 2)
 
| 88 || 89 || 8A
 
|-
 
| $13
 
| First decay level/start level [D1L/SL] of operator 2 (nybble 1) / Release rate [RR] of operator 2 (nybble 2)
 
| 84 || 85 || 86
 
|-
 
| $14
 
| First decay level/start level [D1L/SL] of operator 4 (nybble 1) / Release rate [RR] of operator 4 (nybble 2)
 
| 8C || 8D || 8E
 
|-
 
| $15
 
| Total level [TL] of operator 1
 
| 40 || 41 || 42
 
|-
 
| $16
 
| Total level [TL] of operator 3
 
| 48 || 49 || 4A
 
|-
 
| $17
 
| Total level [TL] of operator 2
 
| 44 || 45 || 46
 
|-
 
| $18
 
| Total level [TL] of operator 4
 
| 4C || 4D || 4E
 
|}
 
 
 
It should be noted that ''[[Sonic 2]]'' uses a different format than the other main Sonic games; to correcty convert songs from and to that game, it is necessary to swap the second and the third byte in each group of operators, as shown in the following chart:
 
[[Image:VoiceOperators.png]]
 
 
 
==Note Editing==
 
The way the music is set up in the Sonic games is similar to how music is structured in a module file. Here are some values that will help you directly edit notation data in the music.
 
 
 
Notation is SMPS usually follows the same general formula:
 
 
 
<center>'''Note | Duration'''</center>
 
 
 
What's worth noting, however, is that the format of notation is not strictly limited by a note definition followed by a duration. Once either a note or a duration value is defined, you can omit repetition of those values; however, you must ''always'' define a note before you can define a duration for the first time.
 
 
 
An example of valid note combinations:
 
 
 
 
 
<center>'''81 01 04 03 02'''</center>
 
 
 
This particular combination of values will play note $81 at multiple durations--first 01, then 04, then 03, and then 02. As long as a note is defined, its value will stay in memory and be repeated on any subsequent duration parsed in the channel.
 
 
 
Another example:
 
 
 
<center>'''82 02 81 82 83 84 86 8F'''</center>
 
 
 
This combination of values will play all of the defined notes with a duration of 02--first 82, then 81, then 82, then 83... so on and so forth. As previously stated, the first definition in a string of values must ''always'' be a note. When repeating notes instead of definitions to omit duplicate data, the string will be ended by placing a new duration value.
 
 
 
Remember that when placing a new duration, it will apply to the last defined note value... so if there were a duration value of 07 after '''8F''', it would play with a duration of 07 instead of 02.
 
 
 
===Value Definitions===
 
The values you see in notation have varying ranges with different purposes. Their significance is as follows:
 
 
 
{| class="prettytable"
 
! Range||Purpose
 
|-
 
|$00-$7F||Note duration (How long a note is held for)
 
|-
 
|$80-$DF||Notes (80 is a rest)
 
|-
 
|$E0-$FF||Coordination flags
 
|}
 
 
 
===Note Equivalents===
 
{| class="prettytable"
 
! Value||Note
 
|-
 
|$81||C
 
|-
 
|$82||C♯/D♭
 
|-
 
|$83||D
 
|-
 
|$84||D♯/E♭
 
|-
 
|$85||E
 
|-
 
|$86||F
 
|-
 
|$87||F♯/G♭
 
|-
 
|$88||G
 
|-
 
|$89||G♯/A♭
 
|-
 
|$8A||A
 
|-
 
|$8B||A♯/B♭
 
|-
 
|$8C||B
 
|-
 
|$8D||1C
 
|-
 
|$8E||1C♯/D♭
 
|-
 
|$8F||1D
 
|-
 
|$90||1D♯/E♭
 
|-
 
|$91||1E
 
|-
 
|$92||1F
 
|-
 
|$93||1F♯/G♭
 
|-
 
|$94||1G
 
|-
 
|$95||1G♯/A♭
 
|-
 
|$96||1A
 
|-
 
|$97||1A♯/B♭
 
|-
 
|$98||1B
 
|-
 
|$99||2C
 
|-
 
|$9A||2C♯/D♭
 
|-
 
|$9B||2D
 
|-
 
|$9C||2D♯/E♭
 
|-
 
|$9D||2E
 
|-
 
|$9E||2F
 
|-
 
|$9F||2F♯/G♭
 
|-
 
|$A0||2G
 
|-
 
|$A1||2G♯/A♭
 
|-
 
|$A2||2A
 
|-
 
|$A3||2A♯/B♭
 
|-
 
|$A4||2B
 
|-
 
|$A5||3C
 
|-
 
|$A6||3C♯/D♭
 
|-
 
|$A7||3D
 
|-
 
|$A8||3D♯/E♭
 
|-
 
|$A9||3E
 
|-
 
|$AA||3F
 
|-
 
|$AB||3F♯/G♭
 
|-
 
|$AC||3G
 
|-
 
|$AD||3G♯/A♭
 
|-
 
|$AE||3A
 
|-
 
|$AF||3A♯/B♭
 
|-
 
|$B0||3B
 
|-
 
|$B1||4C
 
|-
 
|$B2||4C♯/D♭
 
|-
 
|$B3||4D
 
|-
 
|$B4||4D♯/E♭
 
|-
 
|$B5||4E
 
|-
 
|$B6||4F
 
|-
 
|$B7||4F♯/G♭
 
|-
 
|$B8||4G
 
|-
 
|$B9||4G♯/A♭
 
|-
 
|$BA||4A
 
|-
 
|$BB||4A♯/B♭
 
|-
 
|$BC||4B
 
|-
 
|$BD||5C
 
|-
 
|$BE||5C♯/D♭
 
|-
 
|$BF||5D
 
|-
 
|$C0||5D♯/E♭
 
|-
 
|$C1||5E
 
|-
 
|$C2||5F
 
|-
 
|$C3||5F♯/G♭
 
|-
 
|$C4||5G
 
|-
 
|$C5||5G♯/A♭
 
|-
 
|$C6||5A
 
|-
 
|$C7||5A♯/B♭
 
|-
 
|$C8||5B
 
|-
 
|$C9||6C
 
|-
 
|$CA||6C♯/D♭
 
|-
 
|$CB||6D
 
|-
 
|$CC||6D♯/E♭
 
|-
 
|$CD||6E
 
|-
 
|$CE||6F
 
|-
 
|$CF||6F♯/G♭
 
|-
 
|$D0||6G
 
|-
 
|$D1||6G♯/A♭
 
|-
 
|$D2||6A
 
|-
 
|$D3||6A♯/B♭
 
|-
 
|$D4||6B
 
|-
 
|$D5||7C
 
|-
 
|$D6||7C♯/D♭
 
|-
 
|$D7||7D
 
|-
 
|$D8||7D♯/E♭
 
|-
 
|$D9||7E
 
|-
 
|$DA||7F
 
|-
 
|$DB||7F♯/G♭
 
|-
 
|$DC||7G
 
|-
 
|$DD||7G♯/A♭
 
|-
 
|$DE||7A
 
|-
 
|$DF||7A♯/B♭
 
|}
 
 
 
===DAC Sample Definitions===
 
====Sonic 1====
 
{| class="prettytable"
 
! Value||Sample
 
|-
 
|$81||Kick
 
|-
 
|$82||Snare
 
|-
 
|$83||Hi-Timpani
 
|-
 
|$84||Noise
 
|-
 
|$85||Noise
 
|-
 
|$86||Noise
 
|-
 
|$87||Sega Sound
 
|-
 
|$88||Hi-Timpani
 
|-
 
|$89||Mid-Timpani
 
|-
 
|$8A||Low-Timpani
 
|-
 
|$8B||Low-Timpani
 
|}
 
====Sonic 2 Beta====
 
{| class="prettytable"
 
! Value||Sample
 
|-
 
|$81||Kick
 
|-
 
|$82||Snare
 
|-
 
|$83||Clap
 
|-
 
|$84||Scratch
 
|-
 
|$85||Hi-Timpani
 
|-
 
|$86||Hi-Tom
 
|-
 
|$87||Silent
 
|-
 
|$88||Hi-Timpani
 
|-
 
|$89||Mid-Timpani
 
|-
 
|$8A||Low-Timpani
 
|-
 
|$8B||Low-Timpani
 
|-
 
|$8C||Mid-Tom
 
|-
 
|$8D||Low-Tom
 
|-
 
|$8E||Floor-Tom
 
|-
 
|$8F||Clap
 
|}
 
====Sonic 2 Final====
 
{| class="prettytable"
 
! Value||Sample
 
|-
 
|$81||Kick
 
|-
 
|$82||Snare
 
|-
 
|$83||Clap
 
|-
 
|$84||Scratch
 
|-
 
|$85||Timpani
 
|-
 
|$86||Tom
 
|-
 
|$87||Bongo
 
|-
 
|$88||Hi-Timpani
 
|-
 
|$89||Mid-Timpani
 
|-
 
|$8A||Low-Timpani
 
|-
 
|$8B||Low-Timpani
 
|-
 
|$8C||Mid-Tom
 
|-
 
|$8D||Low-Tom
 
|-
 
|$8E||Floor-Tom
 
|-
 
|$8F||Hi-Bongo
 
|-
 
|$90||Mid-Bongo
 
|-
 
|$91||Low-Bongo
 
|}
 
====Sonic 3 and Knuckles/Sonic 3D Blast====
 
{| class="prettytable"
 
! Value||Sample
 
|-
 
|$81||Snare
 
|-
 
|$82||High-Tom
 
|-
 
|$83||Mid-Tom
 
|-
 
|$84||Low-Tom
 
|-
 
|$85||Floor Tom
 
|-
 
|$86||Kick
 
|-
 
|$87||Muffled Snare
 
|-
 
|$88||Crash Cymbal
 
|-
 
|$89||Ride Cymbal(?)
 
|-
 
|$8A||Low Metal Hit
 
|-
 
|$8B||Metal Hit
 
|-
 
|$8C||High Metal Hit
 
|-
 
|$8D||Higher Metal Hit
 
|-
 
|$8F||Clap
 
|-
 
|$90||Electric High-Tom
 
|-
 
|$91||Electric Mid-Tom
 
|-
 
|$92||Electric Low-Tom
 
|-
 
|$93||Electric Floor Tom
 
|-
 
|$94||Tight Snare
 
|-
 
|$95||Mid-pitch Snare
 
|-
 
|$96||Loose Snare
 
|-
 
|$97||Looser Snare
 
|-
 
|$98||Hi-Timpani
 
|-
 
|$99||Low-Timpani
 
|-
 
|$9A||Mid-Timpani
 
|-
 
|$9B||Quick Loose Snare
 
|-
 
|$9C||Click
 
|-
 
|$9D||Power Kick
 
|-
 
|$9E||Quick Glass Crash
 
|-
 
|$9F||Glass Crash with Snare
 
|-
 
|$A0||Glass Crash
 
|-
 
|$A1||Glass Crash with Kick
 
|-
 
|$A2||Quiet Glass Crash
 
|-
 
|$A3||Odd Snare with Kick
 
|-
 
|$A4||Kick with extra bass
 
|-
 
|$A5||"Come on!"
 
|-
 
|$A6||Dance Snare
 
|-
 
|$A7||Loose Kick
 
|-
 
|$A8||Moderately Loose Kick
 
|-
 
|$A9||"Woo!"
 
|-
 
|$AA||"Go!"
 
|-
 
|$AB||Snare with voice going "Go!"
 
|-
 
|$AC||Power Tom
 
|-
 
|$AD||Hi-Wood Block
 
|-
 
|$AE||Low-Wood Block
 
|-
 
|$AF||Hi-Hit Drum
 
|-
 
|$B0||Low-Hit Drum
 
|-
 
|$B1||Metal Crash Hit
 
|-
 
|$B2||Echoed Clap Hit
 
|-
 
|$B3||Lower Echoed Clap Hit
 
|-
 
|$B4||Hip-Hop style hit with a kick
 
|-
 
|$B5||Hip-Hop style hit with a Power Kick
 
|-
 
|$B6||Some Bass with a voice going "Hey!"
 
|-
 
|$B7||Dance Style Kick
 
|-
 
|$B8||Hip-Hop hit with a kick
 
|-
 
|$B9||Hip-Hop hit with a kick
 
|-
 
|$BA||Reverse Fading Wind Sound
 
|-
 
|$BB||Scratch
 
|-
 
|$BC||Loose Snare with noise
 
|-
 
|$BD||Power Kick
 
|-
 
|$BE||Crashing noise with voice going "Woo!"
 
|-
 
|$BF||Quick Hit
 
|-
 
|$C0||Kick with a voice going "Hey!"
 
|-
 
|$C1||Power Kick with hit
 
|-
 
|$C2||Low Power Kick with hit
 
|-
 
|$C3||Lower Power Kick with hit
 
|-
 
|$C4||Lowest Power Kick with hit
 
|}
 
 
 
'''Note:''' Some samples may be missing or changed in ''Sonic 3D'' in contrast with ''Sonic 3 & Knuckles'', such as most sound effect-based samples. All of the major drums are there, though.
 
 
 
====Knuckles' Chaotix====
 
{| class="prettytable"
 
! Value||Sample
 
|-
 
|$81||Electric Kick
 
|-
 
|$82||Electric Snare
 
|-
 
|$83||Splash Cymbal
 
|-
 
|$84||Ride Bell
 
|-
 
|$85||High Tom
 
|-
 
|$86||Mid Tom
 
|-
 
|$87||Low Tom
 
|-
 
|$88||Electric Hi-Hat
 
|-
 
|$89||Crash Cymbal
 
|-
 
|$8A||Clap
 
|-
 
|$8B||Acoustic Kick
 
|-
 
|$8C||Acoustic Snare
 
|-
 
|$8D||Bell
 
|-
 
|$8E||Fingers Snapping
 
|-
 
|$8F||Cowbell
 
|-
 
|$90||High Click
 
|-
 
|$91||Low Click
 
|-
 
|$92||High Bongo
 
|-
 
|$93||Low Bongo
 
|-
 
|$94||High Timpani
 
|-
 
|$95||Low Timpani
 
|-
 
|$96||Silence
 
|}
 
 
 
====Sonic Crackers====
 
{| class="prettytable"
 
! Value||Sample
 
|-
 
|$81||Kick
 
|-
 
|$82||Snare
 
|-
 
|$83||Tom
 
|-
 
|$84||Tom
 
|-
 
|$85||Tom
 
|-
 
|$86||Voice sample "Let's go!"
 
|-
 
|$87||Voice sample "Hey!"
 
|-
 
|$88||Beep/screech
 
|}
 
 
 
==DAC Samples==
 
DAC samples are raw PCM samples, generally used for drums and voices that you hear in game. You can customize these audio samples to your needs. Here is some information to do so below...
 
 
 
===DAC Formats===
 
====Mega Drive====
 
Typically (though not always), SMPS games do not store their sample data as 8-bit unsigned LPCM (the way the YM2612 takes it), but rather as 4-bit DPCM with a single shared delta array of
 
db 0, 1, 2, 4, 8, 10h, 20h, 40h
 
db -80h, -1, -2, -4, -8, -10h, -20h, -40h
 
This form is almost always incorrectly referred to as "compressed;" [[jman2050]] {{LinkRetro|topic=6898|title=wrote a "compressor/decompressor" to convert samples stored in this format to standard 8-bit LCPM and vice versa}}.
 
 
 
There are a few exceptions to this rule:
 
*''[[sega:Michael Jackson's Moonwalker|Michael Jackson's Moonwalker]]'' uses a different delta array for voice samples:
 
db 0, 1, 2, 4, 8, 10h, 20h, 40h
 
db -80h, -1, -3, -4, -8, -10h, -20h, -40h
 
*''[[sega:Streets of Rage|Streets of Rage]]'' has the DPCM delta array for each sample as the first 16 bytes of the sample.
 
 
 
====32X====
 
SMPS-32X stores PWM samples as 8-bit unsigned LPCM. Note ''[[sega:Tempo|Tempo]]'' uses both DPCM samples on the MD side and PWM samples simultaneously; follow the above rules for the DPCM samples.
 
 
 
====Sonic CD====
 
Each SMPS-PCM bank has a table of samples which are stored as 8-bit sign-magnitude; the same format as the Sega CD's PCM chip demands them. This means that each byte of the sample '''always''' consists of a 1-bit sign and 7-bit magnitude. So -1 would be represented as binary 10000001, which is $81. The only exception is $FF, which is used to mark the end of sample data (and time to go back to the loop point), so don't place this in the sample data.
 
 
 
===Sonic 1===
 
Samples in Sonic 1 are inside the Z80 portion of the sound driver, located at $72E7C, and compressed in Kosinski format. All following locations are for the decompressed sound driver.
 
====DAC Sample Pointers====
 
* DAC sample setup index: $D6
 
 
 
Each DAC pointer is listed one after another, and a single entry for one DAC sample is $8 bytes. The format is as follows:
 
{| class="prettytable"
 
|-
 
! Offset||Size||Description
 
|-
 
|$00-$01||Word||Location of the DAC sample in decompressed driver.
 
* NOTE: Value is little endian, so swap the bytes to get the real value.
 
|-
 
|$02-$03||Word||Size of the compressed DAC sample in decompressed driver.
 
* NOTE: Value is little endian, so swap the bytes to get the real value.
 
|-
 
|$05||Byte||Sample rate/pitch. The lower the value, the faster the sample will play.
 
|-
 
|$06-$08||3 Bytes||Unused/redundant.
 
|}
 
 
 
 
 
Sonic 1 has 3 DAC sample slots - one for the kick, one for the snare, and one for the Timpani. The other pitches of Timpani ($88-$8B) are defined by a special table, located at $71CC4, and are fully editable to suit other samples using the Timpani slot ($83).
 
 
 
===Sonic 2===
 
====DAC Sample Pointers====
 
 
 
* Pointers to DAC Samples in Sonic 2 Beta: $ECDA6
 
 
 
 
 
Specifics...
 
* $ECDA6 - Sample 81 pointer
 
* $ECDA8 - Sample 81 length
 
* $ECDAA - Sample 82 pointer
 
* $ECDAC - Sample 82 length (skip FF)
 
* $ECDAF - Sample 83 pointer
 
* $ECDB1 - Sample 83 length
 
* $ECDB3 - Sample 84 pointer
 
* $ECDB5 - Sample 84 length (skip FF)
 
* $ECDB8 - Sample 85 pointer
 
* $ECDBA - Sample 85 length
 
* $ECDBC - Sample 86 pointer
 
* $ECDBE - Sample 86 length -- This one is tricky. You need to skip the second FF, as the first FF is valid.
 
 
 
 
 
 
 
* Pointers to DAC Samples in Sonic 2 Final: $ECF7C
 
Specifics...
 
* $ECF7C - Sample 81 pointer
 
* $ECF7E - Sample 81 length
 
* $ECF81 - Sample 82 pointer
 
* $ECF83 - Sample 82 length
 
* $ECF85 - Sample 83 pointer
 
* $ECF87 - Sample 83 length
 
* $ECF8A - Sample 84 pointer
 
* $ECF8C - Sample 84 length
 
* $ECF8E - Sample 85 pointer
 
* $ECF90 - Sample 85 length
 
* $ECF93 - Sample 86 pointer
 
* $ECF95 - Sample 86 length
 
* $ECF97 - Sample 87 pointer
 
* $ECF99 - Sample 87 length
 
 
 
These pointers are 4 bytes in size. First two bytes are the pointer to the sample (the pointers add to E0000, little endian, and don't follow the music pointer format. Simple 16-bit absolute), and the other two bytes are the length of the sample (also little endian). If you see an FF, skip it and move on to the next byte.
 
 
 
 
 
====DAC Master List====
 
* DAC Master List in Sonic 2 Beta: $ECDC1
 
* DAC Master List in Sonic 2 Final: $ECF9C
 
 
 
These work similarly to the master playlist in concept.. The format is two bytes per sample. First byte defines the sample ID, and the second byte defines the rate that the sample is played at. The lower the rate value, the faster the sample is played. This is used to make certain samples (like toms) appear to have different pitches (high tom, low tom, etc). If you see an FF, skip it and move on to the next byte. If you touch the FF, you fuck the entire sound driver. Don't. :P
 
 
 
===Sonic 3===
 
====Setup Pointers====
 
* DAC $81-$9A Pointer Index (Adds to $E0000): $E0000
 
* DAC $9B-$AA Pointer Index (Adds to $E8000): $E8000
 
* DAC $AB-$C0 Pointer Index (Adds to $F0000): $F0000
 
 
 
These pointer indexes work by pointing to the sample setup data for the particular samples. You'll notice there are 3 pointer indexes - this is since not all the samples can fit in a single bank, so they span 3 banks. The pointers are repeated at all 3 indexes, but only the defined samples for the index (listed above) will be in the relevant ROM bank.
 
 
 
====DAC Sample Setup Format====
 
The format for a DAC sample entry is pretty simple. Follow along:
 
{| class="prettytable"
 
|-
 
! Offset||Size||Function
 
|-
 
|$00||Byte||Sample rate/pitch. The lower the value, the faster the sample will play.
 
|-
 
|$01-$02||Word||Size of the DAC sample, in bytes.
 
* NOTE: Value is little endian, so remember to swap the bytes to get the real value.
 
|-
 
|$03-$04||Word||Pointer to the DAC sample, within the current bank.
 
* NOTE: Value is little endian, so remember to swap the bytes to get the real value.
 
|}
 
 
 
===32X SMPS - PWM===
 
32X games that use the PWM driver for song samples have a sample table of the form
 
 
 
{| class="prettytable"
 
|-
 
! Offset||Size||Function
 
|-
 
|$00||Long||The virtual (SH-2 side) address of the sample — take out the first byte for the ROM address.
 
|-
 
|$04||Long||Size of the DAC sample, in bytes.
 
|-
 
|$08||Long||Zero. Purpose unknown.
 
|-
 
|$0C||Long||Sample rate/pitch. The lower the value, the slower the playback rate. A sample rate of $00000800 is equal to 11025hz.
 
|}
 
 
 
==Coordination flags==
 
Coordination flags are values in the range of $E0-$FF in notation that perform special functions. The use of coordination flags can range from branching to specific locations in the song to altering volume, voice number, pitch, and other variables in real time.
 
 
 
Three of the coordination flags change between S1/S2 and S3/S&K. The rest are the same throughout.
 
 
 
{| class="prettytable"
 
! Flag||Purpose
 
|-
 
|$E0xx||Panning, AMS, FMS
 
*xx - Value
 
**Bit 7 - Left channel status
 
**Bit 6 - Right channel Status
 
**Bit 5-3 - AMS
 
**Bit 2 - 0
 
**Bit 1-0 - FMS
 
|-
 
|$E1xx||Alter note values by xx???
 
|-
 
|$E2FF||Fade-in to previous song (needed on DAC channel, <span style='color:red;'>Sonic 3 & etc</span>)
 
|-
 
|$E3||Return (<span style='color:red;'>Sonic 1 & 2</span>)
 
|-
 
|$E4||Fade-in to previous song (needed on DAC channel, <span style='color:red;'>Sonic 1 & 2</span>)
 
|-
 
|$E5xx||Change tempo divider to xx
 
|-
 
|$E6xx||Change channel volume by xx; xx is signed
 
|-
 
|$E7xx||Prevent next note from attacking
 
|-
 
|$E8xx||Set note fill amount to xx
 
|-
 
|$E9xx||Add xx to channel key (<span style='color:red;'>Sonic 1 & 2</span>)
 
|-
 
|$EAxx||Set music tempo to xx
 
|-
 
|$EBxx||Change Tempo Modifier to xx for ALL channels
 
|-
 
|$ECxx||Change channel volume to xx; xx is signed
 
|-
 
|$EE||Something with Voice Selection
 
|-
 
|$EFxx||Change current voice to xx
 
*00 is the first voice in the bank. So in other words, subtract 01 from the value to get the voice in the bank you want.
 
|-
 
|$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
 
|-
 
|$F3xx||Change current PSG noise to xx (For noise channel)
 
*Applicable values are E0 - E7
 
*Anything beyond E7 will wrap back to the E0 waveform
 
|-
 
|$F4||Turn off modulation
 
|-
 
|$F5xx||Change current PSG tone to xx
 
|-
 
|$F6yyyy||Jump to position yyyy
 
|-
 
|$F7xxyyzzzz||Repeat section of music
 
*xx - Loop index, for loops within loops without confusing the engine.
 
**'''EXAMPLE:''' Some notes, then a section that is looped twice, then some more notes, and finally the ''whole thing'' is looped three times.<br>The "inner" loop (the section that is looped twice) would have an xx of 01, looking something along the lines of F7'''01'''02zzzz, whereas the "outside" loop (the whole thing loop) would have an xx of 00, looking something like F7'''00'''03zzzz.
 
*yy - Number of times to repeat
 
**'''NOTE:''' This includes the initial encounter of the F7 flag, not number of times to repeat AFTER hitting the flag.
 
*zzzz - Position to loop back to
 
|-
 
|$F8yyyy||Jump to position yyyy (keep previous position in memory for returning)
 
|-
 
|$F9||Return (<span style='color:red;'>Sonic 3 & etc</span>)
 
|-
 
|$FBxx||Add xx to channel key (<span style='color:red;'>Sonic 3 & etc</span>)
 
|-
 
|$FCyyyy||Loop Sound Effect from position yyyy. (<span style='color:red;'>Sonic 3 & etc, Sonic CD</span>)
 
|}
 
 
 
====Note on $F3====
 
The $F3 flag determines whether a PSG channel--usually the last one defined in the header--is a tone channel or the noise channel. There is only one noise channel, and 3 tone channels. Also worth noting is that a tone channel can become a noise channel mid-song; however, once it becomes a noise channel, it can not switch back to a tone at any point.
 
 
 
====Note on $F8 and $F9/$E3====
 
Flags $F8 and $F9/$E3 work similarly to the opcodes '''jsr''' and '''rts''' in terms of function. $F8 will branch to a location within the song, saving the previous location to the stack; once the data is parsed, the $F9/$E3 flag will pop the stack to the program counter, continuing on in the song after the initial $F8 branch. This effect is utilized by [[Puto]] frequently in the [[xm4smps]] program to structure SMPS files similarly internally to XM module files.
 
 
 
====Notes on $E0====
 
Only FM and DAC channels can be panned, the PSG channels will ignore this flag.
 
In ''[[Sonic 1]]'', if the sixth channel (either FM6 or the DAC) of your Game Over song is panned, the SEGA sound after the reset will be panned as well. In ''OutRun'' the DAC channel cannot be panned; each sample has its own panning setting, defined in the DAC table.
 
 
 
==Game Specifics==
 
===Sonic 2===
 
====Master Playlist====
 
Sonic 2 has a special "master playlist" that defines what music ID plays in what slot. It works by taking a base address - generally the start of a music bank - and, for each increment of the value, it reads ahead another word in the current ROM bank. So, say, $00 would be the first word in the bank ($00-$01), $01 would be the next ($02-$03), and so on. The base address for this bank, in both Sonic 2 Beta AND final, is $F0000, and the addressing range spans as far as the value can allow, which is two Z80 ROM banks ($10000 bytes). 
 
 
 
However, as a simple guide to understanding how it works (at least, for the casual hacker), all values for the original, untouched music (for the most part, anyway) 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 (visually, anyway - the game still uses $80 > values internally) in the final version of the game. The only exception to this is in Sonic 2 Beta, where some songs use the upper $8000 bytes of the bank start address to store music (making the values for calling said music start with $00). The locations for the master playlist are as follows:
 
 
 
* Master Playlist in Sonic 2 Beta: $ECE9F
 
 
 
* Master Playlist in Sonic 2 Final: $ECF36
 
 
 
As previously mentioned, 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 - these are compression bytes for the driver, and touching them will bork the decompressor in-game, and prevent the sound driver from booting. The "master playlist" is only in Sonic 2 (Beta/Final) 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.
 
 
 
===Sonic 3===
 
====Universal Voice Bank====
 
In Sonic 3, some songs have the value "$D817" as their voice pointer. When a song has this in its voice pointer, that means it's being prepped to use a global set of multiple voices that any song in the game can use. This is generally used to save space for songs that use the same voices. Interestingly enough, though, the Special Stage music has the first 5 voices used in the Universal Voice Bank, and all in the same order, so it's puzzling why they didn't just have the song use the bank (as it's fully capable of doing so).
 
 
 
* Universal Voice Bank in Sonic 3: $E77D8
 
 
 
=====Universal Voice Bank definitions=====
 
Using the Universal Voice Bank is akin to using voices in a normal song - each voice has a value, defined by coordination flag $EF. Here are some of the voices used in the Universal Voice Bank.
 
 
 
{| class="prettytable"
 
|-
 
! Value||Description
 
|-
 
|$00||Synth Bass 2
 
|-
 
|$01||Trumpet 1
 
|-
 
|$02||Slap Bass 2
 
|-
 
|$03||Synth Bass 1
 
|-
 
|$04||Bell Synth 1
 
|-
 
|$05||Bell Synth 2
 
|-
 
|$06||Synth Brass 1
 
|-
 
|$07||Synth like Bassoon
 
|-
 
|$08||Bell Horn type thing
 
|-
 
|$09||Synth Bass 3
 
|-
 
|$0A||Synth Trumpet
 
|-
 
|$0B||Wood Block
 
|-
 
|$0C||Tubular Bell
 
|-
 
|$0D||Strike Bass
 
|-
 
|$0E||Elec Piano
 
|-
 
|$0F||Bright Piano
 
|-
 
|$10||Church Bell
 
|-
 
|$11||Synth Brass 2
 
|-
 
|$12||Bell Piano
 
|-
 
|$13||Wet Wood Bass
 
|-
 
|$14||Silent Bass
 
|-
 
|$15||Picked Bass
 
|-
 
|$16||Xylophone
 
|-
 
|$17||Sine Flute
 
|-
 
|$18||Pipe Organ
 
|-
 
|$19||Synth Brass 2
 
|-
 
|$1A||Harpischord
 
|-
 
|$1B||Metallic Bass
 
|-
 
|$1C||Alternate Metallic Bass
 
|-
 
|$1D||Backdropped Metallic Bass
 
|-
 
|$1E||Sine like Bell
 
|-
 
|$1F||Synth like Metallic with Small Bell.
 
|-
 
|$20||Nice Synth like lead.
 
|-
 
|$21||Rock Organ
 
|-
 
|$22||Strike like Slap Bass
 
|}
 
 
 
==Realtime Music Editing==
 
 
 
By editing values in savestates, you can edit music, pointers and other various values in realtime. Re-load the savestate to see your changes applied!
 
 
 
===Sonic 3/Sonic & Knuckles===
 
{| class="prettytable"
 
|-
 
! Offset||Z80 RAM Location||Purpose
 
|-
 
|$001A8C||1618||Music Pointers (Sonic & Knuckles)
 
|-
 
|$001A8E||161A||Music Pointers (Sonic 3)
 
|-
 
|$001778||1304||Pointer for Music Pointers
 
|-
 
|$000FD9||0B65||Music Bank IDs (Sonic & Knuckles)
 
|-
 
|$000FBC||0B48||Music Bank IDs (Sonic 3)
 
|-
 
|$00177A||1306||Pointer for Sound Effect Pointers
 
|-
 
|$001AF2||167E||Sound Effect Pointers
 
|}
 
 
 
===Sonic 3D===
 
{| class="prettytable"
 
|-
 
! Offset||Z80 RAM Location||Purpose
 
|-
 
|$001AD0||165C||Music Pointers
 
|-
 
|$001778||1304||Pointer for Music Pointers
 
|-
 
|$00177A||1306||Pointer for Sound Effect Pointers
 
|-
 
|$001AD0||165C||Music Pointers
 
|-
 
|$001B34||16C0||Sound Effect Pointers
 
|}
 
 
 
===Sonic 2 Final===
 
{| class="prettytable"
 
|-
 
! Offset||Z80 RAM Location||Purpose
 
|-
 
|$001669||11F5||Master Playlist
 
|-
 
|$000C16||07A2||Pointer for Master Playlist
 
|-
 
|$000DF9||0985||Pointer for Sound Effects list
 
|}
 
 
 
==Games That Use The Engine==
 
This sound engine isn't specific to only the Sonic games - many other games use this sound engine as well. The "official" name for this sound system is called '''SMPS''', or the '''S'''ample '''M'''usic '''P'''layback '''S'''ystem.
 
 
 
There are two derivatives of the system - one is the driver that runs on the Z80 processor, and the other runs on the 68k. 68k games will use relative pointers internally (with absolute music pointers), while the Z80 games will use Z80 bank addressing. Keep this in mind when searching for music data within games.
 
 
 
===Game List===
 
{| class="prettytable"
 
! Game Name||SMPS Version
 
|-
 
|A Ressha de Ikou MD||SMPS 68k
 
|-
 
|Aa Harimanada||SMPS 68k
 
|-
 
|Advanced Daisenryaku||SMPS Z80
 
|-
 
|Air Buster (Aero Blasters)||SMPS Z80
 
|-
 
|Alex Kidd in the Enchanted Castle||SMPS Z80
 
|-
 
|Alien Soldier||SMPS/Treasure
 
|-
 
|Alien Storm||SMPS Z80
 
|-
 
|Arrow Flash||SMPS Z80
 
|-
 
|Art of Fighting (Ryuuko no Ken)||SMPS Z80
 
|-
 
|Atomic Robo-Kid||SMPS Z80 (banked)
 
|-
 
|ATP Tour Championship Tennis||SMPS Z80
 
|-
 
|Ayrton Senna's Super Monaco GP II||SMPS 68k
 
|-
 
|Bahamut Senki||SMPS 68k
 
|-
 
|Battle Golfer Yui||SMPS 68k
 
|-
 
|Battletoads||SMPS Z80
 
|-
 
|Bishoujo Senshi Sailor Moon||SMPS 68k
 
|-
 
|Bonanza Brothers||SMPS Z80
 
|-
 
|Cadash||SMPS Z80
 
|-
 
|Castle of Illusion||SMPS Z80
 
|-
 
|Chou Yakyuu Miracle Nine||SMPS Z80/mod
 
|-
 
|Columns||SMPS Z80
 
|-
 
|Columns III||SMPS Z80
 
|-
 
|Crayon Shin-Chan||SMPS 68k
 
|-
 
|Cyberball||SMPS Z80
 
|-
 
|Dahna: Megami Tanjou||SMPS Z80
 
|-
 
|Dangerous Seed||SMPS Z80
 
|-
 
|Dick Tracy||SMPS Z80
 
|-
 
|DJ Boy||SMPS Z80
 
|-
 
|Doraemon: Yume Dorobouto 7-nin no Gozansu||SMPS 68k
 
|-
 
|Dragon's Eye Plus: Shanghai 3||SMPS 68k
 
|-
 
|Dyna Brothers||SMPS Z80 (banked)
 
|-
 
|Dyna Brothers 2||SMPS Z80 (banked)
 
|-
 
|Dynamite Duke||SMPS Z80
 
|-
 
|Dynamite Headdy||SMPS/Treasure
 
|-
 
|ESWAT Cyber Police||SMPS Z80
 
|-
 
|F1 Circus MD||SMPS Z80
 
|-
 
|Fatal Fury (Garou Densetsu)||SMPS 68k
 
|-
 
|Fatal Fury 2 (Garou Densetsu 2)||SMPS 68k
 
|-
 
|Fatal Labyrinth||SMPS Z80
 
|-
 
|Fighting Masters||SMPS Z80
 
|-
 
|Flicky||SMPS Z80
 
|-
 
|Gain Ground||SMPS Z80
 
|-
 
|Game no Kandzume Otokuyou||SMPS Z80
 
|-
 
|Ghostbusters||SMPS Z80
 
|-
 
|Golden Axe II||SMPS 68k
 
|-
 
|Golden Axe III||SMPS 68k
 
|-
 
|Gouketsuji Ichizoku||SMPS Z80/mod
 
|-
 
|Growl (Runark)||SMPS Z80
 
|-
 
|Gunstar Heroes||SMPS/Treasure
 
|-
 
|Honoo no Toukyuuji Dodge Danpei||SMPS Z80
 
|-
 
|J.League Pro Striker/Perfect Edition||SMPS Z80
 
|-
 
|J.League Pro Striker 2||SMPS Z80
 
|-
 
|King of the Monsters||SMPS Z80
 
|-
 
|King of the Monsters 2||SMPS Z80
 
|-
 
|Light Crusader||SMPS/Treasure
 
|-
 
|Magical Hat no Buttobi Turbo! Daibouken||SMPS Z80
 
|-
 
|Magical Taruruuto-kun||SMPS 68k
 
|-
 
|Marvel Land (Talmit's Adventure)||SMPS Z80
 
|-
 
|Mazin Saga (Mazin Wars)||SMPS Z80
 
|-
 
|McDonald's Treasure Land Adventure||SMPS/Treasure
 
|-
 
|Mega Anser||SMPS Z80
 
|-
 
|Mega Games 2/3 menu||SMPS 68k
 
|-
 
|Mega Man - The Wily Wars||SMPS Z80 (Banked)
 
|-
 
|Mega Q: Party Quiz||SMPS 68k
 
|-
 
|Mercs (Senjou no Ookami II)||SMPS Z80
 
|-
 
|Metal Fangs||SMPS 68k
 
|-
 
|Michael Jackson's Moonwalker||SMPS 68k
 
|-
 
|Mighty Morphin' Power Rangers||SMPS Z80
 
|-
 
|Mighty Morphin' Power Rangers: The Movie||SMPS 68k
 
|-
 
|Mystic Defender (Kujaku Ou II)||SMPS 68k
 
|-
 
|Nekketsu Koukou Dodgeball Bu Soccer Hen MD||SMPS 68k
 
|-
 
|OutRun||SMPS Z80
 
|-
 
|OutRun 2019||SMPS Z80
 
|-
 
|OutRunners||SMPS Z80
 
|-
 
|Pat Riley Basketball (Super Real Basketball)||SMPS Z80
 
|-
 
|Phantasy Star III: Generations of Doom||SMPS Z80
 
|-
 
|Phantasy Star: The End of the Millenium||SMPS 68k
 
|-
 
|Pro Striker Final Stage||SMPS Z80/mod
 
|-
 
|Pulseman||SMPS 68k/mod
 
|-
 
|Puzzle & Action: Ichidant-R||SMPS Z80
 
|-
 
|Puzzle & Action: Tant-R||SMPS Z80
 
|-
 
|QuackShot||SMPS Z80
 
|-
 
|Rastan Saga II||SMPS Z80
 
|-
 
|Ristar||SMPS 68k/mod
 
|-
 
|Saint Sword||SMPS Z80
 
|-
 
|Samurai Shodown (Samurai Spirits)||SMPS 68k
 
|-
 
|Sangokushi Retsuden||SMPS Z80
 
|-
 
|Shadow Dancer: The Secret of Shinobi||SMPS 68k
 
|-
 
|Shinobi III (The Super Shinobi II)||SMPS 68k/mod
 
|-
 
|Shogi no Hoshi||SMPS Z80
 
|-
 
|Shura no Mon||SMPS Z80
 
|-
 
|Slam Dunk||SMPS Z80
 
|-
 
|Sonic & Knuckles||SMPS Z80/mod
 
|-
 
|Sonic 3D Blast (Sonic 3D Flickies' Island)||SMPS Z80
 
|-
 
|Sonic the Hedgehog||SMPS 68k
 
|-
 
|Sonic the Hedgehog 2||SMPS Z80/mod
 
|-
 
|Sonic the Hedgehog 3||SMPS Z80/mod
 
|-
 
|Sorcerian||SMPS Z80 (banked)
 
|-
 
|Streets of Rage (Bare Knuckle)||SMPS 68k/mod
 
|-
 
|Strider (Strider Hiryuu)||SMPS 68k
 
|-
 
|Super League '91||SMPS Z80
 
|-
 
|Super Monaco GP||SMPS Z80
 
|-
 
|Surging Aura||SMPS Z80
 
|-
 
|Syd of Valis (Valis SD)||SMPS Z80
 
|-
 
|Tecmo Cup (Captain Tsubasa) (beta)||SMPS Z80
 
|-
 
|Tecmo World Cup||SMPS Z80
 
|-
 
|The Hybrid Front||SMPS Z80
 
|-
 
|The Revenge of Shinobi (The Super Shinobi)||SMPS 68k
 
|-
 
|Toki: Going Ape Spit (JuJu Densetsu)||SMPS 68k
 
|-
 
|Ultimate Qix (Volfied)||SMPS Z80
 
|-
 
|Viewpoint||SMPS Z80
 
|-
 
|Virtua Fighter 2||SMPS Z80
 
|-
 
|Virtua Racing||SMPS Z80 (banked)
 
|-
 
|Wani Wani World||SMPS Z80
 
|-
 
|Whip Rush||SMPS Z80
 
|-
 
|Wimbledon Championship Tennis||SMPS Z80
 
|-
 
|World of Illusion||SMPS Z80
 
|-
 
|Yuu Yuu Hakusho Gaiden||SMPS Z80
 
|-
 
|Yuu Yuu Hakusho: Makyou Touitsusen||SMPS/Treasure
 
|-
 
! colspan="2" | 32x Games:
 
|-
 
|Cosmic Carnage (Cyber Brawl)||SMPS 68k
 
|-
 
|Knuckles' Chaotix||SMPS Z80/mod
 
|-
 
|Metal Head||SMPS 68k
 
|-
 
|Shadow Squadron (Stellar Assault)||SMPS 68k
 
|-
 
|Tempo||SMPS Z80/mod
 
|-
 
|Virtua Racing Deluxe||SMPS 68k
 
|-
 
|Zaxxon's Motherbase 2000 (Parasquad)||SMPS Z80
 
|}
 
 
 
==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
 
** Pointer to Music Pointers at $F8000: $EC79D
 
* Sound Effect Pointers (These add to $F8000): $FF000
 
** Pointer to Sound Effect Pointers: $EC08E
 
 
 
===Sonic 2 Final===
 
* Music Pointers (These add to F8000): F8000
 
** Specifics...
 
{| class="prettytable"
 
! Pointer ID||Address||Sound Test ID||Song name
 
|-
 
| 81
 
| $F84F6
 
| 08
 
| Casino Night Zone (2 Player)
 
|-
 
| 82
 
| $F88C4
 
| 02
 
| Emerald Hill Zone
 
|-
 
| 83
 
| $F8DEE
 
| 05
 
| Metropolis Zone
 
|-
 
| 84
 
| $F917B
 
| 09
 
| Casino Night Zone
 
|-
 
| 85
 
| $F9664
 
| 0B
 
| Mystic Cave Zone
 
|-
 
| 86
 
| $F9A3C
 
| 03
 
| Mystic Cave Zone (2 Player)
 
|-
 
| 87
 
| $F9D69
 
| 07
 
| Aquatic Ruin Zone
 
|-
 
| 88
 
| $FA36B
 
| 0A
 
| Death Egg Zone
 
|-
 
| 89
 
| $FA6ED
 
| 12
 
| Special Stage
 
|-
 
| 8A
 
| $FAAC4
 
| 11
 
| Option Screens
 
|-
 
| 8B
 
| $FAC3C
 
| 15
 
| "Sweet Sweet Sweet" (Ending)
 
|-
 
| 8C
 
| $FB124
 
| 14
 
| Final Battle
 
|-
 
| 8D
 
| $FB3F7
 
| 0E
 
| Chemical Plant Zone
 
|-
 
| 8E
 
| $FB81E
 
| 13
 
| Boss
 
|-
 
| 8F
 
| $FBA6F
 
| 0D
 
| Sky Chase Zone
 
|-
 
| 90
 
| $FBD8C
 
| 04
 
| Oil Ocean Zone
 
|-
 
| 91
 
| $FC146
 
| 0F
 
| Wing Fortress Zone
 
|-
 
| 92
 
| $FC480
 
| 0C
 
| Emerald Hill Zone (2 Player)
 
|-
 
| 93
 
| $FC824
 
| 01
 
| 2 Player Results Screen
 
|-
 
| 94
 
| $FCBBC
 
| 16
 
| Super Sonic
 
|-
 
| 95
 
| $FCE74
 
| 06
 
| Hill Top Zone
 
|-
 
| 96
 
| $FD48D
 
| 18
 
| 1-Up
 
|-
 
| 97
 
| $FD193
 
| 19
 
| Title Screen
 
|-
 
| 98
 
| $FD35E
 
| 1A
 
| Stage Cleared
 
|-
 
| 99
 
| $FD57A
 
| 1B
 
| Game Over
 
|-
 
| 9A
 
| $F8359
 
| 17
 
| Invincibility
 
|-
 
| 9B
 
| $FD6C9
 
| 1D
 
| Got an Emerald
 
|-
 
| 9C
 
| $F803C
 
| 10
 
| Hidden Palace Zone
 
|-
 
| 9D
 
| $F823B
 
| 1F
 
| Underwater Timing
 
|-
 
| 9E
 
| $FD797
 
| 1E
 
| Credits
 
|}
 
 
 
* Pointer to Music Pointers at $F8000: $EC810
 
 
 
* Music Pointers (These add to F8000 and are for 98-9F, excluding continue): $F802A
 
** Specifics...
 
{| class="prettytable"
 
! Pointer ID||Address||Sound Test ID||Song name
 
|-
 
| 01
 
| 0F0002
 
| 1C
 
| Continue
 
|}
 
* Sound Effect Pointers (These add to F8000): $FEE91
 
** Pointer to Sound Effect Pointers: $EC09C
 
 
 
===Sonic Crackers===
 
* Music Pointers: $0633F
 
** Specifics...
 
{| class="prettytable"
 
|-
 
! Sound ID||Song||Location
 
|-
 
|$81||Electoria||$10000
 
|-
 
|$82||Walkin'||$1088C
 
|-
 
|$83||Hyper-Hyper||$10BDA
 
|-
 
|$84||Evening Star||$11210
 
|-
 
|$85||Moonrise||$1172B
 
|-
 
|$86||Game Over||$11B10
 
|}
 
 
 
===Sonic 3===
 
* Music Pointers (These add to $C8000): $E761A
 
* Music Pointers (These add to $D0000): $E762E
 
* Music Pointers (These add to $D8000): $E7652
 
* Music Pointers (These add to $C0000): $E7674
 
* Sound Effect Pointers (These add to $F8000): $E767E
 
 
 
===Sonic 3D===
 
* Music Pointers (These add to $C0000): $D3233
 
* Music Pointers (These add to $C8000): $D3245
 
* Music Pointers (These add to $D0000): $D325D
 
** Specifics...
 
{| class="prettytable"
 
! Music ID||Music Pointer||Song name
 
|-
 
! colspan="3" | These add to $C0000:
 
|-
 
|01||2480||Green Grove 1
 
|-
 
|02||8F91||Green Grove 2
 
|-
 
|03||A0A8||Rusty Ruin 1
 
|-
 
|04||E7B9||Rusty Ruin 2
 
|-
 
|05||95C7||Volcano Valley 2
 
|-
 
|06||4AD0||Volcano Valley 1
 
|-
 
|07||39D7||Spring Stadium 1
 
|-
 
|08||72E3||Spring Stadium 2
 
|-
 
|09||91F0||Diamond Dust 1
 
|-
 
! colspan="3" | These add to $C8000:
 
|-
 
|0A||2480||Diamond Dust 2
 
|-
 
|0B||DE8B||Gene Gadget 1
 
|-
 
|0C||BD96||Gene Gadget 2
 
|-
 
|0D||A8A0||Panic Puppet 2
 
|-
 
|0E||E0A8||The Final Fight
 
|-
 
|0F||B396||Ending
 
|-
 
|10||55BB||Bonus Stage
 
|-
 
|11||8FC6||Panic Puppet 1/Level Select Screen
 
|-
 
|12||12D0||Boss Theme 1
 
|-
 
|13||20D6||Boss Theme 2
 
|-
 
|14||98DD||Intro
 
|-
 
|15||D9E1||Credits
 
|-
 
! colspan="3" | These add to $D0000:
 
|-
 
|16||2480||Game Over
 
|-
 
|17||7F82||Congratulations: You have found the secret Level Select screen" screen
 
|-
 
|18||9886||Bonus Stage End
 
|-
 
|19||158B||Extra Life
 
|-
 
|1A||658C||Chaos Emerald Gain
 
|-
 
|1B||558D||Invincibility
 
|-
 
|1C||2791||Main Menu
 
|}
 
 
 
* 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
 
{| class="prettytable"
 
|-
 
! Address||Song
 
|-
 
|$40000||Door Into Summer
 
|-
 
|$40D61||Electoria
 
|-
 
|$41904||Speed of Sound
 
|-
 
|$428a6||Seascape
 
|-
 
|$4349a||Midnight Greenhouse
 
|-
 
|$44220||New Moon
 
|-
 
|$4509c||Labyrinth
 
|-
 
|$4536b||Trial and Error
 
|-
 
|$45DEE||Walkin'
 
|-
 
|$461be||Hyper-Hyper
 
|-
 
|$468e5||Evening Star
 
|-
 
|$46Fe8||Moonrise
 
|-
 
|$474e3||Overture
 
|-
 
|$477f0||This Horizon
 
|-
 
|$48000||Take Off
 
|-
 
|$4836a||Combination
 
|-
 
|$48a39||Take a Nap
 
|-
 
|$48c96||Surging Power
 
|-
 
|$4915d||Mechanical Dance
 
|-
 
|$4951d||Tube Panic
 
|-
 
|$49fb0||Crystal Nightmare
 
|-
 
|$4a58c||Child's Song
 
|-
 
|$4ac3c||Soda Pop
 
|-
 
|$4b082||Pendulum
 
|-
 
|$4b6f5||Silver Screen
 
|-
 
|$4bBFF||Tachy Touch
 
|-
 
|$4c44e||Chaotic World
 
|-
 
|$4c8fa||Surprise!
 
|-
 
|$4cd0d||Nice Meeting You
 
|-
 
|$4d0ef||Have a Happy Day
 
|-
 
|$4d34c||Reach the Goal
 
|-
 
|$4d53f||High Five
 
|-
 
|$4d67a||Decision
 
|-
 
|$4d81d||From Party to Party
 
|-
 
|$4d9f4||Have Some Fun
 
|-
 
|$4dc41||Oriental Legend
 
|-
 
|$4e33d||Steel Heart
 
|-
 
|$50000||Tribute
 
|-
 
|$509ac||Destructive Power
 
|-
 
|$50c6a||Just Another Day
 
|-
 
|$5400b||Decision 2nd
 
|}
 
* Sound Effect Pointers (These add to $50000): $76B3B
 
 
 
===Sonic & Knuckles===
 
* Music Pointers: $F793E
 
{| class="prettytable"
 
! Music ID||Music pointer||Song name
 
|-
 
! colspan="3" | 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
 
|-
 
! colspan="3" | These add to E8000:
 
|-
 
| 09
 
| 8000
 
| FBZ1
 
|-
 
| 0A
 
| 8597
 
| FBZ2
 
|-
 
| 0F
 
| 8AFE
 
| MHZ1
 
* NOTE: This one is a bit tricky... The FE is right before the FF. Make sure to skip the FF or the driver will crash.
 
|-
 
| 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
 
| Act 2 Boss
 
|-
 
| 1A
 
| D3DD
 
| Doomsday
 
|-
 
| 1B
 
| DCC0
 
| Rolling Jump Bonus Stage
 
|-
 
| 1C
 
| E223
 
| Special Stage
 
|-
 
| 1D
 
| EABB
 
| Slot Machine Bonus Stage
 
|-
 
| 1F
 
| F5A3
 
| Knuckles' Theme
 
|-
 
| 25
 
| F88E
 
| Title
 
|-
 
| 2A
 
| FD4B
 
| 1UP
 
|-
 
| 2B
 
| FE75
 
| Chaos Emerald
 
|-
 
| 2E
 
| CBB1
 
| Act 1 Boss (same as 18)
 
|-
 
! colspan="3" | These add to 2D0000:
 
|-
 
| 0B
 
| 86AA
 
| ICZ1
 
|-
 
| 0C
 
| 8000
 
| ICZ2
 
|-
 
| 0D
 
| 9345
 
| LBZ1
 
|-
 
| 0E
 
| 8DC8
 
| LBZ2
 
|-
 
| 1E
 
| 8AE8
 
| Gum Ball Machine Bonus Stage
 
|-
 
| 20
 
| 99F7
 
| Azure Lake
 
|-
 
| 21
 
| A4FD
 
| Balloon Park
 
|-
 
| 22
 
| B0EC
 
| Desert Palace
 
|-
 
| 23
 
| C324
 
| Chrome Gadget
 
|-
 
| 24
 
| DA47
 
| Endless Mine
 
|-
 
| 26
 
| E587
 
| S3 credits
 
|-
 
| 2D
 
| F5E4
 
| Competition Menu
 
|-
 
| 31
 
| FABE
 
| S3 countdown
 
|-
 
! colspan="3" | These add to E0000:
 
|-
 
| 27
 
| DD4B
 
| Game/Time Over
 
|-
 
| 28
 
| DFA6
 
| Continue
 
|-
 
| 29
 
| E3C0
 
| Bonus Screen
 
|-
 
| 2C
 
| E574
 
| Invincible
 
|-
 
| 2F
 
| E7AF
 
| Menu
 
|-
 
| 1F
 
| F74C
 
| Knuckles' Theme
 
|-
 
| 32
 
| FCDE
 
| S&K outro
 
|-
 
| DC
 
| C104
 
| S&K credits
 
|}
 
* Sound Effect Pointers (These add to $F8000): $F79AD
 
** Specifics...
 
{| class="prettytable"
 
|-
 
! Sound Test ID||Pointer Value
 
|-
 
|$33||DE30
 
|-
 
|$34||DE5E
 
|-
 
|$35||DE6F
 
|-
 
|$36||DEA1
 
|-
 
|$37||DEC5
 
|-
 
|$38||DEF4
 
|-
 
|$39||DF2A
 
|-
 
|$3A||DF6B
 
|-
 
|$3B||DF96
 
|-
 
|$3C||DFE5
 
|-
 
|$3D||E023
 
|-
 
|$3E||E05D
 
|-
 
|$3F||E088
 
|-
 
|$40||E0AB
 
|-
 
|$41||E0CE
 
|-
 
|$42||E0F1
 
|-
 
|$43||E109
 
|-
 
|$44||E122
 
|-
 
|$45||E14F
 
|-
 
|$46||E177
 
|-
 
|$47||E1A4
 
|-
 
|$48||E1C4
 
|-
 
|$49||E1DE
 
|-
 
|$4A||E206
 
|-
 
|$4B||E22E
 
|-
 
|$4C||E278
 
|-
 
|$4D||E2A2
 
|-
 
|$4E||E2CF
 
|-
 
|$4F||E313
 
|-
 
|$50||E322
 
|-
 
|$51||E35A
 
|-
 
|$52||E38B
 
|-
 
|$53||E3A8
 
|-
 
|$54||E3E8
 
|-
 
|$55||E42B
 
|-
 
|$56||E453
 
|-
 
|$57||E463
 
|-
 
|$58||E481
 
|-
 
|$59||E49A
 
|-
 
|$5A||E4F6
 
|-
 
|$5B||E523
 
|-
 
|$5C||E530
 
|-
 
|$5D||E558
 
|-
 
|$5E||E581
 
|-
 
|$5F||E5B2
 
|-
 
|$60||E5DA
 
|-
 
|$61||E61B
 
|-
 
|$62||E64C
 
|-
 
|$63||E662
 
|-
 
|$64||E68C
 
|-
 
|$65||E6AB
 
|-
 
|$66||E6E1
 
|-
 
|$67||E730
 
|-
 
|$68||E75C
 
|-
 
|$69||E7B0
 
|-
 
|$6A||E7DD
 
|-
 
|$6B||E811
 
|-
 
|$6C||E823
 
|-
 
|$6D||E833
 
|-
 
|$6E||E852
 
|-
 
|$6F||E886
 
|-
 
|$70||E896
 
|-
 
|$71||E8E0
 
|-
 
|$72||E8EA
 
|-
 
|$73||E917
 
|-
 
|$74||E94B
 
|-
 
|$75||E978
 
|-
 
|$76||E9A7
 
|-
 
|$77||E9D1
 
|-
 
|$78||EA1B
 
|-
 
|$79||EA48
 
|-
 
|$7A||EA93
 
|-
 
|$7B||EAC7
 
|-
 
|$7C||EAF7
 
|-
 
|$7D||EB28
 
|-
 
|$7E||EB55
 
|-
 
|$7F||EB6D
 
|-
 
|$80||EB8B
 
|-
 
|$81||EBBA
 
|-
 
|$82||EC05
 
|-
 
|$83||EC32
 
|-
 
|$84||EC7E
 
|-
 
|$85||ECAB
 
|-
 
|$86||ECD8
 
|-
 
|$87||ED05
 
|-
 
|$88||ED3B
 
|-
 
|$89||ED68
 
|-
 
|$8A||ED75
 
|-
 
|$8B||EDA9
 
|-
 
|$8C||EDDF
 
|-
 
|$8D||EE10
 
|-
 
|$8E||EE2A
 
|-
 
|$8F||EE5B
 
|-
 
|$90||EE91
 
|-
 
|$91||EEC3
 
|-
 
|$92||EEF9
 
|-
 
|$93||EF2D
 
|-
 
|$94||EF77
 
|-
 
|$95||EFA6
 
|-
 
|$96||EFD5
 
|-
 
|$97||F009
 
|-
 
|$98||F01C
 
|-
 
|$99||F068
 
|-
 
|$9A||F090
 
|-
 
|$9B||F0AF
 
|-
 
|$9C||F114
 
|-
 
|$9D||F14B
 
|-
 
|$9E||F17F
 
|-
 
|$9F||F1C0
 
|-
 
|$A0||F1FC
 
|-
 
|$A1||F214
 
|-
 
|$A2||F23C
 
|-
 
|$A3||F274
 
|-
 
|$A4||F2A1
 
|-
 
|$A5||F2CE
 
|-
 
|$A6||F2FB
 
|-
 
|$A7||F313
 
|-
 
|$A8||F33B
 
|-
 
|$A9||F365
 
|-
 
|$AA||F38F
 
|-
 
|$AB||F3EA
 
|-
 
|$AC||F42A
 
|-
 
|$AD||F49C
 
|-
 
|$AE||F4AB
 
|-
 
|$AF||F4DA
 
|-
 
|$B0||F507
 
|-
 
|$B1||F582
 
|-
 
|$B2||F5D7
 
|-
 
|$B3||F603
 
|-
 
|$B4||F67D
 
|-
 
|$B5||F6AA
 
|-
 
|$B6||F6D2
 
|-
 
|$B7||F713
 
|-
 
|$B8||F745
 
|-
 
|$B9||F76C
 
|-
 
|$BA||F794
 
|-
 
|$BB||F7BE
 
|-
 
|$BC||F7CE
 
|-
 
|$BD||F7F9
 
|-
 
|$BE||F837
 
|-
 
|$BF||F86A
 
|-
 
|$C0||F89C
 
|-
 
|$C1||F8D1
 
|-
 
|$C2||F907
 
|-
 
|$C3||F91E
 
|-
 
|$C4||F94E
 
|-
 
|$C5||F97E
 
|-
 
|$C6||F9B7
 
|-
 
|$C7||F9F2
 
|-
 
|$C8||FA21
 
|-
 
|$C9||FA2B
 
|-
 
|$CA||FA66
 
|-
 
|$CB||FA9C
 
|-
 
|$CC||FAD7
 
|-
 
|$CD||FB12
 
|-
 
|$CE||FB45
 
|-
 
|$CF||FB60
 
|-
 
|$D0||FB6A
 
|-
 
|$D1||FBA1
 
|-
 
|$D2||FBBE
 
|-
 
|$D3||FBF4
 
|-
 
|$D4||FC2D
 
|-
 
|$D5||FC64
 
|-
 
|$D6||FC9D
 
|-
 
|$D7||FCCE
 
|-
 
|$D8||FCFF
 
|-
 
|$D9||FD32
 
|-
 
|$DA||FD62
 
|-
 
|$DB||FD94
 
|-
 
|$DC||FD94
 
|-
 
|$DD||FD94
 
|-
 
|$DE||FD94
 
|-
 
|$DF||FD94
 
|}
 
 
 
===Ristar===
 
 
 
* Music Pointers (32-bit): $C852A
 
** Specifics...
 
{| class="prettytable"
 
|-
 
! Address||Song
 
|-
 
|$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-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 [Greedy Game]
 
|-
 
|$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 [Let's Go!!]
 
|-
 
|$DD240||area clear [Go Ahead]
 
|-
 
|$DD5C8||game over [Game Over]
 
|-
 
|$DD7EC||defeated Greedy, before imploding cutscene
 
|-
 
|$DD978||Sonata 1 (mini boss 3 note intro)
 
|-
 
|$DDA1E||"Sega" music
 
|}
 
*Sound Effect Pointers (32-bit): $CA2F6
 
 
 
===MJ's Moonwalker===
 
* Music Pointers (32-bit): $600A4
 
** Specifics...
 
{| class="prettytable"
 
|-
 
! Offset||ID||Song
 
|-
 
|$63588||$81||Smooth Criminal
 
|-
 
|$63DAE||$82||Beat It
 
|-
 
|$64614||$83||Another Part of Me
 
|-
 
|$64FEA||$84||Billie Jean
 
|-
 
|$65726||$85||Bad
 
|-
 
|$65D5C||$86||Moonwalker Title SFX
 
|-
 
|$65E22||$87||"Some Cool SFX" (lol Oerg)
 
|-
 
|$65E96||$88||Boss Appears
 
|-
 
|$66300||$89||Smooth Criminal Dance
 
|-
 
|$66488||$8A||Smooth Criminal Dance
 
|-
 
|$666DA||$8B||Smooth Criminal Dance
 
|-
 
|$66924||$8C||Smooth Criminal Dance
 
|-
 
|$66AD8||$8D||Beat It dance
 
|-
 
|$66CB8||$8E||Beat It dance
 
|-
 
|$66E96||$8F||Beat It dance
 
|-
 
|$6706E||$90||Beat It dance (Crashes)
 
|-
 
|$671F0||$91||Bad dance
 
|-
 
|$6742E||$92||???? (Only plays some noises)
 
|-
 
|$6745E||$93||Bad dance
 
|-
 
|$67718||$94||???? (Crashes)
 
|-
 
|$678F6||$95||Thriller dance
 
|-
 
|$67AC2||$96||???? (Crashes)
 
|}
 
 
 
===Gunstar Heroes===
 
* Music Pointers (32-bit): $68F42
 
** Specifics...
 
{| class="prettytable"
 
|-
 
! Offset||ID||Song
 
|-
 
|$68F42||81||Stage 1 - Village
 
|-
 
|$68F46||82||Completion fanfare
 
|-
 
|$68F4A||83||VS. Pinky Roader
 
|-
 
|$68F4E||84||VS. Orange
 
|-
 
|$68F52||85||Stage 2 - The Mine
 
|-
 
|$68F56||86||VS. Bravoo Man
 
|-
 
|$68F5A||87||Stage 3 - Airship (Also used in other in-game locations.)
 
|-
 
|$68F5E||88||VS. Green/Seven Force
 
|-
 
|$68F62||89||Stage 5 - The Empire
 
|-
 
|$68F66||8A||Stage 4 - Black's Silly Dice Maze
 
|-
 
|$68F6A||8B||Title Screen
 
|-
 
|$68F6E||8C||Ending Cutscene
 
|-
 
|$68F72||8D||Stage 6 - Empire's Spaceship
 
|-
 
|$68F76||8E||Stage Complete
 
|-
 
|$68F7A||8F||Crisis theme
 
|-
 
|$68F7E||90||VS. Black
 
|-
 
|$68F82||91||VS. Smash Daisaku
 
|-
 
|$68F86||92||VS. Empire's Spaceship core
 
|-
 
|$68F8A||93||Intro
 
|-
 
|$68F8E||94||VS. Golden Silver
 
|-
 
|$68F92||95||Briefing/Level Select
 
|-
 
|$68F96||96||Credits
 
|-
 
|$68F9A||97||Game Over
 
|-
 
|$68F9E||98||Options tune/Final Stage
 
|-
 
|$68FA2||99||Continue?
 
|-
 
|$68FA6||9A||(not on sound test) Airship
 
|-
 
|$68FAA||9B||(not on sound test) Options
 
|}
 
 
 
*Sound Effect Pointers (32-bit): $69028
 
 
 
===Crayon Shin-Chan===
 
* Music Pointers (32-bit): $1301EC
 
 
 
===Dynamite Headdy===
 
* Music Pointers (32-bit): $5E536
 
 
 
===Alien Soldier===
 
* Music Pointers (32-bit): $84E78
 
 
 
===Phantasy Star 3===
 
* Music Pointers (These add to $6800): $70376
 
 
 
===Phantasy Star 4===
 
*Music Pointers (32-bit): $D1C40
 
*The sound test's pointer table is located at $2AFCDE. Each track is formatted as a 2-byte entry: the first byte uses the internal ID listed below, the second byte designates the composer (00 = IPPO, 01 = GAKI CHAN).
 
{| class="prettytable"
 
|-
 
!ID||Offset||Sound Test||Title
 
|-
 
|$81||$D1D8E||12||TONOE DE PON
 
|-
 
|$82||$D2386||04||INN
 
|-
 
|$83||$D2494||08||MOTABIA VILLAGE
 
|-
 
|$84||$D294E||02||MOTABIA TOWN
 
|-
 
|$85||$D2DA0||20||ORGANIC BEAT
 
|-
 
|$86||$D31E0||31||DEZORIS TOWN 1
 
|-
 
|$87||$D3568||09||NOW ON SALE
 
|-
 
|$88||$D38A2||16||BEHIND THE CIRCUIT
 
|-
 
|$89||$D3D92||23||MACHINE CENTER
 
|-
 
|$8A||$D409C||13||IN THE CAVE
 
|-
 
|$8B||$D42D8||07||WINNERS!
 
|-
 
|$8C||$D43CA||05||FIELD MOTABIA
 
|-
 
|$8D||$D48C4||24||LAND MASTER AVX-25
 
|-
 
|$8E||$D4D8C||35||REQUIEM FOR LUTZ
 
|-
 
|$8F||$D505A||06||MEET THEM HEAD-ON!
 
|-
 
|$90||$D583C||39||RYUCROSS FIELD
 
|-
 
|$91||$D59E2||21||PS1 DUNGEON ARRANGE 1
 
|-
 
|$92||$D5F0E||17||FAL
 
|-
 
|$93||$D61D4||37||TEMPLE NGANGBIUS
 
|-
 
|$94||$D64F4||12||THRAY
 
|-
 
|$95||$D6C86||14||DEFEAT AT A BLOW!
 
|-
 
|$96||$D7142||25||CYBERNETIC CARNIVAL
 
|-
 
|$97||$D7590||10||TERRIBLE SIGHT
 
|-
 
|$98||$D79D2||42||EDGE OF DARKNESS
 
|-
 
|$99||$D7D0C||30||DEZORIS FIELD 1
 
|-
 
|$9A||$D7FA0||40||TOWER
 
|-
 
|$9B||$D8424||28||TAKE OFF! LANDEEL
 
|-
 
|$9C||$D8A14||34||DEZORIS TOWN 2
 
|-
 
|$9D||$D8E40||33||DEZORIS FIELD 2
 
|-
 
|$9E||$D912E||15||A HAPPY SETTLEMENT
 
|-
 
|$9F||$D9530||03||SUSPICION
 
|-
 
|$A0||$D97F4||38||THE KING OF TERRORS
 
|-
 
|$A1||$D9DB0||41||THE AGE OF FABLES
 
|-
 
|$A2||$DA100||43||ABYSS
 
|-
 
|$A3||$DA3F2||--||sound effect
 
|-
 
|$A4||$DA48E||19||HER LAST BREATH
 
|-
 
|$A5||$DA660||18||PAIN
 
|-
 
|$A6||$DA78C||32||JIJY NO RAG
 
|-
 
|$A7||$DAE46||--||PS1 DUNGEON ARRANGE 2 (post-battle fade-in version)
 
|-
 
|$A8||$DB322||26||THE BLACK BLOOD
 
|-
 
|$A9||$DB48E||29||RED ALART
 
|-
 
|$AA||$DB676||27||LAUGHTER
 
|-
 
|$AB||$DBC78||--||sound effect (plays when Chaz reaches the top room of the Anger Tower)
 
|-
 
|$AC||$DBD08||01||THE END OF THE MILLENNIUM
 
|-
 
|$AD||$DC306||--||sound effect (big explosion, tower crumbling, etc)
 
|-
 
|$AE||$DC344||47||STAFF ROLL
 
|-
 
|$AF||$DCAB8||45||THE PROMISSING FUTURE 1
 
|-
 
|$B0||$DCDC2||48||PAO-PAO!
 
|-
 
|$B1||$DD220||22||PS1 DUNGEON ARRANGE 2
 
|-
 
|$B2||$DD5AC||46||THE PROMISSING FUTURE 2
 
|-
 
|$B3||$DDC1E||36||DEZORIS DE DON
 
|-
 
|$B4||$DDD4E||44||OOZE
 
|}
 
 
 
===Pulseman===
 
* Music Pointers (32-bit): $601A6
 
 
 
===The Hybrid Front===
 
* Music Pointers (These add to $60000): $63AFA
 
* Sound Effect Pointers (These add to $68000): $63B2A
 
** Specifics...
 
{| class="prettytable"
 
|-
 
! ID||Pointer||Song
 
|-
 
|$81||8000||Opening Theme ~ Title
 
|-
 
|$82||8FB1||Tactics Preparation
 
|-
 
|$83||951D||Earth ~ Rebellion Fight BGM 1
 
|-
 
|$84||9CF6||Turn Start
 
|-
 
|$85||9D8F||Prologue
 
|-
 
|$86||9EBD||Combat Scenario
 
|-
 
|$87||A306||Earth ~ Sukarabe Fight BGM 1
 
|-
 
|$88||8030||Title (no opening)
 
|-
 
|$89||A99A||Earth ~ Rebellion Fight BGM 2
 
|-
 
|$8A||892F||Earth ~ PETO Fight BGM 1
 
|-
 
|$8B||935B||Game Over
 
|-
 
|$8C||9578||At the End of Combat
 
|-
 
|$8D||98BC||Earth ~ Sukarabe Fight BGM 2
 
|-
 
|$8E||A271||Earth ~ Sukarabe Fight BGM 3
 
|-
 
|$8F||A973||Earth ~ PETO Fight BGM 2
 
|-
 
|$90||B2A4||Ending Theme
 
|-
 
|$91||BDE2||Staff Roll
 
|-
 
|$92||C6A0||Moon - Mars ~ Sakurabe Fight BGM 3
 
|-
 
|$93||CD49||Moon - Mars ~ Sakurabe Fight BGM 1
 
|-
 
|$94||D345||Moon - Mars ~ Sakurabe Fight BGM 2
 
|-
 
|$95||DA73||Moon - Mars ~ Cocoon Fight BGM 2
 
|-
 
|$96||E2DF||Moon - Mars ~ Cocoon Fight BGM 1
 
|-
 
|$97||EA42||Moon - Mars ~ PETO Fight BGM 2
 
|-
 
|$98||ED86||Moon - Mars ~ PETO Fight BGM 1
 
|}
 
 
 
===Dyna Brothers 2===
 
* Music Pointers (These add to $1D0000): $1D01DF
 
 
 
===Revenge of Shinobi===
 
* Music Pointers (32-bit): $74770
 
* Sound Effect Pointers (32-bit): $747EC
 
** Specifics...
 
{| class="prettytable"
 
|-
 
! Address||Song
 
|-
 
|$79A9C||The Shinobi
 
|-
 
|$7A47C||Terrible Beat
 
|-
 
|$7AACE||Round Clear
 
|-
 
|$7AC10||Make Me Dance
 
|-
 
|$7B56C||Over The Bay
 
|-
 
|$7BCE2||China Town
 
|-
 
|$7C44E||Run Or Die
 
|-
 
|$7C884||Like A Wind
 
|-
 
|$7CF8C||Labyrinth
 
|-
 
|$7D1D4||Sunset Blvd.
 
|-
 
|$7D75E||The Dark City
 
|-
 
|$7DBD2||Ninja Step
 
|-
 
|$7E1C2||Long Distance
 
|-
 
|$7E5BC||Failure
 
|-
 
|$7E6B6||Silence Night
 
|-
 
|$7E8F2||My Lover
 
|-
 
|$7EBFA||Game Over
 
|-
 
|$7ECA4||The N. Master
 
|-
 
|$7F1B8||Opening
 
|}
 
 
 
===Shadow Dancer===
 
* Music Pointers (32-bit): $62AF4
 
 
 
===Shinobi III===
 
* Music Pointers (32-bit): $6CE3C
 
** Specifics...
 
{| class="prettytable"
 
|-
 
! Address||Song
 
|-
 
|$6D01C||He Runs (Round 1-2)
 
|-
 
|$6E214||Ninja Soul (Round 2-2)
 
|-
 
|$6EF6A||Shadows (Boss 2)
 
|-
 
|$6F690||Idaten (Round 2-1)
 
|-
 
|$6FFF4||Hassou! (Mid-Boss)
 
|-
 
|$70742||Sakura (Ending)
 
|-
 
|$70DD2||Inner Darkside (Round 3-1)
 
|-
 
|$71526||Shinobi Walk (Round 4-2)
 
|-
 
|$7219E||Rush and Beat (Round 5-2)
 
|-
 
|$72B3A||Storm Wind (Start)
 
|-
 
|$72C48||Getufu (Continue)
 
|-
 
|$72DA4||Wabi (Last Life Missed)
 
|-
 
|$72EA6||Sabi (Life Missed)
 
|-
 
|$72F8E||Idaten SFX
 
|-
 
|$72FA6||Shinobi (Opening Theme)
 
|-
 
|$73A1E||Trap Boogie (Round 3-2)
 
|-
 
|$73F9A||Round Clear
 
|-
 
|$74102||Game Over
 
|-
 
|$741F0||Japonesque (Round 1-1)
 
|-
 
|$7492A||Solitary (Round 7-1)
 
|-
 
|$74F48||Izayoi (Round 6-2)
 
|-
 
|$7534A||Whirlwind (Round 4-1)
 
|-
 
|$75A36||My Dear D (Boss 3)
 
|-
 
|$76398||Stage Clear
 
|-
 
|$76484||Mandara (Boss 1)
 
|-
 
|$76AAC||Ground Zero (Staff Roll)
 
|-
 
|$7733A||Shadow Master (Final Boss)
 
|}
 
 
 
===Dick Tracy===
 
* Music Pointers (These add to $78000): $78236
 
 
 
===Ghostbusters===
 
* Music Pointers (These add to $78000): $78268
 
 
 
===Castle of Illusion===
 
* Music Pointers (These add to $70000): $7008D
 
 
 
===Mystic Defender===
 
* Music Pointers (These add to $48000): $482AA
 
 
 
===ESWAT Cyber Police===
 
* Music Pointers (These add to $18000): $18326
 
 
 
===Dangerous Seed===
 
* Music Pointers (These add to $70000): $7823F
 
 
 
===Viewpoint===
 
* Music Pointers (These add to $10000): $10237
 
 
 
===Alien Storm===
 
* Music Pointers (These add to $78000): $78064
 
{| class="prettytable"
 
|-
 
! ID||Pointer||Song
 
|-
 
|$81||$78088||Player Select
 
|-
 
|$82||$781BD||Theme "BUSTERS"
 
|-
 
|$83||$783FD||Break Out
 
|-
 
|$84||$7858A||Cybernate-Q
 
|-
 
|$85||$78A38||Noise of act!
 
|-
 
|$86||$78E11||That's G.G
 
|-
 
|$87||$79154||Dark Alley
 
|-
 
|$88||$79356||"Beyond" dance
 
|-
 
|$89||$76776||Cybernate-P
 
|-
 
|$8A||$79BAE||We are "BUSTERS"
 
|-
 
|$8B||$7A043||NeuroPath
 
|-
 
|$8C||$7A4A1||Speed Queen!
 
|-
 
|$8D||$7A882||Tireless
 
|-
 
|$8E||$7AB4D||Ulcer
 
|-
 
|$8F||$7AF69||Here we Go!
 
|-
 
|$90||$7B391||Game Over
 
|-
 
|$91||$7B4A1||Nuclear Dance!
 
|}
 
===Streets of Rage/Bare Knuckle (REV01)===
 
*Music Pointers (32-bit): $7288C
 
 
 
===Cosmic Carnage===
 
* Music Pointers (32-bit): $82AAC
 
** NOTE: Cosmic Carnage is 32x, so $900000 is added to each pointer.
 
 
 
===Columns III===
 
* Music Pointers (These add to $70000): $70255
 
===Mega Man: Wily Wars (E)===
 
* Music:
 
:The 68000 copies music data to Z80 RAM location $1000, starting with a pointer to the song data (see below). The 32-bit pointers to the list of songs is at $6E348. Each pointer in the list points to data of the form
 
dc.w length ; 68000 endian
 
dc.w $0210 ; in Z80 endian, this is $1002, the pointer to the song data
 
dc.b (song data)
 
:So to extract the song, start at 4 + the pointer.
 
* Sound Effects:
 
:These, on the other hand, are read from the ROM bank, like with most other SMPS/Z80s. The pointer list is at ROM $1E4000, and each raw pointer value adds to $1D8000.
 
 
 
===OutRun===
 
* Music Pointers (Add raw values to $E8000): $F0479
 
===Outrunners===
 
* Music Pointers: $55114
 
:Each entry in this list is three bytes of the form
 
db ''bank''
 
dw ''offset'' ; (Z80 endian — byte swap when viewing in a hex editor)
 
:''bank'' is either 0 or 1. A value of 0 means add the offset to $1E8000; a value of 1 means add to $1F0000. For example, the first entry reads
 
db 0
 
dw $9EBC
 
:0 means add $9EBC to $1E8000 to get $1F1EBC.
 
 
 
===Stellar Assault (Shadow Squadron)===
 
* Music Pointers (32-bit): $C2868
 
** NOTE: Shadow Squadron is 32x, so $900000 is added to each pointer.
 
===Tempo===
 
* Music:
 
:You will need to consult two lists: a bank list and a pointer list. The bank list is at ROM address $1F0921; the pointer list at ROM $1F11EB. For the nth song (starting with 0), the nth byte in the bank list correspond to bits 22-15 of the final address (clear the upper bit of the final address); the nth word (Z80 endian) in the pointer list correspond to bits 14-0 (drop the upper bit). For example, the first song has a bank value of $38 and a pointer value of $9B8B. Shifting $38 left 15 bits to fill it in bits 22-15 yields $1C0000. Drop the highest bit from the pointer to get $1B8B, which you then add to $1C0000 to get $1C1B8B.
 
 
 
===Virtua Racing Deluxe (U)===
 
* Music Pointers (32-bit): $32AB7
 
** NOTE: "8B" at start of pointers resolves to $30000.
 
 
 
===Zaxxon's Motherbase 2000===
 
* Music Pointers (These add to $78000): $1F7E
 
* Music Pointers (These add to $70000): $1F9E
 
* Sound Effect Pointers (These add to $78000): $1FAE
 
 
 
=== Quackshot (REV01) ===
 
 
 
* Music pointers (add to $130000): $13011B
 
** Music 8C's pointer points to Z80 RAM since the song is loaded into RAM. Its location in the ROM is $13A0CA
 
* Sound pointers: $1392A6
 
** All these pointers point to Z80 RAM as the sound data is loaded into RAM starting at $DD0. To get the location of a sound in the ROM, put the pointer in big-endian order, subtract $DD0 from it and add $1392A6 to it.
 
 
 
==Tricks of the Trade==
 
===Music porting===
 
Ah, yes. Music porting. An infamous practice that many want to achieve. This section will explain the various methods of porting music from one game to another. If something is not possible, it will be noted.
 
 
 
====Sonic 1 -> Sonic 2 Beta====
 
This is one of the easier jobs in my opinion, but it can be a bit tough at first. The trick is to convert the pointer format from S1 to S2B format. First, you have to convert the header pointers. This is the easiest part, as all the pointers are simple relative pointers. So here's what you do...
 
 
 
First off, mark the location you want to place the music at in pointer form. EX: F8000 goes to 8000, which goes to 0080, etc etc. Then, take this base location and add the relative values to it. So if I was placing my music at F9CDE, and my voice pointer was 0312, I would add 312 bytes to F9CDE. This gives me F9FF0. I then take this and convert it into pointer form. An easy way to do so in this case is to simply remove the F. This leaves me with 9FF0, which I then byteswap. This leaves me with the final converted pointer of F09F. Do this for every pointer in the header, as the rest you can leave intact.
 
 
 
The next job is to convert all the pointers in the coordination flags that have them. There are 3 flags in total that do so: F6, F7, and F8. Become familiar with the syntax; Know which is the pointer and which is not. Converting proceeds as follows...
 
 
 
We'll start with an example of sorts. As I noted before, with coordination flag pointers in S1, signed values are used. FFFF is 0, etc. The math works in the same way as our last job, but this time we use different variables. Our base location is found out by marking the offset of the byte where the actual pointer is. In the case of F6 and F8, the byte after F6/F8. In the case of F7, skip two bytes after the F7 to where the pointer is. This is all in my syntax breakdowns, BTW.
 
 
 
Now that we have our base location, we can convert the pointer. Now remember, instead of 0000 being zero, in this case FFFF is zero. So if we want to convert our pointer easily, we have to make our pointer as simple as the header pointers. For negative jumps (below FFFF), we take the pointer value and subtract it from FFFF. This will leave us with a simple relative value. For example, if my S1 pointer was FFE6, I would subtract FFE6 from FFFF. This gives me 19 as a result, meaning this pointer is meant to locate data 19 bytes before our base location. Now we have to convert this into S2B form. Take your base location and subtract your result relative value (19 in my case) from it. For example, if my base location was FEE90 (90EE), I would subtract 19 bytes from it (my result value from the above operation). That would give me the offset of FEE77. I then convert this into pointer form, giving me the final converted pointer of 77EE.
 
 
 
For positive values (above FFFF), things are a bit simpler. Simply take the positive value and subtract 1 from it. Then, add it to your base location. So if my pointer was 0090, I subtract 1 from it. This gives me 8F. I then add this value to my base location, which was FEE90. FEE90 + 8F = FEF1F. Then, convert this into S2B pointer form. This gives me the final converted pointer of 1FEF. Fun, eh? =P
 
 
 
Remember to do this with ALL pointers in the song. You won't get off correcting two or three, I'll tell you that much. :P
 
 
 
=====Points to note=====
 
Always remember to change the music pointer to point to your new music. Otherwise you'll have done this all for nothing. Also, S1 voices are not entirely compatible with S2 voices. You may have to apply new voices to the song to make it sound right. This is why the instruments in Esrael's port of Marble zone sounded different; he had to make new ones.
 
 
 
====Porting between Sonic 3K/3D/Crackers/Chaotix====
 
This job is much simpler, as all pointers use the same format. There are two methods of porting this music between each other...
 
 
 
# Simply put the music in the "same" location according to pointer format. For example, having music at C0000 or C8000 would be the same as having it at 10000 or 18000. All the result pointers would be 0080. Get it? =P Simple copy and paste, and nothing else needs to be done. Just change the music pointer to point to the new music and presto! Ported music. This method limits your customization as where to put the music though, and I don't recommend it unless you are porting whole music banks or it is incredibly convenient. It is easier though, so hey. =P
 
# Modify all pointers inside the music (header and coordination flags) to go along with the new location you put it at. Here's a simple way to do so...
 
 
 
First off, take your original location, which is the beginning of the song. Then, work out where you are going to put the song. Convert both these values into pointer format. Now, work out the difference between these two values. For example, if the original location was F802A (2A80 in pointer format), and I wanted to put it at FD980 (80D9 in pointer format), then I would subtract my new location from my original location. So in my case, FD980 - F802A. This gives me 5956. Now, this will be your modifying value for each pointer. You add this location to each pointer in the song to get your converted pointer.
 
 
 
Let me give an example of a negative value. My original location was FA000 and my new location was F9027. This time, we switch the operation. FA000 - F9027 = FD9. This time, you subtract this value from each pointer in the song to get the converted pointer. So remember, if you are moving a song to a location before the original location, subtract. If you are moving it to a location beyond the original, add.
 
 
 
=====Points to note=====
 
If Sonic 3 music has D817 as the voice pointer, then it cannot be ported outside of S3K without being given a new voice set. Sonic 3K is the only game with this universal voice bank, and specifying it in any other game will have no effect.
 
 
 
====Porting from Sonic 2 Beta to Sonic 3K/3D/Crackers/Chaotix====
 
 
 
This is a very simple job, provided you have a good eye for detail. The trick is to replace the differing coordination flags between the two games. This is a simple task, and you can do it in two simple steps.
 
 
 
# Run a search in the song for coordination flag E3. This is the S2 flag to return. We need to replace this with the Sonic 3K/etc equivalent, F9. Change all valid instances of E3 to F9. This will fix awkward jumps in the song that were hindering porting before.
 
 
 
# Run another search in the song for coordination flag E9. This is the S2 flag to add a value to the current channel pitch. We need to replace this with the Sonic 3K equivalent, FB. Change all valid instances of E9 to FB. This will fix certain lagging in some songs, lack of pitch change, and even crashing.
 
 
 
When I mention valid instances, I mean that the values of E9 or E3 are not part of another coordination flag. Make sure you know the format of most coordination flags, as to avoid making fatal mistakes that may destroy your entire port.
 
 
 
=====Points to note=====
 
Some voices may be wrong. You will have to fix this manually, provided you know how.
 
 
 
====Porting from Sonic 3K/3D/Crackers/Chaotix to Sonic 2 Beta====
 
Just do the opposite of the method above; replace F9 with E3 and FB with E9.
 
 
 
  
 +
* August 23 2011: added missing s3/s&k Dac Sample $8E (Low Metal Hit)
 
{{SCHGuides}}
 
{{SCHGuides}}
 
[[Category:Sonic Community Hacking Guide|Music Hacking]]
 
[[Category:Sonic Community Hacking Guide|Music Hacking]]

Revision as of 12:58, 15 April 2018

Music Hacking: Pointer and Header Format | Voice and Note Editing | DAC Samples, Coordination Flags, Game Specifics, and Real-Time Music Editing | Other Games and Data Locations | Tricks of the Trade



Original Credits

Guide originally created by Tweaker on May 25 2005.

Thanks to:

Prologue

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. It's also recommended that you read and save a copy of the YM2612 technical documentation and maybe the PSG documentation so that you can more easily understand how the voices and coordination flags work.

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. Can't say it works perfectly though. :P.
  • May 24 2005: Updated with even more Sonic 2 final info. Also added music pointer locations for Ristar and Michael Jackson's Moonwalker.
  • September ?? 2005: Fucking huge update. Massive amounts of new info, mainly concerning DAC samples. All the DAC sample definitions for Sonic 3 are now available, leaving many possibilities in the field. Also, I specified the DAC samples in Sonic 1 and 2 more, so Sonic QX users can be more precise with custom imports. Also, the purpose of two more coordination flags has been found out that have to do with PSG. Then, there are the small changes. A bit of proofreading, clarification... etc. I know I promised realtime music editing this update... Sorry I couldn't get it. It's my next priority, promise. =P

Some of these random things:

  1. Added some new locations. Found a new pointer set in Sonic 3 and found the sound effect pointers as well. Can't find out what the SFX add to yet though.
  2. Got into specifics with the Sonic 2 Final pointer list. And yes, it's in the right order. :P
  3. Added "$" signs to most ROM addresses as it's more proper. Meh, nitpicky shit. =P
  4. I wrote a tutorial on porting music from one game to another. I know people have been wanting this, so here you go. ;)


  • September 2 2006: Wow, it's been over a year since the last update! Has it really been that long? o_O

Anyway, I finally got the realtime music editing section done. Savestate locations and Z80 RAM equivalents are listed, with explanations on how to tinker with music, even while it’s still playing. Also added locations for a shitload of games, mostly from my notes. I also added more to the music porting section. And once again, various corrections and such... I can't be arsed to keep track of what I change anymore, so bleh. =P

  • August 22 2011: updated by kram1024, flamewing and others with all the new info discovered recently about smps by flamewing's most recent disasm of the s&k driver.
  • August 23 2011: added missing s3/s&k Dac Sample $8E (Low Metal Hit)
Sonic Community Hacking Guide
General
Sonic Music Hacking Guide | SonED2 Manual
Game-Specific
Sonic the Hedgehog (16-bit) | Sonic the Hedgehog (8-bit) | Sonic Eraser | Sonic CD (prototype 510) | Sonic CD | Sonic CD (PC) | Sonic CD (2011) | Sonic 2 (Nick Arcade prototype) | Sonic 2 (Simon Wai prototype) | Sonic 2 (16-bit) | Sonic 2 (8-bit) | Sonic 2 & Knuckles | Dr. Robotnik's Mean Bean Machine | Sonic Triple Trouble | Sonic 3 | Sonic & Knuckles | Sonic the Hedgehog 3 & Knuckles | Sonic & Knuckles Collection | Sonic Crackers | Sonic 3D: Flickies' Island | Chaotix | Sonic R PC | Sonic Jam 6 | Sonic Advance | Sonic Advance 2 | Sonic Advance 3 | Sonic Battle | Sonic Adventure | Sonic Adventure DX: Director's Cut | Sonic Adventure DX: PC | Sonic Adventure (2010) | Sonic Shuffle | Sonic Adventure 2 | Sonic Adventure 2: Battle | Sonic Adventure 2 (PC) | Sonic Heroes | Shadow the Hedgehog | Sonic Riders | Sonic the Hedgehog (2006) | Sonic & Sega All-Stars Racing | Sonic Unleashed (Xbox 360/PS3) | Sonic Colours | Sonic Generations | Sonic Lost World | Sonic Forces
Legacy Guides
The Nemesis Hacking Guides The Esrael Hacking Guides
ROM: Sonic 1 | Sonic 2 | Sonic 2 Beta | Sonic 3

Savestate: Sonic 1 | Sonic 2 Beta/Final | Sonic 3

Sonic 1 (English / Portuguese) | Sonic 2 Beta (English / Portuguese) | Sonic 2 and Knuckles (English / Portuguese)
Move to Sega Retro
Number Systems (or scrap) | Assembly Hacking Guide | Subroutine Equivalency List | 68000 Instruction Set | 68000 ASM-to-Hex Code Reference | VDP Documentation | Official Sega 32X Documentation | Official Mega-CD Documentation | Official Sega Mega Drive Documentation