Actions

SCHG

Difference between revisions of "Sonic the Hedgehog (16-bit)/RAM Editing"

From Sonic Retro

(Another REV01 variable)
(removing speculation disproven by the discovery of a prototype)
 
(44 intermediate revisions by 7 users not shown)
Line 1: Line 1:
 
{{SCHG S1}}
 
{{SCHG S1}}
==Main System Memory Locations==
+
==Main System Memory locations==
 
This is a map of 68k memory as used by the main gameplay engine. Note that any numbers entered (for example, score or number of rings) will have to be converted to hex first.
 
This is a map of 68k memory as used by the main gameplay engine. Note that any numbers entered (for example, score or number of rings) will have to be converted to hex first.
  
 
These are the offsets in RAM. To convert them to [[Genecyst]] savestate offsets, add $2478. For use in disassemblies, simply add $FF0000 for addresses below $8000 and $FFFF0000 for addresses above or equal to $8000, for example, Sonic's top speed here is $F760, but in the disassembly it is referenced as $FFFFF760. This is useful for finding what bits of code do what when the purpose of a RAM variable is known, or conversely for figuring out the purpose of a RAM variable by looking at the referencing code.
 
These are the offsets in RAM. To convert them to [[Genecyst]] savestate offsets, add $2478. For use in disassemblies, simply add $FF0000 for addresses below $8000 and $FFFF0000 for addresses above or equal to $8000, for example, Sonic's top speed here is $F760, but in the disassembly it is referenced as $FFFFF760. This is useful for finding what bits of code do what when the purpose of a RAM variable is known, or conversely for figuring out the purpose of a RAM variable by looking at the referencing code.
{| border="1" class="prettytable"
+
{| class="prettytable" style="width: auto;"
 
!RAM offset||Description
 
!RAM offset||Description
 
|-
 
|-
Line 26: Line 26:
 
|-
 
|-
 
| $C800 - $CAFF
 
| $C800 - $CAFF
| Sonic's art buffer. Sonic's dynamic pattern reloading routine copies the relevant art over here, from where it is DMAed to VRAM every V-int.
+
| Sonic's art buffer. Sonic's dynamic pattern reloading routine copies the relevant art over here, from where it is DMA'd to VRAM every V-int.
 
|-
 
|-
 
| $CB00 - $CBFF
 
| $CB00 - $CBFF
Line 32: Line 32:
 
|-
 
|-
 
| $CC00 - $CF7F
 
| $CC00 - $CF7F
| Scroll RAM cache (sent to VRAM every frame via DMA)
+
| H-Scroll buffer (sent to VRAM every frame via DMA)
 
|-
 
|-
 
| $CF80 - $CFFF
 
| $CF80 - $CFFF
| <font color=green>Unused</font>
+
| <font color=green>Unused</font> (However, this space is used for the H-Scroll buffer to overflow to, so using this is not recommended)
 
|-
 
|-
 
| $D000 - $D7FF
 
| $D000 - $D7FF
| Reserved object SST space
+
| Reserved object SST space (Various important objects, such as Sonic, shields, invincibility stars, and title cards, are loaded here.)
 
|-
 
|-
 
| $D800 - $EFFF
 
| $D800 - $EFFF
| Main SST space
+
| Dynamic SST space (Level objects are loaded here.)
 
|-
 
|-
 
| $F000 - $F5BF
 
| $F000 - $F5BF
Line 76: Line 76:
 
|-
 
|-
 
| $F606
 
| $F606
| Player 2's held buttons (unused)
+
| <font color=green>Player 2's held buttons (unused, exists because it's from a standard Mega Drive function)</font>
 
|-
 
|-
 
| $F607
 
| $F607
| Player 2's pressed buttons (unused)
+
| <font color=green>Player 2's pressed buttons (unused, exists because it's from a standard Mega Drive function)</font>
 
|-
 
|-
 
| $F608-$F60B
 
| $F608-$F60B
Line 91: Line 91:
 
|-
 
|-
 
| $F614-$F615
 
| $F614-$F615
| An universal counter, mainly used for time to display screens (like the title screen and the demo mode)
+
| General countdown timer
 
|-
 
|-
 
| $F616-$F617
 
| $F616-$F617
| Plane A y-position for previous frame
+
| Plane A y-position for VSRAM
 
|-
 
|-
 
| $F618-$F619
 
| $F618-$F619
| Plane B y-position for previous frame
+
| Plane B y-position for VSRAM
 
|-
 
|-
 
| $F61A-$F61B
 
| $F61A-$F61B
| Plane A x-position for previous frame
+
| <font color=green>Plane A x-position for HScroll (unused)</font>
 
|-
 
|-
 
| $F61C-$F61D
 
| $F61C-$F61D
| Plane B x-position for previous frame
+
| <font color=green>Plane B x-position for HScroll (unused)</font>
 
|-
 
|-
 
| $F61E-$F61F
 
| $F61E-$F61F
| Value of $F71C for previous frame
+
| Copy of $F71C
 
|-
 
|-
 
| $F620-$F621
 
| $F620-$F621
| Value of $F718 for previous frame
+
| Copy of $F718
 
|-
 
|-
 
| $F622-$F623
 
| $F622-$F623
Line 115: Line 115:
 
|-
 
|-
 
| $F624-$F625
 
| $F624-$F625
| VDP setting $8ADF or $8AAF
+
| VDP register $A (H-INT counter) cache (used for water height on screen)
 
|-
 
|-
 
| $F626-$F627
 
| $F626-$F627
Line 121: Line 121:
 
|-
 
|-
 
| $F628
 
| $F628
| <font color=red>Unknown</font>
+
| <font color=green>Counter that increments if the V-INT routine is $E, which is unused</font>
 
|-
 
|-
 
| $F629
 
| $F629
Line 127: Line 127:
 
|-
 
|-
 
| $F62A
 
| $F62A
| VBlank routine counter
+
| V-INT routine ID
 
|-
 
|-
 
| $F62B
 
| $F62B
Line 133: Line 133:
 
|-
 
|-
 
| $F62C
 
| $F62C
| Number of sprites counter
+
| Number of sprites on screen
 
|-
 
|-
 
| $F62D-$F631
 
| $F62D-$F631
Line 154: Line 154:
 
|-
 
|-
 
| $F640-$F641
 
| $F640-$F641
| Used to store VDP values, however is unnecessary.
+
| Used to hold the low word of a DMA transfer command, which is then sent to the VDP control port, to get around a hardware bug.
 
|-
 
|-
 
| $F642-$F643
 
| $F642-$F643
Line 163: Line 163:
 
|-
 
|-
 
| $F646-$F647
 
| $F646-$F647
| Water Height
+
| Water height
 +
|-
 +
| $F648-$F649
 +
| Average water height
 +
|-
 +
| $F64A-$F64B
 +
| Target water height
 
|-
 
|-
| $F648-$F64C
+
| $F64C
| <font color=red>Something to do with Water</font>
+
| Water movement direction
 
|-
 
|-
 
| $F64D
 
| $F64D
Line 172: Line 178:
 
|-
 
|-
 
| $F64E
 
| $F64E
| Water Direction
+
| Flag that is set when water takes up the entire screen
 
|-
 
|-
 
| $F64F
 
| $F64F
Line 178: Line 184:
 
|-
 
|-
 
| $F650-$F661
 
| $F650-$F661
| Used by SBZ palette cycling
+
| SBZ palette cycling buffer (consists of 9 entries with 2 byte sized variables, first being the palette cycle timer, and the second being the palette cycle data index)
 +
|-
 +
| $F662-$F663
 +
| <font color=green>Unused, but is cleared upon loading the SEGA screen</font>
 
|-
 
|-
| $F662-$F67F
+
| $F664-$F67F
 
| <font color=green>Unused</font>
 
| <font color=green>Unused</font>
 
|-
 
|-
| $F680-$F683
+
| $F680-$F6DF
| Address queue for Pattern Load Cues
+
| Pattern load queue. 16 entries with each being 6 bytes in size, consisting of a longword sized variable and a word sized variable. The first variable is a pointer to Nemesis compressed art. The second variable is the destination VRAM address. Once the queue is empty, the first entry's pointer variable is 0.
|-
 
| $F684-$F685
 
| VRAM position to load next PLC'd tiles to
 
|-
 
| $F686-$F6FF
 
| Pattern Load Cues queue
 
|-
 
| $F700-$F701
 
| Plane A x-position
 
 
|-
 
|-
| $F702-$F703
+
| $F6E0-$F6FF
| <font color=green>Unused</font>
+
| Pattern load queue Nemesis decompression variables
 
|-
 
|-
| $F704-$F705
+
| $F700-$F703
| Plane A y-position
+
| Plane A x-position (16.16 fixed point number)
 
|-
 
|-
| $F706-$F707
+
| $F704-$F707
| <font color=green>Unused</font>
+
| Plane A y-position (16.16 fixed point number)
 
|-
 
|-
| $F708-$F709
+
| $F708-$F70B
| Plane B x-position
+
| Primary plane B x-position (16.16 fixed point number)
 
|-
 
|-
| $F70A-$F70B
+
| $F70C-$F70F
| <font color=green>Unused</font>
+
| Primary plane B y-position (16.16 fixed point number)
 
|-
 
|-
| $F70C-$F70D
+
| $F710-$F713
| Plane B y-position
+
| Secondary plane B x-position (16.16 fixed point number)
 
|-
 
|-
| $F70E-$F70F
+
| $F714-$F717
| <font color=green>Unused</font>
+
| Secondary plane B y-position (16.16 fixed point number)
 
|-
 
|-
| $F710-$F711<br>$F714-$F715<br>$F718-$F719<br>$F71C-$F71D
+
| $F718-$F71B
| Used to scroll parts of background
+
| Tertiary plane B x-position (16.16 fixed point number). In REV00, it's only used to scroll the background in special stages, but it ends up having use in normal levels in REV01.
 
|-
 
|-
| $F712-$F713<br>$F716-$F717<br>$F71A-$F71B<br>$F71E-$F71F
+
| $F71C-$F71F
| <font color=green>Seems unused</font>
+
| Tertiary plane B y-position (16.16 fixed point number). Unused in REV00, but it used in REV01.
 
|-
 
|-
 
| $F720-$F721
 
| $F720-$F721
| Levels target left boundary (not implemented)
+
| <font color=green>Level's target left boundary (Unused)</font>
 
|-
 
|-
 
| $F722-$F723
 
| $F722-$F723
| Levels target tight boundary (not implemented)
+
| <font color=green>Level's target right boundary (Unused)</font>
 
|-
 
|-
 
| $F724-$F725
 
| $F724-$F725
| Levels target upper boundary (not implemented)
+
| <font color=green>Level's target upper boundary (Unused)</font>
 
|-
 
|-
 
| $F726-$F727
 
| $F726-$F727
| Levels target lower boundary
+
| Level's target lower boundary
 
|-
 
|-
 
| $F728-$F729
 
| $F728-$F729
| Levels left boundary  
+
| Level's left boundary  
 
|-
 
|-
 
| $F72A-$F72B
 
| $F72A-$F72B
| Levels right Boundary  
+
| Level's right Boundary  
 
|-
 
|-
 
| $F72C-$F72D
 
| $F72C-$F72D
| Levels upper boundary
+
| Level's upper boundary
 
|-
 
|-
 
| $F72E-$F72F
 
| $F72E-$F72F
| Levels lower boundary
+
| Level's lower boundary
 
|-
 
|-
 
| $F730-$F731
 
| $F730-$F731
| <font color=green>Seems to be unused</font>
+
| <font color=green>Written to by LevelSizeLoad, but unused otherwise</font>
 
|-
 
|-
 
| $F732-$F733
 
| $F732-$F733
| <font color=green>Upper level boundary +$240 (Seems to be unused)</font>
+
| <font color=green>Upper level boundary +$240, but unused otherwise</font>
 
|-
 
|-
 
| $F734-$F739
 
| $F734-$F739
Line 256: Line 256:
 
|-
 
|-
 
| $F73A-$F73B
 
| $F73A-$F73B
| Copy of "Plane A X-position"
+
| Number of pixels scrolled by the camera horizontally since the previous frame (multiplied by $100)
 
|-
 
|-
 
| $F73C-$F73D
 
| $F73C-$F73D
| Copy of "Plane A Y-position"
+
| Number of pixels scrolled by the camera vertically since the previous frame (multiplied by $100)
 
|-
 
|-
 
| $F73E-$F73F
 
| $F73E-$F73F
Line 265: Line 265:
 
|-
 
|-
 
| $F740-$F741
 
| $F740-$F741
| <font color=green>Unused</font>
+
| <font color=green>Unused (cleared by LevelSizeLoad)</font>
 
|-
 
|-
 
| $F742
 
| $F742
| Resize Level Routine Counter (Mainly Used For Act 3)
+
| Level's dynamic events routine ID
 
|-
 
|-
 
| $F743
 
| $F743
Line 274: Line 274:
 
|-
 
|-
 
| $F744
 
| $F744
| Scroll Hold Flag (set to disable all scrolling)
+
| Scroll disable flag
 +
|-
 +
| $F745
 +
| <font color=green>Unused</font>
 +
|-
 +
| $F746
 +
| <font color=green>Unused (cleared by LevelSizeLoad)</font>
 
|-
 
|-
| $F745-$F749
+
| $F747
 
| <font color=green>Unused</font>
 
| <font color=green>Unused</font>
 
|-
 
|-
| $F74A<br>$F74B<br>$F74C<br>$F74D<br>$F74E
+
| $F748
| <font color=red>Unknown</font> (Something to do with drawing the plane)
+
| <font color=green>Unused (cleared by LevelSizeLoad)</font>
 +
|-
 +
| $F749
 +
| <font color=green>Unused</font>
 +
|-
 +
| $F74A
 +
| Foreground horizontal plane redraw flag (used to indicate if the camera has passed a 16 pixel boundary)
 +
|-
 +
| $F74B
 +
| Foreground vertical plane redraw flag (used to indicate if the camera has passed a 16 pixel boundary)
 +
|-
 +
| $F74C
 +
| Primary background horizontal plane redraw flag (used to indicate if the camera has passed a 16 pixel boundary)
 +
|-
 +
| $F74D
 +
| Primary background vertical plane redraw flag (used to indicate if the camera has passed a 16 pixel boundary)
 +
|-
 +
| $F74E
 +
| Secondary background horizontal plane redraw flag (used to indicate if the camera has passed a 16 pixel boundary)
 
|-
 
|-
 
| $F74F
 
| $F74F
| <font color=green>Unused</font>
+
| <font color=green>Possibly the secondary background vertical plane redraw flag (used to indicate if the camera has passed a 16 pixel boundary), but is unused in both revisions.</font>
 
|-
 
|-
 
| $F750
 
| $F750
| Used for screen deformation in REV01, <font color=green>Unused in REV00</font>
+
| Tertiary background horizontal plane redraw flag (used to indicate if the camera has passed a 16 pixel boundary) (unused in REV00, used in REV01)
 
|-
 
|-
 
| $F751-$F753
 
| $F751-$F753
 
| <font color=green>Unused</font>
 
| <font color=green>Unused</font>
 
|-
 
|-
| $F754-$F755<br>$F756-$F757<br>$F758-$F759<br>$F75A-$F75B
+
| $F754
| Bitfields used by the scrolling engine
+
| Foreground plane redraw flags
 +
{| class="prettytable" style="width:auto;"
 +
!Bit||Hex||Description
 +
|-
 +
|0||$01||Draw a new row on the top of the screen
 +
|-
 +
|1||$02||Draw a new row on the bottom of the screen
 +
|-
 +
|2||$04||Draw a new column on the left side of the screen
 +
|-
 +
|3||$08||Draw a new column on the right side of the screen
 +
|}
 +
|-
 +
| $F756
 +
| Primary background plane redraw flags (format is the same as above)
 +
|-
 +
| $F758
 +
| Secondary background plane redraw flags (format is the same as above)
 +
|-
 +
| $F75A
 +
| Tertiary background plane redraw flags (unused in REV00, but is used in REV01) (format is the same as above)
 +
|-
 +
| $F755<br>$F757<br>$F759<br>$F75B
 +
| <font color=green>Unused</font>
 
|-
 
|-
 
| $F75C
 
| $F75C
| <font color=red>Unknown</font>
+
| Flag that is set if the level's lower boundary is moving.
 
|-
 
|-
 
| $F75D-$F75F
 
| $F75D-$F75F
Line 301: Line 348:
 
|-
 
|-
 
| $F760-$F761
 
| $F760-$F761
| Sonic's Top Speed
+
| Sonic's top speed
 
|-
 
|-
 
| $F762-$F763
 
| $F762-$F763
| Sonic's Acceleration
+
| Sonic's acceleration
 
|-
 
|-
 
| $F764-$F765
 
| $F764-$F765
| Sonic's Deceleration
+
| Sonic's deceleration
 
|-
 
|-
 
| $F766
 
| $F766
| Sonic's Dynamic PLC last frame number
+
| Sonic's previous DPLC frame ID
 
|-
 
|-
 
| $F767
 
| $F767
| Set to 1 if animation frame and $F766 was not same (In DPLC loading code)
+
| Flag that is set when Sonic's art needs to be reloaded in VRAM.
 +
|-
 +
| $F768
 +
| Angle value at Sonic's left sensor
 +
|-
 +
| $F769
 +
| <font color=green>Unused</font>
 +
|-
 +
| $F76A
 +
| Angle value at Sonic's right sensor
 
|-
 
|-
| $F768-$F76B
+
| $F76B
| Something to do with Sonic's angle
+
| <font color=green>Unused</font>
 
|-
 
|-
 
| $F76C
 
| $F76C
| Object position loader's routine counter
+
| Object manager's routine ID
 
|-
 
|-
 
| $F76D
 
| $F76D
Line 349: Line 405:
 
|-
 
|-
 
| $F794-$F795
 
| $F794-$F795
| Seems to be counter of some sort, for Ending sequence
+
| Palette fade out delay counter
 
|-
 
|-
 
| $F796-$F799
 
| $F796-$F799
Line 355: Line 411:
 
|-
 
|-
 
| $F79A-$F79B
 
| $F79A-$F79B
| Palette cycle counter for Special Stage
+
| Palette cycle counter for the special stages
 
|-
 
|-
 
| $F79C-$F79D
 
| $F79C-$F79D
| Palette cycle delay for Special Stage
+
| Palette cycle delay for the special stages
 
|-
 
|-
 
| $F79E-$F79F
 
| $F79E-$F79F
| <font color=red>Unknown purpose</font> (Something to do with special stage palette cycle)
+
| Palette cycle offset for the special stages
 
|-
 
|-
 
| $F7A0-$F7A1
 
| $F7A0-$F7A1
| Something to do with Special Stage BG deformation
+
| Special stage background scroll mode
 
|-
 
|-
 
| $F7A2-$F7A3
 
| $F7A2-$F7A3
Line 370: Line 426:
 
|-
 
|-
 
| $F7A4-$F7A5
 
| $F7A4-$F7A5
| Unknown (Something to do with Obj31)
+
| Stomping chained metal block Y position (used to align a pushing block on top of it)
 
|-
 
|-
 
| $F7A6
 
| $F7A6
Line 376: Line 432:
 
|-
 
|-
 
| $F7A7
 
| $F7A7
| <font color=red>Unknown</font>
+
| Boss fight flags (0 = before/during boss fight, 1 = boss defeated, 2 = prison capsule destroyed)
 
|-
 
|-
 
| $F7A8-$F7A9
 
| $F7A8-$F7A9
Line 382: Line 438:
 
|-
 
|-
 
| $F7AA
 
| $F7AA
| Screen Lock Flag (Set to lock screen)
+
| Flag to prevent Sonic from going past the right level boundary
 
|-
 
|-
 
| $F7AB
 
| $F7AB
Line 388: Line 444:
 
|-
 
|-
 
| $F7AC-$F7AF
 
| $F7AC-$F7AF
| Flags Used to Make Sonic Run Around Loops (GHZ+SLZ)
+
| Chunk IDs for loops and S tubes (first 2 are for loops, with the first ID being the loop with half of its collision enabled, and the second being the loop with the other half enabled, the last 2 are for S tube chunks) (Only used in GHZ and SLZ)
 
|-
 
|-
 
| $F7B0
 
| $F7B0
Line 412: Line 468:
 
|-
 
|-
 
| $F7B7-$F7BD
 
| $F7B7-$F7BD
| <font color=green>Unused</font>
+
| <font color=green>Unused, but could possibly have been used for animated art tile variables like above.</font>
 
|-
 
|-
 
| $F7BE-$F7BF
 
| $F7BE-$F7BF
Line 418: Line 474:
 
|-
 
|-
 
| $F7C0
 
| $F7C0
| <font color=red>Unknown</font>
+
| Conveyor belt direction (0 = normal, 1 = reversed)
 
|-
 
|-
| $F7C1-$F7C6 <font color=red>(?)</font>
+
| $F7C1-$F7C6
| Array used by LZ and SBZ conveyor belt platforms
+
| Array of flags used by LZ and SBZ conveyor belt platforms
 
|-
 
|-
 
| $F7C7
 
| $F7C7
| <font color=red>Unknown</font> (Something to do with LZ wind tunnels)
+
| Flag to prevent Sonic from using the normal walking animation in wind tunnels and to make air bubbles move horizontally in the wind tunnels
 
|-
 
|-
 
| $F7C8
 
| $F7C8
| Ignore Mode Flag (Ignoring all player control)
+
| Ignore mode flag (Ignoring all player control)
 
|-
 
|-
 
| $F7C9
 
| $F7C9
| LZ wind tunnel flag (clear = enabled)
+
| Flag to make Sonic move in the wind tunnels (0 = enabled)
 
|-
 
|-
 
| $F7CA
 
| $F7CA
Line 436: Line 492:
 
|-
 
|-
 
| $F7CB
 
| $F7CB
| <font color=red>Unknown</font> (Something to do with SBZ Stomper object)
+
| Flag to prevent multiple large moving platforms from SBZ3 from spawning at once
 
|-
 
|-
 
| $F7CC
 
| $F7CC
| Joypad Control Lock Flag
+
| Joypad control lock flag
 
|-
 
|-
 
| $F7CD
 
| $F7CD
| If sonic jumped to big ring flag
+
| Flag that is set when Sonic enters a big ring at the end of a level
 
|-
 
|-
 
| $F7CE
 
| $F7CE
Line 451: Line 507:
 
|-
 
|-
 
| $F7D0-$F7D1
 
| $F7D0-$F7D1
| Enemies destroyed while in air
+
| Number of enemies destroyed without touching the ground
 
|-
 
|-
 
| $F7D2-$F7D3
 
| $F7D2-$F7D3
| Time bonus
+
| End of level time bonus
 
|-
 
|-
 
| $F7D4-$F7D5
 
| $F7D4-$F7D5
| Ring bonus
+
| End of level ring bonus
 
|-
 
|-
 
| $F7D6
 
| $F7D6
| Ring bonus counter update request (updates ring bonus counter)
+
| Flag to update the bonus counters in the end level card
 
|-
 
|-
 
| $F7D7
 
| $F7D7
 +
| Ending sequence routine ID
 +
|-
 +
| $F7D8-$F7D9
 +
| Used for water deformation effects in LZ in REV01, <font color=green>Unused in REV00</font>
 +
|-
 +
| $F7DA-$F7DF
 
| <font color=green>Unused</font>
 
| <font color=green>Unused</font>
|-
 
| $F7D8-$F7DF
 
| Used for LZ deformation in REV01, <font color=green>Unused in REV00</font>
 
 
|-
 
|-
 
| $F7E0-$F7EF
 
| $F7E0-$F7EF
 
| Switch statuses
 
| Switch statuses
 
|-
 
|-
| $F7F0-$F7FF
+
| $F7F0-$F7F1<br>$F7F2-$F7F3<br>$F7F4-$F7F5<br>$F7F6-$F7F7
| <font color=red>Unknown array</font>
+
| Scroll section Y sizes
 +
|-
 +
| $F7F8-$F7FF
 +
| <font color=green>Unused</font>
 
|-
 
|-
 
| $F800-$FA7F
 
| $F800-$FA7F
| Sprite Table Buffer (sent to VRAM every frame via DMA)
+
| Sprite table buffer (sent to VRAM every frame via DMA)
 
|-
 
|-
 
| $FA00-$FA7F
 
| $FA00-$FA7F
Line 490: Line 552:
 
|-
 
|-
 
| $FC00-$FCFF
 
| $FC00-$FCFF
| Destroyable object state table
+
| Object respawn status table
 
|-
 
|-
 
| $FC44
 
| $FC44
| Error Message ID (If crash happens)
+
| Error message ID (If crash happens)
 
|-
 
|-
 
| $FD00-$FDFF
 
| $FD00-$FDFF
| System Stack
+
| System stack
 
|-
 
|-
 
| $FE00
 
| $FE00
Line 505: Line 567:
 
|-
 
|-
 
| $FE02-$FE03
 
| $FE02-$FE03
| Restart Level Flag
+
| Level reload flag
 
|-
 
|-
 
| $FE04-$FE05
 
| $FE04-$FE05
| Level Timer
+
| Internal level counter (number of frames passed since the level fades from black)
 
|-
 
|-
 
| $FE06
 
| $FE06
| Debug mode item pointer
+
| Debug mode item ID
 
|-
 
|-
 
| $FE07
 
| $FE07
Line 526: Line 588:
 
|-
 
|-
 
| $FE0C-$FE0F
 
| $FE0C-$FE0F
| VBlanks occurred since start of the game (unused)
+
| Vertical interrupt counter (increments after each V-INT)
 +
|-
 +
| $FE10
 +
| Zone ID
 
|-
 
|-
| $FE10-$FE11
+
| $FE11
| Zone-Act
+
| Act ID
 
|-
 
|-
 
| $FE12
 
| $FE12
| Lives
+
| Number of lives Sonic has
 
|-
 
|-
 
| $FE13
 
| $FE13
Line 538: Line 603:
 
|-
 
|-
 
| $FE14-$FE15
 
| $FE14-$FE15
| Remaining Air (When underwater)
+
| Air remaining (When underwater)
 
|-
 
|-
 
| $FE16
 
| $FE16
| Last Special Stage Entered
+
| Last special stage entered ID
 
|-
 
|-
 
| $FE17
 
| $FE17
Line 547: Line 612:
 
|-
 
|-
 
| $FE18
 
| $FE18
| Continues
+
| Number of continues
 
|-
 
|-
 
| $FE19
 
| $FE19
Line 553: Line 618:
 
|-
 
|-
 
| $FE1A
 
| $FE1A
| Time Over Flag
+
| Time over flag
 
|-
 
|-
 
| $FE1B
 
| $FE1B
Line 559: Line 624:
 
|-
 
|-
 
| $FE1C
 
| $FE1C
| Lives Counter (Set to update lives total on screen)
+
| Flag to update the life counter in the HUD
 
|-
 
|-
 
| $FE1D
 
| $FE1D
| Ring Counter (Set to update rings total on screen)
+
| Flag to update the ring counter in the HUD (if negative, reset the counter to 0, otherwise, just update it with the new ring amount)
 
|-
 
|-
 
| $FE1E
 
| $FE1E
| Time Counter (Set to update current time on screen)
+
| Flag to update the timer in the HUD
 
|-
 
|-
 
| $FE1F
 
| $FE1F
| Score Counter (Set to update score total on screen)
+
| Flag to update the score in the HUD
 
|-
 
|-
 
| $FE20-$FE21
 
| $FE20-$FE21
| Rings
+
| Number of rings collected
 
|-
 
|-
| $FE22-$FE25
+
| $FE22-$FE23
| Time
+
| Minutes counter for the level timer
 +
|-
 +
| $FE24
 +
| Seconds counter for the level timer
 +
|-
 +
| $FE25
 +
| Frame counter for the level timer
 
|-
 
|-
 
| $FE26-$FE29
 
| $FE26-$FE29
Line 583: Line 654:
 
|-
 
|-
 
| $FE2C
 
| $FE2C
| Shield Flag (Set to take a single hit without losing rings)
+
| Shield flag (Set to take a single hit without losing rings)
 
|-
 
|-
 
| $FE2D
 
| $FE2D
| Invincibility Flag (Set to make Sonic invincible)
+
| Invincibility flag (Set to make Sonic invincible)
 
|-
 
|-
 
| $FE2E
 
| $FE2E
| Speed Shoes Flag (Set to activate speed shoe physics)
+
| Speed shoes flag (Set to activate speed shoe physics)
 
|-
 
|-
 
| $FE2F
 
| $FE2F
| <font color=green>Unused</font> (cleared when level starts)
+
| <font color=green>Unused (cleared when level starts, possibly another power up flag, like the goggles)</font>
 
|-
 
|-
 
| $FE30-$FE54
 
| $FE30-$FE54
Line 598: Line 669:
 
* $FE30    -    Lamppost Counter
 
* $FE30    -    Lamppost Counter
 
* $FE31    -    Copy of Lamppost Counter
 
* $FE31    -    Copy of Lamppost Counter
* $FE32-$FE33 - Copy of Sonic's X Position
+
* $FE32-$FE33 - Copy of Sonic's X position
* $FE34-$FE35 - Copy of Sonic's Y Position
+
* $FE34-$FE35 - Copy of Sonic's Y position
 
* $FE36-$FE37 - Copy of Ring Counter
 
* $FE36-$FE37 - Copy of Ring Counter
 
* $FE38-$FE3B - Copy of Time Counter
 
* $FE38-$FE3B - Copy of Time Counter
Line 606: Line 677:
 
* $FE40-$FE41 - Copy of Plane A X-position
 
* $FE40-$FE41 - Copy of Plane A X-position
 
* $FE42-$FE43 - Copy of Plane A Y-position
 
* $FE42-$FE43 - Copy of Plane A Y-position
* $FE44-$FE4F - Copy of $F710-$F71D (Each other word)
+
* $FE44-$FE4F - Copy of every background sections' X and Y positions
* $FE50-$FE51 - Copy of Water Height
+
* $FE50-$FE51 - Copy of average water height
* $FE52    -    Copy of Water Routine Counter
+
* $FE52    -    Copy of water routine counter
* $FE53    -    Copy of Water Direction
+
* $FE53    -    Copy of water fullscreen flag
* $FE54    -    Copy of Lives Counter
+
* $FE54    -    Copy of extra lives flags
 
|-
 
|-
 
| $FE55-$FE56
 
| $FE55-$FE56
Line 616: Line 687:
 
|-
 
|-
 
| $FE57
 
| $FE57
| Emeralds
+
| Number of emeralds collected
 
|-
 
|-
 
| $FE58-$FE5D
 
| $FE58-$FE5D
 
| Array of collected emeralds
 
| Array of collected emeralds
 
|-
 
|-
| $FE5E-$FE9F <font color=red>(?)</font>
+
| $FE5E-$FE9F
| <font color=red>Unknown array</font> (Something to do with platforms)
+
| Oscillation values
 
|-
 
|-
 
| $FEA0-$FEBF
 
| $FEA0-$FEBF
 
| <font color=green>Unused</font>
 
| <font color=green>Unused</font>
 
|-
 
|-
| $FEC0-$FEC9
+
| $FEC0
| Ring animation flags
+
| Rotating spikes in GHZ animation timer
 +
|-
 +
| $FEC1
 +
| Rotating spikes in GHZ animation frame
 +
|-
 +
| $FEC2
 +
| Ring animation timer
 +
|-
 +
| $FEC3
 +
| Ring animation frame
 +
|-
 +
| $FEC4
 +
| Animation timer <font color=green>(Unused)</font>
 +
|-
 +
| $FEC5
 +
| Animation frame <font color=green>(Unused)</font>
 +
|-
 +
| $FEC6
 +
| Ring loss timer
 
|-
 
|-
| $FECA-$FEEF
+
| $FEC7
 +
| Lost ring animation frame
 +
|-
 +
| $FEC8
 +
| Lost ring animation accumulator
 +
|-
 +
| $FEC9-$FEEF
 
| <font color=green>Unused</font>
 
| <font color=green>Unused</font>
 
|-
 
|-
 
| $FEF0-$FEF3
 
| $FEF0-$FEF3
 
| Debug mode variables
 
| Debug mode variables
* $FEF0-$FEF1 - Copy of levels upper boundary
+
* $FEF0-$FEF1 - Copy of level's upper boundary
* $FEF2-$FEF3 - Copy of levels bottom boundary
+
* $FEF2-$FEF3 - Copy of level's bottom boundary
 +
|-
 +
| $FEF4-$FEFF
 +
| <font color=green>Unused</font>
 
|-
 
|-
| $FEF4-$FF0F
+
| $FF00-$FF01
 +
| Used by the collision code to determine collision response for chunk $00. <font color=green>While this is technically unused</font>, editing this is not a good idea.
 +
|-
 +
| $FF02-$FF0F
 
| <font color=green>Unused</font>
 
| <font color=green>Unused</font>
 
|-
 
|-
Line 648: Line 749:
 
|-
 
|-
 
| $FF80-$FF81
 
| $FF80-$FF81
| Timer for level select selection moving
+
| Timer for level select selection movement
 
|-
 
|-
 
| $FF82-$FF83
 
| $FF82-$FF83
Line 666: Line 767:
 
|-
 
|-
 
| $FFE0
 
| $FFE0
| Level select cheat
+
| Level select enabled flag
 
|-
 
|-
 
| $FFE1
 
| $FFE1
| If is set, enables slow motion cheat
+
| Slow motion enabled flag
 
|-
 
|-
 
| $FFE2
 
| $FFE2
| Debug cheat flag
+
| Debug mode enabled flag
 
|-
 
|-
 
| $FFE3
 
| $FFE3
| Japanese credits cheat
+
| Japanese credits enabled flag
 
|-
 
|-
 
| $FFE4-$FFE5
 
| $FFE4-$FFE5
Line 690: Line 791:
 
|-
 
|-
 
| $FFEC-$FFEF
 
| $FFEC-$FFEF
| <font color=green>Unused</font> (Are overwritten by Sonic_Floor routine, but don't seem to have any use)
+
| <font color=green>Unused</font> (Possibly used for debugging the collision engine while in development)
 
|-
 
|-
 
| $FFF0-$FFF1
 
| $FFF0-$FFF1
| Demo mode flag
+
| Demo mode flag (level demo if positive, credits demo if negative)
 
|-
 
|-
 
| $FFF2-$FFF3
 
| $FFF2-$FFF3
| Demo number
+
| Demo ID
 
|-
 
|-
 
| $FFF4-$FFF5
 
| $FFF4-$FFF5
| Credits Index Number
+
| Credits index ID
 
|-
 
|-
 
| $FFF6-$FFF7
 
| $FFF6-$FFF7
Line 705: Line 806:
 
|-
 
|-
 
| $FFF8
 
| $FFF8
| Version register (Bits 6 and 7 of lower byte)
+
| Hardware version register (Bits 6 and 7 of lower byte)
 
|-
 
|-
 
| $FFF9
 
| $FFF9
Line 711: Line 812:
 
|-
 
|-
 
| $FFFA-$FFFB
 
| $FFFA-$FFFB
| Debug Flag (Set to enable debug mode)
+
| Debug mode flag
 
|-
 
|-
 
| $FFFC-$FFFF
 
| $FFFC-$FFFF
| Checksum flag
+
| Checksum passed flag
  
 
|}
 
|}
  
== Object Status Table Format ==
+
==Object Status Table format==
 
The Object Status Table is located at RAM address $D000. Each entry is $40 bytes long. Here is a list of all the values for one entry in the OST:
 
The Object Status Table is located at RAM address $D000. Each entry is $40 bytes long. Here is a list of all the values for one entry in the OST:
  
{|class="prettytable"
+
{| class="prettytable" style="width:auto;"
 
!Offset||Size||Description
 
!Offset||Size||Description
 
|-
 
|-
Line 727: Line 828:
 
|-
 
|-
 
| $01 || byte|| Render flags. The bitfield looks like this:
 
| $01 || byte|| Render flags. The bitfield looks like this:
{|class="prettytable"
+
{| class="prettytable" style="width:auto;"
 
!Bit||Hex||Description
 
!Bit||Hex||Description
 
|-
 
|-
Line 734: Line 835:
 
|1||$02||This is the vertical mirror flag.
 
|1||$02||This is the vertical mirror flag.
 
|-
 
|-
|2/3||$04/$08||These are the coordinate system. If 0, the object will be positioned by absolute screen coordinates. This is used for things like the HUD and menu options. If 1, the object will be positioned by the playfield coordinates, i.e. where it is in a level. If 2 or 3, the object will be aligned to the background somehow (perhaps this was used for those MZ UFOs).
+
|2/3||$04/$08||These are the coordinate system. If 0, the object will be positioned by absolute screen coordinates. This is used for things like the HUD and menu options. If 1, the object will be positioned by the playfield coordinates, i.e. where it is in a level. If 2 or 3, the object will be aligned to the background somehow.
 
|-
 
|-
 
|4||$10||This is the assume height flag. The object will be drawn if it is vertically within ''x'' pixels of the screen where ''x'' is #$20 if this flag is clear or $16(a0) if it is set.
 
|4||$10||This is the assume height flag. The object will be drawn if it is vertically within ''x'' pixels of the screen where ''x'' is #$20 if this flag is clear or $16(a0) if it is set.
 
|-
 
|-
|5||$20||This is the raw mappings flag. If set, just 5 bytes will be read from the object's mappings offset when the BuildSprites routine draws the object, and these will be interpreted in the normal manner to display a single Genesis sprite. This format is used for objects such as breakable wall fragments.
+
|5||$20||This is the raw mappings flag. If set, just 5 bytes will be read from the object's mappings offset when the BuildSprites routine draws the object, and these will be interpreted in the normal manner to display a single Mega Drive sprite. This format is used for objects such as breakable wall fragments.
 
|-
 
|-
|6||$40||This is Sonic's "Ride B" flag
+
|6||$40||Set if Sonic is behind a loop, clear if above. This is used to change loop collision, based on the chunk Sonic is standing in. <font color=green>(Unused for any other object.)</font>
 
|-
 
|-
 
|7||$80||This is the on-screen flag. It will be set if the object is on-screen, and clear otherwise.
 
|7||$80||This is the on-screen flag. It will be set if the object is on-screen, and clear otherwise.
Line 746: Line 847:
 
|-
 
|-
 
| $02 || word || Art tile
 
| $02 || word || Art tile
{|class="prettytable"
+
{| class="prettytable" style="width:auto;"
 
!Bit||Hex||Description
 
!Bit||Hex||Description
 
|-
 
|-
|0-11||$01-$800||Tile number in VRAM. To get the actual address in VRAM, multiply this number by $20 (32 decimal).
+
|0-10||$01-$400||Tile number in VRAM. To get the actual address in VRAM, multiply this number by $20 (32 decimal).
 +
|-
 +
|11||$800||If clear, sprites will be drawn normally. If set, sprites will be flipped horizontally.
 
|-
 
|-
 
|12||$1000||If clear, sprites will be drawn normally. If set, sprites will be flipped vertically.
 
|12||$1000||If clear, sprites will be drawn normally. If set, sprites will be flipped vertically.
 
|-
 
|-
|13/14||$2000/$4000||Default palette line the sprite uses.
+
|13/14||$2000/$4000||Palette line used by the object. (Note that object mappings may alter this.)
 
|-
 
|-
 
|15||$8000||If clear, sprite will be drawn on low plane. If set, sprite will be drawn on high plane.
 
|15||$8000||If clear, sprite will be drawn on low plane. If set, sprite will be drawn on high plane.
Line 806: Line 909:
 
|$22 || byte ||Status bitfield.
 
|$22 || byte ||Status bitfield.
 
Counting from the least significant bit:
 
Counting from the least significant bit:
{|class="prettytable"
+
{| class="prettytable" style="width:auto;"
 
!Bit||Hex||Description
 
!Bit||Hex||Description
 
|-
 
|-
|0||$01||X Orientation. Clear is left and set is right.
+
|0||$01||X Orientation. Clear is right and set is left.
 
|-
 
|-
 
|1||$02||Y Orientation. Clear is right-side up, and set is upside-down
 
|1||$02||Y Orientation. Clear is right-side up, and set is upside-down
 
|-
 
|-
|2||$04||<font color=red>Unknown or unused</font>
+
|2||$04||<font color=green>Unused</font>
 
|-
 
|-
 
|3||$08||Set if Sonic is standing on this object.
 
|3||$08||Set if Sonic is standing on this object.
 
|-
 
|-
|4||$10||<font color=red>Unknown or unused</font>
+
|4||$10||<font color=green>Unused</font>
 
|-
 
|-
 
|5||$20||Set if Sonic is pushing on this object.
 
|5||$20||Set if Sonic is pushing on this object.
 
|-
 
|-
|6||$40||<font color=red>Unknown or unused</font>
+
|6||$40||<font color=green>Unused</font>
 
|-
 
|-
|7||$80||<font color=red>Unknown or unused</font>
+
|7||$80||Object specific flag
 
|} Note that these bits have different meanings for Sonic (see below).
 
|} Note that these bits have different meanings for Sonic (see below).
 
|-
 
|-
Line 843: Line 946:
 
|-
 
|-
 
|$22 || byte ||Special bitfield. Counting from the least significant bit:
 
|$22 || byte ||Special bitfield. Counting from the least significant bit:
{|class="prettytable"
+
{| class="prettytable" style="width:auto;"
 
!Bit||Hex||Description
 
!Bit||Hex||Description
 
|-
 
|-
|0||$01||Orientation. Clear is left and set is right.
+
|0||$01||Orientation. Set is left and clear is right.
 
|-
 
|-
|1||$02||Set if Sonic is in the air (jump counts).
+
|1||$02||Set if Sonic is in the air
 
|-
 
|-
 
|2||$04||Set if jumping or rolling.
 
|2||$04||Set if jumping or rolling.
Line 854: Line 957:
 
|3||$08||Set if Sonic isn't on the ground but shouldn't fall. (Usually when he is on a object that should stop him falling, like a platform or a bridge.)
 
|3||$08||Set if Sonic isn't on the ground but shouldn't fall. (Usually when he is on a object that should stop him falling, like a platform or a bridge.)
 
|-
 
|-
|4||$10||Set if jumping after rolling.
+
|4||$10||Set if Sonic is jumping after rolling on the ground. (Used mainly to lock horizontal controls.)
 
|-
 
|-
 
|5||$20||Set if pushing something.
 
|5||$20||Set if pushing something.
Line 860: Line 963:
 
|6||$40||Set if underwater.
 
|6||$40||Set if underwater.
 
|-
 
|-
|7||$80||Unused.
+
|7||$80||<font color=green>Unused</font>
 
|}
 
|}
 
You can add the hex values together to use multiple settings at once. Also notice that the first 3 bits (0-2) are used in the character object as a second routine counter.
 
You can add the hex values together to use multiple settings at once. Also notice that the first 3 bits (0-2) are used in the character object as a second routine counter.
Line 880: Line 983:
 
|-
 
|-
 
|$37 || byte ||Angle of ground at Sonic's rear collision hot spot
 
|$37 || byte ||Angle of ground at Sonic's rear collision hot spot
 +
|-
 +
|$38 || byte ||Is set to make Sonic stick to the SBZ wheel
 
|-
 
|-
 
|$39 || byte ||Unused.
 
|$39 || byte ||Unused.
Line 904: Line 1,009:
 
| $3E || byte || Number of times to flash when hit
 
| $3E || byte || Number of times to flash when hit
 
|}
 
|}
 +
==References==
 +
<references />
 +
 
{{SCHGuides}}
 
{{SCHGuides}}
[[Category:Sonic Community Hacking Guide]]
 

Latest revision as of 22:29, 15 July 2021

SCHG: Sonic the Hedgehog

Main System Memory locations

This is a map of 68k memory as used by the main gameplay engine. Note that any numbers entered (for example, score or number of rings) will have to be converted to hex first.

These are the offsets in RAM. To convert them to Genecyst savestate offsets, add $2478. For use in disassemblies, simply add $FF0000 for addresses below $8000 and $FFFF0000 for addresses above or equal to $8000, for example, Sonic's top speed here is $F760, but in the disassembly it is referenced as $FFFFF760. This is useful for finding what bits of code do what when the purpose of a RAM variable is known, or conversely for figuring out the purpose of a RAM variable by looking at the referencing code.

RAM offset Description
$0000 - $A3FF Chunk mappings
$A400 - $A7FF Level layout (1 byte per chunk, $80 bytes per line, 8 lines for planes A and B interlaced)
$A800 - $A9FF 16 pixel scroll buffer primarily used for SLZ (4 bytes = one 16 pixel'd block scroll for FG and BG), this data is transfered/converter correctly to $CC00 - $CFFF (Scroll RAM cache).
$AA00 - $ABFF Nemesis decompression buffer
$AC00 - $AFFF Sprite table input. Consists of 8 different priority levels, each level taking up $80 bytes. The first word of each level is the number of objects currently in that priority level multiplied by 2, and the next $3F words are the addresses in RAM (inside the object RAM space) of the objects on that priority level. The information in this table is processed by BuildSprites to create the actual sprite table
$B000 - $C7FF Block mappings
$C800 - $CAFF Sonic's art buffer. Sonic's dynamic pattern reloading routine copies the relevant art over here, from where it is DMA'd to VRAM every V-int.
$CB00 - $CBFF Sonic previous position array (used for invincibility stars and such)
$CC00 - $CF7F H-Scroll buffer (sent to VRAM every frame via DMA)
$CF80 - $CFFF Unused (However, this space is used for the H-Scroll buffer to overflow to, so using this is not recommended)
$D000 - $D7FF Reserved object SST space (Various important objects, such as Sonic, shields, invincibility stars, and title cards, are loaded here.)
$D800 - $EFFF Dynamic SST space (Level objects are loaded here.)
$F000 - $F5BF Flags used by the sound engine
$F5C0 - $F5FF Unused
$F600 Screen Mode
  • $00 - Sega Screen
  • $04 - Title Screen
  • $08 - Demo Mode
  • $0C - Normal Level
  • $10 - Special Stage
  • $14 - Continue Screen
  • $18 - Ending Sequence
  • $1C - Credits
$F601 Unused
$F602 Player's held buttons used in Sonic's moves, etc.
$F603 Player's pressed buttons used in Sonic's moves, etc.
$F604 Player 1's held buttons
$F605 Player 1's pressed buttons
$F606 Player 2's held buttons (unused, exists because it's from a standard Mega Drive function)
$F607 Player 2's pressed buttons (unused, exists because it's from a standard Mega Drive function)
$F608-$F60B Unused
$F60C-$F60D VDP command for mode register 2
$F60E-$F613 Unused
$F614-$F615 General countdown timer
$F616-$F617 Plane A y-position for VSRAM
$F618-$F619 Plane B y-position for VSRAM
$F61A-$F61B Plane A x-position for HScroll (unused)
$F61C-$F61D Plane B x-position for HScroll (unused)
$F61E-$F61F Copy of $F71C
$F620-$F621 Copy of $F718
$F622-$F623 Unused
$F624-$F625 VDP register $A (H-INT counter) cache (used for water height on screen)
$F626-$F627 Variables used in palette fade routines
$F628 Counter that increments if the V-INT routine is $E, which is unused
$F629 Unused
$F62A V-INT routine ID
$F62B Unused
$F62C Number of sprites on screen
$F62D-$F631 Unused
$F632-$F633 Palette cycle offset counter
$F634-$F635 Palette cycle wait timer
$F636-$F639 Random number generator seed & result
$F63A-$F63B Game paused state
$F63C-$F63F Unused
$F640-$F641 Used to hold the low word of a DMA transfer command, which is then sent to the VDP control port, to get around a hardware bug.
$F642-$F643 Unused
$F644-$F645 Set when water palette should be transferred next HBlank
$F646-$F647 Water height
$F648-$F649 Average water height
$F64A-$F64B Target water height
$F64C Water movement direction
$F64D Dynamic water routine counter
$F64E Flag that is set when water takes up the entire screen
$F64F Is set when sound driver should be ran on HBlank (not enough time before it)
$F650-$F661 SBZ palette cycling buffer (consists of 9 entries with 2 byte sized variables, first being the palette cycle timer, and the second being the palette cycle data index)
$F662-$F663 Unused, but is cleared upon loading the SEGA screen
$F664-$F67F Unused
$F680-$F6DF Pattern load queue. 16 entries with each being 6 bytes in size, consisting of a longword sized variable and a word sized variable. The first variable is a pointer to Nemesis compressed art. The second variable is the destination VRAM address. Once the queue is empty, the first entry's pointer variable is 0.
$F6E0-$F6FF Pattern load queue Nemesis decompression variables
$F700-$F703 Plane A x-position (16.16 fixed point number)
$F704-$F707 Plane A y-position (16.16 fixed point number)
$F708-$F70B Primary plane B x-position (16.16 fixed point number)
$F70C-$F70F Primary plane B y-position (16.16 fixed point number)
$F710-$F713 Secondary plane B x-position (16.16 fixed point number)
$F714-$F717 Secondary plane B y-position (16.16 fixed point number)
$F718-$F71B Tertiary plane B x-position (16.16 fixed point number). In REV00, it's only used to scroll the background in special stages, but it ends up having use in normal levels in REV01.
$F71C-$F71F Tertiary plane B y-position (16.16 fixed point number). Unused in REV00, but it used in REV01.
$F720-$F721 Level's target left boundary (Unused)
$F722-$F723 Level's target right boundary (Unused)
$F724-$F725 Level's target upper boundary (Unused)
$F726-$F727 Level's target lower boundary
$F728-$F729 Level's left boundary
$F72A-$F72B Level's right Boundary
$F72C-$F72D Level's upper boundary
$F72E-$F72F Level's lower boundary
$F730-$F731 Written to by LevelSizeLoad, but unused otherwise
$F732-$F733 Upper level boundary +$240, but unused otherwise
$F734-$F739 Unused
$F73A-$F73B Number of pixels scrolled by the camera horizontally since the previous frame (multiplied by $100)
$F73C-$F73D Number of pixels scrolled by the camera vertically since the previous frame (multiplied by $100)
$F73E-$F73F Y-camera position, based on Sonic ($60 = default)
$F740-$F741 Unused (cleared by LevelSizeLoad)
$F742 Level's dynamic events routine ID
$F743 Unused
$F744 Scroll disable flag
$F745 Unused
$F746 Unused (cleared by LevelSizeLoad)
$F747 Unused
$F748 Unused (cleared by LevelSizeLoad)
$F749 Unused
$F74A Foreground horizontal plane redraw flag (used to indicate if the camera has passed a 16 pixel boundary)
$F74B Foreground vertical plane redraw flag (used to indicate if the camera has passed a 16 pixel boundary)
$F74C Primary background horizontal plane redraw flag (used to indicate if the camera has passed a 16 pixel boundary)
$F74D Primary background vertical plane redraw flag (used to indicate if the camera has passed a 16 pixel boundary)
$F74E Secondary background horizontal plane redraw flag (used to indicate if the camera has passed a 16 pixel boundary)
$F74F Possibly the secondary background vertical plane redraw flag (used to indicate if the camera has passed a 16 pixel boundary), but is unused in both revisions.
$F750 Tertiary background horizontal plane redraw flag (used to indicate if the camera has passed a 16 pixel boundary) (unused in REV00, used in REV01)
$F751-$F753 Unused
$F754 Foreground plane redraw flags
Bit Hex Description
0 $01 Draw a new row on the top of the screen
1 $02 Draw a new row on the bottom of the screen
2 $04 Draw a new column on the left side of the screen
3 $08 Draw a new column on the right side of the screen
$F756 Primary background plane redraw flags (format is the same as above)
$F758 Secondary background plane redraw flags (format is the same as above)
$F75A Tertiary background plane redraw flags (unused in REV00, but is used in REV01) (format is the same as above)
$F755
$F757
$F759
$F75B
Unused
$F75C Flag that is set if the level's lower boundary is moving.
$F75D-$F75F Unused
$F760-$F761 Sonic's top speed
$F762-$F763 Sonic's acceleration
$F764-$F765 Sonic's deceleration
$F766 Sonic's previous DPLC frame ID
$F767 Flag that is set when Sonic's art needs to be reloaded in VRAM.
$F768 Angle value at Sonic's left sensor
$F769 Unused
$F76A Angle value at Sonic's right sensor
$F76B Unused
$F76C Object manager's routine ID
$F76D Unused
$F76E-$F76F Copy of $F700 used by object position loader
$F770-$F77F Flags used by object position loader
$F780-$F781 Special stage's angle
$F782-$F783 Special stage's rotation speed
$F784-$F78F Unused
$F790-$F791 Demo's button press counter (Addition to proper address)
$F792 Seems to be duration to increment button press counter
$F793 Unused
$F794-$F795 Palette fade out delay counter
$F796-$F799 Direct address of collision pointer of the level
$F79A-$F79B Palette cycle counter for the special stages
$F79C-$F79D Palette cycle delay for the special stages
$F79E-$F79F Palette cycle offset for the special stages
$F7A0-$F7A1 Special stage background scroll mode
$F7A2-$F7A3 Unused
$F7A4-$F7A5 Stomping chained metal block Y position (used to align a pushing block on top of it)
$F7A6 Unused
$F7A7 Boss fight flags (0 = before/during boss fight, 1 = boss defeated, 2 = prison capsule destroyed)
$F7A8-$F7A9 Sonic's recorded position array's counter
$F7AA Flag to prevent Sonic from going past the right level boundary
$F7AB Unused
$F7AC-$F7AF Chunk IDs for loops and S tubes (first 2 are for loops, with the first ID being the loop with half of its collision enabled, and the second being the loop with the other half enabled, the last 2 are for S tube chunks) (Only used in GHZ and SLZ)
$F7B0 Animated art tile offset counter
$F7B1 Animated art timer
$F7B2 Animated art tile offset counter
$F7B3 Animated art timer
$F7B4 Animated art tile offset counter
$F7B5 Animated art timer
$F7B6 Animated art tile offset counter
$F7B7-$F7BD Unused, but could possibly have been used for animated art tile variables like above.
$F7BE-$F7BF Big ring art offset counter
$F7C0 Conveyor belt direction (0 = normal, 1 = reversed)
$F7C1-$F7C6 Array of flags used by LZ and SBZ conveyor belt platforms
$F7C7 Flag to prevent Sonic from using the normal walking animation in wind tunnels and to make air bubbles move horizontally in the wind tunnels
$F7C8 Ignore mode flag (Ignoring all player control)
$F7C9 Flag to make Sonic move in the wind tunnels (0 = enabled)
$F7CA Lock controls (Except jumping)
$F7CB Flag to prevent multiple large moving platforms from SBZ3 from spawning at once
$F7CC Joypad control lock flag
$F7CD Flag that is set when Sonic enters a big ring at the end of a level
$F7CE Used by Obj56 (SYZ/SLZ floating block) in REV01, Unused in REV00
$F7CF Unused
$F7D0-$F7D1 Number of enemies destroyed without touching the ground
$F7D2-$F7D3 End of level time bonus
$F7D4-$F7D5 End of level ring bonus
$F7D6 Flag to update the bonus counters in the end level card
$F7D7 Ending sequence routine ID
$F7D8-$F7D9 Used for water deformation effects in LZ in REV01, Unused in REV00
$F7DA-$F7DF Unused
$F7E0-$F7EF Switch statuses
$F7F0-$F7F1
$F7F2-$F7F3
$F7F4-$F7F5
$F7F6-$F7F7
Scroll section Y sizes
$F7F8-$F7FF Unused
$F800-$FA7F Sprite table buffer (sent to VRAM every frame via DMA)
$FA00-$FA7F Target underwater palette (is overwritten by the "BuildSprites" routine after being processed)
$FA80-$FAFF Normal underwater palette
$FB00-$FB7F Normal palette
$FB80-$FBFF Target palette (calling Pal_FadeTo will change the normal palette until it is the same as the target palette)
$FC00-$FCFF Object respawn status table
$FC44 Error message ID (If crash happens)
$FD00-$FDFF System stack
$FE00 Stack pointer
$FE00-$FE01 Unused
$FE02-$FE03 Level reload flag
$FE04-$FE05 Internal level counter (number of frames passed since the level fades from black)
$FE06 Debug mode item ID
$FE07 Unused
$FE08-$FE09 Object placement flag (Set if debug mode is being used)
$FE0A Debug mode speed timer
$FE0B Debug mode moving speed
$FE0C-$FE0F Vertical interrupt counter (increments after each V-INT)
$FE10 Zone ID
$FE11 Act ID
$FE12 Number of lives Sonic has
$FE13 Unused
$FE14-$FE15 Air remaining (When underwater)
$FE16 Last special stage entered ID
$FE17 Unused
$FE18 Number of continues
$FE19 Unused
$FE1A Time over flag
$FE1B Extra life flags (bits 1 and 2 are set if you have received the extra life at 100 and 200 rings)
$FE1C Flag to update the life counter in the HUD
$FE1D Flag to update the ring counter in the HUD (if negative, reset the counter to 0, otherwise, just update it with the new ring amount)
$FE1E Flag to update the timer in the HUD
$FE1F Flag to update the score in the HUD
$FE20-$FE21 Number of rings collected
$FE22-$FE23 Minutes counter for the level timer
$FE24 Seconds counter for the level timer
$FE25 Frame counter for the level timer
$FE26-$FE29 Score
$FE2A-$FE2B Unused
$FE2C Shield flag (Set to take a single hit without losing rings)
$FE2D Invincibility flag (Set to make Sonic invincible)
$FE2E Speed shoes flag (Set to activate speed shoe physics)
$FE2F Unused (cleared when level starts, possibly another power up flag, like the goggles)
$FE30-$FE54 Lamppost Variables
  • $FE30 - Lamppost Counter
  • $FE31 - Copy of Lamppost Counter
  • $FE32-$FE33 - Copy of Sonic's X position
  • $FE34-$FE35 - Copy of Sonic's Y position
  • $FE36-$FE37 - Copy of Ring Counter
  • $FE38-$FE3B - Copy of Time Counter
  • $FE3C-$FE3D - Copy of Resize Level Routine Counter
  • $FE3E-$FE3F - Copy of Levels lower boundary
  • $FE40-$FE41 - Copy of Plane A X-position
  • $FE42-$FE43 - Copy of Plane A Y-position
  • $FE44-$FE4F - Copy of every background sections' X and Y positions
  • $FE50-$FE51 - Copy of average water height
  • $FE52 - Copy of water routine counter
  • $FE53 - Copy of water fullscreen flag
  • $FE54 - Copy of extra lives flags
$FE55-$FE56 Unused
$FE57 Number of emeralds collected
$FE58-$FE5D Array of collected emeralds
$FE5E-$FE9F Oscillation values
$FEA0-$FEBF Unused
$FEC0 Rotating spikes in GHZ animation timer
$FEC1 Rotating spikes in GHZ animation frame
$FEC2 Ring animation timer
$FEC3 Ring animation frame
$FEC4 Animation timer (Unused)
$FEC5 Animation frame (Unused)
$FEC6 Ring loss timer
$FEC7 Lost ring animation frame
$FEC8 Lost ring animation accumulator
$FEC9-$FEEF Unused
$FEF0-$FEF3 Debug mode variables
  • $FEF0-$FEF1 - Copy of level's upper boundary
  • $FEF2-$FEF3 - Copy of level's bottom boundary
$FEF4-$FEFF Unused
$FF00-$FF01 Used by the collision code to determine collision response for chunk $00. While this is technically unused, editing this is not a good idea.
$FF02-$FF0F Unused
$FF10-$FF37 Copy of $F700-$F72F and $F754-$F75B, used in "LoadTilesAsYouMove" routine
$FF38-$FF7F Unused
$FF80-$FF81 Timer for level select selection movement
$FF82-$FF83 Level select selection number
$FF84-$FF85 Level select sound ID
$FF86-$FFBF Unused
$FFC0-$FFC3 Copy of current score (Unused)
$FFC4-$FFDF Unused
$FFE0 Level select enabled flag
$FFE1 Slow motion enabled flag
$FFE2 Debug mode enabled flag
$FFE3 Japanese credits enabled flag
$FFE4-$FFE5 Correct button press counter for level select cheat
$FFE6-$FFE7 C button press counter (Title Screen only)
$FFE8-$FFE9 Unused
$FFEA-$FFEB Unused (However is cleared on the Title Screen)
$FFEC-$FFEF Unused (Possibly used for debugging the collision engine while in development)
$FFF0-$FFF1 Demo mode flag (level demo if positive, credits demo if negative)
$FFF2-$FFF3 Demo ID
$FFF4-$FFF5 Credits index ID
$FFF6-$FFF7 Unused
$FFF8 Hardware version register (Bits 6 and 7 of lower byte)
$FFF9 Unused
$FFFA-$FFFB Debug mode flag
$FFFC-$FFFF Checksum passed flag

Object Status Table format

The Object Status Table is located at RAM address $D000. Each entry is $40 bytes long. Here is a list of all the values for one entry in the OST:

Offset Size Description
$00 byte Object type
$01 byte Render flags. The bitfield looks like this:
Bit Hex Description
0 $01 This is the horizontal mirror flag. If set, the object will be flipped on its horizontal axis.
1 $02 This is the vertical mirror flag.
2/3 $04/$08 These are the coordinate system. If 0, the object will be positioned by absolute screen coordinates. This is used for things like the HUD and menu options. If 1, the object will be positioned by the playfield coordinates, i.e. where it is in a level. If 2 or 3, the object will be aligned to the background somehow.
4 $10 This is the assume height flag. The object will be drawn if it is vertically within x pixels of the screen where x is #$20 if this flag is clear or $16(a0) if it is set.
5 $20 This is the raw mappings flag. If set, just 5 bytes will be read from the object's mappings offset when the BuildSprites routine draws the object, and these will be interpreted in the normal manner to display a single Mega Drive sprite. This format is used for objects such as breakable wall fragments.
6 $40 Set if Sonic is behind a loop, clear if above. This is used to change loop collision, based on the chunk Sonic is standing in. (Unused for any other object.)
7 $80 This is the on-screen flag. It will be set if the object is on-screen, and clear otherwise.
$02 word Art tile
Bit Hex Description
0-10 $01-$400 Tile number in VRAM. To get the actual address in VRAM, multiply this number by $20 (32 decimal).
11 $800 If clear, sprites will be drawn normally. If set, sprites will be flipped horizontally.
12 $1000 If clear, sprites will be drawn normally. If set, sprites will be flipped vertically.
13/14 $2000/$4000 Palette line used by the object. (Note that object mappings may alter this.)
15 $8000 If clear, sprite will be drawn on low plane. If set, sprite will be drawn on high plane.
$04 long Mappings offset
$08 word
  • If in playfield positioning mode, it is the X playfield coordinate.
  • If in screen positioning mode, it is the X screen coordinate.
$0A word
  • If the object is in playfield positioning mode, this is the X subpixel coordinate.
  • If in screen positioning mode, it's the Y screen coordinate.
$0C word
  • If in playfield positioning mode, it is the Y playfield coordinate.
  • If in screen positioning mode, it is unused.
$0E word
  • If the object is in playfield positioning mode, this is the Y subpixel coordinate.
  • If in screen positioning mode, it is unused.
$10 word Horizontal (X) velocity
$12 word Vertical (Y) velocity
$14 word Ground velocity (inertia).
$16 byte Vertical radius of the object's hitbox.
$17 byte Horizontal radius of the object's hitbox.
$18 byte Sprite priority ($00 to $07, lower value has bigger priority).
$19 byte Horizontal radius of the object's visible sprite.
$1A byte Current animation frame to display. i.e, the frame currently being displayed on-screen, according to the animation script (currently parsed mappings frame, in other words).
$1B byte Current frame in animation script. i.e, the frame entry IN the animation script being currently processed.
$1C byte Animation number. When an animation ID is moved here, it's processed and displayed.
$1D byte Restart animation flag (when $1D is not equal to $1C, animation restarts)
$1E byte Animation frame duration (time until next frame).
$20 byte Collision response bitfield. Tells what the object will do if hit by the character. The bitfield is in the format TTSS SSSS. TT is the type of collision - 00 is enemy, 01 increments the routine counter, 10 is harm, and 11 is "special", used for the starpole, caterkiller, yadrin and some other objects. SSSSSS is the size, lifted from a lookup table in the collision response routine.
$21 byte Custom collision property, for special interaction with Sonic. This is used by bosses, badniks, bumpers and other objects. The way in which this byte is used is different for each object. Bosses use this byte as a hit counter.
$22 byte Status bitfield.

Counting from the least significant bit:

Bit Hex Description
0 $01 X Orientation. Clear is right and set is left.
1 $02 Y Orientation. Clear is right-side up, and set is upside-down
2 $04 Unused
3 $08 Set if Sonic is standing on this object.
4 $10 Unused
5 $20 Set if Sonic is pushing on this object.
6 $40 Unused
7 $80 Object specific flag
Note that these bits have different meanings for Sonic (see below).
$23 byte Respawn index reference number, used by badniks, rings and monitors. Each destroyable object is assigned an index number (01, 02, 03 etc.) which refers to a list at $FC00 in the RAM.
$24 byte Routine counter.
$25 byte Second routine counter. This is used for some of the more complicated objects.
$26 word Angle.
$28 byte Object subtype. For example, the current monitor selected. See the Object List above for values. Has a different meaning for Sonic.
$29-$3F Object's scratch RAM
Sonic-specific variables
Offset Size Description
$22 byte Special bitfield. Counting from the least significant bit:
Bit Hex Description
0 $01 Orientation. Set is left and clear is right.
1 $02 Set if Sonic is in the air
2 $04 Set if jumping or rolling.
3 $08 Set if Sonic isn't on the ground but shouldn't fall. (Usually when he is on a object that should stop him falling, like a platform or a bridge.)
4 $10 Set if Sonic is jumping after rolling on the ground. (Used mainly to lock horizontal controls.)
5 $20 Set if pushing something.
6 $40 Set if underwater.
7 $80 Unused

You can add the hex values together to use multiple settings at once. Also notice that the first 3 bits (0-2) are used in the character object as a second routine counter.

$28 byte Seconds of air left. Usually $1E; it decrements every second while the player is underwater. Beeps on $18, $13, and $0E. Countdown starts on $0B.
$29-$2F Unused (scratch RAM)
$30-$31 word Remaining invulnerability time. Starts at $0078 after Sonic is hit, and seems to decrement every frame until it reaches $0000.
$32-$33 word Remaining time of invincibility.
$34-$35 word Remaining time of Speed Shoes.
$36 byte Angle of ground at Sonic's front collision hot spot ($03 is "edge of ground")
$37 byte Angle of ground at Sonic's rear collision hot spot
$38 byte Is set to make Sonic stick to the SBZ wheel
$39 byte Unused.
$3A-$3B word Unused.
$3C byte Set if jumping.
$3D byte OST index of object currently being stood on. (multiply by $40 and add $D000 to get the object's address).
$3E-$3F word Control lock timer. Set to lock left and right controls after hitting a spring or running down a slope.
Boss Variables
Offset Size Description
$21 byte Hit counter. Number of hits it takes to defeat a boss.
$30 word X position
$38 word Y position
$3E byte Number of times to flash when hit

References


Sonic Community Hacking Guide
General
SonED2 Manual | Subroutine Equivalency List
Game-Specific
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 | 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 2 (Nick Arcade prototype) | Sonic CD (prototype; 1992-12-04) | Dr. Robotnik's Mean Bean Machine | Sonic Triple Trouble | Tails Adventures | Sonic Crackers | Sonic 3D: Flickies' Island | Sonic & Knuckles Collection | Sonic R | Sonic Shuffle | Sonic Advance | Sonic Advance 3 | Sonic Battle | Shadow the Hedgehog | Sonic Rush | Sonic Classic Collection | Sonic Free Riders | 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