
	title	'STATTIME as of october 20, 1980'

; 
; 
;  Here  is  an  interesting  "patch"  to  Digital  Research's 
; STAT.COM, that incorporates a "real time clock display. This 
; patch  works with STAT.COM for CP/M version 2.2 ONLY.  Merge 
; it into STAT.COM as follows:
; 
;      A>DDT STAT.COM<cr>
;      NEXT   PC
;      1580  0100
;      -ISTATTIME.HEX<cr>
;      -R<cr>
;      NEXT   PC
;      16CD  0000
;      -^C
;      A>SAVE 22 STATTIME.COM<cr>
; 
;  Now you have a new "STAT" command file called STATTIME.COM, 
; and it will display the "real time" on every execution...
; 
;                         Best regards,
;           
;                         Kelly Smith, MP/M-Net (tm) Sysop
;                         (805) 527-9321 (Modem, 300 Baud)
;
;
;
;	STATTIME.ASM (revised 10/16/80)
;
;	Revised from the May 1980, INTERFACE AGE MAGAZINE
;
;	For Compu-Time T-102 TIME/DATE board (With MM 5375 AC)
;
;       or,
;
;	QT Computer Systems Inc. "Clock/Calendar +" board
;
;
bdos	equ	5
pbuf	equ	9

stat	equ	433h	; STAT.COM entry address

cr	equ	0dh	; ASCII carriage return
lf	equ	0ah	; ASCII line feed

true	equ	-1	; define true
false	equ	not true; define false
qt	equ	true	; define QT Computer Systems Clock/Calendar + board
ct	equ	false	; Compu-Time Time/Date board

	if qt

clock	equ	080h	; real time clock base port address

	endif

	if ct

clock	equ	024h	; real time clock base port address

	endif


	org     0100h

	jmp	date

	org	1501h	; version 2.2 stat.com entry address

date:	push psw ! push b ! push d ! push h
	lxi	h,month	; point to month
	mvi	d,8	; select month tens digit
	call	digit	; read and store high digit
	rlc ! rlc ! rlc ! rlc	; shift to high order hex digit
	mov	b,a	; save in b reg.
	call	digit	; read and store month units digit
	ora	b	; or-in the units and tens digit
	mov	b,a	; save the month in b reg.
	call	digit	; read and store the day tens digit
	rlc ! rlc ! rlc ! rlc	; shift to high order hex digit
	mov	c,a	; save in c reg.
	call	digit	; read and store day units digit
	ora	c	; or-in the units and tens digit
	mov	c,a	; save the day in c reg.

;
; test the date, and convert it to four year calendar format
;

	cpi	031h	; 31st day?
	mov	a,b	; get the month, for next test
	jnz	m2	; if not the 31st, test for february
	cpi	2	; test for months < 31 days
	jz	fix	; ...and fix if needed
	cpi	4
	jz	fix
	cpi	6
	jz	fix
	cpi	9
	jz	fix
	cpi	011h
	jz	fix
m2:	cpi	2	; test for february
	jnz	time	; if not february, then read time
	mov	a,c	; get day for test
	cpi	029h	; is this the 29th day?

;
; insert two NOP's over previous instruction, if this is a leap year
;
	jz	fix	; fix date...
	cpi	030h	; 30th day?
	jnz	time	; if not the 29th or 30th, go read time
fix:	mvi	a,41	; select month units and fast set
	call	rdigit	; read the month units digit
	mov	b,a	; save in b reg.
floop:	in	clock	; read the months unit digit
	cmp	b	; test for digit changed
	jz	floop	; wait until month is bumped (stable data)
time:	lxi	h,hour	; point to hour
	mvi	d,0	; select hour tens digit
	call	ddigit	; read hour tens and units
	inx	h	; step over ":"
	call	ddigit	; read minutes tens and units
	inx	h	; step over ":"
	call	ddigit	; read second tens and units
	lxi	d,pdate	; point to date and time message
	mvi	c,pbuf	; print buffer function
	call	bdos	; let CP/M do the work...
	lda	month	; get high byte of the month
	cpi	' '	; in the range of january to september?
	jz	jansept
	lda	month+1	; must be october to december...
	cpi	'0'	; october?
	lxi	d,oct
	jz	pmonth	; print, if so
	cpi	'1'	; november?
	lxi	d,nov
	jz	pmonth	; print, if so
	lxi	d,dec	; december.
	jmp	pmonth	; print it...
jansept:lda	month+1	; it's january to september
	cpi	'1'	; january?
	lxi	d,jan
	jz	pmonth	; print, if so
	cpi	'2'	; february?
	lxi	d,feb
	jz	pmonth	; print, if so
	cpi	'3'	; march?
	lxi	d,mar
	jz	pmonth	; print, if so
	cpi	'4'	; april?
	lxi	d,apr
	jz	pmonth	; print, if so
	cpi	'5'	; may?
	lxi	d,may
	jz	pmonth	; print, if so
	cpi	'6'	; june?
	lxi	d,jun
	jz	pmonth	; print month
	cpi	'7'	; july?
	lxi	d,jul
	jz	pmonth	; print, if so
	cpi	'8'	; august?
	lxi	d,aug
	jz	pmonth	; print, if so
	lxi	d,sep	; it's september
pmonth:	mvi	c,pbuf	; print buffer function
	call	bdos	; let CP/M do the work...
done:	lxi	d,day	; get the day
	mvi	c,pbuf	; print buffer function
	call	bdos	; let CP/M do the work...
	pop h ! pop d ! pop b ! pop psw
	jmp	stat	; now jump into STAT...

ddigit:	call	digit	; read and store two digits
digit:	mov	a,d	; move digit select code to a reg.
	call	rdigit	; read a clock digit
	cpi	0ffh	; test for board present
	jz	nobrd	; go print error message
	ori	030h	; convert digit to ASCII
	cpi	03fh	; test for blanked leading zero
	jnz	store	; go store digit, if not blanked
	mvi	a,020h	; convert to a blank
store:	mov	m,a	; store the digit in message buffer
	inx	h	; bump message pointer buffer location
	inr	d	; step to next digit
	ani	00fh	; mask off high ASCII nibble
	ret		; return with digit in a reg.

nobrd:	pop	h	; adjust the stack
	lxi	d,errmsg; point to the error message
	jmp	done	; print error message, and exit to CP/M

rdigit:	out	clock	; select digit
	mvi	a,0	; ...some delay time for settling
dloop:	dcr	a
	jnz	dloop
	in	clock	; read a digit
	ret		; return with digit in a reg.

;
; message buffers
;

pdate:	db	cr,lf,'Date: $'
month:	ds	2	; the month
day:	db	'xx, '	; the day...
	db	'1980'	; the year...
	db	'  Time: '
hour:	db	'xx:'	; the hour...
	db	'xx:'	; the minute...
	db	'xx'	; the second...
	db	cr,lf,'$'	; string delimeter

errmsg:	db	cr,lf,'The Clock Board is NOT INSTALLED!',cr,lf,'$'

jan:	db	'January $'
feb:	db	'February $'
mar:	db	'March $'
apr:	db	'April $'
may:	db	'May $'
jun:	db	'June $'
jul:	db	'July $'
Aug:	db	'August $'
sep:	db	'September $'
oct:	db	'October $'
nov:	db	'November $'
dec:	db	'December $'

	end


