cseg    segment para public 'code'
        org 100h

; This program is used to cause the computer to wait until the
; specified time. For example, 'UNTIL 20:20' will cause the system
; to wait until 20:20 (8:20 PM).

until   proc far
        assume cs:cseg,ds:cseg,ss:nothing,es:nothing

        mov si,80h              ; point to command line
        mov ch,0
        mov cl,[si]             ; get length
        jcxz p010               ; it's zero
        jmp p020

p010:   mov dx,offset msg1      ; print error
        call p120
        jmp p040                ; and quit

p020:   mov cx,10
        call p140               ; get hours
        cmp al,0
        jb p010                 ; too low
        cmp al,23
        ja p010                 ; too high
        mov untilhr,al
        aam                     ; convert to ascii
        add ax,3030h
        xchg ah,al
        mov msg2hr,ax

        call p140               ; get minutes
        cmp al,0
        jb p010                 ; too low
        cmp al,59
        ja p010                 ; too high
        mov untilmin,al
        aam                     ; convert to ascii
        add ax,3030h
        xchg ah,al
        mov msg2min,ax

        mov ah,2                ; home the cursor
        mov bh,0
        mov dx,0
        int 10h

        mov ax,600h             ; clear screen
        mov bh,7
        mov cx,0
        mov dx,184fh
        int 10h

        mov dx,offset copyr     ; print copyright
        call p120

        mov dx,offset msg2      ; print target time
        call p120

        mov dx,offset msg3      ; print current time
        call p120

        mov ah,3                ; get cursor position
        mov bh,0
        int 10h
        mov coords,dx           ; save coordinates

p030:                           ; loop til time is up
        mov cx,0ffffh           ; kill time
p031:   inc dx
        loop p031

        mov ah,2                ; set cursor position
        mov bh,0
        mov dx,coords
        int 10h

        mov ah,2ch              ; get time
        int 21h

        mov al,ch
        call p100               ; print hours
        mov dl,':'
        call p110               ; print colon
        mov al,cl
        call p100               ; print minutes
        mov dl,':'
        call p110               ; print colon
        mov al,dh
        call p100               ; print seconds

        mov ah,untilhr
        mov al,untilmin
        cmp ax,cx               ; done?
        jnz p030                ; no

p040:   int 20h                 ; terminate

p100    proc near               ; print number
        push dx
        push cx
        mov dx,0
        mov cx,10
        mov ah,0
        div cx
        add dl,48
        mov bl,dl
        mov dx,0
        div cx
        add dl,48
        call p110
        mov dl,bl
        call p110
        pop cx
        pop dx
        ret
p100    endp

p110    proc near               ; print char
        push ax
        mov ah,2
        int 21h
        pop ax
        ret
p110    endp

p120    proc near               ; print string
        push ax
        mov ah,9
        int 21h
        pop ax
        ret
p120    endp

p140    proc near               ; get hours & minutes
        mov ax,0
        cmp ch,0                ; end of line?
        jnz p148                ; yes

p142:   inc si                  ; point to next char
        mov dl,[si]
        cmp dl,':'              ; colon?
        jz p148                 ; yes
        cmp dl,13               ; carriage return?
        jz p147                 ; yes
        cmp dl,'0'
        jb p142                 ; < 0 - ignore it
        cmp dl,'9'
        ja p142                 ; > 9 - ignore it
        sub dl,'0'              ; convert to binary
        mul cl                  ; current contents of al times 10
        add al,dl               ; add latest digit
        jmp p142                ; get next one

p147:   inc ch                  ; end of line
p148:   ret
p140    endp

copyr   db 'UNTIL - Copyright 1983 Data Base Decisions',10,13,'$'
msg1    db 'Missing/Invalid time',07,10,13,'$'
msg2    db 'Waiting until: '
msg2hr  dw '00'
        db ':'
msg2min dw '00'
        db 10,13,'$'
msg3    db 'The time is  : $'

untilhr db 0                    ; target hour & minute
untilmin db 0
coords  dw 0                    ; cursor coords

until   endp
cseg    ends
end     until
