The 6502 architecture was very common in 1980s microcomputers such as Commodore 64, Atari 800, and Apple II, etc. The 2A03 is a version of 6502, used only in the NES and Famicom game consoles, that lacks 6502 decimal mode, has extra pins connected to sound and the joypads, and adds 21 memory-mapped registers that control those devices, along with one for sprite DMA. The NES motherboard clocks the 2A03 at 21.47727MHz on NTSC consoles (Famicom, US NES) or 26.601171MHz for PAL consoles (European NES); the 2A03's external interface divides this by 12 (NTSC) or 16 (PAL) to produce a 1.79 MHz clock signal for the 6502 core.

Sound registers

This is a summary. For more information, read Brad Taylor's reverse-engineering of the 2A03's sound hardware, available at; the files are nessound.txt and dmc.txt
$4000 (write): Square wave 1 control
$4004 (write): Square wave 2 control
$400C (write): Noise control
||||++++- Volume or decay rate
|||+----- Envelope mode (0: automatic decay; 1: volume
|||       controlled by software)
||+------ 1: Disable length counter and decay looping
++------- Pulse width (00: 1/8; 01: 1/4; 02: 1/2; 03: 3/4)

$4001 (write): Square wave 1 sweep
$4005 (write): Square wave 2 sweep
$4008 (write): Triangle wave linear counter
See nessound.txt for more information.

$4002 (write): Square wave 1 period and length (16-bit)
$4006 (write): Square wave 2 period and length
$400A (write): Triangle wave period and length
$4003    $4002
FEDCBA98 76543210
|||||||| ||||||||
|||||+++-++++++++- Period
+++++------------- Length counter load register

The period controls how many CPU cycles long each sample is, in a useful range of about seven octaves. (Higher numbers produce lower tones.) The square waveform is 16 samples long; the triangle waveform is 32 samples long, making it an octave lower.

$400E (write): Noise period
|   ||||
|   ++++- Noise period (through lookup table)
+-------- Noise waveform (0: 32,767 samples; 1: 93 samples)

$400F (write): Noise length
+++++---- Length counter load register

Delta modulation coding (DMC) is a simple predictive audio coding scheme. The bits are packed little-endian into bytes; a 0 means "subtract 1 from the counter" while a 1 means "add 1." (IMA ADPCM expands upon this technique.)

$4010 (write): DMC play mode
||  ||||
||  ++++- DMC period (through lookup table)
++------- DMC play mode (00: play once then stop;
          01/11: loop sample; 10: play once then stop and
          raise IRQ)

$4011 (write): DAC register
 ||||||+- LSB of the DAC (not touched by DMC counter)
 ++++++-- DMC counter load register
Raw samples can be played by writing 7-bit unsigned samples to $4011 using timed code. Some documents seem to imply that this register is not available on some early NES models; this is inaccurate.
$4012 (write): Sample address load
The start address of a DMC sample is (value << 6) + 0xC000.

$4013 (write): Sample length load
A DMC sample is (value << 4) + 1 bytes long.

$4015 (write): Sound channel enable
   ||||+- 1: Play square wave 1
   |||+-- 1: Play square wave 2
   ||+--- 1: Play triangle wave
   |+---- 1: Play noise
   +----- 1: Play DMC

$4015 (read): Sound channel status
|  |||||
|  ||||+- 1: Square wave 1 active
|  |||+-- 1: Square wave 2 active
|  ||+--- 1: Triangle wave active
|  |+---- 1: Noise active
|  +----- 1: DMC active
+-------- 1: DMC IRQ line active
          (cleared by $4015 write)

Sprite DMA

$4014 (write): Sprite DMA
Write a byte here, and the CPU will take 512 cycles to copy information from $xx00-$xxFF to $2004 (sprite data port). It's much faster than copying it all in yourself.

Joypads and expansion port

$4016 (write): Controller initialization
To reset both controllers, write 1 then 0 to this port.
This is necessary for all serial controllers (joypad,
Power Pad, and paddle) but not for the light gun.

$4017 (write): Interrupt initialization
The function of this register is not fully known, except
that writing $C0 here in a program's init code will make
interrupts behave properly.

$4016 (read): Joypad 1 data
   || ||
   || |+- Joypad 1/3 D0 data
   || +-- Auxiliary joypad 1/3 D0 data (Famicom only)
   |+---- Joypad 1 D3 data
   +----- Joypad 1 D4 data

$4017 (read): Joypad 2 data
   || ||
   || |+- Joypad 2/4 D0 data
   || +-- Auxiliary joypad 2/4 D0 data (Famicom only)
   |+---- Joypad 2 D3 data
   +----- Joypad 2 D4 data

Joypad data formats


The NES controller itself is depicted and described in its own node. Sequential reads of $4016 will return data for controllers in ports 1 and 3 in D0; reads of $4017 will return data for controllers 2 and 4.

     JOYPAD 1/2     JOYPAD 3/4
Read #1: A          #9: A
     #2: B         #10: B
     #3: Select    #11: Select (not on original Famicom)
     #4: Start     #12: Start (not on original Famicom)
     #5: Up        #13: Up
     #6: Down      #14: Down
     #7: Left      #15: Left
     #8: Right     #16: Right

The original Famicom used D0 for hardwired controllers and D1 for plug-in controllers. To be 100% compatible with the Famicom, you should OR bits D0 and D1 when reading the port in a 1- or 2-player game; in a 4-player game, read players 1 and 2 from D0 and players 3 and 4 from D1, and OR Famicom players 3 and 4 (D1 of first 8 reads) with NES players 3 and 4 (D0 of second 8 reads). And ignore anything you read about joypad signatures; they don't exist on this platform, and any documentation of them is a misguided extrapolation of other platforms' interfaces.

Light gun

The Zapper light gun operates as a primitive light pen that can detect the light or dark state of the pixel at which it is aimed. To increase the contrast, games darken the screen and draw sprites in bright white when the player pulls the trigger. If there is more than one target, a binary search through all target sprites will narrow down the possibilities. If, on the other hand, the game turns the screen white first, then it can use cycle-timed code to determine which scanline caused the gun to register light and more quickly eliminate other sprites from the calculation.

Most games use the gun connected to Player 2's controller port; a few games such as Chiller can operate with dual guns.

$4016 (read): Player 1 light gun status
   |+---- 1: Pixel in front of gun is light
   +----- 0: Trigger is pressed (active low!)

$4017 (read): Player 2 light gun status
   |+---- 1: Pixel in front of gun is light
   +----- 0: Trigger is pressed (active low!)


The japanese version of Taito's Arkanoid used a paddle as its primary controller; it had a compatibility mode for joypads. First, write 1 then 0 to $4016 (as for joypads). Then:
$4016 (read): Paddle button
      +-- 1: Paddle button is pressed

$4017 (read): Paddle 
      +-- Paddle position, MSB first

Values of the paddle position range from 13 (turned completely clockwise) to 157 (completely anticlockwise).

Dance mat

For information about the Power Pad dance mat, see NES Power Pad.


Based on documentation from . Michel Iwaniec ( submitted more complete information on the CPU's clock.

(return to) NES Programming

Log in or register to write something here or to contact authors.