; ; SYSLIB Module Name: SFNAME ; Author: Richard Conn ; SYSLIB Version Number: 2.0 ; Module Version Number: 1.0 ; Module Entry Points: ; FNAME ; Module External References: ; CAPS ; ;* ;* FNAME is a file name scanner. Pointing to the first character ;* of a file name specification of the form 'du: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 d and u if they are specified (or FFH if they ;* are not). ;* ;* ;* EXTERNALS ;* EXT CAPS ; CAPITALIZE ROUTINE ;* ;* BASIC EQUATES ;* MAXDISK EQU 16 ; MAX NUMBER OF DISKS MAXUSER EQU 31 ; MAX USER NUMBER CPM EQU 0 ; CP/M ENTRY CR EQU 0DH LF EQU 0AH ;* ;* 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 ;* FNAME:: PUSH D ; SAVE DE MVI A,0FFH ; SET DEFAULT DISK AND USER STA DISK STA USER MVI B,36 ; INIT FCB PUSH D ; SAVE PTR XRA A ; A=0 FNINI: STAX D ; STORE ZERO INX D ; PT TO NEXT DCR B ; COUNT DOWN JNZ FNINI POP D ; GET PTR BACK ; SCAN FOR COLON IN STRING PUSH H ; SAVE PTR COLON: MOV A,M ; SCAN FOR COLON OR SPACE INX H ; PT TO NEXT CPI ':' ; COLON FOUND? JZ COLON1 CPI ',' ; COMMA FOUND? JZ GETF1 CPI ' '+1 ; DELIM? JC GETF1 JMP COLON ; CONTINUE IF NOT END OF LINE COLON1: POP H ; CLEAR STACK MOV A,M ; SAVE POSSIBLE DRIVE SPEC CALL CAPS ; CAPITALIZE CPI 'A' ; DIGIT IF LESS THAN 'A' JC USERCK ; PROCESS USER NUMBER SUI 'A' ; CONVERT TO 0-15 CPI MAXDISK ; WITHIN BOUNDS? JC SVDISK ERREXIT: XRA A ; ERROR INDICATOR POP D ; RESTORE DE RET ; LOG IN SPECIFIED DISK SVDISK: INR A ; ADJUST TO 1 FOR A 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 GETFILE CPI '?' ; ALL USER NUMBERS? JNZ USERC1 STA USER ; SET VALUE INX H ; PT TO AFTER MOV A,M ; MUST BE COLON CPI ':' JZ GETFILE JMP ERREXIT ; 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 ERREXIT ; USER NUMBER ERROR? CPI 10 JNC ERREXIT 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 ; WITHIN RANGE? JNC ERREXIT STA USER ; SAVE IN FLAG JMP GETFILE ; EXTRACT FILE NAME GETF1: POP H ; GET PTR TO BYTE GETFILE: MOV A,M ; PTING TO COLON? CPI ':' JNZ GFILE1 INX H ; SKIP OVER COLON GFILE1: MOV A,M ; GET NEXT CHAR CPI ',' ; DELIM? JZ GFQUES CPI ' '+1 ; NOT A DELIMITER? JNC GFILE2 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 FNDONE: LDA DISK ; GET DISK NUMBER 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 GFILE3: CALL SCANF4 ; FILL WITH JMP FNDONE ; ; SCANNER ROUTINE ; SCANF: CALL DELCK ; CHECK FOR DELIMITER JZ SCANF4 ; 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,' ' ; FILL STAX D DCR B ; COUNT DOWN JNZ SCANF4 RET ;* ;* BUFFERS ;* DISK: DS 1 ; DISK NUMBER USER: DS 1 ; USER NUMBER ; ; 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 ; +1 JC DELCK1 ; 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 END