; Z80DOS - Z80 Disk Operating System
;
; Version 1.0 - 05 Sept. 87 by Carson Wilson
;

; -------------------------------------------------------------------
;
; Z80DTIME.Z80 - Time Functions, Exit Routine, RAM Area
;
; -------------------------------------------------------------------

;	Time Routines

;
; Set file's time and date
;
;	Entry:	E = 2 - set creation date or get time stamp
;		E = 4 - Set last update time/date
;		E = 8 - Set last access time/date
;
;	Exit:	Z  if time stamps present
;		NZ if no time stamps

stime:	ld	hl,(dirbuf)		; get directory entry
	ld	bc,060h			; offset entry point time/date stamp
	add	hl,bc			; add offset to time stamp
	ld	a,(hl)			; get time stamp byte
	sub	021h			; time stamp present?
	ret	nz			; no, return
	ld	d,a			; yes, clear d
	add	hl,de			; add entry (update/create/access)
	ld	a,e			; set access time if E ge 8 <crw>
	and	8			;
	jr	z,stim1			; E lt 8
	srl	e			; E ge 8, set to 4
stim1:	ld	b,e			; save # bytes to write
	ld	a,(secpnt)		; get sector pointer
	rrca				; shift 2 times
	rrca
	ld	e,a			; save it
	rrca				; shift 2 times
	rrca
	add	a,e			; add it (a=0,10,20)
	ld	e,a			; save in e
	add	hl,de			; add offset
	ld	a,(funct)
	cp	54			; if set DOS time
	ret	z			; ..just point to date stamp
	push	hl			; save result
	ld	c,0			; time return date/time pointer in hl
	push	bc			; save 2 or 4 byte count <crw>
	call	time			; return pointer in hl
	pop	bc
	pop	de			; get pointer
	ld	c,b			; set write 2 or 4 bytes <crw>
	ld	b,0
	ldir				; copy 2 or 4 bytes to directory buff.
	xor	a			; set zero flag - time stamps present
	ret				; and return to caller

;
; Store time stamp following file find, open, or make. <crw>
;
;	Exit:	HL points to file's 10-byte time stamp
;		stored in DOS for subsequent commands
;		when DOS-time is on (command 55).
;
GetStp:
	ld	e,2			; point to file's stamp
	call	stime			; point to beginning of
					; ..last file's stamp
	ld	de,cdate		; point to DOS storage
	ld	(pexit),de		; save for return
	ld	bc,10
	jr	nz,GtStp1		; no stamp found
	ldir				; save full stamp
	ret
GtStp1:
	ld	b,c
GtStp2:
	ld	a,0			; else zero out storage
	ld	(de),a
	inc	de
	djnz	GtStp2
	ret				; return to calling program
;
; Time - get time for stamping from DOS storage or BIOS <crw>
;
;	Entry:	rdwr and dtime both = 0ffh, get time from DOS
;		    and reset dtime to 0
;		else get time from BIOS
;
; Format of time returned to pointer in HL:
;
;	HL + 0 = low  byte of date since Dec. 31, 1977
;	HL + 1 = high byte of date since Dec. 31, 1977
;	HL + 2 = hours	 (BCD)
;	HL + 3 = minutes (BCD)
;	HL + 4 = seconds (BCD) (not used in time stamp)
;

time:
	ld	a,(dtime)		; Use DOS time?
	or	a
	jr	z,btime			; no, get BIOS time
	ld	a,(funct)
	cp	22			; creating file?
	ld	hl,cdate		; point to create date
	jr	z,time2			; yes
	ld	hl,udate		; no, point to update date/time
time2:
	xor	a
	ld	(dtime),a		; use DOS time for one call only
	ret
;
; Get BIOS time to address DE
;
gettim:	push	de			; save address to put time
	ld	c,0			; get time address
	call	btime			; execute p2bios call
	pop	de			; restore address to put time
	ld	bc,5			; 5 bytes to move
	ldir				; store the time
	ret				; and return to caller
;
; Set BIOS time from address DE
;
settim:	ex	de,hl			; get address time in hl
	ld	de,0ff60h
	ld	bc,5
	ldir				; 5 bytes to move
	ld	c,0ffh			; set time address
					; and fall through to p2bios call
;
; Get/Set time in BIOS clock interface
;
;	Entry:	C =  0: On return HL points to 5-byte time entry
;		C <> 0: 5-byte entry pointed to by HL sets system time

btime:					; get system time
	push	hl			; save value in hl
	ld	hl,(timead)		; get address time routine
	ex	(sp),hl			; put address on stack and restore hl
	ret				; execute BIOS time routine
;
; Use stored time stamp for very next DOS call <crw>
; ..all other DOS calls cancel DOS time thru p2exit
;
UseStp:
	or	0ffh
	ld	(dtime),a		; Use DOS time
	pop	hl			; clean up stack
	jr	p2ext0

; ----------------------------

;	DOS exit routines

; ----------------------------


p2exit:	xor	a
	ld	(dtime),a		; turn off DOS time <crw>
	ld	a,(fldrv)		; test drive select used flag
	or	a
	jr	z,p2ext0		; no then exit
	ld	a,(FCB0)		; get FCB byte 0
	ld	(ix+0),a		; save it
	ld	a,(drive)		; get old drive number
	call	seldk			; select disk
p2ext0:	push	ix			; save ix
	pop	de			; restore de
	pop	ix			; restore ix
	ld	sp,(spsave)		; get old sp
	ld	hl,(pexit)		; get exit code
	ld	a,(funct)		; get function code
	ld	c,a			; restore c
	ld	a,l			; copy function code
	ld	b,h
	ret				; and return to caller

; --------------------

;	RAM area

; --------------------

tabcnt:	defb	0			; tab counter
tabcx1:	defb	0			; temporary tab counter (used by rdbuf)
fcontp:	defb	0			; list enable flag (control p)
lastch:	defb	0			; last character
delay:	defb	0ffh			; delay counter
;
trans:	defw	0			; translation vector
temp0:	defw	0			; number of files on drive
dirbuf:	defw	0			; directory buffer
ixp:	defw	0			; disk parameter block
csv:	defw	0			; check sum pointer
alv:	defw	0			; allocation vector pointer
;
maxsec:	defw	0			; maximum number of sectors/track
nblock:	defb	0			; number of blocks
nmask:	defb	0			; mask number of blocks
nextnd:	defb	0			; extent mask
maxlen:	defw	0			; maximum block number-1
nfiles:	defw	0			; maximum number of files-1
ndir0:	defb	0			; first two entries alv buffer
ndir1:	defb	0
ncheck:	defw	0			; number of checksum entries
nftrk:	defw	0			; first track number
;
dskro:	defw	0			; disk R/O vector
login:	defw	0			; login vector
DMA:	defw	080h			; DMA address
;
funct:	defb	0			; function number
pexit:	defw	0			; exit code
fldrv:	defb	0			; drive select used flag
rdwr:	defb	0			; read/write flag
;
FCB0:	defb	0			; FCB byte 0
user:	defb	0			; user number
drive:	defb	0			; drive number
defdrv:	defb	0			; default drive number
recdir:	defw	0			; record directory (checksum)
filcnt:	defw	0			; file counter
secpnt:	defb	0			; sector pointer
subflg:	defb	0			; submit flag (reset disk command)
;
dcopy:	defw	0			; copy address FCB
searex:	defb	0			; exit code search
searnb:	defb	0			; search number of bytes
searqu:	defb	0			; search question mark used
searpu:	defb	0			; search public file
;next two flags added by b.h.
diff:	db	0			; Disk changed flag
retflg:	db	0			; allow retry on error when non-zero
;
dtime:	db	0			; Flag for UseStp <crw>
cdate:	ds	2			; Create date storage
udate:	ds	4			; Update date/time
adate:	ds	4			; Last access date/time <crw>
;
spsave:	defw	0			; stack pointer location
	defs	64
DOSs	equ	$			; DOS internal 64 byte stack
DOSstop	equ	$
;
	 if	((DOSstop-DOS) gt 3584)
	* BDOS over 3584 bytes - too large!! *
	 endif

; END Z80DTIME.Z80

b	0			; Disk changed flag
retflg:	db	0			; allow retry on error when non-zero
;
dtime:	db	0			; Flag for UseStp <crw>
cdate:	ds	2			; Create date storage
udate:	ds	4			; Update date/time
adate:	ds	4			; Last access date/time <crw>
;
spsave:	defw	0	ееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееееее; Z80DOS - Z80 Disk Operating System
;
; Version 1.0 - 05 Sept. 87 by Carson Wilson
;

; -------------------------------------------------------------------
;
; Z80DTIME.Z80 - Time Functions, Exit Routine, RAM Area
;
; -------------------------------------------------------------------

;	Time Routines

;
; Set file's time and date
;
;	Entry:	E = 2 - set creation date or get time stamp
;		E = 4 - Set last update time/date
;		E = 8 - Set last access time/date
;
;	Exit:	Z  if time stamps present
;		NZ if no time stamps

stime:	ld	hl,(dirbuf)		; get directory entry
	ld	bc,060h			; offset entry point time/date stamp
	add	hl,bc			; add offset to time stamp
	ld	a,(hl)			; get time stamp byte
	sub	021h			; time stamp present?
	ret	nz			; no, return
	ld	d,a			; yes, clear d
	add	hl,de			; add entry (update/create/access)
	ld	a,e			; set access time if E ge 8 <crw>
	and	8			;
	jr	z,stim1			; E lt 8
	srl	e			; E ge 8, set to 4
stim1:	ld	b,e			; save # bytes to write
	ld	a,(secpnt)		; get sector pointer
	rrca				; shift 2 times
	rrca
	ld	e,a			; save it
	rrca				; shift 2 times
	rrca
	add	a,e			; add it (a=0,10,20)
	ld	e,a			; save in e
	add	hl,de			; add offset
	ld	a,(funct)
	cp	54			; if set DOS time
	ret	z			; ..just point to date stamp
	push	hl			; save result
	ld	c,0			; time return date/time pointer in hl
	push	bc			; save 2 or 4 byte count <crw>
	call	time			; return pointer in hl
	pop	bc
	pop	de			; get pointer
	ld	c,b			; set write 2 or 4 bytes <crw>
	ld	b,0
	ldir				; copy 2 or 4 bytes to directory buff.
	xor	a			; set zero flag - time stamps present
	ret				; and return to caller

;
; Store time stamp following file find, open, or make. <crw>
;
;	Exit:	HL points to file's 10-byte time stamp
;		stored in DOS for subsequent commands
;		when DOS-time is on (command 55).
;
GetStp:
	ld	e,2			; point to file's stamp
	call	stime			; point to beginning of
					; ..last file's stamp
	ld	de,cdate		; point to DOS storage
	ld	(pexit),de		; save for return
	ld	bc,10
	jr	nz,GtStp1		; no stamp found
	ldir				; save full stamp
	ret
GtStp1:
	ld	b,c
GtStp2:
	ld	a,0			; else zero out storage
	ld	(de),a
	inc	de
	djnz	GtStp2
	ret				; return to calling program
;
; Time - get time for stamping from DOS storage or BIOS <crw>
;
;	Entry:	rdwr and dtime both = 0ffh, get time from DOS
;		    and reset dtime to 0
;		else get time from BIOS
;
; Format of time returned to pointer in HL:
;
;	HL + 0 = low  byte of date since Dec. 31, 1977
;	HL + 1 = high byte of date since Dec. 31, 1977
;	HL + 2 = hours	 (BCD)
;	HL + 3 = minutes (BCD)
;	HL + 4 = seconds (BCD) (not used in time stamp)
;

time:
	ld	a,(dtime)		; Use DOS time?
	or	a
	jr	z,btime			; no, get BIOS time
	ld	a,(funct)
	cp	22			; creating file?
	ld	hl,cdate		; point to create date
	jr	z,time2			; yes
	ld	hl,udate		; no, point to update date/time
time2:
	xor	a
	ld	(dtime),a		; use DOS time for one call only
	ret
;
; Get BIOS time to address DE
;
gettim:	push	de			; save address to put time
	ld	c,0			; get time address
	call	btime			; execute p2bios call
	pop	de			; restore address to put time
	ld	bc,5			; 5 bytes to move
	ldir				; store the time
	ret				; and return to caller
;
; Set BIOS time from address DE
;
settim:	ex	de,hl			; get address time in hl
	ld	de,0ff60h
	ld	bc,5
	ldir				; 5 bytes to move
	ld	c,0ffh			; set time address
					; and fall through to p2bios call
;
; Get/Set time in BIOS clock interface
;
;	Entry:	C =  0: On return HL points to 5-byte time entry
;		C <> 0: 5-byte entry pointed to by HL sets system time

btime:					; get system time
	push	hl			; save value in hl
	ld	hl,(timead)		; get address time routine
	ex	(sp),hl			; put address on stack and restore hl
	ret				; execute BIOS time routine
;
; Use stored time stamp for very next DOS call <crw>
; ..all other DOS calls cancel DOS time thru p2exit
;
UseStp:
	or	0ffh
	ld	(dtime),a		; Use DOS time
	pop	hl			; clean up stack
	jr	p2ext0

; ----------------------------

;	DOS exit routines

; ----------------------------


p2exit:	xor	a
	ld	(dtime),a		; turn off DOS time <crw>
	ld	a,(fldrv)		; test drive select used flag
	or	a
	jr	z,p2ext0		; no then exit
	ld	a,(FCB0)		; get FCB byte 0
	ld	(ix+0),a		; save it
	ld	a,(drive)		; get old drive number
	call	seldk			; select disk
p2ext0:	push	ix			; save ix
	pop	de			; restore de
	pop	ix			; restore ix
	ld	sp,(spsave)		; get old sp
	ld	hl,(pexit)		; get exit code
	ld	a,(funct)		; get function code
	ld	c,a			; restore c
	ld	a,l			; copy function code
	ld	b,h
	ret				; and return to caller

; --------------------

;	RAM area

; --------------------

tabcnt:	defb	0			; tab counter
tabcx1:	defb	0			; temporary tab counter (used by rdbuf)
fcontp:	defb	0			; list enable flag (control p)
lastch:	defb	0			; last character
delay:	defb	0ffh			; delay counter
;
trans:	defw	0			; translation vector
temp0:	defw	0			; number of files on drive
dirbuf:	defw	0			; directory buffer
ixp:	defw	0			; disk parameter block
csv:	defw	0			; check sum pointer
alv:	defw	0			; allocation vector pointer
;
maxsec:	defw	0			; maximum number of sectors/track
nblock:	defb	0			; number of blocks
nmask:	defb	0			; mask number of blocks
nextnd:	defb	0			; extent mask
maxlen:	defw	0			; maximum block number-1
nfiles:	defw	0			; maximum number of files-1
ndir0:	defb	0			; first two entries alv buffer
ndir1:	defb	0
ncheck:	defw	0			; number of checksum entries
nftrk:	defw	0			; first track number
;
dskro:	defw	0			; disk R/O vector
login:	defw	0			; login vector
DMA:	defw	080h			; DMA address
;
funct:	defb	0			; function number
pexit:	defw	0			; exit code
fldrv:	defb	0			; drive select used flag
rdwr:	defb	0			; read/write flag
;
FCB0:	defb	0			; FCB byte 0
user:	defb	0			; user number
drive:	defb	0			; drive number
defdrv:	defb	0			; default drive number
recdir:	defw	0			; record directory (checksum)
filcnt:	defw	0			; file counter
secpnt:	defb	0			; sector pointer
subflg:	defb	0			; submit flag (reset disk command)
;
dcopy:	defw	0			; copy address FCB
searex:	defb	0			; exit code search
searnb:	defb	0			; search number of bytes
searqu:	defb	0			; search question mark used
searpu:	defb	0			; search public file
;next two flags added by b.h.
diff:	db	0			; Disk changed flag
retflg:	db	0			; allow retry on error when non-zero
;
dtime:	db	0			; Flag for UseStp <crw>
cdate:	ds	2			; Create date storage
udate:	ds	4			; Update date/time
adate:	ds	4			; Last access date/time <crw>
;
spsave:	defw	0			; stack pointer location
	defs	64
DOSs	equ	$			; DOS internal 64 byte stack
DOSstop	equ	$
;
	 if	((DOSstop-DOS) gt 3584)
	* BDOS over 3584 bytes - too large!! *
	 endif

; END Z80DTIME.Z80

