OOStuBS - Technische Informatik II (TI-II)
2.4
|
Zur Programmierung des Tastaturkontrollers und der Verwendung von Tastaturabfragen sind verschiedene Codes von Bedeutung.
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.
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.
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 Keyboard_Controller::key_decoded) muss aus den Make- und Breakcodes der gedrückten Tasten die gewünschten Zeichen ermitteln.
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 |
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 |