DATAS SEGMENT
TAB DB 0C0H,0F9H,0A4H,0B0H,99H
DB 92H,82H,0F8H,80H,90H
DB 88H,83H,0C6H,0A1H,86H,8EH
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
KEYSCAN: MOV AL,10000001B;8255A的方式选择控制字为81H
MOV DX,36H;控制端口为36H
OUT DX,AL;8255A方式选择控制字写入控制端口
WAIT1: MOV AL,00001111B;让列全为0,行为1
MOV DX,34H;PC口地址为34H
OUT DX,AL;把行和列的状态送到C端口
IN AL,DX;读行线的状态
AND AL,00001111B
CMP AL,0FH
JZ KEYEND;若相等(行全为1),则无键按下,使用WAIT时要等待按键按下
MOV CL,0EFH;(11101111B,扫描初值)
MOV CH,0;0列
LP1:MOV DX,34H
MOV AL,CL
OUT DX,AL
IN AL,DX
TEST AL,00000001B;
JNZ LONE;表示0行没有按下,则跳转到下一行
MOV AL,00H;行首值
JMP KEYJS;无条件跳转到计算键值
LONE: TEST AL,00000010B
JNZ LTWO
MOV AL,04H;行首值
JMP KEYJS
LTWO: TEST AL,00000100B
JNZ LTHR
MOV AL,08H;行首值
JMP KEYJS
LTHR: TEST AL,00001000B
JNZ NEXT;若最后一行都扫描完了,没有键按下,则跳转到下一列
MOV AL,0CH;行首值
JMP KEYJS
KEYJS: ADD AL,CH;计算键值
LEA BX,TAB
XLAT;(换码指令,把数据段中偏移地址为BX+AL的内存单元的内容送到AL中)无规则的数据放到表格中可以有序输出
MOV DX,30H;将键值送到PA口显示输出
OUT DX,AL
MOV DX,34H
MOV AL,0FH
OUT DX ,AL
WAIT2: IN AL,DX
AND AL,0FH
CMP AL,0FH
JNZ WAIT2;JNZ表示有键按下
KEYEND: JMP KEYSCAN;RET
NEXT: INC CH;列加1
ROL CL,1;修改扫描值
CMP CL,0FEH
JZ KEYEND
JMP LP1
MOV AH,4CH
INT 21H
CODES ENDS
END START