CIA

Aus C64-Wiki
Zur Navigation springenZur Suche springen
Produktionsdatum dieses CIA: 1985 - Kalenderwoche 13

Der CIA (Complex Interface Adapter) ist ein Interface-Chip, der in Commodore-Heimcomputern eingebaut ist. Er stellt diverse interne Steuerungssignale und Ein- und Ausgabeleitungen sowie Timer und eine Echtzeituhr zur Verfügung. Der CIA wurde von dem Halbleiterhersteller MOS Technology entwickelt, der 1976 von Commodore übernommen wurde. Im C64 befinden sich zwei CIA 6526. Vorgänger des CIA war der VIA, der u. a. in der Commodore 1541 Verwendung fand.

Einzelheiten des CIA 6526[Bearbeiten | Quelltext bearbeiten]

  • 16 einzeln programmierbare Ein- und Ausgabeleitungen (TTL, Open Collector).
    • Im C64 werden einige dieser Leitungen zur Abfrage/Ansteuerung der Ein-/Ausgabegeräte (Tastatur, Joystick, IEC-Bus etc.) benutzt, einige sind mit dem VIC verbunden und legen den für ihn sichtbaren Speicherbereich fest, andere stehen zur freien Verfügung und sind am Userport herausgeführt.
    • Die Leitungen sind als Open Collector mit internen Pullups[1] herausgeführt.
    • Die Pullups erlauben Stromentnahme (Leitung auf High/Ausgang) bis etwa 1 mA pro Leitung; die Treibertransistoren sind für etwa 3 mA spezifiziert (Low/Ausgang). Es darf auf keinen Fall eine Spannung größer 0 V ohne entsprechenden Schutzwiderstand o.ä. angeschlossen werden, da der im Falle des Leitungszustands Low/Ausgang in die CIA fließende Strom den jeweiligen Treibertransistor zerstören würde. Das Schalten von Pins direkt auf Masse oder gegen eine andere Open-Collector-Leitung dagegen ist problemlos möglich, da der Pullup-Widerstand den fließenden Strom dann begrenzt.
    • Port B hat zusätzlich relativ hochohmige aktive Pullups, was in der Praxis kaum Unterschied macht.[2]
    • Lesen der Register PRA/PRB gibt immer den tatsächlichen gelesenen Zustand der Datenleitungen zurück, auch wenn die Leitungen per DDRA/DDRB als Ausgänge geschaltet sind.
  • 8- oder 16-Bit-Datentransport (lesend und schreibend) mit Handshake-Funktion.
  • 2 unabhängige 16-Bit-Intervalltimer mit Kaskadierungsmöglichkeit.
    • Jeder Timer besteht aus einem 16-Bit-Latch (Startwert) und dem eigentlichen 16-Bit-Timer.
    • Das Latch kann man direkt setzen, den Timer nur lesen bzw. indirekt über das Latch setzen.
    • Der Timer kann von der Chip-Frequenz, von einem externen Signal oder ein Timer vom Unterlauf des anderen (in Kaskade) getaktet werden.
  • 24-Stunden-Zeituhr ("Time of Day"/TOD, AM/PM) mit programmierbarem Alarm, getaktet per eigenem 50/60-Hz-Takteingang
  • 8-Bit-Schieberegister für serielle Ein- und Ausgabe.
    • Am Userport herausgeführt.
    • Open-Drain-Leitung, erlaubt die Zusammenschaltung zu einem Bus.
    • Das Einlesen erfordert einen externen Takt.
  • 2 TTL-Handshake-Leitungen, flankengesteuert/-sensitiv (1 Ausgang PC, 1 Eingang FLAG)
    • Wird im C64 standardmäßig nur beim Kassettenport (Leseleitung) verwendet.
    • Teilweise am Userport herausgeführt.
  • CMOS-kompatibel
  • Taktung: 1 MHz (6526) oder 2 MHz (6526A) oder 3 MHz (6526B)

Speicheradressen der CIAs[Bearbeiten | Quelltext bearbeiten]

Folgende Speicheradressen werden von den beiden CIA-Chips im C64 belegt:

CIA 1[Bearbeiten | Quelltext bearbeiten]

Adressbereich: $DC00-$DCFF, 56320-56575 Aufgaben: Tastatur, Joystick, Paddles, Datasette, Userport, IRQ-Steuerung
Adresse
Hex
Adresse
Dez
Register Funktion Bemerkung
$DC00 56320 0
PRA
Daten Port A Abfrage/Steuerung der acht Datenleitungen von Port A. Die Leitungen sind mehrfach belegt:

Lesen/Schreiben: Bit 0..7 Tastaturmatrixspalten
Lesen: Joystick Port 2: Bit 0..3 Richtung (Bit 0: hoch, Bit 1: runter, Bit 2: links, Bit 3: rechts), Bit 4 Feuerknopf. 0 = aktiviert.
Paddle: Lesen Bit 2..3 Feuerknöpfe, Schreiben Bit 6..7 Auswahl Port 1 (%01) oder Port 2 (%10), Lesen der Werte dann via SID $D419/D41A

$DC01 56321 1
PRB
Daten Port B Abfrage/Steuerung der acht Datenleitungen von Port B. Ein Schreiben oder Auslesen dieses Ports bewirkt die Ausgabe eines Low-Pulses auf Handshake-Leitung PC für die Dauer eines Systemtaktzyklus (beim C64 nicht verwendet). Die Leitungen sind mehrfach belegt:

Lesen/Schreiben: Bit 0..7 Tastaturmatrixzeilen
Lesen: Joystick Port 1: Bit 0..3 Richtung (Bit 0: hoch, Bit 1: runter, Bit 2: links, Bit 3: rechts), Bit 4 Feuerknopf. 0 = aktiviert.
Paddle: Lesen Bit 2..3 Feuerknöpfe
Lesen: Lightpen: Bit 4 (wie Feuerknopf), auch mit LP (Pin 9) des VIC verbunden
Lesen: Bit 6: Timer A: Toggle/Impulsausgang (siehe Register 14 Bit 2)
Lesen: Bit 7: Timer B: Toggle/Impulsausgang (siehe Register 15 Bit 2)

$DC02 56322 2
DDRA
Datenrichtung
Port A
Bit X: 0=Eingang (nur lesen), 1=Ausgang (lesen und schreiben)
$DC03 56323 3
DDRB
Datenrichtung
Port B
Bit X: 0=Eingang (nur lesen), 1=Ausgang (lesen und schreiben)
$DC04 56324 4
TA LO
Timer A
Low-Byte
Lesen: aktueller Wert Timer A (Low-Byte)

Schreiben: Latch des Timers A setzen (Low-Byte)

$DC05 56325 5
TA HI
Timer A
High-Byte
Lesen: aktueller Wert Timer A (High-Byte)

Schreiben: Latch des Timers A setzen (High-Byte) - falls der Timer gestoppt ist, wird gleichzeitig das High-Byte des Timers neu gesetzt

$DC06 56326 6
TB LO
Timer B
Low-Byte
Lesen: aktueller Wert Timer B (Low-Byte)

Schreiben: Latch des Timers B setzen (Low-Byte)

$DC07 56327 7
TB HI
Timer B
High-Byte
Lesen: aktueller Wert Timer B (High-Byte)

Schreiben: Latch des Timers B setzen (High-Byte) - falls der Timer gestoppt ist, wird gleichzeitig das High-Byte des Timers neu gesetzt

$DC08 56328 8
TOD 10THS
Echtzeituhr
1/10 s
Lesen:

Bit 0..3: Zehntelsekunden im BCD-Format ($0-$9)
Bit 4..7: immer 0
Schreiben:
Bit 0..3: wenn CRB-Bit7=0: Setzen der Zehntelsekunden im BCD-Format
Bit 0..3: wenn CRB-Bit7=1: Vorwahl der Zehntelsekunden der Alarmzeit im BCD-Format

$DC09 56329 9
TOD SEC
Echtzeituhr
Sekunden
Bit 0..3: Einersekunden im BCD-Format ($0-$9)

Bit 4..6: Zehnersekunden im BCD-Format ($0-$5)
Bit 7: immer 0

$DC0A 56330 10
TOD MIN
Echtzeituhr
Minuten
Bit 0..3: Einerminuten im BCD-Format( $0-$9)

Bit 4..6: Zehnerminuten im BCD-Format ($0-$5)
Bit 7: immer 0

$DC0B 56331 11
TOD HR
Echtzeituhr
Stunden
Bit 0..3: Einerstunden im BCD-Format ($0-$9)

Bit 4..6: Zehnerstunden im BCD-Format ($0-$5)
Bit 7: Unterscheidung AM/PM, 0=AM, 1=PM
Schreiben in dieses Register stoppt TOD, bis Register 8 (TOD 10THS) geschrieben wird.
Lesen aus diesem Register friert alle TOD-Register ein (TOD läuft aber weiter), bis Register 8 (TOD 10THS) gelesen wird.
Anomalie beim Schreiben und und Lesen von 12-Stundenwerten, siehe Abschnitt Fehler.

$DC0C 56332 12
SDR
Serielles
Schieberegister
Am SP-Pin wird das Byte in diesem Register bitweise mit jeder positiven Flanke am CNT-Pin eingelesen bzw. hinausgeschoben (bei letzterem kann CNT auch von TIMER-A-Unterläufen getrieben sein).
Die Signale SP und CNT sind am Userport (Pin 5 bzw. 4) herausgeführt.
$DC0D 56333 13
ICR
Interrupt Control
und Status
CIA1 ist mit der IRQ-Leitung der CPU verbunden.

Lesen: (Bit0..4 = INT DATA, Herkunft des Interrupts)
Bit 0: 1 = Unterlauf Timer A
Bit 1: 1 = Unterlauf Timer B
Bit 2: 1 = Gleichheit von Uhrzeit und Alarmzeit
Bit 3: 1 = SDR (Schieberegister) vollständig abgearbeitet, also ein vollständiges Byte übertragen, abhängig von der Betriebsart des Schieberegisters (lesend, schreibend)
Bit 4: 1 = Am FLAG-Pin (Handshake-Leitung) ist eine negative Flanke aufgetreten (Kassettenport D-4, READ-Leitung und serielle Schnittstelle SRQ IN - wird von den KERNAL-Routinen nur für Kassettenport verwendet)
Bit 5..6: immer 0
Bit 7: 1 = IRQ Ein Interrupt ist aufgetreten, also Übereinstimmung mindestens eines Bits von INT MASK und INT DATA
Die Bits werden durch das Lesen gelöscht!
Schreiben: (Bit 0..4 = INT MASK, Interruptmaske)
Bit 0: 1 = Interruptfreigabe für Timer A Unterlauf.
Bit 1: 1 = Interruptfreigabe für Timer B Unterlauf.
Bit 2: 1 = Interruptfreigabe für Uhrzeit-Alarmzeit-Übereinstimmung.
Bit 3: 1 = Interruptfreigabe für das Ende der Übertragung eines kompletten Bytes über das serielle Schieberegister.
Bit 4: 1 = Interruptfreigabe für das Erkennen einer negativen Flanke am FLAG-Pin.
Bit 5..6: unbenutzt
Bit 7: Quellbit: 0 = jedes gesetzte Bits 0..4 löscht das entsprechende Masken-Bit. 1 = jedes gesetzte Bits 0..4 setzt das entsprechende Masken-Bit. Gelöschte Bits 0..4 lassen die Maske also in jedem Fall unverändert.

$DC0E 56334 14
CRA
Control Timer A Bit 0: 0 = Stop Timer; 1 = Start Timer

Bit 1: 1 = Zeigt einen Timer Unterlauf an Port B in Bit 6 an
Bit 2: 0 = Bei Timer Unterlauf wird an Port B das Bit 6 invertiert , 1 = Bei Timer-Unterlauf wird an Port B das Bit 6 für einen Systemtaktzyklus High
Bit 3: 0 = Timer-Neustart nach Unterlauf (Latch wird neu geladen), 1 = Timer stoppt nach Unterlauf
Bit 4: 1 = Einmalig Latch in den Timer laden
Bit 5: 0 = Timer wird mit der Systemfrequenz getaktet, 1 = Timer wird von positiven Flanken am CNT-Pin getaktet
Bit 6: Richtung des seriellen Schieberegisters, 0 = SP-Pin ist Eingang (lesen), 1 = SP-Pin ist Ausgang (schreiben)
Bit 7: Echtzeituhr, 0 = 60 Hz, 1 = 50 Hz an Pin 19

$DC0F 56335 15
CRB
Control Timer B Bit 0: 0 = Stop Timer; 1 = Start Timer

Bit 1: 1 = Zeigt einen Timer Unterlauf an Port B in Bit 7 an
Bit 2: 0 = Bei Timer Unterlauf wird an Port B das Bit 7 invertiert , 1 = Bei Timer-Unterlauf wird an Port B das Bit 7 für einen Systemtaktzyklus High
Bit 3: 0 = Timer-Neustart nach Unterlauf (Latch wird neu geladen), 1 = Timer stoppt nach Unterlauf
Bit 4: 1 = Einmalig Latch in den Timer laden
Bit 5..6: Timer wird getaktet ...

  • %00 = mit der Systemfrequenz
  • %01 = von positiver Flanke am CNT-Pin
  • %10 = vom Unterlauf des Timer A
  • %11 = vom Unterlauf des Timer A, wenn CNT-Pin High ist

Bit 7: 0 = Schreiben in die TOD-Register setzt die Uhrzeit, 1 = Schreiben in die TOD-Register setzt die Alarmzeit

$DC10-$DCFF 56336-56575 - - Die CIA 1 Register wiederholen sich alle 16 Bytes

CIA 2[Bearbeiten | Quelltext bearbeiten]

Der zweite CIA-Chip ist identisch mit dem ersten. Deshalb sind in der folgenden Tabelle nur Einträge zu finden, die sich auf die spezifische Verwendung im C64 beziehen.

Adressbereich: $DD00-$DDFF, 56576-56831 Aufgaben: Serielle Schnittstelle, RS-232, VIC Speicheradressierung, Userport, NMI-Steuerung
Adresse
Hex
Adresse
Dez
Register Funktion Bemerkung
$DD00 56576 0
PRA
Daten Port A Bit 0..1: Auswahl der Position des VIC-Speichers
  • %00, 0: Bank 3: $C000-$FFFF, 49152-65535
  • %01, 1: Bank 2: $8000-$BFFF, 32768-49151
  • %10, 2: Bank 1: $4000-$7FFF, 16384-32767
  • %11, 3: Bank 0: $0000-$3FFF, 0-16383 (Standard)

Bit 2: RS-232: TXD Ausgang, Userport: Daten PA 2 (Pin M)
Bit 3..5: Serielle Schnittstelle Ausgang (0=High/Inactive, 1=Low/Active)

  • Bit 3: ATN OUT
  • Bit 4: CLOCK OUT
  • Bit 5: DATA OUT

Bit 6..7: Serielle Schnittstelle Eingang (0=Low/Active, 1=High/Inactive)

  • Bit 6: CLOCK IN
  • Bit 7: DATA IN
$DD01 56577 1
PRB
Daten Port B Bit 0..7: Userport Daten PB 0-7 (Pins C,D,E,F,H,J,K,L), außerdem Userport (Pin 8) Handshake-Leitung PC, die bei jedem Schreiben oder Lesen des Ports aktiv wird.

Der KERNAL bietet einige RS232-Routinen an, die die Pins folgendermaßen benutzen:
Bit 0, 3..7: RS-232: lesen

  • Bit 0: RXD
  • Bit 3: RI
  • Bit 4: DCD
  • Bit 5: Userport Pin J
  • Bit 6: CTS
  • Bit 7: DSR

Bit 1..5: RS-232: schreiben

  • Bit 1: RTS
  • Bit 2: DTR
  • Bit 3: RI
  • Bit 4: DCD
  • Bit 5: Userport Pin J
$DD02 56578 2
DDRA
Datenrichtung
Port A
siehe CIA 1
$DD03 56579 3
DDRB
Datenrichtung
Port B
siehe CIA 1
$DD04 56580 4
TA LO
Timer A
Low-Byte
siehe CIA 1
$DD05 56581 5
TA HI
Timer A
High-Byte
siehe CIA 1
$DD06 56582 6
TB LO
Timer B
Low-Byte
siehe CIA 1
$DD07 56583 7
TB HI
Timer B
High-Byte
siehe CIA 1
$DD08 56584 8
TOD 10THS
Echtzeituhr
1/10 s
siehe CIA 1
$DD09 56585 9
TOD SEC
Echtzeituhr
Sekunden
siehe CIA 1
$DD0A 56586 10
TOD MIN
Echtzeituhr
Minuten
siehe CIA 1
$DD0B 56587 11
TOD HR
Echtzeituhr
Stunden
siehe CIA 1
$DD0C 56588 12
SDR
Serielles
Schieberegister
dazugehörige Signale SP und CNT sind am Userport (Pin 7 bzw. 6) herausgeführt, siehe CIA 1
$DD0D 56589 13
ICR
Interrupt Control
und Status
CIA2 ist an die NMI-Leitung der CPU angeschlossen.

Bit 4: 1 = NMI wenn negative Flanke am FLAG-Pin aufgetreten ist (RS-232 Daten empfangen, am Userport, Pin B, herausgeführt)
Bit 7: 1 = NMI Ein Interrupt ist aufgetreten, also Übereinstimmung mindestens eines Bits von INT MASK und INT DATA

$DD0E 56590 14
CRA
Control Timer A siehe CIA 1
$DD0F 56591 15
CRB
Control Timer B siehe CIA 1

Pinbelegung[Bearbeiten | Quelltext bearbeiten]

Pin Beschreibung
CIA 6526 - Pinbelegung.png Vss Versorgungsspannung 0 V, Systemmasse
PA0 - PA7 I/O-Port A Bit0-7 bidirektional
PB0 - PB7 I/O-Port B Bit0-7 bidirektional
PC Port Control - Ausgangs-Handshakeleitung: Ein Impuls von einem Taktzyklus zeigt an, dass die Daten am Port-B-Register gelesen wurden oder bereitstehen.
TOD Time Of Day - Takteingang für Echtzeituhr (50/60Hz) - ergibt sich beim C64 aus der Netzfrequenz.
Vcc Versorgungsspannung +5V DC
IRQ Interrupt Request (bei Interrupt nimmt dieser Ausgang einen Low-Pegel an.)
R/W High-Pegel = Lesen (Datentransfer aus dem CIA), Low-Pegel = Schreiben (Datentransfer in den CIA)
CS Chip Select - ein Low-Pegel an diesem Eingang bedeutet, dass die Daten am Datenbus gültig sind.
FLAG Dieser Eingang reagiert auf eine fallende Flanke und setzt das FLAG-Bit (Bit 4) im ICR-Register. Wenn das zugehörige Maskenbit gesetzt ist, wird zusätzlich ein Interrupt ausgelöst.
phi2 Systemtakteingang - Alle Datentransferaktionen finden nur bei High-Pegel statt.
DB0 - DB7 Datenbus Bits 0 - 7
RES Reseteingang - Ein Low-Pegel versetzt alle internen Register in den Grundzustand.
RS0 - RS3 Register Select - Mit diesen vier Adresseingängen wird eines der insgesamt 16 internen Register angewählt.
SP Serial Port - Ein/Ausgang für das serielle Schieberegister
CNT Count - Ein/Ausgang des Schieberegistertaktes oder Triggereingang für die Intervalltimer.

Fehler[Bearbeiten | Quelltext bearbeiten]

  • Echtzeituhr/TOD
    • Wenn das Stundenregister TOD HR (Register 11/$0B) den Wert BCD $12 erreicht (also Punkt Mittag bzw. Mitternacht), wird das PM-Flag (MSB) invertiert. Das heißt, wenn $12 geschrieben wird, enthält das Register den Wert $92 (BCD $12 + $80 für PM-Flag) und umgekehrt.[3]
      Das kann umgangen werden, in dem beim Schreiben statt $12 der Wert $00 verwendet wird (mit entsprechendem Bit 7), also $00 für 0 h un $80 für 12 h. Beim Wechsel auf die 12. Stunde wird von $11 (11 AM) auf den Wert $92 (12 PM) bzw. von $91 (11 PM) auf $12 (12 AM) geschaltet und dieser Wert dann auch gelesen.
  • 6526A
    • NMI löst einen Taktzyklus früher aus als bei originalen CIA 6526.[4]

Weblinks[Bearbeiten | Quelltext bearbeiten]

WP-W11.png Wikipedia: MOS Technology CIA
WP-W11.png Wikipedia: MOS Technology CIA Sprache:english
WP-W11.png Wikipedia: TTL
WP-W11.png Wikipedia: CMOS

Quellen[Bearbeiten | Quelltext bearbeiten]

  1. Genaugenommen benutzt Port A des CIA einen N-FET als Pullup und Port B einen schaltbaren N-FET als Highside in einer Push-Pull-ähnlichen Konfiguration; da es sich um NMOS, nicht CMOS handelt, verhält sich die Highside relativ hochohmig.
  2. Thema: J-CIA - CIA 6526/8521-Ersatz auf Forum64.de mit Diskussion zu den "aktiven Pullups" von Port B
  3. Thema: CIA TOD AM/PM-Flag verkehrt auf Forum64.de: TOD-Anomalie beim Schreiben/Lesen der 12. Stunde
  4. Detecting 6526 vs 6526A CIA Chips auf codebase64.org Sprache:englisch