Due to our recent technical difficulties, we only have OVER NINE THOUSAAAAAAAAAAND of our images and files working. The Sonic Retro staff is working as fast as they can to restore these documents. Please do not report broken links at this time.
SCHG:Sonic 2 SMS/Music Hacking
From Sonic Retro
| SCHG: Sonic 2 (Master System) |
|---|
| Main Article |
| Art Editing |
| Editing Art |
| Level Editing |
| Editing Levels |
| Object Editing |
| Editing Objects |
| Music Editing |
| Editing Music |
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 | Main Trigger. |
| $DD04 | Byte | Trigger 1. |
| $DD05 | Byte | Trigger 2. |
| $DD06 | Byte | Trigger 3. |
| $DD07 | Byte | Unknown. |
| $DD08 | Byte | Reset/Disable Trigger |
| $DD09 | Byte | Fade-out countdown - major value. |
| $DD0A | Byte | Fade-out countdown - minor value. |
| $DD0B | Byte | Fade-out countdown - minor reset value. |
| $DD0C | Byte | Unknown. |
| $DD0D | Byte | Current sound effect number. |
| $DD0E | Byte | Unknown |
| $DD0F | Byte | Sound priority. |
| $DD10 | Byte | Unknown. |
| $DD11 | Byte | Unknown (noise channel related). |
| $DD12 | Byte | Unknown. |
| $DD13 | Byte | Unknown. |
| $DD14 | Byte | Unknown. |
| $DD15 | Byte | Unknown (noise channel related). |
| $DD16 | Byte | Noise channel attenuation. |
| $DD17 | 40 Bytes | Unused. |
| $DD40 | 48 Bytes | Primary channel 0 structure. |
| $DD70 | 48 Bytes | Primary channel 1 structure. |
| $DDA0 | 48 Bytes | Primary channel 2 structure. |
| $DDD0 | 48 Bytes | Primary channel 3 (noise) structure. |
| $DE00 | 48 Bytes | Secondary channel 0 structure. |
| $DE30 | 48 Bytes | Secondary channel 1 structure. |
| $DE60 | 48 Bytes | Secondary channel 2 structure. |
Channel Structures
Each channel occupies 48 bytes of RAM:
| Offset | Type | Description |
|---|---|---|
| $00 | Byte | Control flags. |
| $01 | Byte | PSG channel number. |
| $02 | Unsigned Byte | Channel tempo. |
| $03 | Word | Data pointer. |
| $05 | Signed Byte | Pitch adjustment. |
| $06 | Signed Byte | Volume adjustment. |
| $07 | Byte | Pitch effect flags. |
| $08 | Byte | Volume effect flags. |
| $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 | Unknown. |
| $0F | Byte | Unknown. |
| $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 | Unknown (volume effect related). |
| $1F | Unsigned Byte | Channel volume / Volume envelope index. |
| $20 | Signed Byte | Volume Effects - Adjustment value. |
| $21 | 4 Bytes. | Volume effect memory. |
| $25 | Signed Byte | Detune value. |
| $26 | Byte | Unused. |
| $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. |
| 3 | Triggers literal read mode. |
| 4 | Suppress writes to the PSG volume register. |
| 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 | Channel tempo. 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. |
| $03 | Byte | Volume adjustment. |
Commands
| Command | Description |
|---|---|
| $00 - $7F | Duration values. |
| $80 - $DF | Notes ($80 = rest). |
| $E0vvwwxxyyzz | Volume effects (parameters currently unknown). |
| $E1xx | Detune - xx = amount (signed). |
| $E2xx | Adjust volume - xx = amount (signed). |
| $E3 | Nothing (empty slot). |
| $E4xx | Adjust noise volume - xx = amount (signed). |
| $E5xx | Unknown. |
| $E6xx | Adjust volume - same as $E2. |
| $E7 | Maintain effect state (sets bit 1 of channel control). |
| $E8xx | Unknown. |
| $E9 | Nothing (empty slot). |
| $EA | Nothing (empty slot). |
| $EB | Nothing (empty slot). |
| $EC | Nothing (empty slot). |
| $EDxx | Set global speed - xx = new speed. |
| $EE | Nothing (empty slot). |
| $EF | Invalid command (points into data). |
| $F0wwxxyyzz | Pitch Bend -
|
| $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
|
| $F8xxxx | Branch - xxxx = absolute address. |
| $F9 | Return from branch. |
| $FAxx | Set channel speed - xx = new speed. |
| $FBxx | Pitch adjustment - xx = adjustment (added to current value). |
| $FC | Nothing (empty slot). |
| $FDxx | Set read literal mode. Turned on if xx == $01, otherwise off. |
| $FE | Nothing (empty slot). |
| $FF | Nothing (empty slot). |


