;
; SYSLIB Module Name: SZFNAM
; Author: Richard Conn
; SYSLIB Version Number: 2.2
; Module Version Number: 1.1
; Module Entry Points:
; ZFNINIT ZFNAME ZDNAME ZDNFIND
; ZCPRQ2
; Module External References:
; CAPS FI3$CLOSE FI3$OPEN F3$GET
; INITFCB MOVEB ZPFIND BDOS
;
;*
;* ZFNAME is a file name scanner. Pointing to the first character
;* of a file name specification of the form 'dir:filename.typ', where
;* any part of this specification is optional, this routine fills in
;* an FCB with zeros, properly initializes the FN and FT (File Name and
;* File Type) fields if 'filename.typ' or any part thereof is present,
;* and returns the value of disk and user if they are specified
;* (or FFH if they are not).
;* The directory indicator 'dir:', if specified, may be of one of two forms:
;* DIRECT -- A named directory, of up to 8 chars in length
;* d -- A disk drive letter
;* u -- A user number
;* du -- A disk drive letter and a user number
;* The named directory form is checked first, so if a directory named
;* A or A10 exists, it matches, as opposed to Drive A or
;* drive/user A/10.
;* Examples:
;* HELP:*.HLP
;* A5:TEST.TXT
;* C?:ABC.*
;* PASCAL:*.COM
;* NOTE: It is the programmer's responsibility to have called and
;* properly initialized the buffers in the ZCPRINIT routine
;* in the SZCPR module
;*
;*
;* BASIC EQUATES
;*
MAXDISK EQU 16 ; MAX NUMBER OF DISKS
MAXUSER EQU 31 ; MAX USER NUMBER
MAXNAME EQU 64 ; MAX NUMBER OF NAMES IN DIR FILE
CPM EQU 0 ; CP/M ENTRY
BENTRY EQU CPM+5 ; BDOS ENTRY
CR EQU 0DH
LF EQU 0AH
;*
;* INIT MODULE
;* IF THE USER WISHES TO CHANGE THE NAME OF THE DIRECTORY FILE TO LOOK
;* FOR, HE CALLS THIS ROUTINE, WITH THE FCB PTR IN DE
;*
;* IF THE USER WISHES TO CHANGE THE ADDRESS OF THE MEMORY-RESIDENT
;* DISK NAMES BUFFER, HE CALLS THIS ROUTINE WITH THE ADDRESS IN HL
;*
;* IF THE USER WISHES TO CHANGE THE NUMBER OF DIRECTORY NAMES PERMITTED
;* IN THE DIRECTORY FILE, HE CALLS THIS ROUTINE, WITH THE NEW NAME
;* COUNT IN C
;*
;* THE SPECIFIC BUFFERED VALUES TO CHANGE ARE INDICATED BY THE A
;* REGISTER AS FOLLOWS:
;* BIT 7 -- SET NAME OF DIR FILE TO FCB PTED TO BY DE
;* BIT 6 -- SET MAX NUMBER OF DIRECTORY NAMES PERMITTED
;* BIT 5 -- SET ADDRESS OF MEMORY-RESIDENT BUFFER
;*
;* IF THIS MODULE IS NOT CALLED, THE FOLLOWING DEFAULT VALUES ARE
;* ASSUMED:
;* NAME OF DIRECTORY NAMES FILE -- NAMES.DIR
;* MAX NUMBER OF DIRECTORY NAMES -- 64
;* NO MEMORY-RESIDENT NAMES BUFFER
;*
;* NO REGS ARE AFFECTED
;* ON INPUT, DE PTS TO NEW FCB
;* HL IS THE ADDRESS OF THE MEMORY-RESIDENT NAMES BUFFER
;* C IS THE MAX NUMBER OF DIRECTORY NAMES
;* A IS FLAG --
;* BIT 7 SET (1) - LOAD DEFAULT FCB FROM DE
;* BIT 6 SET (1) - LOAD NAME COUNT FROM C
;*
ZFNINIT::
PUSH H ; SAVE REGS
PUSH D
PUSH B
PUSH PSW
MOV B,A ; SAVE FLAG IN B
ANI 20H ; LOOK AT BIT 5
JZ ZFNIN0 ; SKIP ADDRESS LOAD IF BIT 5 = 0
SHLD NDADR ; SET ADDRESS FROM HL
ZFNIN0:
MOV A,B ; GET FLAG BYTE
ANI 80H ; LOOK AT BIT 7
JZ ZFNIN1 ; SKIP FCB LOAD IF BIT 7 = 0
PUSH B ; SAVE FLAG IN B
XCHG ; HL PTS TO FCB
LXI D,FNFCB ; PT TO MY FCB
MVI B,12 ; COPY 12 BYTES
CALL MOVEB ; COPY
POP B ; GET FLAG IN B
ZFNIN1:
MOV A,B ; GET FLAG
ANI 40H ; LOOK AT BIT 6
JZ ZFNIN2 ; SKIP NAMES LOAD IF BIT 6 = 0
MOV A,C ; GET COUNT
STA MAXN ; STORE IN BUFFER
ZFNIN2:
POP PSW ; RESTORE REGS
POP B
POP D
POP H
RET
;*
;* ZCPRQ2 -- RETURN POINTER TO BUFFER AREA IN 2ND ZCPR2 MODULE
;* ON RETURN, HL PTS TO FIRST BYTE OF BUFFER AREA
;*
ZCPRQ2::
LXI H,MAXN ; 1ST BYTE
RET
;
; FCB USED BY ZFNAME
;
MAXN:
DB MAXNAME ; INIT TO MAXNAME
NDADR:
DW 0 ; INIT TO NO BUFFER
FNFCB:
DB 0,'NAMES DIR',0,0,0,0 ; INIT TO NAMES.DIR
DS 16
DS 4
;*
;* MAIN MODULE
;* ON ENTRY, DE PTS TO FCB TO BE FILLED AND HL PTS TO FIRST BYTE OF
;* TARGET STRING; FCB IS 36 BYTES LONG
;* ON EXIT, B=DISK NUMBER (1 FOR A, ETC) AND C=USER NUMBER
;* HL PTS TO TERMINATING CHAR
;* A=0 AND Z SET IF ERROR IN DISK OR USER NUMBERS, A=0FFH AND NZ
;* IF OK
;*
ZFNAME::
PUSH D ; SAVE DE
PUSH H ; SAVE HL
XCHG ; SAVE PTR TO FCB
SHLD FCBPTR
XCHG ; DE PTS TO FCB
POP H ; GET HL
MVI A,0FFH ; SET DEFAULT DISK AND USER
STA DISK
STA USER
; FILL TARGET FCB WITH ZEROES
MVI B,36 ; INIT FCB
XRA A ; A=0
FNINI:
STAX D ; STORE ZERO
INX D ; PT TO NEXT
DCR B ; COUNT DOWN
JNZ FNINI
; SCAN FOR COLON IN STRING
PUSH H ; SAVE PTR TO TARGET STRING
COLON:
MOV A,M ; SCAN FOR COLON OR SPACE
CPI ':' ; COLON FOUND?
JZ COLON1
CALL DELCK ; DELIMITER FOUND?
JZ GETF1
INX H ; PT TO NEXT
JMP COLON ; CONTINUE IF NOT END OF LINE
; WE HAVE FOUND A COLON, SO THERE IS A DIR: PREFIX
COLON1:
POP H ; GET PTR TO FIRST CHAR
MVI A,0FFH ; ALLOW DU: FORM
CALL ZDNFIND ; SCAN FOR DIRECTORY NAME; RETURN DISK IN DISK,
JNZ GETFILE ; USER IN USER, NZ IF OK, HL PTS TO COLON
XRA A ; ERROR INDICATOR
POP D ; RESTORE DE
RET
; EXTRACT FILE NAME
GETF1:
POP H ; GET PTR TO BYTE
GETFILE:
XCHG ; GET PTR TO FCB
LHLD FCBPTR
XCHG ; HL PTS TO TARGET STRING, DE PTS TO FCB
MOV A,M ; PTING TO COLON?
CPI ':'
JNZ GFILE1
INX H ; SKIP OVER COLON
GFILE1:
CALL DELCK ; GET NEXT CHAR AND CHECK FOR A DELIMITER
JNZ GFILE2 ; PROCESS SINCE NOT A DELIMITER
CPI '.' ; WAS DELIMITER A '.'?
JZ GFILE2 ; PROCESS SINCE FN MISSING
; NO NAME SPECIFIED, SO MAKE IT WILD
GFQUES:
INX D ; FILL WITH '?'
MVI B,11 ; 11 BYTES
MVI A,'?'
GFFILL:
STAX D ; PUT ?
INX D ; PT TO NEXT
DCR B ; COUNT DOWN
JNZ GFFILL
; EXIT ZFNAME
FNDONE:
LDA DISK ; GET DISK NUMBER
CPI 0FFH ; CURRENT DISK?
JZ FNDN1
INR A ; ADD 1 SO IN THE RANGE FROM 1 TO 16
FNDN1:
MOV B,A ; ... IN B
LDA USER ; GET USER NUMBER
MOV C,A ; ... IN C
POP D ; RESTORE REGS
MVI A,0FFH ; NO ERROR
ORA A ; SET FLAGS
RET
; GET FILE NAME FIELDS
GFILE2:
MVI B,8 ; AT MOST 8 BYTES FOR FN
CALL SCANF ; SCAN AND FILL
MVI B,3 ; AT MOST 3 BYTES FOR FT
MOV A,M ; GET DELIMITER
CPI '.' ; FN ENDING IN '.'?
JNZ GFILE3
INX H ; PT TO CHAR AFTER '.'
CALL SCANF ; SCAN AND FILL
JMP FNDONE ; DONE ... RETURN ARGS
; FT FIELD NOT GIVEN, SO <SP> FILL FT FIELD IN FCB
GFILE3:
CALL SCANF4 ; FILL WITH <SP>
JMP FNDONE
;
; SCANNER ROUTINE
;
SCANF:
CALL DELCK ; CHECK FOR DELIMITER
JZ SCANF4 ; <SP> FILL IF FOUND
INX D ; PT TO NEXT BYTE IN FN
CPI '*' ; ? FILL?
JNZ SCANF1
MVI A,'?' ; PLACE '?'
STAX D
JMP SCANF2
SCANF1:
STAX D ; PLACE CHAR
INX H ; PT TO NEXT POSITION
SCANF2:
DCR B ; COUNT DOWN
JNZ SCANF ; CONTINUE LOOP
SCANF3:
CALL DELCK ; "B" CHARS OR MORE - SKIP TO DELIMITER
RZ
INX H ; PT TO NEXT
JMP SCANF3
SCANF4:
INX D ; PT TO NEXT FN OR FT
MVI A,' ' ; <SP> FILL
STAX D
DCR B ; COUNT DOWN
JNZ SCANF4
RET
;*
;* ZDNAME -- LOAD THE CONTENTS OF THE NAMES.DIR FILE INTO THE MEMORY
;* BUFFER PTED TO BY HL
;* ON ENTRY, HL PTS TO THE MEMORY BUFFER EXTENDING TO THE BASE OF
;* THE BDOS
;* ON EXIT, HL PTS TO THE FIRST ENTRY IN THE NAMES.DIR FILE, BC IS
;* THE NUMBER OF VALID ENTRIES, A IS THE ERROR FLAG (A=0FFH
;* AND NZ IF NO ERROR, A=0 AND Z IF ERROR)
;* ERRORS MAY BE EITHER MEMORY OVERFLOW OR NAMES.DIR
;* NOT FOUND
;* EACH NAMES.DIR ENTRY IS 10 BYTES LONG, STRUCTURED AS FOLLOWS:
;* BYTE 0: DISK NUMBER (A=0)
;* BYTE 1: USER NUMBER
;* BYTES 2-9: DIRECTORY NAME, 8 CHARS MAX, <SP> FILL AT END
;*
ZDNAME::
PUSH D ; SAVE UNCHANGED REG
SHLD DIRNAME ; SAVE PTR TO BUFFER
SHLD CURNAME ; SAVE PTR TO FIRST ENTRY
LXI D,FNFCB ; PT TO FCB WHICH CONTAINS DIR FILE NAME
CALL INITFCB ; INIT FCB
MVI B,0FFH ; SEARCH CURRENT USER
CALL ZPFIND ; LOOK FOR NAMES.DIR FILE
JZ DIRNERR ; FILE NOT FOUND ERROR
;
; FOUND NAMES.DIR, SO LOAD IT
;
CALL PUTUD ; SAVE CURRENT USER/DISK
CALL LOGUD ; LOG IN NEW USER/DISK
LXI D,FNFCB ; PT TO FCB
CALL FI3$OPEN ; OPEN FOR INPUT
;
; LOAD NAMES.DIR FILE
;
MVI C,0 ; SET ENTRY COUNT
LDA MAXN ; GET MAX NUMBER OF NAMES
MOV B,A ; ... IN B
ZDNA1:
LXI H,ENTRY ; PT TO ENTRY BUFFER
CALL GETNAME ; GET NAME FROM DISK
JNZ ZDNA3 ; DONE?
LDA ENTRY+2 ; LOOK AT FIRST LETTER OF DIR NAME
ORA A ; NO ENTRY?
JZ ZDNA2
LHLD DIRNAME ; PT TO BUFFER ENTRY
LXI D,ENTRY ; PT TO NEW ENTRY
INR C ; INCREMENT ENTRY COUNTER
PUSH B ; SAVE COUNTERS
XCHG ; HL PTS TO NEW ENTRY, DE PTS TO DEST
MOV A,M ; GET DISK NUMBER
STAX D ; STORE DISK NUMBER
INX H ; PT TO USER NUMBER
INX D
MOV A,M ; GET USER
STAX D ; PUT USER
MVI B,8 ; AT MOST 8 MORE BYTES
ZDNA1A:
INX H ; PT TO NEXT BYTE
INX D
MOV A,M ; GET NEXT BYTE
ORA A ; END OF NAME?
JZ ZDNA1B ; <SP> FILL
STAX D ; PUT BYTE
DCR B ; COUNT DOWN
JNZ ZDNA1A
INX D ; PT TO FIRST BYTE OF NEXT ENTRY
JMP ZDNA1C
ZDNA1B:
MVI A,' ' ; <SP> FILL
STAX D ; PLACE <SP>
INX D ; PT TO NEXT
DCR B ; COUNT DOWN
JNZ ZDNA1B
ZDNA1C:
POP B ; RESTORE COUNTERS
LHLD BENTRY+1 ; PT TO BDOS ADDRESS
MOV A,H ; CHECK FOR PAGE BEFORE BDOS
DCR A ; PAGE BEFORE
CMP D ; ARE WE THERE?
JZ DNSC2A ; ERROR IF SO, BUT RESTORE UD
JC DNSC2A
XCHG ; HL PTS TO NEXT BUFFER POSITION
SHLD DIRNAME ; SAVE PTR
;
; CONTINUE LOOPING
;
ZDNA2:
DCR B ; COUNT DOWN
JNZ ZDNA1
;
; COMPLETION EXIT
;
ZDNA3:
CALL FI3$CLOSE ; CLOSE FILE
CALL GETUD ; RESTORE USER/DISK
MVI B,0 ; SET HIGH-ORDER BYTE
LHLD CURNAME ; GET PTR TO FIRST ENTRY
MVI A,0FFH ; SET NO ERROR
ORA A ; SET FLAGS
POP D ; RESTORE DE
RET
;*
;* ZDNFIND -- SCAN FOR POSSIBLE DISK DIRECTORY NAME
;* THIS ROUTINE EXAMINES THE DIR: PREFIX FOR EITHER A DIRECTORY NAME
;* OR THE DU FORM
;* ON ENTRY, HL PTS TO DIRECTORY NAME ENDING IN ANY VALID DELIMITER
;* AND A=0 IF DU: FORM NOT ALLOWED (JUST DIR: FORM ALLOWED)
;* RETURN DISK IN B, USER IN C, NZ IF OK, HL PTS TO COLON
;* DE IS NOT AFFECTED
;*
ZDNFIND::
PUSH D ; SAVE DE
SHLD DIRNAME ; SAVE DIRECTORY NAME AWAY
ORA A ; DU: FORM ALLOWED?
JNZ SVDISK ; SCAN FOR DU: FORM FIRST
;
; LOOK FOR DIR: FORM
;
NAME:
;
; SCAN MEMORY-RESIDENT BUFFER IF ONE IS AVAILABLE
;
LHLD NDADR ; GET ADDRESS
MOV A,L ; CHECK FOR ZERO
ORA H
JZ NAME2
INX H ; PT TO ENTRY COUNT
MOV A,M ; GET ENTRY COUNT
ORA A ; CHECK FOR NO ENTRIES
JZ NAME2 ; GOTO DISK IF NO ENTRIES IN MEMORY
MOV B,A ; ENTRY COUNT IN B
INX H ; PT TO FIRST ENTRY
XCHG ; DE PTS TO FIRST ENTRY IN MEMORY
;
; MAIN SCANNING LOOP FOR MEMORY-RESIDENT BUFFER
;
NAME0:
LHLD DIRNAME ; HL PTS TO DIR NAME
PUSH D ; SAVE PTR TO CURRENT MEMORY ENTRY
MVI C,8 ; SCAN UP TO 8 BYTES
INX D ; SKIP DISK
INX D ; SKIP USER
NAME1:
CALL DELCK ; CHECK FOR DELIMITER IN DIR NAME
JZ NAME1B
LDAX D ; GET CHAR IN BUFFER
CMP M ; COMPARE AGAINST TARGET NAME
JNZ NAME1A
INX H ; PT TO NEXT
INX D
DCR C ; COUNT DOWN
JNZ NAME1
JMP NAME1C ; FOUND
NAME1A:
POP H ; GET PTR TO CURRENT BUFFER ENTRY
LXI D,10 ; SKIP TO NEXT ENTRY
DAD D ; HL PTS TO NEXT ENTRY
XCHG ; DE PTS TO NEXT ENTRY
DCR B ; COUNT DOWN
JNZ NAME0
JMP NAME2 ; COMPLETE FAILURE -- DISK SCAN NOW
;
; DELIM ENCOUNTERED ON TARGET NAME, SO CHECK FOR SPACE ON BUFFER ENTRY
; FOR A MATCH
;
NAME1B:
LDAX D ; DELIM ENCOUNTERED, SO MUST BE <SP> TO MATCH
CPI ' ' ; CHECK FOR SPACE
JNZ NAME1A ; NOT SPACE, SO SKIP TO NEXT
;
; ENTRY FOUND
;
NAME1C:
POP H ; GET PTR TO ENTRY
JMP DNSC3A ; EXTRACT DATA AND CONTINUE
;
; LOOK FOR DIR NAME FILE
;
NAME2:
LXI D,FNFCB ; PT TO FCB WHICH CONTAINS DIR FILE NAME
CALL INITFCB ; INIT FCB
MVI B,0FFH ; SEARCH CURRENT USER
CALL ZPFIND ; LOOK FOR NAME FILE
JZ DIRNERR ; ERROR IF NOT FOUND
;
; FOUND DIR NAME FILE, SO LOAD IT AND SCAN IT FOR TARGET NAME
;
CALL PUTUD ; SAVE CURRENT USER/DISK
CALL LOGUD ; LOG IN NEW USER/DISK
LXI D,FNFCB ; PT TO FCB
CALL FI3$OPEN ; OPEN FOR INPUT
;
; LOAD DIR NAME FILE ENTRIES
;
LDA MAXN ; GET MAXIMUM NUMBER OF NAMES
MOV B,A ; ... IN B
DNSC1:
LXI H,ENTRY ; PT TO ENTRY BUFFER
CALL GETNAME ; GET NAME FROM DISK
JNZ DNSC2 ; ERROR EXIT?
CALL SCANAME ; SCAN FOR DIR NAME
JZ DNSC3 ; FOUND ENTRY, SO GET VALUES
DCR B ; COUNT DOWN
JNZ DNSC1
DNSC2:
CALL FI3$CLOSE ; CLOSE FILE
DNSC2A:
CALL GETUD ; RESTORE CURRENT USER/DISK
JMP DIRNERR ; ERROR SINCE NO ENTRY FOUND
;
; DIR NAME FOUND, SO GET DISK AND USER INFORMATION
;
DNSC3:
CALL FI3$CLOSE ; CLOSE FILE
CALL GETUD ; RESTORE CURRENT USER/DISK
DNSC3A:
MOV A,M ; GET DISK (HL PTS TO CURRENT ENTRY)
STA DISK ; SAVE DISK
INX H ; PT TO USER
MOV A,M ; GET USER
STA USER ; SAVE USER
;
; SKIP TO COLON AFTER DIR NAME
;
LHLD DIRNAME ; PT TO DIR NAME
DNSC4:
CALL DELCK ; SKIP TO DELIMITER
JZ DIRNX ; EXIT IF SO
INX H ; PT TO NEXT
JMP DNSC4
;
; LOOK AT START OF DU: FORM
; ON ENTRY, HL PTS TO FIRST CHAR OF DIRECTORY NAME
;
SVDISK:
MOV A,M ; GET DISK LETTER
CALL CAPS ; CAPITALIZE LETTER
CPI 'A' ; DIGIT?
JC USERCK ; IF NO DIGIT, MUST BE USER OR COLON
SUI 'A' ; CONVERT TO NUMBER
CPI MAXDISK ; LIMIT?
JNC NAME ; NAME IF OUT OF LIMIT
STA DISK ; SAVE FLAG
INX H ; PT TO NEXT CHAR
;
; CHECK FOR USER
;
USERCK:
MOV A,M ; GET POSSIBLE USER NUMBER
CPI ':' ; NO USER NUMBER
JZ DIRNX ; EXIT IF SO
CPI '?' ; ALL USER NUMBERS?
JNZ USERC1
STA USER ; SET VALUE
INX H ; PT TO AFTER
MOV A,M ; MUST BE COLON
CPI ':'
JZ DIRNX ; EXIT
JMP DIRNERR ; FATAL ERROR IF NOT COLON AFTER ?
USERC1:
XRA A ; ZERO USER NUMBER
MOV B,A ; B=ACCUMULATOR FOR USER NUMBER
USRLOOP:
MOV A,M ; GET DIGIT
INX H ; PT TO NEXT
CPI ':' ; DONE?
JZ USRDN
SUI '0' ; CONVERT TO BINARY
JC NAME ; NAME IF USER NUMBER ERROR
CPI 10
JNC NAME
MOV C,A ; NEXT DIGIT IN C
MOV A,B ; OLD NUMBER IN A
ADD A ; *2
ADD A ; *4
ADD B ; *5
ADD A ; *10
ADD C ; *10+NEW DIGIT
MOV B,A ; RESULT IN B
JMP USRLOOP
USRDN:
MOV A,B ; GET NEW USER NUMBER
CPI MAXUSER+1 ; WITHIN RANGE?
JNC NAME ; NAME IF OUT OF RANGE
STA USER ; SAVE IN FLAG
;
; VALID EXIT -- FOUND IT, SO LOAD BC AND EXIT FLAG; ON ENTRY, HL PTS TO :
;
DIRNX:
LDA USER ; RETURN USER IN C, DISK IN B
MOV C,A
LDA DISK
MOV B,A
INR B ; DISK A = 1
MVI A,0FFH ; SET NO ERROR
ORA A ; SET FLAGS
POP D ; RESTORE DE
RET
;
; INVALID EXIT -- NOT FOUND OR ERROR
; NO VALID RETURN PARAMETERS (BC, HL)
;
DIRNERR:
XRA A ; ERROR CODE
POP D ; RESTORE DE
RET
;*
;* BUFFERS
;*
FCBPTR: DS 2 ; PTR TO FCB
DISK: DS 1 ; DISK NUMBER
USER: DS 1 ; USER NUMBER
ENTRY:
DS 11 ; ENTRY FROM DISK FILE (DISK, USER, DIR NAME)
DIRNAME:
DS 2 ; PTR TO DIRECTORY NAME
CURNAME:
DS 2 ; PTR TO CURRENT LOCATED NAME
;
; SCAN DIRECTORY ENTRY PTED TO BY HL FOR DIRECTORY NAME STARTING AT DIRNAME
; RETURN WITH Z IF FOUND; DO NOT AFFECT BC
;
SCANAME:
PUSH B ; SAVE BC
SHLD CURNAME ; SET CURRENT NAME PTR
INX H ; SKIP DISK
INX H ; SKIP USER
MVI B,9 ; UP TO 9 CHARS
XCHG ; CURRENT PTR IN DE
LHLD DIRNAME ; PT TO TARGET NAME
SCANL:
LDAX D ; GET CHAR
ORA A ; END OF STRING?
JZ SCANL2
MOV C,A ; SAVE IN C
MOV A,M ; GET TARGET NAME CHAR
CALL CAPS ; CAPITALIZE IT
CMP C ; COMPARE
JNZ SCANL1 ; ABORT IF NO MATCH
CALL DELCK ; END OF TARGET NAME?
JZ SCANL1 ; ABORT IF SO
INX H ; PT TO NEXT
INX D
DCR B ; COUNT DOWN
JNZ SCANL
; NOT FOUND RETURN
SCANL1:
LHLD CURNAME ; PT TO CURRENT ENTRY
LXI B,11 ; SKIP 11 BYTES
DAD B ; PT TO NEXT ENTRY
POP B ; RESTORE BC
MVI A,0FFH ; NOT FOUND FLAG
ORA A ; SET FLAGS
RET
; FOUND RETURN
SCANL2:
CALL DELCK ; MUST PT TO DELIMITER IF MATCH
JNZ SCANL1 ; ABORT IF NOT
LHLD CURNAME ; PT TO FOUND ENTRY
POP B ; RESTORE BC
XRA A ; FOUND
RET
;
; GET NAME FROM FILE 3 INTO BUFFER PTED TO BY HL
; DO NOT AFFECT BC OR HL; RET W/NZ IF ERROR
;
GETNAME:
PUSH B ; SAVE BC
PUSH H ; SAVE HL
CALL F3$GET ; GET DISK LETTER
JNZ GNERR ; ERROR?
SUI 'A' ; CONVERT TO NUMBER
MOV M,A ; STORE IT
INX H ; PT TO NEXT
MVI B,10 ; GET USER AND DIRECTORY NAME
GETN1:
CALL F3$GET ; GET BYTE
JNZ GNERR ; ERROR?
MOV M,A ; STORE IT
INX H ; PT TO NEXT
DCR B ; COUNT DOWN
JNZ GETN1
XRA A ; OK
GNERR:
POP H ; RESTORE HL
POP B ; RESTORE BC
RET
;
; CHECK CHAR PTED TO BY HL FOR A DELIMITER
; RET WITH Z FLAG SET IF DELIMITER
;
DELCK:
MOV A,M ; GET CHAR
CALL CAPS ; CAPITALIZE
ORA A ; 0=DELIM
RZ
CPI ' '+1 ; <SP>+1
JC DELCK1 ; <SP> OR LESS
CPI '='
RZ
CPI 5FH ; UNDERSCORE
RZ
CPI '.'
RZ
CPI ':'
RZ
CPI ';'
RZ
CPI ','
RZ
CPI '<'
RZ
CPI '>'
RET
DELCK1:
CMP M ; COMPARE WITH SELF FOR OK
RET
;
; PUTUD -- SAVE CURRENT USER/DISK FOR LATER RESTORE
; NO REGS AFFECTED
;
PUTUD:
PUSH B ; SAVE REGS
PUSH PSW
PUSH D
PUSH H
MVI C,25 ; GET CURRENT DISK
CALL BDOS
STA CDISK ; SET CURRENT DISK
MVI E,0FFH ; GET USER
MVI C,32 ; GET CURRENT
USER
CALL BDOS
STA CUSER ; SET CURRENT USER
POP H ; RESTORE REGS
POP D
POP PSW
POP B
RET
;
; BUFFERS
;
CDISK:
DS 1 ; CURRENT DISK
CUSER:
DS 1 ; CURRENT USER
;
; GETUD -- RESTORE USER/DISK FROM PREVIOUS PUTUD
;
GETUD:
PUSH H ; SAVE REGS
PUSH D
PUSH B
PUSH PSW
LDA CDISK ; SELECT DISK
MOV E,A
MVI C,14 ; SELECT
CALL BDOS
LDA CUSER ; SELECT USER
MOV E,A
MVI C,32 ; SELECT
CALL BDOS
DONE:
POP PSW ; GET REGS
POP B
POP D
POP H
RET
;
; LOGUD -- LOG IN USER/DISK, WHICH C=USER AND B=DISK
;
LOGUD:
PUSH H ; SAVE REGS
PUSH D
PUSH B
PUSH PSW
MOV E,C ; SELECT USER
MVI C,32
CALL BDOS
MOV E,B ; SELECT DISK
MVI C,14
CALL BDOS
JMP DONE