📄 电子钟 注释.asm
字号:
CODE SEGMENT
ASSUME CS:CODE
INTPORT1 EQU 0020H ;8259口地址1,用来写ICW1
INTPORT2 EQU 0021H ;8259口地址2,用来写ICW2,ICW4
INTQ3 EQU INTERUPT3 ;中断程序的入口地址
INTQ7 EQU INTERUPT7 ;中断程序的入口地址
CONTPORT EQU 00DDH ;8279命令状态口地址
DATAPORT EQU 00DEH ;8279键盘显示数据口地址
DATA1 EQU 0500H ;错误信息显示缓冲区起始地址(0500H--0507H)
DATA2 EQU 0508H ;显示译码表起始地址(0508--0517H)
DATA3 EQU 0518H ;初始状态显示缓冲区(0518--051FH)
DATA4 EQU 0520H ;时间显示缓冲区起始地址(0502H--0527H)
DATA5 EQU 0528H ;存放已重新刷新数据管个数
DATA6 EQU 0529H ;存放1/20秒定时中断次数
DATA7 EQU 052AH ;存放时间的小时值
DATA8 EQU 052BH ;存放时间的分值
DATA9 EQU 052CH ;存放时间的秒值
DATA10 EQU 052EH ;等更新的显示区内的地址
ORG 1800H
START: JMP TINT1
TINT1: CALL FORMAT
CLD ;清除DF标志
MOV DX,004BH ;设置8253工作方式为工作方式3,这就会一个方波发生器
MOV AL,0B6H
OUT DX,AL
MOV DX,004AH ;写8253的时间常数
MOV AL,50H ;先写低位
OUT DX,AL
MOV AL,0C3H ;再写高位
OUT DX,AL ;时间常数为C350H,也就是十进制的50000,输入的时钟是1MHz,这样的话就是
;每1/20秒就会在8253的OUT输出一个方波
MOV SI,DATA3
CALL LEDDISP ;显示00-00-00
MOV AX,0H
MOV DS,AX ;设置数据段为0H
CALL WRINTVER ;更改中断向量地址
MOV AL,13H ;设置ICW1初始化命令字
MOV DX,INTPORT1 ;设置8259A的偶地址端口
OUT DX,AL ;将ICW1输出到偶地址端口(ICW1寄存器)
MOV AL,08H ;设置ICW2中断类型号基值为:1H,也就是8259A的8个中数年对应的8个中断类
;码为:08H,09H,0AH,0BH,0CH,0DH,0EH,0FH
MOV DX,INTPORT2 ;
OUT DX,AL ;
MOV AL,0BH ;ICW4: 0BH=0000 1011
;A0 D7 D6 D5 D4 D3 D2 D1 D0
;1 0 0 0 SFNM BUF M/S AEOI PM
; 0 0 0 0 1 0 1 1
;这个表明:是非特殊全嵌套方式,采用缓冲方式,中断自动结束方式,与8086/
;8088CPU相连
OUT DX,AL ;
MOV AL,0F7H ;设置0CW1,0F7H=1111 0111,也就是只允许IR3中断
OUT DX,AL ;
WAITING: STI ;设置中断标志为1,IF=1,允许CPU响应外设的中断请求
JMP WAITING
WRINTVER: MOV AX,0H
MOV ES,AX ;这时:ES为0H,这是中断向量的开始地址
MOV DI,002CH ;DI是002CH,ES:DI组成的地址是002CH,这是我们要更改的中断向量地址
LEA AX,INTQ3 ;将中断过程的入口地址INTERUPT3(偏移地址IP)放到AX中
;INTQ3是外部中断IRQ3产生时调用的
STOSW ;改变中断向量的入口地址,AX->ES:DI,也就是将AX的值放到002CH中
MOV AX,CS ;送段地址(CS)到AX
STOSW ;保存段地址,来到这里中断向量的入口地址为CS:IP,它是由CS和IP组成的
MOV DI,003CH ;设置下一个中断向量的入口地址
LEA AX,INTQ7 ;将中断过程的入口地址INTERUPT7(偏移地址IP)放到AX中
;INTQ7是电平信号不符合要求时的中断例程
STOSW ;改变中断向量的入口地址,AX->ES:DI,也就是将AX的值放到003CH中
MOV AX,CS ;送段地址(CS)到AX
STOSW
RET
INTERUPT3: CLI ;清除中断允许
MOV AL,DS:[DATA6] ;读入现在存放1/20秒定时中断次数
INC AL ;计数值加1
MOV DS:[DATA6],AL ;写回到DS:[DATA6]
CMP AL,14H ;比较,是否已经中断了20次了(14H即是十进制的20),CMP只会修改标志位
;两数相等时,CF=0,否则CF=1
JC PLAY ;标志位CF=1,就跳到PLAY处执行
MOV BYTE PTR DS:[DATA6],00H ;清除计数,置为0,重新开始计数
MOV SI,DATA4 ;
CALL LEDDISP
CALL NEWTIME
CALL CONVERSALL
PLAY: MOV AL,20H ;定义OCW2,普通EOI结束方式
MOV DX,INTPORT1
OUT DX,AL
STI ;设置中断允许
IRET ;中断返回,也就是结束中断
INTERUPT7: CLI
MOV SI,DATA1
CALL LEDDISP
MOV AL,20H
MOV DX,INTPORT1
OUT DX,AL
IRET
LEDDISP: MOV AL,90H
MOV DX,CONTPORT ;写8279的命令状态字
OUT DX,AL
MOV BYTE PTR DS:[DATA5],00H
LED1: CMP BYTE PTR DS:[DATA5],07H
JA LED2
MOV BL,DS:[DATA5]
MOV BH,0H
MOV AL,CS:[BX+SI]
MOV DX,DATAPORT
OUT DX,AL
ADD BYTE PTR DS:[DATA5],01H
JNZ LED1
LED2: RET
FORMAT: MOV BX,0
MOV WORD PTR DS:[BX+DATA1],5050H
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],0079H
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],0000H
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],0000H
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],063FH
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],4F5BH
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],6D66H
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],077DH
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],6F7FH
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],7C77H
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],5E39H
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],7179H
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],3F3FH
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],3F40H
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],403FH
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],3F3FH
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],3F3FH
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],3F40H
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],403FH
ADD BX,2
MOV WORD PTR DS:[BX+DATA1],3F3FH
MOV BYTE PTR DS:[DATA6],00D ;这里用的是BCD码,即是十进制表示
MOV BYTE PTR DS:[DATA7],00D
MOV BYTE PTR DS:[DATA8],00D
MOV BYTE PTR DS:[DATA9],00D
MOV WORD PTR DS:[DATA10],DATA4
RET
CONVERS1: MOV BH,0H
AND AL,0FH
MOV BL,AL
MOV AL,CS:[BX+DATA2]
RET
CONVERS2: PUSH AX
CALL CONVERS1
MOV BX,WORD PTR DS:[DATA10]
MOV DS:[BX],AL
ADD WORD PTR DS:[DATA10],01H
POP AX
PUSH CX
MOV CL,4H
SHR AL,CL
POP CX
CALL CONVERS1
MOV BX,WORD PTR DS:[DATA10]
MOV DS:[BX],AL
RET
CONVERSALL: MOV AL,BYTE PTR DS:[DATA9]
CALL CONVERS2
ADD WORD PTR DS:[DATA10],02H
MOV AL,BYTE PTR DS:[DATA8]
CALL CONVERS2
ADD WORD PTR DS:[DATA10],02H
MOV AL,BYTE PTR DS:[DATA7]
CALL CONVERS2
MOV WORD PTR DS:[DATA10],DATA4
RET
NEWTIME: CMP BYTE PTR DS:[DATA9],59H
JC ADD1 ;秒值大于59H,就将分值加1
MOV BYTE PTR DS:[DATA9],0D
CMP BYTE PTR DS:[DATA8],59H
JC ADD2 ;分值大于59H,就将小值加1
MOV BYTE PTR DS:[DATA8],0D
CMP BYTE PTR DS:[DATA7],23H
JC ADD3 ;小时值大于24H,就清零
MOV BYTE PTR DS:[DATA7],0D
JMP OK
ADD1: MOV AL,BYTE PTR DS:[DATA9]
ADD AL,1D ;这里的是用BCD码进行加法的
DAA
MOV BYTE PTR DS:[DATA9],AL
JMP OK
ADD2: MOV AL,BYTE PTR DS:[DATA8]
ADD AL,1D
DAA
MOV BYTE PTR DS:[DATA8],AL
JMP OK
ADD3: MOV AL,BYTE PTR DS:[DATA7]
ADD AL,1D
DAA
MOV BYTE PTR DS:[DATA7],AL
OK: RET
CODE ENDS
END START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -