NES RAM (Mapping/Finding Values)
NES Mapping
This guide gives a map of the addresses in the NES cpu and explains each portion in detail.
It also provides information for the basic layout of ram values in typical NES games. This info can be used to quickly map and find useful values in the game's ram.
Contents
Memory Map
Gives a diagram of the 2A03 CPU memory map .
2C02 PPU memory map
Gives more detailed info about each section of the Memory map diagram
Game Ram Details
On board RAM Map ($000-$07FF) Map (gives specific info on the how NES games typically layout their ram values)
Online Resources
Memory Map (NES RAM/ROM)
2A03 CPU memory map
2A03 CPU is a 6502-compatible CPU without the decimal mode (CLD and SED do nothing). It has an on-die sound generator, very limited DMA capability, and an input device controller that can be accessed through the 2A03 registers.
6502 CPU Memory Map
Address Range Size in bytes Notes (Page size = 256bytes)
(Hexadecimal)
$0000 - $07FF 2048 Game Ram
($0000 - $00FF) 256 Zero Page - Special Zero Page addressing modes give faster memory read/write access
($0100 - $01FF) 256 Stack memory
($0200 - $07FF) 1536 RAM
$0800 - $0FFF 2048 Mirror of $0000-$07FF
($0800 - $08FF) 256 Zero Page
($0900 - $09FF) 256 Stack
($0A00 - $0FFF) 1024 Ram
$1000 - $17FF 2048 bytes Mirror of $0000-$07FF
($1000 - $10FF) 256 Zero Page
$1100 - $11FF 256 Stack
$1200 - $17FF 1024 RAM
$1800 - $1FFF 2048 bytes Mirror of $0000-$07FF
($1800 - $18FF) 256 Zero Page
($1900 - $19FF) 256 Stack
($1A00 - $1FFF) 1024 RAM
$2000 - $2007 8 bytes Input / Output registers
$2008 - $3FFF 8184 bytes Mirror of $2000-$2007 (mulitple times)
$4000 - $401F 32 bytes Input / Output registers
$4020 - $5FFF 8160 bytes Expansion ROM - Used with Nintendo's MMC5 to expand the capabilities of VRAM.
$6000 - $7FFF 8192 bytes SRAM - Save Ram used to save data between game plays.
$8000 - $BFFF 16384 bytes PRG-ROM lower bank - executable code
$C000 - $FFFF 16384 bytes PRG-ROM upper bank - executable code
$FFFA - $FFFB 2 bytes Address of Non Maskable Interrupt (NMI) handler routine
$FFFC - $FFFD 2 bytes Address of Power on reset handler routine
$FFFE - $FFFF 2 bytes Address of Break (BRK instruction) handler routine
2C02 PPU memory map
2C02 PPU is a character generator with sprites, designed by Nintendo specifically for the NES.
__________________________________________
0000| Pattern table 0 |
|__________________________________________|
1000| Pattern table 1 |
|__________________________________________| _____ _____
2000| Nametable 0 | | | |
|__________________________________________| | 0 | 1 |
2400| Nametable 1 | |_____|_____|
|__________________________________________| | | |
2800| Nametable 2 | | 2 | 3 |
|__________________________________________| |_____|_____|
2c00| Nametable 3 |
|__________________________________________|
3000| Mirror of $2000-$2eff |
|__________________________________________|
3f00| Palette |
|__________________________________________|
3f20| Mirrors of $3f00-$3f1f |
|__________________________________________|
The NES PPU has enough RAM for two nametables (0 and 3); it brings some PPU nametable address lines to the cart edge so that the cart can decide whether to map 0 onto 2 and 1 onto 3 (vertical mirroring as in Super Mario Brothers and Contra) or 0 onto 1 and 2 onto 3 (horizontal mirroring as in Kid Icarus and Ikari), all screens to either 0 or 3 (as in many Rare games such as Battletoads and Jeopardy!), or all screens to RAM on the cartridge (as in Gauntlet). Split-screen games that scroll in all four directions (such as Super Mario Brothers 3 and Kirby's Adventure) often use vertical or one-screen mirroring (with a small amount of screen corruption at the sides due to tiles wrapping around the sides) and stick the status bar in some random unused area of the screen.
Game RAM Details
Mapping RAM/Finding Ram
Written by: adelikat
This guide is written specifically for finding useful values for TAS movie making.
It does not tell you how to use specific tools to find values. For that refer to Hex editor, Cheat Search, and RAM filter.
Most games use the basic on board ram. The address range of this ram is $0000-$07FF. This translates to 2048 possible ram values.
Pages
This ram is broken down into 8 pages. A "page" is a block of 256 ram values.
I will refer to these values as such:
Block 0 $00xx ($0000-$00FF)
Block 1 $01xx ($0100-$01FF)
Block 2 $02xx ($0200-$02FF)
Block 3 $03xx ($0300-$03FF)
Block 4 $04xx ($0400-$04FF)
Block 5 $05xx ($0500-$05FF)
Block 6 $06xx ($0600-$06FF)
Block 7 $07xx ($0700-$07FF)
Each block will be organized will similar data. For instance, all sprite data will be in the same block. Enemy/Player statistics (energy, coordinates, speed, etc.) will be in another. For instance, if you find the main character's HP and it is located in block 3, you know that the remaining stats for the character are also in that block. This can significantly cut down time when trying to find related values.
There are always the following blocks:
Sprite Data Block 2
I've yet to see map a game that does not use this block solely for sprite data. It will contain the "ID" numbers for all the items currently on the screen. Simply put, this data is precisely the data you see on the screen. For making TAS movies this is not useful data. If you are using cheat search and have narrowed it down your search to a few values, you can immediately discard any $02xx values.
In games with a lot of sprite data, I've seen blocks 1 & 3 also reserved for sprite data.
Music & Sound FX Block 1 or 7, generally
This one has more deviation, but almost all games reserve an entire block for memory allocated to the game's Music and Sound FX. Again, for TAS purposes these values are not *useful. By finding even 1 of these values, you can eliminate that block from your search possibilities. Finding which block is reserved for music is often quite simple with the Hex editor. Watching the ram values with the game playing, you can see which addresses "move to the beat".
*Actually they can come in handy for "dancing to the beat"
Player & Enemy Stats Blocks 1,3,4,5 generally (any or all of these)
This is your "sweet spot" for movie making, as often you will be wanting to track the players speed or coordinates, enemy energy, or enemy coordinates.
These values rarely (if at all) reside outside blocks 1, 3, 4, or 5. This knowledge already reduces your search possibilities in half!
Rows
Each block is broken down into 16 "rows" of addresses. For example, in block 3, the first row is $030x ($0300-$030F).
Each row of 16* will contain similar data. For instance all x coordinates will generally be in the same row. So xxx0 might be the main characters x position. xxxx1 would be "enemy 1" (1st enemy loaded onto the screen), and so on.
The y coordinates would be in another row, x subpixel values in yet another row, etc.
*Super Mario Bros. 2 (U) is a rare example that uses rows of 10
Columns
A column would be all the values of a block that share the same last digit. So a column would be 16 addresses such as $0300, $0310, $0320, etc.
For enemy/player stats, columns usually refer to the same player or enemy.
So for example, if a player's energy was stored in $0300. The remaining row will be other player/enemy's energy.
If the next row ($031x) is x positions. $0310 would be the player's x position. The remaining positions of that row would correspond to the other player/enemy x positions in line with the hp values of the previous row.
Example
These distinctions are easier to see in a visual example. This is the enemy/player stats as they are mapped in the game Teenage Mutant Ninja Turtles.
Block 4
P W1 W2 W3 E1 E2 E3 E4 E5 E6 E7 E8 X X X X
Sprite ID: 040x: 09 00 00 00 00 9E 9E 9E 9E 00 00 00 00 00 00 00
ID counter: 041x: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Timer/sp change: 042x: 02 00 00 00 00 03 03 03 03 00 00 00 00 00 00 00
hit animation: 043x: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
characteristics: 044x: 00 00 00 00 00 8D 8D 8D 8D 00 00 00 00 00 00 00
characteristics: 045x: C2 00 00 00 00 C2 C2 C3 C3 00 00 00 00 00 00 00
Y position: 046x: 4C 00 00 00 00 B4 B4 64 B4 00 00 00 00 00 00 00
Y subpixel: 047x: 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
X position: 048x: 50 00 00 00 00 79 B9 CC CC 00 00 00 00 00 00 00
X subpixel: 049x: 80 00 00 00 00 C0 C0 C0 00 00 00 00 00 00 00 00
Not used: 04ax: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Y pix speed: 04bx: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Y subpix speed: 04cx: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Not used: 04dx: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
X pix speed: 04ex: 00 00 00 00 00 01 01 FE FE 00 00 00 00 00 00 00
X subpix speed: 04fx: 00 00 00 00 00 60 60 A0 A0 00 00 00 00 00 00 00
P = current turtle (player)
W = weapon (up to 3 on the screen at one time)
E = enemy (up to 8 on the screen at one time)
X = no use
E1 = "Enemy slot 1" which will be the first enemy on the screen loaded into memory. The 2nd will be placed in "Enemy slot 2". When enemy 1 is removed from memory (killed or goes off screen), the next enemy will be loaded into that slot. Enemy's always take the lowest available slot when loaded. Note: usually enemy slots are in reverse order. So the first addresses is usually the last enemy slot loaded into memory. TMNT is an exception.
All object (player, weapon, enemy) characteristics reside in block 4.
Each row is a different characteristic of each object on the screen (040x refers to a sprite ID of an object)
Each column corresponds to a specific object on the screen. (All 04x0 's refer to the player).
See also, Memory Watch, Hex Editor, Cheat Search, Ram Filter, Movie Making, Tool Assisted Speedruns
Created with the Personal Edition of HelpNDoc: Easy CHM and documentation editor