home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
ENTERPRS
/
CPM
/
UTILS
/
S
/
ZCNFG21.LBR
/
CFGLIB.LBR
/
GETZFS.ZZ0
/
GETZFS.Z80
Wrap
Text File
|
1991-10-25
|
10KB
|
327 lines
;routine to perform parse of [DU/DIR:]FN[.FT]
;date: 09/18/91
;author: A.E. Hawley
;version 1.3 previous: v 1.2, 10/19/88
;v 1.5 10/25/91
; added logic to decrement default DRive in SCAN: if it
; is 0ffh. This records the occurrence of a lone ':'.
; Also added error handling after the call to DIRSCN so
; a bogus value is not put into BC!
;v 1.4 09/12/91
; corrected SCAN to store the error flag!
; corrected main routine to properly test error flag!
; added code in main routine to store User at FCB+13
;v 1.3 09/08/91
; Modified DUSCN so that default DU passed in BC
; is not tested for out-of-range values. Such values
; can then be used to test for presence of user
; supplied D or U, and defaults provided separately.
; If BC contains legal values, operation is unchanged.
;v 1.2 10/19/88
; Modified delimiter list to include '/'
; Default D/U are passed in BC rather than an external.
; Uses ALL 8080 registers, no Z80 special registers
PUBLIC dirscn,duscn,fname
GLOBAL fill,ifcb,inifcb,mpy16,pkgoff,radbin
GLOBAL rten1,sdelm,sksp,ucase
;-----------------------------------------
;entry- HL -> Token to be parsed as Z3 filespec
; DE -> FCB drive byte
; B = Default Drive
; C = Default User
;exit- HL -> Delimiter which terminated the parse
; DE is preserved
; BC = D/U, with defaults replaced by explicit D or U
; (caller is responsible for legality of defaults)
; if BC=-1 on entry, a parsed colon decrements B allowing
; detection of an FS of form ':[FN.FT]' (10/25/91)
; FCB drive byte, FN, FT, map fields initialized
; FCB-1 = FCB+13 = Default or declared User area
; NZ = Error, FCB+15 contains error flag
; Z = no error
; A = number of '?' in fn/ft. (wildcard count)
;-----------------------------------------
fname: push de ; Save pointer while initializing
ld (tempusr),bc ; Initialize temporary DU
call inifcb ; Initialize FCB
pop de
push de
call scan ; parse token into the FCB
;on return, A=number of '?' encountered
pop de ;->fcb
push hl ; Initialize fcb-1, fcb with bc
ld h,d
ld l,e
ld (hl),b ; Drive
dec hl
ld (hl),c ; User
ld hl,13
add hl,de ;-> Z3 User byte
ld (hl),c
inc hl
inc hl ;->error flag
inc (hl)
dec (hl) ;returns Z if no errors
pop hl ;->next char after token
ret ;return NZ if bad du or wildcards
;-----------------------------------------
; This routine processes a token pointed to by HL. It attempts
; to interpret the token according to the form [DU:|DIR:]NAME.TYP and places
; the corresponding values into the FCB pointed to by DE.
; On entry, HL->token, DE->target fcb, BC=current DU (1..16,0..32)
; On exit, HL points to the delimiter encountered at the end of the token.
; The Z flag is set if a wild card was detected in the token, and A=? count.
; The drive byte is initialized, and the S1 byte contains the user number.
; BC contains the Drive/User.
; ERROR conditions: on a bad directory reference, the RC byte in the FCB
; will be set to NZ. (usually 0FFh)
scan:
call scanf8 ; Extract possible file name
cp ':' ; Was terminating character a colon?
jr nz,scant ; If not, go on to extract file type
inc hl ; Point to character after colon
; Code for resolving directory specifications returns
; with a nonzero value and NZ flag setting
; if the DU/DIR specification cannot be resolved.
push hl
push de
ld bc,(tempusr) ; Preset C to current user, B to current drive
ld a,b
inc a ; -1 default?
jr nz,scan1 ; no, don't disturb it
dec b ; else make it 0FEh to show colon present
ld (tempusr),bc ; and save it
scan1: call duscn ;check for DU form
jr z,gotit
pop de ;not DU, check for DIR
pop hl
push hl
push de
call dirscn ;returns nz if bad dir|no ndir|not Z3
jr nz,scan3 ;not found, BC destroyed
gotit: ld (tempusr),bc
scan3: pop de ; Get FCB pointer back
ld b,a ; save error flag
push de ;clear FN field after du/dir scan use
inc de ;12/04/87
call ifcb ; ret A=B=0, Z
pop de
ld hl,15
add hl,de ; point to RC byte of the FCB
ld (hl),b ; Store error flag there (NZ if error)
ld a,(tempdr) ; Set designated drive
ld (de),a ; ..into FCB
pop hl ; Restore pointer to token string
;..and save error flag pointer
call scanf8 ; Scan for file name
; Process the file type specification in the token
scant:
ld a,(hl) ; Get ending character of file name field
ex de,hl ; Switch FCB pointer into HL
ld bc,8 ; Offset to file type field
add hl,bc
ex de,hl ; Switch pointers back
cp '.' ; See if file type specified
jr nz,scant2 ; If not, skip over file type parsing
inc hl ; Point to character after '.'
push de ; Save pointer to FCB file type
ld b,3 ; Maximum characters in file type
call scanfield ; Parse file type into FCB
pop de
scant2: call scanf3 ; Skip to next delimiter or line end
; Set zero flag if '?' in filename.typ
qmcnt equ $+1 ; Pointer for in-the-code modification
ld a,0 ; Number of question marks
or a ; Set zero flag
ld bc,(tempusr) ; return DU in BC
ret
;-----------------------------------------
; This routine invokes SCANFIELD for a file name field. It initializes the
; question mark count and preserves the FCB pointer.
scanf8:
xor a ; Initialize question mark count
ld (qmcnt),a
push de ; Save pointer to FCB
ld b,8 ; Scan up to 8 characters
call scanfield
pop de ; Restore pointer to FCB
ret
; This routine scans a command-line token pointed to by HL for a field whose
; maximum length is given by the contents of the B register. The result is
; placed into the FCB buffer pointed to by DE. Wild cards of '?' and '*' are
; expanded. On exit, HL points to the terminating delimiter.
scanfield:
call sdelm ; Done if delimiter encountered
ret z
inc de ; Point to next byte in FCB
cp '*' ; Is character a wild card?
jr nz,scanf1 ; Continue if not
ld a,'?' ; Process '*' by filling with '?'s
ld (de),a
call qcountinc ; Increment count of question marks
jr scanf2 ; Skip so HL pointer left on '*'
scanf1: ; Not wildcard character '*'
call ucase ; make sure it's upper case ascii
ld (de),a ; Store character in FCB
inc hl ; Point to next character in command line
cp '?' ; Check for question mark (wild)
call z,qcountinc ; Increment question mark count
scanf2:
djnz scanfield ; Decrement char count until limit reached
scanf3:
call sdelm ; Skip until delimiter
ret z ; Zero flag set if delimiter found
inc hl ; Pt to next char in command line
jr scanf3
; Subroutine to increment the count of question mark characters in the
; parsed file name.
qcountinc:
push hl
ld hl,qmcnt ; Point to count
inc (hl) ; Increment it
pop hl
ret
;-----------------------------------------
; This code attempts to interpret the token in the FCB pointed to by register
; pair DE as a DIR (named directory) prefix. If it is successful, the drive
; and user values are stored in TEMPDR and TEMPUSR, and the zero flag is set.
dirscn:
inc de ; Point to first byte of directory form
ex de,hl ; Switch pointer to FCB to HL
ld de,15h ; Offset to NDR address
push hl ; Preserve pointer to FCB
call pkgoff ; Get NDR address from ENV into DE
pop hl
jr z,direrr ; Branch if no NDR implemented
dirsc1:
ld a,(de) ; Get next character
or a ; Zero if end of NDR
jr z,direrr
inc de ; Point to name of directory
inc de
push hl ; Save pointer to name we are looking for
push de ; Save pointer to NDR entry
ld b,8 ; Number of characters to compare
dirsc2:
ld a,(de)
cp (hl)
jr nz,dirsc3 ; If no match, quit and go on to next DIR
inc hl ; Point to next characters to compare
inc de
djnz dirsc2 ; Count down
dirsc3:
pop de ; Restore pointers
pop hl
jr z,dirsc4 ; Branch if we have good match
ex de,hl ; Advance to next entry in NDR
ld bc,16 ; 8 bytes for name + 8 bytes for password
add hl,bc
ex de,hl
jr dirsc1 ; Continue comparing
dirsc4: ; Match found
ex de,hl ; Switch pointer to NDR entry into HL
push hl ; ..and save it for later
dec hl ; Point to user corresponding to the DIR
ld c,(hl) ; Get user value into C
dec hl ; Point to drive
ld b,(hl) ; Get it into B
pop hl
ret
;-----------------------------------------
direrr: ; Error exit for dirscn, duscan
duerr: or 0ffh ; Return NZ to show failure
ret
;-----------------------------------------
; This code attempts to interpret the token in the FCB pointed to by register
; pair DE as a DU (drive/user) prefix. If it is successful, the drive and
; user values are stored in TEMPDR and TEMPUSR, and the zero flag is set.
; Entry- BC = default drive, user
duscn:
ex de,hl ; Switch FCB pointer to HL
inc hl ; Point to first byte of file name in FCB
ld a,(hl) ; Get possible drive specification
sub 'A' ; Otherwise convert to number 0..15
jr c,duscn1 ; If < 0, leave B as is
cp 16
jr nc,duscn1 ; If > 15, leave B as is
ld b,a ; Otherwise use value given
inc hl ; ..and point to next character
inc b ; Shift drive to range 1..16
duscn1: ld a,(hl) ; Get possible user specification
cp ' '
ret z ; if none present, leave C as is
push bc ; Save DU values in BC
call rten1 ; Get specified decimal user number into BC
pop hl ; Restore values to HL
jr c,duerr ; Return NZ if invalid decimal conversion
ld a,b ; Get high byte of result
or a ; Make sure it is zero
ret nz ; If not, return NZ to show bad user number
ld a,31
sub c ; if CY set, then number > 31
sbc a,a ; propagate CY into A and set flags
ret nz ; NZ = bad user number
ld b,h ; DU value is now in BC
xor a ; Set Z to flag success
ret
;-----------------------------------------
tempusr: ;temporary local values
db 0
tempdr:
db 0
end