我刚刚完成了我的16位操作系统的编写,但我使用int 0x16来告诉用户按下了哪个键 . 现在我想编写自己的键盘驱动程序,我不想使用任何中断 . (这样我就可以进入长模式) . 我意识到有两个扫描码,AT和XT . 如何确定计算机在NASM x86组件中使用哪个键盘?
当操作系统启动时,我是否应该要求用户按一个键并确定使用端口0x60中的扫描代码?
例如:一个键 - 对于AT为0x1c(make),对于XT为0x1e(make)
但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'键中断!
在此先感谢您的帮助 .
1 回答
每当你需要一些编程操作系统的建议时,看一下OSDev维基很棒!
这两页将帮助您:
The PS2 Controller .
The PS2 Keyboard .
您不太可能需要处理XT键盘,因为它们在PC-XT中使用时没有8042而是8255(PPI)芯片 .
并且PPI仅对60h-63h的端口做出响应,而忽略了我认为你正在使用的64h .
见this listing .
不要混淆键盘命令和控制器命令,从你的操作系统转换成写入同一数据端口,但第一次下降到键盘,后者停在8042 .
考虑有三个扫描代码集(名为第1,2和3组) .
XT使用第一个,第二个目前由每个键盘支持,第三个很少使用 .
因此,您必须检查键盘使用的扫描代码集 by default it is the second .
使用 keyboard command 0f0h和00h的有效负载来知道当前的扫描码(在通常的键盘ACK 0fah之后) .
如果使用01h,02h或03h的有效负载,则可以设置正在使用的扫描代码集 .
_8070940_默认情况下8082将扫描代码集2转换为扫描代码集1,要禁用此转换,请使用 controller commands 20h和60h清除控制器配置字节的第6位 .
简而言之:
您可能正在处理扫描代码转换,而不是使用(仿真)XT键盘 .
禁用翻译 .
明确设置您支持的扫描代码集 .