Files
Microcomputer_System_and_In…/Lab/Lab_final/material/code.asm
2025-05-27 16:03:52 +08:00

339 lines
9.9 KiB
NASM
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

DATA SEGMENT
A8255A EQU 280H
A8255B EQU 281H
A8255C EQU 282H
A8255COM EQU 283H
A8254A EQU 288H
A8254B EQU 289H
A8254COM EQU 28BH
OLD_OFF DW 0
OLD_SEG DW 0
TMP1 DB 0
TMP2 DB 0
LED DB 3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H, 7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H
WAITING DB 40H ; 等待状态的字节码
FAULT DB 71H ; 违规状态的字节码
SUCCESS DB 6DH ; 抢答成功状态的字节码
ZERO DB 3FH ; 数码管显示0的字节码
DATA ENDS
CODE SEGMENT
ASSUME DS:DATA, CS:CODE
; 1. 程序逻辑
;   1.1. 当K7为0时K0-6都必须为0否则为1的违规数码管显示违规选手 && 扬声器鸣叫
;   1.2. 当K7为1时当K0-6中有一个为1时停止检测为1的按键对应的选手抢答成功数码管显示抢答成功选手
; 2. 程序设计
;   2.1. 2个PROC
;       2.1.1. PROC1扫描到 K7为0 && K0-6中存在1的按键时进入K0-6全为0时退出
;               进入PROC1后蜂鸣器响起不断扫描K0-7数码管显示违规选手。
;               当全为0时蜂鸣器关闭退出PROC1
;       2.1.2. PROC2扫描到K7为1时进入K7为0时退出
;               进入PROC2后循环扫描K0-7K0-6存在1后数码管显示抢答成功选手
;               继续循环扫描但只看K7K7为0时退出
;               进入PROC2后进行计时4秒后若无变化触发中断退出PROC
;   2.2. 主程序 循环扫描K0-7
;       2.2.1. K7为0 && K0-6按键全0时不变继续循环
;       2.2.2. K7为0 && K0-6中存在1的按键时进入PROC1
;       2.2.2. K7为1时进入PROC2
START:
MOV AX, DATA
MOV DS, AX
CLI ; 关中断,防止中断干扰
; 保存旧的中断向量
MOV AX, 350BH
INT 21H
MOV OLD_OFF, BX
MOV BX, ES
MOV OLD_SEG, BX
; 设置新的中断向量
MOV AX, 250BH
MOV DX, SEG TIMEOUT
MOV DS, DX
MOV DX, OFFSET TIMEOUT
INT 21H
STI
; 恢复数据段
MOV AX, DATA
MOV DS, AX
; 初始化8255
MOV AX, 10001001B ; A口输出段码B口输出位码C口输入拨动开关
MOV DX, A8255COM
OUT DX, AL
; 使用8254 A口将1MHz降频为1kHz为8254 B口提供时钟源
MOV DX, A8254COM
MOV AL, 00110110B
OUT DX, AL
MOV DX, A8254A
MOV AL, 11101000B
OUT DX, AL
MOV AL, 00000011B
OUT DX, AL
; 主程序
MAIN:
MOV DX, A8255C
IN AL, DX
MOV SI, 0 ; 中断标志位
; K7为0 && K0-6按键全0时不变继续循环
CMP AL, 0 ; 比较AL寄存器的值与0
JE MAIN ; 如果相等则跳转到MAIN
; K7为0 && K0-6中存在1的按键时进入PROC1
AND AL, 10000000B ; 将AL寄存器的值与10000000B进行按位与操作
CMP AL, 0 ; 比较AL寄存器的值与0即判断第7位是否为0
JNE P2 ; 如果不相等则跳转到P2
CALL PROC1 ; 调用PROC1子程序
; K7为1时进入PROC2
P2:
CALL PROC2 ; 调用PROC2子程序
JMP MAIN ; 无条件跳转到MAIN
FINISH:
CLI ; 关中断,防止中断干扰
MOV AX, 250BH ; 恢复原来的中断向量
MOV DX, OLD_OFF
MOV DS, DX
MOV DS, OLD_SEG
INT 21H
MOV AX, 4C00H
INT 21H
PROC1 PROC NEAR
; K7为0 && K0-6中存在1的按键时进入K0-6全为0时退出
; 进入PROC1后蜂鸣器响起不断扫描K0-7数码管显示违规选手。
; 当全为0时蜂鸣器关闭退出PROC1
PUSH DX
PUSH CX
LOOP1:
MOV DX, A8255C
IN AL, DX
MOV TMP1, AL
CMP AL, 0
JE RETURN1
MOV CX, 8
MOV TMP2, 10000000B ; 位码
LOOP2:
ROR TMP2, 1
JMP OUTPUT1
BACK1:
LOOP LOOP2
JMP LOOP1
; 在数码管上输出
OUTPUT1:
CALL CLEAR
MOV AL, TMP1
AND AL, TMP2
CMP AL, TMP2
JE FAULT1
MOV AL, WAITING
JMP DISPLAY1
FAULT1:
MOV AL, FAULT
DISPLAY1:
MOV DX, A8255A
OUT DX, AL
MOV DX, A8255B
MOV AL, TMP2
OUT DX, AL
CALL DELAY
JMP BACK1
RETURN1:
CALL CLEAR
POP CX
POP DX
RET
PROC1 ENDP
PROC2 PROC NEAR
; 进入PROC2后循环扫描K0-7K0-6存在1后数码管显示抢答成功选手
; 继续循环扫描但只看K7K7为0时退出PROC2
PUSH DX
PUSH CX
MOV SI, 0 ; 时间到退出抢答标志
; 开始计时1000Hz * 4000 = 4s后输出低电平取反后用于触发中断
MOV DX, A8254COM
MOV AL, 10111000B
OUT DX, AL
MOV DX, A8254B
MOV AL, 10100000B
OUT DX, AL
MOV AL, 00001111B
OUT DX, AL
; 设置中断屏蔽
CLI
IN AL, 21H
AND AL, 11110111B
OUT 21H, AL
STI
LOOP3:
CMP SI, 1
JE RETURN2
MOV DX, A8255C
IN AL, DX
MOV TMP1, AL
AND AL, 10000000B ; 位码
CMP AL, 0
JE RETURN2
MOV AL, TMP1
AND AL, 01111111B
MOV TMP1, AL
CMP AL, 0
JE LOOP3
; 检测到有变化,恢复中断屏蔽,取消中断
CLI
IN AL, 21H
OR AL, 00001000B
OUT 21H, AL
STI
LOOP4:
MOV DX, A8255C
IN AL, DX
AND AL, 10000000B
CMP AL, 0
JE RETURN2
MOV CX, 7
MOV TMP2, 10000000B ; 位码
LOOP5:
ROR TMP2, 1
JMP OUTPUT2
BACK2:
LOOP LOOP5
JMP LOOP4
OUTPUT2:
CALL CLEAR
MOV AL, TMP1
AND AL, TMP2
CMP AL, TMP2
JE SUCCESS2
MOV AL, WAITING
JMP DISPLAY2
SUCCESS2:
MOV AL, SUCCESS
DISPLAY2:
MOV DX, A8255A
OUT DX, AL
MOV DX, A8255B
MOV AL, TMP2
OUT DX, AL
CALL DELAY
JMP BACK2
RETURN2:
CALL CLEAR
; 恢复中断屏蔽
CLI
IN AL, 21H
OR AL, 00001000B
OUT 21H, AL
STI
POP CX
POP DX
RET
PROC2 ENDP
TIMEOUT PROC FAR
CLI
PUSH CX
PUSH BX
MOV SI, 1
CALL CLEAR
MOV BX, 0FH
LOOP6:
MOV CX, 8
MOV TMP1, 00000001B ; 位码
LOOP7:
ROR TMP1, 1
JMP OUTPUT3
BACK3:
LOOP LOOP7
DEC BX
JZ RETURN3
JMP LOOP6
OUTPUT3:
MOV AL, ZERO
MOV DX, A8255A
OUT DX, AL
MOV DX, A8255B
MOV AL, TMP1
OUT DX, AL
CALL DELAY
JMP BACK3
RETURN3:
MOV AL, 20H ; 发送EOI指令
OUT 20H, AL
POP BX
POP CX
STI
IRET
TIMEOUT ENDP
CLEAR PROC NEAR
PUSH DX
PUSH AX
MOV DX, A8255A
MOV AL, 00000000B
OUT DX, AL
MOV DX, A8255B
MOV AL, 0
OUT DX, AL
POP AX
POP DX
RET
CLEAR ENDP
DELAY PROC NEAR
PUSH CX
PUSH BX
MOV CX, 0FFFFH
LOOP8:
MOV BX, 2
LOOP9:
DEC BX
JNZ LOOP9
DEC CX
JNZ LOOP8
POP BX
POP CX
RET
DELAY ENDP
END START
CODE ENDS