; B5C-MTN2.INS   -   Clock routine for Mountain Hardware 100,000 day clock
;			Dennis Recla    9/15/85
;
;	This version does not take into account the number of days
;	since some far off starting point (Jan 1, 1978), but begins
;	from January 1 of the current year.  This way only a running
;	count of days since the beginning of the year needed to be
;	calculated.  When you set the days on the clock be sure you
;	use the Julian day for the current year.
;
;	Remember to set CLOCK, BCD2BIN, and BIN2BCD to YES.
;
;	Real - Time clock buffer is organized as HH:MM:SS YYY/MM/DD
;
;	RTCBUF:
;		DB	99H,99H,99H	;HH:MM:SS (BCD 24 Hr Time)
;		DB	19H,85H,01H,31H ;YYYY/MM/DD (BCD ISO Date)
;
;
;-------------------------------------------------------------------------
;
;
CENTURY:EQU	019H		;Current century (19xx) in BCD
;
CLKADR:	EQU	0E0H		;Starting address of Clock board
CLKMSK:	EQU	0FH		;Mask for high nibble 
CYEAR:	EQU	085H		;Update this once a year (Current Year)
;
;
;
TIME:	IN	CLKADR+8	;Read in the hour value
	ANI	CLKMSK		;Remove the high nibble status
	MOV	B,A		;Put the value in B to hold
	IN	CLKADR+9	;Read in the 10's of hours
	ANI	CLKMSK		;Remove the high nibble status
	CALL	ROTADD		;Combine the two values
	STA	RTCBUF		;Put the hours value in 
	CALL	BCDBIN		;Convert the value to binary
	STA	CCHOUR		;Store it in the hour value
;
	IN	CLKADR+6	;Read in the Minute value
	ANI	CLKMSK		;Remove the high nibble status
	MOV	B,A		;Put the value in B to hold
	IN	CLKADR+7	;Read in the 10's of Minutes
	ANI	CLKMSK		;Remove the high nibble status
	CALL	ROTADD		;Combine the two values
	STA	RTCBUF+1	;Put the minutes value in
	CALL	BCDBIN		;Convert the value to binary
	STA	CCMIN		;Store it in the Minutes value
;
	IN	CLKADR+4	;Read in the Seconds value
	ANI	CLKMSK		;Remove the high nibble status
	MOV	B,A		;Put the value in B to hold
	IN	CLKADR+5	;Read in the 10's of Seconds
	ANI	CLKMSK		;Remove the high nibble status
	CALL	ROTADD		;Combine the two values
	STA	RTCBUF+2	;Put the seconds value in
;
;	Put Century in the right place
;
	MVI	A,CENTURY	;Put Century value in A
	STA	RTCBUF+3
;
	MVI	A,CYEAR		;Put Years value in A
	STA	RTCBUF+4
;
;	Now to calculate the month and days since Jan 1st
;
	IN	CLKADR+10	;Get the days digit
	ANI	CLKMSK		;Remove the high nibble status
	MOV	B,A		;Store the value in B
	IN	CLKADR+11	;Get the 10's days digit
	ANI	CLKMSK		;Remove the high nibble status
	CALL	ROTADD		;Rotate and Add the values
	CALL	BCDBIN		;Convert the value to Binary
	MOV	E,A		;Store it in E
	MVI	D,0		;Clear out the D register
				;I'll use it later
;
	IN	CLKADR+12	;Get the 100's days digit
	ANI	CLKMSK		;Remove the high nibble status
	MOV	C,A		;Store the value in C
	RLC			; X2
	RLC			; X4
	RLC			; X8
	MOV	B,A		; Store the X8 value in B
	RLC			; X16
	ADD	B		; Add the X16 and the X8
	ADD	C		; Add the X1 value
				; This is a total of X25
;
	LXI	H,00		; Clear the H register
	RLC			; X2
	ORA	A		; Clear the Carry
	RAL			; X4 with carry
	JNC	LOADHL		; If no carry jump
	MVI	H,1		; Put a 1 in H register
LOADHL: MOV	L,A		; Put a value in the low byte
	DAD	D		; Add H&L to D&E
	SHLD	TIMEPB		; Store the number of days here
;
	MVI	A,CYEAR		; Put the Years value in A
	CALL	CKLEAP		; Check if leap year
	MVI	A,-28
	JNZ	FEBNO		; February not 29 days
	MVI	A,-29		; Leap year
;
FEBNO:	STA	FEB		; Set february
	LHLD	TIMEPB		; Get days count
	LXI	D,MTABLE	; Point to months table
	MVI	B,0FFH		; Set up 'B' for subtract
	MVI	A,0		; Set a for # of months
;
MLOOP:	PUSH	PSW
	LDAX	D		; Get month
	MOV	C,A		; Put in 'C' for subtract
	POP	PSW
	SHLD	TIMEPB		; Save days count
	DAD	B		; Subtract
	INX	D		; Increment months counter
	INR	A
	JC	MLOOP		; Loop for next month
;
;
; The months are finished, days count is on stack.  First, calculate
; month.
;
MDONE:	MOV	B,A		; Save months
	LHLD	TIMEPB
	MOV	A,H
	ORA	L
	JNZ	NZD
	DCX	D
	DCX	D
	LDAX	D
	CMA
	INR	A
	MOV	L,A
	DCR	B
;
NZD:	MOV	A,B		; Retrieve the binary month
	CALL	BINBCD		; Convert binary month to BCD
	STA	RTCBUF+5	; Store BCD month in RTCBUF
	MOV	A,L		; Retrieve binary day of month
	CALL	BINBCD		; Convert to BCD
	STA	RTCBUF+6	; Store BCD day of month in RTCBUF
;
	RET
;.....
;
;
; This routine checks for leap years.
;
CKLEAP:	MOV	B,A
	ANI	0FCH
	CMP	B
	RET
;.....
;
;				;Rotate left and Add the B register
ROTADD: RLC			;Shift the BCD value from low nibble
	RLC			;to the high nibble
	RLC
	RLC			;done shifted it 4 bits left
	ANI	0F0H		;Mask off the high nibble
	ORA	B		;add the low nibble and high nibble
	RET
;
;
;
; This is the month's table
;
MTABLE:	DB	-31		;January
FEB:	DB	-28		;February
	DB	-31,-30,-31,-30	;Mar-Jun
	DB	-31,-31,-30	;Jul-Sep
	DB	-31,-30,-31	;Oct-Dec
;
TIMEPB:	DW	0		; Temporary storage
;
