.TITLE PARFL - PARSE FILE ID .IDENT /01.00/ .LIST MEB .PSECT PARFL ; ; AUTHOR: H. L. COLEMAN ; MILLIKEN AND CO. ; P. O. BOX 1926 ; MAIL STOP M-103 ; SPARTANBURG, S. C. 29304 ; (803)573-2556 ; ; VERSION: 01.00 ; ; MODIFICATIONS: ; ; FUNCTION: THIS ROUTINE PARSES AN ASCII STRING OF THE FORM: ; ; DDUU:[G,O]NAME.TYP;VER ; ; ALL FIELDS ARE OPTIONAL. ; ; INPUT: ; ; R0 = A(STRING) ; R1 = A(NINE WORD PARSE BUFFER) ; ; OUTPUT: ; ; IF CS - SYNTAX ERROR ; ; R0 - POSITION WHEN ERROR DETECTED. ; ; IF CC - NO ERROR DETECTED ; ; R0 = A(FINAL DELIMITER CHATACTER) ; PARSE BUFFER CONTAINS THE PARSED FILE INFORMATION ; THE STATUS FLAGS IN THE PARSE BUFFER ARE SET APPROPRIATELY ; ; PARSE BUFFER FORMAT: ; ; OFFSET LENGTH CONTENTS ; +00 2 DEVICE NAME - TWO ASCII CHARACTERS ; +02 2 DEVICE NUMBER - BINARY ; +04 1 UIC GROUP NUMBER - BINARY ; +05 1 UIC OWNER NUMBER - BINARY ; +06 6 FILE NAME - NINE RAD50 CHARACTERS ; +14 2 FILE TYPE - THREE RAD50 CHARACTERS ; +16 2 FILE VERSION NUMBER - BINARY ; +20 2 STATUS FLAGS ; ; STATUS FLAGS BIT DEFINITIONS: ; ; BIT ; VALUE MEANING WHEN SET ; 1 EXPLICITE FILE VERSION NUMBER SPECIFIED ; 2 EXPLICITE FILE TYPE SPECIFIED ; 4 EXPLICITE FILE NAME SPECIFIED ; 10 WILD CARD VERSION SPECIFIED ; 20 WILD CARD FILE TYPE SPECIFIED ; 40 WILD CARD FILE NAME SPECIFIED ; 100 EXPLICITE UIC SPECIFIED ; 200 EXPLICITE DEVICE SPECIFIED ; 400 WILD CARD IN GROUP PORITON OF UIC ; 1000 WILD CARD IN OWNER PORTION OF UIC ; .PAGE ; OFFSET AND BIT DEFINITIONS ; PBFDNM==0 PBFDUN==2 PBFUIC==4 PBFGRP==5 PBFOWN==4 PBFNAM==6 PBFTYP==14 PBFVER==16 PBFSTS==20 PB.VER==1 PB.TYP==2 PB.NAM==4 PB.SVR==10 PB.STP==20 PB.SNM==40 PB.DIR==100 PB.DEV==200 PB.SD1==400 PB.SD2==1000 .PAGE $PARFL::MOV R1,-(SP) ;SAVE REGISTERS MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV R5,-(SP) MOV R1,R5 ;R5 = A(PARSE BUFFER) CALL PARDEV ;PARSE DEVICE BCS 1000$ ;IF CS, SYNTAX ERROR CALL PARUIC ;PARSE UIC BCS 1000$ ;IF CS, SYNTAX ERROR CALL PARNAM ;PARSE FILE NAME BCS 1000$ ;IF CS, SYNTAX ERROR CALL PARTYP ;PARSE FILE TYPE BCS 1000$ ;IF CS, SYNTAX ERROR CALL PARVER ;PARSE VERSION NUMBER 1000$: MOV (SP)+,R5 ;RESTORE REGISTERS MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 RETURN ;RETURN TO CALLER .PAGE ; PARDEV ; ; FUNCTION: PARSE THE DEVICE SPECIFIER IF SPECIFIED. ; ; INPUT: ; ; R0 = A(NEXT CHARACTER IN STRING) ; ; OUTPUT: ; ; IF CC - NO ERROR ; ; R0 = A(NEXT CHARACTER IN STRING) ; PARSE BUFFER CONTAINS PARSED DEVICE SPECIFIER ; PB.DEV SET APPROPRIATELY ; ; IF CS - SYNTAX ERROR DETECTED ; ; R0 = STRING POSITION WHEN ERROR DETECTED. ; PARDEV: CALL GETFLD ;ISOLATE NEXT FIELD CMPB #':,(R2) ;IS DELIMITER A COLON? BNE 1200$ ;IF NE, NO - NO DEVICE SPECIFIED CMP #2,R3 ;ENOUGH CHARACTERS? BLE 1100$ ;IF LE, YES - CONTINUE 1000$: SEC ;INDICATE SYNTAX ERROR RETURN ;RETURN TO CALLER 1100$: MOVB (R0)+,PBFDNM(R5) ;MOVE DEVICE NAME MOVB (R0)+,PBFDNM+1(R5) MOV R2,R4 ;R4 = A(DELIMITER) CALL $COTB ;CONVERT UNIT NUMBER CMP R1,#256. ;IS IT VALID? BHIS 1000$ ;IF HIS, NO - SYNTAX ERROR CMPB #':,R2 ;WAS TERMINAL CHARACTER A COLON? BNE 1000$ ;IF NE, NO - SYNTAX ERROR INC R4 ;BUMP R4 CMP R0,R4 ;DID WE FIND SAME DELIMITER? BNE 1000$ ;IF NE, NO - SYNTAX ERROR MOV R1,PBFDUN(R5) ;SET UNIT NUMBER BIS #PB.DEV,PBFSTS(R5) ;INDICATE EXPLICITE DEVICE NAME 1200$: CLC ;INDICATE NO ERROR RETURN ;RTEURN TO CALLER .PAGE ; PARUIC ; ; FUNCTION: PARSE UIC SPECIFIER IF PRESENT ; ; INPUT: ; ; R0 = A(NEXT CHARACTER IN STRING) ; ; OUTPUT: ; ; IF CC - NO ERROR ; ; R0 = A(NEXT CHARACTER IN STRING) ; PARSE BUFFER CONTAINS PARSED UIC INFO ; PB.DIR, PB.SD1, AND PB.SD2 SET APPROPRIATELY ; ; IF CS - SYNTAX ERROR ; ; R0 = STRING POSITION WHEN ERROR DETECTED. ; PARUIC: CALL GETFLD ;ISOLATE NEXT FIELD JSR R5,MCCMP ;INVALID DELIMITER? .ASCII /:]/<0><0> BCC 1100$ ;IF CC, DELIMITER OK 1000$: SEC ;INDICATE ERROR RETURN ;RETURN TO CALLER 1100$: CMPB #'[,(R2) ;LEFT BRACKET NEXT? BNE 1800$ ;IF NE, NO - NO UIC SPECIFIED TST R3 ;ANY CHARACTERS BEFORE BRACKET? BNE 1000$ ;IF NE, YES - SYNTAX ERROR BIS #PB.DIR,PBFSTS(R5) ;INDICATE EXPLICITE UIC INC R0 ;BUMP OVER BRACKET CALL GETFLD ;ISOLATE NEXT FIELD CMPB #'*,(R0) ;WILD CARD GROUP? BNE 1300$ ;IF NE, NO BIS #PB.SD1,PBFSTS(R5) ;INDICATE WILD CARD GROUP CLRB PBFGRP(R5) ;CLEAR GROUP CODE INC R0 ;BUMP OVER * CALL GETFLD ;ISOLATE NEXT FIELD BNE 1000$ ;IF NE, YES - SYNTAX ERROR 1200$: MOVB (R0)+,R2 ;R2 = DELIMITER CHARACTER BR 1400$ ;CONTINUE SCAN 1300$: TST R3 ;GROUP PRESENT? BEQ 1200$ ;IF EQ, NO CALL $COTB ;CONVERT GROUP CODE CMP R1,#256. ;VALID? BHIS 1000$ ;IF HIS, NO - SYNTAX ERROR MOVB R1,PBFGRP(R5) ;SET GROUP CODE 1400$: CMPB #'],R2 ;WAS TERMINATOR A RIGHT BRACKET? BEQ 1800$ ;IF EQ, YES - WE'RE THROUGH CMPB #',,R2 ;WAS TERMINATOR A COMMA? BNE 1000$ ;IF NE, NO - SYNTAX ERROR CALL GETFLD ;ISOLATE NEXT FIELD CMPB #'*,(R0) ;WILD CARD USER? BNE 1600$ ;IF NE, NO BIS #PB.SD2,PBFSTS(R5) ;INDICATE WILD CARD OWNER CLRB PBFOWN(R5) ;CLEAR OWNER CODE INC R0 ;BUMP OVER * CALL GETFLD ;ISOLATE NEXT FIELD BNE 1000$ ;IF NE, YES - SYNTAX ERROR 1500$: MOVB (R0)+,R2 ;R2 = DELIMITER BR 1700$ ;CONTINUE 1600$: TST R3 ;OWNER PRESENT? BEQ 1500$ ;IF EQ, NO CALL $COTB ;CONVERT OWNER CODE CMP R1,#256. ;VALID? BHIS 1000$ ;IF HIS, NO - SYNTAX ERROR MOVB R1,PBFOWN(R5) ;STORE OWNER CODE 1700$: CMPB #'],R2 ;WAS DELIMITER A RIGHT BRACKET? BNE 1000$ ;IF NE, NO - SYNTAX ERROR 1800$: CLC ;INDICATE NO ERROR RETURN ;RETURN TO CALLER .PAGE ; PARNAM ; ; FUNCTION: PARSE FILE NAME IF PRESENT ; ; INPUT: ; ; R0 = A(NEXT CHARACTER IN STRING) ; ; OUTPUT: ; ; IF CC - NO ERROR ; R0 = A(NEXT CHARACTER IN STRING) ; PARSE BUFFER CONTAINS PARSED FILE NAME ; PB.NAM, AND PB.SNM SET APPROPRIATELY ; ; IF CS - SYNTAX ERROR ; ; R0 = STRING POSITION WHEN ERROR DETECTED ; PARNAM: CALL GETFLD ;ISOLATE NEXT FIELD JSR R5,MCCMP ;VALID DELIMITER? .ASCII /:[]/<0> BCC 1100$ ;IF CC, VALID DELIMITER 1000$: SEC ;INDICATE SYNTAX ERROR RETURN ;RETURN TO CALLER 1100$: TST R3 ;FILE NAME SPECIFIED? BEQ 1600$ ;IF EQ, NO - WE'RE THROUGH BIS #PB.NAM,PBFSTS(R5) ;INDICATE EXPLICITE NAME MOV R5,R4 ;R4 = A(PARSE BUFFER) ADD #PBFNAM+6,R4 ;R4 = A(END OF NAME FIELD) CLR -(R4) ;INITILIZE NAME FIELD CLR -(R4) CLR -(R4) CMPB #'*,(R0) ;WILD CARD NAME BNE 1200$ ;IF NE, NO BIS #PB.SNM,PBFSTS(R5) ;INDICATE WILD CARD NAME INC R0 ;BUMP OVER * CALL GETFLD ;ISOLATE NEXT FIELD BNE 1000$ ;IF NE, YES - SYNTAX ERROR BR 1600$ ;EXIT 1200$: MOV R2,-(SP) ;SAVE A(DELIMITER) MOV #3,R3 ;SET COUNT 1300$: CLR R1 ;PERIOD IS TERMINATOR CALL $CAT5 ;CONVERT TO RAD50 MOV R1,(R4)+ ;STORE IN BUFFER BCS 1400$ ;IF CS, DELIMITER SEEN - WE'RE THROUGH SOB R3,1300$ ;LOOP UNTIL DONE BR 1500$ ;CONTINUE 1400$: DEC R0 ;R0 = A(DELIMITER) 1500$: CMP (SP)+,R0 ;DID WE FIND SAME DELIMITER? BNE 1000$ ;IF NE, NO - SYNTAX ERROR 1600$: CLC ;INDICATE NO ERROR RETURN ;RETURN TO CALLER .PAGE ; PARTYP ; ; FUNCTION: PARSE FILE TYPE IF PRESENT ; ; INPUT: ; ; R0 = A(NEXT CHARACTER IN STRING ; ; OUTPUT: ; ; IF CC - NO ERROR ; ; R0 = A(NEXT CHARACTER IN STRING ; PARSE BUFFER CONTAINS PARSED TYPE ; PB.TYP, AND PB.STP SET APPROPRIATELY ; ; IF CS - SYNTAX ERROR ; ; R0 = POSITION IN STRING WHEN ERROR DETECTED ; PARTYP: CMPB #'.,(R0) ;TYPE PRESENT? BNE 1400$ ;IF NE, NO - WE'RE THROUGH INC R0 ;BUMP OVER PERIOD CALL GETFLD ;ISOLATE NEXT FIELD JSR R5,MCCMP ;VALID DELIMITER? .ASCII /:.[]/<0><0> BCC 1100$ ;IF CC, DELIMITER VALID 1000$: SEC ;INDICATE SYNTAX ERROR RETURN ;RETURN TO CALLER 1100$: TST R3 ;TYPE SPECIFIED? BEQ 1400$ ;IF EQ, NO - WE'RE THROUGH BIS #PB.TYP,PBFSTS(R5) ;INDICATE EXPLICITE TYPE CLR PBFTYP(R5) ;CLEAR TYPE CMPB #'*,(R0) ;WILD CARD TYPE? BNE 1200$ ;IF NE, NO BIS #PB.STP,PBFSTS(R5) ;INDICATE WILD CARD TYPE INC R0 ;BUMP OVER * CALL GETFLD ;ISOLATE NEXT FIELD BNE 1000$ ;IF NE, YES - SYNTAX ERROR BR 1400$ ;EXIT 1200$: MOV R2,R3 ;R3 = A(DELIMITER) CLR R1 ;PERIOD IS TERMINATOR CALL $CAT5 ;CONVERT TO RAD50 MOV R1,PBFTYP(R5) ;STORE TYPE BCC 1300$ ;IF CC, NO DELIMITER FOUND DEC R0 ;R0 = A(DELIMITER) 1300$: CMP R0,R3 ;DID WE FIND SAME DELIMITER? BNE 1000$ ;IF NE, NO - SYNTAX ERROR 1400$: CLC ;INDICATE NO ERROR RETURN ;RETURN TO CALLER .PAGE ; PARVER ; ; FUNCTION: PARSE VERSION NUMBER IF PRESENT ; ; INPUT: ; ; R0 = A(NEXT CHARACTER IN STRING) ; ; OUTPUT: ; ; IF CC - NO ERROR ; ; R0 = A(NEXT CHARACTER IN STRING) ; PARSE BUFFER CONTAINS PARSED VERSION NUMBER ; PB.VER, AND PB.SVR SET APPROPRIATELY ; ; IF CS - SYNTAX ERROR ; ; R0 = POSITION IN STRING WHEN ERROOR DETECTED ; PARVER: CMPB #';,(R0) ;VERSION PRESENT? BNE 1500$ ;IF NE, NO - WE'RE ALMOST THROUGH INC R0 ;BUMP OVER ; CALL GETFLD ;ISOLATE NEXT FIELD JSR R5,MCCMP ;IS DELIMITER VALID? .ASCII /:.[];/<0> BCC 1100$ ;IF CC - DELIMITER VALID 1000$: SEC ;INDICATE SYNTAX ERROR RETURN ;RETURN TO CALLER 1100$: TST R3 ;VERSION SPECIFIED? BEQ 1500$ ;IF EQ, NO - WE'RE ALMOST THROUGH BIS #PB.VER,PBFSTS(R5) ;INDICATE EXPLICITE VERSION CLR PBFVER(R5) ;CLEAR VERSION CMPB #'*,(R0) ;WILD CARD VERSION? BNE 1200$ ;IF NE, NO BIS #PB.SVR,PBFSTS(R5) ;INDICATE WILD CARD VERSION INC R0 ;BUMP OVER * CALL GETFLD ;ISOLATE NEXT FIELD BNE 1000$ ;IF NE, YES - SYNTAX ERROR BR 1500$ ;GO FINISH UP 1200$: MOV R2,R3 ;R3 = A(DELIMITER) CLR R4 ;R4 = 0 CMPB #'-,(R0) ;MINUS? BNE 1300$ ;IF NE, NO INC R0 ;BUMP OVER - DEC R4 ;FLAG MINUS 1300$: CALL $COTB ;CONVERT TO BINARY TST R1 ;ZERO? BEQ 1400$ ;IF EQ, YES - IGNORE MINUS TST R4 ;WAS IT MINUS? BEQ 1400$ ;IF EQ, NO NEG R1 ;MAKE IT NEGATIVE 1400$: MOV R1,PBFVER(R5) ;STORE VERSION DEC R0 ;R0 = A(DELIMITER) CMP R0,R3 ;DID WE FIND SAME DELIMITER? BNE 1000$ ;IF NE, NO - SYNTAX ERROR 1500$: MOV R0,R2 ;R2 = A(DELIMITER) JSR R5,MCCMP ;VALID DELIMITER? .ASCII /:.[];/<0> BCS 1000$ ;IF CS, NOT A VALID DELIMITER RETURN ;RETURN TO CALLER .PAGE ; GETFLD ; ; FUNCTION: SUBROUTINE TO LOCATE THE START AND END OF THE NEXT ; FIELD. ; ; INPUT: ; ; R0 = A(NEXT CHARACTER IN STRING) ; ; OUTPUT: ; ; R0 = A(NEXT NON-BLANK CHARACTER IN STRING) ; R2 = A(NEXT DELIMITER) ; R3 = STRING LENGTH (R2-R3) ; GETFLD: CMPB #' ,(R0)+ ;BLANK? BEQ GETFLD ;IF EQ, YES - KEEP LOOKING DEC R0 ;R0 = A(NEXT NON-BLANK CHARACTER) MOV R0,R2 ;R2 = A(CURRENT POSITION) 1000$: CMPB #' ,(R2) ;EOL? BHI 1100$ ;IF HI, YES - WE'RE THROUGH JSR R5,MCCMP ;IS IT A DELIMITER? .ASCII <57>/=,:[].;/<0><0> BCS 1100$ ;IF CS, YES - WE'RE THROUGH INC R2 ;BUMP TO NEXT CHARACTER BR 1000$ ;KEEP LOOKING 1100$: MOV R2,R3 ;R3 = A(DELIMITER) SUB R0,R3 ;R3 = STRING LENGTH RETURN ;RETURN TO CALLER .PAGE ; MCCMP ; ; FUNCTION: COMPARE A CHARACTER IN MEMORY TO A LIST OF CHARACTERS. ; ; INPUT: ; ; R2 = A(CHARACTER TO BE COMPARED) ; R5 = A(LIST OF CHARACTERS) ; ; OUTPUT: ; ; IF CC - CHARACTER NOT IN LIST ; IF CS - CHARACTER IN LIST ; MCCMP: MOV #-2,-(SP) ;INITILIZE HIT FLAG 1000$: TSTB (R5)+ ;END OF LIST BEQ 1100$ ;IF EQ, YES - WE'RE THROUGH CMPB (R2),-1(R5) ;MATCH? BNE 1000$ ;IF NE, NO - KEEP LOOKING ASR (SP) ;SET HIT FLAG BR 1000$ ;KEEP LOOKING FOR END OF LIST 1100$: INC R5 ;ROUND R5 UP TO MULTIPLE OF 2 BIC #1,R5 ROR (SP)+ ;SET/CLEAR CARRY RTS R5 ;RETURN TO CALLER .END