The NES CPU core is based on the 6502 processor and runs at approximately 1.79 MHz (1.66 MHz in a PAL NES). It is made by Ricoh and lacks the MOS6502's decimal mode. In the NTSC NES, the RP2A03 chip contains the CPU and APU; in the PAL NES, the CPU and APU are contained within the RP2A07 chip.
- CPU instructions
- CPU addressing modes
- CPU memory map
- CPU power-up state
- CPU registers
- CPU status flag behavior
- CPU interrupts
- Unofficial opcodes
- CPU pin-out and signals, and other hardware pin-outs
The CPU generates its clock signal by dividing the master clock signal.
|Rate||NTSC NES/Famicom||PAL NES||Dendy|
|Color subcarrier frequency fsc (exact)||3579545.45 Hz (315/88 MHz)||4433618.75 Hz||4433618.75 Hz|
|Color subcarrier frequency fsc (approx.)||3.579545 MHz||4.433619 MHz||4.433619 MHz|
|Master clock frequency 6fsc||21.477272 MHz||26.601712 MHz||26.601712 MHz|
|Clock divisor d||12||16||15|
|CPU clock frequency 6fsc/d||1.789773 MHz (~559 ns per cycle)||1.662607 MHz (~601 ns per cycle)||1.773448 MHz (~564 ns per cycle)|
* The vast majority of PAL famiclones use a chipset or NOAC with this timing. A small number have UMC UA6540+6541, which also uses PAL NES timing.
- All illegal 6502 opcodes execute identically on the 2A03/2A07.
- Every cycle on 6502 is either a read or a write cycle.
- A printer friendly version covering all section is available here.
- Emulator authors may wish to emulate the NTSC NES/Famicom CPU at 21441960 Hz ((341×262−0.5)×4×60) to ensure a synchronised/stable 60 frames per second.
- Cycle reference chart
- 2A03 technical reference by Brad Taylor. (Pretty old at this point; information on the wiki might be more up-to-date.)
|$0000–$07FF||$0800||2 KB internal RAM|
|$0800–$0FFF||$0800||Mirrors of $0000–$07FF|
|$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:
- 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.
Pin out and signal description
.--\/--. AD1 <- |01 40| -- +5V AD2 <- |02 39| -> OUT0 /RST -> |03 38| -> OUT1 A00 <- |04 37| -> OUT2 A01 <- |05 36| -> /OE1 A02 <- |06 35| -> /OE2 A03 <- |07 34| -> R/W A04 <- |08 33| <- /NMI A05 <- |09 32| <- /IRQ A06 <- |10 31| -> M2 A07 <- |11 30| <- TST (usually GND) A08 <- |12 29| <- CLK A09 <- |13 28| <> D0 A10 <- |14 27| <> D1 A11 <- |15 26| <> D2 A12 <- |16 25| <> D3 A13 <- |17 24| <> D4 A14 <- |18 23| <> D5 A15 <- |19 22| <> D6 GND -- |20 21| <> D7 `------'
Active-Low signals are indicated by a "/". Every cycle is either a read or a write cycle.
- CLK : 21.47727 MHz (NTSC) or 26.6017 MHz (PAL) clock input. Internally, this clock is divided by 12 (NTSC 2A03) or 16 (PAL 2A07) to feed the 6502's clock input φ0, which is in turn inverted to form φ1, which is then inverted to form φ2. φ1 is high during the first phase (half-cycle) of each CPU cycle, while φ2 is high during the second phase.
- AD1 : Audio out pin (both pulse waves).
- AD2 : Audio out pin (triangle, noise, and DPCM).
- Axx and Dx : Address and data bus, respectively. Axx holds the target address during the entire read/write cycle. For reads, the value is read from Dx during φ2. For writes, the value appears on Dx during φ2 (and no sooner).
- OUT0..OUT2 : Output pins used by the controllers ($4016 output latch bits 0-2). These 3 pins are connected to either the NES or Famicom's expansion port, and OUT0 is additionally used as the "strobe" signal (OUT) on both controller ports.
- /OE1 and /OE2 : Controller ports (for controller #1 and #2 respectively). Each enable the output of their respective controller, if present.
- R/W : Read/write signal, which is used to indicate operations of the same names. Low is write. R/W stays high/low during the entire read/write cycle.
- /NMI : Non-maskable interrupt pin. See the 6502 manual and CPU interrupts for more details.
- /IRQ : Interrupt pin. See the 6502 manual and CPU interrupts for more details.
- M2 : Can be considered as a "signals ready" pin. It is a modified version the 6502's φ2 (which roughly corresponds to the CPU input clock φ0) that allows for slower ROMs. CPU cycles begin at the point where M2 goes low.
- In the NTSC 2A03E, G, and H, M2 has a duty cycle of 15/24 (5/8), or 350ns/559ns. Equivalently, a CPU read (which happens during the second, high phase of M2) takes 1 and 7/8th PPU cycles. The internal φ2 duty cycle is exactly 1/2 (one half).
- In the PAL 2A07, M2 has a duty cycle of 19/32, or 357ns/601ns, or 1.9 out of 3.2 pixels.
- In the original NTSC 2A03 (no letter), M2 has a duty cycle of 17/24, or 396ns/559ns, or 2 and 1/8th pixels.
- TST : (tentative name) Pin 30 is special: normally it is grounded in the NES, Famicom, PC10/VS. NES and other Nintendo Arcade Boards (Punch-Out!! and Donkey Kong 3). But if it is pulled high on the RP2A03G, extra diagnostic registers to test the sound hardware are enabled from $4018 through $401A, and the joystick ports $4016 and $4017 become open bus. On the RP2A07 (and presumably also the RP2A03E), pulling pin 30 high instead causes the CPU to stop execution by means of activating the embedded 6502's RDY input.
- /RST : When low, holds CPU in reset state, during which all CPU pins (except pin 2) are in high impedance state. When released, CPU starts executing code (read $FFFC, read $FFFD, ...) after 6 M2 clocks.
Power up state
The following results are from a US (NTSC) NES, original front-loading design, RP2A03G CPU chip, NES-CPU-07 main board revision, manufactured in 1988. The memory values are probably slightly different for each individual NES console. Please note that you should NOT rely on the state of any registers after Power-UP and especially not the stack register and RAM ($0000-$07FF).
- P = $34 (IRQ disabled)
- A, X, Y = 0
- S = $FD
- $4017 = $00 (frame irq enabled)
- $4015 = $00 (all channels disabled)
- $4000-$400F = $00
- $4010-$4013 = $00 
- All 15 bits of noise channel LFSR = $0000. The first time the LFSR is clocked from the all-0s state, it will shift in a 1.
- APU Frame Counter:
- 2A03E, G, various clones: APU Frame Counter reset.
- 2A03letterless: APU frame counter powers up at a value equivalent to 15
- Internal memory ($0000-$07FF) has unreliable startup state. Some machines may have consistent RAM contents at power-on, but others do not.
- Emulators often implement a consistent RAM startup state (e.g. all $00 or $FF, or a particular pattern), and flash carts like the PowerPak may partially or fully initialize RAM before starting a program, so an NES programmer must be careful not to rely on the startup contents of RAM.
- A, X, Y were not affected
- S was decremented by 3 (but nothing was written to the stack)
- The I (IRQ disable) flag was set to true (status ORed with $04)
- The internal memory was unchanged
- APU mode in $4017 was unchanged
- APU was silenced ($4015 = 0)
- APU triangle phase is reset to 0 (i.e. outputs a value of 15, the first step of its waveform)
- APU DPCM output ANDed with 1 (upper 6 bits cleared)
Status flag behavior
The flags register, also called processor status or just P, is one of the six architectural registers on the 6502 family CPU. It is composed of six one-bit registers; instructions modify one or more bits and leave others unchanged.
Instructions that save or restore the flags map them to bits in the architectural 'P' register as follows:
7 bit 0 ---- ---- NV1B DIZC |||| |||| |||| |||+- Carry |||| ||+-- Zero |||| |+--- Interrupt Disable |||| +---- Decimal |||+------ (No CPU effect; see: the B flag) ||+------- (No CPU effect; always pushed as 1) |+-------- Overflow +--------- Negative
- The PHP (Push Processor Status) and PLP (Pull Processor Status) instructions can be used to retrieve or set this register directly via the stack.
- Interrupts, including the NMI and also the pseudo-interrupt BRK instruction, implicitly push the status register to the stack.
- Interrupts returning with RTI will implicitly pull the saved status register from the stack.
- The two bits with no CPU effect are ignored when pulling flags from the stack; there are no corresponding registers for them in the CPU.
- When P is displayed as a single 8-bit register by debuggers, there is no convention for what values to use for bits 5 and 4 and their values should not be considered meaningful.
- After ADC, this is the carry result of the addition.
- After SBC or CMP, this flag will be set if no borrow was the result, or alternatively a "greater than or equal" result.
- After a shift instruction (ASL, LSR, ROL, ROR), this contains the bit that was shifted out.
- Increment and decrement instructions do not affect the carry flag.
- Can be set or cleared directly with SEC, CLC.
- After most instructions that have a value result, this flag will either be set or cleared based on whether or not that value is equal to zero.
I: Interrupt Disable
- When set, all interrupts except the NMI are inhibited.
- Can be set or cleared directly with SEI, CLI.
- Automatically set by the CPU when an IRQ is triggered, and restored to its previous state by RTI.
- If the /IRQ line is low (IRQ pending) when this flag is cleared, an interrupt will immediately be triggered.
- On the NES, decimal mode is disabled and so this flag has no effect. However, it still exists and can be observed and modified, as normal.
- On the original 6502, this flag causes some arithmetic instructions to use binary-coded decimal representation to make base 10 calculations easier.
- Can be set or cleared directly with SED, CLD.
- ADC and SBC will set this flag if the signed result would be invalid, necessary for making signed comparisons.
- BIT will load bit 6 of the addressed value directly into the V flag.
- Can be cleared directly with CLV. There is no corresponding set instruction.
- After most instructions that have a value result, this flag will contain bit 7 of that result.
- BIT will load bit 7 of the addressed value directly into the N flag.
The B flag
While there are only six flags in the processor status register within the CPU, the value pushed to the stack contains additional state in bit 4 called the B flag that can be useful to software. The value of B depends on what caused the flags to be pushed. Note that this flag does not represent a register that can hold a value, but rather a transient signal in the CPU controlling whether it was processing an interrupt when the flags were pushed. B is 0 when pushed by interrupts (/IRQ and /NMI) and 1 when pushed by instructions (BRK and PHP).
|Instruction||B||Side effects after pushing|
|/IRQ||0||I is set to 1|
|/NMI||0||I is set to 1|
|BRK||1||I is set to 1|
The only way for an IRQ handler to distinguish /IRQ from BRK is to read the flags byte from the stack and test bit 4. The slowness of this is one reason why BRK wasn't used as a syscall mechanism. Instead, it was more often used to trigger a patching mechanism that hung off the /IRQ vector: a single byte in PROM, UVEPROM, flash, etc. would be forced to 0, and the IRQ handler would pick something to do instead based on the program counter.
Some debugging tools, such as Visual6502, display the B flag as bit 4 of P to save space on screen. The user can see it turn off at the start of an interrupt and back on after the CPU reads the vector.
- The golden log of nestest differs from this in the irrelevant bits 5 and 4 of P
- IRQ was first asserted about 1/60 second after power-up, by APU.
- RESET uses the logic shared with NMI, IRQ, and BRK that would push PC and P. However, like some but not all 6502s, the 2A03 prohibits writes during reset. This test relies on open bus being precharged by these reads. See 27c3: Reverse Engineering the MOS 6502 CPU (en) from 41:45 onward for details
- Eliminator Boat Duel
- Noise channel init log
- 2A03letterless is missing transistor to set frame counter LFSR on reset
- Article: The Overflow (V) Flag Explained
- Article: Beyond 8-bit Unsigned Comparisons, Signed Comparisons