PCj や Tandy 1000 などの古い 8086 搭載コンピューターで動作するゲームを作成できるように、今年の 1 月に x86 アセンブリを趣味として取りましたが、見つけた本はその特定のトピックについてあまり教えてくれませんでした。一部の dos および bios 割り込みは、ある程度機能しますが、完全にはほど遠いものです。
私の主な問題は、プログラムを停止せずに、押されたキーのキーボードステータスを読み取ることです。いくつかの方法を見つけましたが、それらは非常に限られています。INT 21h、AH 0Ch は、最後に押されたキーを読み取りますが、テキスト編集方式です。一度に 1 つのキーしか読み取ることができないだけでなく、メモ帳のようなヒット検出により、キーが押されている時間を知ることができません。Google の旅行中にポート 60h から 64h への参照も見ましたが、それは単なる参照です。実際の説明と作業コードは事実上存在しません。あるいは、検索エンジンの使い方が下手なだけかもしれません。
私が知る必要があるのは、キーが押されているかどうかです。最善の解決策は、すべてのキーボード キーのバッファ/配列を用意し、その状態を読み取ることです。1 はダウンしていることを意味し、0 はダウンしていないことを意味します。または、最後にヒットしてリリースされたキーのリストにアクセスできるだけでもいいでしょう (もちろん、そのバッファをクリアする方法があれば)。誰かが私を正しい方向に向けることができますか?
編集:まず、Borland TASM を使用していることを言及する必要がありました。今、私はあなたのコードをコンパイルしました。私はその半分を理解していないことを認めるのはほとんど恥ずかしがり屋ですが、それはうまく機能します. TASMに対応させようとしたのですが、画面にガベージを作ってフリーズするだけです。
これが私が思いついたものです。
.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
割り込みを正しくコーディングしたかどうかもわかりません。そして、ポート 060h - 064h がどのように機能するかを知っているかどうか。