rem ------------------------------------------
rem cron for Psion 3a
rem 01 Sep 94
rem
rem by Paul Merriman
rem
rem A program to trigger the execution of
rem macros at regular intervals
rem
rem ------------------------------------------

app Cron
	type $1000
	icon "b:\ibx\cron.ibx"
enda

PROC main:
	global lg&,max&,period%,next&,intrvl&,count&
	global mins&,secs&,hrs&,forever%, mac$(128)
	global mid&,version,tim&
	global aoff%
	
	local ret%
	
	version=1.2
	
	rem -- load code to run macros
	loadmac:
	
	rem -- initialise globals
	initg:

	max&=hrs&*mins&*secs&
	lg&=now&: - mid&
	
	rem -- show dialog panel
	ret%=shDialog:
	
	rem -- print log header
	header:
	
	if ret%
		rem -- set auto-off time
		rem -- note that we only do this at the start
		setaoff:(aoff%)
		
		rem -- time we want to wakeup
		next& = mid&+lg&
		
		rem -- main loop
		while count& > 0
			log:("Waiting for event")
			rem -- wakeup at next time interval
			wakeup:(next&-now&:)
			next&=now&:
			log:("Event happened - running macro")
			log:(mac$)
			rem -- run the macro
			runit:(mac$)
			if period% = 1
				next&=next&+intrvl&
			elseif period% = 2
				next&=next&+(secs&*intrvl&)
			elseif period% = 3
				next&=next&+(mins&*secs&*intrvl&)
			elseif period% = 4
				next&=next&+(hrs&*mins&*secs&*intrvl&)
			endif
			rem -- if we aren't doing this forever then
			rem -- decrement count
			if forever% = 2
				count&=count& - 1
			endif
		endwh
		
		rem -- its all over now
		print "Cron has finished cycle"
		print "Hit a key to exit"
		get
	else
		rem -- nothing to do
		print "No run scheduled"
		print "Hit a key to exit"
		get
	endif
ENDP

PROC shDialog:
rem -- show the dialog panel to setup job params
	local ret%
	mac$="M:\macro\mco\*"
	forever%=2
	period%=1
	tim&=getaoff%:
	dINIT "Cron scheduler - by P. Merriman"
	dLONG intrvl&, "Interval between events",0,60
	dCHOICE period%, "Units: ", "seconds,minutes,hours,days"
	dLONG count&, "Number of events",0,999999
	dCHOICE forever%, "Continue forever", "yes,no"
	dTIME lg&, "Next event: ", 1, 0, max&
	dFILE mac$, "Macro file to run", 0
	dTIME tim&, "Auto off period", 3, 15, 64799
	ret%=DIALOG
	aoff%=peekw(addr(tim&))
	return ret%
ENDP

PROC header:
rem -- print a log header
	print "Cron event scheduler. Version",version
	print "Interval of",intrvl&,
	if period%=1
		print "seconds"
	elseif period%=2
		print "minutes"
	elseif period%=3
		print "hours"
	elseif period%=4
		print "days"
	endif
	if forever%=1
		print "Running forever"
		count&=1
	else
		print "Occurring",count&,"times"
	endif
	print "First event in",mid&+lg&-now&:,"seconds"
	print "Auto-off set to",tim&,"secs"
	print "Set to run macro file",mac$
	print
	ENDP

PROC wakeup:(secs&)
rem -- ask for a wakeup call in secs& seconds
rem -- works even if we are powered off!
	local ax%,bx%,cx%,dx%,si%,di%
	local t&,a%
	ax%=$0200
	os($89,addr(ax%))
	rem -- make sure you do unsigned arithmetic
	t&=unsig&:(ax%)*&10000 + unsig&:(bx%)
	t&=t& + secs&
	a%=addr(t&)
	call($0c89,0,peekw(uadd(a%,2)),peekw(a%))
ENDP

PROC now&:
rem -- the time now in seconds
	return(DATETOSECS(YEAR, MONTH, DAY, HOUR, MINUTE, SECOND))
ENDP

PROC runit:(macro$)
rem -- run a named macro
	runmacro:( macro$, "macro" )
ENDP

PROC fexist:( ptr% )
rem -- look for macro on all drives
if exist( peek$( ptr% ) ) : return -1 : endif
pokeb ptr% + 1, %a
if exist( peek$( ptr% ) ) : return -1 : endif
pokeb ptr% + 1, %b
if exist( peek$( ptr% ) ) : return -1 : endif
ENDP

PROC log:(mess$)
rem -- write a timed log message
	print datim$,":",mess$
ENDP

PROC unsig&:(num%)
rem -- turn a signed int into an unsigned 
rem -- one (and return as a long value)
	local ret&
	ret&=num%
	if num% < 0
		ret&=ret&+65536
	endif
	return ret&
ENDP

PROC loadmac:
rem -- load macro running routine
	local opa$(128)
	opa$ = "m:\app\macro.opa"
	if fexist:( addr( opa$ ) )
		trap loadm opa$
		if err
			alert( err$( err ) )
			stop
		endif
	else
		alert( "Macro application not found" )
	endif
ENDP

PROC initg:
rem -- init global variables
	mid&=DATETOSECS(YEAR, MONTH, DAY, 0, 0, 0)
	secs&=60
	mins&=60
	hrs&=24
ENDP

PROC getaoff%:
rem -- get system auto-off time
	local ax%
	local t&
	ax%=call($178b)
	return ax%
ENDP

PROC setaoff:(secs%)
rem -- set system auto-off time
    call($188b,secs%)
ENDP
