Actions

SCHG

Sonic the Hedgehog 2 (16-bit)/RAM Editing

From Sonic Retro

Revision as of 14:04, 5 August 2007 by Xenowhirl (talk | contribs) (Main System Memory Locations)


Sonic Community Hacking Guide
Sonic the Hedgehog 2 (16-bit)
Art
Objects
Levels
Text
Music
RAM
Miscellaneous

RAM Hacking

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 Metablock table
$8000 - $8FFF Level layout
$9000 - $A9FF Block table
$AA00 - $AFFF Decompression buffer
$B000 - $D5FF Object attribute table
$D600 - $D8FF Primary collision index
$D900 - $DBFF Secondary collision index
$E000 - $E3FF Horizontal scroll buffer
$E500 - $E5FF Player 1's invincibility star position table
$E600 - $E6FF Player 2's invincibility star position table
$EE00-$EE01 Camera's X position, as measured from the top left corner of the Act.
$EE04-$EE05 Camera's Y position from the same point.
$EE06-$EE0B Unknown
$EE0C-$EE0D Variable used by the software scroll managers. Its exact purpose is not known.
$EE0E-$EEC5 Unknown
$EEC6-$EEC7 Screen Y end location for Sonic; the maximum value for camera Y position.
$EEC8-$EEC9 Screen X start location for Sonic; minimum value for camera X position. Should be 0.
$EECA-$EECB Screen X end location for Sonic; should be at least $30 less than the end of the level, otherwise, Sonic will fall off the screen.
$EECC-$EECD Screen Y start location. Note that if $FF00 is placed in both the start and the end, the screen will be Y wrapped. Y wrapping should not be used on levels with water - note what happened in the beta's Hidden Palace Zone.
$EECE-$EECF Maximum camera scroll speed
$EEDF Routine counter for Dynamic Screen Resizing. (Dynamic Level Events)
$EEF8-$EEF9 Screen X start location for Tails; minimum value for camera X position. Should be 0.
$EEFA-$EEFB Screen X end location for Tails; should be at least $30 less than the end of the level, otherwise, Tails will fall off the screen.
$EEFE-$EEFF Screen Y end location for Tails; the maximum value for camera Y position.
$F600 Master level trigger. Tells the game what it should be doing. Values:
  • $00 - Sega logo
  • $04 - Title screen
  • $08 - Demo (return to title screen at 27 seconds)
  • $0C - Normal level (Level loop, when it has been loaded)
  • $10 - Special stage
  • $14 - Continue screen
  • $18 - 2P vs. result
  • $1C - 2P vs. level select
  • $20 - Game end sequence
  • $24 - Options menu
  • $28 - Level select

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...

$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 custcene 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:
  • Bit 0 - Up
  • Bit 1 - Down
  • Bit 2 - Left
  • Bit 3 - Right
  • Bit 4 - B
  • Bit 5 - C
  • Bit 6 - A
  • Bit 7 - Start

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.
$F648-$F649 Current water level. Should be a valid Y-axis value. Remember, the top of the level is $0000.
$F650-$F651 The level that the water should be at. If this is different than the value above, the water will move until they are the same.
$F652 Water level change speed. If set to $00, the water level won't change.
$F65E Super Sonic palette counter. Decremented with every frame. How it works, exactly, is not known.
$F65F Sets the rotating palette for Super Sonic.
$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.
$F670 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.
$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.
$F760-$F761 Sonic's top speed
$F762-$F763 Sonic's acceleration
$F764-$F765 Sonic's deceleration
$F76C Object placement function's subroutine counter
$F76E-$F76F Unknown
$F770-$F773
$F774-$F777
$F778-$F77B
$F77C-$F77F
Sprite loading addresses. Tells the game where in the ROM to get sprite info.
$F780-??? Something
$F78C-$F78D Unknown
$F7AA Seems to be clear during normal play, but set to some value during a boss fight. That value may be the current Zone number.
$F7CC Controller lock. Normally the player object overwrites $F602 with the actual controller state, but setting this flag will prevent that. Used when the game will supply its own movement script.
$F7DA Counts the number of times the camera has scrolled to the right by one full screen width from its previous position - initial value is $FF.
$F7DB Unknown (may be unused)
$FC00 - $FCFF Object respawn table
$FE00 Start of the 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 incermented.
$FE06 Object currently selected in debug mode.
$FE09 Object placement mode flag.
$FE10 The current Zone. This is the value assigned to the Zone, not its position in the level list.
$FE11 Act number
$FE12 Number of lives.
$FE16 Current special stage.
$FE18 Number of continues.
$FE19 Super Sonic flag. Setting this will load the Super 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.
$FE1B This bitfield tells the game if the player has collected extra lives from rings.
  • Bit 0 - 100 rings life collected
  • Bit 1 - 200 rings life collected
  • Bit 2 - Unused
  • Bit 3 - Unused
  • Bit 4 - Unused
  • Bit 5 - Unused
  • Bit 6 - Unused
  • Bit 7 - Unused
$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 Ring count
$FE23 Minutes on clock. Should not go above $09, or the clock will look like shit.
$FE24 Seconds. This one shouldn't go above $3B, for the same reason.
$FE25 Milliseconds. I don't know what'll happen if this goes out of range, but it's probably not good.
$FE26-$FE29 Score (divided by 10)
$FE30 Greatest reference number of passed star poles
$FEC0-$FEC1 Tails's max speed
$FEC2-$FEC3 Tails's acceleration
$FEC4-$FEC5 Tails's deceleration
$FEC6 Tails's lives in 2P mode
$FEC7 This bitfield tells the game if the player has collected extra lives from rings. Used for Tails in 2P mode.
  • Bit 0 - 100 rings life collected
  • Bit 1 - 200 rings life collected
  • Bit 2 - Unused
  • Bit 3 - Unused
  • Bit 4 - Unused
  • Bit 5 - Unused
  • Bit 6 - Unused
  • Bit 7 - Unused
$FEC9 Flag determines if the rings counter needs to be updated. Used for Tails in 2P mode.
$FED0 Tails's rings in 2P mode.
$FF40-$FF41 Number of rings to collect before a perfect is scored
$FF70-$FF71 Player in game (at the start of the game, $FF72 is copied over to $FF70, so they're mostly identical)
$FF72-$FF73 Player option (Sonic and Tails - 0, Sonic alone - 1, Tails alone - 2)
$FF74-$FF75 2P mode items (all kinds items - 0, teleport only - 1=<)
$FF82-$FF83 Item in level select menu that's selected (set to 16 to see the HPZ picture)
$FF84-$FF85 Sound currently selected in sound test; value retained when options menu is exited
$FF86 Selection on Title Screen
$FF88 Selection on 2 Player Level Select Menu
$FF8C Box slected in options menu
$FF90-$FF91 Zone music currently playing. Used for quick access when switching music.
$FFB0 Special stage completed flag
$FFB1 Number of emeralds collected so far
$FFB2-$FFB8 Array of finished special stages. Each byte represents one stage.
$FFD0 Level select flag
$FFD1 Slow motion flag
$FFD4-$FFD5 Number of correct sounds that have been played for the level select oe debug codes
$FFD6-$FFD7 Same as $FFD4, except it's for the 14 continues or 7 emeralds codes
$FFD8-$FFD9 2P mode flag
$FFE1 Play specified sound effect. Not sure how it works.
$FFE4 Play specified music. These are the actual playlist values, NOT the sound test values. To convert from sound test to playlist, add $80 to the sound test value. For example, putting in $96 here will play the Super Sonic music; putting in $97 will play the invincibility music.
$FFF0-$FFF1 Demo mode flag
$FFFA Debug mode flag

Object Status Table Format

The starting offset in RAM for this list is $B000. The first object is always Sonic; the second is always Tails. After this, there is a gap, and the list picks up again at $B400. Each object is alloted a block of $40 bytes. I will use the beginning of a block as a reference point. 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 Object number. See object list above.
$01 Action flags. The bitfield looks like this:
  • Bit 0 is the horizontal mirror flag. If set, the object will be flipped on its horizontal axis.
  • Bit 1 is the vertical mirror flag.
  • Bit 2 is the coordinate system flag. If clear, the object will be positioned by absolute screen coordinates. This is used for things like the HUD and menu options. If set, the object will be positioned by the playfield coordinates, i.e. where it is in a level. Sonic and Tails use both positioning systems (though I don't know how Tails uses it in a Sonic and Tails game).
  • Bits 3, 4, and 5 are either unused, or their purpose is unknown.
  • Bit 6 is not used in this game.
  • Bit 7 is the draw object flag. It will be set if the object was onscreen when it came time to draw things. Otherwise, it is clear. There should be no reason to edit this flag, but it's good to know what it does.
$02-$03 Starting art block. This is an index into an array of cells; to get the actual address, multiply by $20.
$04-$07 Object's mappings offset
$08-$09 If the object is Sonic or Tails, this is the X playfield coordinate. Otherwise:
  • If in playfield positioning mode, it is the X playfield coordinate.
  • If in screen postioning mode, it is the screen coordinate.
$0A-$0B If the object is Sonic or Tails, this is the X screen coordinate. Otherwise:
  • If in playfield positioning mode, it is unused.
  • If in screen positioning mode, it's the Y screen coordinate.
$0C-$0D If the object is Sonic or Tails, this is the Y playfield coordinate. Otherwise:
  • If in playfield positioning mode, it is the Y playfield coordinate.
  • If in screen positioning mode, it is unused.
$0E-$0F If the object is Sonic or Tails, this is the Y screen coordinate. Otherwise:
  • It's unused.
$10-$11 X speed
$12-$13 Y speed
$14-$15 Potential speed (inertia).
$16 Height/2
$17 Width/2
$18 Sprite priority (00 = front).
$19 Width of the object, in pixels
$1A Current animation frame to display.
$1B Current frame in animation script.
$1C Animation number.
$1D Restart animation flag (when $1D is not equal to $1C, animation restarts)
$1E Animation frame duration (time until next frame).
$20 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.
$21 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 Status bitfield.

Counting from the least significant bit:

Bit Hex Description
0 $01 X Orientation. Clear is left and set is right.
1 $02 Y Orientation. Clear is right-side up, and set is upside-down
2 $04 Unknown or unused.
3 $08 Set if Sonic is standing on this object.
4 $10 Set if Tails is standing on this object.
5 $20 Set if Sonic is pushing on this object.
6 $40 Set if Tails is pushing on this object.
7 $80 Unknown or unused.
Note that these bits have different meanings for Sonic (see below).
$23 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 Routine counter.
$25 Second routine counter. This is used for some of the more complicated objects.
$26-$27 Angle.
$28 Object subtype. For example, the current monitor selected. See the Object List above for values. Has a different meaning for Sonic and Tails.
Object-specific variables
Offset Description
$22 Sonic and Tails: Special bitfield. Counting from the least significant bit:
Bit Hex Description
0 $01 Orientation. Clear is left and set is right.
1 $02 Set if Sonic/Tails is in the air (jump counts).
2 $04 Set if jumping or rolling.
3 $08 Set if Sonic/Tails 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.
5 $20 Set if pushing something.
6 $40 Set if underwater.
7 $80 Unused.

You can add the hex values together to use multiple settings at once. Also notice that bits 1 and 2 are used in the character object as a second routine counter.

$28 Sonic and Tails: 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.
$2B Sonic and Tails: Another bitfield.
Bit Hex Description
0 $01 Shield flag. Can be set to create the effect of having a shield, though the graphics will not be loaded.
1 $02 Sets invincibility. Behaves like you would expect. No graphics are loaded when set manually.
2 $04 Speed Shoes flag. (Doesn't have visible effect in game)
3 $08 Unused
4 $10 Unused
5 $20 Unused
6 $40 Unused
7 $80 Sets infinite inertia. While Sonic is in collision with the ground, he will continue moving in the same direction and at the same speed that he was moving before (even if that speed was zero). You can still jump and control him in midair. (A few movement routines are skipped if it's set, which produces this effect.)
$2F Sonic and Tails: Unknown, may have something to do with slope resistance.
$30-$31 Sonic and Tails: Remaining invunerability time. Starts at $0078 after Sonic is hit, and seems to decrement every frame until it reaches $0000.
$32-$33 Sonic and Tails: Remaining time of invincibility.
$34-$35 Sonic and Tails: Remaining time of Speed Shoes.
$36 Sonic and Tails: Seems to be related with the collision block boundaries (this isn't a flag)
$37 Sonic and Tails: Seems to be related with the collision block boundaries (the opposite side of $36) (this isn't a flag)
$39 Sonic and Tails: Set if charging a spindash.
$3A-$3B Sonic and Tails: Spindash counter. Cleared when the spindash 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.
$3C Sonic and Tails: Set if jumping.
$3F Sonic and Tails: Unknown, seems to have something to do with collision.


Sonic Community Hacking Guide
General
SonED2 Manual | Subroutine Equivalency List
Game-Specific
Sonic the Hedgehog (16-bit) | Sonic the Hedgehog (8-bit) | Sonic CD (prototype 510) | Sonic CD | Sonic CD (PC) | Sonic CD (2011) | Sonic 2 (Simon Wai prototype) | Sonic 2 (16-bit) | Sonic 2 (Master System) | Sonic 3 | Sonic 3 & Knuckles | Chaotix | Sonic Jam | Sonic Jam 6 | Sonic Adventure | Sonic Adventure DX: Director's Cut | Sonic Adventure DX: PC | Sonic Adventure (2010) | Sonic Adventure 2 | Sonic Adventure 2: Battle | Sonic Adventure 2 (PC) | Sonic Heroes | Sonic Riders | Sonic the Hedgehog (2006) | Sonic & Sega All-Stars Racing | Sonic Unleashed (Xbox 360/PS3) | Sonic Colours | Sonic Generations | Sonic Forces
Technical information
Sonic Eraser | Sonic 2 (Nick Arcade prototype) | Sonic CD (prototype; 1992-12-04) | Dr. Robotnik's Mean Bean Machine | Sonic Triple Trouble | Tails Adventures | Sonic Crackers | Sonic 3D: Flickies' Island | Sonic & Knuckles Collection | Sonic R | Sonic Shuffle | Sonic Advance | Sonic Advance 3 | Sonic Battle | Shadow the Hedgehog | Sonic Rush | Sonic Classic Collection | Sonic Free Riders | Sonic Lost World
Legacy Guides
The Nemesis Hacking Guides The Esrael Hacking Guides
ROM: Sonic 1 | Sonic 2 | Sonic 2 Beta | Sonic 3

Savestate: Sonic 1 | Sonic 2 Beta/Final | Sonic 3

Sonic 1 (English / Portuguese) | Sonic 2 Beta (English / Portuguese) | Sonic 2 and Knuckles (English / Portuguese)
Move to Sega Retro
Number Systems (or scrap) | Assembly Hacking Guide | 68000 Instruction Set | 68000 ASM-to-Hex Code Reference | SMPS Music Hacking Guide | Mega Drive technical information