Sonic the Hedgehog 2 (Master System)/Music Hacking

From Sonic Retro

(Redirected from SCHG:Sonic 2 SMS/Music Hacking)
SCHG: Sonic 2 (Master System)
Main Article
Art Editing
Editing Art
Uncompressed Art
Level Editing
Editing Levels
Level Headers
32x32 MetaTiles
Level Layout
Object Editing
Editing Objects
Object Layout
Object Types
Music Editing
Editing Music
Driver Technical Info
Module Format

Driver Technical Information

Note: Since this is Z80 code, all words are little-endian unless otherwise stated.

Memory layout

Address Size Description
$DD00 Byte Unused
$DD01 Byte Global speed counter
$DD02 Byte Global speed counter reset
$DD03 Byte Sound ID Main Trigger
$DD04 Byte Sound ID Queue, Slot 1
$DD05 Byte Sound ID Queue, Slot 2
$DD06 Byte Sound ID Queue, Slot 3
$DD07 Byte Unused
$DD08 Byte Pause Mode (00 - off, 01-7F - paused, 80-FF - do unpause)
$DD09 Byte Fade-out countdown - major value
$DD0A Byte Fade-out countdown - minor value
$DD0B Byte Fade-out countdown - minor reset value
$DD0C Byte Unused
$DD0D Byte Current sound effect number
$DD0E Byte Unused
$DD0F Byte Current Sound priority
$DD10 Byte Unused (Game Gear Stereo bits in later drivers)
$DD11 Byte Current PSG noise mode
$DD12-14 3 Bytes Unused
$DD15 Byte Unknown (modifies noise mode, never written and should always be 0)
$DD16 Byte Noise channel attenuation
$DD17 41 Bytes Unused
$DD40 48 Bytes Music Channel 1 RAM (PSG 1)
$DD70 48 Bytes Music Channel 2 RAM (PSG 2)
$DDA0 48 Bytes Music Channel 3 RAM (PSG 3)
$DDD0 48 Bytes Music Channel 4 RAM (PSG Noise)
$DE00 48 Bytes SFX Channel 1 RAM (PSG 2)
$DE30 48 Bytes SFX Channel 2 RAM (PSG 3)
$DE60 48 Bytes SFX Channel 3 RAM (PSG Noise)

Channel Structures

Each channel occupies 48 bytes of RAM:

Offset Type Description
$00 Byte Control flags
$01 Byte PSG channel number
$02 Unsigned Byte Note length multiplier
$03 Word Data pointer
$05 Signed Byte Transposition (added to note value)
$06 Signed Byte Volume
$07 Byte Pitch Envelope
$08 Byte Volume Envelope
$09 Unsigned Byte Channel branch "stack" pointer
$0A Unsigned Byte Note duration counter
$0B Unsigned Word PSG tone register value (i.e. the value written to the PSG to generate the note)
$0D Unsigned Byte Note duration reset value
$0E Byte Note Stop counter (number of frames after the note gets turned off)
$0F Byte Note Stop reset value
$10 Word Data pointer for pitch bend effect.
$12 Signed Word Pitch bend effect adjustment value. Added to word at $0B before writing to the PSG.
$14 Unsigned Byte Number of ticks to wait before starting pitch bend.
$15 Unsigned Byte Number of ticks to wait before increasing the pitch bend. Also used as the pitch envelope index.
$16 Signed Byte Pitch bend step size.
$17 Unsigned Byte Number of pitch bend steps before negating step value.
$18 5 Bytes Unused.
$1D Byte Volume effect flags
$1E Byte Volume effect mode (00 - normal, 08 - repeat Attack/Decay phase)
$1F Unsigned Byte Volume effect value / Volume envelope index
$20 Signed Byte Volume Effects - Adjustment value
$21 4 Bytes. Volume effect memory
$25 Signed Byte Detune value (added to raw PSG frequency)
$26 Byte Unused (Channel Stereo Bits in later drivers)
$27 3 Bytes Loop counters
$2A 3 Words Branch return address stack

Channel Control flags

Bit Description
0 Unknown.
1 Maintain effect state across notes
2 Suppress PSG writes (i.e. music channel that is overridden by SFX)
3 Triggers literal read mode
4 Suppress writes to the PSG volume register (channel plays a rest)
5 Unknown
6 Allow PSG volume updates only
7 Channel active flag

Pitch Effect flags

Bit Description
0-6 If bit 7 = 0: pitch envelope number otherwise unused.
7 Set = pitch bend; Reset = pitch envelope.

Literal Read Mode

If bit 3 of the channel's control byte is set the driver enters literal read mode. This changes the way that data is read from the channel's stream: instead of reading bytes, the driver starts reading big-endian words (command bytes are still processed). These words are interpreted as PSG tone register values and are copied into offset $0B. The pitch adjustment at $05 is sign-extended to 16-bits and treated as a detune value which is added to the word before copying to the offset. Each word must be followed by a duration byte.

Module editing

Module header

Offset Size Description
$00 Word Unused. Was probably intended as a pointer to volume envelope data but the driver ignores it.
$02 Byte Number of channels.
$03 Byte Unused. Skipped by the driver.
$04 Byte Note length multiplier. Copied into offset $02 of each channel structure.
$05 Byte Global speed. Copied into $DD01 and $DD02

Following the module header are the channel headers. The number of channel headers must match the value at offset $02 in the module header.

Offset Size Description
$00 Word Channel data pointer (absolute).
$02 Byte Pitch adjustment. (transposition)
$03 Byte Volume adjustment.


Command Description
$00 - $7F Duration values
$80 - $DF Notes ($80 = rest)
$E0vvwwxxyyzz Volume effect / ADSR envelope (Attack, Decay, Sustain, Release)
  • vv - Attack Rate (volume starts at silence and increases with this speed until it reaches the maximum)
  • ww - Decay Rate (how fast the volume decreases after the Attack Phase)
  • xx - Decay Level (volume level where the Decay Phase ends)
  • yy - Sustain Rate (how fast the volume decreases after the Decay Phase)
  • zz - Release Rate (how fast the volume decreases after being turned off)
$E1xx Detune - xx = amount (signed)
$E2xx Adjust volume - same as $E6
$E3xx Nothing (empty slot)
$E4xx Adjust noise volume - xx = amount (signed)
$E5xx Change ADSR Mode. 00 - normal, 01-FF - repeat Attack/Decay phases
$E6xx Adjust volume - xx = amount (signed)
$E7 Maintain effect state (sets bit 1 of channel control)
$E8xx set Note Stop timeout (number of frames after that the note is turned off forcibly, 0 - off)
$E9xx Nothing (empty slot)
$EAxx Nothing (empty slot)
$EBxx Nothing (empty slot)
$ECxx Nothing (empty slot)
$EDxx Set global speed - xx = new speed
$EExx Nothing (empty slot)
$EF Invalid command (points into data)
$F0wwxxyyzz Pitch Bend
  • ww - Number of ticks to wait.
  • xx - Number of ticks before increasing pitch bend.
  • yy - Pitch bend step size.
  • zz - Number of ticks before negating step size.
$F1 Invalid command (points into data)
$F2 Stop channel playback
$F3?? Unknown
$F4xx Pitch envelope - xx = envelope number
$F5xx Volume envelope - xx = envelope number
$F6xxxx Jump - xxxx = absolute address
$F7xxyyzzzz Loop
  • xx - Slot number
  • yy - Loop count
  • zzzz - Absolute address
$F8xxxx Subroutine branch - xxxx = absolute address
$F9 Return from subroutine
$FAxx Set channel speed - xx = new speed
$FBxx Transpose channel by xx (added to current transpose value, which is added to all notes before looking up the PSG frequency)
$FCxx Nothing (empty slot)
$FDxx Set read literal mode. Turned on if xx == $01, otherwise off.
$FExx Nothing (empty slot)
$FFxx Nothing (empty slot)


Sonic Community Hacking Guide
SonED2 Manual | Subroutine Equivalency List
Sonic the Hedgehog (16-bit) | Sonic the Hedgehog (8-bit) | Sonic CD (prototype 510) | Sonic CD | Sonic CD (PC) | Sonic CD (2011) | Sonic 2 (Simon Wai prototype) | Sonic 2 (16-bit) | Sonic 2 (Master System) | Sonic 3 | Sonic 3 & Knuckles | Chaotix | Sonic Jam 6 | Sonic Adventure | Sonic Adventure DX: Director's Cut | Sonic Adventure DX: PC | Sonic Adventure (2010) | Sonic Adventure 2 | Sonic Adventure 2: Battle | Sonic Adventure 2 (PC) | Sonic Heroes | Sonic Riders | Sonic the Hedgehog (2006) | Sonic & Sega All-Stars Racing | Sonic Unleashed (Xbox 360/PS3) | Sonic Colours | Sonic Generations | Sonic Forces
Technical information
Sonic Eraser | Sonic CD (prototype; 1992-12-04) | Sonic 2 (Nick Arcade prototype) | Dr. Robotnik's Mean Bean Machine | Sonic Triple Trouble | Tails Adventures | Sonic & Knuckles Collection | Sonic Crackers | Sonic 3D: Flickies' Island | Sonic R | Sonic Advance | Sonic Advance 3 | Sonic Battle | Sonic Shuffle | Shadow the Hedgehog | Sonic Rush | Sonic Classic Collection | Sonic Lost World
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 | 68000 Instruction Set | 68000 ASM-to-Hex Code Reference | SMPS Music Hacking Guide | Mega Drive technical information