We've managed to restore 99% of our file loss earlier in the year, but it's now THE FINAL COUNTDOWN. Visit the wiki file request topic to help make Sonic Retro better than ever.
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). |


