Interrupts 80x86/ INT 16

Aus Wikibooks

Int 16h Tastatur

Funktion 0[Bearbeiten]

MOV   AH,00   ; Keyboard Read: auf Tastendruck warten
INT   16h      ; AL = ASCII Code (=0 für Sondertasten), AH = Scancode

oder über einen I/O-Port abrufen:

in al, 0x60   ; AL = Scancode

Funktion 1[Bearbeiten]

MOV   AH,01   ; Keyboard Status OHNE Abholung des Zeichens
INT   16h      ; ZF =1: kein wartendes Zeichen
              ; ZF =0: ein Zeichen steht zur Abholung bereit:
              ; AL = ASCII Code (=0 für Sondertasten), AH = Scancode

Funktion 2[Bearbeiten]

MOV   AH,02   ; Shift Status
INT   16h      ; im AL Register sind die gedrückten Tasten kodiert
Bit 7  Insert on
Bit 6  Caps Lock on
Bit 5  Num Lock on
Bit 4  Scroll Lock on
Bit 3  Alt Key pressed
Bit 2  Ctrl Key pressed
Bit 1  Left Shift pressed
Bit 0  Right Shift pressed

Dieses Statusbyte ist auch unter 0040:0017 gespeichert und wird mit jeder Tastenbetätigung aktualisiert. Mit dem DEBUG-Befehl D 40:17 oder D 0:417 kann man es abfragen.

Es gibt übrigens noch weitere zwei Statusbytes:

  • 0040:0096 für den MF II-Status
  • 0040:0097 für den LED-Status

Einige Scancodes[Bearbeiten]

Beachte: Bei den nachfolgenden Tasten wird als erstes Byte ein Nullbyte übermittelt, danach das hier aufgeführte. Die Codes sind dezimal.

71   Home (Pos1)
72   Cursor Up
73   PgUp
75   Cursor Left	
77   Cursor Right
79   End
80   Cursor Down
81   PgDn
   zweiter Scancode der Funktionstasten
  F1 F2 F3 F4 F5 F6 F7 F8 F9 F10
  - 59 60 61 62 63 64 65 66 67 68
Shift 84 85 86 67 88 89 90 91 92 93
Strg 94 95 96 97 98 99 100 101 102 103

Hier finden Sie die vollständige Liste der Interrupts 80x86/ Scancodes

Beispiel[Bearbeiten]

Das Programm INT16BSP.COM liest Zeichen von der Tastatur ein und schreibt diese in die obere linke Ecke des Bildschirms, solange bis die Taste Esc gedrückt wird.

xxxx:0100 B400     MOV   AH,00      ; auf Tastendruck warten
xxxx:0102 CD16     INT   16h         ; BIOS-Interrupt 16h
xxxx:0104 3C1B     CMP   AL,1B      ; Taste Esc gedrückt?
xxxx:0106 7505     JNZ   010D       ; nein, weiter auf Adresse 10D
xxxx:0108 B8004C   MOV   AX,4C00    ; ja: Programm beenden
xxxx:010B CD21     INT   21         ; DOS-Interrupt 21h, Funktion 4C
xxxx:010D BB00B8   MOV   BX,B800    ; Segmentadresse Bildwiederholspeicher
xxxx:0110 8EC3     MOV   ES,BX      ; ... in das ES Segmentregister 
xxxx:0112 26       ES:              ; eingegebenes Zeichen schreiben
xxxx:0113 A20000   MOV   [0000],AL  ; in die obere linke Bildschirmecke
xxxx:0016 EBE8     JMP   0100       ; weiter mit nächstem Zeichen

Ein wenig anschaulicher ist die folgende Modifikation. Beachte, dass Funktions- und Sondertasten nicht angezeigt werden, weil von zwei Bytes nur das erste Byte ausgewertet wird.

xxxx:0100 BF00B8   MOV   DI,B800    ; Segmentadresse Bildwiederholspeicher
xxxx:0103 8EC7     MOV   ES,DI      ; ... in das ES Segmentregister
xxxx:0105 BF0000   MOV   DI,0000    ; Offset AA BWS
xxxx:0108 B400     MOV   AH,00      ; auf Tastendruck warten
xxxx:010A CD16     INT   16h         ; BIOS-Interrupt 16h
xxxx:010C 3C1B     CMP   AL,1B      ; Taste Esc gedrückt?
xxxx:010E 7505     JNZ   0115       ; nein, weiter auf Adresse 10D
xxxx:0110 B8004C   MOV   AX,4C00    ; ja: Programm beenden
xxxx:0113 CD21     INT   21         ; DOS-Interrupt 21h, Funktion 4C
xxxx:0115 AA       STOSB            ; eingegebenes Zeichen zum Bildschirm
xxxx:0116 B007     MOV   AL,07      ; Farbe: weiß
xxxx:0118 AA       STOSB            ; ... zum Bilschirm
xxxx:0119 EBED     JMP   0108       ; weiter mit nächstem Zeichen
xxxx:011B 

Anmerkungen:

Die DOS-Funktion 07 macht fast das Gleiche viel langsamer, erlaubt aber andererseits eine Umleitung der Eingabe.
Die DOS-Funktion 01 funktioniert wie die DOS-Funktion 07, gibt aber zusätzlich das eingegebene Zeichen als Echo auf den Bildschirm aus.