📄 cx2.asm
字号:
.model small
;-------------------------------------------------------------------------
.stack
;-------------------------------------------------------------------------
.data
HOUR db ?
MIN db ?
SEC db ?
MSEC db ?
NHOUR db 0 ;设置时间使用
NMIN db 0 ;设置时间使用
NSEC db 0 ;设置时间使用
RHOUR db 1 ;设置闹铃时间使用
RMIN db 1 ;设置闹铃时间使用
RSEC db 1 ;设置闹铃时间使用
FUNKEY db ? ;功能设置使用
keySw db 00h ;是否按键开关
RingSw db 00h ;闹铃开关
SWITCH db 0FFh ;刷新开关,真,则不断在定时器中断函数中刷新,否则不刷新
n db 0dh,0ah,'$'
count dw 1
sMsg db '@@@@ welcome to Simple clock @@@@',0dh,0ah,'$'
qMsg db '**** Please Input q to quit ****',0dh,0ah
db ' ','**** Input s to set new Time ****',0dh,0ah
db ' ','**** Input r to set ringTime ****',0dh,0ah,'$'
SETTMSG DB 'Please Input new Time(HH:MM:SS)',0DH,0AH
db 'what do you want to change:',0dh,0ah
db 'hour<h> @ min<m> @ sec<c>' ,0DH,0AH,'$'
setRMsg db 'Please Input Ring Time(HH:MM)',0dh,0ah,'$'
authorMsg db ' ',0dh,0ah
db ' --------------------------- ',0dh,0ah
db ' Author: yanchunxia',0dh,0ah
db ' Number: 0905040430',0dh,0ah
db ' Date : 2007/01/05',0dh,0ah
db ' ---------------------------',0dh,0ah,'$'
;-------------------------------------------------------------------------
.code
PUSHA MACRO
PUSH DS
PUSH AX
PUSH BX
PUSH CX
PUSH DX
ENDM
POPA MACRO
POP DX
POP CX
POP BX
POP AX
POP DS
ENDM
;----------------------------------------------------------------------------
;Main program
main proc far
start:
mov ax,@data ;allot data segment
mov ds,ax
push ds ;store the ds
;get the System time
call GETTIME ;取得系统时间
call initUI ;初始化界面
;save old interrupt vector
mov al,1ch ;al<=vector number
mov ah,35h ;to get interrupt vector
int 21h ;call DOS
push es ;save registers for restore(old base address)
push bx ;save offset of interrupt 1CH
push ds
;set new interrupt vector
mov dx,offset tUpdate ;dx<=offset of procedure ring
mov ax,seg tUpdate ;ax<=segment of procedure ring
mov ds,ax ;ds<=ax
mov al,1ch ;al<=vector#
mov ah,25h ;to set interrupt vector
int 21h ;call DOS
pop ds ;restore ds
in al, 21h ;set interrupt mask bits
and al, 11111100b ;读IMR
out 21h,al
sti
delay:
PUSHA
cmp ds:[keySw],0FFh ;check if any key is pressed
jz exitdelay ;exit delay if any key is pressed
ringP: ;闹铃判断
;mov dl,ds:[MIN]
mov dl,ds:[RHOUR] ;判断闹铃时间(小时)
cmp dl,ds:[HOUR]
jne noRing
mov bl,ds:[RMIN] ;判断闹铃时间(分钟)
cmp bl,ds:[MIN]
jne noRing
mov dh,ds:[RingSw] ;check if the Ring Switch is On.(只要调用SETRTIME就会打开闹铃开关)
cmp dh,00h
jz noRing
call GENSOUND ;call GENSOUND to make clock ring
noRing:
POPA
;wait
jmp delay
exitdelay:
POPA
;restore old interrupt vector
pop dx ;restore registers(restore the old offset)
pop ds ;restore old base of interrupt
mov al, 1ch ;al<=vector#
mov ah, 25h ;to restore interrupt
int 21h ;call DOS
pop ds ;restore ds
;读敲入的按键
mov ah,07h
int 21h
;mov al,ds:[FUNKEY]
cmp al,'s'
jne next1
;判断读入字符然后进行相应处理,此时中断函数已经取消,只是单线程
setT:
; mov ah,07h ;读字符
; int 21h
mov ds:[FUNKEY],al
call SETTIME ;调用子函数设置时间
; mov ah,01h
; int 21h
mov ds:[keySw],00h
jmp start
next1:
cmp al,'r'
jnz next2
setr: mov ds:[FUNKEY],al
call setring ;调用字函数设置闹铃时间
mov ds:[keySw],00h
jmp start
next2: cmp al,'q'
je endmain
mov ds:[keySw],00h
jmp start
endmain:
mov ax,4c00h ;exit
int 21h
main endp
;------------------------------------------------------------------------
;定时中断程序()
;
;Introduction:
;在系统定时器(中断类型为8)的中断处理程序中,有一条中断指令INT 1CH,
;时钟中断每发生一次(约每秒发生18.2次,即55ms发生一次)都要嵌套调用
;一次中断类型1CH的处理程序。在ROM BIOS例程中,1CH的处理程序只有一条IRET,
;实际上它并没有作任何工作,只是为用户提供了一个中断类型号。如果用户有某种
;定时周期性的工作需要完成,就可以利用系统定时器的中断间隔,用自己设计的
;处理程序来代替原有的1CH的中断程序。
; 本程序就是将原有1CH中断程序进行替换,实现了定时更新时间。采用DOS
;中断驻留中断程序。
;
tUpdate proc near
pusha
mov ax, @data ;allot data segment
mov ds, ax
sti
dec count ;count for timer interval(约18.2次为1秒)
jnz exit ;exit if not for 1 second
mov count,18 ;control ring interval delay(10s)
call CALTIME ;更新时间
;检测刷新开关是否打开
mov bl,ds:[SWITCH]
cmp bl,00H
jz exit
;检测是否有按键按下,取适当的值进行退出控制
PUSHA
MOV AH, 0BH ;检测是否输入消息(按键消息)
INT 21H
INC AL
JNZ nokey
mov ds:[keySw],0FFh ; 设置已经被按键
POPA
jmp exit
nokey:
POPA
call DISPLYH ;显示小时
call DISPLYM ;显示分钟
call DISPLYS ;显示秒
exit:
cli
mov al,20h ;set EOI
out 20h,al
POP DX
pop cx
pop bx
pop ax
pop ds
iret ;中断返回
tUpdate endp
;--------------------------------------------------------------------
;关闭定时刷新开关
closeSw proc near
PUSHA
mov bl,0h
mov ds:[SWITCH],bl ;关闭刷新开关
POPA
ret
closeSw endp
;----------------------------------------------------------
;打开定时刷新开关
openSw proc near
PUSHA
mov bl,0FFh
mov ds:[SWITCH],bl ;打开刷新开关
POPA
ret
openSw endp
;---------------------------------------------------------------------------
;初始化显示界面,可以在此处添加额外的设置选项
INITUI proc near
PUSHA
mov ah,00h
mov al,00h
int 10h
;显示头标题
mov dh,00h
mov dl,02h
call MOVCUR
mov dx,offset sMsg ;dx<=offset of sMsg
mov ah,09h ;to display sMsg
int 21h ;call DOS
;显示结尾标题
mov dh,02h
mov dl,02h
call MOVCUR
mov dx,offset qMsg ;dx<=offset of qMsg
mov ah,09h ;to display qMsg
int 21h ;call DOS
;显示作者信息
mov dh,0bh
mov dl,05h
call MOVCUR
mov dx,offset authorMsg ;dx<=offset of authorMsg
mov ah,09h ;to display authorMsg
int 21h ;call DOS
mov
POPA
ret
initUI endp
;--------------------------------------------------------------------------
;移动光标(dh:row,dl:col)
; dh ;参数设置行
; dl ;参数设置列
MOVCUR proc near
PUSHA
;设置光标位置
mov ah,2h
mov bh,0
int 10h
POPA
ret
MOVCUR endp
;-------------------------------------------------------------------------
;显示小时
DISPLYH PROC NEAR
PUSHA
; 设置光标位置
mov dh,08h ;set Row No.
mov dl,13d ;set Column NO.
call MOVCUR
mov dh,0
mov dl,ds:[HOUR]
call output ;调用output函数输出小时
mov dl,':'
mov ah,02h
int 21h
POPA
RET
DISPLYH ENDP
;----------------------------------------------------------
;显示分钟
DISPLYM PROC NEAR
PUSHA
;设置光标位置
mov dh,08h ;set Row No.
mov dl,16d ;set Column NO.
call MOVCUR
mov dh,0
mov dl,ds:[MIN]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -