Trailing-Edge
-
PDP-10 Archives
-
decuslib20-07
-
decus/20-0161/parse.mac
There are 11 other files named parse.mac in the archive. Click here to see a list.
;<P.HURLEY.2>PARSE.MAC.2, 27-Jul-79 08:45:02, EDIT BY HURLEY
TITLE PARSE - ROUTINE TO PARSE COMMANDS
ENTRY PARSE
SALL
SEARCH MONSYM,MACSYM,PARUNV
.REQUIRE SYS:MACREL
T1=1
T2=2
T3=3
T4=4
Q1=5
Q2=6
Q3=7
P1=10
P2=11
P3=12
P4=13
P5=14
P6=15
CX=16
P=17
;DEFINITIONS
DEFINE SAVEPQ <
JSP CX,SAVPQ>
DEFINE SAVEP <
JSP CX,SAVP>
;DEFSTR DEFINITIONS
MSKSTR (CMFNC,.CMFNP,CM%FNC) ;COMMAND FUNCTION CODE
MSKSTR (CMLST,.CMFNP,CM%LST) ;ADR OF FUNCTION DESCRIPTOR BLOCK
DEFSTR (CMDAT,.CMDAT,35,36) ;COMMAND DATA
DEFSTR (PDBER,PDB.ER,35,36) ;ERROR MESSAGE ROUTINE ADDRESS
DEFSTR (PDBNX,PDB.NX,35,36) ;ADR OF NEXT PDB
DEFSTR (PDBDF,PDB.DF,35,36) ;ADR OF DEFAULT FILLING ROUTINE
SUBTTL Constant Definitions
NCHPW==5 ;NUMBER OF ASCII CHARACTERS PER WORD
BUFSIZ==200 ;SIZE OF INPUT TEXT BUFFER
ATMSIZ==BUFSIZ ;SIZE OF ATOM BUFFER FOR COMND JSYS
GJFSIZ==.GJRTY+2 ;SIZE OF GTJFN BLOCK USED BY COMND JSYS
FDBSIZ==.CMDEF+2 ;SIZE OF FUNCTION DESCRIPTOR BLOCK
SUBTTL Local Storage
;STORAGE FOR PARSER TO EVENT PROCESSOR COMMUNICATION
ZERBEG==. ;START OF AREA TO BE ZEROED
PARFRE: BLOCK 1 ;POINTER TO FIRST FREE IN COMM BLOCK
ARGFRE: BLOCK 1 ;POINTER TO FIRST FREE WORD IN ARG SPACE
JFNFRE: BLOCK 1 ;IOWD POINTER TO JFN STACK
JFNSTL==40 ;LENGTH OF JFNSTK
JFNSTK: BLOCK JFNSTL ;LIST OF ALL STACKED JFNS
PARBLK: BLOCK 50 ;SPACE FOR COMM BLOCK
ARGBLK: BLOCK 400 ;SPACE FOR ARGUMENTS (ASCIZ, ETC.)
ARGEND==.-1 ;WHERE TO STOP ZEROING
;STORAGE FOR THE PARSER
CMDBLK: BLOCK .CMGJB+5 ;COMMAND STATE BLOCK FOR COMND JSYS
BUFFER: BLOCK BUFSIZ ;INPUT TEXT STORED HERE
ATMBFR: BLOCK ATMSIZ ;ATOM BUFFER FOR COMND JSYS
GJFBLK: BLOCK GJFSIZ ;GTJFN BLOCK FOR COMND JSYS
ZEREND==. ;END OF AREA TO BE ZEROED
SUBTTL Main ROUTINE
;ROUTINE TO PARSE A COMMAND
;ACCEPTS IN T1/ STRING POINTER TO PROMPT
; T2/ POINTER TO THE COMMAND "PDB" CHAIN
; T3/ ADDRESS OF WHERE TO STORE THE PARSED COMMAND
; CALL PARSE
;RETURNS +1: FAILED - COMMAND "PDB" BLOCK DID NOT START WITH A .CMINI
; +2: OK, PARSED COMMAND IS STORED IN BLOCK GIVEN IN T3
; T1/ POINTER TO THE COMMAND STRING
; T2/ FIRST UNUSED WORD IN ANSWER BLOCK
PARSE:: SAVEPQ ;SAVE ALL PERMANENT ACS
STKVAR <PARCMT,PARADR>
MOVEM T2,PARCMT ;SAVE POINTER TO THE COMMAND TABLE
MOVEM T3,PARADR ;SAVE POINTER TO WHERE TO BUILD THE PARAMETER BLOCK
LOAD T4,CMFNC,(T2) ;GET THE FIRST FUNCTION CODE
CAIE T4,.CMINI ;IT MUST BE AN INI FUNCTION
RET ;IF NOT, THEN GIVE ERROR RETURN
;NOW SET UP THE COMMAND STATE BLOCK
MOVE T4,[ZERBEG,,ZERBEG+1]
SETZM ZERBEG ;FIRST ZERO ALL STORAGE USED
BLT T4,ZEREND-1
MOVEM T1,CMDBLK+.CMRTY ;PUT RE-TYPE PROMPT POINTER IN STATE BLOCK
HRROI T1,BUFFER ;GET POINTER TO INPUT TEXT BUFFER
MOVEM T1,CMDBLK+.CMPTR ;SAVE POINTER TO COMMAND STRING
MOVEM T1,CMDBLK+.CMBFP ;SAVE POINTER TO START-OF-BUFFER
MOVE T1,[.PRIIN,,.PRIOU] ;GET PRIMARY INPUT,, OUTPUT JFN'S
MOVEM T1,CMDBLK+.CMIOJ ;SAVE PRIMARY JFN'S
MOVEI T1,REPARS ;GET RE-PARSE ADDRESS
MOVEM T1,CMDBLK+.CMFLG ;SAVE RE-PARSE ADDRESS
SETZM CMDBLK+.CMINC ;INITIALIZE # OF CHARACTERS AFTER POINTER
MOVEI T1,BUFSIZ*NCHPW ;GET # OF CHARACTERS IN BUFFER AREA
MOVEM T1,CMDBLK+.CMCNT ;SAVE INITIAL # OF FREE CHARACTER POSITIONS
HRROI T1,ATMBFR ;GET POINTER TO ATOM BUFFER
MOVEM T1,CMDBLK+.CMABP ;SAVE POINTER TO LAST ATOM INPUT
MOVEI T1,ATMSIZ*NCHPW ;GET # OF CHARACTERS IN ATOM BUFFER
MOVEM T1,CMDBLK+.CMABC ;SAVE COUNT OF SPACE LEFT IN ATOM BUFFER
MOVEI T1,GJFBLK ;GET ADDRESS OF GTJFN BLOCK
MOVEM T1,CMDBLK+.CMGJB ;SAVE IN COMMAND STATE BLOCK
MOVE T1,[IOWD JFNSTL,JFNSTK]
MOVEM T1,JFNFRE ;SET UP POINTER TO JFN STACK
PARSER: MOVEI P1,CMDBLK ;COMND STATE BLOCK
MOVE P2,PARCMT ;INITIAL PDB TO FEED TO COMND
CALL RELJFN ;RELEASE ALL JFNS ON THE STACK
PARS.1: DMOVE T1,P1 ;COPY THE COMND ARGS
COMND ;PARSE NEXT FIELD
ERJMP CMDERR ;ERROR, SEE WHY
TXNN T1,CM%NOP ;VALID COMMAND ENTERED ?
JRST PARS.3 ;YES, GO DISPATCH TO PROCESSING ROUTINE
LOAD P2,PDBER,(P2) ;GET ADDR OF SPECIAL ERROR ROUTINE
JUMPE P2,PARS.2 ;IF NO ROUTINE JUST TYPE COMMAND ERROR
CALL (P2) ;CALL THE ROUTINE
JRST PARSER ;GO TRY TO GET A COMMAND AGAIN
PARS.2: HRROI T1,[ASCIZ/
?COMMAND ERROR: /]
PSOUT
MOVX T1,.PRIOU ;TO PRIMARY OUTPUT
MOVE T2,[.FHSLF,,-1] ;OUR LAST ERROR
ERSTR ;TYPE OUT THE ERROR STRING
JRST [ CALL ERRUEN ;UNDEFINED ERROR NUMBER
JRST PARSER]
JRST [ CALL ERRBDD ;BAD DESTINATION DESIGNATOR
JRST PARSER]
JRST PARSER ;AND TRY AGAIN
;HERE ON SUCCESSFUL PARSE FROM COMMAND JSYS
PARS.3: MOVE P2,T2 ;COPY DATA TO P2
MOVE P4,T3 ;SAVE POINTER TO FUNCTION BLOCK
LOAD P3,CMFNC,(P4) ;GET THE COMMAND FUNCTION CODE
MOVE T1,P3 ;COPY FUNCTION TO T1
MOVE T2,P2 ;AND DATA TO T2
CALL @PARTAB(T1) ;DISPATCH OFF FUNCTION
MOVE T1,P3 ;COPY FUNCTION TO T1
MOVE T2,P2 ;AND DATA TO T2
SKIPE T4,PDB.RT(P4) ;GET SPECIAL ROUTINE ADDRESS FROM PDB
CALL (T4) ;CALL THE SPECIAL ROUTINE IF THERE
HRRZ P2,(P2) ;GET CONTENTS OF RETURNED DATA
LOAD T1,PDBNX,(P4) ;GET NEXT FDB IF ANY
JUMPN T1,PARS.4 ;USE IT IF ONE IS SPECIFIED
CAIE P3,.CMKEY ;KEYWORD
CAIN P3,.CMSWI ;OR SWITCH ?
SKIPA T1,(P2) ;YES, USE DATA IN KEYTAB AS FDB ADR
LOAD T1,PDBNX,(P4) ;NO, GET NEXT FDB FROM CURRENT
JUMPE T1,PARS.5 ;IF NO NEXT PDB, GO BUILD ANSWER
PARS.4: HRRZS P2,T1 ;PASS ONLY RIGHT HALF
CALL FILDEF ;GO FILL IN ANY DEFAULTS NEEDED
JRST PARS.1 ;AND FINISH COMMAND
PARS.5: MOVE T1,PARADR ;GET ADR OF WHERE TO BUILD BLOCK
CALL BLDCOM ;GO BUILD A COMMAND MESSAGE
MOVE T2,T1 ;SAVE FIRST FREE WORD
MOVE T1,[POINT 7,BUFFER] ;RETURN POINTER TO THE COMMAND
RETSKP ;DONE
SUBTTL Routine to Take a Parser Block and Build a Command Message
;ROUTINE TO BUILD THE PARSED BLOCK
;ACCEPTS IN T1/ ADR OF WHERE TO PUT THE BUILT BLOCK
; ASSMUES ALL DATA IS SET UP IN AGRBLK
;RETURNS +1: ALWAYS
; T1/ FIRST UNUSED WORD IN ANSWER BLOCK
BLDCOM: SAVEP ;SAVE NEEDED AC'S
MOVE P1,PARFRE ;COMPUTE LENGTH OF
SUBI P1,PARBLK ;PARSER BLOCK
MOVE P2,ARGFRE ;GET END OF ARG SPACE
SUBI P2,ARGBLK ;COMPUTE LENGTH
MOVE P3,P1 ;TAKE COPY OF PARSER BLOCK LENGTH
MOVNS P1 ;MAKE P1 NEGATIVE FOR AOBJN
HRLS P1 ;MAKE AOBJN POINTER
HRRI P1,PARBLK ;POINT TO PARBLK (PARSER DATA BLOCK)
BLDC.1: MOVE T4,(P1) ;GET DATA
HLRZ Q1,T4 ;GET CODE
CAIE Q1,.CMSWI ;SWITCH?
CAIN Q1,.CMKEY ;OR KEYWORD?
JRST BLDC.2 ;YES, NO OFFSET NEEDED
CAIE Q1,.CMCFM ;CONFIRM?
CAIN Q1,.CMCMA ;OR COMMA?
JRST BLDC.2 ;YES, NO OFFSET NEEDED
ADD T4,P3 ;ADD IN OFFSET
BLDC.2: MOVEM T4,(T1) ;COPY TO IPCF PAGE
ADDI T1,1 ;INCREMENT IPCF PAGE POINTER
AOBJN P1,BLDC.1 ;LOOP FOR ALL
MOVNS P2 ;GET NEGATIVE LENGTH OF DATA AREA
HRLZS P2 ;MAKE AN AOBJN POINTER
BLDC.3: MOVE T4,ARGBLK(P2) ;GET CURRENT WORD INTO T4
MOVEM T4,(T1) ;SAVE IN MESSAGE BEING BUILT
ADDI T1,1 ;INCREMENT POINTER TO MESSAGE
AOBJN P2,BLDC.3 ;AND STEP THRU DATA AREA
RET ;AND RETURN
SUBTTL Routine to Set Up for COMND Reparse
;THIS ROUTINE IS GOTTEN TO BY THE COMND JSYS CHANGING THE PC WHEN
;A USER RUBS OUT ACROSS A FIELD. IT JUST CLEARS OUT THE TEMPORARY
;STORAGE USED BY COMND AND RESTARTS THE PARSER
REPARS: CALL RELJFN ;RELEASE ALL JFNS SO FAR
CALL @.CMINI+PARTAB ;TELL SAVE ROUTINES TO FORGET IT
MOVE T1,[GJFBLK,,GJFBLK+1] ;SET UP TO CLEAR GTJFN BLOCK
SETZM GJFBLK ;CLEAR FIRST WORD
BLT T1,GJFBLK+GJFSIZ-1 ;CLEAR THE BLOCK
MOVEI P1,CMDBLK ;GET STATE BLOCK ADDRESS
MOVE P2,PARCMT ;GET INITIAL COMMAND TABLE POINTER
LOAD P2,PDBNX,(P2) ;STEP TO BLOCK AFTER .CMINI
JRST PARS.1 ;JUST RESTART PARSER
;ROUTINE TO RELEASE ALL JFNS STACKED SO FAR
RELJFN: MOVSI T4,JFNSTL ;SET UP AN AOBJN POINTER TO JFN STACK
RELJFL: SKIPE T1,JFNSTK(T4) ;IS THERE A JFN HERE?
RLJFN ;YES, RELEASE IT
JFCL
SETZM JFNSTK(T4) ;ZERO THE STACK
AOBJN T4,RELJFL ;LOOP BACK FOR ALL OF THEM
MOVE T1,[IOWD JFNSTL,JFNSTK]
MOVEM T1,JFNFRE ;INIT STACK POINTER
RET ;DONE
SUBTTL Routine To Fill in Defaults for COMND
;ROUTINE TO FILL IN DEFAULTS IF NEEDED
;CALLED WITH P2 POINTING TO PDB ABOUT TO BE FED TO COMND
;FILLS IN ALL DEFAULTS FOR THE NEXT SET OF LINKED PDB'S
FILDEF: MOVE T1,P2 ;COPY THE PDB ADDRESS
FILD.1: LOAD T2,PDBDF,(T1) ;GET THE ADDR OF THE DEFAULT FILLING ROUTINE
JUMPE T2,FILD.2 ;NONE THERE, LOOK FOR LINKED PDB'S
PUSH P,T1 ;SAVE ADR OF PDB
CALL (T2) ;CALL THE DEFAULT FILLER
POP P,T1
FILD.2: LOAD T1,CMLST,(T1) ;GET THE ADDR OF NEXT PDB IN LIST
JUMPN T1,FILD.1 ;LOOP IF THERE IS ONE
RET ;AND RETURN
;CMDERR - ROUTINE TO PROCESS ERRORS ON EXECUTING A COMND JSYS
; IF END OF FILE REACHED ON A TAKE FILE, THE NEXT COMMAND
; IS SIMPLY PROCESSED. ELSE AN ERROR MESSAGE IS ISSUED AND
; THE PROGRAM IS RESTARTED.
;
;CALL: JRST CMDERR
CMDERR: HRROI T1,[ASCIZ/
?COMMAND ERROR: /]
PSOUT
MOVX T1,.PRIOU ;TO PRIMARY OUTPUT
MOVE T2,[.FHSLF,,-1] ;OUR LAST ERROR
ERSTR ;TYPE OUT THE ERROR STRING
JRST [ CALL ERRUEN ;UNDEFINED ERROR NUMBER
JRST PARSER]
JRST [ CALL ERRBDD ;BAD DESTINATION DESIGNATOR
JRST PARSER]
JRST PARSER ;GO START OVER AGAIN
SUBTTL ERROR ROUTINES
BADCOM:: HRROI T1,[ASCIZ/
?INVALID COMMAND "/]
PSOUT
HRROI T1,ATMBFR
PSOUT
HRROI T1,[ASCIZ/" /]
PSOUT
RET
BADIFI:: MOVX T1,GJ%OFG ;PARSE-ONLY GTJFN
MOVEM T1,GJFBLK+.GJGEN ;IN FLAGS WORD
MOVE T1,[XWD .NULIO,.NULIO] ;SUPPLY NO JFNS
MOVEM T1,GJFBLK+.GJSRC ;INTO BLOCK
MOVEI T1,GJFBLK ;GTJFN BLOCK ADDRESS
HRROI T2,ATMBFR ;STRING POINTER TO ATOM BUFFER
GTJFN ;GET A JFN
JRST BADI.1 ;JUST DO THE ERSTR
HRROI T1,[ASCIZ/
?CAN'T FIND FILE "/]
PSOUT
HRRZ T2,T1 ;MOVE JFN TO T2 FOR JFNS
MOVEI T1,.PRIOU ;TO PRIMARY OUTPUT
MOVE T3,[111100,,1] ;GET OUT EVERYTHING UP TO THE PROTECTION
JFNS ;MAKE THE JFN INTO A STRING
HRROI T1,[ASCIZ/"
/]
PSOUT
BADI.1: MOVX T1,.PRIOU ;TO PRIMARY OUTPUT
MOVE T2,[.FHSLF,,-1] ;OUR LAST ERROR
ERSTR ;TYPE OUT THE ERROR STRING
CALLRET ERRUEN ;UNDEFINED ERROR NUMBER
CALLRET ERRBDD ;BAD DESTINATION DESIGNATOR
RET
;ERSTR JSYS FAILURE ROUTINES
ERRBDD: SKIPA T1,[-1,,[ASCIZ/ERSTR Jsys Failure, Bad Destination Designator/]]
ERRUEN: HRROI T1,[ASCIZ/ERSTR Jsys Failure, Undefined Error Number/]
PSOUT
RET
SUBTTL Dispatch for Parser Save Routines
COMMENT \
THE ROUTINES ON THE NEXT FEW PAGES SAVE THE OUTPUT OF THE PARSER IN
A FORM USABLE BY THE EVENT PROCESSOR. THE ACTUAL DATA STRUCTURE IS
DOCUMENTED IN PARSER.RNO
\
;THIS IS THE DISPATCH TABLE FOR THE VARIOUS SAVE ROUTINES, ONE FOR
;EACH TYPE OF FIELD THE COMND JSYS CAN PARSE. THESE ROUTINES ARE CALLED
;ON EACH SUCCESSFUL RETURN FROM THE COMND JSYS
;ALL THESE ROUTINES ARE CALLED WITH T1 CONTAINING THE COMND FUNCTION CODE
;USED TO PARSE THE LAST FIELD AND T2 CONTAINING THE DATA RETURNED BY COMND
;T3 MUST CONTAIN THE ADDRESS OF THE FDB USED BY COMND TO PARSE THE FIELD
PARTAB: SAVIND ;KEYWORD (.CMKEY)
SAVNUM ;NUMBER (.CMNUM)
R ;NOISE WORD (.CMNOI) (NO PROCESSING)
SAVIND ;SWITCH (.CMSWI)
SAVJFN ;INPUT FILE SPEC (.CMIFI)
SAVJFN ;OUTPUT FILE SPEC (.CMOFI)
SAVJFN ;GENERAL FILE SPEC (.CMFIL)
SAVATM ;ARBITRARY FIELD (.CMFLD)
SAVZER ;CONFIRM (.CMCFM)
SAVRSS ;DIRECTORY (.CMDIR)
SAVRSS ;USER NAME (.CMUSR)
SAVZER ;COMMA (.CMCMA)
SAVINI ;INITIALIZATION (.CMINI)
;THIS IS CALLED TO INITIALIZE SAVE STUFF
SAVRES ;FLOATING POINT NUMBER (.CMFLT)
SAVRES ;DEVICE NAME (.CMDEV)
SAVATM ;TEXT TO CARRAIGE RETURN (.CMTXT)
SAVRES ;DATE AND TIME (.CMTAD)
SAVATM ;QUOTED STRING (.CMQST)
R ;***RET FOR NOW***;UNQUOTED STRING (.CMUQS)
SAVTOK ;TOKEN (.CMTOK)
SAVNUM ;NUMBER (ARBITRARY TERMINATOR) (.CMNUX)
R ;(.CMACT)
SAVATM ;NODE NAME(.CMNOD)
SUBTTL Save Routines
;DATA RETURNED IS A POINTER INTO A TABLE (SWITCH OR KEYWORD)
SAVIND: HRRZ T2,(T2) ;GET INDIRECT ADDRESS
LOAD T4,PDBNX,(T3) ;GET THE NEXT FDB FROM THIS ONE
SKIPN T4 ;IF ONE THERE, STORE ADDRESS INSTEAD
HLRZ T2,(T2) ;FETCH CODE SET UP BY KEYTAB MACRO
JRST MAKENT ;AND MAKE THE ENTRY
;SAVE ROUTINES FOR FUNCTIONS WHICH COPY VALUE TO ATOM BUFFER
;(.CMFLD, .CMTXT, .CMQST)
SAVATM: SAVEP ;SAVE NEEDED REGS
MOVE T2,ARGFRE ;GET FIRST FREE ARG LOCATION
HRLI T2,(POINT 7,) ;MAKE T2 A BYTE POINTER
MOVE P1,[POINT 7,ATMBFR] ;POINT AT THE ATOM BUFFER
SAVA.1: ILDB P2,P1 ;GET A CHARACTER FROM THE ATOM BUFFER
IDPB P2,T2 ;SAVE IT IN THE ARGUMENT SPACE
JUMPN P2,SAVA.1 ;AND LOOP IF MORE
HRRZI T2,1(T2) ;STEP TO NEXT LOC AND CLEAR LH
EXCH T2,ARGFRE ;STORE NEXT FREE AND GET FIRST USED
SUBI T2,ARGBLK ;CONVERT TO RELATIVE ADDRESS
JRST MAKENT ;AND MAKE THE ENTRY
;SAVE A ZERO (CONFIRM OR COMMA, FUNCTION TELLS ALL)
SAVZER: SETZ T2, ;JUST A ZERO
JRST MAKENT ;GO MAKE AN ENTRY
;SAVE ROUTINE FOR NUMBERS
SAVNUM: SAVEP ;SAVE AN AC
LOAD P1,CMDAT,(T3) ;GET THE RADIX USED
DPB P1,[POINT 9,T1,26] ;SAVE IT WITH FUNCTION
;AND FALL INTO SAVRES
;ROUTINE TO STACK A JFN
SAVJFN: MOVE T4,JFNFRE ;GET POINTER TO JFN STACK
PUSH T4,T2 ;STACK THE JFN
MOVEM T4,JFNFRE ;STORE THE UPDATED STACK POINTER
JRST SAVRES ;GO SAVE THE JFN IN THE ANSWER BLOCK
;SAVE ROUTINES WHICH SAVE A POINTER TO WHAT COMND RETURNS IN AC2
;(FLOATING NUMBER, DATE/TIME, DEVICE, FILE SPECS)
SAVRES: SAVEP ;SAVE A WORKING REG
MOVE P1,ARGFRE ;GET THE NEXT FREE ARG BLOCK WORD
MOVEM T2,(P1) ;SAVE THE RESULT OF COMND THERE
MOVE T2,P1 ;GET ADDR USED INTO T2
SUBI T2,ARGBLK ;MAKE IT THE OFFSET INTO ARGBLK
AOS ARGFRE ;STEP FREE LOC UP ONE
JRST MAKENT ;AND GO MAKE THE ENTRY
;ROUTINE TO SAVE ANSWER AND ATOM BUFFER
;(USER, DIRECTORY)
SAVRSS: SAVEP ;SAVE A WORKING REG
MOVE P1,ARGFRE ;GET THE NEXT FREE ARG BLOCK WORD
MOVEM T2,(P1) ;SAVE THE RESULT OF COMND THERE
AOS T2,ARGFRE ;STEP FREE LOC UP ONE
HRLI T2,(POINT 7,) ;MAKE T2 A BYTE POINTER
MOVE P1,[POINT 7,ATMBFR] ;POINT AT THE ATOM BUFFER
SAVR.1: ILDB P2,P1 ;GET A CHARACTER FROM THE ATOM BUFFER
IDPB P2,T2 ;SAVE IT IN THE ARGUMENT SPACE
JUMPN P2,SAVR.1 ;AND LOOP IF MORE
HRRZI T2,1(T2) ;STEP TO NEXT LOC AND CLEAR LH
EXCH T2,ARGFRE ;STORE NEXT FREE AND GET FIRST USED
SUBI T2,ARGBLK+1 ;CONVERT TO RELATIVE ADDRESS
JRST MAKENT ;AND MAKE THE ENTRY
;SAVE A TOKEN
SAVTOK: SAVEP ;SAVE SOME WORKING SPACE
MOVE T2,ARGFRE ;GET SPACE TO STORE ARG TO T2
HRLI T2,(POINT 7,) ;MAKE IT A BYTE POINTER
LOAD P2,CMDAT,+PDB.FD(T2) ;GET THE DATA USED BY COMND
HRLI P2,(POINT 7,) ;MAKE IT A BYTE POINTER
SAVT.1: ILDB P1,P2 ;GET A CHARACTER
IDPB P1,T2 ;AND SAVE IT AWAY
JUMPN P1,SAVT.1 ;LOOP IF NOT DONE
HRRZI T2,1(T2) ;POINT T2 TO FIRST FREE LOC
EXCH T2,ARGFRE ;AND CHANGE IT WITH FIRST USED
SUBI T2,ARGBLK ;CONVERT TO RELATIVE ADDRESS
JRST MAKENT ;AND GO MAKE ENTRY
SUBTTL Initialization for Parser Save Routines
;THIS ROUTINE IS CALLED TO INITIALIZE THE SAVE ROUTINES FOR THE PARSER
;IT IS THE FUNCTION DEPENDENT ROUTINE FOR THE .CMINI FUNCTION
SAVINI: MOVEI T1,ARGBLK ;GET THE ADDRESS OF THE ARGUMENT STORAGE
MOVEM T1,ARGFRE ;SAVE AS FIRST FREE PLACE TO SAVE STUFF
MOVEI T1,PARBLK ;GET ADDRESS OF PARSER COMMUNICATIONS BLOCK
MOVEM T1,PARFRE ;SAVE AS FIRST FREE LOC IN THAT BLOCK
MOVE T1,[PARBLK,,PARBLK+1] ;GET START OF BLOCK TO CLEAR
SETZM (T1) ;CLEAR FIRST WORD
BLT T1,ARGEND ;CLEAR TO END OF ARGUMENT SPACE
RET ;AND RETURN
SUBTTL MAKENT -- Routine To Make an Entry for Parser Save Routines
;THIS ROUTINE IS CALLED WITH T2 CONTAINING WHAT WILL BE THE RIGHT HALF
;OF THE ENTRY AND T1 CONTAINING THE LEFT HALF.
MAKENT: HRRZM T2,@PARFRE ;SAVE THE RIGHT HALF
HRLM T1,@PARFRE ;SAVE THE LEFT HALF
AOS PARFRE ;UPDATE THE FREE POINTER
RET ;RETURN
;SUPPORT ROUTINES
SAVPQ: PUSH P,Q1
PUSH P,Q2
PUSH P,Q3
PUSH P,P1
PUSH P,P2
PUSH P,P3
PUSH P,P4
PUSH P,P5
PUSH P,P6
CALL 0(CX)
SKIPA
AOS -11(P)
POP P,P6
POP P,P5
POP P,P4
POP P,P3
POP P,P2
POP P,P1
POP P,Q3
POP P,Q2
POP P,Q1
RET
SAVP: PUSH P,P1
PUSH P,P2
PUSH P,P3
PUSH P,P4
PUSH P,P5
PUSH P,P6
CALL 0(CX)
SKIPA
AOS -6(P)
POP P,P6
POP P,P5
POP P,P4
POP P,P3
POP P,P2
POP P,P1
RET
END