📄 3.6扩充键盘处理功能.asm
字号:
;扩充键盘处理功能
;---------------------------------------------------------------
stack segment para stack 'stack'
db 256 dup(0)
stack ends
;---------------------------------------------------------------
data segment para public 'data'
buffer db 16h dup(0)
bufpt1 dw 0
bufpt2 dw 0
kbflag db 0
kbflag1 db 0
prompt db '---kbd_io program begin---',0dh,0ah,'$'
scantab db 0,0,'1234567890-=',8,0
db 'qwertyuiop[]',0dh,0
db 'asdfghjkl;',27h,0,0,0
db 'zxcvbnm,./',0,0,0
db ' ',0,0,0,0,0,0,0,0,0,0,0,0,0
db '789-456+1230.'
shiftab db 0,0,'!@#$%^&*()_+',0,0
db 'QWERTYUIOP{}',0DH,0
db 'ASDFGHJKL:"',0,0,0
db 'ZXCVBNM<>?',0,0,0
db ' ',26 dup(0)
even
oldcs9 dw ?
oldip9 dw ?
data ends
;-----------------------------------------------------------------
code segment para public 'code'
start proc far
assume cs:code,ds:data
push ds
mov ax,0
push ax
mov ax,data
mov ds,ax
;
cli
mov al,09
mov ah,35h
int 21h
mov oldcs9,es
mov oldip9,bx
;
push ds
mov dx,offset kbint
mov ax,seg kbint
mov ds,ax
mov al,09
mov ah,25h
int 21h
pop ds
;
in al,21h
and al,0fdh
out 21h,al
;
mov dx,offset prompt
mov ah,9
int 21h
sti
forever:
call kbget
test kbflag,80h
jnz endint
push ax
call dispchar
pop ax
cmp al,0dh
jnz forever
mov al,0ah
call dispchar
jmp forever
endint:
mov dx,oldip9
mov ax,oldcs9
mov ds,ax
mov al,09h
mov ah,25h
int 21h
;
ret
start endp
;-------------------------------------------------------
kbget proc near
push bx
cli
mov bx,bufpt1
cmp bx,bufpt2
jnz kbget2
cmp kbflag,0
jnz kbget3
sti
pop bx
jmp kbget
kbget2:
mov al,[buffer+bx]
inc bx
cmp bx,16
jc kbget3
mov bx,0
kbget3:
mov bufpt1,bx
pop bx
ret
kbget endp
;-----------------------------------------------------
kbint proc far
push bx
push ax
;
in al,60h
push ax
in al,61h
or al,80h
out 61h,al
and al,7fh
out 61h,al
;
pop ax
test al,80h
jnz kbint2
;
cmp al,2ah ;是left_shift吗?
jnz shift5
cmp kbflag1,1 ;不是left_shift,再判断标志位是否为1
jz shift1
mov kbflag1,1 ;不是1,置为1
jmp shift1
shift5:
cmp al,36h ;是right_shift吗?
jnz shift2
cmp kbflag1,1 ;不是right_shift,再判断标志位是否为1
jz shift1
mov kbflag1,1 ;不是1,置为1
jmp shift1
shift2: ;不是shift键,
cmp kbflag1,1 ;再判断标志位
jnz shift3
lea bx,shiftab ;标志位为1,表明shift键按下,采用shiftab换码,ASCII码放在AL里
xlat
jmp shift4
shift3: ;不是shift键,标志位又不是1
lea bx,scantab ;采用scantab换码,ASCII码放在AL里
xlat
shift4:
cmp al,0 ;ASCII码为0,表明为shift以外的功能键,准备退出
jnz kbint4
mov kbflag,80h ;置退出标志位
jmp kbint2
kbint4:
mov bx,bufpt2
mov [buffer+bx],al
inc bx
cmp bx,16
jc kbint3
mov bx,0
kbint3:
cmp bx,bufpt1
jz kbint2
mov bufpt2,bx
kbint2:
cmp al,0aah ;判断left_shift是否松开
jnz shift6
mov kbflag1,0 ;松开即复位标志位为0
shift6:
cmp al,0b6h ;判断right_shift是否松开
jnz shift1
mov kbflag1,0 ;松开即复位标志位为0
shift1: ;键盘中断结束
cli
mov al,20h
out 20h,al
pop ax
pop bx
sti
iret
kbint endp
;------------------------------------------------------
dispchar proc near
push bx
mov bx,0
mov ah,0eh
int 10h
pop bx
ret
dispchar endp
;------------------------------------------------------
code ends
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -