汇编中如何判断电脑是否有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).
如果您使用01h、02h或03h的有效负载,您可以设置使用的扫描码集.
注意 8082 默认将扫描码集 2 转换为扫描码集 1,要禁用此转换,请使用 控制器命令 20h 和 60h 以清除 控制器配置字节 的第 6 位。
简而言之:
- 您可能正在处理扫描代码翻译,而不是(模拟的)XT 键盘。
- 禁用翻译。
- 明确设置你支持的扫码集。
我刚写完我的 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
在此先感谢您的帮助。
每当您需要一些编程 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).
如果您使用01h、02h或03h的有效负载,您可以设置使用的扫描码集.
注意 8082 默认将扫描码集 2 转换为扫描码集 1,要禁用此转换,请使用 控制器命令 20h 和 60h 以清除 控制器配置字节 的第 6 位。
简而言之:
- 您可能正在处理扫描代码翻译,而不是(模拟的)XT 键盘。
- 禁用翻译。
- 明确设置你支持的扫码集。