Difference between revisions of "Sonic the Hedgehog (16-bit)/RAM Editing"
From Sonic Retro
Green Snake (talk | contribs) m (→Main System Memory Locations: Changed some in-convience of mine) |
Brainulator (talk | contribs) (removing speculation disproven by the discovery of a prototype) |
||
(82 intermediate revisions by 10 users not shown) | |||
Line 1: | Line 1: | ||
{{SCHG S1}} | {{SCHG S1}} | ||
− | ==Main System Memory | + | ==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. | ||
− | {| | + | {| class="prettytable" style="width: auto;" |
!RAM offset||Description | !RAM offset||Description | ||
|- | |- | ||
Line 11: | Line 11: | ||
|- | |- | ||
| $A400 - $A7FF | | $A400 - $A7FF | ||
− | | Level layout (1 byte per chunk, $ | + | | Level layout (1 byte per chunk, $80 bytes per line, 8 lines for planes A and B interlaced) |
|- | |- | ||
| $A800 - $A9FF | | $A800 - $A9FF | ||
Line 20: | Line 20: | ||
|- | |- | ||
| $AC00 - $AFFF | | $AC00 - $AFFF | ||
− | | Sprite table | + | | 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 | | $B000 - $C7FF | ||
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 | + | | 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 | + | | H-Scroll buffer (sent to VRAM every frame via DMA) |
|- | |- | ||
| $CF80 - $CFFF | | $CF80 - $CFFF | ||
− | | | + | | <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 | ||
− | | | + | | Dynamic SST space (Level objects are loaded here.) |
|- | |- | ||
− | | $F000 - $ | + | | $F000 - $F5BF |
| Flags used by the sound engine | | Flags used by the sound engine | ||
+ | |- | ||
+ | | $F5C0 - $F5FF | ||
+ | | <font color=green>Unused</font> | ||
|- | |- | ||
| $F600 | | $F600 | ||
Line 56: | Line 59: | ||
* $18 - Ending Sequence | * $18 - Ending Sequence | ||
* $1C - Credits | * $1C - Credits | ||
+ | |- | ||
+ | | $F601 | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $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 | ||
+ | | <font color=green>Player 2's held buttons (unused, exists because it's from a standard Mega Drive function)</font> | ||
+ | |- | ||
+ | | $F607 | ||
+ | | <font color=green>Player 2's pressed buttons (unused, exists because it's from a standard Mega Drive function)</font> | ||
+ | |- | ||
+ | | $F608-$F60B | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $F60C-$F60D | ||
+ | | VDP command for mode register 2 | ||
+ | |- | ||
+ | | $F60E-$F613 | ||
+ | | <font color=green>Unused</font> | ||
|- | |- | ||
| $F614-$F615 | | $F614-$F615 | ||
− | | | + | | General countdown timer |
|- | |- | ||
| $F616-$F617 | | $F616-$F617 | ||
− | | Plane A y-position for | + | | Plane A y-position for VSRAM |
|- | |- | ||
| $F618-$F619 | | $F618-$F619 | ||
− | | Plane B y-position for | + | | Plane B y-position for VSRAM |
|- | |- | ||
| $F61A-$F61B | | $F61A-$F61B | ||
− | | Plane A x-position for | + | | <font color=green>Plane A x-position for HScroll (unused)</font> |
|- | |- | ||
| $F61C-$F61D | | $F61C-$F61D | ||
− | | Plane B x-position for | + | | <font color=green>Plane B x-position for HScroll (unused)</font> |
|- | |- | ||
| $F61E-$F61F | | $F61E-$F61F | ||
− | | | + | | Copy of $F71C |
|- | |- | ||
| $F620-$F621 | | $F620-$F621 | ||
− | | | + | | Copy of $F718 |
+ | |- | ||
+ | | $F622-$F623 | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $F624-$F625 | ||
+ | | VDP register $A (H-INT counter) cache (used for water height on screen) | ||
+ | |- | ||
+ | | $F626-$F627 | ||
+ | | Variables used in palette fade routines | ||
+ | |- | ||
+ | | $F628 | ||
+ | | <font color=green>Counter that increments if the V-INT routine is $E, which is unused</font> | ||
+ | |- | ||
+ | | $F629 | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $F62A | ||
+ | | V-INT routine ID | ||
+ | |- | ||
+ | | $F62B | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $F62C | ||
+ | | Number of sprites on screen | ||
+ | |- | ||
+ | | $F62D-$F631 | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $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 | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $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 | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $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 | | $F64C | ||
− | | Water Level | + | | 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 | ||
+ | | <font color=green>Unused, but is cleared upon loading the SEGA screen</font> | ||
+ | |- | ||
+ | | $F664-$F67F | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $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 | ||
+ | | <font color=green>Level's target left boundary (Unused)</font> | ||
+ | |- | ||
+ | | $F722-$F723 | ||
+ | | <font color=green>Level's target right boundary (Unused)</font> | ||
+ | |- | ||
+ | | $F724-$F725 | ||
+ | | <font color=green>Level's target upper boundary (Unused)</font> | ||
+ | |- | ||
+ | | $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 |
− | | | + | | <font color=green>Written to by LevelSizeLoad, but unused otherwise</font> |
|- | |- | ||
− | | $ | + | | $F732-$F733 |
− | | | + | | <font color=green>Upper level boundary +$240, but unused otherwise</font> |
|- | |- | ||
− | | $ | + | | $F734-$F739 |
− | | | + | | <font color=green>Unused</font> |
|- | |- | ||
− | | $ | + | | $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 | | $F73E-$F73F | ||
| Y-camera position, based on Sonic ($60 = default) | | Y-camera position, based on Sonic ($60 = default) | ||
+ | |- | ||
+ | | $F740-$F741 | ||
+ | | <font color=green>Unused (cleared by LevelSizeLoad)</font> | ||
|- | |- | ||
| $F742 | | $F742 | ||
− | | | + | | Level's dynamic events routine ID |
+ | |- | ||
+ | | $F743 | ||
+ | | <font color=green>Unused</font> | ||
|- | |- | ||
| $F744 | | $F744 | ||
− | | Scroll | + | | Scroll disable flag |
+ | |- | ||
+ | | $F745 | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $F746 | ||
+ | | <font color=green>Unused (cleared by LevelSizeLoad)</font> | ||
+ | |- | ||
+ | | $F747 | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $F748 | ||
+ | | <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 | ||
+ | | <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 | ||
+ | | 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 | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $F754 | ||
+ | | 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 | ||
+ | | Flag that is set if the level's lower boundary is moving. | ||
+ | |- | ||
+ | | $F75D-$F75F | ||
+ | | <font color=green>Unused</font> | ||
|- | |- | ||
| $F760-$F761 | | $F760-$F761 | ||
− | | Sonic's | + | | Sonic's top speed |
|- | |- | ||
| $F762-$F763 | | $F762-$F763 | ||
− | | Sonic's | + | | Sonic's acceleration |
|- | |- | ||
| $F764-$F765 | | $F764-$F765 | ||
− | | Sonic's | + | | 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 | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $F76A | ||
+ | | Angle value at Sonic's right sensor | ||
+ | |- | ||
+ | | $F76B | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $F76C | ||
+ | | Object manager's routine ID | ||
+ | |- | ||
+ | | $F76D | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $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 | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $F790-$F791 | ||
+ | | Demo's button press counter (Addition to proper address) | ||
+ | |- | ||
+ | | $F792 | ||
+ | | Seems to be duration to increment button press counter | ||
+ | |- | ||
+ | | $F793 | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $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 | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $F7A4-$F7A5 | ||
+ | | Stomping chained metal block Y position (used to align a pushing block on top of it) | ||
+ | |- | ||
+ | | $F7A6 | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $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 | | $F7AA | ||
− | | | + | | Flag to prevent Sonic from going past the right level boundary |
+ | |- | ||
+ | | $F7AB | ||
+ | | <font color=green>Unused</font> | ||
|- | |- | ||
| $F7AC-$F7AF | | $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 | ||
+ | | <font color=green>Unused, but could possibly have been used for animated art tile variables like above.</font> | ||
+ | |- | ||
+ | | $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 | | $F7CC | ||
− | | Joypad | + | | 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, <font color=green>Unused in REV00</font> | ||
+ | |- | ||
+ | | $F7CF | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $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, <font color=green>Unused in REV00</font> | ||
+ | |- | ||
+ | | $F7DA-$F7DF | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $F7E0-$F7EF | ||
+ | | Switch statuses | ||
+ | |- | ||
+ | | $F7F0-$F7F1<br>$F7F2-$F7F3<br>$F7F4-$F7F5<br>$F7F6-$F7F7 | ||
+ | | Scroll section Y sizes | ||
+ | |- | ||
+ | | $F7F8-$F7FF | ||
+ | | <font color=green>Unused</font> | ||
|- | |- | ||
| $F800-$FA7F | | $F800-$FA7F | ||
− | | Sprite | + | | Sprite table buffer (sent to VRAM every frame via DMA) |
|- | |- | ||
| $FA00-$FA7F | | $FA00-$FA7F | ||
Line 150: | Line 551: | ||
| Target palette (calling Pal_FadeTo will change the ''normal'' palette until it is the same as the ''target'' palette) | | Target palette (calling Pal_FadeTo will change the ''normal'' palette until it is the same as the ''target'' palette) | ||
|- | |- | ||
− | | $FC00-$ | + | | $FC00-$FCFF |
− | | | + | | Object respawn status table |
|- | |- | ||
| $FC44 | | $FC44 | ||
− | | Error | + | | Error message ID (If crash happens) |
+ | |- | ||
+ | | $FD00-$FDFF | ||
+ | | System stack | ||
|- | |- | ||
| $FE00 | | $FE00 | ||
− | | | + | | Stack pointer |
|- | |- | ||
− | | $ | + | | $FE00-$FE01 |
− | | | + | | <font color=green>Unused</font> |
|- | |- | ||
− | | $ | + | | $FE02-$FE03 |
− | | Level | + | | Level reload flag |
|- | |- | ||
− | | $ | + | | $FE04-$FE05 |
− | | | + | | Internal level counter (number of frames passed since the level fades from black) |
|- | |- | ||
− | | $FE10-$FE11 | + | | $FE06 |
− | | | + | | Debug mode item ID |
+ | |- | ||
+ | | $FE07 | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $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 | | $FE12 | ||
− | | | + | | Number of lives Sonic has |
+ | |- | ||
+ | | $FE13 | ||
+ | | <font color=green>Unused</font> | ||
|- | |- | ||
− | | $FE14 | + | | $FE14-$FE15 |
− | | | + | | Air remaining (When underwater) |
|- | |- | ||
| $FE16 | | $FE16 | ||
− | | Last | + | | Last special stage entered ID |
+ | |- | ||
+ | | $FE17 | ||
+ | | <font color=green>Unused</font> | ||
|- | |- | ||
| $FE18 | | $FE18 | ||
− | | | + | | Number of continues |
+ | |- | ||
+ | | $FE19 | ||
+ | | <font color=green>Unused</font> | ||
|- | |- | ||
| $FE1A | | $FE1A | ||
− | | Time | + | | 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 | | $FE1C | ||
− | | | + | | Flag to update the life counter in the HUD |
|- | |- | ||
| $FE1D | | $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 | | $FE1E | ||
− | | | + | | Flag to update the timer in the HUD |
|- | |- | ||
| $FE1F | | $FE1F | ||
− | | | + | | Flag to update the score in the HUD |
|- | |- | ||
| $FE20-$FE21 | | $FE20-$FE21 | ||
− | | | + | | Number of rings collected |
|- | |- | ||
− | | $FE22-$FE25 | + | | $FE22-$FE23 |
− | | | + | | Minutes counter for the level timer |
+ | |- | ||
+ | | $FE24 | ||
+ | | Seconds counter for the level timer | ||
+ | |- | ||
+ | | $FE25 | ||
+ | | Frame counter for the level timer | ||
|- | |- | ||
| $FE26-$FE29 | | $FE26-$FE29 | ||
| Score | | Score | ||
+ | |- | ||
+ | | $FE2A-$FE2B | ||
+ | | <font color=green>Unused</font> | ||
|- | |- | ||
| $FE2C | | $FE2C | ||
− | | Shield | + | | Shield flag (Set to take a single hit without losing rings) |
|- | |- | ||
| $FE2D | | $FE2D | ||
− | | Invincibility | + | | Invincibility flag (Set to make Sonic invincible) |
|- | |- | ||
| $FE2E | | $FE2E | ||
− | | Speed | + | | Speed shoes flag (Set to activate speed shoe physics) |
|- | |- | ||
| $FE2F | | $FE2F | ||
− | | Unused | + | | <font color=green>Unused (cleared when level starts, possibly another power up flag, like the goggles)</font> |
|- | |- | ||
− | | $FE30 | + | | $FE30-$FE54 |
− | | Lamppost Counter | + | | 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 | ||
+ | | <font color=green>Unused</font> | ||
|- | |- | ||
| $FE57 | | $FE57 | ||
− | | | + | | Number of emeralds collected |
+ | |- | ||
+ | | $FE58-$FE5D | ||
+ | | Array of collected emeralds | ||
+ | |- | ||
+ | | $FE5E-$FE9F | ||
+ | | Oscillation values | ||
+ | |- | ||
+ | | $FEA0-$FEBF | ||
+ | | <font color=green>Unused</font> | ||
+ | |- | ||
+ | | $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 <font color=green>(Unused)</font> |
|- | |- | ||
− | | $ | + | | $FEC5 |
− | | | + | | Animation frame <font color=green>(Unused)</font> |
|- | |- | ||
− | | $ | + | | $FEC6 |
− | | | + | | Ring loss timer |
|- | |- | ||
− | | $ | + | | $FEC7 |
− | | | + | | Lost ring animation frame |
+ | |- | ||
+ | | $FEC8 | ||
+ | | Lost ring animation accumulator | ||
|- | |- | ||
− | | $ | + | | $FEC9-$FEEF |
− | | | + | | <font color=green>Unused</font> |
|- | |- | ||
− | | $ | + | | $FEF0-$FEF3 |
− | | | + | | Debug mode variables |
− | + | * $FEF0-$FEF1 - Copy of level's upper boundary | |
− | + | * $FEF2-$FEF3 - Copy of level's bottom boundary | |
− | |||
− | |||
− | |||
− | |||
|- | |- | ||
− | + | | $FEF4-$FEFF | |
− | + | | <font color=green>Unused</font> | |
− | |||
|- | |- | ||
− | | $ | + | | $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> | ||
|- | |- | ||
− | | $ | + | | $FF10-$FF37 |
− | | $ | + | | Copy of $F700-$F72F and $F754-$F75B, used in "LoadTilesAsYouMove" routine |
− | |||
|- | |- | ||
− | | $FF38 - $FF7F | + | | $FF38-$FF7F |
− | |||
| <font color=green>Unused</font> | | <font color=green>Unused</font> | ||
|- | |- | ||
− | | $FF80 - $ | + | | $FF80-$FF81 |
− | | | + | | Timer for level select selection movement |
− | |||
|- | |- | ||
− | | $ | + | | $FF82-$FF83 |
− | | $ | + | | Level select selection number |
+ | |- | ||
+ | | $FF84-$FF85 | ||
+ | | Level select sound ID | ||
+ | |- | ||
+ | | $FF86-$FFBF | ||
| <font color=green>Unused</font> | | <font color=green>Unused</font> | ||
|- | |- | ||
− | | $ | + | | $FFC0-$FFC3 |
− | + | | Copy of current score <font color=green>(Unused)</font> | |
− | | <font color= | ||
|- | |- | ||
− | | $ | + | | $FFC4-$FFDF |
− | |||
| <font color=green>Unused</font> | | <font color=green>Unused</font> | ||
|- | |- | ||
− | | $FFE0 - $ | + | | $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 | + | | $FFE8-$FFE9 |
− | |||
| <font color=green>Unused</font> | | <font color=green>Unused</font> | ||
|- | |- | ||
− | | $FFEA - $FFF1 | + | | $FFEA-$FFEB |
− | | $ | + | | <font color=green>Unused</font> (However is cleared on the Title Screen) |
− | | <font color= | + | |- |
+ | | $FFEC-$FFEF | ||
+ | | <font color=green>Unused</font> (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 | ||
+ | | <font color=green>Unused</font> | ||
|- | |- | ||
− | | $ | + | | $FFF8 |
− | | | + | | Hardware version register (Bits 6 and 7 of lower byte) |
− | |||
|- | |- | ||
− | | $ | + | | $FFF9 |
− | |||
| <font color=green>Unused</font> | | <font color=green>Unused</font> | ||
|- | |- | ||
− | | $ | + | | $FFFA-$FFFB |
− | | $ | + | | Debug mode flag |
− | | | + | |- |
+ | | $FFFC-$FFFF | ||
+ | | Checksum passed flag | ||
+ | |||
|} | |} | ||
− | == Object Status Table | + | ==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 319: | 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 326: | 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 | + | |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 | + | |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 | + | |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. | ||
|} | |} | ||
|- | |- | ||
− | | $02 || word || | + | | $02 || word || Art tile |
+ | {| class="prettytable" style="width:auto;" | ||
+ | !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 | | $04 || long || Mappings offset | ||
Line 367: | Line 889: | ||
|$17 || byte || Horizontal radius of the object's hitbox. | |$17 || byte || Horizontal radius of the object's hitbox. | ||
|- | |- | ||
− | |$18 || byte || Sprite priority (00 | + | |$18 || byte || Sprite priority ($00 to $07, lower value has bigger priority). |
|- | |- | ||
|$19 || byte || Horizontal radius of the object's visible sprite. | |$19 || byte || Horizontal radius of the object's visible sprite. | ||
Line 387: | 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 | + | |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|| | + | |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|| | + | |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|| | + | |6||$40||<font color=green>Unused</font> |
|- | |- | ||
− | |7||$80|| | + | |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 424: | 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. | + | |0||$01||Orientation. Set is left and clear is right. |
|- | |- | ||
− | |1||$02||Set if Sonic is in the air | + | |1||$02||Set if Sonic is in the air |
|- | |- | ||
|2||$04||Set if jumping or rolling. | |2||$04||Set if jumping or rolling. | ||
Line 435: | 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 441: | 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 461: | 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 485: | 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}} | ||
− |
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
| |||||||||||||||
$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
| |||||||||||||||
$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
| |||||||||||||||
$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
| |||||||||||||||
$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:
| |||||||||||||||||||||||||||
$02 | word | Art tile
| |||||||||||||||||||||||||||
$04 | long | Mappings offset | |||||||||||||||||||||||||||
$08 | word |
| |||||||||||||||||||||||||||
$0A | word |
| |||||||||||||||||||||||||||
$0C | word |
| |||||||||||||||||||||||||||
$0E | word |
| |||||||||||||||||||||||||||
$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:
| |||||||||||||||||||||||||||
$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:
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