Hardware Registers
Complete hardware register reference for the Atari 8-bit computers.
Overview
Hardware registers are located in the $D000-$D7FF address range. These registers control the GTIA, POKEY, PIA, and ANTIC chips.
GTIA Registers ($D000-$D01F)
GTIA (Graphics Television Interface Adapter) handles Player/Missile graphics, colors, and collision detection.
Player/Missile Horizontal Positions
| Address | Hex | Name | Description |
|---|
| $D000 | $D000 | HPOSP0 | Player 0 horizontal position |
| $D001 | $D001 | HPOSP1 | Player 1 horizontal position |
| $D002 | $D002 | HPOSP2 | Player 2 horizontal position |
| $D003 | $D003 | HPOSP3 | Player 3 horizontal position |
| $D004 | $D004 | HPOSM0 | Missile 0 horizontal position |
| $D005 | $D005 | HPOSM1 | Missile 1 horizontal position |
| $D006 | $D006 | HPOSM2 | Missile 2 horizontal position |
| $D007 | $D007 | HPOSM3 | Missile 3 horizontal position |
Player/Missile Graphics
| Address | Hex | Name | Description |
|---|
| $D00D | $D00D | GRAFP0 | Player 0 graphics |
| $D00E | $D00E | GRAFP1 | Player 1 graphics |
| $D00F | $D00F | GRAFP2 | Player 2 graphics |
| $D010 | $D010 | GRAFP3 | Player 3 graphics |
| $D011 | $D011 | GRAFM | Missile graphics |
Color Registers
| Address | Hex | Name | Shadow | Description |
|---|
| $D012 | $D012 | COLPM0 | PCOLR0 $02C0 | Player/Missile 0 color |
| $D013 | $D013 | COLPM1 | PCOLR1 $02C1 | Player/Missile 1 color |
| $D014 | $D014 | COLPM2 | PCOLR2 $02C2 | Player/Missile 2 color |
| $D015 | $D015 | COLPM3 | PCOLR3 $02C3 | Player/Missile 3 color |
| $D016 | $D016 | COLPF0 | COLOR0 $02C4 | Playfield color 0 |
| $D017 | $D017 | COLPF1 | COLOR1 $02C5 | Playfield color 1 |
| $D018 | $D018 | COLPF2 | COLOR2 $02C6 | Playfield color 2 |
| $D019 | $D019 | COLPF3 | COLOR3 $02C7 | Playfield color 3 |
| $D01A | $D01A | COLBK | COLOR4 $02C8 | Background color |
Control Registers
| Address | Hex | Name | Description |
|---|
| $D01D | $D01D | GRACTL | Graphics control |
| $D01E | $D01E | HITCLR | Clear collisions |
| $D01F | $D01F | CONSOL | Console keys (START, SELECT, OPTION) |
Collision Registers
| Address | Hex | Name | Description |
|---|
| $D000 | $D000 | M0PF | Missile 0 to playfield collisions |
| $D001 | $D001 | M1PF | Missile 1 to playfield collisions |
| $D002 | $D002 | M2PF | Missile 2 to playfield collisions |
| $D003 | $D003 | M3PF | Missile 3 to playfield collisions |
| $D004 | $D004 | P0PF | Player 0 to playfield collisions |
| $D005 | $D005 | P1PF | Player 1 to playfield collisions |
| $D006 | $D006 | P2PF | Player 2 to playfield collisions |
| $D007 | $D007 | P3PF | Player 3 to playfield collisions |
| $D008 | $D008 | M0PL | Missile 0 to player collisions |
| $D009 | $D009 | M1PL | Missile 1 to player collisions |
| $D00A | $D00A | M2PL | Missile 2 to player collisions |
| $D00B | $D00B | M3PL | Missile 3 to player collisions |
| $D00C | $D00C | P0PL | Player 0 to player collisions |
POKEY Registers ($D200-$D2FF)
POKEY (Pot Keyboard) handles audio, serial I/O, timers, and keyboard.
Audio Registers
| Address | Hex | Name | Description |
|---|
| $D200 | $D200 | AUDF1 | Audio frequency 1 |
| $D201 | $D201 | AUDC1 | Audio control 1 |
| $D202 | $D202 | AUDF2 | Audio frequency 2 |
| $D203 | $D203 | AUDC2 | Audio control 2 |
| $D204 | $D204 | AUDF3 | Audio frequency 3 |
| $D205 | $D205 | AUDC3 | Audio control 3 |
| $D206 | $D206 | AUDF4 | Audio frequency 4 |
| $D207 | $D207 | AUDC4 | Audio control 4 |
| $D208 | $D208 | AUDCTL | General audio control |
| $D209 | $D209 | KBCODE | Keyboard code |
| $D20A | $D20A | RANDOM | Random number generator |
| $D20E | $D20E | IRQEN | Interrupt request enable |
| $D20E | $D20E | IRQST | Interrupt request status (read) |
| $D20F | $D20F | SKSTAT | Serial port status |
| $D20F | $D20F | SKCTL | Serial port control (write) |
Shadow Registers
| Address | Hex | Name | Description |
|---|
| $0010 | $0010 | POKMSK | IRQEN shadow |
ANTIC Registers ($D400-$D4FF)
ANTIC (Alpha-Numeric Television Interface Controller) handles display lists, scrolling, and character sets.
Display Control
| Address | Hex | Name | Shadow | Description |
|---|
| $D400 | $D400 | DMACTL | SDMCTL $022F | Direct Memory Access control |
| $D401 | $D401 | CHACTL | CHART $02F3 | Character control |
| $D402 | $D402 | DLISTL | SDLSTL $0230 | Display list pointer (low) |
| $D403 | $D403 | DLISTH | SDLSTH $0231 | Display list pointer (high) |
| $D404 | $D404 | HSCROL | - | Horizontal scroll |
| $D405 | $D405 | VSCROL | - | Vertical scroll |
| $D407 | $D407 | PMBASE | - | Player/Missile base address |
| $D409 | $D409 | CHBASE | CHBAS $02F4 | Character set base address |
| $D40A | $D40A | WSYNC | - | Wait for horizontal sync |
| $D40E | $D40E | NMIEN | - | Non-maskable interrupt enable |
| $D40F | $D40F | NMIST | - | Non-maskable interrupt status |
PIA Registers ($D300-$D3FF)
PIA (Peripheral Interface Adapter) handles peripheral interrupts.
| Address | Hex | Name | Description |
|---|
| $D302 | $D302 | PACTL | Peripheral A control |
| $D303 | $D303 | PBCTL | Peripheral B control |
Shadow Registers
Many hardware registers have shadow registers in RAM that are copied to the hardware registers during vertical blank. Writing to shadow registers is safer than writing directly to hardware.
Color Shadow Registers
| Address | Hex | Name | Hardware | Description |
|---|
| $02C0 | 704 | PCOLR0 | $D012 | Player/Missile 0 color |
| $02C1 | 705 | PCOLR1 | $D013 | Player/Missile 1 color |
| $02C2 | 706 | PCOLR2 | $D014 | Player/Missile 2 color |
| $02C3 | 707 | PCOLR3 | $D015 | Player/Missile 3 color |
| $02C4 | 708 | COLOR0 | $D016 | Playfield color 0 |
| $02C5 | 709 | COLOR1 | $D017 | Playfield color 1 |
| $02C6 | 710 | COLOR2 | $D018 | Playfield color 2 |
| $02C7 | 711 | COLOR3 | $D019 | Playfield color 3 |
| $02C8 | 712 | COLOR4 | $D01A | Background color |
Display Shadow Registers
| Address | Hex | Name | Hardware | Description |
|---|
| $022F | 559 | SDMCTL | $D400 | DMA control shadow |
| $0230-$0231 | 560-561 | SDLSTL, SDLSTH | $D402-$D403 | Display list pointer shadow |
| $02F3 | 755 | CHART | $D401 | Character control shadow |
| $02F4 | 756 | CHBAS | $D409 | Character base shadow |
Register Usage Examples
Setting Colors
' Using shadow registers (recommended)
POKE 708, 0 ' COLOR0 = black
POKE 709, 16 ' COLOR1 = white
POKE 710, 32 ' COLOR2 = red
' Direct hardware access (faster, but use with care)
POKE $D016, 0 ' COLPF0 = black
POKE $D017, 16 ' COLPF1 = white
POKE $D018, 32 ' COLPF2 = red
Player/Missile Positions
' Set Player 0 horizontal position
POKE $D000, 80 ' HPOSP0 = 80
' Set Player 1 horizontal position
POKE $D001, 100 ' HPOSP1 = 100
Audio Control
' Set audio frequency and control
POKE $D200, 121 ' AUDF1 = 121
POKE $D201, $A8 ' AUDC1 = distortion + volume
Display List
' Get display list address
DLIST = DPEEK(560) ' SDLSTL/SDLSTH
' Wait for horizontal sync (useful in DLIs)
POKE $D40A, 0 ' WSYNC
Best Practices
- Use shadow registers when possible - They're updated during VBI, avoiding timing issues
- Direct hardware access for DLIs - In Display List Interrupts, write directly to hardware
- Read collision registers - They're cleared when read, so read once per frame
- Use WSYNC for timing - Write to WSYNC to wait for horizontal sync
- Document register usage - Hardware registers can be confusing
Related Topics