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
http://nesdev.parodius.com; the files are
nessound.txt and dmc.txt
$4000 (write): Square wave 1 control
$4004 (write): Square wave 2 control
$400C (write): Noise control
76543210
||||||||
||||++++- 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
76543210
| ||||
| ++++- Noise period (through lookup table)
+-------- Noise waveform (0: 32,767 samples; 1: 93 samples)
$400F (write): Noise length
76543210
|||||
+++++---- 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
76543210
|| ||||
|| ++++- 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
76543210
|||||||
||||||+- 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
76543210
|||||
||||+- 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
76543210
| |||||
| ||||+- 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
76543210
|| ||
|| |+- 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
76543210
|| ||
|| |+- Joypad 2/4 D0 data
|| +-- Auxiliary joypad 2/4 D0 data (Famicom only)
|+---- Joypad 2 D3 data
+----- Joypad 2 D4 data
Joypad data formats
Joypad
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
76543210
||
|+---- 1: Pixel in front of gun is light
+----- 0: Trigger is pressed (active low!)
$4017 (read): Player 2 light gun status
76543210
||
|+---- 1: Pixel in front of gun is light
+----- 0: Trigger is pressed (active low!)
Paddle
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
76543210
|
+-- 1: Paddle button is pressed
$4017 (read): Paddle
76543210
|
+-- 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.
Credits
Based on documentation from http://nesdev.parodius.com/ .
Michel Iwaniec (bananmos_uv@hotmail.com) submitted more complete information on the CPU's clock.
(return to)
NES Programming