Forum: PC-Programmierung Problem mit BIOS Int 16h/Fkt. 11h Keyboard


von Nils S. (kruemeltee) Benutzerseite


Lesenswert?

Hi,

ich bin gerade dabei am einem Real-Mode Programm zu basteln und brauche 
dafür Tastatur-Eingabe. Die Funktion 11h aus int 16h scheint dafür 
perfekt zu sein. Jedoch habe ich ein paar Probleme damit.

In einer Schleife (beginnt bei "footer:") hole ich Zufallszahlen und 
nehme die für die Farbe für ein paar Zeichen die immerwieder geschrieben 
werden. Das funktioniert soweit wie es soll. Jetzt sollen da aber noch 
ein paar Tastendrücke ausgewertet werden, also springt die Schleife auf 
noch in jedem Durchlauf nach "keyboard_handler".

Dort wird int 16h/funktion 11h aufgerufen. Die Funktion wartet nicht auf 
einen Tastendruck, sondern setzt das Zero Flag oder nicht.
Das will ich auswerten an der Stelle direkt nach "int 0x16".
Eigentlich müsste da doch ein JZ (jump if zero) hin? Denn wenn ich da 
ein JZ habe, dann springt er sofort nach gotkey, auch wenn nichts 
gedrückt wurde. Mit JNZ springt er erst beim ersten Tastendruck dorthin.
Dann allerdings die ganze Zeit, bei jedem Durchlauf wieder.

Ich hoffe, ich habe die Dokumentation richtig verstanden... Zwei Fragen 
ergeben sich jetzt. Wieso JNZ statt JZ? Wie sage ich dem BIOS, dass ich 
den Tastendruck abgeholt habe und nicht dauernd wieder nach gotkey 
laufen will?
1
keyboard_handler:
2
         mov  ah, 0x11  ; get keyboard status without wait
3
         int  0x16      ; on return: ZF=0 if key pressed (data waiting)
4
                        ;            AX=0 if no scan code avail
5
                        ;            AH=scancode
6
                        ;            AL=ascii char or special function key
7
         jnz  gotkey
8
         nop
9
         ret
10
gotkey:
11
         mov   [rcv_key], al  ; receive ascii code of pressed key
12
         mov   dh, 6
13
         mov   dl, 10
14
         call  set_curs
15
         mov   al, [rcv_key]
16
         mov   bl, 0x47
17
         call  put_char
18
         ret
19
rcv_key db 0x00  
20
21
22
footer:  mov   dh, 20     ; row
23
         mov   dl, 0      ; col
24
         call  set_curs
25
         mov   cx, 400    ; 80x5 = 400 chars
26
loopfs:  push  ax
27
         push  bx
28
         push  cx
29
         push  dx
30
         call  rand       ; 8bit rand in AL
31
         mov   bl, al     ; BL=color for put_char
32
         mov   al, '%'    ; char to put
33
         call  put_char
34
         call  inc_cursor
35
         call  keyboard_handler  
36
         pop   dx
37
         pop   cx
38
         pop   bx
39
         pop   ax
40
         loop  loopfs
41
.hang_forever:  jmp  footer

Ich Teste das ganze in qemu und ab und zu dann auf echter Hardware. Auf 
beiden gab's schon unerwartete Phänomene...

von Clemens L. (c_l)


Lesenswert?

Nils S. schrieb:
> Wie sage ich dem BIOS, dass ich den Tastendruck abgeholt habe

Das geht nicht. Aber du könntest den Tastendruck einfach abholen (Fkt. 
10h).

von Nils S. (kruemeltee) Benutzerseite


Lesenswert?

Vielen Dank, Clemens!

Ich dachte, wenn ich 10h verwende, dann lande ich bei gotkey und dort 
wartet er wieder auf einen Tastendruck.
So ist es genau das, was ich will:
1
keyboard_handler:
2
  mov  ah, 0x11
3
  int  0x16
4
  jnz  gotkey
5
  ; no keypress happened
6
  ret
7
gotkey:
8
  mov  ah, 0x10
9
  int  0x16    ; get keypress
10
  ; al has ascii of pressed key now
11
  ret

von Georg (Gast)


Lesenswert?

Nils S. schrieb:
> und dort
> wartet er wieder auf einen Tastendruck.

Nicht wenn du vorher per Funktion 11h festgestellt hast, dass eine Taste 
verfügbar ist. Das ist der Sinn der Sache.

Georg

von Nils S. (kruemeltee) Benutzerseite


Lesenswert?

Georg schrieb:
> Nicht wenn du vorher per Funktion 11h festgestellt hast, dass eine Taste
> verfügbar ist. Das ist der Sinn der Sache.

Ja, so ist das ganze dann doch schlüssig. Aber erstmal ist das eine ganz 
neue Welt...

von c-hater (Gast)


Lesenswert?

Nils S. schrieb:

> Ja, so ist das ganze dann doch schlüssig. Aber erstmal ist das eine ganz
> neue Welt...

Eigentlich ist es eher eine alte Welt.

Aber nur, was den PC betrifft. Im µC-Bereich sind solche 
Tastaturschnittstellen auch heute noch "state of the art". Und zu Recht. 
Denn sowas ist um Größenordnungen effizienter als z.B. die Blähungen, 
die Tastatureingaben unter etwa Windows oder Linux durchlaufen müssen, 
bis sie dann irgendwann endlich zur Anwendung durchdringen...

Wenn man sowas mal mit einem Debugger wirklich durch alle Schichten der 
Software verfolgt hat, dann sehnt man sich doch sehr intensiv nach dem 
guten alten BIOS zurück, wo alles noch dermaßen klar und simpel war...

von Nils S. (Gast)


Lesenswert?

Ich habe mich heute auch noch durch den Code eines AT-Bios gewühlt um 
ein paar Sachen herauszufinden und war doch erstaunt wie einfach das 
alles eigentlich gehalten ist.

Leider kam ich zum Schluss, nun wohl doch direkt mit dem kbc zu reden. 
Ich brauche auch Key-Release-"Events", an die ich Anfangs nicht gedacht 
habe. Mit den Interrupts kam ich da zu keiner Lösung.
Etwa 100byte noch für die kbc-Kommunikation und eine State-Machine, die 
10 Tasten-Drücke und Loslassen auswerten soll und entsprechend 
springen...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.