.TITLE PSZPRS - PARSING SUBROUTINE FOR PARSIZ TASK. .SBTTL PSZPRS - TITLE PAGE .IDENT /V001A/ ;+ ; ; PSZPRS - PARSING SUBROUTINE FOR PARSIZ TASK. ; ; AUTHOR - RODGER S. MILES DATE: 14-APR-80 ; ; THIS ROUTINE WILL PARSE THE COMMAND LINE POINTED ; TO BY R0. IT ASSUMES THAT THE LINE IS TERMINATED ; BY A NULL CHARACTER (ZERO). IF ANY ERROR IS ; ENCOUNTERED, THE ROUTINE WILL RETURN THE C-BIT ; SET. OTHERWISE IT WILL RETURN HAVING UPDATED THE ; PARAMETERS PARNM, IF "/PAR=" IS USED, AND $PSIZE, ; IF "/SIZE=" IS USED. ; THIS ROUTINE WAS ADAPTED FROM THE LDCTL MODULE ; OF THE RSX11M TASK "...LOA". ; ; INPUTS: ; R0 = ADDRESS OF A COMMAND LINE. ; ; OUTPUTS: ; C-BIT - SET ON ERROR/CLEAR ON SUCCESS ; $PARNM - UPDATED IF '/PAR' SWITCH IS USED. ; $PSIZE - UPDATED IF '/SIZE' SWITCH IS USED. ; R0-R5 - DESTROYED. ; ; THE GENERAL FORM OF THE COMMAND LINE IS: ; ; XXX[...] [/PAR=PNAME][/SIZE=PSIZE] ; ; WHERE XXX[...] - THE TASK NAME. ; PNAME - THE NAME OF THE PARTITION TO BE REDUCED IN SIZE. ; PSIZE - THE NEW UPPER LIMIT OF THE PARTITION IN UNITS ; OF 64 BYTES BLOCKS. THE VALUE MUST BE OCTAL. ; ;- .MCALL DIR$,FINIT$ .SBTTL ...... - LOCAL DATA - TEXT STRINGS .PSECT DATA,D .NLIST BEX PARSTR: .ASCII /PAR/ ;'/PAR' KEYWORD STRING PARLEN=.-PARSTR ;STRING LENGTH SIZSTR: .ASCII /SIZE/ ;'/SIZE' KEYWORD STRING SIZLEN=.-SIZSTR ;STRING LENGTH TOPSTR: .ASCII /TOP/ TOPLEN=.-TOPSTR BOTSTR: .ASCII /BOT/ BOTLEN=.-BOTSTR COMSTR: .ASCII /COM/ COMLEN=.-COMSTR NOCSTR: .ASCII /NOC/ NOCLEN=.-NOCSTR .EVEN .SBTTL PSZPRS - SUBROUTINE ENTRY .PSECT CODE,I PSZPRS:: ;ENTRY POINT CLR $SQZ ;assume not a find-space operation CLR $NOC ;assume not a common-removal CLR $AST ;assume not an asterisk command CLR $COM CLR $COM+2 CLR $PSIZE CLR $TOP CLR $INC CLR $BTINC CLR $BOT 10$: CALL GETCHR ;FETCH NEXT CHARACTER BCS 15$ ;IF 'EOL', ASSUME NO COMMAND LINE GIVEN. CMPB #40,R5 ;HAVE WE REACHED SEPARATING BLANK? BNE 10$ ;IF NE NO CALL GETNB ;GET NEXT NON-BLANK CHARACTER BCC 29$ ;IF CC DID NOT FIND END-OF-LINE 15$: JMP PDONE ; 29$: CMPB #'/,R5 ;NEXT LEGAL CHARACTER IS A SLASH BEQ 31$ 30$: JMP STXERR ;NE=.syntax error 31$: CALL GETCHR ;GET NEXT CHARACTER BCS 30$ ;IF CS SYNTAX ERROR MOV #BOTSTR,R4 ;ASSUME /SIZE KEYWORD CMPB (R4)+,R5 ;FOUND AN B? BNE 50$ ;IF NE NO TST $BOT ;already set? BNE 30$ ;if yes, skip MOV #,R3 40$: CALL CHKCOM ;parse command BCS 30$ ;skip if bad 42$: CMPB (0),#'- ;minus sign? BNE 45$ INC R0 CALL $COTB NEG R1 MOV R1,$BOT ;save change in bottom INC $BTINC 43$: JMP 120$ 45$: CMPB (0),#'+ BNE 47$ INC R0 CALL $COTB MOV R1,$BOT INC $BTINC BR 43$ 47$: CALL $COTB MOV R1,$BOT BR 43$ 50$: MOV #SIZSTR,R4 CMPB (4)+,R5 BNE 60$ ; ; /SIZE=PSIZE ; TST $PSIZE ;ALREADY DID /SIZE? BNE 30$ ;IF NE YES TST $TOP 51$: BNE 30$ MOV #,R3 ;GET REMAINING LENGTH OF KEYWORD 52$: CALL CHKCOM ;check command 53$: BCS 30$ ;skip if illegal 54$: CMPB (0),#'* ;(as big as possible) BEQ 68$ ;if yes, as if TOP switch 56$: CALL $COTB ;CONVERT OCTAL TO BINARY MOV R1,$PSIZE ;SAVE THE RESULT JMP 120$ ; 60$: MOV #TOPSTR,R4 CMPB (4)+,R5 ;T for TOP? BNE 70$ ;if not, skip TST $PSIZE BNE 51$ TST $TOP BNE 51$ MOV #-1,R3 62$: CALL CHKCOM ;parse command BCS 53$ ;skip if bad 64$: CMPB (0),#'- ;minus sign? BNE 65$ INC R0 CALL $COTB ;octal to binary NEG R1 MOV R1,$TOP INC $INC BR 120$ 65$: CMPB (0),#'+ BNE 67$ ;if not + must be absolute INC R0 CALL $COTB MOV R1,$TOP INC $INC BR 120$ 67$: CMPB (0),#'* ;(as big as possible) BNE 69$ ;if not, skip 68$: INC R0 ;next char. INC $TOP INC $AST ;set asterisk flag BR 115$ 69$: CALL $COTB MOV R1,$TOP BR 120$ 70$: ;/COM check MOV #COMSTR,R4 CMPB (4)+,R5 ;C for common? BNE 80$ ;if not, skip TST $COM ;already speced? BNE STXERR ;if yes, skip MOV #,R3 72$: CALL CHKCOM ;parse command BCS STXERR ;skip if bad 74$: CLR R1 CALL $CAT5 ;convert to RAD50 BCS STXERR MOV R1,$COM CALL $CAT5 ;again convert MOV R1,$COM+2 BCS 75$ ;skip if already have char. in R2 MOVB (0)+,R2 ;next character 75$: CMPB #':,R2 BEQ 76$ ;on : or = we take size CMPB #'=,R2 BNE 120$ ;if neither look for /... 76$: CALL $COTB ;convert desired size MOV R1,$SQZ ;squeeze size BEQ STXERR ;0 is invalid MOV $TOP,-(SP) BIS $PSIZE,(SP)+ BNE STXERR ;either top or size, not allowed MOV $SQZ,$TOP ;for congruence with /TOP=-/COM command NEG $TOP BR 120$ ;continue 80$: MOV #NOCSTR,R4 ;check for NOC= CMPB (4)+,R5 ;N? BNE 90$ ;if not, skip TST $PARNM ;partition already set? BNE STXERR ;if yes, error MOV #NOCLEN-1,R3 ;remaining string length CALL CHKCOM ;ok? BCS STXERR ;if not error MOV $PSIZE,-(SP) ;size or top not allowed BIS $TOP,(SP)+ BNE STXERR ;if either, error INC $TOP ;as it top with... INC $AST ;...asterisk INC $NOC ;flag as removal BR 105$ ;and handle as with partition ; ; /PAR=PNAME ; 90$: DEC R0 ;BACK UP SCAN TST $PARNM ;ALREADY DID /PAR KEYWORD? BNE STXERR ;IF NE YES MOV #PARSTR,R4 ;POINT R4 TO 'PAR' STRING MOV #PARLEN,R3 ;PUT CHARACTER COUNT IN R3 100$: CALL CHKCOM ;parse command BCS STXERR 105$: CALL GETNB ;GET NEXT NON-BLANK CHARACTER BCS STXERR ;IF CS END-OF-LINE DEC R0 ;BACKUP CHARACTER POINTER MOV SP,R1 ;PREPARE TO CONVERT TO RAD50 CALL $CAT5 ;CONVERT NEXT 3 CHARACTERS MOV R1,$PARNM ;STORE RESULT BCS 120$ ;IF CS FEWER THAN 3 CHARS CONVERTED CALL $CAT5 ;CONVERT 3 MORE CHARACTERS MOV R1,$PARNM+2 ;STORE SECOND HALF OF NAME BCS 120$ ;IF CS FEWER THAN 3 CHARS CONVERTED 115$: MOVB (R0)+,R2 ;GET NEXT CHARACTER 120$: TST R2 ;IS THIS THE END-OF-LINE? BEQ PDONE ;IF EQ YES MOV R2,R5 ;PUT CHARACTER WHERE IT IS EXPECTED JMP 29$ ; STXERR: SEC ;RETURN ERROR. RETURN PDONE: TST $COM ;common speced? BEQ 130$ ;if not, skip TST $SQZ ;general find a place? BNE 130$ ;if yes, ok TST $TOP ;must be top=- BEQ STXERR TST $INC BEQ STXERR TST $TOP BGT STXERR 130$: CLC ;success RETURN .SBTTL GETNB - SUBROUTINE TO GET NEXT NON-BLANK CHARACTER ;+ ; ; GETNB - GET NEXT NON-BLANK CHARACTER FROM BUFFER ; GETCHR - GET NEXT CHARACTER FROM BUFFER ; ; INPUTS: ; R0=ADDRESS OF NEXT CHARACTER IN BUFFER ; ; OUTPUTS: ; R0=UPDATED ADDRESS OF NEXT CHARACTER IN BUFFER ; R5=CHARACTER FROM BUFFER ; C-BIT CLEAR IF NOT AT END-OF-LINE ; C-BIT SET IF END-OF-LINE REACHED (R5=0) ; ;- GETNB: CALL GETCHR ;GET NEXT CHARACTER BCS 10$ ;IF CS END-OF-LINE CMPB #40,R5 ;IS THIS A BLANK? BEQ GETNB ;IF EQ GET NEXT CHARACTER CLC ;INDICATE SUCCESS 10$: RETURN ; .SBTTL GETCHR - SUBROUTINE TO GET NEXT CHARACTER GETCHR: SEC ;ASSUME AT END-OF-LINE MOVB (R0),R5 ;GET CHARACTER FROM BUFFER BEQ 20$ ;IF EQ AT END-OF-LINE TSTB (R0)+ ;CLEAR C-BIT AND POINT TO NEXT CHARACTER 20$: RETURN ; ; CHKCOM ; checks for proper command syntax ; assumes first char. already checked ; returns C set if invalid ; ; Entry: ; R4 -> command string ; R0 -> input characters ; R3 length of command ; Exit: ; R0 after = or : ; ; R5 = or : (if C clear) ; R4 munged ; CHKCOM: CALL GETCHR ;next character BCS 50$ ;hit EOF in command CMPB (4)+,R5 ;still eligible? BNE 50$ ;if not, skip DEC R3 BGT CHKCOM ;loop till done CALL GETNB ;next non-blank BCS 50$ CMPB #':,R5 ;: or = are valid here BEQ 10$ CMPB #'=,R5 BNE 50$ ;others are invalid 10$: CLC RETURN ;valid return 50$: SEC ;invalid return RETURN .SBTTL $DIV64 - DIVIDE BY 64 BYTES. ;+ ; **-$DIV64-DIVIDE BY 64 ; ; INPUTS: ; ; R1=NUMBER TO BE DIVIDED ; ; OUTPUTS: ; ; R1=QUOTIENT ;- $DIV64::CLC ; ROR R1 ; ASR R1 ; ASR R1 ; ASR R1 ; ASR R1 ; ASR R1 ; RETURN ; .END