Ваша функция _KEYCHECK использует BIOS.ReadKeyboard Состояние Функция.
Он будет информировать вас о наличии клавиши клавиатуры, установив ZeroFlag (ZF), если клавиша недоступна, или очистив ZeroFlag, если клавиша ожидает. В последнем случае вы также получите код ключа ASCII и код сканирования.
Здесь важно то, что сообщаемая клавиша остается в буфере клавиатуры . Информация, которую вы получаете в AL
и AH
- это просто предварительный просмотр, а не фактический ключ (в некотором смысле). Это объясняет ваше наблюдение:
... но если до этого была нажата какая-либо другая клавиша, органы управления освобождаются ...
Решение состоит в том, чтобы удалить ключ из буфера клавиатуры. Вот что делает BIOS.ReadKeyboard Символ . Если ключ ожидает, он очень быстро вернется, удалив ключ из буфера. Если ключ недоступен, он будет ждать, пока он не появится, а затем вернется, удалив этот ключ из буфера.
_KEYCHECK:
mov ah, 01h ; BIOS.ReadKeyboardStatus
int 16h ; -> AX ZF
jz NoKeyAvailable
mov ah, 00h ; BIOS.ReadKeyboardCharacter
int 16h ; -> AX
cmp al, 1Bh ;ESC
je _QUIT
cmp ah, 48h ;UP
je _PLAYER.UP
cmp ah, 50h ;DOWN
je _PLAYER.DOWN
cmp ah, 4Bh ;LEFT
je _PLAYER.LEFT
cmp ah, 4Dh ;RIGHT
je _PLAYER.RIGHT
NoKeyAvailable:
ret
Обратите внимание:
- Вы на самом деле не проверяли ZeroFlag, чтобы выяснить, действительна ли информация в
AL
и AH
.
- Число 1Bh (ESC) является кодом ASCII и должно проверяться с
AL
, но все остальные коды 48h (UP), 50h (DOWN), 4Bh (LEFT) и 4Dh (RIGHT) являются кодами сканирования и таким образом, должны быть проверены с AH
.