*  PROGRAM:  SPTTIME.ASM
*  AUTHOR:  RICHARD CONN
*  VERSION:  1.0
*  DATE:  7 MAR 82
*  PREVIOUS VERSIONS:  None

VERS	EQU	10	;Version Number

*
*  SPTTIME is a Support Package which provides Clock Interface Support
*  to programs which generally require it for enhanced performance
*  (i.e., Time included in their outputs).  SPTTIME consists of two
*  Modules:
*	1.  ENDIT -- Returns address of next available page after SPTTIME
*		in HL
*	2.  GETTIME -- Returns a pointer to an ASCII text string (vector
*		of characters ending in a binary 0) which represents the
*		Time, Day of Week, and Date read from a clock.  This pointer
*		is returned in HL, and a condition code (0 if clock not
*		supported and 0FFH if clock supported, which is usually the
*		case, with the Zero Flag set appropriately) is returned in A.
*
*	Both routines may affect only HL and A/PSW Registers.
*

*
*  This SPTTIME Support Package is implemented for the DC Hayes Chronograph
*  which is wired into the system to be commanded thru the PUN: device and
*  read thru the RDR: device.
*

*
*  Basic Equates
*
BDOS	equ	5	; BDOS Entry
CR	equ	0dh	; <CR>

*
*  Program Equates
*	Set the desired program to TRUE and all others FALSE
*
FALSE	equ	0	; FALSE Definition
TRUE	equ	NOT FALSE

PRINT2	equ	TRUE
CAT2	equ	FALSE

*
*  Origin Table -- this should be set up for each program supported
*
	IF	PRINT2
BASE	EQU	1500H	; BASE ADDRESS
	ENDIF

	IF	CAT2
BASE	EQU	2000H	; BASE ADDRESS
	ENDIF

*
*  SPTTIME Modules --
*
	org	BASE	; Origin

	jmp	endit	; Return Page After Support Package in HL
	jmp	gettime	; Return Time Pted to by HL and A <> 0 with flag set

*
*  Return Page Address after Support Package in HL
*
endit:
	lxi	h,endall	; Address in HL
	ret

*
*  Return Time as String Pted to by HL
*
gettime:
	push	d	; Save DE, BC
	push	b

*
*  Extract Data from Clock
*
	call	readclock

*
*  Load Time/Date/Weekday into buffer 'String'
*
	call	prclock

	lxi	h,string	; Pt to Buffer

	mvi	a,0ffh		; OK
	ora	a		; Clear Flags

	pop	b		; Restore BC, DE
	pop	d
	ret

*
*  Clock Input/Output Entry Routines
*
ciclk:
	push	h	; Save regs
	push	d
	push	b
	mvi	c,3	; RDR: Input
	call	bdos
	ani	7fh	; Mask out MSB if Set
	pop	b	; Restore regs
	pop	d
	pop	h
	ret

coclk:
	push	h	; Save regs
	push	d
	push	b
	push	psw
	mvi	c,4	; PUN: Output
	mov	e,a	; Char in E
	call	bdos
	pop	psw	; Restore regs
	pop	b
	pop	d
	pop	h
	ret

*
*  Print Time/Date/Weekday on String
*
prclock:
	call	prinit	;Initialize Print
	call	prtime	;Print Time
	call	space	;Space
	call	space
	call	prmonth	;Print Month Name
	call	space
	call	prday	;Print Day Number
	call	pryear	;Print Year
	call	prdone	;Close Print
	ret

*
*  Read Time, Date, and Weekday from Clock
*
readclock:
	lxi	h,time	;Point to Time Buffer
	call	command
	db	'RT'	;Read Time
	lxi	h,date	;Point to Date Buffer
	call	command
	db	'RD'	;Read Date
	ret

*
*  Print Time on String
*
prtime:
	lxi	h,time	;Print Time Info
	call	pr2s	;Print 2 digits
	call	colon	;Print :
	call	pr2	;Print 2 digits
	call	colon	;Print :
	call	pr2	;Print 2 digits
	call	space	;Space
	mov	a,m	;Get A or P
	call	cpout
	mvi	a,'M'	;Print M
	call	cpout
	ret

*
*  Print Month Name
*
prmonth:
	lxi	h,date+2	;Convert month number
	mov	a,m	;Get first digit
	sui	'0'	;Convert to Binary
	mov	b,a	;Save in B
	add	a	;*2
	add	a	;*4
	add	b	;*5
	add	a	;*10
	inx	h	;Point to next digit
	mov	b,a	;Value in B
	mov	a,m	;Get Digit
	sui	'0'	;Convert to Binary
	add	b	;Add in
	lxi	d,mlen	;Length of Month Strings
	lxi	h,months	;Beginning of Month Strings
	call	offset	;Compute Offset to Desired String
	call	cpstr	;Print Month Name
	ret

*
*  Print Day Number
*
prday:
	lxi	h,date+4	;Point to Day Digits
	call	pr2s	;Print as 2 Digits
	ret

*
*  Print Year
*
pryear:
	call	cprint	;Print Year Prefix
	db	', 19',0
	lxi	h,date	;Point to Year
	call	pr2	;Print 2 Digits
	ret

*
*  Print colon or space
*
colon:
	mvi	a,':'	;Print colon
	jmp	cpout
space:
	mvi	a,' '	;Print space
	jmp	cpout

*
*  Command -- Issue 2-letter command pointed to by Return Address to Clock
*    and copy response into buffer pointed to by HL; affect all registers
*
command:
	mvi	a,'A'	;Send 'AT'
	call	coclk	;Send to Clock
	mvi	a,'T'
	call	coclk
	xthl		;Pt to command letters and save HL
	mov	a,m	;Get it
	call	coclk	;Send to Clock
	inx	h	;Pt to next char
	mov	a,m	;Get it
	call	coclk	;Send to Clock
	inx	h	;Pt to ret adr
	xthl		;Get HL and save ret adr
	mvi	a,CR	;Send <CR>
	call	coclk	;Send to Clock

*  Collect Response Chars
cmdloop:
	call	ciclk	;Get letter
	cpi	CR	;End of Response?
	jz	cmddone
	mov	m,a	;Store in Buffer
	inx	h	;Point to next position
	jmp	cmdloop
cmddone:
	mvi	m,0	;Store ending zero
	ret

*
*  PR2S -- Print chars pointed to by HL and HL+1; if first character is '0',
*    print only one char; affect all registers; on exit, HL points to byte
*    after 2nd char printed
*  PR2 -- PR2S but always print 2 digits
*
pr2:
	mov	a,m	;Get first char
	jmp	pr2a
pr2s:
	mov	a,m	;Get first char
	cpi	'0'	;Leading zero?
	jz	pr2b
pr2a:
	call	cpout	;Print char
pr2b:
	inx	h	;Point to next
	mov	a,m	;Get it
	call	cpout
	inx	h	;Point to next
	ret

*
*  Compute Offset to selected string; on input, HL points to first
*    string, DE=string length, A=Number of String desired (first string = 1)
*
offset:
	dcr	a	;Count down
	rz
	dad	d	;Point to next
	jmp	offset

*
*  Initialize Buffer Output
*
prinit:
	lxi	h,string	; Pt to first byte of string
	shld	bptr		; Set ptr
	ret

*
*  Close Buffer Output
*
prdone:
	push	h	; save HL
	lhld	bptr	; Get ptr
	mvi	m,0	; Store ending 0
	pop	h	; restore HL
	ret

*
*  Send char in A to String
*
cpout:
	push	h	; save HL
	lhld	bptr	; Pt to next char location
	mov	m,a	; Put char
	inx	h	; Incr ptr
	shld	bptr
	pop	h
	ret

*
*  Print string pted to by return address into String
*
cprint:
	xthl		;Pt to string
cpr1:
	mov	a,m	;Get char
	inx	h	;Pt to next
	ora	a	;Done?
	jz	cpr2
	call	cpout	;Print to CON: or LST:
	jmp	cpr1
cpr2:
	xthl		;Restore HL and Ret Adr
	ret

*
*  Print string pted to by HL into String
*
cpstr:
	push	h	;Save ptr
	push	psw	;Save char
cpstr1:
	mov	a,m	;Get next char
	inx	h	;Pt to next char
	ora	a	;Done?
	jz	cpstr2
	call	cpout	;Print char
	jmp	cpstr1
cpstr2:
	pop	psw	;Get char
	pop	h	;Get ptr
	ret

*
*  Month Strings
*
months:
	db	'January',0,0,0
month1:
	db	'February',0,0
	db	'March',0,0,0,0,0
	db	'April',0,0,0,0,0
	db	'May',0,0,0,0,0,0,0
	db	'June',0,0,0,0,0,0
	db	'July',0,0,0,0,0,0
	db	'August',0,0,0,0
	db	'September',0
	db	'October',0,0,0
	db	'November',0,0
	db	'December',0,0
mlen	equ	month1-months	;Number of Bytes in Each Entry

*
*  Input Buffers
*
bptr:
	ds	2	; Pointer to next char position in String Buffer
time:
	ds	10	; Time Buffer
date:
	ds	10	; Date Buffer
string:
	ds	80	; Output String Buffer

endall	equ	$/256*256+256	; End of Support Package

	end
