Category : Assembly Language Source Code
Archive   : MISC_ASM.ZIP
Filename : EC.ASM

 
Output of file : EC.ASM contained in archive : MISC_ASM.ZIP

TITLE exec clock, 5-21-89
PAGE 63,132

cr equ 0dh ; ASCII carriage return
lf equ 0ah ; ASCII line feed
row equ 0 ; row position for clock
column equ 72 ; column " " "

code segment para public 'code'
assume cs:code, ds:code, es:code

org 100h
start:
mov sp,offset stk ; set up the 'stack'
call de_alloc ; free up the hogged ram area,
; must make room for a child
call video_set ; cga/mono detect
call time_set ; read in the trigger time
cloop:
mov ah,0 ; get timer count, placed in
int 1Ah ; BIOS CALL, result => cx,dx
;
; we're going to 'paint' once every eight timer ticks, or every 8/18th seconds
mov al,dl ; set up
and al,0F8h ; mask out 3 low bits, 8 counts
cmp al,entry ; can we enter?
je skip_out ; if same, then no, jump out
mov entry,al ; save it as the next mask
call time_paint ; toss up the time on the crt
;let's see if it's time to go do an 'exec'
mov al,exec_flag ; flag, bit 0 & bit 1 are used
cmp al,3 ; both bits true to go for it
jz do_exec
skip_out:
mov ah,6 ; get a keypress, don't wait!
mov dl,0ffh ; if we get one, break the loop
int 21h
jz cloop
main_exit:
mov ax,4C00h ; exit to dos
int 21h
err_exit:
mov ax,4c01h ; exit with 'errorlevel' to 1
int 21
do_exec:
clc ; clear the carry
call exec ; stupid 8088 can't do a call
; on a flag condition
jc err_exit ; did we boo boo?
jmp short main_exit ;

;---------------------------------------------------
; --------------process the command line parameter
;---------------------------------------------------
time_set proc near
mov bx,80h ; point to command string
cmp byte ptr [bx],0 ; if we don't have one
je time_explain
mov di,offset hour ; point to ram for the time
inc bx ; bump to skip over the 'space'
time_get:
inc bx ; hopefully points to first
mov al,[bx] ; number of time
cmp al,cr ; done & exit
je time_done
mov [byte ptr di],al ; stuff to hour, minute
inc di ; bump
jmp short time_get ; loop

time_explain:
mov dx,offset help_msg ; explain how it works
mov ah,9
int 21h
jmp short time_exit

time_done:
mov ax,hourW ; build the string before out
mov hour_msgW,ax
mov ax,minuteW
mov min_msgW,ax
mov dx,offset signon_msg ; sign on, tell its working
mov ah,9
int 21h
time_exit:
retn
time_set endp

;----------------------------------------------------------
; ------------- de-allocation, return mem to the mem pool
;----------------------------------------------------------
de_alloc proc near
mov ah,4Ah ; mod mem alloc
mov bx,offset end_code ; how big we are
mov cl,4
shr bx,cl ; converted to pages
int 21h
; jc alloc_fail ; we got errors
retn
;alloc_fail:
; retn
de_alloc endp

;-----------------------------------------------------
; ------------- estab and setup the video seg/offset
;-----------------------------------------------------
video_set proc near
mov ax,0F00h ; find out the video mode
int 10h ; video display, 'al' is mode

cmp al,7 ; is it monochrome mode?
je calc_offset ; yes, jump
mov crt_seg,0B800h ; must be color offset
calc_offset:
mov al,row ; get row, top!
mov cl,80 ;
imul cl ; times '80', in ax
mov cl,column ; get col, far right!
xor ch,ch ; first, zero 'ch'
add ax,cx ; add
add ax,ax ; mul
mov seg_offset,ax ; save it
retn
video_set endp

;--------------------------------------------
; ------------- paint screen, check to exec
;--------------------------------------------
time_paint proc near
mov es,crt_seg ; load extra seg to crt ram
mov di,seg_offset ;

mov ax,cx ; convert the hours to ascii
mov cl,24 ; note a 24 hour clock
idiv cl ; al, ah rem = ax/reg
mov al,ah
cmp al,0 ; is it midnight?
jne not_midnight ; no, keep value
mov al,24 ; yes, set to '24'
not_midnight:
aam ; ascii adjust
add ax,3030h ; ascii covert
;test for match
xchg ah,al ; swap for test
cmp ax,hourW
jne hr_continue
or exec_flag,2 ;true, set the 1 bit
hr_continue:
xchg ah,al ; swap back to continue
cmp ah,30h ; is tenths digit a '0'?
jne tenths_digit ; no, keep value
mov ah,20h ; yes, set to ' '
tenths_digit:
xchg ah,al
; write out the tenths hour
stosb ; Store al to es:[di]
inc di ; skip over ATTRIBUTE byte
mov al,ah
; write out the units hour
stosb ; Store al to es:[di]
inc di ; skip attr.
mov al,':' ; write out the hours to
; minutes separator
stosb ; Store al to es:[di]

inc di ; skip attr.
mov ax,dx ; convert the minutes to ascii
mov cx,60
mul cx ; dx:ax = reg * ax
xchg ax,dx
aam ; Ascii adjust
add ax,3030h
;test for match
xchg ah,al ; flip for test
cmp ax,minuteW
jne min_continue
or exec_flag,1 ; true, set the 0 bit
min_continue:
; xchg ah,al ; flip back
; xchg ah,al ; oops, well flip for an 'out
; write out the tenths minute
stosb ; Store al to es:[di]
inc di ; skip attr
mov al,ah
; write out the units minute
stosb ; Store al to es:[di]
inc di ; skip attr
mov al,':' ; write out the minutes to
; seconds separator
stosb ; Store al to es:[di]

inc di ; skip attr
mov ax,dx ; convert the seconds to ascii
mov cx,60 ; SECONDS
mul cx ; dx:ax = reg * ax
xchg ax,dx
aam ; Ascii adjust
add ax,3030h
xchg ah,al
; write out the tenths second
stosb ; Store al to es:[di]
inc di ; skip attr
mov al,ah
; write out the units second
stosb ; Store al to es:[di]
retn
time_paint endp

;-------------------------------------------------
; ------------- the parent makes a child process
;-------------------------------------------------
exec proc near
lea bx,parm_blk ; seg override for debug of
; set up exec block info
;now spawn child
lea dx,prgm_name
push ds ; ES: was used for crt seg
pop es ; ES: must point to our seg
mov ax,ds
mov parm_seg,ax ; fix up segment registers
mov fcb1_seg,ax ; of the child process
mov fcb2_seg,ax
mov ax,4B00h ; do exec
int 21h
jc error_exit ; exit if error spawning child
;back to the parent
mov ah,4dh ; get return code
int 21h ; used by a parent after the
jmp short exec_exit ; successful completion of call
error_exit:
mov dx,offset err_msg0 ; report error to console
mov ah,9
int 21h
exec_exit:
retn
exec endp

;-------------------------------------
; ---------- data area -----------
;-------------------------------------
exec_flag db 0 ; do we have an exec? init off
entry db 0FFh ; counter to screen painter
crt_seg dw 0B000h ; assume we got a MONO crt
seg_offset dw 00000h
hourW label word ; for comparison, to allow it
hour db '00' ; target time
minuteW label word
minute db '00'
err_msg0 db cr,lf,'Error reported by DOS when trying to run the '
db 'batch.$';
help_msg db cr,lf,'You have envoked "EXEC-CLK" without specifying '
db 'a time for the batch file',cr,lf
db '( EXEC-CLK.BAT ) to execute. The default time for '
db 'execution is midnight.',cr,lf
db 'Press any key to immediately stop the process. If '
db 'you wish to specify',cr,lf
db 'the time, type "EC 1930" to start up your batch at '
db '7:30 at night.$'
signon_msg db cr,lf,'You have envoked "EXEC-CLK". The time for '
db 'batch execution will be '
hour_msgW label word
hour_msg db '00:'
min_msgW label word
min_msg db '00.',cr,lf,cr,lf,'$'
;--------- program data area ----------
stk_seg dw 0 ; stack segment pointer
stk_off dw 0 ; save area during exec
;---------- the needs of the child -----------
prgm_name db 'C:\COMMAND.COM',0 ; the batch file to do!
fname equ ($ + 3)
parm_str db fcb1-parm_str-2 ; dynamix adj.
db '/C EXEC-CLK.BAT',cr ; actual parameter string
fcb1 db 0
db 11 dup (' ')
db 25 dup (0)
fcb2 db 0
db 11 dup (' ')
db 25 dup (0)
; --------- parameter block for dos function 4Bh --------
parm_blk dw 0 ; use current environment

parm_off dw offset parm_str ; command line address
parm_seg dw 0 ; fill in at init

fcb1_off dw offset fcb1 ; default FCB #1
fcb1_seg dw 0 ; fill in at init

fcb2_off dw offset fcb2 ; default FCB #2
fcb2_seg dw 0 ; fill in at init
;
dw 128 dup ( 0 ) ; program stack area
stk equ $

align 16 ; round up to next page
end_code equ $ ; marker for de-alloc

code ends

end start