|
Have you ever wanted to place a clock in your DOS app and have it continually keep updating itself with out you having to "keep track of time"? Well here is some source code called by Basic to do it.
To call it from basic, all you need is the DECLARE SUB line and then call it to turn it on and again to turn it off. Very simple.
Heres an example on how to call it from Basic:
DECLARE SUB Clock (Mode%)
Clock 1
PRINT "Press any key to quit..."
V$ = INPUT$(1)
Clock 0
END
In the assembler code, all we do is see if we are already installed. If not, we install it.
The hardware interrupt 1Ch, is called by the hardware 18+ times a second. There is no need for us to update our clock 18+ times a second, so we decrement and check our counter. If we reach zero with our counter, we set it to 18 again and do our code.
All we do with our code is get the current time and display it in the upper right corner.
This code was assembled with MASM 5.1x. You can modify it for your tastes to print the color you want or to make it print in a different place. This code should assemble in TASM with a few modifications.
¥
DOSSEG
.MODEL medium, basic
.286
.STACK
.CODE
Adapter DB 0
Attribute DB 70h
ClockText DB ?,?,58,?,?,58,?,?,32,?,109
Counter DB ?
OldInt1C DW ?,?
Status DB 0
VideoBffr DW ?
VideoOff DW ?
Hrs DB ?
Min DB ?
Sec DB ?
public Clock
Clock proc far basic uses bp bx cx dx si di ds es, Mode:word
xor dh,dh
mov dl,61
mov si,offset Mode
mov bh,[si]
push cs
pop ds
or bh,bh
jz Terminate
cmp bh,1
jne Exit
call Initialize
mov ah,2Ch
int 21h
mov Hrs,ch
mov Min,cl
mov Sec,dh
mov Counter,2
call DoClock
cmp Status,1
je Exit
mov ax,351Ch
int 21h
mov OldInt1C,bx
mov OldInt1C[2],es
mov ax,251Ch
lea dx,INT1C
int 21h
mov Status,1
jmp short Exit
Terminate: cmp Status,1
jne Exit
mov Status,0
lds dx,dword ptr OldInt1C
mov ax,251Ch
int 21h
Exit: ret
Clock ENDP
INT1C proc far
call DoClock
IRET
INT1C endp
DoClock proc near uses ax cx dx si di ds es
push cs
pop ds
sti
dec Counter
jz NotDone
jmp Done
NotDone: mov cl,60
mov dx,0C0Ah
lea di,ClockText[6]
mov al,Sec
inc al
cbw
div cl
mov Sec,ah
call Bin2ASCII
mov al,Min
add al,ch
cbw
div cl
mov Min,ah
call Bin2ASCII
mov al,Hrs
add al,ch
mov Hrs,al
cbw
div dh
or ah,ah
jnz Cont
mov ah,12
Cont: call Bin2ASCII
mov ClockText[9],'p'
cmp ch,1
je WriteTime
mov ClockText[9],'a'
WriteTime: mov es,VideoBffr
lea si,ClockText
mov ah,Attribute
mov di,VideoOff
mov dx,3DAh
mov cx,11
cld
jmp short Output2
Output1: cmp Adapter,2
jne Output2
NoRetrace: in al,dx
test al,1
jne NoRetrace
Retrace: in al,dx
test al,1
je Retrace
Output2: lodsb
stosw
loop Output2
mov Counter,18
Done: ret
DoClock endp
Bin2ASCII proc near
mov ch,al
mov al,ah
cbw
div dl
add al,48
mov [di],al
inc di
add ah,48
mov [di],ah
sub di,4
ret
Bin2ASCII endp
Initialize Proc near
mov al,160
mul dh
shl dl,1
xor dh,dh
add ax,dx
mov VideoOff,ax
cmp Adapter,0
jne InitExit
mov ax,40h
mov es,ax
mov bx,0B000h
mov dl,1
mov al,es:[10h]
and al,110000b
cmp al,30h
je SaveVals
add bx,800h
inc dl
mov al,es:[87h]
or al,al
jz SaveVals
inc dl
SaveVals: mov VideoBffr,bx
mov Adapter,dl
InitExit: ret
Initialize endp
end
|