汇编中如何判断电脑是否有XT/AT键盘?

How to determine whether the computer has an XT/AT keyboard in assembly?

我刚写完我的 16 位操作系统,但我使用 int 0x16 来告诉用户按下了哪个键。现在我想写我自己的键盘驱动,我不想使用任何中断。 (这样我就可以进入长模式)。我意识到有两个扫描码,AT 和 XT。 如何确定计算机在 NASM x86 程序集中使用哪个键盘?

OS 启动时是否要让用户按一个键确定使用0x60 端口的扫描码?
例如:一把钥匙 - 0x1c(make) 用于 AT,0x1e(make) 用于 XT
但是linux不会那样做.......

我使用了以下代码,发现虚拟框使用 XT 键盘....

[org 0x2e00]

mov bx, 0x1000
mov ds, bx      ;The program is loaded at 0x12e00 or 1000:2e00 by the operating system

    xor ax, ax  ;Set AX to zero
    mov bl, 0x0e    ;Set text color 

loop:           ;Main loop

    in al, 0x60 ;Read all ports and display them
    mov cx, ax
    call hex_print  ;Print content of the port in hex
    in al, 0x61
    mov cx, ax
    call hex_print
    in al, 0x62
    mov cx, ax
    call hex_print
    in al, 0x63
    mov cx, ax
    call hex_print
    in al, 0x64
    call hex_print
    call com_cls    ;Clear the screen after printing content
    jmp loop    ;Jump to loop


;Print hex values;;;;;;;;;;;;;;;;;
hex_print:
    push ax
    push cx
    mov ah, 0x0e
    mov al, ' '
    int 0x10
    mov al, '0'
    int 0x10
    mov al, 'x'
    int 0x10
hex_print_start:
    mov al, ch
    and al, 0xf0
    call hex_map
    int 0x10
    shl cx, 0x04
    mov al, ch
    and al, 0xf0
    call hex_map
    int 0x10
    shl cx, 0x04
    mov al, ch
    and al, 0xf0
    call hex_map
    int 0x10
    shl cx, 0x04
    mov al, ch
    and al, 0xf0
    call hex_map
    int 0x10
hex_print_end:
    pop cx
    pop ax
    ret

hex_map:
    cmp al, 0x00
    jne zero_end
    mov al, '0'
    ret
zero_end:
    cmp al, 0x10
    jne one_end
    mov al, '1'
    ret
one_end:
    cmp al, 0x20
    jne two_end
    mov al, '2'
    ret
two_end:
    cmp al, 0x30
    jne three_end
    mov al, '3'
    ret
three_end:
    cmp al, 0x40
    jne four_end
    mov al, '4'
    ret
four_end:
    cmp al, 0x50
    jne five_end
    mov al, '5'
    ret
five_end:
    cmp al, 0x60
    jne six_end
    mov al, '6'
    ret
six_end:
    cmp al, 0x70
    jne seven_end
    mov al, '7'
    ret
seven_end:
    cmp al, 0x80
    jne eight_end
    mov al, '8'
    ret
eight_end:
    cmp al, 0x90
    jne nine_end
    mov al, '9'
    ret
nine_end:
    cmp al, 0xa0
    jne a_end
    mov al, 'A'
    ret
a_end:
    cmp al, 0xb0
    jne b_end
    mov al, 'B'
    ret
b_end:
    cmp al, 0xc0
    jne c_end
    mov al, 'C'
    ret
c_end:
    cmp al, 0xd0
    jne d_end
    mov al, 'D'
    ret
d_end:
    cmp al, 0xe0
    jne e_end
    mov al, 'E'
    ret
e_end:
    cmp al, 0xf0
    jne f_end
    mov al, 'F'
    ret
f_end:
    ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;The "cls" command;;;;;;;;;;;;;;;;;;;;;;;;;;;;
com_cls:
    push ax
    push bx
    push cx
    push dx
    mov ax, 0x0700      ; function 07, AL=0 means scroll whole window
    mov bh, 0x00        ; character attribute = black
    mov cx, 0x0000      ; row = 0, col = 0
    mov dx, 0x1e54      ; row = 30 (0x1e), col = 79 (0x4f)
    int 0x10            ; call BIOS video interrupt
    mov ah, 0x02        ;function 02, set curser position
    mov dx, 0x00
    int 0x10
    pop dx
    pop cx
    pop bx
    pop ax
    ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ret

扫码0x9E:XT键盘'A'键中断!

在此先感谢您的帮助。

每当您需要一些编程 OS 的建议时,请查看 OSDev wiki 很棒!
这两个页面将帮助您:


您不太可能需要处理 XT 键盘,因为它们在没有 8042 但有 8255 (PPI) 芯片的 PC-XT 中使用.
PPI 仅响应端口 60h-63h,而忽略了我认为您正在使用的 64h
参见 this listing


不要混淆 键盘命令 控制器命令 ,您的 OS 都转换为写入相同的数据端口,但第一个进入键盘,后者停在 8042。

考虑到存在三个扫描码集(命名为集 1、2 和 3)。
XT用的是第一种,第二种目前所有键盘都支持,第三种很少用
所以你必须检查键盘使用的是哪个扫描码集,默认是第二个
使用 keyboard command 0f0h with a payload 00h 来知道当前的扫描码(在通常的键盘之后ACK 0fah).
如果您使用01h02h03h的有效负载,您可以设置使用的扫描码集.

注意 8082 默认将扫描码集 2 转换为扫描码集 1,要禁用此转换,请使用 控制器命令 20h60h 以清除 控制器配置字节 的第 6 位。


简而言之:

  1. 您可能正在处理扫描代码翻译,而不是(模拟的)XT 键盘。
  2. 禁用翻译。
  3. 明确设置你支持的扫码集。