CPU memory map: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
(punctuation)
(More address space details and caveats. Clearer formatting.)
Line 18: Line 18:
| $4018–$401F || $0008 || APU and I/O functionality that is normally disabled. See [[CPU Test Mode]].
| $4018–$401F || $0008 || APU and I/O functionality that is normally disabled. See [[CPU Test Mode]].
|-
|-
| $4020–$FFFF || $BFE0 || Cartridge space: PRG ROM, PRG RAM, and [[mapper]] registers (see note)
| $4020–$FFFF || $BFE0 || Cartridge space: PRG ROM, PRG RAM, and [[mapper]] registers
|}
|}


Some parts of the 2 KiB of internal RAM at $0000–$07FF have predefined purposes dictated by the 6502 architecture.
* Some parts of the 2 KiB of internal RAM at $0000–$07FF have predefined purposes dictated by the 6502 architecture:
The zero page is $0000–$00FF, and the stack always uses some part of the $0100–$01FF page.
** $0000-$00FF: The zero page, which can be accessed with fewer bytes and cycles than other addresses
Games may divide up the rest however the programmer deems useful.
** $0100–$01FF: The page containing the stack, which can be located anywhere here, but typically starts at $01FF
See [[Sample RAM map]] for an example allocation strategy for this RAM.
: Games may divide up the rest however the programmer deems useful. See [[Sample RAM map]] for an example allocation strategy for this RAM. Most commonly, $0200-$02FF is used for the OAM buffer to be copied to PPU OAM during vblank.


Note: Most common boards and iNES mappers address ROM and Save/Work RAM in this format:
* The cartridge space at $4020-$FFFF can be used by cartridges for any purpose, such as ROM, RAM, and registers. Many common mappers place ROM and save/work RAM in these locations:
** $6000–$7FFF: Battery-backed save or work RAM
** $8000–$FFFF: ROM and mapper registers (see [[MMC1]] and [[UxROM]] for examples)
: The cartridge is able to passively observe reads from and writes to any address in the CPU address space, even outside this cartridge space, except for reads from $4015, the only readable register that is internal to the CPU. The cartridge can map writable registers anywhere, but its readable memory can only be placed where it does not interfere with other readable hardware, which would produce a [[bus conflict]]. While cartridges can map readable memory at $4000-$4014 and $4018-$401F, a quirk in the 2A03's register decoding can cause DMA to misbehave if the CPU is halted while reading from $4000-$401F, so it is recommended that cartridges only map readable memory from $4020-$FFFF.


*$6000–$7FFF = Battery Backed Save or Work RAM
* If using [[APU DMC|DPCM playback]], samples are limited to the following practical range:
*$8000–$FFFF = Usual ROM, commonly with Mapper Registers (see [[MMC1]] and [[UxROM]] for example)
** $C000–$FFF1: DPCM sample data
: Sample playback wraps around from $FFFF to $8000. The highest sample starting address is $FFC0 and longest sample is $FF1 bytes, so the full DPCM range is $C000-$FFFF and $8000-$8FB0, but making use of the wraparound is challenging because of banking and the presence of the CPU vectors.


If using [[APU DMC|DMC audio]]:
* The CPU expects interrupt vectors in a fixed place at the end of the cartridge space:
** $FFFA–$FFFB: NMI vector
** $FFFC–$FFFD: Reset vector
** $FFFE–$FFFF: IRQ/BRK vector
: If a mapper doesn't fix $FFFA–$FFFF to some known bank (normally by fixing an entire bank-sized region at the top of the address space, such as $C000-$FFFF, to a specific bank) nor use some sort of reset detection, the vectors need to be stored in all banks.


*$C000–$FFF1 = DPCM samples
* Reading from memory that is not mapped to anything normally returns [[Open bus behavior|open bus]]. The cartridge hardware may affect open bus behavior across the entire CPU address space, such as by pulling bits high or low.
 
The CPU expects interrupt vectors in a fixed place at the end of the cartridge space:
 
*$FFFA–$FFFB = NMI vector
*$FFFC–$FFFD = Reset vector
*$FFFE–$FFFF = IRQ/BRK vector
 
If a mapper doesn't fix $FFFA–$FFFF to some known bank (typically, along with the rest of the bank containing them, e.g. $C000–$FFFF for a 16KiB banking mapper) or use some sort of reset detection, the vectors need to be stored in all banks.

Revision as of 23:03, 16 April 2023

Address range Size Device
$0000–$07FF $0800 2 KB internal RAM
$0800–$0FFF $0800 Mirrors of $0000–$07FF
$1000–$17FF $0800
$1800–$1FFF $0800
$2000–$2007 $0008 NES PPU registers
$2008–$3FFF $1FF8 Mirrors of $2000–$2007 (repeats every 8 bytes)
$4000–$4017 $0018 NES APU and I/O registers
$4018–$401F $0008 APU and I/O functionality that is normally disabled. See CPU Test Mode.
$4020–$FFFF $BFE0 Cartridge space: PRG ROM, PRG RAM, and mapper registers
  • Some parts of the 2 KiB of internal RAM at $0000–$07FF have predefined purposes dictated by the 6502 architecture:
    • $0000-$00FF: The zero page, which can be accessed with fewer bytes and cycles than other addresses
    • $0100–$01FF: The page containing the stack, which can be located anywhere here, but typically starts at $01FF
Games may divide up the rest however the programmer deems useful. See Sample RAM map for an example allocation strategy for this RAM. Most commonly, $0200-$02FF is used for the OAM buffer to be copied to PPU OAM during vblank.
  • The cartridge space at $4020-$FFFF can be used by cartridges for any purpose, such as ROM, RAM, and registers. Many common mappers place ROM and save/work RAM in these locations:
    • $6000–$7FFF: Battery-backed save or work RAM
    • $8000–$FFFF: ROM and mapper registers (see MMC1 and UxROM for examples)
The cartridge is able to passively observe reads from and writes to any address in the CPU address space, even outside this cartridge space, except for reads from $4015, the only readable register that is internal to the CPU. The cartridge can map writable registers anywhere, but its readable memory can only be placed where it does not interfere with other readable hardware, which would produce a bus conflict. While cartridges can map readable memory at $4000-$4014 and $4018-$401F, a quirk in the 2A03's register decoding can cause DMA to misbehave if the CPU is halted while reading from $4000-$401F, so it is recommended that cartridges only map readable memory from $4020-$FFFF.
  • If using DPCM playback, samples are limited to the following practical range:
    • $C000–$FFF1: DPCM sample data
Sample playback wraps around from $FFFF to $8000. The highest sample starting address is $FFC0 and longest sample is $FF1 bytes, so the full DPCM range is $C000-$FFFF and $8000-$8FB0, but making use of the wraparound is challenging because of banking and the presence of the CPU vectors.
  • The CPU expects interrupt vectors in a fixed place at the end of the cartridge space:
    • $FFFA–$FFFB: NMI vector
    • $FFFC–$FFFD: Reset vector
    • $FFFE–$FFFF: IRQ/BRK vector
If a mapper doesn't fix $FFFA–$FFFF to some known bank (normally by fixing an entire bank-sized region at the top of the address space, such as $C000-$FFFF, to a specific bank) nor use some sort of reset detection, the vectors need to be stored in all banks.
  • Reading from memory that is not mapped to anything normally returns open bus. The cartridge hardware may affect open bus behavior across the entire CPU address space, such as by pulling bits high or low.