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
$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)
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 Vert. accel (exponential) 0311 Horiz. accel (exponential) 0312 Vert. accel (linear) 0313 Horiz. accel (linear) 0314 Samus gravity 0315 Horiz. accel 0316 Horiz. max speed 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.
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.
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
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
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.
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
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|