We've just updated MediaWiki and its underlying software. If anything doesn't look or work quite right, please mention it to us. --RanAS

F-Zero RAM Map

From SnesLab
Revision as of 04:28, 14 July 2019 by Catador (talk | contribs) (Slight rewording and $7E0092-$7E00D5 added)
Jump to: navigation, search

Here is a RAM Map for F-Zero that aims to be fairly comprehensible.

Data Types
Name Accepted Values Size Description
Angle16 0x0000 - 0xBFFF 16-bit An angle with extra fractional precision.

0x0000 = 0 degrees
0xBFFF ≃ 359.992675781 degrees
Only the high byte affects the gameplay, the low byte is there just for fractional precision.
(Each unit increments the real angle value by about 0.00732421875 degrees)

Angle8 0x00 - 0xBF 8-bit An angle without the fractional precision.

0x00 = 0 degrees
0xBF ≃ 358.125 degrees
(Each unit increments the real angle value by about 1.875 degrees)

CoordX 0x0000 - 0x1FFF 16-bit X coordinate value. These usually wrap around at 0x1FFF automatically.
CoordY 0x0000 - 0x0FFF 16-bit Y coordinate value. These usually wrap around at 0x0FFF automatically.


Zero Page (Direct Page)

The Direct Page register (DP) is fixed to #$0000 all the time.

Address Length Type Description
$7E0000 ?? bytes Misc. Scratchpad RAM. Used for various purposes, including: temporary storage, subroutine parameters, etc.
$7E0034 1 byte Sprites Used in the AI car graphics routine.

How many sprite tiles were needed to draw the AI car.
Stored to $7E11D0 when the graphics routine ends.

$7E003E 2 bytes Misc. Relevant value picked from the table at 7E:1076.
$7E0040 1 byte Flag "Frame done" flag. Set to zero at the start of the main loop.

When NMI happens, it's decremented to #$FF, unless the value was already non-zero (i.e. a lag frame occurred.)
This is used to make sure the gamestate runs once per frame.

$7E0041 2 bytes Pointer IRQ code pointer.

$8612 - Do nothing;
$8616 (V-Counter = 18) - Set transparent power bar color, then trigger next IRQ at V-Counter = 28, set IRQ code pointer $863C;
$863C (V-Counter = 28) - Set "horizon fog" color math settings, then trigger next IRQ at V-Counter = 47, set IRQ code pointer $865A;
$865A (V-Counter = 47) - Set BG mode to 7, then trigger next IRQ at V-Counter = 86, set IRQ code pointer $8673;
$8673 (V-Counter = 86) - Set player's shadow/finished rank color, then set the IRQ code pointer to $8612;
$8691 (V-Counter = $7E0043) - Set BG mode to 7, then set the IRQ code pointer to $8612.

$7E0043 2 bytes IRQ Scanline where the Mode7 BG starts. Used only for IRQ pointer $8691, on the race intro sequence.
$7E0045 1 byte Flag When the MSB is set, sound effects won't play. This is used to keep playing the "player wreckage" sounds when $7E0048 >= #$80.
$7E0046 4 bytes I/O SPC700 I/O ports. Various values can be written to play music or sound effects.
$7E004A 1 byte Misc. Number of cars currently on screen, multiplied by two. (A bit of a mystery still, but seems to be used in a loop that assigns sprite priorities based on their Y position)
$7E004B 2 bytes Sprites Index to OAM Table #1 ($7E0200) for routines that print characters/strings on screen.
$7E004D 1 byte Sprites Index to OAM Table #2 ($7E0420) for routines that print characters/strings on screen.
$7E004E 1 byte Sprites Used for bit-fiddling on OAM Table #2. Used in conjunction with $7E004D.
$7E004F 1 byte Hardware mirror Mirror of SNES register $2101.
$7E0050 1 byte Flag "Is the game drawing cars" flag. Non-zero = Yes.

This is used to correctly handle OAM DMA.

$7E0051 1 byte Counter "Global" frame counter. Always increments every frame (except lag frames), no matter what.

See also: $7E009A ("in-race" frame counter)

$7E0052 1 byte Misc. Player car type.

#$00 = Blue Falcon; #$01 = Wild Goose; #$02 = Golden Fox; #$03 = Fire Stingray.

$7E0053 1 byte Misc. Current race number.

From #$00 to #$04 in Grand Prix mode.
From #$00 to #$06 in Practice mode.

$7E0054 3 bytes Misc. Current gamestate (game mode).

The first byte is the "main" gamestate, the second byte is the "sub" gamestate and the third byte is the "sub-sub" gamestate.
This gamestate stuff is a complicated subject, which I plan to explain in more detail later.

$7E0057 1 byte Misc. Current difficulty setting.

#$00 = Beginner; #$01 = Standard; #$02 = Expert/Master (for Master, the flag at $7E0F3D is set)

$7E0058 1 byte Misc. Practice mode flag.

#$00 = Grand Prix mode; #$01 = Practice Mode

$7E0059 1 byte Misc. Number of spare machines (extra lives).
$7E005A 1 byte Misc. Used by most menus as current selected option.
$7E005B 1 byte Misc. "Is running pre-recorded race" flag.

#$00 = Player is in control; Other = Pre-recorded race is running.

$7E005C 1 byte Flag A flag related to color math effects.

When == #$00:

  • HDMA channels 1 and 3 are disabled;
  • $7E009B is stored to $2131;
  • $7E0E27 is treated as the red color intensity for color math and it should range from #$00 to #$1F. ($7E0E27 | #$20) is stored to $2132;
  • 7E:0E28 is treated as the green color intensity for color math and it should range from #$00 to #$1F. ($7E0E28 | #$40) is stored to $2132;
  • 7E:0E29 is treated as the blue color intensity for color math and it should range from #$00 to #$1F. ($7E0E29 | #$80) is stored to $2132;
  • IRQ is disabled.

When == #$01:

  • HDMA channels 1 and 3 are enabled. Channel 1 is used for Mode7 and BG1 horizon, channel 3 is used for the "horizon fog";
  • $212C is set to (#$13 ^ $7E005F);
  • $7E0E25 is stored to $2131;
  • $2132 is set to #$E0;
  • IRQ is enabled to trigger at V-Counter = 18, IRQ code pointer is set to $8616.

When > #$01:

  • HDMA channel 1 is enabled. Channel 1 is used for Mode7 and BG1 horizon;
  • HDMA channel 3 is disabled;
  • $212C is set to #$13;
  • IRQ is enabled to trigger at V-Counter = $7E0043, IRQ code pointer is set to $8691.
$7E005D 1 byte Hardware mirror Screen brightness and F-Blank flag. Mirror of SNES register $2100
$7E005E 1 byte Hardware mirror Enabled HDMA channels. Mirror of SNES register $420C
$7E005F 1 byte Flag Flags related to shown layers and HUD updating. Format: u--s4321

1 = Hide BG1; 2 = Hide BG2; 3 = Show BG3; 4 = Hide BG4 (unused, F-Zero never uses BG4); s = Hide sprites; - = Unused bit u = Stop updating HUD (rank, timer, score and speedometer)

$7E0060 1 byte Misc. Screen fade type.

#$00 = Not fading; #$01 = Fade-in; Other = Fade-out.

$7E0061 1 byte Misc. Screen fade delay. How many frames it takes to increment/decrement the screen brightness.
$7E0062 1 byte Misc. Screen fade timer. How many frames until the screen brightness is incremented/decremented.
$7E0063 1 byte I/O Controller 1 data (held buttons). Format: axlr----

a = A; x = X; l = L; r = R; - = Unused bits

$7E0064 1 byte I/O Controller 1 data (held buttons). Format: byetUDLR

b = B; y = Y; e = Select; t = Start; U = Up; D = Down; L = Left; R = Right.

$7E0065 1 byte I/O (Seems to be the exact same as $7E0063?) Used more often than $7E0063
$7E0066 1 byte I/O (Seems to be the exact same as $7E0064?) Used more often than $7E0064
$7E0067 1 byte I/O Controller 1 data (pressed buttons on current frame). Format: axlr----

a = A; x = X; l = L; r = R; - = Unused bits

$7E0068 1 byte I/O Controller 1 data (pressed buttons on current frame). Format: byetUDLR

b = B; y = Y; e = Select; t = Start; U = Up; D = Down; L = Left; R = Right.

$7E0069 1 byte I/O Controller 1 data (released buttons on current frame). Format: axlr----

a = A; x = X; l = L; r = R; - = Unused bits

$7E006A 1 byte I/O Controller 1 data (released buttons on current frame). Format: byetUDLR

b = B; y = Y; e = Select; t = Start; U = Up; D = Down; L = Left; R = Right.

$7E006B 1 byte Flag A flag related to windowing effects.

When == #$00:

  • $212E and $212F are set to #$00;
  • $7E0070 is stored to $2130;
  • HDMA channel 2 is disabled.

When == #$01:

  • HDMA channel 2 is enabled. Channel 2 is used for windowing effects, such as player's shadow and the big rank number when finishing a race;
  • $7E006C is stored to $4322 (16-bit, HDMA channel 2 table address);
  • $7E0E20 is stored to $7E0DE3;
  • $7E006E is stored to $212E;
  • $7E006F is stored to $212F;
  • $7E0070 is stored to $2130;
  • $7E0071 is stored to $2123;
  • $7E0072 is stored to $2124;
  • $7E0073 is stored to $2125.

When > #$01:

  • $7E006E is stored to $212E;
  • $7E006F is stored to $212F;
  • $7E0070 is stored to $2130;
  • $7E0071 is stored to $2123;
  • $7E0072 is stored to $2124;
  • $7E0073 is stored to $2125.
$7E006C 2 bytes Pointer Pointer to data for windowing effects (HDMA channel 2). Points to $7E0DD0 while racing, and to $7E0DF0 while showing the big rank number after finishing a race.
$7E006E 1 byte Hardware mirror Mirror of SNES register $212E.
$7E006F 1 byte Hardware mirror Mirror of SNES register $212F.
$7E0070 1 byte Hardware mirror Mirror of SNES register $2130.
$7E0071 1 byte Hardware mirror Mirror of SNES register $2123.
$7E0072 1 byte Hardware mirror Mirror of SNES register $2124.
$7E0073 1 byte Hardware mirror Mirror of SNES register $2125.
$7E0074 1 byte Misc. Index to $7E0EA0. Alternates between #$00 and #$10 every frame, to compensate for slowdowns (if it didn't alternate, the Mode7 layer would look jiterry when updating while the game was lagging).
$7E0075 2 bytes Hardware mirror BG1 horizontal scroll. Mirror of SNES register $210D.
$7E0077 2 bytes Hardware mirror BG1 vertical scroll. Mirror of SNES register $210E.
$7E0079 2 bytes Hardware mirror BG2 horizontal scroll. Mirror of SNES register $210F.
$7E007B 2 bytes Hardware mirror BG2 vertical scroll. Mirror of SNES register $2110.
$7E007D 2 bytes Hardware mirror Mode7 X center. Mirror of SNES register $211F.
$7E007F 2 bytes Hardware mirror Mode7 Y center. Mirror of SNES register $2120.
$7E0081 1 byte Misc. Mode7 rendering type.

#$00 = No Mode7; #$01 = Perspective effect; Other = Top-down view.

$7E0082 1 byte Misc. This value + #$80 is written to $4342 and $4372. Similarly, this value + #$A0 is written to $4352 and $4362. This updates the Mode 7 rotation through HDMA.

Similar to $7E0074, this address also alternates between #$00 and #$10 every frame to compensate for slowdowns.
Only used if $7E0081 == #$01.

$7E0083 1 byte Misc. Used after the "course zoom-in" on the race intro. This value is incremented every frame to raise the viewpoint pitch angle. When it reaches #$10, it stops increasing and the cars appear.
$7E0084 1 byte Hardware mirror Written to $4347. Only used if 7E:0081 == #$01.
$7E0085 1 byte Hardware mirror Written to $4357. Only used if 7E:0081 == #$01.
$7E0086 1 byte Hardware mirror Written to $4367. Only used if 7E:0081 == #$01.
$7E0087 1 byte Hardware mirror Written to $4377. Only used if 7E:0081 == #$01.
$7E0088 2 bytes Hardware mirror Mode7 matrix A and D. Mirror of SNES registers $211B and $211E
$7E008A 2 bytes Hardware mirror Mode7 matrix B. Mirror of SNES register $211C
$7E008C 2 bytes Hardware mirror Mode7 matrix C. Mirror of SNES register $211D
$7E008E 2 bytes Misc. Mode7 scaling. The Mode7 layer shrinks as this value increases. Only used if $7E0081 > #$01 (top-down view)
$7E0090 1 byte Misc. Current league.

#$00 = Knight League; #$01 = Queen League; #$02 = King League.

$7E0091 1 byte Empty Empty. Cleared on reset
$7E0092 1 byte Misc. Amount of VRAM DMA transfers to perform for the next frame. Used for the $7E0AE0 DMA queue.

Should only range from #$00 to #$04, since the DMA queue has only four entries.
See also: $7E009F (similar to this one, but for the $7E0420 DMA queue)

$7E0093 1 byte Flag Mode7 tilemap update flag. #$00 = don't update; #$01 = update only horizontally; Other = update both horizontally and vertically
$7E0094 2 bytes Misc. VRAM address for horizontal updates on the Mode7 tilemap.
$7E0096 2 bytes Misc. VRAM address for vertical updates on the Mode7 tilemap.
$7E0098 1 byte Misc. CGRAM update mode. #$00 = don't update CGRAM; #$01 = update CGRAM normally; Other = set the whole background (colors 0-127) to the color at $7E0E26.

When the value is greater than #$01, it decrements until reaching #$01 again. This is used for flashing effects upon car explosions

$7E0099 1 byte Empty Empty. Cleared on reset
$7E009A 1 byte Counter "In-race" frame counter. Increments every frame (except lag frames) while racing and the game is unpaused. Cleared on course load

See also: $7E0051 ("global" frame counter)

$7E009B 1 byte Hardware mirror CGADSUB settings. Mirror of SNES register $2131. Only used if $7E005C is zero
$7E009C 1 byte Hardware mirror CGADSUB settings. Mirror of SNES register $2131. Used for the "horizon fog"
$7E009D 1 byte Hardware mirror CGADSUB settings. Mirror of SNES register $2131. Used for the player's shadow and big finish rank
$7E009E 1 byte Flag Flag used to force a visual update on a landmine tile that exploded. Non-zero = update tile at X position $7E0CFA and Y position $7E0CFC
$7E009F 1 byte Misc. Amount of VRAM DMA transfers to perform for the next frame. Used for the $7E0420 DMA queue.

This is a bit different from $7E0092, due to the fact that the $7E0420 DMA queue can be interpreted in two different ways.
When the MSB clear, the DMA queue is interpreted normally (same functionality as the $7E0AE0 DMA queue, but structured differently.)
When the MSB is set, the DMA queue is interpreted as a "fill with byte," and each entry in the DMA queue occupies four bytes.
For more information, see the description of $7E0420.

$7E00A0 2 bytes Misc. A copy of the fractional part of the player's X position ($7E0B80,) actually unused
$7E00A2 2 bytes CoordX Related to camera's X position

(Player's X position, minus #$0200)

$7E00A4 2 bytes Misc. A copy of the fractional part of the player's Y position ($7E0BA0,) actually unused
$7E00A6 2 bytes CoordY Related to camera's Y position

(Player's Y position, minus #$0200)

$7E00A8 2 bytes CoordX Related to camera's X position

(Value at $7E00A2, plus value at $0AED00 table)

$7E00AA 2 bytes CoordY Related to camera's Y position

(Value at $7E00A6, plus value at $0AED00 table)

$7E00AC 1 byte Angle8 Camera's facing
$7E00AD 1 byte Misc. Amount of checkpoints present in the current course
$7E00AE 1 byte Misc. High byte of the starting point's X position
$7E00AF 1 byte Misc. High byte of the starting point's Y position
$7E00B0 2 bytes Pointer 16-bit pointer to bank $7F. Points to the course chunks table (either #$4C00 or #$4E00)
$7E00B2 2 bytes Empty Empty. Cleared on reset
$7E00B4 2 bytes Misc. Something to do with X position after finishing a race first place, when the camera stops following the AI car. Still not understood
$7E00B6 2 bytes Misc. Something to do with X position after finishing a race first place, when the camera fully turns while following the AI car. Still not understood
$7E00B8 1 byte Misc. Current screen text. Format: rplLfyws.

r = Reverse; p = Power Down; l = Limit X; L = X laps left; f = Final lap; y = You lost; w = You won/Goal in; s = Special (spaceship, "READY." and "GO!!" sprites)
Lower bits have more priority.

$7E00B9 1 byte Flag "Push start" text flag. Non-zero = show text
$7E00BA 1 byte Misc. Last screen text shown. Used to clear this bit from $7E00B8 when the $7E00BB timer runs out
$7E00BB 1 byte Counter Screen text timer. Decrements every frame until reaching zero.

However, when showing "You lost," "You won," or "Goal in," this value is incremented and is not taken into consideration.

$7E00BC 1 byte Misc. Offset to $00AFF8 table (screen text code pointer) for the last shown screen text. This is used so the game knows if the screen text was already being shown or if it needs to be initialized
$7E00BD 1 byte Misc. Number of tiles used on the current screen text, multiplied by 8. Used to address OAM.

Note that when the text flashes and goes away temporarily, this value becomes zero

$7E00BE 2 bytes Timer GP ending timer. After finishing the final race of a Grand Prix, this value is set to #$1000. This value is decremented every frame until it reaches #$017C, at which time it is set to #$003B.

When this value is #$003B, the screen starts to fade out. When this value is #$0020, the music starts to fade out.

$7E00C0 1 byte Timer Race timer (minutes)
$7E00C1 1 byte Timer Race timer (seconds)
$7E00C2 1 byte Timer Race timer (centiseconds)
$7E00C3 1 byte Misc. Race finish state. Format: lefcr??h

l = Race lost; e = Exploded; f = Race finished, follows AI car based on finish rank; c = Camera follows AI car indefinitely; ? = Unknown (possibly unused); h = Horizon moves according to camera's X position, not facing

$7E00C4 1 byte Empty Empty. Cleared on reset
$7E00C5 1 byte Angle8 Facing of the player's current checkpoint
$7E00C6 1 byte Empty Empty. Cleared on reset
$7E00C7 1 byte Misc. Player surface flags. Format: irlp----

i = Ice; R = Right-push tile; L = Left-push tile; p = Pit area; - = Unused

$7E00C8 1 byte Misc. Player's invincibility frames
$7E00C9 2 byte Misc. Player's machine power. The game actually allows this value to be a negative number, which is very odd
$7E00CB 1 byte Empty Empty. Cleared on course load
$7E00CC 1 byte Timer How many frames until the spaceship starts to go away. Set to #$10 while on pit areas. Decrements every frame when outside pit areas. When this value is zero, $7E00F3 starts to decrement
$7E00CD 1 byte Timer A general purpose timer. Used in a multitude of situations
$7E00CE 1 byte Misc. Has four purposes:
  • Screen Y position offset for the cars before the race countdown;
  • Index to the $0AEF80 (OAM data for the "GO!!" sprites);
  • How many lap results are being shown on screen. Also accounts for the "Totals" row;
  • Facing sprite of the car being selected in the car select screen.
$7E00CF 1 byte Timer Timer for the player explosion animation. Starts at #$00 and increments every frame until #$30. Used to play effects like flashing colors and etc.
$7E00D0 1 byte Misc. Directly related to the "malfunction effect" animation timer ($7E0F3C.) Increments every frame until reaching a certain value when executing the animation (still not fully understood)
$7E00D1 1 byte Misc. 16-bit indexer for player data. This is actually the value from $7E0052, multiplied by two
$7E00D2 1 byte Misc. Stored to $7E040C. Determines whether to show one or two digits for the current rank. #$00 = Two digits; #$0F = One digit
$7E00D3 2 bytes Empty Empty. Cleared on reset
$7E00D5 2 bytes Misc. Player turning stage. Increases when turning left, decreases when turning right. Zero means not turning.

When turning left:
- Increases until reaching #$0E if not sharp-cornering, if sharp-cornering it's set to #$10. Decreases when not turning left.
When turning right:
- Decreases until reaching #$F2 if not sharp-cornering, if sharp-cornering it's set to #$F0. Increases when not turning right.

Invalid values lead to weird sprite animations and turning speed

This is still a work-in-progress! More will be added later, and descriptions will be made clearer as time goes on.