; NWATCH - Watch for non-TVs   -*-MIDAS-*-
versio==.fnam2

title Digital watch


.insrt syseng;$call macro
.insrt eak;macros >
bp=d
cc=e

tyoc==1


lpdl==10
lcmdbuf==10

var stime		; sleep time, i.e. time between updates
var oline		; output line no.
var linel		; terminal line length
var pagel		; terminal page length
var pdl(lpdl)		; stack
var cmdbuf(lcmdbuf)	; command buffer
var obuf(4)		; output buffer

flag ovr		; set if TTY can't overprint
flag mil		; use 24 hour (military) time
flag pact		; use the paacific time zone
flag secs		; include seconds in display

nwatch:	move p,[-lpdl,,pdl-1]	; set up stack
	.suset [.roption,,f]
	trz f,%fovr+%fmil+%fsecs	; init flags
	movei t,5*30.		; init sleep time to 5 seconds
	movem t,stime		; ...
	setzm oline		; use top line for output
	.open tyoc,[.uio,,'tty]
	 .lose %lsfil
	$call cnsget,[#tyoc][pagel,linel,t,t,a]
	 .lose %lssys		; too bad
	tlne a,%toovr		; copy %TOOVR into %FOVR
	 tro f,%fovr
	aos linel		; include continuation column in linel
	tlnn f,optcmd		; superior have a command line for us?
	 jrst cmd3
	move t,[cmdbuf,,cmdbuf+1]	; clear command buffer
	setzm cmdbuf
	blt t,cmdbuf+lcmdbuf-1
	.break 12,[5,,cmdbuf]		; read command from superior
	move a,[440700,,cmdbuf]		; b.p. to command buffer
	movei b,0
	ldb t,[350700,,cmdbuf]		; get first char of JCL
	caie t,"?		; requesting doc?
	 jrst cmd1
	sout #tyoc,,"NWATCH command line options:
<number>	No. of seconds between updates (5 sec default)
/B		Display on bottom line of screen
/M		Use 24 hour time
/S		Display seconds
/P		Convert time to pacific time zone
"
	jrst quit
cmd1:	ildb t,a		; take no. of seconds to sleep from
	cail t,"0		; command line and convert to binary
	 caile t,"9
	  jrst cmd2
	imuli b,10.		; multiply previous crap by 10
	addi b,-"0(t)		; add in this digit
	jrst cmd1
cmd2:	imuli b,30.		; convert to 30ths
	skipe b			; don't allow a zero sleep time
	 movem b,stime		; store sleep time
	caia			; character already in T, skip ILDB
cmd2a:	ildb t,a		; get next character
	caie t,^M		; CR or ^C?
	 cain t,^C
	  jrst cmd3
	caie t,"/		; terminator a slash?
	 jrst cmd2a
	ildb t,a		; get character after slash
	cail t,"a		; lowercase letter?
	 caile t,"z
	  caia
	   subi t,40		; convert to uppercase
	cain t,"M		; /M?
	 tro f,%fmil		; /M, use 24 hour time
	move b,pagel		; get bottom line no.
	cain t,"B		; /B?
	 movem b,oline		; /B, make output line the bottom line
	cain t,"S		; /S?
	 tro f,%fsecs		; /S, include seconds in output
	cain t,"P		; /P?
	 tro f,%fpact		; /P, use pacific time zone
	jrst cmd2a
cmd3:	tlne f,optddt
	 .value [asciz ":FORGET "]	; start running

update:	move bp,[440700,,obuf]	; buffer ptr
	movei cc,0		; character count
	move a,[440700,,[asciz "SV"]]
	pushj p,ascout		; buf ^PV for setting vertical position
	move t,oline		; get output line no.
	addi t,8		; add 8 for ITS
	idpb t,bp		; store vertical position
	aos cc			; ...
	move a,[440700,,[asciz "H"]]
	pushj p,ascout		; buf ^PH for setting horizontal position
	move t,linel		; get horizontal position
	subi t,5		; subtract no. of chars in time
	trne f,%fsecs		; seconds too?
	 subi t,3		; need three more chars
	addi t,8		; add 8 for ITS
	idpb t,bp		; move there
	aos cc
	trnn f,%fovr		; can TTY overprint?
	 jrst l1		; no, don't need to erase to end of line
	move a,[440700,,[asciz "L"]]	; output an erase to end of line
	pushj p,ascout
l1:	$call rqdate,,a		; get date
	 .lose %lssys
	movei a,(a)		; time is low 18 bits 
	idivi a,60.*2		; convert from half seconds to minutes
	push p,b		; now minutes in a, half seconds in b
	idivi a,60.		; convert to hours and minutes
	trnn f,%fpact		; pacific time zone?
	 jrst l1.5
	subi a,3		; we're 3 hours behind
	jumpge a,l1.5		; no wrap to worry about
	 addi a,24.		; correct to the previous day
l1.5:	trne f,%fmil		; 24 hour time?
	 jrst l2
	cail a,12.		; convert from 24 hour to 12 hour time
	 subi a,12.
	cain a,0		; in 12-hour mode the first hour after midnight
	 addi a,12.		; is called 12 o'clock too.
l2:	pushj p,deczs		; put out hours
	movei t,":
	idpb t,bp		; put in ":"
	aos cc
	move a,b
	pushj p,decout		; put out minutes
	pop p,a			; restore half seconds
	trnn f,%fsecs		; seconds?
	 jrst l3
	movei t,":
	idpb t,bp		; put in ":"
	aos cc
	lsh a,-1		; convert to seconds
	pushj p,decout
l3:	move a,[440700,,[asciz "R"]]
	pushj p,ascout
	move bp,[440700,,obuf]
	$call siot,[#tyoc,bp,cc],#%tjdis+%tjctn
	 .lose %lsfil
;	$call finish,#tyoc
;	 .lose %lsfil
	move t,stime
	.sleep t,		; sleep peacefully
	jrst update

ascout:	ildb t,a
	jumpe t,cpopj
	idpb t,bp
	aos cc
	jrst ascout
cpopj:	popj p,


deczs:	push p,b
	idivi a,10.
	addi a,"0
	cain a,"0
	 movei a,40
	jrst dec1

decout:	push p,b
	idivi a,10.
	addi a,"0
dec1:	idpb a,bp
	aos cc
	addi b,"0
	idpb b,bp
	aos cc
	pop p,b
	popj p,


quit:	.break 16,140000
	.value


constants
variables


end nwatch
