;    感觉双休就想睡觉,这鬼天气,一直下雨。设置时间未完成,只是加了一个所谓的主界面
;   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

posted on 2014-05-18 20:50  Notflybird  阅读(159)  评论(0编辑  收藏  举报