📄 gg301.asm
字号:
;gg301.asm
;for 【1.反转法】键盘工作<8255芯片、3X6键盘>
;2005-05
;wenq/wxz/p_Sa/lcy
data SEGMENT
table DW 0101h,0102h,0104h,0108h,0110h,0120h
DW 0201h,0202h,0204h,0208h,0210h,0220h
DW 0401h,0402h,0404h,0408h,0410h,0420h ;高2位列值(横),低2位行值(竖)
buf DB '6789AB012345CDEFGP'
tip0 DB 'let key down(p for over):',0dh,0ah,'$'
tip1 DB 0dh,0ah,'The End.$'
PA EQU 280h
PB EQU 281h
PC EQU 282h
PCTL EQU 283h
data ENDS
stack0 SEGMENT para stack
DW 20h DUP(0)
stack0 ENDS
coseg SEGMENT
ASSUME CS:coseg,DS:data,SS:stack0
start: MOV AX, data
MOV DS, AX
;================MOV-DS-AX==============
LEA DX, tip0
CALL printstr ;提示信息'let key down(p for over):'
key1:MOV DX, PCTL
MOV AL, 10000010b ;a口输出,b口输入
OUT DX, AL
MOV AL, 0 ;a口输出全0
MOV DX, PA
OUT DX, AL
INC DX
ls0:IN AL, DX
OR AL, 0f8h ;屏蔽列值高位(AND AL, 07h)
CMP AL, 0FFh ;比较b口是否输出全1,以判断是否按键
JE ls0
CALL delay ;延时,消除抖动
CALL delay
MOV AL, 0 ;a口输出全0
MOV DX, PA
OUT DX, AL
INC DX
IN AL, DX ;输入列值到al中,消除抖动后读第二次
OR AL, 0f8h ;屏蔽列值高位
MOV AH, 0
PUSH AX ;列值进栈
PUSH AX
MOV AL, 10010000b ;a口输入,b口输出——反转!!
MOV DX, PCTL
OUT DX, AL
POP AX ;弹出列值到ax
MOV DX, PB
OUT DX, AL
MOV DX, PA
IN AL, DX ;输入行值到al中
POP BX ;弹出列值到bx
MOV AH, BL ;列值放入ah中
OR AL, 11000000b ;屏蔽行值高位
NOT AX ;求反对应键值表
MOV CX, 12h ;查表,表长18
LEA BX, table
LEA SI, buf
ls1:CMP AX, [BX]
JE ls2 ;若有查到,跳到显示部分,否则继续查表
ADD BX, 2
ADD SI, 1
LOOP ls1
JMP key1 ;说明无此键,重新开始读键盘
ls2:MOV DL, [SI] ;显示对应字符——!!
MOV AH, 02h
INT 21h
MOV DX, PCTL
MOV AL, 10000010b ;a口输出,b口输入
OUT DX, AL
MOV AL, 0 ;a口输出全0
MOV DX, PA
OUT DX, AL
INC DX
ls3:IN AL, DX
CALL delay ;延时,消除抖动,防止影响下一次按键
AND AL, 07h
CMP AL, 07h ;比较b口是否输出全1,以判断是否按键
JNE ls3
MOV DL, [SI]
CMP DL, 'P' ;是否要结束'p'
JNE key1
LEA DX, tip1
CALL printstr ;提示信息'The End.'
;================INT-21H================
MOV AH, 4ch
INT 21h
delay PROC ;延时子程序,消除抖动
PUSH CX
MOV CX, 0ffffh
ys:NOP
LOOP ys
POP CX
RET
delay ENDP
printstr PROC ;打印字符串子程序
PUSH AX
MOV AH, 09h
INT 21h
POP AX
RET
printstr ENDP
coseg ENDS
END start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -