wziąłem zespół x86 jako hobby W styczniu tego roku, więc może tworzyć gry, które działają na starych 8086 zasilanych komputerach takich jak PCJ i Tandy 1000 książek, ale nie znalazłem dokładnie nauczyć wiele na temat tego konkretnego tematu. Podczas gdy niektóre metody dos i bios przerywają rodzaj wykonywanej pracy, są dalekie od doskonałości.Jak sprawdzić status kluczy w zestawie x86?
Moim głównym problemem jest czytanie stan klawiatury po wciśnięciu przycisku bez zatrzymania programu. Znalazłem kilka metod, ale są one bardzo ograniczone. INT 21h, AH 0Ch czyta ostatni wciśnięty klawisz, ale w trybie edycji tekstu. Nie tylko odczytuje tylko jeden klucz na raz, ale wykrywanie trafienia w sposób podobny do notatnika uniemożliwia ustalenie, jak długo klucz był trzymany. Podczas moich podróży do Google widziałem także odniesienia do portów od 60 do 64 godzin, ale to tylko odniesienia. Rzeczywiste wyjaśnienia i działający kod praktycznie nie istnieją. A może po prostu źle korzystam z wyszukiwarek.
Co muszę wiedzieć, czy klawisz jest wciśnięty czy nie. Najlepszym rozwiązaniem byłoby posiadanie bufora/tablicy wszystkich klawiszy klawiatury i odczytanie jego stanu; 1 oznacza, że jest wyłączony, 0 oznacza, że nie. Lub po prostu dostęp do listy ostatnich kluczy, które zostały trafione i wydane, byłoby miłe (oczywiście z możliwością wyczyszczenia tego bufora). Czy ktoś może wskazać mi właściwy kierunek?
Edit: Po pierwsze, muszę wspomnieć, że używam Borland TASM. Teraz skompilowałem twój kod i działa świetnie i wszystko, mimo że jestem prawie nieśmiały, aby przyznać, że nie rozumiem połowy tego. Próbowałem uczynić go kompatybilnym z TASM, ale wszystko, co robi, to tworzenie śmieci na ekranie i zamrażanie.
Oto, co wymyśliłem;
.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
Nie jestem pewien, czy nawet zakodowałem przerwanie w prawo. I do cholery, jeśli wiem, jak działają porty 060h - 064h.
Twoim głównym problemem jest to, że robisz się programu podczas .EXE kod powinien zostać skompilowany do programu .COM. Zobacz zaktualizowaną odpowiedź. –
Działający Tetris OS, który robi to, co chcesz: https://github.com/programble/tetrasm –