; 感觉双休就想睡觉,这鬼天气,一直下雨。设置时间未完成,只是加了一个所谓的主界面
; display system time. press f1 to change the color displayed, press esc to return main list. f3 exit
; clear_screen 清空屏幕
assume cs:codesg
stacksg segment
dw 128 dup(0)
stacksg ends
codesg segment
line db 12
csip dw 0,0
exitflag db 0 ; f3-2, esc-1. 只有在主界面才能退出,所以每次从时钟返回都会重置此值
color db 2
list dw display, setclock
setclock db '2) set clock', 0
display db '1) clock', 0
start:
mov ax, stacksg
mov ss, ax
mov sp, 128
mov ax, cs
mov ds, ax
mov ax, 0
mov es, ax
push es:[9*4]
pop csip[0]
push es:[9*4 + 2]
pop csip[2]
cli
mov word ptr es:[9*4], offset int9
mov es:[9*4 + 2], cs
sti
; 主菜单
main_screen:
call clear_screen
mov cx, 2
mov al, 1
dis_main:
mov bx, cx
dec bl
add bx,bx
mov si,list[bx]
call printf
dec al
loop dis_main
; 获取输入
getinput:
cmp exitflag, 2
je exit
; 1,2为有效输入,其它忽略(暂时只实现1)
mov ah, 0
int 16h
cmp ah, 02h ; 通码 1-9:02-0a
je main_print_clock
cmp ah, 03h
je main_set_clock
; 其它情况,对比是否有功能键触发事件
jmp getinput
main_print_clock:
; 显示时钟,若返回,则显示主界面
mov ah, 0
call clock
mov exitflag, 0
mov color, 2
jmp main_screen
main_set_clock:
mov ah, 1
call clock
mov exitflag, 0
mov color, 2
jmp main_screen
exit:
; 恢复向量表
push csip[0]
pop es:[9*4]
push csip[2]
pop es:[9*4 + 2]
mov ax, 4c00h
int 21h
; clock子函数,ah 传递功能号, 0- 显示时钟,1- 设置时钟
clock:
jmp short do_clock
clocktable dw dis_clock, set_clock
clock_str db '20yy/mm/dd hh:mm:ss',0
row db 9,8,7,4,2,0
; 秒: 0 分:2 时: 4 日 : 7 月:8 年:9
do_clock:
push bx
push ax
push si
push di
push cx
push ds
cmp ah, 1
ja clock_ret
cmp ah, 0
jb clock_ret
mov bl, ah
mov bh, 0
add bx,bx
jmp word ptr clocktable[bx]
; 每1s显示一次时钟
dis_clock:
call clear_screen
s_second:
mov di, 2
mov si, 0
mov cx, 6
; 设置时钟字符串
s: mov al, row[si]
out 70h, al
in al, 71h
mov ah, al
push cx
mov cl, 4
shr ah, cl
pop cx
add ah, 30h
and al, 00001111b
add al, 30h
mov clock_str[di], ah
mov clock_str[di + 1], al
add di, 3
inc si
loop s
mov si, offset clock_str
mov al, 1
call printf
call delay
cmp exitflag, 1 ; only esc can return from clock screen
je clock_ret
jmp short s_second
set_clock:
clock_ret:
pop ds
pop cx
pop di
pop si
pop ax
pop bx
ret
delay:
push ax
push dx
mov dx, 0BFFh
mov ax, 0
s_delay:
sub ax, 1
sbb dx, 0
cmp ax, 0
jne s_delay
cmp dx, 0
jne s_delay
pop dx
pop ax
ret
clear_screen:
blank db ' ', 0
push si
push cx
push ax
mov si, offset blank
mov cx, 4
mov al, 0
s_clear:
call printf
inc al
loop s_clear
pop ax
pop cx
pop si
ret
printf:
push ax
push es
push si
push di
push bx
; 显示函数, 行号在line变量中,从第8列开始。al-表示第X(X>=1)次调用。字符串地址-ds:[si],碰到0结束返回
mov bl, al
mov ax, 0b800h
mov es, ax
mov bh, 160
add bl, line[0]
mov al, bl
mul bh
mov di, ax
add di, 2*8
s_print:
mov bl, ds:[si]
cmp bl,0
je s_print_out
mov bh, color
; 无论哪行,从第8列开始显示
mov es:[di], bx
inc si
add di, 2
jmp s_print
s_print_out:
pop bx
pop di
pop si
pop es
pop ax
ret
int9:
push ax
in al, 60h
pushf
call dword ptr csip
; check if equal esc:01, f1:3b, f1 change color. esc exit function
cmp al, 01h ;esc
je sesc
cmp al, 3bh
je f1
cmp al, 3dh ; F3 退出
je f3
mov exitflag, 0
jmp int9ret
f1: inc color
jmp int9ret
f3:
mov exitflag, 2
jmp int9ret
sesc:
mov exitflag, 1
int9ret:
pop ax
iret
codesg ends
end start