home *** CD-ROM | disk | FTP | other *** search
- title 'Parse file name into FCB'
- page 58
-
- public PARFCB ; parse file name at <HL> into FCB at <DE>
- public UPCASE ; A := UPCASE(A), use only AF register
-
- ; Data structure of target FCB at <DE> :
-
- user$offset equ -1 ; 1 byte user number
- ; 0 = default
- ; 1..16 = user 0..15
-
- fcb$offset equ 0 ; 36 bytes FCB
- ; byte 0 = drive
- ; 0 = default
- ; 1..16 = drive A..P
- ; byte 1..8 = name
- ; default = <spaces>
- ; byte 9..11 = type
- ; default = <spaces>
- ; byte 12..36= not used
- ; default = <blank>
-
- password$offset equ 36 ; 8 bytes password field
- ; default = <spaces>
-
-
- ; Format of file name :
-
- ; user drive : name . type ; password
- ; or
- ; drive user : name . type ; password
-
- ; Parameters :
-
- ; DE = pointer to FCB
- ; HL = pointer to ASCIIZ name string
-
- ; Results :
-
- ; A = 0 if ok
- ; A = 0FFH if parse error
-
- cseg
- PARFCB: shld name$ptr ; save pointers
- xchg
- shld fcb$ptr ; now HL = .FCB
-
- xra a ; A := 0
- dcx h ; let HL point to user number
- mov m,a ; user number := default
- inx h
-
- mov m,a ; drive := default
- inx h
-
- lxi b,0B20h ; file name,type := <spaces>
- call fill$in
-
- lxi b,1800h ; rest of FCB := <blank>
- call fill$in
-
- lxi b,0820h ; passsword := <spaces>
- call fill$in
-
- lhld name$ptr ; let HL point to filename
- skip$start: mov a,m ; skip leading rubbish
- inx h
- ora a ; test for end of string
- jz parse$err
- cpi ' '+1 ; test for space and control chars
- jc skip$start
- dcx h
- shld name$ptr ; save pointer to new start of string
-
- mvi b,0 ; prefix char count := 0
- search$colon: mov a,m ; get next char
- inx h
- inr b
- ora a
- jz trans$name ; no user/drive present
- cpi ':'
- jnz search$colon
-
- shld name$ptr ; save pointer to start of file name
- dcx h ; skip over colon
- dcr b
-
- prefix: dcx h ; HL points to next char
- dcr b ; B counts characters to the left
- jm trans$name ; no chars left ?
-
- mov a,m ; get next char of prefix
- call UPCASE ; drive code may be upper or lower case
- sui '0' ; numeric ?
- jc parse$err ; below numeric (huh?)
- cpi 9+1
- jnc drive ; not numeric
- mov c,a
- push h
- lhld fcb$ptr ; get old user number
- dcx h
- mov a,m
- ora a ; first digit of user number ?
- jz user$first
-
- user$second: dcr a ; user number is 1-based
- mov e,a ; E := old user number
- mov a,c ; A := current digit
- add a ; A := A*10
- mov d,a
- add a
- add a
- add d
- add e ; A := A*10+E
- inr a ; user number is 1-based
- mov m,a ; store new user number
- pop h
- jmp prefix
-
- user$first: inr c
- mov m,c
- pop h
- jmp prefix
-
- drive: sui 'A'-'0' ; drive code ?
- jc parse$err ; huh?
- cpi 'P'-'A'+1
- jnc parse$err ; huh?
- inr a ; drive code starts with 1
- push h
- lhld fcb$ptr ; store drive code
- mov m,a
- pop h
- jmp prefix ; test rest of prefix
-
- trans$name: lhld fcb$ptr ; let DE point to name field
- xchg
- inx d
- lhld name$ptr ; let HL point to start of name
- mvi b,8+1 ; max. number of chars
-
- name$loop: mov a,m ; get byte
- inx h
- ora a ; end of string ?
- rz
- cpi '.' ; start of type ?
- jz trans$type
- cpi ';' ; start of password
- jz trans$pass
- cpi '/' ; directory information ?
- jz skip$dir
- cpi '\'
- jz skip$dir
- call UPCASE
- dcr b ; number of chars-1
- jz parse$err ; name too long
- stax d ; into name field
- inx d
- jmp name$loop ; next char
-
- trans$type: push h ; save pointer to first type char
- lhld fcb$ptr
- lxi d,9 ; start of type field
- dad d
- xchg
- pop h
- mvi b,3+1 ; max. number of chars
-
- type$loop: mov a,m ; get byte
- inx h
- ora a ; end of string ?
- rz
- cpi ';' ; start of password ?
- jz trans$pass
- call UPCASE
- dcr b ; number of chars-1
- jz parse$err ; type too long
- stax d ; into type field
- inx d
- jmp type$loop
-
- trans$pass: push h ; save pointer to first type char
- lhld fcb$ptr
- lxi d,36 ; start of password field
- dad d
- xchg
- pop h
- mvi b,8+1 ; max. number of chars
-
- pass$loop: mov a,m ; get byte
- inx h
- ora a ; end of string ?
- rz
- call UPCASE
- dcr b ; number of chars-1
- jz parse$err ; password too long
- stax d ; into password field
- inx d
- jmp pass$loop
-
- parse$err: mvi a,0FFH ; error code
- ret
-
- skip$dir: shld name$ptr ; save new start of name string
- lhld fcb$ptr ; erase name field of FCB
- inx h
- lxi b,0820H
- call fill$in
- jmp trans$name ; and try again
-
-
- ; fill <B> bytes at <HL> with <C>, advance <HL>
-
- cseg
- fill$in: mov m,c ; fill byte
- inx h ; HL ++
- dcr b
- jnz fill$in ; until B = 0
- ret
-
-
- ; translate char in <A> to upper case. uses <AF>
-
- cseg
- UPCASE: cpi 'a' ; < 'a' ?
- rc ; no translation performed
- cpi 'z'+1 ; > 'z' ?
- rnc ; no translation performed
- sui 'a'-'A' ; lower -> upper
- ret
-
-
- dseg
- name$ptr: ds 2 ; pointer to ASCIIZ name string
- fcb$ptr: ds 2 ; pointer to FCB
-
- end
-