The current URL is datacrystal.tcrf.net.
Metroid/RAM map
This RAM map for Metroid is primarily based on the disassembly by Dirty McDingus, which is based on the disassembly by SnowBro. Addresses are given in hex. Other numbers generally use a dollar sign ($) to denote hexadecimal. For two-byte values, such as pointers, a "16" will follow the address. Any other type of data (i.e. 24-bit values or structures) list each byte separately.
System RAM is organized by page ($100 byte blocks). Cartridge RAM (WRAM) isn't really very organized at all.
Zero Page ($0000)
Zero page (ZP) generally contains commonly used variables and pointers.
Address Usage
0C 16 Used for indirect jumping
12 Controller 1 changed buttons
13 Controller 2 changed buttons
14 Controller 1 pressed buttons
15 Controller 2 pressed buttons
16 Controller 1 held auto-repeating buttons
17 Controller 2 held auto-repeating buttons
18 Controller 1 auto-repeat timer
19 Controller 2 auto-repeat timer
1A NMI flag - Zero indicates NMI in progress
1B PPU data flag - 1 indicates there is ppu data to ready to be processed during NMI
1C PPU pal data flag - set to (pal # + 1) to indicate that a palette needs to be updated
1D Engine mode (0 = game, 1 = title/password)
1E Game mode (5 = paused, 3 = playing, other values might be used during init or for dying)
1F Title mode (similar to Game mode for gameplay)
20 16 Routine to run after timer expires (?)
23 Current ROM bank loaded into $8000-$BFFF slot
24 Bank swap pending (1 = yes)
25 Stores value to be loaded into MMC1 Register 0
28 Stores bits 3 and 4 for MMC1 register 3 (should always be 0 under normal conditions)
29 Counts down from 9 to 0 (by 1 each frame)
2A Timer. Counts down (1 per frame) when non-zero.
2B Timer. Counts down (1 per frame) when non-zero.
2C Timer. Counts down (10 per frame) when non-zero.
2D Frame counter. Increments each frame, wraps around to zero.
2E Random number 1
2F Random number 2
30 Initialized but unused
31 Paused (1 = yes)
Used for decoding room layouts into a block or room-layout-RAM:
33 16 Room data pointer
35 16 Structure data pointer
37 16 Output pointer into room data while decoding
39 16 Pointer to start of room data block
3B 16 Ptr to the pointer table for (compressed) room layouts
3D 16 Ptr to the pointer table for structures
3F 16 Ptr to the combo (a.k.a. macro/metatile/TSA/etc) definitions
41 16 Ptr to the pointer table for enemy animation sequences
43 16 Ptr to second half of above table
45 16 Ptr to the pointer table for enemy sprite layouts (layout = position of each tile)
47 16 Ptr to the pointer table for enemy sprite tile numbers (tiles to be used with above layouts)
49 Current scroll direction (0-3 for Up, Down, Left, Right)
4A Temporary scroll direction variable
4B Index of object currently being processed (i.e. bullet, missile, or most anything that's not an enemy or an item)
4C "ItemIndex" ?
4D Samus direction: 0 = right, 1 = left
4E Direction samus passed through door
4F Y position on map
50 X position on map
51 X position on screen
52 Y position on screen
53 Timer for footstep sounds
55 Set to 1 if samus is the object currently being processed
56 0 = not in a door
1 = in a right-side door
2 = in a left-side door
3 = scrolling up to center a door before room transition
4 = scrolling down to center a door before room transition
57 1 = Entered right-side door from horizontal area
2 = entered left-side door from horizontal area
3 = entered door in vertical area, screen needs to be centered
4 = entered door in vertical area, screen is centered
58 Bit 4 causes scrolling direction to be toggled after transition.
Bit 5 causes scrolling to become horizontal after transition
Lower nibble temporarily stores samus' state when she entered door
59 Timer for delay before room transition
5A Index of room layout being loaded
5B Indexer for sprite RAM
64 Samus in lava (1 = yes)
Object processing:
65 Timer
67 Palette number for room object
68 Palette number for room
69 Temporary X variable
6A Temporary Y variable
6B Object attributes
6C Door on name table 3? (used to stop scrolling when a door is encountered)
6D Door on name table 0?
Health is stored as fixed-point BCD (###.#)
6E TENTHS of health to be added or subtracted (when routine to add or subtract health is called)
6F TENS of health to be added or subtracted
70 Invincibility blink timer
71 Updating projectile? (1 = yes)
72 Damage push back direction (= 0 left, 1 = right, FF = none)
73 Used with exploding bomb so that the invincibility timer doesn't make you blink. FF = blink when hit, 00 = don't blink when hit.
74 Current level ($10 = Brinstar, $11 = Norfair, $12 = Kraid, $13 = Tourian, $14 = Ridley)
75 Initialized, usused
76 Set to indicate palette will be toggled
79 $00 = Item room music not playing
$01 = Play item room music after room transition
$80 = Stop item room music after room transition
$81 = Item room music is playing
7A Write ending message (1 = yes) (?)
7B Credits rolling? (1 = yes)
7C Indicates if ending sprites are done loading
7D Gameplay: Is samus standing on a frozen enemy (1 = yes)
Ending: Index to samus sprite graphic
7E Attribute of some sprites (?)
7F Color count index (?)
80 Current page of credits
81 0=show end message, 1=erase end message.
82 Color change counter
83 Address pointer to Samus hand waving sprites in end.
84 Stores length of wave sprite data (#$10).
92 Metroid on Samus (1 = yes)
93 Maximum # of missiles samus can grab in current room (resets after you go through as door)
94 Maximum # of health pickups samus can grab in current room
95 # of missiles samus has grabbed in current room
96 # of health pickups samus has grabbed in current room
98 0 = nothing
1 = Mother brain in room
2 = Mother brain got hit
3 = Mother brain dying
4 = Mother brain disappearing
5 = Mother brain gone
6 = "Time bomb set"
7 = Time-bomb exploded
8 = Init mother brain
9, A = Mother brain already dead
99 # of times mother brain has been hit (dies at 32 hits)
A0 Skree projectile table, 4 bytes per projectile. The projectile directions are, in order, left, top left, top right, right
- AF byte 0 : despawn timer, byte 1 : room Y position, byte 2 : room X position, byte 3 : screen number (boolean)
B7 Written to during title screen, never read
B8 "
BB "
Title screen:
BC "Cross-hair" sprite speed-up delay
BD 32-frame delay before "cross-hair" sprite animation
BF 1 = second crosshair animation
C0 1 = Flash screen during crosshair animation
C1 Palette data index
C2 Screen flash palette index
C3 Indexer for start twinkle data
C4 Palette fade Indexer
C5 Unused
C6 Cross-hair sprite index
C7 1 = Draw crosshair on screen
C8 Set to 0 after sprite RAM load complete
C9 Unused
- D7
D8 After all title routines run twice, restarts intro music. (?)
EA Temp storage for data of first address sound channel
EB Desired address number in VolumeCntrlAdressTbl
F0 Stores A and B button status in AreaInit. Never used.
FA If bit 3 is set, PPU set to horizontal mirroring
if bit 3 is clear, PPU is set to vertical
No other bits seem to matter.
FC Scroll Y
FD Scroll X
FE PPU Register $2000
FF PPU Register $2001
Stack ($0100)
$0100 - $01FF is reserved for the hardware stack, but since the game does not need to use the entire stack, some of this space is used for game variables. The hardware stack starts at $01FF and works backward.
Address Usage 0106 16 Health - BCD, fixed point (###.#) 0106 Low nibble stores tenths of health, upper nibble stores 1's place 0107 Low nibble stores tens of health, upper nibble stores filled tanks 0108 Set to initiate momentary pause after a boss is killed 0109 Set to initiate momentary pause after an item is picked up 010A 16 End game escape timer 010E Missiles enabled? (1 = yes)
OAM ($0200)
This page of memory is reserved for OAM (sprite) data which is transferred to PPU each frame via DMA.
Object Memory ($0300)
The game stores data for "objects" between $0300 and $03FF. Each object has 16 bytes (Samus and the Tourian bridge have more). Most objects don't use all available object variables. The locations for each "object" are listed below. Note that there are additional variables for the same objects stored in another area of RAM. Even though a slot below may be listed unused, the variables ELSEWHERE in RAM that correspond to the unused object may be in use, so placing an object in that slot could cause problems.
Address Usage 0300 Samus (takes up two object slots) 0310 " 0320 Elevator (also used for cursor title/password screens) 0330 Unused 0340 Power Up 0350 Unused 0360 Tourian Bridge (takes up two object slots) 0370 " 0380 Door 1 0390 Door 2 03A0 Door 3 03B0 Door 4 03C0 Unused 03D0 Bullet/bomb/missile 03E0 Bullet/bomb/missile 03F0 Bullet/bomb/missile
These are the variables that are stored for each object.
Address Usage
03_0 Status/type of object (0 = no object)
03_1 Object vertical "radius"
03_2 Object horizontal "radius"
03_3 Index for sprite layout ptr table for current frame
03_4 Number of video frames for current sprite animation frame
03_5 Index of sprite frame layout to reset to when animation finishes
03_6 Index for animation sequence ptr table for current animation
03_7 (Samus only) Is samus on elevator? (1 = yes)
03_8 Vertical speed (signed)
03_9 Horizontal speed (signed)
03_A (Samus only) Set if Samus is hit by an enemy
03_B Object on screen (i.e. 'active') (1 = yes)
03_C Screen of object (boolean)
03_D Y position (within room, NOT screen coordinates)
03_E X position (within room, NOT screen coordinates)
03_F (Samus only) Vertical distance from the point from which player jumped (presumably cumulative)
Samus only:
0310 Y position sub-pixels
0311 X position sub-pixels
0312 Vertical speed sub-pixels
0313 Horizontal speed sub-pixels
0314 Samus gravity (sub-pixels)
0315 Horizontal acceleration (sub-pixels)
0316 Horizontal max speed (16ths of pixels)
Title/Password Cursor:
0320 Password cursor position
0321 "keyboard" row
0322 "keyboard" column
0325 0 = START selected, 1 = PASSWORD selected
Enemy Memory ($0400)
This memory is used much like object memory, but for enemies and pickups.
Address Usage 04_0 Y position in room.(not actual screen position). 04_1 X position in room.(not actual screen position). 04_2 04_3 04_4 04_5 04_6 Counts such things as explosion time. 04_7 04_8 04_9 Delay counter between enemy actions. 04_A 04_B Current hit points of enemy. 04_C 04_D Despawn timer for pickups, ?? for enemies 04_E 04_F Bit 7 set=tough version of enemy, bit 6 set=mini boss.
$0500 Page
This memory has various uses, including additional variables for some objects/enemies (not sure which one or if both), as well as variables for breakable blocks that need to respawn.
Address Usage
Tile respawning:
0500 Tile Routine
0503 Tile Anim Frame
0504 Tile Anim Delay
0506 Tile Anim Index
0507 Tile Delay
0508 16 Tile WRAM pointer
050A Tile Type
Sound Engine ($0600)
This section consists mostly of variable names from the Metroid disassembly, and the variables' descriptions.
Address Usage
0600 16 Music SQ1 Period
0602 0=Game not paused, 1=Game paused
0603 Pause Music SFX plays if less than $12
0604 16 Music SQ2 Period
0607 1=data needs to be written, 0=no data to write
0608 16 Music Tri Period
0610 16 Triangle Period
0612 16 Triangle Change
0614 16 Triangle Percentage Stores percent to change period by each frame
0616 Percent Difference, if=5, percent=1/5(20%), if=0A, percent=1/10(10%), etc
0617 Divide Data
061F Bit 7 set=has long beam, bit 0 set=has ice beam
The following addresses are loaded into $0640 thru $0643 when those
addresses decrement to zero. These addresses do not decrement.
0620 SQ1FrameCountInit Holds number of frames to play sq1 channel data
0621 SQ2FrameCountInit Holds number of frames to play sq2 channel data
0622 TriangleFrameCountInit Holds number of frames to play triangle channel data
0623 NoiseFrameCountInit Holds number of frames to play noise channel data
0624 SQ1RepeatCounter Number of times to repeat SQ1 music loop
0625 SQ2RepeatCounter Number of times to repeat SQ2 music loop
0626 TriangleRepeatCounter Number of times to repeat Triangle music loop
0627 NoiseRepeatCounter Number of times to repeat Noise music loop
0628 SQ1DutyEnvelope Loaded into SQ1Cntrl0 when playing music
0629 SQ2DutyEnvelope Loaded into SQ2Cntrl0 when playing music
062A TriLinearCount disable\enable counter, linear count length
062B NoteLengthTblOffset Stores the offset to find proper note length table
062C MusicRepeat 0=Music does not repeat, Nonzero=music repeats
062D TriangleCounterCntrl $F0=disable length cntr, $00=long note, $0F=short note
062E SQ1VolumeCntrl Entry number in VolumeCntrlAdressTbl for SQ1
062F SQ2VolumeCntrl Entry number in VolumeCntrlAdressTbl for SQ2
0630 SQ1LowBaseByte low byte of base address for SQ1 music data
0631 SQ1HighBaseByte High byte of base address for SQ1 music data
0632 SQ2LowBaseByte low byte of base address for SQ2 music data
0633 SQ2HighBaseByte High byte of base address for SQ2 music data
0634 TriangleLowBaseByte low byte of base address for Triangle music data
0635 TriangleHighBaseByte High byte of base address for Triangle music data
0636 NoiseLowBaseByte low byte of base address for Noise music data
0637 NoiseHighBaseByte High byte of base address for Noise music data
0638 SQ1MusicIndexIndex Index to find sQ1 sound data index. Base=$630,$631
0639 SQ2MusicIndexIndex Index to find SQ2 sound data index. Base=$632,$633
063A TriangleMusicIndexIndx Index to find Tri sound data index. Base=$634,$635
063B NoiseMusicIndexIndex Index to find Noise sound data index. Base=$636,$637
063C SQ1LoopIndex SQ1 Loop start index
063D SQ2LoopIndex SQ2 loop start index
063E TriangleLoopIndex Triangle loop start index
063F NoiseLoopIndex Noise loop start index
0640 SQ1MusicFrameCount Decrements every sq1 frame. When 0, load new data
0641 SQ2MusicFrameCount Decrements every sq2 frame. when 0, load new data
0642 TriangleMusicFrameCoun Decrements every triangle frame. When 0, load new data
0643 NoiseMusicFrameCount Decrements every noise frame. When 0, load new data
0648 MusicSQ1Sweep Value is loaded into SQ1Cntrl1 when playing music
0649 MusicSQ2Sweep Value is loaded into SQ2Cntrl1 when playing music
064A TriangleSweep Loaded into TriangleCntrl1(not used)
064B ThisSoundChannel Least sig. byte of current channel(00,04,08 or 0C)
064D CurrentSFXFlags Stores flags of SFX currently being processed.
0652 NoiseInUse Noise in use? (Not used)
0653 SQ1InUse 1=SQ1 channel being used by SFX, 0=not in use
0654 SQ2InUse 2=SQ2 channel being used by SFX, 0=not in use
0655 TriangleInUse 3=Triangle channel being used by SFX, 0=not in use
065C ChannelType Stores channel type being processed(0,1,2,3 or 4)
065D CurrentMusicRepeat Stores flags of music to repeat
065E MusicInitIndex index for loading $62B thru $637(base=$BD31).
0660 NoiseSFXLength Stores number of frames to play Noise SFX
0661 SQ1SFXLength Stores number of frames to play SQ1 SFX
0662 SQ2SFXLngth Stores number of frames to play SQ2 SFX
0663 TriangleSFXLength Stores number of frames to play Triangle SFX
0664 MultiSFXLength Stores number of frames to play Multi SFX
0665 ThisNoiseFrame Stores current frame number for noise SFX
0666 ThisSQ1Frame Stores current frame number for sq1 SFX
0667 ThisSQ2Frame Stores current frame number for SQ2 SFX
0668 ThisTriangleFrame Stores current frame number for triangle SFX
0669 ThisMultiFrame Stores current frame number for Multi SFX
066A SQ1VolumeIndex Stores index to SQ1 volume data in a volume data tbl
066B SQ2VolumeIndex Stores index to SQ2 volume data in a volume data tbl
066C SQ1VolumeData stores duty cycle and this frame volume data of SQ1
066D SQ2VolumeData Stores duty cycle and this frame volume data of SQ2
0670 NoiseSFXData Stores additional info for Noise SFX
0671 SQ1SFXData Stores additional info for SQ1 SFX
0672 SQ2SFXData Stores additional info for SQ2 SFX
0673 TriangleSFXData Stores additional info for triangle SFX
0674 MultiSFXData Stores additional info for Multi SFX
0675 SQ1SQ2SFXData Stores additional info for SQ1 and SQ2 SFX
0678 ScrewAttackSFXData Contains extra data for screw attack SFX
0679 SQ1SFXPeriodLow Period low data for processing multi SFX routines
0680 NoiseSFXFlag Initialization flags for noise SFX
0681 SQ1SFXFlag Initialization flags for SQ1 SFX
0682 SQ2SFXFlag Initialization flags for SQ2 SFX(never used)
0683 TriangleSFXFlag Initialization flags for triangle SFX
0684 MultiSFXFlag Initialization Flags for SFX and some music
0685 MusicInitFlag Music init flags
0688 NoiseContSFX Continuation flags for noise SFX
0689 SQ1ContSFX Continuation flags for SQ1 SFX
068A SQ2ContSFX Continuation flags for SQ2 SFX (never used)
068B TriangleContSFX Continuation flags for Triangle SFX
068C MultiContSFX Continuation flags for Multi SFX
068D CurrentMusic Stores the flag of the current music being played
$0700 Page
The $0700 page holds some data for power-ups displayed on screen and respawning tiles, as well as "PPU strings", i.e. small blocks of data to be sent to PPU.
The game can manage up to two power-ups at once (this would happen if there are power-ups in connected screens, like the missiles at the top of Norfair).
Address Usage
Power up 1:
0748 Power Up Type Holds the byte describing what power-up is on name table.
0749 Power Up Y Coord Y coordinate of the power-up.
074A Power Up X Coord X coordinate of the power-up
074B Power Up NameTable #$00 if on name table 0, #$01 if on name table 3.
074F Power Up Anim Index Entry into FramePtrTable for item animation.
Power up 2:
0750 Power Up Type Holds the description byte of a second power-up(if any).
0751 Power Up Y Coord Y coordinate of second power-up.
0752 Power Up X Coord X coordinate of second power-up.
0753 Power Up Name Table #$00 if on name table 0, #$01 if on name table 3.
0757 Power Up Anim Index Entry into FramePtrTable for item animation.
Respawning Blocks: 0780 Tile Size 4 MSBs=Y size of tile to erase.4 LSBs=X size of tile to erase. 0781 Tile byte 0 0782 Tile byte 1 0783 Tile byte 2 0784 Tile byte 3 0785 Tile byte 4 0786 Tile byte 5
"PPU strings" are small blocks of data ready to be copied to video memory. While many are pulled directly from the ROM, sometimes the game needs to construct them in RAM.
PPU String: 07A0 Number of bytes of data to send to PPU (max $4F) 07A1 Data to send to PPU - 07F0
WRAM ($6000)
Address Usage
6000 Stores the tile layout for one screen
6400 Stores the tile layout for a second screen
6872 Ending type (1 to 5 for worst to best)
6875 Index for current save file (referenced by vestigial FDS code)
6876 Unused byte for storing Samus info.
6877 Number of energy tanks.
6878 Equipment flags
bit 0: Bombs
bit 1: High Jump
bit 2: Long Beam
bit 3: Screw Attack
bit 4: Maru Mari (Morph Ball)
bit 5: Varia Suit
bit 6: Wave Beam
bit 7: Ice Beam
6879 Missiles
687A Missile capacity
687B Kraid statue (bit 0 set, the statues blink, bit 7 set, statues are raised)
687C Ridley statue (bit 0 set, the statues blink, bit 7 set, statues are raised)
687D Low byte of game time
687E Mid byte
687F High byte
6881 16 Number of times player has died. (Tracked, but never used. Probably left over from FDS)
6883 Alt ending: 1=End scenes playing, 0=Not at ending.
6884 MSB set=erase selected saved game (from FDS).
6885 Save file to load. (from FDS)
6886 # of password-tracked items obtained/red doors opened
6887 Location and type of password-tracked items obtained/red doors opened
- 68FC
6987 $01=Kraid/Ridley present, $00=Kraid/Ridley not present.
Password variables:
Address Usage
6988 Decoded password data:
- 6999
6988 password-tracked items/doors 0 thru 7.
6989 password-tracked items/doors 8 thru 15.
698A password-tracked items/doors 16 thru 23.
698B password-tracked items/doors 24 thru 31.
698C password-tracked items/doors 32 thru 39.
698D password-tracked items/doors 40 thru 47.
698E password-tracked items/doors 48 thru 55.
698F password-tracked items/doors 56 thru 58(bits 0 thru 2).
6990 start location(bits 0 thru 5), Samus suit status (bit 7).
6991 Equipment
6992 Missiles
6993 Game time (low byte)
6994 Game time (mid byte)
6995 Game time (high byte)
6996 Unused
6997 Stores Statue statuses(bits 4 thu 7).
6998 Random number
6999 Stores checksum
699A Password characters
- 69B1
Misc:
Address Usage
69B2 "NARPASSWORD" enabled (invincible, infinite missiles)
69B3 Justin Bailey (0 = Samus has suit, 1 = Samus is without suit.)
69B4 password-tracked items/doors saved game data (not used).
- 6A73
More enemy RAM: Addresses are given for first enemy. Each successive enemy's variables appear 16 ($10) bytes later.
Address Usage
6AF4 enemy status (00=Enemy slot not in use, 4=Enemy frozen, etc)
6AF5 Enemy vertical "radius"
6AF6 Enemy horizontal "radius"
6AF7 Current animation frame number
6AF8 Number of frames to delay between animation frames.
6AF9 First animation frame number
6AFA Index to current animation.
6AFB $00=Enemy on name table 0, $01=Enemy on name table 3.
6B02 Contains index into enemy data tables.
The following memory holds info for eight sprites during the title screen. Each sprite uses 16 bytes of RAM. Each successive sprite follows 16 ($10) bytes after. The first sprite uses some variables that none of the others used, marked by an asterix.
Address Usage
6E00- Holds sprite data for stars for title screen (4 bytes ea)
6E9C
6EA0 Intro sprite 0 and sparkle sprite:
6EA0 OAM Y
6EA1 OAM pattern
6EA2 OAM attribute
6EA3 OAM X
6EA4 * Index to next sparkle sprite data byte.
6EA5 * Decrements each frame. When 0, load new sparkle sprite data.
6EA6 x total movement distance.
6EA7 y total movement distance.
6EA8 * sparkle effect timer
6EA9 * sparkle type
6EAA Is sprite finished? (1 = yes)
6EAB Not used.
6EAC x displacement of sprite movement(run).
6EAD y displacement of sprite movement(rise).
6EAE X speed (signed)
6EAF Y speed (signed)
6EB0 Intro sprite 1 and sparkle sprite:
6EC0 Intro sprite 2
6ED0 Intro sprite 3
6EE0 Intro sprite 4
6EF0 Intro sprite 5
6F00 Intro sprite 6
6F10 Intro sprite 7
Internal Data for Metroid
| |
|---|---|