Sonic the Hedgehog (16-bit)/RAM Editing

From Sonic Retro

(Redirected from SCHG:Sonic the Hedgehog/RAM Editing)
SCHG: Sonic the Hedgehog

Main System Memory Locations

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

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

RAM offset Description
$0000 - $A3FF Chunk mappings
$A400 - $A7FF Level layout (1 byte per chunk, $80 bytes per line, 8 lines for planes A and B interlaced)
$A800 - $A9FF 16 pixel scroll buffer primarily used for SLZ (4 bytes = one 16 pixel'd block scroll for FG and BG), this data is transfered/converter correctly to $CC00 - $CFFF (Scroll RAM cache).
$AA00 - $ABFF Nemesis decompression buffer
$AC00 - $AFFF Sprite table input. Consists of 8 different priority levels, each level taking up $80 bytes. The first word of each level is the number of objects currently in that priority level multiplied by 2, and the next $3F words are the addresses in RAM (inside the object RAM space) of the objects on that priority level. The information in this table is processed by BuildSprites to create the actual sprite table
$B000 - $C7FF Block mappings
$C800 - $CAFF Sonic's art buffer. Sonic's dynamic pattern reloading routine copies the relevant art over here, from where it is DMAed to VRAM every V-int.
$CB00 - $CBFF Sonic previous position array (used for invincibility stars and such)
$CC00 - $CF7F Scroll RAM cache (sent to VRAM every frame via DMA)
$CF80 - $CFFF Unused
$D000 - $D7FF Reserved object SST space
$D800 - $EFFF Main SST space
$F000 - $F5BF Flags used by the sound engine
$F5C0 - $F5FF Unused
$F600 Screen Mode
  • $00 - Sega Screen
  • $04 - Title Screen
  • $08 - Demo Mode
  • $0C - Normal Level
  • $10 - Special Stage
  • $14 - Continue Screen
  • $18 - Ending Sequence
  • $1C - Credits
$F601 Unused
$F602 Player's held buttons used in Sonic's moves, etc.
$F603 Player's pressed buttons used in Sonic's moves, etc.
$F604 Player 1's held buttons
$F605 Player 1's pressed buttons
$F606 Player 2's held buttons (unused)
$F607 Player 2's pressed buttons (unused)
$F608-$F60B Unused
$F60C-$F60D VDP command for mode register 2
$F60E-$F613 Unused
$F614-$F615 An universal counter, mainly used for time to display screens (like the title screen and the demo mode)
$F616-$F617 Plane A y-position for previous frame
$F618-$F619 Plane B y-position for previous frame
$F61A-$F61B Plane A x-position for previous frame
$F61C-$F61D Plane B x-position for previous frame
$F61E-$F61F Value of $F71C for previous frame
$F620-$F621 Value of $F718 for previous frame
$F622-$F623 Unused
$F624-$F625 Water's height onscreen. More specifically, VDP setting for the scanline H-int happens at. The value stored is $8Axx, where xx is the scanline number. This is moved to VDP each V-int.
$F626-$F627 Variables used in palette fade routines
$F628 Unknown
$F629 Unused
$F62A VBlank routine counter
$F62B Unused
$F62C Number of sprites counter
$F62D-$F631 Unused
$F632-$F633 Palette cycle offset counter
$F634-$F635 Palette cycle wait timer
$F636-$F639 Random number generator seed & result
$F63A-$F63B Game paused state
$F63C-$F63F Unused
$F640-$F641 Used to store VDP values, however is unnecessary.
$F642-$F643 Unused
$F644-$F645 Set when water palette should be transferred next HBlank
$F646-$F647 Water Height
$F648-$F64C Something to do with Water
$F64D Dynamic water routine counter
$F64E Water Direction
$F64F Is set when sound driver should be ran on HBlank (not enough time before it)
$F650-$F661 Used by SBZ palette cycling
$F662-$F67F Unused
$F680-$F683 Address queue for Pattern Load Cues
$F684-$F685 VRAM position to load next PLC'd tiles to
$F686-$F6FF Pattern Load Cues queue
$F700-$F701 Plane A x-position
$F702-$F703 Unused
$F704-$F705 Plane A y-position
$F706-$F707 Unused
$F708-$F709 Plane B x-position
$F70A-$F70B Unused
$F70C-$F70D Plane B y-position
$F70E-$F70F Unused
Used to scroll parts of background
Seems unused
$F720-$F721 Levels target left boundary (not implemented)
$F722-$F723 Levels target tight boundary (not implemented)
$F724-$F725 Levels target upper boundary (not implemented)
$F726-$F727 Levels target lower boundary
$F728-$F729 Levels left boundary
$F72A-$F72B Levels right Boundary
$F72C-$F72D Levels upper boundary
$F72E-$F72F Levels lower boundary
$F730-$F731 Written to by LevelSizeLoad, but seems to be unused
$F732-$F733 Upper level boundary +$240 (Seems to be unused)
$F734-$F739 Unused
$F73A-$F73B Copy of "Plane A X-position"
$F73C-$F73D Copy of "Plane A Y-position"
$F73E-$F73F Y-camera position, based on Sonic ($60 = default)
$F740-$F741 Unused (cleared by LevelSizeLoad)
$F742 Resize Level Routine Counter (Mainly Used For Act 3)
$F743 Unused
$F744 Scroll Hold Flag (set to disable all scrolling)
$F745 Unused
$F746 Unused (cleared by LevelSizeLoad)
$F747 Unused
$F748 Unused (cleared by LevelSizeLoad)
$F749 Unused
Unknown (Something to do with drawing the plane)
$F74F Unused
$F750 Used for screen deformation in REV01, Unused in REV00
$F751-$F753 Unused
Bitfields used by the scrolling engine
$F75C Unknown
$F75D-$F75F Unused
$F760-$F761 Sonic's Top Speed
$F762-$F763 Sonic's Acceleration
$F764-$F765 Sonic's Deceleration
$F766 Sonic's Dynamic PLC last frame number
$F767 Set to 1 if animation frame and $F766 was not same (In DPLC loading code)
$F768-$F76B Something to do with Sonic's angle
$F76C Object position loader's routine counter
$F76D Unused
$F76E-$F76F Copy of $F700 used by object position loader
$F770-$F77F Flags used by object position loader
$F780-$F781 Special stage's angle
$F782-$F783 Special stage's rotation speed
$F784-$F78F Unused
$F790-$F791 Demo's button press counter (Addition to proper address)
$F792 Seems to be duration to increment button press counter
$F793 Unused
$F794-$F795 Seems to be counter of some sort, for Ending sequence
$F796-$F799 Direct address of collision pointer of the level
$F79A-$F79B Palette cycle counter for Special Stage
$F79C-$F79D Palette cycle delay for Special Stage
$F79E-$F79F Unknown purpose (Something to do with special stage palette cycle)
$F7A0-$F7A1 Something to do with Special Stage BG deformation
$F7A2-$F7A3 Unused
$F7A4-$F7A5 Unknown (Something to do with Obj31)
$F7A6 Unused
$F7A7 Unknown
$F7A8-$F7A9 Sonic's recorded position array's counter
$F7AA Screen Lock Flag (Set to lock screen)
$F7AB Unused
$F7AC-$F7AF Flags Used to Make Sonic Run Around Loops (GHZ+SLZ)
$F7B0 Animated art tile offset counter
$F7B1 Animated art timer
$F7B2 Animated art tile offset counter
$F7B3 Animated art timer
$F7B4 Animated art tile offset counter
$F7B5 Animated art timer
$F7B6 Animated art tile offset counter
$F7B7-$F7BD Unused
$F7BE-$F7BF Big ring art offset counter
$F7C0 Unknown
$F7C1-$F7C6 (?) Array used by LZ and SBZ conveyor belt platforms
$F7C7 Unknown (Something to do with LZ wind tunnels)
$F7C8 Ignore Mode Flag (Ignoring all player control)
$F7C9 LZ wind tunnel flag (clear = enabled)
$F7CA Lock controls (Except jumping)
$F7CB Unknown (Something to do with SBZ Stomper object)
$F7CC Joypad Control Lock Flag
$F7CD If sonic jumped to big ring flag
$F7CE Used by Obj56 (SYZ/SLZ floating block) in REV01, Unused in REV00
$F7CF Unused
$F7D0-$F7D1 Enemies destroyed while in air
$F7D2-$F7D3 Time bonus
$F7D4-$F7D5 Ring bonus
$F7D6 Ring bonus counter update request (updates ring bonus counter)
$F7D7 Unused
$F7D8-$F7DF Used for LZ deformation in REV01, Unused in REV00
$F7E0-$F7EF Switch statuses
$F7F0-$F7FF Unknown array
$F800-$FA7F Sprite Table Buffer (sent to VRAM every frame via DMA)
$FA00-$FA7F Target underwater palette (is overwritten by the "BuildSprites" routine after being processed)
$FA80-$FAFF Normal underwater palette
$FB00-$FB7F Normal palette
$FB80-$FBFF Target palette (calling Pal_FadeTo will change the normal palette until it is the same as the target palette)
$FC00-$FCFF Destroyable object state table
$FC44 Error Message ID (If crash happens)
$FD00-$FDFF System Stack
$FE00 Stack pointer
$FE00-$FE01 Unused
$FE02-$FE03 Restart Level Flag
$FE04-$FE05 Level Timer
$FE06 Debug mode item pointer
$FE07 Unused
$FE08-$FE09 Object placement flag (Set if debug mode is being used)
$FE0A Debug mode speed timer
$FE0B Debug mode moving speed
$FE0C-$FE0F VBlanks occurred since start of the game (unused)
$FE10-$FE11 Zone-Act
$FE12 Lives
$FE13 Unused
$FE14-$FE15 Remaining Air (When underwater)
$FE16 Last Special Stage Entered
$FE17 Unused
$FE18 Continues
$FE19 Unused
$FE1A Time Over Flag
$FE1B Extra life flags (bits 1 and 2 are set if you have received the extra life at 100 and 200 rings)
$FE1C Lives Counter (Set to update lives total on screen)
$FE1D Ring Counter (Set to update rings total on screen)
$FE1E Time Counter (Set to update current time on screen)
$FE1F Score Counter (Set to update score total on screen)
$FE20-$FE21 Rings
$FE22-$FE25 Time
$FE26-$FE29 Score
$FE2A-$FE2B Unused
$FE2C Shield Flag (Set to take a single hit without losing rings)
$FE2D Invincibility Flag (Set to make Sonic invincible)
$FE2E Speed Shoes Flag (Set to activate speed shoe physics)
$FE2F Unused (cleared when level starts)
$FE30-$FE54 Lamppost Variables
  • $FE30 - Lamppost Counter
  • $FE31 - Copy of Lamppost Counter
  • $FE32-$FE33 - Copy of Sonic's X Position
  • $FE34-$FE35 - Copy of Sonic's Y Position
  • $FE36-$FE37 - Copy of Ring Counter
  • $FE38-$FE3B - Copy of Time Counter
  • $FE3C-$FE3D - Copy of Resize Level Routine Counter
  • $FE3E-$FE3F - Copy of Levels lower boundary
  • $FE40-$FE41 - Copy of Plane A X-position
  • $FE42-$FE43 - Copy of Plane A Y-position
  • $FE44-$FE4F - Copy of $F710-$F71D (Each other word)
  • $FE50-$FE51 - Copy of Water Height
  • $FE52 - Copy of Water Routine Counter
  • $FE53 - Copy of Water Direction
  • $FE54 - Copy of Lives Counter
$FE55-$FE56 Unused
$FE57 Emeralds
$FE58-$FE5D Array of collected emeralds
$FE5E-$FE9F (?) Unknown array (Something to do with platforms)
$FEA0-$FEBF Unused
$FEC0-$FEC9 Ring animation flags
$FECA-$FEEF Unused
$FEF0-$FEF3 Debug mode variables
  • $FEF0-$FEF1 - Copy of levels upper boundary
  • $FEF2-$FEF3 - Copy of levels bottom boundary
$FEF4-$FF0F Unused
$FF10-$FF37 Copy of $F700-$F72F and $F754-$F75B, used in "LoadTilesAsYouMove" routine
$FF38-$FF7F Unused
$FF80-$FF81 Timer for level select selection moving
$FF82-$FF83 Level select selection number
$FF84-$FF85 Level select sound ID
$FF86-$FFBF Unused
$FFC0-$FFC3 Copy of current score (Unused)
$FFC4-$FFDF Unused
$FFE0 Level select cheat
$FFE1 If is set, enables slow motion cheat
$FFE2 Debug cheat flag
$FFE3 Japanese credits cheat
$FFE4-$FFE5 Correct button press counter for level select cheat
$FFE6-$FFE7 C button press counter (Title Screen only)
$FFE8-$FFE9 Unused
$FFEA-$FFEB Unused (However is cleared on the Title Screen)
$FFEC-$FFEF Unused (Are overwritten by Sonic_Floor routine, but don't seem to have any use)
$FFF0-$FFF1 Demo mode flag
$FFF2-$FFF3 Demo number
$FFF4-$FFF5 Credits Index Number
$FFF6-$FFF7 Unused
$FFF8 Version register (Bits 6 and 7 of lower byte)
$FFF9 Unused
$FFFA-$FFFB Debug Flag (Set to enable debug mode)
$FFFC-$FFFF Checksum flag

Object Status Table Format

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

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

Counting from the least significant bit:

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

$28 byte Seconds of air left. Usually $1E; it decrements every second while the player is underwater. Beeps on $18, $13, and $0E. Countdown starts on $0B.
$29-$2F Unused (scratch RAM)
$30-$31 word Remaining invulnerability time. Starts at $0078 after Sonic is hit, and seems to decrement every frame until it reaches $0000.
$32-$33 word Remaining time of invincibility.
$34-$35 word Remaining time of Speed Shoes.
$36 byte Angle of ground at Sonic's front collision hot spot ($03 is "edge of ground")
$37 byte Angle of ground at Sonic's rear collision hot spot
$39 byte Unused.
$3A-$3B word Unused.
$3C byte Set if jumping.
$3D byte OST index of object currently being stood on. (multiply by $40 and add $D000 to get the object's address).
$3E-$3F word Control lock timer. Set to lock left and right controls after hitting a spring or running down a slope.
Boss Variables
Offset Size Description
$21 byte Hit counter. Number of hits it takes to defeat a boss.
$30 word X position
$38 word Y position
$3E byte Number of times to flash when hit
Sonic Community Hacking Guide
Sonic Music Hacking Guide | SonED2 Manual
Sonic the Hedgehog (16-bit) | Sonic the Hedgehog (8-bit) | Sonic Eraser | Sonic CD (prototype 510) | Sonic CD | Sonic CD (PC) | Sonic 2 (Nick Arcade prototype) | Sonic 2 (Simon Wai prototype) | Sonic 2 (16-bit) | Sonic 2 (8-bit) | Sonic 2 & Knuckles | Dr. Robotnik's Mean Bean Machine | Sonic Triple Trouble | Sonic 3 | Sonic & Knuckles | Sonic 3 & Knuckles | Sonic & Knuckles Collection | Sonic Crackers | Sonic 3D: Flickies' Island | Chaotix | Sonic R PC | Sonic Jam 6 | Sonic Advance | Sonic Advance 2 | Sonic Advance 3 | Sonic Battle | 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 | Shadow the Hedgehog | Sonic Riders | Sonic the Hedgehog (2006) | Sonic & Sega All-Stars Racing | Sonic Unleashed (Xbox 360/PS3) | Sonic Generations
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 | Subroutine Equivalency List | 68000 Instruction Set | 68000 ASM-to-Hex Code Reference | VDP Documentation | Official Sega 32X Documentation | Official Mega-CD Documentation | Official Sega Mega Drive Documentation