SCHG:Sonic the Hedgehog 3 & Knuckles/RAM Editing
From Sonic Retro
SCHG: Sonic the Hedgehog 3 & Knuckles |
---|
Main Article |
Art Editing |
Editing Art |
Object Editing |
Editing Objects |
Level Editing |
Editing Levels |
Music Editing |
Editing Music |
RAM Editing |
Editing RAM |
Sonic & Knuckles Collection |
Sonic & Knuckles Collection |
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.
RAM offset | Description | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
$0000-$7FFF | 128x128 chunk mappings | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$8000-$8FFF | Level layout
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$9000-$A7FF | 16x16 block mappings | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$A800-$A9FF | Background scroll buffer. Used mainly to save data about positions of different layers of parallax backgrounds, but sometimes is used for other purposes in the Screen Events routines. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$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-$CFCB | Object attribute table
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$CFCC-$CFDF | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$CFE0-$CFEE | Array of flags used by the HCZ conveyor belts to avoid loading them more than once. The size of the array depends on the highest object subtype used. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$CFEF-$CFFF | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$D000-$DFFF | Kosinski decompression buffer. Used also for software scaling. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E000-$E37F | Horizontal scroll buffer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E380 | Number of objects currently in collision response list, multiplied by 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E382-$E3FF | Collision response list. The format is one word per object, where the word is the starting address of the object's status table. Only objects in this list are processed by the collision response routine. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E400-$E4FF | In 1-player mode, this is Sonic's statistic recording buffer, used by Tails' AI. In 2-player mode, this is player 2's position table. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E422-$E423 | Player position X in Special Stage, with each checkerboard field having a size of $100. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E424-$E425 | Player position Y in Special Stage, with each checkerboard field having a size of $100. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E426-$E427 | Player direction in Special Stage. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E428-$E429 | Current player movement speed in Special Stage. Negative if walking backwards. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E42A | Direction change at the next checkerboard corner in Special Stage. Can be either -4, 0 or 4. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E42B, $E42C, $E42F, $E430 | Unknown in Special Stage. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E431 | This flag is set to 1 while going forward in Special Stage. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E432, $E433, $E434-$E435, $E436-$E437 | Unknown in Special Stage. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E438-$E439 | The number of blue spheres remaining to be collected in a Special Stage. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E43A-$E43B | The number of rings collected in a Special Stage. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E43C | Unknown in Special Stage. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E43D | Special Stage ring collection flags. Bit 0 is set when 50 rings have been collected, bit 1 is set for 100 rings, bit 2 is set for 200 rings, and bit 7 is set when the rings display needs to be refreshed. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E43E-$E43F | Number of frames remaining till the speed of a Special Stage increases. Initial value is 1800 (i.e. 30 seconds in 60Hz mode) for regular special stages and 2700 (i.e. 45 seconds in 60Hz mode) for Blue Spheres special stages. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E440 | Unknown in Special Stage. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E442-$E443 | Total rings remaining to be collected in a Special Stage. A 50000 points perfect bonus is awarded for collecting all the rings. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E444-$E445 | Special Stage speed. Starts off at $1000 and is incremented by $400 every time the speed increase timer expires until it reaches $2000. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E436-$E439 | Unknown in Special Stage. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E44A-$E44B | Height of spheres when they fly up after collecting the last blue sphere in Special Stage. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E44C, $E44D, $E44E-$E44F, $E450 | Unknown in Special Stage. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E500-$E5FF | Position table for player 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E600-$E653 | Saved competition mode data | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E654-$E65F | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E660-$E663 | Long pointer to the currently-playing save slot's data in memory. Set to $FFFFE6AC when playing save slot 1, $FFFFE6B6 when playing save slot 2, etc. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E664-$E665 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E666-$E667 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E668-$E6AB | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E6AC-$E6FF | Variables for each save slot. The format is $A bytes long:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$E700-$EAFF | Ring status table. The format is two bytes per ring, these bytes being 0000 while the ring has yet to be consumed, serving as a ring destruction timer while the ring is being consumed, and being set to FFFF when the ring has been fully consumed. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EB00-$EDFF | Object respawn table. Each object which is part of a level's object placement gets an entry in this table, and whenever the objects manager creates a new object, it sets bit 7 of the object's entry in the object respawn table. While bit 7 is set, the object will not be loaded again by the objects manager. The other seven bits of the entry are free for use by the object - for example, monitors set bit 0 to signify a broken monitor. Since every object which is part of the level's object placement has an entry in this table, the maximum number of objects any level can have in its object placement is 768, although the only level that gets close to that number is AIZ2, with 751 objects. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE00-$EE01 | Variable set by the horizontal scroll manager to the difference between the old and new camera X positions, multiplied by 256 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE02-$EE03 | Variable set by the vertical scroll manager to the difference between the old and new camera Y positions, multiplied by 256 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE04-$EE05 | Variable set by the horizontal scroll manager to the difference between the old and new camera X positions for player 2, multiplied by 256 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE06-$EE07 | Variable set by the vertical scroll manager to the difference between the old and new camera Y positions for player 2, multiplied by 256 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE08 | Unused, but cleared when the level starts. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE09 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE0A | Scroll lock for player 1 - if this is set, scrolling routines won't be processed. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE0B | Scroll lock for player 2 - if this is set, scrolling routines won't be processed. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE0C-$EE0D | Level's target left boundary (Unused) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE0E-$EE0F | Level's target right boundary (Unused) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE10-$EE11 | Level's target upper boundary (Unused) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE12-$EE13 | Level's target lower boundary. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE14-$EE15 | Level's left boundary. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE16-$EE17 | Level's right boundary. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE18-$EE19 | Level's upper boundary. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE1A-$EE1B | Level's lower boundary. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE1C-$EE1D | Level's left boundary for player 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE1E-$EE1F | Level's right boundary for player 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE20-$EE21 | Level's upper boundary for player 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE22-$EE23 | Level's lower boundary for player 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE24-$EE25 | Horizontal scroll delay. If this is nonzero, the upper byte is the offset into the player 1 position table, which is used to calculate camera position. Used for example by the Spin Dash and fire dash. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE26-$EE27 | Index into Player 1's statistics recording buffer and position table. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE28-$EE29 | Horizontal scroll delay for player 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE2A-$EE2B | Index into Player 2's position table. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE2C-$EE2D | Screen Y-offset to center the camera to. This is used for looking up or down, which changes the camera Y-offset to show more of the screen. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE2E-$EE2F | Screen Y-offset to center the camera to for player 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE30 | Deform lock flag. If this flag is set, camera will not be scrolled and level resize events are not processed. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE31 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE32 | Flag that is set, if camera is going to scroll vertically this frame, because the target bottom boundary was changed. This seems to only be used for the camera scrolling. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE33 | Routine counter for screen resize routines. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE34-$EE38 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE39 | Fast vertical scrolling flag. If set, screen can be scrolled up to $18 pixels per frame, as opposed to 6 pixels. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE3A-$EE3B | Copy of the foreground vertical scroll position for player 2. Seems to be used for the competition mode (Change camera position mid-screen). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE3C-$EE3D | Copy of the background vertical scroll position for player 2. Seems to be used for the competition mode (Change camera position mid-screen). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE3E-$EE3F | This is the difference between the foreground horizontal position and background horizontal position. Used for various things, such as collision with the background layer. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE40-$EE41 | This is the difference between the foreground vertical position and background vertical position. Used for various things, such as collision with the background layer. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE42-$EE45 | Address (in the ROM) of the next ring to the left. Used to more efficiently load unloaded rings when the camera is moved. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE46-$EE49 | Address (in the ROM) of the next ring to the right. Used to more efficiently load unloaded rings when the camera is moved. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE4A-$EE4B | Address (in the ring status table) of the next ring to the left. Used to more efficiently load unloaded rings when the camera is moved. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE4C-$EE4D | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE4E | Apparent current zone. This is identical to $FE10. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE4F | Apparent current act. Unlike $FE11, this is only incremented by the actual end of act score tally, so it differs from $FE11 in levels like AIZ, where $FE11 is set to 1 as soon as the first cutscene is over, while this is incremented only after the end of act points tally. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE50-$EE51 | Animated palette timer. When set to a negative value, no palette cycling occurs. When set to 0, normal palette cycling occurs. When set to above 0, palette is either faded from black or white, depending on the level. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE52-$EE55 | Address of the demo playback data. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE56-$EE59 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE5A | Unknown, maybe competition mode related. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE5B | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE5C-$EE5D | Unknown, maybe competition mode related. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE5E | Flag used to indicate we started act 3. This flag disables the title cards. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE5F | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE60-$EE63 | Plane A X-position for player 2 in 2p mode. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE64-$EE67 | Plane A Y-position for player 2 in 2p mode. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE68-$EE6B | Copy of plane A X-position for player 2 in 2p mode. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE6C-$EE6F | Copy of plane A Y-position for player 2 in 2p mode. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE70-$EE71 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE72-$EE73 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE74-$EE75 | Unused, only referenced in dead code. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE76-$EE77 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE78-$EE7B | Plane A X-position. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE7C-$EE7F | Plane A Y-position. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE80-$EE81 | Copy of plane A X-position. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE82-$EE83 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE84-$EE85 | Copy of plane A Y-position. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE86-$EE87 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE88-$EE89 | Rounded plane A X-position. The position is rounded down to the last full block ($10 pixels). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE8A-$EE8B | Rounded plane A Y-position. The position is rounded down to the last full block ($10 pixels). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE8C-$EE8D | Copy of plane B X-position. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE8E-$EE8F | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE90-$EE91 | Copy of plane B Y-position. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE92-$EE93 | Unknown, possibly unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE94-$EE95 | Rounded plane B X-position. The position is rounded down to the last full block ($10 pixels). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE96-$EE97 | Rounded plane B Y-position. The position is rounded down to the last full block ($10 pixels). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE98-$EE99 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE9A-$EE9B | Unknown, possibly unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EE9C-$EE9F, $EEA0-$EEA1, $EEA2, $EEA3 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEA4 | Plane double update flag. This is set, when the plane has moved by more than $10 pixels this frame. It is used temporarily to remember to update the next row or column of the plane. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEA5 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEA6-$EEA7 | Special V-int routine. This flag is used to control various special functions that occur during the vertical interrupt. This is mainly used for the LBZ2 ship sequence. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEA8-$EEA9 | Plane X-wrap value. This flag is used to wrap the horizontal position of the level. It looks like, that this was never used for anything. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEAA-$EEAB | Plane Y-wrap value. This flag is used to wrap the vertical position of the level. This is used to create infinitely looping levels. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEAC-$EEAD | Plane Y-wrap value masked by $FFF0. Used to wrap the vertical position of the level, while aligning to 16px units. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEAE-$EEAF | Layout row mask. Used to wrap vertically while dealing with units of level layout row indices, which are multiples of 4. For example, it's $3C when level wraps every $800 pixels, and $7C when level wraps every $1000 pixels. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEB0-$EEB1 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEB2-$EEB3 | Special events routine counter. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEB4-$EEB5 | Various meanings for screen events routines. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEB6-$EEB7 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEB8-$EEB9 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEBA-$EEBB | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEBC-$EEBD | X-position offset for various objects this frame. Used mainly for looping parts of the level, to make the illusion of constant forward movement. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEBE-$EEBF | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEC0-$EEC1 | Screen event routine counter. Each routine is 4 units, so this counter can only contain multiples of 4. Affects AIZ2, FBZ2, LBZ2, MHZ2, SOZ2, SSZ1, SSZ2, DEZ2, DDZ, the slot machine bonus stage, the LRZ boss act, the DEZ boss act and the ending sequence. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEC2-$EEC3 | Trigger event routine counter. Each routine is 4 units, so this counter can only contain multiples of 4. Affects all levels except for the bonus stages, DDZ, and MHZ1. For some reason, the ICZ1 screen event routine also uses this counter, so both the screen and trigger event routines are linked in that act. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEC4-$EEC5 | Used to trigger various level events or scrolling events. This varies for each level. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEC6-$EEC7 | Similar to $EEC4, used for different events. Level property (like killer wall in HCZ2 or avalanche in ICZ1). The high byte is set when an Act 1 signpost stops spinning, to signal the code that loads Act 2 into memory. This doesn't happen for AIZ and ICZ since they load Act 2 before the midboss. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEC8-$EEC9 | Used for drawing the entire plane across multiple frames. It is a counter of sorts, to remember which plane row the draw next. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EECA-$EECB | Used for drawing the entire plane across multiple frames. This determines how many rows are left to draw. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EECC-$EECD | Screen shaking flag. If zero, screen is not shaking. If negative, screen is shaking for an earthquake and will continue indefinitely. If positive, screen is shaking from a bomb impact or the like, and the value will be decremented each frame until it reaches zero, then shaking will stop. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EECE-$EECF | Screen shaking offset: the difference between the "true" camera Y position and what appears on screen that frame. Most acts' screen events add this to $EE84 each frame. AIZ1, HCZ1, CNZ1, FBZ1, ICZ2, MHZ1 and DEZ ignore this value, so you'll need to edit the screen events if you want to add shaking effects in those acts. MHZ2 uses it as an X offset instead of a Y offset (when Robotnik hits the tree) so adds it to $EE80 instead of $EE84. ICZ1 uses it for both, depending on where in the level you are. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EED0-$EED1 | Stores the value that $EECE had during the previous frame. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EED2-$EED3 | Secondary screen event routine counter, used by some acts. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EED4-$EED5 | Various meanings in level events, used for example as the X-position for destroying blocks in the CNZ miniboss. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EED6-$EED7 | Various meanings in level events, used for example as the Y-position for destroying blocks in the CNZ miniboss. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EED8-$EEEB | Various meanings in level events and sometimes other game modes. Every word usually has different meaning. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEEA-$EF0D | FBZ2 cloud object pointers. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEEA-$EF39 | V-Scroll buffer. The buffer contains 20 entries, where an entry is a word for foreground vertical position, and a word for background vertical position. Each 16 pixel column of the screen can be scrolled a different amount as per contents of this buffer. This effect is used only in rare occasions (examples are: MGZ2 level collapse when boss fight starts, LBZ1 building breakdown before boss). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EEEA | Various other uses which are unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF3A-$EF3B | Is set to indicate that there are object(s) that are meant to mask other sprites horizontally. These sprites are set to x-position 0, which makes VDP mask overlapping sprites. various level events use this to hide some artifacts. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF3C-$EF3D | If set, an alternate address is used for the sprite attribute table data. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF3E-$EF3F | Flag that if set, changes the state of $EF3C | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF40-$EF43 | Unknown, seems to have various functions. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF44-$EF47 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF48 | Competition menu item (00 = Grandprix, 01 = Matchrace, 02 = Timeattack, 03 = Exit) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF49 | Flag which determines whether the second player in a 2P versus game is player-controlled or just a "ghost" of the first player. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF4A | Competition menu zone. This is different from the actual zone id, which is later calculated based on this flag. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF4B | Data select save selection. This also includes NO SAVE and DELETE options. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF4C-$EF4D | Stores the data select player mode for NO SAVE option (00 = Sonic & Tails, 01 = Sonic, 02 = Tails, 03 = Knuckles) (see also $FF08) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF4E | Competition menu monitor selection. If set, monitors are disabled. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF4F | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF50 | Keeps track of whether controller 1 has pressed the start button. It is not clear why this is necessary. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF51 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF52-$EF55 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF56-$EF57 | Flag that if set, SRAM save and load routines will disable interrupts while SRAM is enabled. This is likely done to avoid interrupts firing while SRAM is enabled, that could crash the processor. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF58-$EF59 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF5A-$EF5D | There are 2 object lists; Sonic 3 list, and Sonic & Knuckles list. This flag points to either one depending on the level ID. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF5E-$EF5F | Used to temporarily store ring count, while transitioning to act 3. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF60-$EF63 | Used to temporarily store level timer value, while transitioning to act 3. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF64-$EF65 | Position Y of the window of active objects. Only actually used in glowing spheres bonus stage. Objects with Y coordinate lower or at least $280 higher than that will despawn. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF66-$EF67 | Alternate screen shaking flag, only used when Hyper Knuckles hits a wall after gliding. If zero, screen is not shaking. If nonzero, the value will be decremented each frame until it reaches zero, then shaking will stop. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF68-$EF69 | Unknown, always set to $98, and only ever used to set the art tile of various Special Stage Result objects. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF6A-$EF6B | Zone and act is stored here during Special Stage Results screen. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF6C-$EF6D | Flag which is set to $FF00 when a Super Emerald special stage is newly completed. This stops the HPZS initalizer from repeating the "beam" effect that you see when you go to HPZ from a giant ring to pick the special stage in the first place. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF6E | Seems to be a copy of $FE16 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF6F | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF70 | Seems to be a copy of $FE16, specifically used for HPZS | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF71 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF72-$EF73 | Flag which is set to $FF00 if an ending is running. The only thing this seems to do is prevent the game from being able to pause. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF74-$EF77 | Address of secondary plane buffer. If set to 0, it is ignored. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF78 | The number of frames to hold buttons specified by $EF79 in S&K demos. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF79 | The buttons to hold in S&K demos. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF7A-$EF7B | Currently running demo ID. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF7C-$EF7F | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF80-$EF81 | The number of rings inside the ring consumption table. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$EF82-$EFFF | Ring consumption table. Contains the RAM addresses (inside the ring status table) of rings which are currently being consumed. Once consumed, the rings are deleted from this table. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F000-$F07F | Target underwater palette. Used to fade the underwater palette slowly. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F080-$F0FF | Current underwater palette. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F100-$F57F | Plane buffer. During the normal level processing period, display update routines decide which tiles need to be updated and write the results here, and then in V-int a routine processes this and updates the planes accordingly. The first word of each entry in this buffer is the address in VRAM to write to - if this is 0, the buffer processing routine terminates. The second word is the number of 16x16 tiles to be written - 1, and the sign bit of this word being set indicates that the constituent 8x8 tiles are to be written column-by-column rather than row-by-row. Following this is the actual data to write. Warning: Some levels can, on some occasions, overflow from this buffer, inevitably causing a crash! This can be fixed by carefully rearranging RAM. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F580-$F5FF | VRAM buffer. Used to temporarily hold data while it is being transferred from one VRAM location to another. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F600 | Game mode flag. This flag is used to determine what game mode to go to next. This only takes effect when the last game mode ends (some game modes check for this flag specifically).
The MSB is a loading routine flag. It only matters for some game modes. It won't have any effect when changing modes because it's filtered out, but the corresponding routine does pay attention to it... Known meanings of certain values of the lower 7 bits:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F601 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F602 | In-game Controller 1 held state. Same as $F604, but it only updates during the main game loop, and not while paused, or a cutscene is running. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F603 | In-game Controller 1 pressed state. Same as $F602, but only tells which buttons are being pressed newly this frame. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F604 | This bitfield tells which button(s) on Controller 1, if any, are currently pressed. Format is:
This is updated every frame. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F605 | Same as $F604, but only tells which buttons are being pressed newly this frame. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F606 | Same as $F604, but for Controller 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F607 | Same as $F606, but only tells which buttons are being pressed newly this frame for Controller 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F608-$F60D | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F60E-$F60F | VDP command for mode register 2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F610-$F613 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F614-$F615 | Demo time left & Time until demo starts from title screen. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F616-$F617 | Foreground vertical scroll position. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F618-$F619 | Background vertical scroll position. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F61A-$F61D | Unused, but cleared in various places. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F61E-$F61F | Foreground vertical scroll position for player 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F620-$F621 | Background vertical scroll position for player 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F622 | Teleport timer (leftover from Sonic 2). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F623 | Teleport active flag (leftover from Sonic 2). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F624-$F625 | VDP register $A (H-INT counter) cache. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F626 | Number of bytes from the palette start to be ignored in screen fading routines. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F627 | Number of palette entries minus one to be affected in screen fading routines. The first affected palette entry index is half of the value in $F626. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F628-$F629 | Number of lag frames per level loop. Displayed in the place of the minutes counter in the debug HUD. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F62A | V-INT routine ID. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F62B | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F62C | Number of sprites rendered on screen. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F62D | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F62E-$F631 | Address to a list of offsets, used in various horizontal interrupt routines, to load the water palette gradually. These are offsets are offsets to either water palette, or the normal palette, and target CRAM locations. 3 colors are loaded each scanline, and for each scanline, new offset is read. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F632-$F635 | Counters used for palette cycling. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F636-$F639 | Random number generator seed & result. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F63A-$F63B | Game paused flag. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$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 | H-int enable flag. This flag is used to make sure the horizontal interrupt code is never run twice in a single frame unintentionally. If set, the next H-int will be enabled. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F646-$F647 | Same as $F648. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F648-$F649 | Current water level. Should be a valid Y-axis value. Remember, the top of the level is $0000. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F64A-$F64B | Target water level. If this differs from $F648, the water level will move up or down $F64C lines per frame until they match. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F64C | The rate at which water rises or falls during a change in water level. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F64D | Incremented each time a player enters water. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F64E | Set to 1 if water covers the entire visible screen; clear otherwise. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F64F | If set, H-int routines will also update the HUD numbers, process the Nemesis queue, and update the demo timer flag. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F650, $F652-$F65B | Counters used for palette cycling. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F651 | Seems unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F65C-$F65D | Offset into the Super/Hyper color array, determines which set of colors we are currently on. Each palette entry is 2 bytes and there are 3 entries per set, so this is always a multiple of 6. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F65E | Number of frames remaining until the next set of Super/Hyper colors are loaded into the palette. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F65F | The current state of Super/Hyper palette rotation. 0 means disabled, 1 means the character is newly transforming to Super/Hyper, -1 ($FF) means the player is fully transformed, 2 means the character was Super/Hyper and is transforming back to normal. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F660-$F661 | Timer used in the outro to briefly wait before starting the credits. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F662-$F663 | Unused, but cleared. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F664 | Dual collision plane flag. Set to -1 ($FF) when there are two collision planes active (Examples: HCZ2 wall chase, MGZ2 partial level collapse, SOZ2 rising sand). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F665 | When set to -1 ($FF), hitting the lower level border won't lead to death. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F666 | Hyper Sonic Dash screen flash timer. Usually zero, except while the screen flash is visible. Starts at 4 and decreases by one each frame. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F667 | Tails super flag, same as $FE19, just for Tails. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F668 | Same as $F65C, but for Tails. So this variable is used to control Tails' colors, and $F65C is used to control the Super Sonic flickies. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F669 | Same as $F65E, but for Tails. So this variable is used to control Tails' colors, and $F65E is used to control the Super Sonic flickies. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F66A | In-game Controller 2 held state. Same as $F602, but for controller 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F66B | In-game Controller 2 pressed state. Same as $F66A, but only tells which buttons are being pressed newly this frame. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F66C | Counter used by Super Flickies to determine which entry from collsion response list to check next as a possible target. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F66D-$F66F | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F670-$F671 | Super Sonic ring drain counter. This is updated each frame, so the counter is set to 60 ($3C) on consoles operating in 60Hz mode, or 50 ($32) in consoles operating in 50Hz mode. After each frame, the code subtracts 1. One ring is removed when this counter reaches zero; in other words, each second. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F672-$F675 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F676 | Follow custom position flag. If this flag is set, this frame player 1's position is substituted for custom positions. This is used to focus scrolling on certain objects in the game. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F677 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F678-$F679 | Follow custom position X-position. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F67A-$F67B | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F67C-$F67D | Follow custom position Y-position. Must come 4 bytes after the X-position. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F67E-$F67F | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F680-$F6DF | Pattern load queue. Each entry in this consists of one longword followed by one word, the longword being the location in ROM of the compressed art, and the word being the VRAM location to decompress to. Can store a maximum of 16 entries, but a coding error in the clearing routine means that storing a PLC in the last slot screws everything up, so effectively only 15 requests can be stored at one time. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F6E0-$F6E3 | The address in ROM of the decompression routine to be used for the art | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F6E4-$F6F7 | Used by the PLC routines using decompression. No idea what their function is, although it seems they get passed in as parameters to the decompression routine, and are stored updated when the routine returns. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F6F8-$F6F9 | The total number of tiles left to be decompressed for the current piece of art | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F6FA-$F6FB | The number of tiles left to be decompressed in the current frame | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F6FD-$F6FF | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F700-$F701 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F702-$F703 | Tails control counter. Counts how long until the CPU takes control. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F704-$F705 | Tails respawn counter. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F706-$F707 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F708-$F709 | Tails CPU routine. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F70A-$F70B | Tails CPU target X position. Tells Tails where Sonic's X position is so he can fly back to him. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F70C-$F70D | Tails CPU target Y position. Tells Tails where Sonic's Y position is so he can fly back to him. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F70E-$F70F | Tails interact ID. Object ID of last object Tails stood on. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F710 | Routine counter for the rings manager. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F711 | Level started flag. Set to 1 as soon as the player first gets control in the level. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F712-$F72D | Unknown, seems to be unused however. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F72E | Flag used to determine which animated palette AIZ1 uses. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F72F | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F730 | Water flag. Must be set for any of the other water variables to have any effect. Note that levels without water don't have an underwater palette; you must set one or everything below the water level will be black. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F731-$F73D | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F73E | Tails carrying flag. Set to 1 whenever Tails carries Sonic. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F73F | Number of frames until Tails can catch Sonic again. Used to avoid immediate catching after Sonic jumps off. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F740-$F741 | Unknown, something to do with the software scaler used by MGZ2 boss and SSZ badniks. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F742-$F743 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F744-$F745 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F746 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F747 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F748 | Same as $F604, but for the title screen. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F749 | Same as $F605, but for the title screen. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F74A, $F74B, $F74C-$F74D, $F74E | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F74F | Flag that disables Knuckles' wall grab when set to a negative value. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F750-$F75F | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F760-$F761 | Sonic's and Knuckles' top speed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F762-$F763 | Sonic's and Knuckles' acceleration | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F764-$F765 | Sonic's and Knuckles' deceleration | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F766 | Sonic's and Knuckles' current mapping frame number. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F767 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F768 | Angle value at Sonic's left sensor | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F769 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F76A | Angle value at Sonic's right sensor | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F76B | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F76C-$F76D | Routine counter for object spawning. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F76E-$F76F | Camera X position rounded down to last multiple of $80. Used in the object spawning routine. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F770-$F771 | Camera Y position rounded down to last multiple of $80. Used in the object spawning routine. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F772-$F775 | Long pointer to level object list address of next object to spawn when moving right. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F776-$F779 | Long pointer to level object list of next object to spawn when moving left. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F77A-$F77B | Pointer into the object respawn table in RAM. Points to the entry associated with the next object to spawn when moving left. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F77C-$F77D | Pointer into the object respawn table in RAM. Points to the entry associated with the next object to spawn when moving right. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F77E-$F793 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F794-$F795 | Some type of timer used in palette fade routines. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F796-$F799 | Pointer to the currently used collision layer for players. Is always the same as either $F7B4 or $F7B8. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F79A-$F7A9 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7AA | Boss flag. Set when a boss is active, and cleared after defeat or end of sequence. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7AB-$F7AF | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7B0-$F7B3 | Unknown, used by some objects for storing player-specific state. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7B4-$F7B7 | Pointer to collision layer 1 of this level. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7B8-$F7BB | Pointer to collision layer 2 of this level. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7BC-$F7BF | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7C0 | MHZ pollen and leaves counter. This count how many pollen or leaves are active, and will stop spawning more if 10 or more pollen/leaves are active. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7C1 | Unknown flag used in MHZ. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7C2 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7C3 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7C4-$F7C5 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7C6 | Reverse gravity flag. Only in Sonic & Knuckles. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7C7 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7C8 | Wind tunnel flag. Set if player 1 is in a wind tunnel. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7C9 | Wind tunnel flag. Set if player 2 is in a wind tunnel. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7CA | Controller lock for controller 1. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7CB | Controller lock for controller 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7CC-$F7CF | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7D0-$F7D1 | Bonus counter. Increments upon destruction of a destroyable object, and is used to determine how many points the destruction should give. Resets when the player touches the ground. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7D2-$F7D3 | Time bonus counter at the end of level result screen. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7D4-$F7D5 | Ring bonus counter at the end of level result screen. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7D6-$F7D9 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7DA-$F7DB | Counts the number of times the camera has scrolled to the right by one full screen width from its previous position - initial value is $FF80 and then counts up like: $FF80,$0000,$0080,$0100,$0180,etc. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7DC-$F7DD | Unused, referenced in dead code. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7DE | Tails' current mapping frame number. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7DF | Tails' tails current mapping frame number. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7E0-$F7EF | Level trigger array. This has different meanings in most levels, but generally it is used to determine if a switch has been pressed, and platforms or other objects may react to these button presses using this array. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F7F0-$F7FF | Level animation counter. Each word is a different counter, and these are used to process animated level art. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$F800-$FA7F | Sprite table buffer. This is a temporary buffer used to store VDP sprite data, and it is DMA'd to VRAM each frame. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FA80-$FA81 | Unused, but cleared. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FA82-$FA83, $FA84-$FA85, $FA86-$FA87, $FA88 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FA89 | Flag that if set, will tell Mecha Sonic's head to get deleted. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FA8A-$FA8B | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FA8C-$FA8D | Unused, but written to once. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FA8E-$FA8F, $FA90-$FA91, $FA92-$FA93, $FA94-$FA95, $FA96-$FA97, $FA98-$FA99, $FA9A-$FAA1, $FAA2, $FAA3, $FAA4-$FAA5 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAA6-$FAA7 | Pointer to a signpost object. Hidden Monitors use this to easily find the currently active signpost used for bouncing. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAA8 | End-of-level flag. Set when a mid-boss or end boss is defeated, set back to zero when the results screen goes away. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAA9 | Unknown flag which is something to do with control lock | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAAA | Flag which is set when a title card goes away, or when an Act 1 results screen goes away. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAAB | Unknown flag which is only used by the LBZ1 boss. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAAC, $FAAD, $FAAE-$FAAF, $FAB0-$FAB1, $FAB2-$FAB3, $FAB4-$FAB5, $FAB6-$FAB7, $FAB8, $FAB9, $FABA-$FABB, $FABC-$FABD | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FABE | Unused, but written to once. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FABF | Flag that if set, palette rotation scripts will not be processed. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAC0, $FAC1, $FAC2-$FAC3 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAC4-$FAC7 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAC8-$FACB, $FACC, $FACD, $FACE-$FACF | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAD0-$FAD9 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FADA-$FADD | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FADE-$FAED | Data used by palette rotation scripts. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAEE-$FAEF | Unused, however should not be written to; Needs to be 0 for palette rotation script routine. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAF0-$FAF1 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAF2-$FAF3 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAF4-$FAF5 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAF6-$FAF7 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAF8-$FAF9, $FAFA-$FAFB, $FAFC-$FAFD | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FAFE-$FAFF | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FB00-$FBFB | VDP command buffer. Stores up to 18 sets of queued up VDP commands to be issued later. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FBFC-$FBFF | VDP command buffer free slot. Stores the address of the first available empty place in the VDP command buffer. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FC00-$FC7F | Normal dry palette. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FC80-$FCFF | Target dry palette. Used to fade the underwater palette slowly. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FD00-$FDFF | System stack. Note that the stack grows up rather than down. This means that when something is pushed onto the stack, the SP is decremented, and when something is popped from it, the SP is incremented. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE00-$FE01 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE02-$FE03 | Level restart flag. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE04-$FE05 | Level frame timer. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE06 | Object currently selected in debug mode. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE08 | Object placement mode routine counter. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE09 | Object placement mode flag (0 - normal, 1 - object placement, 2 - frame cycling) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE0A | Delay countdown until camera movement starts in object placement mode. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE0B | Current camera movement speed in object placement mode. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE0C-$FE0F | Counts the number of times V-int has run. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE10 | The current Zone. This is the value assigned to the Zone, not its position in the level list. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE11 | Act number | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE12 | Life Count | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE13-$FE17 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE18 | Number of continues. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE19 | Super/Hyper Sonic flag. 1 means Super and -1 ($FF) means Hyper. Setting this will load the Super/Hyper Sonic tiles, adjust Sonic's jump height, and start draining rings, but it will not load the rotating palette, change acceleration, max speed, or deceleration, or make him invincible. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE1A | Flag which is set when the player has a time over. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE1B | This bitfield tells the game if the player has collected extra lives from rings. Seems to work differently in S3K than in S2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE1C | Flag determines if the lives counter needs to be updated. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE1D | Flag determines if the rings counter needs to be updated. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE1E | Flag determines if the timer needs to be updated. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE1F | Flag determines if the score counter needs to be updated. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$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 (divided by 10) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE2A | ID of the last starpole the player has hit. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE2B-$FE47 | Starpole variables. When you hit a starpole, these variables are stored from the current actual values. When you die, the values are loaded from here.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE48 | Flag that determines which of the two sets of variables to restore. 0 is for starpole, anything else is for the special stage one. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE49-$FE65 | Special stage variables. When you enter a special stage, these variables are stored from the current actual values. When you return, the values are loaded from here.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE65 | Routine counter for LRZ special rocks. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE66-$FE69 | Address of leftmost LRZ rock, used for loading. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE6A-$FE6D | Address of rightmost LRZ rock, used for loading. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FE6E-$FEAF | Oscillating numbers data. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEB0 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEB1 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEB2 | Rings animation counter. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEB3 | Rings animation frame. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEB4 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEB5 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEB6 | Lost rings animation counter. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEB7 | Lost rings animation frame. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEB8-$FEB9 | Lost rings animation accumulator(?) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEBA-$FEBB | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEBC-$FEBD | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEBE | Unused, but referenced in some code. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEBF | Extra lives bits from rings for player 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEC0-$FEC1 | Tails' max speed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEC2-$FEC3 | Tails' acceleration | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEC4-$FEC5 | Tails' deceleration | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEC6 | Tails' lives in 2P mode. Unused in S3K, but referenced in code. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEC7 | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEC8-$FEC9 | Rings collected since level load. Resets if you enter Special/Bonus stage. Starts recounting from 0 when level is reentered. Not sure what this is used for. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FECA-$FECB | Same as $FEC8, but for player 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FECC-$FECD | Strange counter, that is incremented when a monitor or a ring gives you an extra life, and also when a robotnik monitor has been destroyed. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FECE-$FECF | Strange counter, that is incremented when a robotnik monitor has been destroyed by player 2. Oddly, this counter does not get incremented for extra lives; Instead, $FECC is despite being player 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FED0-$FED1 | Number of rings counter for player 2. It is unclear if this is ever used for anything. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FED2-$FED5 | Unknown, seems to be unused. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FED6-$FED9 | Unknown, seems to be level timer for player 2, unknown if this is used in any way. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEDA | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEDB | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEDC-$FEDD | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEDE-$FEDF | Unused, but cleared once. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FEE0-$FF01 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF02-$FF03 | Unused, but cleared once. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF04-$FF05 | Total rings remaining to be collected in a level. No perfect bonus is actually given for collecting all the rings, making this variable virtually useless. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF06-$FF07 | Unused, but cleared once. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF08-$FF09 | Player mode (00 = Sonic & Tails, 01 = Sonic, 02 = Tails, 03 = Knuckles, 04 = Blue Knuckles) (see also $EF4C) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF0A-$FF0B | Character selected in level select (00 = Sonic & Tails, 01 = Sonic, 02 = Tails, 03 = Knuckles, 04 = Blue Knuckles) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF0C-$FF0D | Unused, but cleared once. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF0E-$FF0F | Number of Kosinski compressed data pieces on the Kosinski decompression queue ($FF40-$FF5F) waiting to be decompressed to RAM. The most significant bit of this being set signifies a decompression is in progress. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF10-$FF37 | Kosinski queue processing routine register backup. Registers d0-d6 and a0-a2 are backed up here in case the Kosinski queue processing routine is interrupted by V-Int. They're restored the next time the processing routine is called. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF38-$FF39 | Kosinski queue processing routine status register backup. In case the processing routine is interrupted by V-Int, the SR is stored here and restored the next time the routine is called. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF3A-$FF3D | Kosinski queue processing routine program counter backup. In the instance of the processing routine being interrupted by V-Int, when V-Int is ready to return, the processing does not resume. Instead, by means of the subroutine at $1BF0, program resumption is forced to occur at $1D0C, and the actual overwritten program counter value gets stored here. Next time the processing routine is called, the routine at $1CFC kicks in, pushing this value and the stored SR onto the stack and executing an RTE, causing both to get restored and the processing to resume. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF3E-$FF3F | The Kosinski queue processing routine uses this to store words byte-swapped. It's used by the processing routine the same way the stack is used by the normal Kosinski decompression routine. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF40-$FF5F | The Kosinski decompression queue. Each entry consists of two longwords:
Since this is 32 bytes long, only 4 pieces can be stored on it at one time. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF60-$FF61 | Number of modules left to decompress in the current Kosinski Moduled archive. Bit 7 indicates that the current module has finished decompressing and can be DMA'd to VRAM. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF62-$FF63 | The decompressed size of the last module of the KosinskiM data divided by 2. All other modules have a fixed decompressed size of $1000. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF64-$FF7B | The KosinskiM decompression and DMA queue. Each entry consists of a longword followed by a word:
Like the decompression queue, this can also only store 4 pieces at a time. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF7C-$FF7D | Copy of controller 2, something to do with competition mode demos. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF7E-$FF7F | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF80-$FF81 | Unknown, used in the level select. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF82-$FF83 | Selected item in level select. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF84-$FF85 | Selected sound in sound test. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF86 | Option number in title screen. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF87-$FF89 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF8A | Competition mode monitor selection. If set, monitors are disabled. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF8B | Competition mode type (0 = grand prix, 1 = match race, -1 = time attack). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF8C-$FF8D | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF8E-$FF8F | Total amount of bonus added this frame. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF90-$FF91 | Used to store what music to resume after other music like the drowning music. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF92-$FF95 | Special Stage entry rings entered for this level. Each bit is a single entry ring, when that bit is set, the entry ring will not appear again. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF96 | State of the main character's secondary status bitfield when the last special stage was entered, used to restore any shield the character had when he entered the special stage and cleared once the shield is restored. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF97 | If set, the sprite and ring loaders will not clear the respawn table when the level loads. Used for returning from special and bonus stages. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF98-$FF99 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF9A | Apparent Zone in which the last starpole was hit (See $EE4E) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF9B | Apparent Act in which the last starpole was hit (See $EE4B) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF9C | Apparent Zone in which special stage or bonus stage was entered (See $EE4E) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF9D | Apparent Act in which special stage or bonus stage was entered (See $EE4B) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF9E | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FF9F | Blue Spheres challenge uses this to determine whether the header was "SEGA MEGA DRIVE" (1) or "SEGA GENESIS" (0) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFA0 | Set to 1 if the full Blue Sphere mode is available because Sonic & Knuckles is locked-on to Sonic 1; it's 0 for any other game | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFA1 | Unknown, something to do with blue spheres challenge. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFA2-$FFA5 | Map section IDs in Blue Sphere | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFA6-$FFA9 | Level number in Blue Sphere | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFAA, $FFAB, $FFAC, $FFAD | Unknown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFAE-$FFAF | 0 if locked on to Sonic 3; nonzero otherwise. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFB0 | Number of chaos emeralds | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFB1 | Number of super emeralds | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFB2-$FFB8 | Array of finished special stages. Each byte represents one stage:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFB9 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFBA | Flag that when set, prevents Sonic and Knuckles from transforming into super or hyper. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFBB | If this is set to 0, Sonic 3 special stages will run. If it's 1, Sonic & Knuckles special stages will run. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFBC | Title screen animation flag. Sonic 3 title screen uses the fullscreen Sonic animation to transition from SEGA to title screen. It uses 2 Plane A and Plane B nametables and switches between them after they have been updated. This flag keeps track of which one to transition to next. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFBD | Delay timer before the next animation transition. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFBE-$FFBF | Animation frame number for the title animation. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFC0-$FFC3 | Amount of score required for the next extra life. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFC4-$FFC7 | Amount of score required for the next extra life for player 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFC8-$FFC9 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFCA-$FFCD | Player 1's mappings address is stored here while in debug mode. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFCE-$FFCF | Player 1's VDP pattern index is stored here while in debug mode. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFD0-$FFD1 | Demo mode flag. Set when demo mode is active. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFD2-$FFD3 | Demo number. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFD4 | Blue Sphere flag. This is 1 in the standalone Blue Spheres game, and 0 in regular special stages. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFD5 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFD6-$FFD7 | Number of cycles between two V-ints. The purpose of this flag is not known, as the hardware always has specific processor speeds in 50hz and 60hz versions, so you could use the hardware version register to get the region. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFD8 | Hardware register value, specifically the region bits (bits 6 and 7).
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFD9 | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFDA-$FFDB | Debug mode flag. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFDC-$FFDF | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFE0 | Level select cheat flag. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFE1 | Slow motion cheat flag. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFE2-$FFE3 | Debug mode cheat flag. If this flag is set, holding A while entering level enables debug mode. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFE4-$FFE5 | Unused, but cleared and referenced in dead code. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFE6-$FFE7 | Unused, but cleared and referenced in dead code. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFE8-$FFE9 | 2P versus mode flag. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFEA | 2p mode player 1's character. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFEB | 2p mode player 2's character. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFEC-$FFEF | Unused | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFF0-$FFF1 | Must be $4EF9 (68k opcode for long jump) as this address is the vertical interrupt vector. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFF2-$FFF5 | Pointer to the current vertical interrupt routine. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFF6-$FFF7 | Must be $4EF9 (68k opcode for long jump) as this address is the horizontal interrupt vector. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFF8-$FFFB | Pointer to the current horizontal interrupt routine. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$FFFC-$FFFF | Contains the ASCII string "SM&K" to indicate that the checksum is correct. |
Object Status Table format
The starting offset in RAM for this list is $B000. The first object is always player 1; the second is always player 2. Each object is allocated a block of $4A bytes. Note that many of these variables are object-specific - for example, some of them only make sense for Sonic, and some only work on badniks.
Offset | Description | |||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
$00-$03 | Pointer to object code. Note that this pointer does not necessarily remain constant for a single object. | |||||||||||||||||||||||||||
$04 | Render flags. The bitfield looks like this:
| |||||||||||||||||||||||||||
$05 | Routine number. This is always an even value (i.e. it goes in units of 2) | |||||||||||||||||||||||||||
$06 | Height of the object, in pixels. | |||||||||||||||||||||||||||
$07 | Width of the object, in pixels. | |||||||||||||||||||||||||||
$08-$09 | Sprite priority, in units of $80 (00 = front). | |||||||||||||||||||||||||||
$0A-$0B | The lower 11 bits of this represent the starting art block. This is an index into an array of cells; to get the actual address, multiply by $20. Bits 14 and 13 are used to specify the default palette line the sprite uses, and bit 15 is the priority flag - if this is set, the sprite will be given high priority. | |||||||||||||||||||||||||||
$0C-$0F | Object's mappings offset. | |||||||||||||||||||||||||||
$10-$11 | If the object is Sonic, Tails or Knuckles, this is the X playfield coordinate. Otherwise:
| |||||||||||||||||||||||||||
$12-$13 | If the object is Sonic, Tails or Knuckles, this is the X subpixel playfield coordinate. Otherwise, it's unused. | |||||||||||||||||||||||||||
$14-$15 | If the object is Sonic, Tails or Knuckles, this is the Y playfield coordinate. Otherwise:
| |||||||||||||||||||||||||||
$16-$17 | If the object is Sonic, Tails or Knuckles, this is the Y subpixel playfield coordinate. Otherwise, it's unused. | |||||||||||||||||||||||||||
$18-$19 | X speed. | |||||||||||||||||||||||||||
$1A-$1B | Y speed. | |||||||||||||||||||||||||||
$1C-$1D | Potential speed (inertia). | |||||||||||||||||||||||||||
$1E | Height/2 | |||||||||||||||||||||||||||
$1F | Width/2 | |||||||||||||||||||||||||||
$20 | Animation number. | |||||||||||||||||||||||||||
$21 | Restart animation flag (when $21 is not equal to $20, animation restarts) | |||||||||||||||||||||||||||
$22 | Current animation frame to display. | |||||||||||||||||||||||||||
$23 | Current frame in animation script. | |||||||||||||||||||||||||||
$24 | Animation frame duration (time until next frame). | |||||||||||||||||||||||||||
$25 | Animation counter. | |||||||||||||||||||||||||||
$26 | Angle. $00 represents flat ground. $80 is the ceiling, $40 is a wall to the left of the object, $C0 is a wall to the right of the object. $20 is a 45 degree slope going down to the right, $E0 is a 45 degree slope going up to the right, and so on. | |||||||||||||||||||||||||||
$27 | Second angle (different axis). | |||||||||||||||||||||||||||
$28 | 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 seems to be a special thing for the starpole. SSSSSS is the size, lifted from a lookup table in the collision response routine. | |||||||||||||||||||||||||||
$29 | 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. | |||||||||||||||||||||||||||
$2A | Status bitfield.
Counting from the least significant bit:
| |||||||||||||||||||||||||||
$2B | Object shield reaction bitfield.
| |||||||||||||||||||||||||||
$2C | Object subtype. For example, the current monitor selected. Has a different meaning for Sonic, Tails and Knuckles. | |||||||||||||||||||||||||||
$2E-2F | Used as a timer/counter, upon completion the routine will jump to a pointer in $34. | |||||||||||||||||||||||||||
$34-$37 | Stores a code pointer branched to from various routines upon meeting certain conditions. | |||||||||||||||||||||||||||
$3B | If the RSS flag is set, this is the bit (0-7) to be cleared when the object is destroyed. See bit 2 of offset $2A above. | |||||||||||||||||||||||||||
$3C-$3D | If the RSS flag is set, this is the RAM address to be modified when the object is destroyed. See bit 2 of offset $2A above. | |||||||||||||||||||||||||||
$46-$47 | Used by child objects to point to their parent. | |||||||||||||||||||||||||||
$48-$49 | RAM location of the object's entry in the object respawn table. | |||||||||||||||||||||||||||
Variables specific to Sonic, Tails and/or Knuckles | ||||||||||||||||||||||||||||
Offset | Description | |||||||||||||||||||||||||||
$25 |
| |||||||||||||||||||||||||||
$2A | Status bitfield. Counting from the least significant bit:
You can add the hex values together to use multiple settings at once. Also notice that bits 1 and 2 are used in the character object as a second routine counter. | |||||||||||||||||||||||||||
$2B | Secondary status bitfield.
| |||||||||||||||||||||||||||
$2C | 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. | |||||||||||||||||||||||||||
$2D | Invert flipping flag. | |||||||||||||||||||||||||||
$2E | Object control flag. If bit 7 is not set, the character is under control of another object but can jump out (e.g. being carried by Tails), and if it is, the character is under control of another object and cannot jump out (e.g. LBZ tubes). | |||||||||||||||||||||||||||
$2F | Double jump flag. For Sonic:
For Tails:
For Knuckles:
| |||||||||||||||||||||||||||
$30 | Number of flip revolutions remaining. | |||||||||||||||||||||||||||
$31 | Number of flip revolutions per frame divided by 256. | |||||||||||||||||||||||||||
$32-$33 | Horizontal control lock. Counts down to 0, left and right control on the ground is locked unless it's 0. Used for springs and bumpers and falling down slopes. | |||||||||||||||||||||||||||
$34 | Remaining invulnerability time. Starts at $78 after Sonic is hit, and is decremented every frame until it reaches $00. | |||||||||||||||||||||||||||
$35 | Remaining time of invincibility. Decremented once every eight frames. | |||||||||||||||||||||||||||
$36 | Remaining time of Speed Shoes. Decremented once every eight frames. | |||||||||||||||||||||||||||
$37 | Some sort of bitfield. If bit 7 of this is set, whenever the player is hit, even if he does not have a shield the game will act like he does and he will just recoil instead of losing rings. If he actually has a shield, however, he will lose it, as the shield check takes precedence over this bit check. Used, for example, by the spinning tops in MGZ. | |||||||||||||||||||||||||||
$38 | Character ID:
| |||||||||||||||||||||||||||
$39 | Character looking up/ducking counter. Starts off at 0 and is incremented each frame the character is looking up/ducking. When this reaches $78, the camera starts to scroll. Reset to 0 upon release of the up/down button. | |||||||||||||||||||||||||||
$3A | Angle on ground in front of sprite. | |||||||||||||||||||||||||||
$3B | Angle on ground under sprite. | |||||||||||||||||||||||||||
$3C | Stick to convex surfaces flag. | |||||||||||||||||||||||||||
$3D | Set if charging a Spin Dash. | |||||||||||||||||||||||||||
$3E-$3F | Spin Dash counter. Cleared when the Spin Dash is started. After each subsequent "rev", $200 is added to the counter, which then rapidly decreases (the algorithm is to logically shift the value right by five bits and subtract the results from the original). It maxes out at $800. The game looks at the high-order byte to determine how fast the character should move after the dash is released. | |||||||||||||||||||||||||||
$40 | Set if jumping. | |||||||||||||||||||||||||||
$42-43 | RAM address of the last object Sonic stood on. | |||||||||||||||||||||||||||
$44 | Default height. | |||||||||||||||||||||||||||
$45 | Default width. | |||||||||||||||||||||||||||
$46 | The bit in the 16x16 entries in the 128x128 block mappings to check for top solidity. Is either $C (for the default collision layer), or $E (for the alternate collision layer). | |||||||||||||||||||||||||||
$47 | The bit in the 16x16 entries in the 128x128 block mappings to check for left/right/bottom solidity. Is either $D (for the default collision layer), or $F (for the alternate collision layer). | |||||||||||||||||||||||||||
Variables specific to dynamically reloaded sprites, excluding Sonic, Tails and Knuckles | ||||||||||||||||||||||||||||
$34 | Previous frame. | |||||||||||||||||||||||||||
$38-$3B | Pointer to uncompressed art. | |||||||||||||||||||||||||||
$3C-$3F | Pointer to dPLCs. | |||||||||||||||||||||||||||
$40-$41 | Address of art in VRAM (the same as starting art block * $20) |
References