CIA (Complex Interface Adapter) Registers

The Amiga carries two MOS 8520 Complex Interface Adapter (CIA) chips — CIAA and CIAB — that handle I/O glue logic:

  • CIAA ($BFE001) — primary I/O: gameports, floppy status, LED, memory overlay
  • CIAB ($BFD000) — disk stepper control, serial port, parallel (printer) port, TOD clock

CIAA is accessed on odd byte addresses (low byte of the 16-bit chip bus); CIAB on even byte addresses (high byte). Each CIA exposes 16 byte-wide registers covering I/O ports, timers, time-of-day clock, serial port, and interrupt control.

Register map

Offsets are relative to the CIA base. CIAA is at $BFE001 (use odd offsets: $0001, $0101, etc.); CIAB is at $BFD000 (use even offsets: $0000, $0100, etc.).

Offset Name Access Description
$00xx ciapra RW Peripheral port A (CIAA: gameports, floppy status, LED, overlay / CIAB: serial, printer)
$01xx ciaprb RW Peripheral port B (CIAA: parallel port / CIAB: disk stepper control)
$02xx ciaddra RW Data direction register for port A (1 = output, 0 = input)
$03xx ciaddrb RW Data direction register for port B
$04xx ciatalo RW Timer A low byte
$05xx ciatahi RW Timer A high byte
$06xx ciatblo RW Timer B low byte
$07xx ciatbhi RW Timer B high byte
$08xx ciatodlow RW Time-of-day clock low byte (1/10 sec)
$09xx ciatodmid RW Time-of-day clock middle byte (seconds)
$0Axx ciatodhi RW Time-of-day clock high byte (minutes + hours)
$0Cxx ciasdr RW Serial data register
$0Dxx ciaicr RW Interrupt control register
$0Exx ciacra RW Control register A (timer A mode + serial)
$0Fxx ciacrb RW Control register B (timer B mode + alarm)

Absolute addresses

CIAA ($BFE001 base, odd offsets)

Address Name
$BFE001 ciapra
$BFE101 ciaprb
$BFE201 ciaddra
$BFE301 ciaddrb
$BFE401 ciatalo
$BFE501 ciatahi
$BFE601 ciatblo
$BFE701 ciatbhi
$BFE801 ciatodlow
$BFE901 ciatodmid
$BFEA01 ciatodhi
$BFEC01 ciasdr
$BFED01 ciaicr
$BFEE01 ciacra
$BFEF01 ciacrb

CIAB ($BFD000 base, even offsets)

Address Name
$BFD000 ciapra
$BFD100 ciaprb
$BFD200 ciaddra
$BFD300 ciaddrb
$BFD400 ciatalo
$BFD500 ciatahi
$BFD600 ciatblo
$BFD700 ciatbhi
$BFD800 ciatodlow
$BFD900 ciatodmid
$BFDA00 ciatodhi
$BFDC00 ciasdr
$BFDD00 ciaicr
$BFDE00 ciacra
$BFDF00 ciacrb

Interrupt control register (ciaicr)

Bit Bit name Flag Meaning
0 CIAICRB_TA CIAICRF_TA Timer A underflow interrupt
1 CIAICRB_TB CIAICRF_TB Timer B underflow interrupt
2 CIAICRB_ALRM CIAICRF_ALRM TOD alarm interrupt
3 CIAICRB_SP CIAICRF_SP Serial port byte received / transmit buffer empty
4 CIAICRB_FLG CIAICRF_FLG FLAG pin (PA2) negative edge
7 CIAICRB_IR / CIAICRB_SETCLR CIAICRF_IR / CIAICRF_SETCLR Interrupt request / set-vs-clear selector

Bit 7 has dual meaning: when read, bit 7 is the actual interrupt request (1 = any enabled interrupt is pending). When written, bit 7 selects set-vs-clear mode: write 1 to set bits, 0 to clear bits (lower 4 bits).

The masked interrupt from each CIA is fed into bit 6 of the custom-chip INTREQ register (INTF_INT6 for CIAA, INTF_INT7 for CIAB).

Control register A (ciacra)

Drives Timer A and the serial port.

Bit Bit name Flag Meaning
0 CIACRAB_START CIACRAF_START Start/stop Timer A
1 CIACRAB_PBON CIACRAF_PBON Timer A PBON output mode
2 CIACRAB_OUTMODE CIACRAF_OUTMODE Timer A output mode (toggle / pulse)
3 CIACRAB_RUNMODE CIACRAF_RUNMODE Timer A run mode (continuous / one-shot)
4 CIACRAB_LOAD CIACRAF_LOAD Force-load Timer A from latch
5 CIACRAB_INMODE CIACRAF_INMODE Timer A input mode (0 = count Phi2, 1 = count CNT pulses)
6 CIACRAB_SPMODE CIACRAF_SPMODE Serial port mode (0 = output, 1 = input)
7 CIACRAB_TODIN CIACRAF_TODIN 50/60 Hz TOD input select (0 = 60 Hz NTSC, 1 = 50 Hz PAL)

Control register B (ciacrb)

Drives Timer B and the alarm register.

Bit Bit name Flag Meaning
0 CIACRBB_START CIACRBF_START Start/stop Timer B
1 CIACRBB_PBON CIACRBF_PBON Timer B PBON output mode
2 CIACRBB_OUTMODE CIACRBF_OUTMODE Timer B output mode (toggle / pulse)
3 CIACRBB_RUNMODE CIACRBF_RUNMODE Timer B run mode
4 CIACRBB_LOAD CIACRBF_LOAD Force-load Timer B from latch
5 CIACRBB_INMODE0 CIACRBF_INMODE0 Timer B input mode (low bit)
6 CIACRBB_INMODE1 CIACRBF_INMODE1 Timer B input mode (high bit)
7 CIACRBB_ALARM CIACRBF_ALARM 0 = write TOD registers, 1 = write ALARM registers

Timer B input mode (2-bit selector)

INMODE1 INMODE0 Mode Flag
0 0 Count Phi2 clock CIACRBF_IN_PHI2
0 1 Count CNT pulses CIACRBF_IN_CNT
1 0 Count Timer A underflows CIACRBF_IN_TA
1 1 Count CNT pulses + Timer A underflows CIACRBF_IN_CNT_TA

CIAA port A pins ($BFE001)

Peripherals tied to each bit of ciapra on CIAA:

Bit Bit name Flag Peripheral
0 CIA_OVERLAY CIAF_OVERLAY Memory overlay (1 = overlay RAM, 0 = Kickstart ROM)
1 CIA_LED CIAF_LED Power LED (0 = bright, 1 = dim)
2 CIA_DSKCHANGE CIAF_DSKCHANGE Disk change* (active low)
3 CIA_DSKPROT CIAF_DSKPROT Disk write-protect* (active low)
4 CIA_DSKTRACK0 CIAF_DSKTRACK0 Disk on track 00* (active low)
5 CIA_DSKRDY CIAF_DSKRDY Disk ready* (active low)
6 CIA_GAMEPORT0 CIAF_GAMEPORT0 Gameport 0 fire button (active low)
7 CIA_GAMEPORT1 CIAF_GAMEPORT1 Gameport 1 fire button (active low)

(* = active-low signal — the input reads 0 when the condition is true.)

CIAB port A pins ($BFD000)

Serial port and parallel (printer) port handshaking:

Bit Bit name Flag Peripheral
0 CIA_PRTRBUSY CIAF_PRTRBUSY Printer busy
1 CIA_PRTRPOUT CIAF_PRTRPOUT Printer paper out
2 CIA_PRTRSEL CIAF_PRTRSEL Printer SELECT
3 CIA_COMDSR CIAF_COMDSR Serial Data Set Ready
4 CIA_COMCTS CIAF_COMCTS Serial Clear to Send
5 CIA_COMCD CIAF_COMCD Serial Carrier Detect
6 CIA_COMRTS CIAF_COMRTS Serial Request to Send* (output)
7 CIA_COMDTR CIAF_COMDTR Serial Data Terminal Ready* (output)

CIAB port B pins ($BFD100)

Floppy disk stepper control:

Bit Bit name Flag Peripheral
0 CIA_DSKSTEP CIAF_DSKSTEP Disk step pulse*
1 CIA_DSKDIREC CIAF_DSKDIREC Disk seek direction (1 = inward)
2 CIA_DSKSIDE CIAF_DSKSIDE Disk side select*
3 CIA_DSKSEL0 CIAF_DSKSEL0 Disk select unit 0*
4 CIA_DSKSEL1 CIAF_DSKSEL1 Disk select unit 1*
5 CIA_DSKSEL2 CIAF_DSKSEL2 Disk select unit 2*
6 CIA_DSKSEL3 CIAF_DSKSEL3 Disk select unit 3*
7 CIA_DSKMOTOR CIAF_DSKMOTOR Disk motor* (active low)

CIAA port B pins ($BFE101)

Parallel (printer) bidirectional data port — bits not individually named in hardware headers; used directly for Centronics handshake and 8-bit data.

Time-of-day clock (ciatod)

The TOD clock is a BCD 24-hour clock incremented every 1/10 second (or by external 50/60 Hz line frequency when CIACRAB_TODIN selects PAL/NTSC mode).

Register Range BCD format
ciatodlow 0–9 1/10 seconds (bit 7 = 0)
ciatodmid 0–59 seconds
ciatodhi 0–23 + AM/PM bit hours + AM/PM flag (bit 7)

When the TOD equals the ALARM registers, the CIA raises CIAICRF_ALRM (turning it into an interrupt if enabled).

Cross-references