Metroid/RAM map

From Data Crystal
< Metroid
Revision as of 02:13, 6 June 2016 by FCC (talk | contribs)
Jump to navigation Jump to search

Chip tiny.png The following article is a RAM map for Metroid.

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)
   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          Maximim # 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)

   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 Y
   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 nubble 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_D        Y position (within room, NOT screen coordiantes)
   03_D        X position (within room, NOT screen coordiantes)
   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.

   Address     Usage
   04_0        Enemy y position in room.(not actual screen position).
   04_1        Enemy 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        
   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 coordiante 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 coordiante 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 (each bit represents one power up)
   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, inifinite 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|game=Metroid}}