Module Name:        DATEHL
; Author:	Carson Wilson
; Version:      1.0              modified for AMSTRAD CPC with
; Date:         25 Sept 87                    DOBBERTIN Harddisk

	Public	DateHL

;
; DATEHL converts the value in HL to BCD year, month, day
;	 for use with Z80DOS time stamps.
;
; Inputs:	HL contains hex days since December 31, 1977
;
; Outputs:	H contains BCD 20th century year
;		L contains BCD month
;		A contains BCD day
;
;		Zero flag set (Z) and A=0 if invalid date (zero) detected,
;		Zero flag reset (NZ) and A=0ffh otherwise.

; Adapted from B5C-CPM3.INS

DateHL:
	ld	a,h
	or	l		; Test blank date (zero)
	ret	z		; Return Z and A=0 if so

	ld	(days),hl	; Save initial value
	ld	b,78		; Set years counter
loop:
	call	ckleap
	ld	de,-365		; Set up for subtract
	jp	nz,nolpy	; Skip if no leap year
	dec	de		; Set for leap year
nolpy:
	add	hl,de		; Subtract
	jp	nc,ydone	; Continue if years done
	ld	a,h
	or	l
	jp	z,ydone
	ld	(days),hl	; Else save days count
	inc	b		; Increment years count
	jp	loop		; And do again
;
; The years are now finished, the years count is in 'B' (HL is invalid)
;
ydone:
	ld	a,b
	call	binbcd
	ld	(dyear),a	; save BCD year
;
	call	ckleap		; Check if leap year
	ld	a,-28
	jp	nz,febno	; February not 29 days
	ld	a,-29		; Leap year
febno:
	ld	(feb),a		; Set february
	ld	hl,(days)	; Get days count
	ld	de,mtable	; Point to months table
	ld	b,0ffh		; Set up 'B' for subtract
	ld	a,0		; Set a for # of months
mloop:
	push	af
	ld	a,(de)		; Get month
	ld	c,a		; Put in 'C' for subtract
	pop	af
	ld	(days),hl	; save days count
	add	hl,bc		; Subtract
	inc	de		; Increment months counter
	inc	a
	jp	c,mloop		; Loop for next month
;
; The months are finished, days count is on stack.  First, calculate
; month.
;
mdone:
	ld	b,a		; Save months
	ld	hl,(days)
	ld	a,h
	or	l
	jp	nz,nzd
	dec	de
	dec	de
	ld	a,(de)
	cpl
	inc	a
	ld	l,a
	dec	b
nzd:
	ld	a,l		; Retrieve binary day of month
	call	binbcd		; Convert to BCD
	push	af		; Save day in A
;
	ld	a,b		; Retrieve the binary month
	call	binbcd		; Convert binary month to BCD
	ld	l,a		; Return month in L
;
	ld	a,(dyear)
	ld	h,a		; Return year in H
;
	or	0ffh		; Return no error
	pop	af		; Restore day
	ret

;
; Support Routines:
;

;
; Check for leap years.
;
ckleap:	ld	a,b
	and	0fch
	cp	b
	ret
;
; Convert A to BCD & store back in A
;
BinBCD:
	or	a
	ret	z
	push	bc
	ld	b,a
	xor	a
BinBCD1:
	add	a,1
	daa
	djnz	BinBCD1
	pop	bc
	ret
;
; Buffers:
;

;
; Months 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
days:
	ds	2		; temporary buffers
dyear:
	ds	1

	end

; END DATEHD.Z80


