NES architecture: the 6502 registers

In the NES architecture series, I’ll be discussing several properties and characteristics the NES hardware uses. In this post I’ll explain a little bit about the 6502 microprocessor it uses, zooming in on the registers.

Sorry… 6502 what?

The NES hardware consists of several microchips and processors, like a picture processing unit (the PPU) that handles everything that has to do with graphics, an audio processing unit (APU) that handles sound related stuff, the central processing unit (CPU) that basically handles the game code, and a lockout chip that’s supposed to prevent unauthorized games from playing. We’re focussing on the CPU part of the NES, which is a 2A03 chip based on MOS Technology 6502. This is the processor that handles the assembly code you may have been writing for your NES games, which is also why we call it 6502 assembly.

What are registers?

The 6502 processor uses a few registers. These are special parts of memory inside the processor which enable it to temporarily store bytes of data and perform calculations on them. The three registers you’ll probably encounter the most while using NESmaker, are the Accumulator, and the X- and Y-registers. There’s also the status register, which is important for the processor itself but you probably won’t directly touch those yourself at first. Anyway, I’ll try to explain what each register does.

The accumulator

Probably the most important register of the 6502 processor is the accumulator (called A in short). You can use the accumulator to temporarily store data from memory, compare its value to other data from memory, or do simple arithmetic or logical operations, to name a few.

The X-register

The X-register (or X in short) is another byte within the processor that can temporarily hold data from memory. You can’t directly do operations like adding or subtracting on the X-register. You can however copy data from the X-register to the accumulator and vice versa. Also, you can use the X-register as an index, to get an indexed value from memory.

The Y-register

The Y-register (or Y in short) pretty much does the same the X-register does. There seem to be some things the Y-register can do that the X-register cannot, and vice versa, but those are differences you’ll most likely will not encounter when writing code for your game.

The status register

Apart from the A, X and Y registers, there’s a somewhat special register: the status register. This register holds seven bits of additional data used as helpers for arithmetic and logical operations. The seven bits are stored in a byte as follows:

7 6 5 4 3 2 1 0
S V . B D I Z C

The most important bits of the status register are the following:

  • Bit 0 (C) is the Carry flag. This flag equals 0 if a borrow is required, and 1 if a borrow is not required.
  • Bit 1 (Z) is the Zero flag. This flag equals 1 if the result of an operation is zero, or 0 if the result is not zero. This bit is used in compares and branches, for example.
  • Bit 6 (V) is the Overflow flag. This flag equals 1 if an arithmetic operation produces a result that is bigger than 255 (the maximum value of a byte), and 0 if not.
  • Bit 7 (S) is the Sign flag. This flag equals 1 if an arithmetic operation produces a negative result (using signed integers), and 0 if the result is positive.

The other bits are less often used. Bit 2 (I) is the Interrupt flag, which is set to 1 if interrupts are disabled. Bit 3 (D) is the decimal mode status, which is 1 if arithmetic operations should use decimal (0-99) mode when carrying over, and 0 if binary/hexadecimal (0-255) mode is used. This most likely will always be 0 in a NES game. Bit 4 (B) is the Break flag, which is 1 when a BRK instruction is executed. Bit 5 is always 1 and not used for anything.

I will add a table with all assembly instructions available, and explain what they do on a microprocessor level. That’s something that deserves its own post though.

The Program Counter

You won’t use this register in your assembly code, but it’s a pretty important one still: the Program Counter (PC). This register keeps track of where the game is currently present in the code, so that it knows what code to execute next.

The Stack Pointer

Another register you won’t use directly is the Stack Pointer. The stack is used to temporarily save bytes of memory, by pushing (adding on top of the stack) or pulling (taking from the stack) data. This register keeps track where you’re currently at in the stack. Without this pointer, the stack wouldn’t work.