CIA Chips โ 8520 MOS Technology
Overview
The Amiga uses two MOS 8520 CIA (Complex Interface Adapter) chips, providing timers, parallel/serial I/O ports, a time-of-day clock, and interrupt generation. They are the primary source of hardware timing outside the vertical blank and audio DMA.
- CIA-A at
$BFE001(even byte addresses) - CIA-B at
$BFD000(odd byte addresses)
Both CIAs are accessed via byte reads/writes; the 68000 byte-lane placement means CIA-A uses even offsets and CIA-B uses odd offsets on the 16-bit bus.
Register Map
Each CIA has 16 registers, spaced 256 bytes apart in the Amiga address space:
| Offset | Register | CIA-A Function | CIA-B Function |
|---|---|---|---|
| $000 | PRA | Parallel port data (input) | Disk control outputs |
| $100 | PRB | Parallel port data (output) | Disk status inputs |
| $200 | DDRA | Port A direction (1=output) | Port A direction |
| $300 | DDRB | Port B direction | Port B direction |
| $400 | TALO | Timer A low byte | Timer A low byte |
| $500 | TAHI | Timer A high byte | Timer A high byte |
| $600 | TBLO | Timer B low byte | Timer B low byte |
| $700 | TBHI | Timer B high byte | Timer B high byte |
| $800 | TODLO | TOD clock low (1/60 s) | Disk position (latched) |
| $900 | TODMID | TOD clock mid | |
| $A00 | TODHI | TOD clock high | |
| $B00 | (unused) | โ | โ |
| $C00 | SDR | Serial data register | Serial data register |
| $D00 | ICR | Interrupt control | Interrupt control |
| $E00 | CRA | Control register A | Control register A |
| $F00 | CRB | Control register B | Control register B |
CIA-A: $BFE001
CIA-A handles:
| Bit | Port A (PRA, read $BFE001) |
|---|---|
| 7 | /FIR1 โ joystick port 1 button |
| 6 | /FIR0 โ joystick port 0 button |
| 5 | /RDY โ floppy ready |
| 4 | /TK0 โ track 0 sensor |
| 3 | /WPRO โ write-protect |
| 2 | /CHNG โ disk change |
| 1 | /LED โ power LED (write: 0=bright) |
| 0 | /OVL โ Chip RAM overlay (write during boot) |
Port B (PRB, $BFE101): Parallel port data lines D0โD7.
CIA-A interrupts appear on CPU IPL level 2 via INTENA bit INTB_EXTER โ actually CIA is on IPL 6.
CIA-B: $BFD000
CIA-B handles floppy drive motor/selection and disk DMA sync:
| Bit | Port A (PRA, $BFD000) |
|---|---|
| 7 | /MTR โ motor on/off |
| 6 | /SEL3 โ drive 3 select |
| 5 | /SEL2 โ drive 2 select |
| 4 | /SEL1 โ drive 1 select |
| 3 | /SEL0 โ drive 0 select |
| 2 | /SIDE โ head side (0=upper) |
| 1 | /DIR โ step direction |
| 0 | /STEP โ step pulse |
Port B (PRB, $BFD100): Parallel port shadow (less commonly used on B).
CIA-B interrupts appear on CPU IPL level 6.
Timers
Each CIA has two 16-bit countdown timers (Timer A and Timer B):
- Count from a loaded latch value down to zero
- Can be one-shot or continuous
- Clock sources: system clock (709 kHz PAL / 715 kHz NTSC), or Timer A output (for Timer B)
- Timer A can generate
SDRbaud rate for serial output
Control Register A (CRA) bits:
bit 0: START โ 1 = timer running
bit 1: PBON โ 1 = timer output on Port B bit 6
bit 2: OUTMODE โ 0=pulse, 1=toggle
bit 3: RUNMODE โ 0=continuous, 1=one-shot
bit 4: LOAD โ 1 = force load latch into counter
bit 5: INMODE โ 0=clock, 1=count rising edges on CNT pin
bit 6: SPMODE โ 0=SDR input, 1=SDR output
bit 7: TODIN โ 0=60 Hz TOD, 1=50 Hz TOD (PAL)
Time-of-Day (TOD) Clock
24-bit counter, clocked at 60 Hz (NTSC) or 50 Hz (PAL):
- CIA-A TOD: used by OS as software clock
- TOD registers latch on read of TODHI โ must read TODHI first, then TODMID, then TODLO
ciaa.ciatodhiโciaa.ciatodmidโciaa.ciatodlo- Set by writing TODHI โ TODMID โ TODLO (halts during write)
Interrupt Control Register (ICR)
Write to enable interrupts, read to see which fired:
/* Enable Timer A interrupt */
ciaa.ciaicr = CIAICRF_SETCLR | CIAICRF_TA;
/* On read: bits indicate which sources fired */
UBYTE icr = ciaa.ciaicr;
if (icr & CIAICRF_TA) { /* Timer A fired */ }
if (icr & CIAICRF_TB) { /* Timer B fired */ }
if (icr & CIAICRF_ALRM) { /* TOD alarm fired */ }
if (icr & CIAICRF_SP) { /* Serial register full/empty */ }
if (icr & CIAICRF_FLG) { /* /FLAG pin (index pulse on CIA-B) */ }
Write bit 7 (CIAICRF_SETCLR): 1 = set enable bits, 0 = clear enable bits.
AmigaOS Timer Device Integration
AmigaOS's timer.device uses CIA timers internally:
- UNIT_MICROHZ โ uses CIA-A Timer A for microsecond delays
- UNIT_VBLANK โ uses vertical blank interrupt (not CIA)
- UNIT_ECLOCK โ uses the E clock (709/715 kHz, same as CIA clock)
Direct CIA programming should be done with ciaa/ciab resource claims via OpenResource("ciaa.resource") โ not by poking CIA registers directly.
C Access via NDK Headers
#include <hardware/cia.h>
#include <resources/cia.h>
/* CIA-A is at fixed address */
#define ciaa (*((volatile struct CIA *)0xBFE001))
#define ciab (*((volatile struct CIA *)0xBFD000))
/* struct CIA fields (hardware/cia.h): */
/* ciaa.ciapra, ciaa.ciaprb, ciaa.ciaicr, ciaa.ciacra, ... */
Per-Model CIA Wiring Variations
While CIA-A and CIA-B register layouts are identical across all Amigas, the physical wiring of their port pins varies by model:
CIA-A Port A Differences
| Bit | Standard (A500/A2000/A1200/A4000) | A1000 | CDTV | CD32 |
|---|---|---|---|---|
| 7 | /FIR1 โ joystick 1 fire |
Same | Same | CD32 pad button (via shift register) |
| 6 | /FIR0 โ joystick 0 fire |
Same | Same | CD32 pad button (via shift register) |
| 5 | /RDY โ floppy ready |
Same | No internal floppy | No floppy |
| 4 | /TK0 โ track 0 sensor |
Same | No internal floppy | No floppy |
| 3 | /WPRO โ write protect |
Same | No internal floppy | No floppy |
| 2 | /CHNG โ disk change |
Same | No internal floppy | No floppy |
| 1 | /LED โ power LED |
Same | Front panel LED | Front panel LED |
| 0 | /OVL โ Chip RAM overlay |
Same | Same | Same |
CIA-A /FLG Pin
| Model | /FLG Source |
|---|---|
| A500/A2000/A3000 | Directly accessible for parallel port BUSY or expansion |
| A600/A1200 | Gayle interrupt routing โ IDE and PCMCIA interrupts arrive here |
| CDTV | IR remote receiver โ IR data packets trigger /FLG |
| CD32 | Akiko interrupt routing โ CD-ROM and NVRAM events |
CIA-B Port A (Floppy Drive Selection)
| Bit | Standard | CDTV | CD32 |
|---|---|---|---|
| 7 | /MTR โ motor |
N/A (no internal floppy) | N/A |
| 6โ3 | /SEL3โ/SEL0 โ drive select |
External floppy only (/SEL0) |
N/A |
| 2 | /SIDE โ head side |
N/A | N/A |
| 1 | /DIR โ step direction |
N/A | N/A |
| 0 | /STEP โ step pulse |
N/A | N/A |
[!NOTE] On CDTV and CD32, the CIA-B floppy control bits are electrically disconnected from any drive hardware. Writing to them has no effect. If an external floppy is connected (CDTV with external drive, or CD32 with SX-1), only
/SEL0and related signals are active.
CD32 Gamepad โ CIA Shift Register Protocol
The CD32 gamepad uses CIA-A's Serial Data Register (SDR) for button reads. The controller contains a shift register that is clocked via the joystick port pin 5:
; Read CD32 gamepad buttons
; Returns 7 button bits in d0
move.b #$FF, $BFE301 ; CIA-A DDRA: all outputs (temporarily)
bset #6, $BFE001 ; Pin 5 high (clock start)
bclr #6, $BFE001 ; Pin 5 low โ latch button state
; Clock in 7 bits via pin toggling
moveq #6, d1
.read_pad:
bset #6, $BFE001 ; clock pulse high
btst #0, $BFE001 ; read data bit
bclr #6, $BFE001 ; clock pulse low
roxl.b #1, d0 ; shift into result
dbf d1, .read_pad
Standard 2-button Atari joysticks ignore the clock signal and remain fully compatible.
References
- MOS Technology 6526/8520 datasheet
- ADCD 2.1 Hardware Manual โ CIA chapter: http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/
- NDK39:
hardware/cia.h,resources/cia.h - Autodocs:
ciaresource โ http://amigadev.elowar.com/read/ADCD_2.1/Includes_and_Autodocs_3._guide/node00C7.html - See also: Kickstart Boot Diagnostics โ CIA-A LED blink pattern (coldCrash handler), overlay bit in PRA
See Also
- Video Signal & Timing โ E-clock derivation from master crystal, CIA timer implications
- DMA Architecture โ scanline slot allocation, bus arbitration