IBM-PC Parallel-Printerport
Der Original IBM-PC Printerport hat insgesamt 12 digitale Ausgänge und 5 digitale Eingänge, die über 3 hintereinanderliegende 8-Bit-Ports angesprochen werden
  • 8 Ausgangsbits über den DATA Port
  • 5 Eingangsbits (davon eines invertiert) über den STATUS Port
  • 4 Ausgangsbits (davon drei invertiert) über den CONTROL Port
  • Die übrigen 8 Pins liegen an Masse

Anschlußbelegung am 25-poligen DB-Stecker (w)*

Im Laufe der Jahre sind verbesserte Versionen der Original-Spezifikation hinzugekommen:

  • Bi-direktional (PS/2)
  • Enhanced Parallel Port (EPP)
  • Extended Capability Port (ECP)

Der 'alte' Printerport wird heute meist als SPP = STANDARD PRINTER PORT bezeichnet. Die folgende Beschreibung bezieht sich auf SPP.

Programmierung
In den Ur-PCs war die Druckerschnittstelle auf den (monochromen !!!) Hercules-Grafikkarten untergebracht. Hier war die Basisadresse meistens 3BC-3BE. Heute findet man die Druckerschnittstelle(n)  auf 278-27A, eine zweite auf 378-37A (alle Adressen hexadezimal). Für die erste Schnittstelle ist traditionell der Interrupt 7, für die zweite der Interrupt 5 reserviert. Früher lag auf Interrupt 5 oft auch eine ISA-Soundkarte.

Das BIOS liefert bei Bedarf die Basisadressen (je 2 Bytes) des/der Druckerports:

Startadresse Druckerport
0000:0408 LPT1
0000:040A LPT2
0000:040C LPT3
0000:040E LPT4

Bei den heutigen PCs liegt die Basisadresse des Druckerports (LPT1) im allgemeinen auf 378, der zugehörige Interrupt ist die Nr. 7

Die Ausgangs-Latches können auch gelesen werden. Auf diese Weise kann man feststellen, ob an der Ziel-Portadresse ein Controller angesprochen wird oder ob die Ausgabe 'ins Leere' geht.

Ports
Die Parallelschnittstelle reagiert auf zwei Ausgabeports und drei Eingabeports.

Die Ausgabeports übergeben die geschriebenen Daten an jeweils ein Register (Latch) und die entsprechenden Bits erscheinen auf den Ausgängen an der DB25 Buchse.

(Vorangestelltes n bedeutet, dass das Signal invertiert ist)

Ausgabe an Basisadresse+0 DATAPORT (278/378/3BC)

Bit 7 6 5 4 3 2 1 0
Pin 9 8 7 6 5 4 3 2

Ausgabe an Basisadresse+2 CONTROLPORT (27A/37A/3BE)

Bit 7 6 5 4 3 2 1 0
Pin     Bidir.
enable
IRQ
enable
-17 16 -14 -1
Drucker
Signal
        nSelect Initialize nAuto LF nStrobe

Mit der Ausgabe an den Controlport werden die 4 niederwertigen Bits ins Register geladen. Die Bits 0,1,und 3 werden dabei von der Hardware invertiert.
Bit 4 steuert die Interruptfreigabe: Wenn Bit 4 auf H gesetzt wird, erzeugt eine fallende Flanke an Bit 6 des Statusports (Pin 10) einen Hardware-Interrupt  (IRQ 7 für LPT1).

Eingabe von Basisadresse+0 DATAPORT (278/378/3BC)
Input von dieser Adresse liefert die zuletzt geschriebenen Bitkombination des Dataports.

Eingabe von Basisadresse+1 STATUSPORT (279/379/3BD)
Dieser Port liefert die Statusbits

Bit 7 6 5 4 3 2 1 0
Pin 11 10 12 13 15      
Drucker
Signal
Busy nAck Paper Out Select In nError      

 

Eingabe von Basisadresse+2 CONTROLPORT (27A/37A/3BE)
Dieser Befehl liest die an den Controlport zuletzt ausgegebene Bitkombination zurück. Die gesamte Controllerlogik hängt am Reset des Mainboards, so dass bei einem Hardware-Reset die Standard-Einstellungen wiederhergestellt werden.

Bit 7 6 5 4 3 2 1 0
Pin       IRQ
enable
n17 16 n14 n1
Zustand nach Reset
        0 1 0 1 1

Besonderheiten:
Die Printerport-Ausgänge sind nicht genormt. Ein traditioneller Ausgang  liefert ca. 2,5 mA gegen Masse und 25mA gegen +5V. Es gibt auch alte Druckerschnittstellen mit offenem Kollektor oder 'Totem-Pole' Ausgang. Es ist angeblich sogar möglich, die Ausgänge zu lesen, wenn sie von außen mit dem notwendigen Strom auf einen anderen als den über den Port ausgegebenen Zustand gezogen werden (das hab' ich aber nie ausprobiert).

Druckbetrieb
Wenn der Adapter zur Steuerung eines Druckers verwendet wird, werden die zu druckenden Daten an den gepufferten 8-Bit-Datenport ausgegeben und anschließend für min. 1 µs das nStrobe-Bit auf L gesetzt. Der Drucker reagiert, indem er sein Busy-Signal so lange auf H-Pegel hält, bis er bereit ist, das nächste Zeichen zu empfangen. Am Ende der Busy-Phase nimmt der Drucker kurzzeitig das nAck-Signal auf L, so dass ein Hardware-Interrupt ausgelöst wird, wenn Bit 6 des Statusports auf H liegt. Wenn das System sonst nichts zu tun hat, kann man das Busy-Signal oder das nAck-Signal 'pollen', d.h. in einer Schleife wird so lange warten, bis es am Busy-Eingang oder am nAck eine fallende Flanke gegeben hat. Dieses Verfahren arbeitet allerdings nur dann zuverlässig, wenn das steuernde System zu jeder Zeit wesentlich schneller ist als das angeschlossene Gerät. Wenn man z.B. mit einer 'alten Kiste' nach dem Strobe auf die negative Busy-Flanke wartet, kann es bei einem schnellen Drucker passieren, dass das Busy auf H geht und schon wieder auf L ist, bevor die Abfrage überhaupt erfolgt ist - das Busy wird 'verschlafen' und das Handshake kommt zum Stillstand.

Die elegante Lösung mit dem Interrupt ist nicht kinderleicht und eine Herausforderung für den Programmierer. Es folgt hier später einmal eine Beschreibung, wie man so etwas in Pascal zaubern kann.

Quellen und Links

Wesentlich weitergehende Informationen (allerdings auf Englisch) gibt's hier:

http://retired.beyondlogic.org