Centronics-Schnittstelle

Aus C64-Wiki
Zur Navigation springenZur Suche springen

Unter Centronics-Schnittstelle versteht man eine Druckerschnittstelle des nicht mehr existierenden Druckerherstellers Centronics, der diese Schnittstelle bei seinem Drucker verwendete. Ursprünglich entstand die CENTRONICS-Schnittstelle Ende der 1960er Jahre bei der Firma Wang Laboratories, von denen sich kurz danach der Druckerhersteller CENTRONICS abspaltete.

Bis heute ist diese parallele Druckerschnittstelle bei vielen Computern und Druckern noch vorhanden, wird aber zunehmend von der USB-Schnittstelle verdrängt.

Aus der Centronics-Schnittstelle ging im Jahr 1994 der IEEE 1284 Standard für eine parallele Schnittstelle zur bidirektionalen Übertragung von Daten zwischen Computer und unterschiedlichen Peripheriegeräten (meist Drucker, aber auch Scanner und Datenlaufwerke) hervor.

Beschreibung[Bearbeiten | Quelltext bearbeiten]

Typische Steckerarten sind:

Da der C64/C128 keine Centronics-Schnittstelle hat, kann man sich mit einem Drucker-Userport-Kabel, angeschlossen am Userport behelfen, was aber entsprechende Unterstützung in Software zur Bedienung der Schnittstelle erforderlich macht. Alternativ gibt es auch ein Druckermodul für die serielle Schnittstelle des C64/128, z. B. von der Firma Wiesemann. In dieser Form kann die Schnittstelle auch ohne Software einfach mit den vorhandenen BASIC-Befehlen genutzt werden.

Die Signale der Centronics-Schnittstelle haben TTL-Pegel (0 V für low, 5 V für high in einem bestimmten Toleranzbereich) und können typischerweise maximal eine Verbindung bis zu 3,5 m (je nach Kabelqualität, bei entsprechender Schirmung eventuell sogar bis 5 m) Länge überbrücken.

Die Datenübertragung über diese Schnittstelle läuft über ein Handshake-Verfahren, das allerdings in gewissen Details von Geräten unterschiedlich ausgelegt und umgesetzt ist, was leider auch zu typischen Kompatibilitätsproblemen führt. Der klassische Ablaufzyklus sieht (ohne genaue Zeitspezifikation) bei einer Übertragung vom Computer zu einem Gerät folgendermaßen aus:

  1. Das zu übertragende Byte wird auf die 8 Datenleitungen angelegt, sofern das Signal BUSY nicht aktiv ist.
  2. Das Vorhandensein der Daten wird mit einer kurzen Aktivierung via STROBE angezeigt.
  3. Mit dem Aktivwerden von BUSY zeigt das Gerät nun an, dass die Daten "verarbeitet" werden und vorerst keine weiteren Daten angenommen werden können.
  4. Durch Aktivieren von ACK meldet das Gerät, dass nun weitere Daten folgen können und BUSY wird danach inaktiv.

Pinbelegung der Stecker[Bearbeiten | Quelltext bearbeiten]

Hinweise:

  • Ein Strich über dem Signalnamen bedeutet, dass das Signal bei Low-Pegel aktiv ist.

Richtung:

  • → bedeutet vom Computer zum Gerät
  • ← bedeutet vom Gerät zum Computer
  • – Signalmasse bzw. Masseleitung (0 V), ohne Datenflussrichtung

Pinbelegung 25-poliger D-Sub-Stecker (Typ A)[Bearbeiten | Quelltext bearbeiten]

Pin Name Richtung Funktion
1 STROBE Strobe, zeigt bei fallender Flanke gültige Daten an
2 D0 Datenbit 0
3 D1 Datenbit 1
4 D2 Datenbit 2
5 D3 Datenbit 3
6 D4 Datenbit 4
7 D5 Datenbit 5
8 D6 Datenbit 6
9 D7 Datenbit 7
10 ACK Acknowledge, Bestätigung des Druckers über Empfang der Daten
11 BUSY Busy, wenn nicht aktiv, zeigt die Bereitschaft des Druckers für weitere Daten an
12 PE Paper End, Papierende
13 SEL Select, zeigt Druckerstatus (on- oder offline) an
14 AUTOFD Autofeed, veranlasst nach Carriage Return (CR) einen Zeilenumbruch (LF)
15 ERROR Error
16 INIT Druckerreset
17 SELIN Select In, teilt dem Drucker mit, dass er angesprochen ist
18 GND Signalmasse
19 GND Signalmasse
20 GND Signalmasse
21 GND Signalmasse
22 GND Signalmasse
23 GND Signalmasse
24 GND Signalmasse
25 GND Signalmasse

Pinbelegungen Peripheriegerät, 36-poliger "Centronics"-Stecker (Typ B)[Bearbeiten | Quelltext bearbeiten]

Pin Name Richtung Funktion
1 STROBE Strobe, zeigt bei fallender Flanke gültige Daten an
2 D0 Datenbit 0
3 D1 Datenbit 1
4 D2 Datenbit 2
5 D3 Datenbit 3
6 D4 Datenbit 4
7 D5 Datenbit 5
8 D6 Datenbit 6
9 D7 Datenbit 7
10 ACK Acknowledge
11 BUSY Busy
12 POUT Paper Out (kein Papier mehr)
13 SEL Select
14 AUTOFEED Autofeed
15 N/C nicht belegt
16 0 V Masse
17 CHASSIS GND Masse
18 +5 V PULLUP +5 V DC (50 mA max.)
19 GND Signalmasse (Strobe)
20 GND Signalmasse (D0)
21 GND Signalmasse (D1)
22 GND Signalmasse (D2)
23 GND Signalmasse (D3)
24 GND Signalmasse (D4)
25 GND Signalmasse (D5)
26 GND Signalmasse (D6)
27 GND Signalmasse (D7)
28 GND Signalmasse (Acknowledge)
29 GND Signalmasse (Busy)
30 GNDRESET Signalmasse (Reset)
31 RESET Reset
32 FAULT Fehler
33 0 V Masse
34 N/C nicht belegt
35 +5 V +5 V DC
36 SLCT IN Select In

Anschluss eines Druckers mit Centronics-Schnittstelle an den C64[Bearbeiten | Quelltext bearbeiten]

Es gibt zwei Möglichkeiten, den C64 mit einem Centronics-Drucker zu verbinden:

  1. Die komfortabelste Möglichkeit ist ein Interface, das an den seriellen IEC-Bus angeschlossen wird und die Daten an die Centronics-Schnittstelle des Druckers weiterleitet. Da ein solches Interface im Prinzip ein vollständiger Computer ist, ist es entsprechend teuer. Außerdem ist der serielle Bus relativ langsam, was sich insbesondere beim Drucken von Grafik bemerkbar machen kann. Dafür kann das Interface zusätzliche Aufgaben wie das Konvertieren von PETSCII- zu ASCII-Zeichencodes übernehmen.
  2. Eine weitaus günstigere Möglichkeit ist der Anschluss des Druckers über ein Userportkabel, allerdings muss dann auf dem C64 ein Treiberprogramm laufen oder die Software diese Schnittstelle explizit unterstützen. Weiterhin können die zusätzlichen Status- und Steuerleitungen der Centronics (PAPER END, AUTO FEED, SELECT usw.) nicht genutzt werden, da der Userport nur die unbedingt zur Datenübertragung nötigen Pins zur Verfügung stellt.

Anschluss über ein Centronics-Userport-Kabel[Bearbeiten | Quelltext bearbeiten]

Centronics-Userport-Kabel

Verbindungsplan des Userportkabels:

C64 Drucker Bemerkung
GND A GND 16 Es können auch andere Masse-Pins sowohl auf Userport-Seite (1, 12, N) als auch auf Druckerseite (19-30, 33) verwendet werden
Flag2 B BUSY/
ACK
11/
10
je nach Wahl des Pins sind unterschiedliche Routinen zur Datenübermittlung nötig
PB0 C D0 2
PB1 D D1 3
PB2 E D2 4
PB3 F D3 5
PB4 H D4 6
PB5 J D5 7
PB6 K D6 8
PB7 L D7 9
PA2 M STROBE 1
RESET 3 INIT 31 optional; wenn verbunden, wird bei einem C64-Reset auch der Drucker initialisiert

Ansteuerung des Druckers[Bearbeiten | Quelltext bearbeiten]

  1. (nur wenn Flag2 mit BUSY verbunden ist): Warten, bis am Flag2-Eingang von CIA2 das BUSY-Signal von aktiv auf inaktiv gewechselt hat (also den Low-Pegel erreicht hat) => Gerät ist bereit für die Zeichenübertragung
  2. zu übertragendes Zeichen in Register PRB der CIA schreiben
  3. Bit 2 von PRA der CIA löschen und unmittelbar darauf wieder setzen = STROBE-Signal an Drucker senden
  4. (nur wenn Flag2 mit ACK verbunden ist): Warten, bis am Flag2-Eingang das ACK-Signal von inaktiv auf aktiv gewechselt hat (also eine Änderung erfahren hat) => Drucker hat Zeichen verarbeitet

Minimal-Implementation eines Druckertreibers[Bearbeiten | Quelltext bearbeiten]

Der folgende Druckertreiber wird in den Kassettenpuffer geladen und benutzt die Geräteadresse 4.
Der Quelltext ist im ACME-Format.
Diese vereinfachte Implementierung nutzt hier nur das BUSY-Signal, wobei hier nicht der Zustand selbst, sondern nur die Änderung von aktiv auf inaktiv erkannt werden kann und berücksichtigt nicht die durch das ACK-Signal angezeigte Datenübernahme, was aber in der Praxis keinen Nachteil darstellt.

!to "centronics.obj", cbm 
* = $33C	; assemblieren in den Kassettenpuffer

vecCHROUT = $326
vecCHKOUT = $320

CIA2 = $DD00
CIA2_PRA  = CIA2
CIA2_PRB  = CIA2 + 1
CIA2_DDRA = CIA2 + 2
CIA2_DDRB = CIA2 + 3
CIA2_ICR  = CIA2 + 13

Init:           ; Aufruf aus BASIC mit SYS 828
; CHROUT-Vektor umbiegen
               LDA #<newCHROUT
               STA vecCHROUT
               LDA #>newCHROUT
               STA vecCHROUT + 1
 
; CHKOUT-Vektor umbiegen
               LDA #<newCHKOUT
               STA vecCHKOUT
               LDA #>newCHKOUT
               STA vecCHKOUT + 1

; CIA-Register initialisieren
               LDA CIA2_PRA 
               ORA #$04        ; STROBE auf High-Pegel
               STA CIA2_PRA
               LDA #$10
               STA CIA2_ICR    ; IRQ durch CIA2_ICR-Flag ausschalten
               LDA CIA2_DDRA
               ORA #$04        ; Datenrichtung für STROBE auf Ausgabe
               STA CIA2_DDRA
               LDA #$FF
               STA CIA2_DDRB   ; Datenrichtung für DATA auf Ausgabe

               LDA #$00
               BEQ toCentronics; NULL-Zeichen ausgeben, um BUSY-Flag zu intialisieren

newCHROUT:
               PHA             ; Zeichen auf Stack sichern
               LDA $9A         ; aktuelle Gerätenummer lesen
               CMP #$04        ; auf Ausgabegerät 4 testen
               BEQ +
               JMP $F1CD       ; wenn nicht, weiter in Originalroutine (Inhalt von $9A im Akku)
+
               LDA #$10        ; auf fallende Flanke (von aktiv auf inaktiv) von Flag2-Pin prüfen
               SEI             ; Keine Unterbrechungen und damit ohne Timing-Verzögerungen
-              BIT CIA2_ICR    ; Bit-Muster in Akku mit Register verknüpfen
               BEQ -           ; warten auf fallende Flanke des BUSY-Signals (im Register das Bit 1 ist)

               PLA             ; Zeichen vom Stack holen
toCentronics:
               STA CIA2_PRB    ; Ausgabebyte auf den Userport legen
               PHA             ; für Restauration beim Ausstieg
               LDA CIA2_PRA
               AND #!$04       ; STROBE kurz aktiv setzen (Low-Pegel)
               STA CIA2_PRA
               ORA #$04        ; und sofort wieder inaktiv (High-Pegel)
               STA CIA2_PRA

               CLI             ; Unterdrückung von IRQs wieder aufheben
               PLA             ; im Akku muss das Ausgabezeichen erhalten bleiben
               CLC             ; Fehler-Flag löschen
               RTS             ; und fertig

newCHKOUT:                     ; entsprechend dem Original ab $F250
               JSR $F30F       ; File-Index ermitteln
               BEQ +
               JMP $F701       ; "file not open" Fehler
+              JSR $F31F       ; aktuelle File-Parameter in Zeropage hinterlegen
                               ;  (File Number $B8, Device Number $BA, Secondary Address $B9)
               LDA $BA         ; Gerätenummer des Files ermitteln
               CMP #$04        ; auf Ausgabegerät 4 testen
               BEQ +           ; wenn nicht, dann
               JMP $F25B       ; weiter in originaler CHKOUT-Routine ($BA wird erneut geladen)

+              STA $9A         ; sonst aktuelle Ausgabegerätenummer setzen (vergl. $F275)
               CLC             ; Fehler-Flag löschen
               RTS             ; und fertig

Mit der Interrupt-Unterdrückung per SEI werden auch empfindlich auf das Timing reagierende Ausgabegeräte zuverlässig angesprochen. Nachteil ist allerdings, dass der Fortschritt des Systemtimers hier an Genauigkeit verliert.
Dennoch kann es passieren, dass ein dauerhaft gesetztes BUSY-Flag bei einem Gerät eine dauerhafte Blockierung verursacht. Diese kann dann nur noch durch die Tastenkombination für einen Warmstart RUN/STOP +RESTORE  beendet werden oder eventuell auch durch ein Hardware-Reset beim jeweiligen Gerät.

Weblinks[Bearbeiten | Quelltext bearbeiten]

WP-W11.png Wikipedia: IEEE 1284