# CIA 6526 Register Reference Both CIA chips use the same register layout. CIA #1 = $DC00, CIA #2 = $DD00. ## Register Map (offset from chip base) | Offset | CIA#1 Addr | CIA#2 Addr | Name | Description | |--------|------------|------------|------|-------------| | +0 | $DC00 | $DD00 | PRA | Port A data register | | +1 | $DC01 | $DD01 | PRB | Port B data register | | +2 | $DC02 | $DD02 | DDRA | Port A direction (1=output) | | +3 | $DC03 | $DD03 | DDRB | Port B direction (1=output) | | +4 | $DC04 | $DD04 | TIMALO | Timer A low byte (latch/counter) | | +5 | $DC05 | $DD05 | TIMAHI | Timer A high byte | | +6 | $DC06 | $DD06 | TIMBLO | Timer B low byte | | +7 | $DC07 | $DD07 | TIMBHI | Timer B high byte | | +8 | $DC08 | $DD08 | TODTEN | TOD tenths of seconds (BCD) | | +9 | $DC09 | $DD09 | TODSEC | TOD seconds (BCD) | | +A | $DC0A | $DD0A | TODMIN | TOD minutes (BCD) | | +B | $DC0B | $DD0B | TODHR | TOD hours + AM/PM (bit 7) | | +C | $DC0C | $DD0C | SDR | Serial data register | | +D | $DC0D | $DD0D | ICR | Interrupt control register | | +E | $DC0E | $DD0E | CRA | Control register A | | +F | $DC0F | $DD0F | CRB | Control register B | ## CIA #1 ($DC00) — Keyboard and Joystick ### Port A ($DC00) — Keyboard Column Select / Joystick 2 - Writing to $DC00 selects keyboard columns to scan (0=select) - Reading $DC00 gives joystick 2 state (bits 0-4, active low) ### Port B ($DC01) — Keyboard Row Read / Joystick 1 - Reading $DC01 returns keyboard row data for selected column - Also joystick 1 state (bits 0-4, active low) ### Keyboard Matrix The keyboard is a 8×8 matrix. To read a key: 1. Write column mask to $DC00 (0 selects that column) 2. Read rows from $DC01 | Bit set in $DC00 column | Keys in that column | |------------------------|---------------------| | $FE (col 0) | DEL, RETURN, ←→, F7, F1, F3, F5, ↑↓ | | $FD (col 1) | 3, W, A, 4, Z, S, E, Left Shift | | $FB (col 2) | 5, R, D, 6, C, F, T, X | | $F7 (col 3) | 7, Y, G, 8, B, H, U, V | | $EF (col 4) | 9, I, J, 0, M, K, O, N | | $DF (col 5) | +, P, L, -, ., :, @, , | | $BF (col 6) | £, *, ;, Home, Right Shift, =, ↑, / | | $7F (col 7) | 1, ←, CTRL, 2, Space, C=, Q, Stop | ### Joystick Bits ($DC00 joystick 2 / $DC01 joystick 1) ``` Bit 0: Up (0=pressed) Bit 1: Down (0=pressed) Bit 2: Left (0=pressed) Bit 3: Right (0=pressed) Bit 4: Fire (0=pressed) ``` ```basic J = PEEK(56321) ' Read joystick 1 ($DC01) IF (J AND 16) = 0 THEN PRINT "FIRE!" IF (J AND 1) = 0 THEN PRINT "UP!" ``` ## CIA #2 ($DD00) — Serial Bus and VIC-II Bank ### Port A ($DD00) — Serial Bus / VIC-II Bank ``` Bit 7: Serial bus data line (input) Bit 6: Serial bus clock line (input) Bit 5: Serial bus data line (output) Bit 4: Serial bus attention ACK (output) Bit 3: Serial bus clock (output) Bit 2: RS-232 data output (User Port) Bit 1: VIC-II bank select bit 1 \ Together: 00=bank3, 01=bank2 Bit 0: VIC-II bank select bit 0 / 10=bank1, 11=bank0(default) ``` ```basic ' Switch VIC-II to Bank 1 ($4000-$7FFF) POKE 56576, (PEEK(56576) AND 252) OR 2 ' Bank 0 (default): POKE 56576, (PEEK(56576) AND 252) OR 3 ``` ## Control Register A (CRA — $DC0E / $DD0E) ``` Bit 7: TODIN — TOD clock: 1=60Hz, 0=50Hz Bit 6: SPMODE — Serial port: 1=output, 0=input Bit 5: INMODE — Timer A input: 1=CNT pulses, 0=system clock Bit 4: LOAD — Force load timer (write 1 to reload latch into counter) Bit 3: RUNMODE — 0=continuous, 1=one-shot Bit 2: OUTMODE — Timer A output to PB6: 1=pulse, 0=toggle Bit 1: PBON — Port B output enable (1=Timer A appears on PB6) Bit 0: START — 1=start timer, 0=stop timer ``` ## Control Register B (CRB — $DC0F / $DD0F) ``` Bit 7: ALARM — 1=write TOD alarm, 0=write TOD clock Bit 6: INMODE (high bit) — with bit 5: timer B source Bit 5: INMODE (low bit) — 00=φ2 clock, 01=CNT, 10=Timer A, 11=TimA/CNT Bit 4: LOAD — Force load Bit 3: RUNMODE — 0=continuous, 1=one-shot Bit 2: OUTMODE — Timer B output to PB7 Bit 1: PBON — Port B output enable Bit 0: START — 1=start, 0=stop ``` ## Interrupt Control Register ($DC0D / $DD0D) **Reading**: Returns interrupt flags (1=occurred), clears all flags on read **Writing**: Sets/clears interrupt enables ``` Bit 7: (read) IRQ occurred (any source) / (write) 1=enable, 0=disable bits 0-4 Bit 4: FLG — FLAG pin interrupt Bit 3: SP — Serial port interrupt Bit 2: ALRM — TOD alarm interrupt Bit 1: TB — Timer B interrupt Bit 0: TA — Timer A interrupt ``` ## Timer Calculations Timer counts down from latch value to 0, then triggers interrupt and reloads. ``` Timer Period = (latch value + 1) / clock_frequency NTSC: clock = 1,022,727 Hz PAL: clock = 985,248 Hz For 1/60 second at NTSC: latch = 1,022,727 / 60 - 1 = 17,044 = $4294 For 1/50 second at PAL: latch = 985,248 / 50 - 1 = 19,704 = $4CB8 ``` ```asm ; Set CIA #1 Timer A for ~1/60 second, continuous IRQ LDA #$94 ; $4294 low byte STA $DC04 LDA #$42 ; high byte STA $DC05 LDA #$81 ; enable Timer A IRQ STA $DC0D LDA #$11 ; start timer, continuous, system clock STA $DC0E ```