amiga-bootcamp/01_hardware/common/cia_chips.md
2026-06-02 11:57:54 -04:00

8.4 KiB
Raw Blame History

← Home · Hardware

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 D0D7.

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 SDR baud 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.ciatodhiciaa.ciatodmidciaa.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
63 /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 /SEL0 and 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

See Also