Ich nahm x86 Assembly als Hobby im vergangenen Januar, so dass ich Spiele machen konnte, die auf alten 8086 betriebenen Computern wie dem PCj und Tandy 1000 funktionieren würden, aber die Bücher, die ich fand, lehren nicht gerade viel über dieses spezielle Thema. Während einige Dos und Bios die Arbeit unterbrechen, sind sie bei weitem nicht perfekt.Wie überprüft man den Status der Tasten in der x86-Baugruppe?
Mein Hauptproblem ist das Lesen des Tastaturstatus für gedrückte Tasten, ohne das Programm zu stoppen. Ich habe ein paar Methoden gefunden, aber sie sind sehr begrenzt. INT 21h, AH 0Ch liest die zuletzt gedrückte Taste, jedoch in Textausgabe. Es liest nicht nur jeweils nur einen Schlüssel, aber die Notizblock-ähnliche Treffererkennung macht es unmöglich zu wissen, wie lange der Schlüssel gehalten wurde. Ich habe während meiner Google-Reisen auch Hinweise auf die Ports 60h bis 64h gesehen, aber das sind nur Referenzen. Tatsächliche Erklärungen und Arbeitscode sind praktisch nicht existent. Oder vielleicht bin ich so schlecht im Umgang mit Suchmaschinen.
Was ich wissen muss ist, ob eine Taste gedrückt gehalten wird oder nicht. Die beste Lösung wäre, einen Puffer/ein Array aller Tastaturtasten zu haben und seinen Zustand zu lesen; 1 bedeutet, es ist down, 0 bedeutet, dass es nicht ist. Oder einfach Zugang zu einer Liste der letzten Schlüssel, die getroffen und freigegeben wurden, wäre nett (mit einer Möglichkeit, diesen Puffer zu löschen, natürlich). Kann mir jemand in die richtige Richtung zeigen?
Edit: Zunächst einmal sollte ich erwähnt haben, dass ich Borland TASM verwende. Jetzt habe ich deinen Code kompiliert und es funktioniert super und alle, auch wenn ich fast schüchtern bin zuzugeben, dass ich die Hälfte davon nicht verstehe. Ich habe versucht, es mit TASM kompatibel zu machen, aber es wird nur Müll auf dem Bildschirm erzeugt und eingefroren.
Hier ist, was ich gefunden habe;
.MODEL TINY
.STACK 256
.DATA
kbdbuf DB 128 DUP (0)
msg1 db "Press and hold ESC", 13, 10, "$"
msg2 db "ESC pressed, release ESC", 13, 10, "$"
msg3 db "ESC released", 13, 10, "$"
.CODE
main PROC
org 0100h
mov ax, @data
mov ds, ax
xor ax, ax
mov es, ax
cli ; update ISR address w/ ints disabled
push word [es:9*4+2] ; preserve ISR address
push word [es:9*4]
lea si, irq1isr
mov word [es:9*4], si ; requires a register
mov [es:9*4+2],cs
sti
mov ah, 9
lea dx, msg1
int 021h ; print "Press and hold ESC"
test1:
mov al, [kbdbuf + 1] ; check Escape key state (Esc scan code = 1)
or al, al
jz test1 ; wait until it's nonzero (pressed/held)
lea dx, msg2
int 021h ; print "ESC pressed, release ESC"
test2:
mov al, [kbdbuf + 1] ; check Escape key state (Esc scan code = 1)
or al, al
jnz test2 ; wait until it's zero (released/not pressed)
lea dx, msg3 ; print "ESC released"
int 021h
cli ; update ISR address w/ ints disabled
pop word [es:9*4] ; restore ISR address
pop word [es:9*4+2]
sti
ret
irq1isr:
push ax bx
; read keyboard scan code
in al, 060h
; update keyboard state
xor bh, bh
mov bl, al
and bl, 07Fh ; bx = scan code
shr al, 7 ; al = 0 if pressed, 1 if released
xor al, 1 ; al = 1 if pressed, 0 if released
mov [cs:bx+kbdbuf], al
; send EOI to XT keyboard
in al, 061h
mov ah, al
or al, 080h
out 061h, al
mov al, ah
out 061h, al
; send EOI to master PIC
mov al, 020h
out 020h, al
pop bx ax
iret
main ENDP
END main
Ich bin mir nicht sicher, ob ich sogar den Interrupt richtig codiert habe. Und wenn ich weiß wie die Ports 060h - 064h funktionieren.
Ihr Hauptproblem ist, dass Sie ein .EXE-Programm während machen Der Code soll zu einem .COM-Programm kompiliert werden. Siehe die aktualisierte Antwort. –
Arbeiten Tetris OS, das tut was Sie wollen: https://github.com/programmable/tetrasm –