home *** CD-ROM | disk | FTP | other *** search
- .printx Reading ZFSUBS5.Z80
- ;===========================================================================
- ;
- ; ZFSUBS5.Z80 - DateStamper Routines
- ;
- ;===========================================================================
-
- rndoff equ 33 ; FCB offset to random record number
- ; BDOS function numbers
- getvrs equ 12 ; Get version
- setusr equ 32 ; Get/set user number
- setatt equ 30 ; Set attributes
- readrnd equ 33 ; read-random
- writernd equ 34 ; write-random
-
- ;-----------------------------------------------------------------------------
-
- ; This routine copies the time stamp from the source file (at SOURCE fcb
- ; to the destination file (at DEST fcb).
-
- tdname:
- db 0 ; Drive
- db '!!!TIME&' ; Name
- db 'DAT' ; Type
-
- copydate:
- call checkds ; Check and initialize DatStamper code
- ret z ; If not installed, return now
-
- ld hl,tdname ; Initialize the T&D FCB with name
- ld de,tdfcb
- ld bc,12 ; Copy 12 characters
- ldir
-
- ld bc,(du$req) ; Log into source drive
- ld c,0 ; ..but user 0
- call logud
- ld hl,(ssector) ; Get sector/offset info for source
- ld a,(sindex)
- call setindex ; Set TDSECTOR and TDINDEX values
-
- xor a ; Flag for getting time stamp
- call getset ; Get or set the time stamp
-
- ld bc,(du$dest) ; Log into destination drive
- ld c,0 ; ..but user 0
- call logud
- ld hl,(dsector) ; Get sector/offset info for destination
- ld a,(dindex)
- call setindex
-
- xor a ; Set flag for
- dec a ; ..setting time stamp
- call getset ; Set destination time stamp
- ret z ; Return now if error
-
- ld hl,msg119 ; "(date)"
- jp pstri ; Note successful date copy
-
- ; Subroutine to get or set the time/date stamp for a file.
- ; NOTE: on error this routine pops the original return address and
- ; returns one level higher, thereby aborting the date copy routine.
- ;
- ; Entry: A = 0 and Z set if read
- ; A = FF and NZ if write
- ; TDSECTOR, TDINDEX, and the T&D FCB must be set
-
- getset:
- push af ; Save read/write flag
- call tdopen ; Open source T&D file
- jr z,fferror ; Return two levels if error
- pop af ; Get read/write flag again
- push af ; ..and save it again
- call rwtd ; Read or write T&D info
- jr z,fferror ; Return two levels if error
- pop af
- call nz,tdclose ; Close the T&D file if written to
- ret
- fferror:
- pop af ; Pop registers pushed above
- pop hl ; Pop address of calling program
- ret ; Return to level above that
-
- ;-----------------------------------------------------------------------------
-
- ; Routine to see if DateStamper is loaded.
- ;
- ; Entry: nothing
- ; Return: if DateStamper not loaded: A=0 and Z
- ; if loaded, A<>0, NZ, and HL has address of DS clock routine.
-
- checkds:
- ld hl,tdfcb ; Initialize time/date FCB
- ld de,tdfcb+1
- ld (hl),0 ; Seed with 0
- ld bc,35 ; Propagate to 35 more bytes
- ldir
- ld e,'D' ; DS identifier request
- ld c,getvrs ; Get CP/M version
- call bdosptr
- cp 22h ; Must be 2.2
- jr nz,checkds1 ; Branch if not
- ld a,h ; See if DS ID returned
- cp 'D'
- jr nz,checkds1 ; Branch if not
- ex de,hl ; Get clock routine address into HL
- ld a,h ; Make sure there is a clock
- or l
- ret
- checkds1:
- xor a ; Return Z to show no DS
- ret
-
- ;-----------------------------------------------------------------------------
-
- ; Computes checksum of first 127 bytes of the T&D sector loaded at TDBUFF.
- ;
- ; Entry: nothing
- ; Exit: A = sum of 127 bytes
- ; HL -> 128th byte
-
- checksum:
- ld hl,tdbuff ; Point to T&D buffer
- ld b,127 ; Bytes to sum
- xor a ; Initialize sum
- checksum1:
- add a,(hl) ; Add in byte
- inc hl ; Advance to next
- djnz checksum1 ; Loop through them all
- ret
-
- ;-----------------------------------------------------------------------------
-
- ; Set DMA to the address of the T&D buffer
- ;
- ; Entry: nothing
- ; Exit: nothing
-
- settddma:
- ld de,tdbuff ; Point to T&D buffer
- ld c,setdma
- jr bdossave
-
- ;-----------------------------------------------------------------------------
-
- ; BDOS call acting on T&D file control block
- ;
- ; Entry: normal BDOS information less DE
- ; Exit: normal BDOS output information
- ; DE return code saved in BDOSDE
-
- bdostd:
- ld de,tdfcb ; Set FCB pointer
- ; Fall through to bdossave
-
- ;-----------------------------------------------------------------------------
-
- ; Routine to call BDOS and save the value returned by DateStamper in DE
- ; in BDOSDE. (Do not move this routine -- one above falls into it.)
- ;
- ; Entry: normal BDOS information
- ; Exit: normal BDOS output information
- ; DE return code saved in BDOSDE
-
- bdossave:
- call bdosptr
- ld (bdosde),de
- ret
-
- ;-----------------------------------------------------------------------------
-
- ; Open the time and date file. We must already be in user 0.
- ;
- ; Entry: A=0 for reading
- ; A=FF for writing (routine clears R/O status)
- ; Exit; Z set if error
-
- tdopen:
- ld (rwflag),a ; Save read/write flag
- ld c,open ; Open-file function
- call bdostd ; BDOS call on T&D FCB
- inc a ; Error FF -> 0
- ret z ; Return with Z if error
- ld a,(rwflag) ; Check function
- or a
- jr z,openret ; If reading, we can return now
- ld hl,tdfcb ; Point to T&D FCB
- ld de,9 ; Offset to R/O attribute byte
- add hl,de
- res 7,(hl) ; Mark file R/W
-
- attrset: ; Entry point for setting file attrib.
- ld c,setatt
- call bdostd
-
- openret: ; Entry point for no attribute change
- push af ; Save error flag
- pop af
- inc a ; Error FF -> 0
- ret
-
- ;-----------------------------------------------------------------------------
-
- ; Close time and date file. We must be in user 0 when this is called.
- ;
- ; Entry: nothing
- ; Exit: Z is set if there is an error
-
- tdclose:
- ld de,tdfcb ; Get FCB pointer
- ld hl,9 ; Offset to R/O attribute byte
- add hl,de
- set 7,(hl) ; Set file to R/O for ATTRSET
- ld c,close ; Close the file
- call bdostd
- inc a ; Error code FF -> 0
- ret z ; Return Z if error
- jr attrset ; Set file attributes
- ret
-
- ;-----------------------------------------------------------------------------
-
- ; Read or write a time and date sector. This routine will change the DMA
- ; address, and the calling code must reset it. Since the T&D file is never
- ; more than one extent, the code does not bother setting and resetting the
- ; user number. On reading, the 15-byte time stamp string is copied to the
- ; buffer pointed to by HL on entry. On writing, the contents of the buffer
- ; pointed to by HL are copied to the disk sector.
- ;
- ; On entry: A=0 to read or A=FF to write
- ; TDSECTOR and TDINDEX data must have been set up
- ; T&D file must be open in R/W mode
- ;
- ; On exit: T&D file is open
- ; with reading, data is in buffer
- ; on writing, data is in sector buffer
-
- rwtd:
- ld (rwflag),a ; Save the read/write flag
- ld de,tdfcb ; Get FCB pointer
- ld hl,rndoff ; Offset to random record value
- add hl,de
- ld de,(tdsector) ; Get sector offset in T&D file
- ld (hl),e ; Store it in FCB
- inc hl
- ld (hl),d
- call settddma ; Set DMA for T&D operation
- ld c,readrnd ; Read the sector
- call bdostd
- or a ; Errors are > 0
- jr nz,rwerror
- call checksum ; Compute the checksum
- cp (hl) ; Is file OK?
- jr nz,rwerror
- ld a,(tdindex) ; Get index into the sector
- add a,a ; Multiply by 16
- add a,a
- add a,a
- add a,a
- ld hl,tdbuff ; Address of start of buffer
- add a,l ; Add offset
- ld l,a
- jr nc,rwtd1 ; If no carry, we are all set
- inc h ; Otherwise increment H
- rwtd1:
- ld a,(rwflag) ; See if read or write
- or a
- jr nz,rwtd2 ; If nonzero, we have more to do
-
- ; Reading date stamp
-
- ld de,timestr ; Get data buffer as destination
- ld bc,15 ; Bytes to copy
- ldir
- xor a
- inc a ; Make nonzero (since no error)
- ret ; ..and return (just reading)
- rwtd2:
- ex de,hl ; DE is destination
- ld hl,timestr ; Get pointer to data to write
- ld bc,15 ; Write 15 bytes
- ldir
- call checksum ; Compute the new checksum
- ld (hl),a ; ..and store it in sector
- ld c,writernd ; Write the sector out
- call bdostd
- or a ; Check for error
- jr nz,rwerror
- inc a ; Make A nonzero to show no error
- ret
- rwerror:
- xor a ; Make A zero to show error
- ret
-
- ;-----------------------------------------------------------------------------
-
- ; Calculate the sector number in the T&D file and the index within that sector.
- ;
- ; Entry; A = directory index for file
- ; HL = sector index returned by DateStamper in DE
- ; Exit: T&D sector number stored in TDSECTOR
- ; T&D index stored in TDINDEX
-
- setindex:
- ld b,a ; Save directory index in B
- or a ; Clear carry for arithmetic below
- ld a,h ; Calculate HL/2
- rra
- ld h,a
- ld a,l
- rra
- ld l,a
- ld (tdsector),hl ; Save T&D sector number
- ld a,b ; Get partial index back
- jr nc,setindex1 ; If no carry, we are all set
- add a,4 ; If HL was odd, add 4 to offset
- setindex1:
- ld (tdindex),a ; Store result
- ret
-
- ; End of ZFSUBS5.Z80
-