;***********************************************************************
; CLOCK.ASM
;***********************************************************************
;Description:
; An extremely simple TSR that loads the time to the upper right
; corner of the screen from (70,0) to (79,0).
; It uses int 1Ah to read real time, and int 10H to go to the
; locations needed and writes it.
;Comments:
; For advanced programmers this program seems clumsy, they may
; wonder :
; - Why in earth would you use int 10 functions and need to
; put the cursor up to the location, then write the character, then
; go back, and continue this way while you could've written direct-
; ly to the screen at location 0B800H CGA buffer?
;
; - Why use int 1AH and need to do all these corrections to the
; hour, minute, and seconds while you could've applied int 21H's
; DOS functions to get the time?
;
; - Why in earth need to write this program at all, while you
; can know the time by writing time at the DOS prompt?
;
; The answers of all these questions is :
; It's possible to write directly to the buffer, and it's also
; possible to use DOS's get time function. But I did it the
; hard way to demonstrate the use of these interrupts. The truth
; is that this program could've been and faster easier to build.
; But,,,,,
; Why I wrote this program is another matter, it's because I
; needed to since I used to enter telnet from an NFS system in a
; LAN, and needed to run some unix command to get the time, so I
; said why not write the program to stay even in telnet shells?
; And I did. If you think that it's of no use, you may delete it!
;
; Thanx for getting my program, please report any bugs to:
;
; Walid Al-Saqqaf
; e78199@erkin.ceng.metu.edu.tr
;**********************************************************************
.MODEL SMALL
.CODE
ORG 100H
FIRST: jmp Install
old_int_label label word
old_int dd ?
H db ?; hours
M db ?; minutes
S db ?; seconds
LD db ?; lower digit
HD db ?; higher digit
new_int PROC
push ax ;save registers and flags
push bx
push cx
push dx
pushf
mov ah,03 ;save the original x,y coord.
mov bh,0
int 10h ; dh:row,dl:col
push cx
push dx
mov ah,1 ;and hide cursor for a while
mov cx,2000h
int 10h
;Begin WRITE TIME
mov ah,2 ;Get time from CMOS directly, (not from DOS)
int 1Ah ;Use the interrrupt 1Ah to get real time
cmp ch,25 ;from RTC (CMOS)
jle h1
sub ch,12
jmp h2
h1: cmp ch,9 ;Adjust the hour's value from RTC to resolve
jle h2 ;the actual time
sub ch,6
h2: mov H,ch
cmp cl,73
jle m1
sub cl,30 ;Adjust the minutes' value from RTC to resolve
jmp m5 ;the correct minutes' value
m1: cmp cl,57
jle m2
sub cl,24
jmp m5
m2: cmp cl,41
jle m3
sub cl,18
jmp m5
m3: cmp cl,25
jle m4
sub cl,12
jmp m5
m4: cmp cl,9
jle m5
sub cl,6
m5: mov M,cl
cmp dh,73
jle s1 ;Adjust the seconds' value from RTC to resolve
sub dh,30 ;the correct seconds' value
jmp s5
s1: cmp dh,57
jle s2
sub dh,24
jmp s5
s2: cmp dh,41
jle s3
sub dh,18
jmp s5
s3: cmp dh,25
jle s4
sub dh,12
jmp s5
s4: cmp dh,9
jle s5
sub dh,6
s5: mov S,dh
mov ah,0 ;Since we can only type one digit at a time,
mov al,H ;with the int 10H, We should partition the
mov bl,10 ;BCD value of H, M, and S to 2 digits (LD,HD)
div bl
mov HD,al
mov LD,ah ;get HD & LD of hours (low and high digits)
mov ah,2 ;go to position (2,70)
mov dh,0
mov dl,70
int 10h
mov ah,9
mov al,'║' ;and write a '║'
mov bl,27
mov cx,1
int 10h
mov ah,2 ;go to hour position (2,71)
mov dl,71
int 10h
mov ah,9
add HD,48
mov al,HD ;and First write HD of the Hours
mov bl,27
int 10h
mov ah,2 ;go to hour position (2,72)
mov dl,72
int 10h
mov ah,9
add LD,48
mov al,LD ;and write the LD of Hours
mov bl,27
int 10h
mov ah,2 ;go to hour's : position (2,73)
mov dl,73
int 10h
mov ah,9
mov al,':' ;and write a ':'
mov bl,27
int 10h
mov ah,0
mov al,M
mov bl,10
div bl ;get HD & B of Minutes
mov HD,al
mov LD,ah
mov ah,2 ;go to hour position (2,74)
mov dl,74
int 10h
mov ah,9
add HD,48
mov al,HD ;and First write HD of the Minutes
mov bl,27
int 10h
mov ah,2 ;go to Minute position (2,75)
mov dl,75
int 10h
mov ah,9
add LD,48
mov al,LD ;and write the LD of Minutes
mov bl,27
int 10h
mov ah,2 ;go to position (2,76)
mov dl,76
int 10h
mov ah,9
mov al,58 ;and write a blinking ':'
mov bl,155
int 10h
mov ah,0
mov al,S
mov bl,10
div bl ;get HD & LD of Seconds
mov HD,al
mov LD,ah
mov ah,2 ;go to second's position (2,77)
mov dl,77
int 10h
mov ah,9
add HD,48
mov al,HD ;and First write HD of the Seconds
mov bl,27
mov cx,1
int 10h
mov ah,2 ;go to hour position (2,78)
mov dl,78
int 10h
mov ah,9
add LD,48
mov al,LD ;and write the LD of Seconds
mov bl,27
int 10h
mov ah,2 ;go to position (2,79)
mov dl,79
int 10h
mov ah,9
mov al,'║' ;and write a '║'
mov bl,27
int 10h
;End write time
exit: mov ah,1 ;enable cursor
mov ch,6
mov cl,7
int 10h
pop dx
mov ah,02 ;go back to where you were
int 10h
pop cx
mov ah,1 ;with the same cursor type
int 10h
popf
pop dx ;restore registers
pop cx
pop bx
pop ax
pushf
call old_int ;and call old_int (original int 8)
iret
new_int ENDP
Install PROC
mov ax,3508h
int 21h
mov old_int_label, bx
mov old_int_label[2], es ;save the old int 8
mov ah, 25h
lea dx, new_int
int 21h ;associate new_int with int 8
mov dx, offset Install
int 27h
Install ENDP
END FIRST