NES architecture: the CPU memory map

This article will try to make sense of the 64KB of memory the NES’ central processing unit (CPU) uses. This is a first, shorter dive into the CPU. In future posts, I’ll go into more detail about the CPU.

The NES CPU supports 64k of memory. Memory will be represented in hexadecimal addresses here, starting at address $0000 up to address $FFFF. This memory consists of the following sections.

Visual representation of the CPU memory

Work RAM

Adress $0000 to $1FFF are reserved for Work RAM. This is where variable data is stored. The CPU uses 8KB of memory for this Work RAM, although you will only use the first 2KB (address $0000-07FF). These 2KB of data are mirrored in addresses $0800-0FFF, $1000-17FF and $1800-$1FFF. This means for example that when you write data to address $0000, this data will also be written to addresses $0800, $1000 and $1800.

Work RAM is split into three parts: the Zero Page (address $0000-$00FF, these are the easiest and fastest for the NES to work with and therefore usually contain more dynamic data that needs to be read and updated the most often), the Stack (address $0100-$01FF, for pushing and pulling data serially; NESmaker uses the stack most often when values from the X- or Y-register need to be temporarily stored) and Random-access memory (RAM, address $0200-$07FF, reading or writing data here will take longer compared to data in the Zero Page).

PPU control registers

Adress $2000 to $3FFF are reserved for the PPU control registers. These allow the CPU to interact with the unit that processes the graphics. There are eight registers (address $2000-2007) which are mirrored again and again up until address $3FFF. These registers are used to tell the PPU which background or sprite graphics should be drawn where on screen, which colors to use and where the screen should be scrolled to, for example. To fully understand how this works, we’ll also need to take a look at the PPU memory map, which we’ll get into later on in another post.

APU control registers

Adress $4000 to $4017 are used for the APU control registers. These allow the CPU to interact with the audio processing unit. It tells the APU which channel should make a sound, what it should sound like, how loud or silent it is and how long it should play said sound. Again, we’ll go into more detail later in another post.

Joypad

Addresses $4016 and $4017 are used by the CPU to handle joypad controller input. Implementing these addresses will tell the CPU which buttons are held down, and which are not. In a later post, I will explain how these work exactly, showing a basic implementation in Assembly.

Address $4017 is a special one. Reading from this address is used to handle the inputs from player 2; Writing to it though, is related to the APU frame counter, most often use to disable audio output.

Program ROM

Adress $8000-$FFFF are used for the program ROM. These are split into two 16KB banks: a lower bank (address $8000-$BFFF – this bank can be switched when using NESmaker for game development) and an upper bank (address $C000-$FFFF – unlike the lower bank, this bank is static and won’t be changed throughout the game). This is where the game’s code and data from the cartridge resides. In 99% of NESmaker games, this data will only be read – unless you’re implementing flash saving, but that’s gonna be a whole new can of worms which I won’t be touching yet.

What about address $4018-$7FFF?

The observant reader might have noticed I skipped over a few addresses. These are either unused by the NES, or not used by NESmaker games. These are:

  • $4018-$401F – these are APU test registered which are unused by the NES – unless you modify the hardware, but let’s not get into that 🙂
  • $4020-$5FFF – this is the cartridge expansion area, which different hardware, cartridges and mappers will put to their own unique use. For example, address $4020 is used by the Arcade / VS Unisystem to acknowledge a coin has been put into the coin slot. NESmaker games don’t use this area, so I won’t go into more detail here.
  • $6000-$7FFF – the cartridge SRAM space. Cartridges with SRAM functionality (often battery powered, like in The Legend of Zelda) use this space for game saves. NESmaker does not use this type of saving. It’s possible to implement flash saving in NESmaker games, but that uses a different method of saving data.

So there you have it, the general CPU memory map. In the near future, I’ll go further into each part of the memory map, like the PPU and APU control registers.