Informationen Tastaturkontroller
Zeichen- und Tastaturcodes
Zur Programmierung des Tastaturkontrollers und der Verwendung von Tastaturabfragen sind verschiedene Codes von Bedeutung.
ASCII Code
Zeichen und Zeichenketten werden üblicherweise im ASCII-Code abgespeichert. Der American Standard Code for Information Interchange ist eine in der Computerwelt sehr weit verbreitete Zuordnungstabelle für die Darstellung von Buchstaben, Ziffern und Sonderzeichen. Ursprünglich waren pro Zeichen 7 Bits vorgesehen, mittlerweile haben sich aber 8 Bits, also die Darstellung in einem Byte durchgesetzt.
Scancode
Der Scancode ordnet den Tasten einer PC Tastatur eindeutige Nummern zu. Dadurch ist es auch möglich Tasten zu identifizieren, die keinem druckbaren Zeichen entsprechen (z.B. Cursortasten). Bei der Verwendung von Scancodes ist darauf zu achten, dass nicht zwischen Groß- und Kleinbuchstaben unterschieden wird, da beide mit derselben Taste erreicht werden (Groß- und Kleinschreibung ergibt sich aus der Kombination des Scancodes mit den Make- und Breakcodes). Im Laufe der PC Entwicklungsgeschichte wurden unterschiedliche Tastaturen mit einer unterschiedlichen Anzahl und Bedeutung von Tasten herausgebracht. Gerade bei den Funktions- und Spezialtasten gibt es daher auch unterschiedliche Scancodes. Da PC Tastaturen jedoch nur wenig mehr als 100 Tasten besitzen, genügen 7 Bits, um den Scancode einer PC Tastatur darzustellen.
Make- und Breakcodes
Programme müssen nicht nur feststellen können, welche der
normalen Tasten gedrückt wurden, sondern auch, ob gleichzeitig
die Shift (Umschalt)-Taste, die Control (Steuerungs)-Taste oder die ALT-Taste
festgehalten wurden.
Daher sendet die Tastatur statt eines einfachen Scancodes einen oder mehrere
sogenannte Makecodes für jedes Drücken und einen oder mehrere
Breakcodes für jedes Loslassen einer Taste. Wenn eine Taste länger
als eine bestimmte Zeitspanne festgehalten wird, werden darüberhinaus
zusätzliche Makecodes gesendet, durch die die Wiederholungsfunktion
realisiert wird. Bei den meisten Tasten entspricht sowohl der Makecode als
auch der Breakcode dem Scancode mit gesetztem 7. Bit.
Einige Tasten erzeugen jedoch aus historischen Gründen schon beim
einmaligen Drücken und Loslassen mehrere Make- und Breakcodes. Der
Tastaturtreiber (siehe 3. Aufgabe, Keyboard::prologue()
)
muss aus den Make- und Breakcodes der gedrückten Tasten die
gewünschten Zeichen ermitteln.
Anmerkung: Da die Interpretation der Make- und Breakcodes ziemlich mühsam, langweilig und wenig lehrreich ist, haben wir euch die Dekodierung bereits abgenommen. Es kann allerdings sein, dass diese Funktion bei eurer Tastatur nicht alle Zeichen, insbesondere die deutschen Umlaute korrekt erkennt. In diesem Fall müsst ihr entweder mit ein paar falschen Zeichen leben oder die Tabellen der Dekodierfunktion entsprechend anpassen.
Tastaturkontroller
Wenn bei einer PC-Tastatur eine Taste gedrückt wird, werden zwei
sich kreuzende Leitungen der Scan-Matrix innerhalb der Tastatur verbunden.
Der Tastaturprozessor (8042 für PC/XT-, 8048 für AT und
MF II-Tastaturen) ermittelt die Position der gedrückten Taste
und daraus den Scancode.
Über eine serielle Schnittstelle wird der Code dann zum Motherboard
des PCs gesendet. Auf dem Motherboard des PCs befindet sich ein
Tastaturcontroller, der einerseits über einen Eingabe- und einen
Ausgabeport mit der Tastatur kommuniziert (Tastaturkommandos).
Andererseits verwendet der Kontroller Register, die mit Hilfe von
in
und out
-Befehlen über den Systembus
gelesen und beschrieben werden können.
Port | R / W | Register | Bedeutung |
0x60 | R | Ausgabepuffer | Make/Breakcode von der Tastatur |
0x60 | W | Eingabepuffer | Befehle für die Tastatur (z.B. LEDs setzen) |
0x64 | W | Steuerregister | Befehle für den Tastaturcontroller |
0x64 | R | Statusregister | Zustand des Tastaturcontrollers (z.B. Ausgabepuffer voll?) |
Das Schreiben eines Bytes vom Tastaturontroller in seinen Ausgabepuffer
wird immer durch das Setzen einer Interruptanforderung signalisiert.
Auf diese Anforderung reagiert der Prozessor, indem er das
ankommende Byte aus dem Ausgabepuffer ausliest und im Statusregister
vermerkt, dass der Ausgabepuffer wieder leer ist. Erst jetzt können
neue Zeichen von der Tastatur entgegengenommen werden.
Wird die Tastatur im Pollingbetrieb benutzt, kann durch
Bit 0
überprüft werden, ob sich auch tatsächlich
ein Zeichen im Ausgabepuffer des Tastaturcontrollers befinden.
Soll ein Byte an den Kontroller geschickt werden
(z.B. Tastaturkommando), muss immer gewartet werden, bis der
Eingabepuffer des Kontrollers leer ist (Bit 1
gelöscht),
bevor der Buffer erneut beschrieben werden kann.
Beachtet werden sollte, dass bei PS/2 PCs die Maus ebenfalls an den
Tastaturkontroller angeschlossen ist. Dadurch landen sowohl die Codes der
Tastatur als auch die der Maus im Ausgabepuffer.
Damit die Quelle der Codes unterschieden werden kann, steht im Statusregister
das Bit 5 (AUXB
) zur Verfügung
(1 = Maus, 0 = Tastatur).
Bit | Maske | Name | Bedeutung |
0 | 0x01 | outb | Gesetzt, wenn ein Zeichen im Ausgabepuffer des Tastaturcontrollers zum Lesen bereit steht |
1 | 0x02 | inpb | Gesetzt, solange der Tastaturcontroller ein von der CPU geschriebenes Zeichen noch nicht abgeholt hat |
5 | 0x20 | auxb | Gesetzt, wenn der Wert im Ausgabepuffer von der Maus und nicht von der Tastatur stammt |
Tastaturcontroller programmieren
Der Tastaturcontroller kann durch das Senden von Befehlscodes an
den Eingabepuffer konfiguriert werden. Zuvor sollte man jedoch sicherstellen,
das der Eingabepuffer des Tastaturcontrollers leer ist (inpb
).
Danach wird der Befehlscode (siehe Tabelle) in den Datenport
geschrieben. Danach sollte man warten, bis der Tastaturcontroller geantwortet
hat und der Ausgabepuffer das Bestätigungsbyte 0xfa
(ACK
)
enthält (wieder vor dem Lesen outb prüfen).
Wir werden von den etwa 20 Befehlen, die der Tastaturcontroller versteht,
nur zwei verwenden:
Befehl | Steuercode |
set_led | 0xed |
set_speed | 0xf3 |
Die folgende Tabelle zeigt den Aufbau des Steuerbytes von
set_led
zum Ansteuern der Tastatur-LEDs. MSB
bedeutet hierbei most significant bit (entspricht also 0x80
in Hexadezimal-Darstellung)
und LSB least significant bit (also 0x01
).
MSB | LSB | ||||||
Always 0 | Always 0 | Always 0 | Always 0 | Always 0 | Caps Lock | Num Lock | Scroll Lock |
Der Aufbau des Konfigurationsbyte von set_speed
ist in
diesen zwei Tabellen beschrieben. Die Wiederholungsrate wird durch die
Bits 0-4 spezifiziert, die Verzögerung durch Bit 5 und 6.
Bits 0-4 (hex) | Wiederholungsrate (Zeichen pro Sekunde) |
0x00 | 30 |
0x02 | 25 |
0x04 | 20 |
0x08 | 15 |
0x0c | 10 |
0x10 | 7 |
0x14 | 5 |
Bits 5 und 6 (hex) | Verzögerung (in Sekunden) |
0x00 | 0.25 |
0x01 | 0.5 |
0x02 | 0.75 |
0x03 | 1.0 |
Weiterführende Informationen und Referenzen
- Messmer, Hans Peter: PC-Hardwarebuch - Aufbau, Funktionsweise, Programmierung., Addison-Wesley, 1994
- The AT keyboard controller