Trailing-Edge
-
PDP-10 Archives
-
cuspbinsrc_1of2_bb-x128c-sb
-
10,7/galaxy/batcon/batctl.mac
There are 3 other files named batctl.mac in the archive. Click here to see a list.
TITLE BATCTL - GALAXY-10 Batch controller control file logic
SUBTTL C.D.O'Toole, D.P.Mastrovito /CDO/DPM 27-Jul-87
;
;
; COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1986,1987.
; ALL RIGHTS RESERVED.
;
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE
; AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS
; SOFTWARE OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR
; OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO
; AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE
; WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT
; BY DIGITAL EQUIPMENT CORPORATION.
;
; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
; OF ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY
; DIGITAL.
SEARCH BATMAC ;BATCON SYMBOLS
SEARCH GLXMAC ;GALAXY SYMBOLS
SEARCH QSRMAC ;QUASAR SYMBOLS
SEARCH ORNMAC ;ORION SYMBOLS
PROLOG (BATCTL) ;SET UP
%%.BAT==:%%.BAT ;FORCE VERSION INTO SYMBOL TABLE
TOPS10 <IF1,<PRINTX [Assembling GALAXY-10 BATCTL]>>
TOPS20 <IF1,<PRINTX [Assembling GALAXY-20 BATCTL]>>
.TEXT |,OPRPAR/SEGMENT:LOW| ;LOAD THE GALAXY PARSER
GLOB <JIBTXT>
SUBTTL Table of contents
; TABLE OF CONTENTS FOR BATCTL
;
;
; SECTION PAGE
; 1. Table of contents......................................... 2
; 2. Batch step header parse tables............................ 3
; 3. Batch step header command scanner......................... 4
; 4. Batch step header commands
; 4.1 $ACCOUNT.......................................... 5
; 4.2 Simple keywords................................... 6
; 4.3 $TIME............................................. 7
; 4.4 $ALLOCATE and $MOUNT.............................. 8
; 4.5 $ENDHDR........................................... 9
; 4.6 $STEP............................................. 10
; 5. C$SCAN - Command scanner.................................. 11
; 6. Label logic............................................... 12
; 7. Comment/Vertical motion/User/DDT mode..................... 15
; 8. RDNMOD - Random first character checking.................. 16
; 9. Monitor mode.............................................. 17
; 10. Batch step mode........................................... 18
; 11. C$OPEN - Open the control file............................ 19
; 12. Control file positioning routines......................... 21
; 13. C$DISP - Dispose of control file at EOJ................... 22
; 14. C$CLOS - Close control file............................... 23
; 15. C$READ - Read a line from the control file................ 24
; 16. C$STRT - Find the starting point in the control file...... 25
; 17. C$COPY - Re-copy a command line........................... 26
; 18. Miscellaneous scanner routines............................ 28
; 19. Batch command set up and dispatching...................... 29
; 20. Macros to generate Batch command tables................... 30
; 21. Batch command tables...................................... 31
; 22. Batch commands
; 22.1 ABORT and STATUS.................................. 32
; 22.2 BACKTO and GOTO................................... 33
; 22.3 CHKPNT and REQUEUE................................ 34
; 22.4 DUMP.............................................. 35
; 22.5 ERROR and OPERATOR................................ 37
; 22.6 IF................................................ 38
; 22.7 MESSAGE and PLEASE................................ 42
; 22.8 NOERROR, NOOPERATOR, REVIVE, and SILENCE.......... 43
; 23. MOUNT parser
; 23.1 ALLOCATE and MOUNT command syntax tables.......... 44
; 23.2 MOUNT and ALLOCATE option tables.................. 45
; 23.3 General routines.................................. 56
; 23.4 Data Storage...................................... 61
; 24. End....................................................... 62
SUBTTL Batch step header parse tables
JSP010: $INIT (JSP020)
JSP020: $KEYDSP (JSP030)
JSP030: $STAB
IFN FTMODIFY,< DSPTAB (ACC010,$ACCT,<ACCOUNT>)>
TOPS10 < DSPTAB (ALL010,$ALLOCATE,<ALLOCATE>)>
TOPS20 < DSPTAB (,$ALLOCATE,<ALLOCATE>)>
;IFN FTMODIFY,< DSPTAB (ASS010,$ASSIST,<ASSISTANCE>)>
;IFN FTMODIFY,< DSPTAB (BAT010,$BATLOG,<BATLOG>)>
DSPTAB (END010,$ENDHDR,<ENDHDR>)
TOPS10 < DSPTAB (MOU010,$MOUNT,<MOUNT>)>
TOPS20 < DSPTAB (,$MOUNT,<MOUNT>)>
IFN FTMODIFY,< DSPTAB (OUT010,$OUTPUT,<OUTPUT>)>
IFN FTMODIFY,< DSPTAB (RES010,$RESTART,<RESTART>)>
DSPTAB (STP010,$STEP,<STEP>)
IFN FTMODIFY,< DSPTAB (TIM010,$BTIME,<TIME>)>
IFN FTMODIFY,< DSPTAB (UNI010,$UNIQUE,<UNIQUE>)>
$ETAB
ACC010: $ACCOU (ACC020,,)
ACC020: $CRLF
END010: $CRLF
STP010: $FIELD (STP020,,)
STP020: $CRLF
ASS010: $KEY (ASS030,ASS020)
ASS020: $STAB
KEYTAB (.OPINN,<NO>)
KEYTAB (.OPINY,<YES>)
$ETAB
ASS030: $CRLF
BAT010: $KEY (BAT030,BAT020)
BAT020: $STAB
KEYTAB (%BAPND,<APPEND>)
KEYTAB (%BSPOL,<SPOOL>)
KEYTAB (%BSCDE,<SUPERSEDE>)
$ETAB
BAT030: $CRLF
OUT010: $KEY (OUT030,OUT020)
OUT020: $STAB
KEYTAB (%EQOLE,<ERROR>)
KEYTAB (%EQOLG,<LOG>)
KEYTAB (%EQONL,<NOLOG>)
$ETAB
OUT030: $CRLF
RES010: $KEY (RES030,RES020)
RES020: $STAB
KEYTAB (%EQRNO,<NO>)
KEYTAB (%EQRYE,<YES>)
$ETAB
RES030: $CRLF
TIM010: $TIME (TIM020)
TIM020: $CRLF
UNI010: $KEY (UNI030,UNI020)
UNI020: $STAB
KEYTAB (%EQUNO,<NO>)
KEYTAB (%EQUYE,<YES>)
$ETAB
UNI030: $CRLF
SUBTTL Batch step header command scanner
C$STEP::AOS .JSSTP(R) ;COUNT THE LINE
$IDENT (HEADER,<^T/.JSCTL(R)/^A>) ;YES - ECHO STEP HEADER LINE
ILDB S1,.JSCTB(R) ;GET THE FIRST CHARACTER
CAIE S1,";" ;OLD STYLE COMMENT?
CAIN S1,"!" ;NEW STYLE COMMENT?
$RETT ;YES TO EITHER - RETURN SUCESSFUL
MOVEI S1,JSP010 ;GET ADDRESS OF PARSE TABLES
MOVEM S1,.JSPAR+PAR.TB(R) ;STORE IT
MOVE T1,.JSCMD(R) ;GET ADDRESS OF COMMAND BLOCK
MOVEM T1,.JSPAR+PAR.CM(R) ;STORE IT
SETZM (T1) ;CLEAR THE FIRST WORD FO THE BLOCK
HRLZI S1,(T1) ;BUILD BLT POINTER
HRRI S1,1(T1) ;SO WE CAN CLEAR THE ENTIRE BLOCK
BLT S1,PAGSIZ-1(T1) ;ZAP THE COMMAND BLOCK
MOVX S1,COM.SZ-1 ;GET INITIAL SIZE OF MESSAGE
HRLZM S1,.MSTYP(T1) ;STORE IT
MOVE S1,.JSCTB(R) ;GET THE BUFFER POINTER
MOVEM S1,.JSPAR+PAR.SR(R) ;TELL THE PARSER
SETZB S1,S2 ;NO TIMER INTERRUPTS
PUSHJ P,P$INIT## ;INIT THE PARSER
MOVX S1,PAR.SZ ;GET LENGTH OF PARSE BLOCK
MOVEI S2,.JSPAR(R) ;GET ADDRESS OF PARSE BLOCK
PUSHJ P,PARSER## ;PARSE THE COMMAND
JUMPF STEP.E ;ANY ERRORS?
MOVE T1,.JSCMD(R) ;GET COMMAND BLOCK ADDRESS
MOVEI S1,COM.SZ(T1) ;POINT OT THE FIRST BLOCK
PUSHJ P,P$SETU## ;SETUP TO EAT THE PARSE BLOCKS
PUSHJ P,P$KEYW## ;GET THE PARAMETER KEYWORD
JUMPF STEP.E ;ANY ERRORS?
PUSHJ P,(S1) ;DISPATCH
$RET ;PROPAGATE TRUE/FALSE RETURN BACK
STEP.E: TXO R,RL.JIE ;SET JOB IN ERROR
$IDENT (BATSSE,<? Step header syntax error - ^T/@PRT.EM(S2)/>)
$RETF ;RETURN UNSUCESSFUL
SUBTTL Batch step header commands -- $ACCOUNT
$ACCT: SKIPN .JLSTP(R) ;WAS $STEP SEEN?
$RETF ;NO
SKIPN .JBSPS(R) ;DOING ONLY A STEP HEADER SCAN?
$RETT ;NO - THEN NOTHING TO DO
PUSHJ P,B$MODP## ;SET UP MODIFY PAGE
MOVEI P1,.MQACT(S1) ;POINT TO START OF ACCOUNT BLOCK
HRLZI S1,(P1) ;GET SOURCE ADDRESS
HRRI S1,1(P1) ;+1
SETZM (P1) ;CLEAR FIRST WORD
BLT S1,7(P1) ;CLEAR ENTIRE ACCOUNT STRING BLOCK
PUSHJ P,P$ACCT## ;GET AN ACCOUNT STRING
$RETIF ;RETURN IF WE COULDN'T
MOVEI S1,ARG.DA(S1) ;POINT TO THE ACCOUNT STRING
HRLI S1,(P1) ;GET DESTINATION ADDRESS ON LH
MOVSS S1 ;MAKE A BLT POINTER
ADDI S2,-ARG.DA(P1) ;COMPUTE END ADDRESS
BLT S1,-1(S2) ;COPY INTO MODIFY BLOCK
MOVEI P2,.JQACT(R) ;GET ADDRESS OF ACCOUNT STRING IN THE EQ
MOVEI S1,10 ;SET UP A COUNTER
ACCT.1: MOVE S2,(P1) ;GET A WORD
CAME S2,(P2) ;THE SAME?
JRST ACCT.2 ;NO - CHANGE THE COUNT
ADDI P1,1 ;+1
ADDI P2,1 ;+1
SOJG S1,ACCT.1 ;LOOP FOR ALL WORDS
$RETT ;Return
ACCT.2: AOS .JMODC(R) ;INDICATE NEED FOR MODIFY
$RETT ;RETURN
SUBTTL Batch step header commands -- Simple keywords
$ASSIST:MOVEI P1,.MQAST
MOVE P2,[GETLIM S2,.JQLIM(R),OINT]
PJRST STPKEY
$BATLOG:MOVEI P1,.MQBLG
MOVE P2,[GETLIM S2,.JQLIM(R),BLOG]
PJRST STPKEY
$OUTPUT:MOVEI P1,.MQOUT
MOVE P2,[GETLIM S2,.JQLIM(R),OUTP]
PJRST STPKEY
$RESTART:MOVEI P1,.MQRST
MOVE P2,[GETLIM S2,.JQLIM(R),REST]
PJRST STPKEY
$UNIQUE:MOVEI P1,.MQUNI
MOVE P2,[GETLIM S2,.JQLIM(R),UNIQ]
PJRST STPKEY
;CALL:
; P1/ modify page offset
; P2/ instruction to XCT to load old value into S2
; PUSHJ P,STPKEY
STPKEY: SKIPN .JLSTP(R) ;WAS $STEP SEEN?
$RETF ;NO
SKIPN .JBSPS(R) ;DOING ONLY A STEP HEADER SCAN?
$RETT ;NO - THEN NOTHING TO DO
PUSHJ P,B$MODP## ;SET UP MODIFY PAGE
ADDI P1,(S1) ;ADD IN BASE PAGE
PUSHJ P,P$KEYW## ;GET A KEYWORD
$RETIF ;RETURN IF WE COULDN'T
XCT P2 ;LOAD THE VALUE
CAMN S2,S1 ;SEE IF DIFERENT
$RETT ;NO CHANGE
MOVEM S1,(P1) ;YES--STORE NEW VALUE
AOS .JMODC(R) ;INDICATE NEED FOR MODIFY
$RETT ;RETURN
SUBTTL Batch step header commands -- $TIME
$BTIME: SKIPN .JLSTP(R) ;WAS $STEP SEEN?
$RETF ;NO
SKIPN .JBSPS(R) ;DOING ONLY A STEP HEADER SCAN?
$RETT ;NO - THEN NOTHING TO DO
PUSHJ P,B$MODP## ;SET UP MODIFY PAGE
MOVEI P1,.MQTIM(S1) ;SAVE POINTER TO TIME
PUSHJ P,P$TIME## ;GET A TIME
$RETIF ;RETURN IF WE COULDN'T
TLZ S1,-1 ;REMOVE DATE PART
MUL S1,[^D24*^D60*^D60*^D1000];CONVERT
ASHC S1,^D17 ;POSITION
IDIVI S1,^D1000 ;MAKE SECONDS
CAIL S2,^D500 ;NEED TO ROUND?
ADDI S1,1 ;YES!
GETLIM S2,.JQLIM(R),TIME ;GET TIME
CAMN S2,S1 ;SEE IF DIFERENT
$RETT ;NO CHANGE
MOVEM S1,(P1) ;YES--STORE NEW VALUE
AOS .JMODC(R) ;INDICATE NEED FOR MODIFY
$RETT ;RETURN
SUBTTL Batch step header commands -- $ALLOCATE and $MOUNT
$ALLOCATE:
TOPS10 <SKIPA P1,[.ALLOC]> ;ALLOCATE ROUTINE ADDRESS
$MOUNT:
TOPS10 <MOVEI P1,.MOUNT> ;MOUNT ROUTINE ADDRESS
SKIPE G$MDA## ;MDA TURNED ON?
JRST MOUN.1 ;YES
$IDENT (BATMDF,<[Mountable device facilities not supported - line ignored]>)
$RETT ;RETURN
MOUN.1: SKIPN .JLSTP(R) ;WAS $STEP SEEN?
$RETF ;NO
SKIPN .JBSPS(R) ;DOING ONLY A STEP HEADER SCAN?
JRST MOUN.3 ;NO - SEND MDA REQUEST TO THE PTY
PUSHJ P,B$MDAP## ;GET MDA PAGE IF WE NEED ONE
$CALL M%GPAG ;GET A TEMPORARY PAGE FOR MNTPAR TO USE
MOVEM S1,.JMDAT(R) ;STORE PAGE ADDRESS FOR LATER
PUSHJ P,(P1) ;DO SOMETHING WITH THE ARGUMENTS
SKIPT ;ANY ERRORS?
JRST [MOVE S1,.JMDAT(R) ;GET TEMPORARY PAGE ADDRESS
$CALL M%RPAG ;REMOVE THE PAGE
$RETF] ;RETURN UNSUCESSFUL
MOVE T1,.JMDAP(R) ;GET MDA PAGE BASE ADDRESS
MOVE T2,.JMDAF(R) ;GET MDA PAGE FIRST FREE POINTER
MOVE T3,.JMDAT(R) ;GET MNTPAR TEMPORARY PAGE ADDRESS
LOAD S1,.MSTYP(T3),MS.CNT ;GET LENGTH OF THIS MESSAGE
SUBX S1,.MMHSZ ;STRIP OFF THE MOUNT MESSAGE HEADER
LOAD S2,.MSTYP(T1),MS.CNT ;GET LENGTH OF THIS MESSAGE SO FAR
ADDI S2,(S1) ;GET NEW TOTAL LENGTH
CAXG S2,PAGSIZ ;WILL IT FIT IN A PAGE?
JRST MOUN.2 ;YES
$IDENT (BATTMM,<? Too may ALLOCATE/MOUNT requests to process>)
$RETF ;RETURN UNSUCESSFUL
MOUN.2: STORE S2,.MSTYP(T1),MS.CNT ;STORE NEW TOTAL LENGTH
HRLI S2,.MMHSZ(T3) ;MOVE FROM FIRST ME IN MNTPAR PAGE
HRRI S2,(T2) ;TO FIRST FREE IN MDA PAGE
ADDI T2,(S1) ;COMPUTE NEW FIRST FREE ADDRESS
MOVEM T2,.JMDAF(R) ;REMEMBER NEW FIRST FREE LOCATION
BLT S2,-1(T2) ;MOVE DATA TO MDA PAGE
LOAD S2,.MMARC(T3) ;GET THE NUMBER OF ME'S IN THIS LINE
ADDM S2,.MMARC(T1) ;UPDATE MDA PAGE
MOVE S1,T3 ;GET ADDRESS OF TEMPORARY PAGE
$CALL M%RPAG ;REMOVE PAGE
$RETT ;RETURN SUCESSFUL
MOUN.3: PUSHJ P,B$RTYO## ;ECHO THE RESPONSE BUFFER
PUSHJ P,B$SETB## ;RESET THE BYTE POINTER
ILDB S1,.JSCTB(R) ;EAT THE STEP PROMPT CHARACTER
PUSHJ P,B$XFER## ;TRANSFER THE LINE TO THE PTY
PUSHJ P,IOWAIT## ;GET RESPONSE
$RETT ;RETURN SUCESSFUL
; Dummy routines to keep MNTPAR happy
;
CHKMNT::
HELPER::
ERROR:: $RETF
SUBTTL Batch step header commands -- $ENDHDR
$ENDHDR:
SKIPN .JLSTP(R) ;WAS $STEP SEEN?
$RETF ;NO
POP P,(P) ;TRIM STACK
$IDENT (HEADER,<[^D/.JSSTP(R)/ lines processed in step ^W/.JLSTP(R)/ header]>)
TXO R,RL.DRT ;DELAY THE RESPONSE BUFFER OUTPUT
PUSHJ P,B$EOJ## ;PROCESS END OF JOB (STEP) HEADER
$RETT ;RETURN
SUBTTL Batch step header commands -- $STEP
$STEP: SKIPE .JLSTP(R) ;WAS $STEP ALREADY SEEN?
JRST STPE.0 ;YES - CAN'T HAVE THAT
PUSHJ P,P$SIXF## ;RETURN A SIXBIT VALUE
JUMPF STPE.1 ;ERROR?
JUMPE S1,STPE.1 ;MAKE SURE WE HAVE ONE
MOVEM S1,.JLSTP(R) ;STORE STEP LABEL
LSH S1,-^D30 ;RIGHT JUSTIFY THE FIRST CHARACTER
CAIN S1,'%' ;IS IT A RESERVED LABEL?
JRST STPE.2 ;YES - CAN'T HAVE THAT
PUSHJ P,P$CFM## ;GET CONFIRMATION
JUMPF STPE.3 ;ERROR?
SKIPN .JBSPS(R) ;SKIP IF ONLY STEP HEADER SCAN
$WTOJ (<Starting step ^W/.JLSTP(R)/>,<^R/.JQJBB(R)/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
$RETT ;RETURN SUCESSFUL
STPE.0: $IDENT (BATMSI,<? Multiple $STEP lines illegal in a single step>)
$RETF ;RETURN UNSUCESSFUL
STPE.1: $IDENT (BATMSL,<? Missing $STEP label>)
SETOM .JLSTP(R) ;FAKE OUT ERROR RECOVERY CODE
$RETF ;RETURN UNSUCESSFUL
STPE.2: $IDENT (BATISL,<? Illegal $STEP label>)
SETOM .JLSTP(R) ;FAKE OUT ERROR RECOVERY CODE
$RETF ;RETURN UNSUCESSFUL
STPE.3: $IDENT (BATSSE,<? Step header syntax error>)
$RETF ;RETURN UNSUCESSFUL
SUBTTL C$SCAN - Command scanner
C$SCAN::TXO F,FL.LSL ;FORCE LABEL TYPE OUT IF WE FIND ONE
TXZ F,FL.SUP!FL.UKJ ;CLEAR EOL SUPRESSION AND USER KJOB
ILDB S1,.JSCTB(R) ;GET FIRST CHARACTER
JUMPE S1,.POPJ ;RETURN ON NULL LINE
SETZM .JPEOL(R) ;CLEAR EOL SENT
MOVEI S2,CHRTAB ;POINT TO CHARACTER DISPATCH TABLE
SCAN.1: SKIPN (S2) ;END OF TABLE?
JRST SCAN.2 ;YES
HLRZ T1,(S2) ;GET A CHARACTER
CAME S1,T1 ;A MATCH?
AOJA S2,SCAN.1 ;NO - TRY ANOTHER
MOVE T1,(S2) ;GET DISPATCH ADDRESS
HRRZM T1,.JSCDP(R) ;STORE IT
JRST SCAN.3 ;SKIP LABEL CHECKS
SCAN.2: MOVEI T1,RNDMOD ;ASSUME RANDOM MODE IF NO LABEL
MOVEM T1,.JSCDP(R) ;STORE ADDRESS
PUSHJ P,LABEL ;TRY TO GET A LABEL
JRST SCAN.3 ;CAN'T
POPJ P, ;GOT IT - RETURN
SCAN.3: TXZ F,FL.LSL ;CLEAR LABEL TYPE OUT FLAG
PUSHJ P,@.JSCDP(R) ;DISPATCH TO PROCESSOR
JFCL
MOVE S1,.JSCFL(R) ;GET COMMAND FLAGS
SETZM .JSCFL(R) ;AND CLEAR FOR NEXT POSSIBLE PASS
TXNE S1,BC.CIC ;PARSE COMMAND IN CORE?
TXO F,FL.RCL ;YES - REMEMBER TO RE-EAT COMMAND LINE
POPJ P, ;RETURN
; Character table
; Format: XWD character,processor address
;
CHRTAB: XWD .CHLFD,VRTMOD ;LINE-FEED
XWD .CHVTB,VRTMOD ;VERTICAL-TAB
XWD .CHFFD,VRTMOD ;FORM-FEED
XWD .CHCRT,CRTMOD ;CARRIAGE-RETURN
XWD ";",COMENT ;OLD STYLE COMMENT
XWD "!",COMENT ;NEW STYLE COMMENT
XWD MONCHR,MONMOD ;BATCH OR MONITOR MODE COMMAND
XWD STPCHR,STPMOD ;BATCH STEP MODE
XWD "*",USRMOD ;USER MODE COMMAND
XWD "=",DDTMOD ;DDT MODE COMMAND
XWD "%",LABUSR ;RESERVED LABEL
XWD 0,0 ;END TABLE WITH A ZERO WORD
SUBTTL Label logic
; Here from command scanner top level to parse a label
;
LABEL: PUSHJ P,B$SETB## ;RESET BYTE POINTER
PUSHJ P,LABINP ;GET A LABEL
PJRST B$SETB## ;CAN'T - RESET BYTE POINTER AND RETURN
TXO R,RL.DRT ;DELAY RESPONSE BUFFER OUTPUT
PUSHJ P,FLUSH ;FLUSH LEADING TABS AND SPACES
JFCL ;ALWAYS SKIPS
PUSHJ P,EOLTST ;CHECK FOR EOL
JRST LABE.1 ;YES - SPECIAL CASE
PUSHJ P,BACKUP ;BACKUP THE BYTE POINTER 1 CHARACTER
PJRST C$COPY ;RE-COPY COMMAND AND RETURN SUCESSFUL
LABE.1: PUSHJ P,B$SETB ;RESET THE BYTE POINTER
SETZM .JSCTL(R) ;ZAP THE LINE
JRST .POPJ1 ;RETURN SUCESSFUL
;[4707] Input a label into .JLLBL(R) (:: required after label)
;
LABINP: PUSHJ P,SIXINP ;READ A SIXBIT WORD
JUMPE S1,.POPJ ;HAVE A LABEL?
MOVE T1,S1 ;COPY LABEL NAME
PUSHJ P,TYI ;READ NEXT CHARACTER
CAIN S1,":" ;A COLON?
CAIE S2,":" ;NEED TWO TO BE A LABEL
POPJ P, ;NOT A LABEL
CAME T1,['%FIN '] ;IS THIS %FIN?
JRST LABI.1 ;NO
HRRZ TF,.JSCDP(R) ;GET COMMAND DISPATCH ADDRESS
CAIE TF,.BACKTO ;ARE WE PROCESSING A .BACKTO COMMAND?
TXO F,FL.LSL ;NO - TURN ON LISTING OF LINES
LABI.1: TXNN F,FL.LSL ;LISTING SKIPPED LINES?
CAMN T1,.JLABL(R) ;OR IS THIS THE LABEL WE WANT?
$IDENT (LABEL,<^W/T1/::^A>) ;YES TO EITHER - LOG THE LABEL
MOVEM T1,.JLLBL(R) ;STORE LAST LABEL ENCOUNTERED
JRST .POPJ1 ;RETURN SUCESSFUL
; Input a label into .JLABL(R)
;
LABARG: PUSHJ P,SIXINP ;READ A SIXBIT WORD
MOVEM S1,.JLABL(R) ;STORE IT
JUMPE S1,.POPJ ;RETURN IF NO LABEL INPUT
; Check for legal label
;
LABCHK: LSH S1,-^D30 ;GET THE FIRST CHARACTER
CAIG S1,'Z' ;MUST BEGIN WITH A
CAIGE S1,'A' ;LETTER FROM A THROUGH Z
JRST LABERR ;NO GOOD
POPJ P, ;RETURN
; Search for %CERR or %ERR after user error occured
;
LABUSR::TXO F,FL.LSL ;LIST SKIPPED LINES
TXZ F,FL.FIN ;WE CAN'T SKIP OVER A %FIN
TXNN R,RL.JIE ;JOB IN ERROR?
JRST LABFIN ;YES - SEARCH FOR %FIN
TOPS10 < ;TOPS-10 ONLY
HRL S1,J ;GET JOB NUMBER
HRRI S1,.GTLIM ;BATCH TIME LIMIT TABLE
GETTAB S1, ;GET LIMIT WORD
SKIPA ;CAN'T
TXNE S1,JB.LSY ;PROGRAM COME FROM PHYSICAL SYS:?
SKIPA S1,['%CERR '] ;YES - USER %CERR LABEL
> ;END OF TOPS10 CONDITIONAL
MOVX S1,'%ERR ' ;NO - USE %ERR LABEL
MOVEM S1,.JLABL(R) ;STORE IT
PUSHJ P,LABSRC ;SEARCH FOR THE APPROPRIATE LABEL
TXZ R,RL.JIE ;CLEAR JOB IN ERROR CONDITION
POPJ P, ;RETURN
; Search for %FIN
;
LABFIN::SKIPA S1,['%FIN '] ;GET LABEL TO SEARCH FOR
; Search for %TERR
;
LABTER::MOVX S1,'%TERR ' ;GET LABEL TO SEARCH FOR
MOVEM S1,.JLABL(R) ;STORE IT AND FALL INTO LABSRC
TXO F,FL.LSL ;LIST SKIPPED LINES
TXZ F,FL.FIN ;WE CAN'T SKIP OVER A %FIN
;FALL INTO LABSRC
; Search for the label stored in .JLABL(R)
;
LABSRC::SETZM G$FAIR## ;INITIALIZE FAIRNESS COUNT
PUSHJ P,B$SETB## ;RESET THE BYTE POINTER
JRST LABS.2 ;SKIP INITIAL CALL TO C$READ
LABS.1: PUSHJ P,C$READ ;READ A LINE FROM THE CONTROL FILE
JUMPF LABEOF ;END OF FILE?
LABS.2: PUSHJ P,LABEL ;TRY TO INPUT A LABEL
JRST LABS.4 ;CAN'T
MOVE S1,.JLLBL(R) ;GET LABEL JUST FOUND
CAXN S1,<'%FIN '> ;SPECIAL %FIN LABEL?
JRST LABS.5 ;YES
CAMN S1,.JLABL(R) ;FOUND WHAT WE WANT?
POPJ P, ;YES - RETURN
LABS.4: TXNE F,FL.LSL ;LISTING SKIPPED LINES?
$IDENT (IGNORE,<^T/.JSCTL(R)/^A>) ;YES - DO IT
AOS S1,G$FAIR## ;COUNT THE LINE
CAXGE S1,CTLFCT ;EXCEEDED FAIRNESS COUNT?
JRST LABS.1 ;TRY ANOTHER LINE
AOS G$FFLG## ;REMEMBER FAIRNESS COUNT EXPIRED
PUSHJ P,QTS## ;ON TO THE NEXT STREAM
SETZM G$FAIR## ;RESET COUNTER
JRST LABS.1 ;TRY ANOTHER LINE
LABS.5: TXNE F,FL.FIN ;ALLOWED TO SKIP OVER %FIN?
JRST LABS.1 ;YES - KEEP SEARCHING
CAME S1,.JLABL(R) ;FOUND %FIN WHILE SEARCHING FOR %FIN?
$IDENT (BATFFS,<[Found %FIN while searching for ^W/.JLABL(R)/ - proceeding from %FIN]^A>)
PUSHJ P,B$DUMP## ;SEE IS A CLOSE/DUMP IS REQUIRED
POPJ P, ;NOPE
LABEOF: MOVE S1,.JLABL(R) ;GET LABEL WE'RE SEARCHING FOR
CAMN S1,['%TERR '] ;TIME LIMIT EXCEEDED?
$WTOJ (<Batch error>,<^I/JIBTXT/^I/LABTX1/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
$IDENT (BATECF,<? ^I/LABTX2/>) ;LOG EOF ERROR
TXO F,FL.TXT ;MESSAGE TEXT AVAILABLE
MOVE S1,.JLABL(R) ;GET LABEL AGAIN
CAME S1,['%TERR '] ;CHECK AGAIN
SKIPA S1,[[ASCIZ ||]] ;NULL TEXT
MOVEI S1,[ASCIZ |Time limit exceeded; |]
$TEXT (<-1,,.JWTOP(R)>,<^T/(S1)/Label ^W/.JLABL(R)/ not found^0>)
PJRST CLOSJB## ;DISMISS THE JOB
LABTX1: ITEXT (<Time limit exceeded; end of control file while searching for label %TERR>)
LABTX2: ITEXT (<End of control file while searching for label ^W/.JLABL(R)/>)
SUBTTL Comment/Vertical motion/User/DDT mode
; Put comments into the log file
;
COMENT: TXO R,RL.DRT ;DELAY RESPONSE BUFFER OUTPUT
$IDENT (COMENT,<^T/.JSCTL(R)/^A>)
JRST .POPJ1 ;RETURN SUCESSFUL
; Here on vertical motion characters
;
VRTMOD: PUSHJ P,B$SETB## ;RESET THE BYTE POINTER
TXNN J,JL.UML ;JOB AT USER LEVEL?
JRST USRMOD ;NOPE
TXZ F,FL.SUP ;CLEAR EOL SUPRESSION
ILDB S1,.JSCTB(R) ;GET THE VERTICAL MOTION CHARACTER
PUSHJ P,L$PLOG## ;LOG IT
SETZM .JLTIM(R) ;CLEAR TIME STAMP NEEDED FLAG
TXO R,RL.DRT ;DELAY RESPONSE BUFFER OUTPUT
JRST .POPJ1 ;RETURN SUCESSFUL
; Here on carriage returns
;
CRTMOD: PUSHJ P,B$SETB## ;RESET THE BYTE POINTER
; Send a line of user data
;
USRMOD: TXZA F,FL.SUP ;CLEAR EOL SUPRESSION
; DDT mode (suppress EOL characters)
;
DDTMOD: TXO F,FL.SUP ;SET EOL SUPPRESSION
TXNN R,RL.JIE ;IS JOB IN ERROR?
TXNE J,JL.UML ;JOB AT MONITOR LEVEL?
PJRST IGNORE ;YES - IGNORE THE LINE
TXZE R,RL.DRT ;WAS RESPONSE BUFFER OUTPUT DELAYED?
PUSHJ P,B$RTYO ;YES - OUTPUT IT NOW
PUSHJ P,B$XFER## ;SEND DATA TO THE PTY
TXZ F,FL.SUP ;MAKE EOL SUPRESSION IS OFF
JRST .POPJ1 ;RETURN SUCESSFUL
; Here when a job is at monitor level and a user level line is given
;
IGNORE: TXO R,RL.DRT ;DELAY RESPONSE BUFFER OUTPUT
$IDENT (IGNORE,<^T/.JSCTL(R)/^A>)
JRST .POPJ1 ;RETURN SUCESSFUL
SUBTTL RDNMOD - Random first character checking
RNDMOD: PUSHJ P,B$SETB## ;RESET THE BYTE POINTER
LDB S1,[POINT 7,.JSCTL(R),6] ;GET THE FIRST CHARACTER
CAIG S1,"Z" ;CHECK FOR ALPHA
CAIGE S1,"A"
SKIPA ;NO MATCH
JRST RNDM.1 ;YES
CAIG S1,"Z"+40 ;CHECK FOR LOWER CASE ALPHA
CAIGE S1,"A"+40
JRST USRMOD ;NO MATCH - TREAT AS USER MODE
RNDM.1: TXNN J,JL.UML ;USER MODE?
JRST RNDM.2 ;YES - THEN SEND LINE TO JOB
PUSHJ P,BATSET ;TRY TO SET UP A BATCH COMMAND
JUMPT BATPRC ;GOT ONE - GO PROCESS IT
RNDM.2: PUSHJ P,B$SETB## ;RESET THE BYTE POINTER
TXNE R,RL.JIE ;JOB IN ERROR?
JRST RNDM.3 ;YES - MAKE SPECIAL CHECKS
TXZ J,JL.UML ;FAKE OUT USRMOD BY CLEAING FLAG
JRST USRMOD ;TREAT LINE AS USER DATA
RNDM.3: TXNE J,JL.UML ;AT MONITOR LEVEL?
JRST LABUSR ;YES - SEARCH FOR ERROR PACKETS
JRST IGNORE ;NO - IGNORE THE LINE
SUBTTL Monitor mode
; Here on a Batch or monitor mode command
;
MONMOD: PUSHJ P,B$SETB## ;RESET THE BYTE POINTER
ILDB S1,.JSCTB(R) ;EAT THE FIRST CHARACTER
PUSHJ P,FLUSH ;GET THE NEXT CHARACTER
JFCL ;ALWAYS SKIPS
IFE <MONCHR-".">,< ;IF MONITOR PROMPT IS A PERIOD
CAIG S1,"9" ;CHECK FOR A DIGIT
CAIGE S1,"0" ;A FLOATING POINT NUMBER IS USER DATA
SKIPA ;NO MATCH
JRST MONM.2 ;SEND LINE IN USER MODE
> ;END OF IFE <MONCHR-"."> CONDITIONAL
CAIG S1,"Z" ;CHECK FOR UPPER CASE ALPHA
CAIGE S1,"A"
SKIPA ;NO MATCH
JRST MONM.1 ;COULD BE A BATCH OR MONITOR COMMAND
CAIGE S1,"Z"+40 ;CHECK FOR LOWER CASE ALPHA
CAIGE S1,"A"+40
JRST MONCMD ;NO MATCH
MONM.1: PUSHJ P,BACKUP ;BACKUP THE BYTE POINTER ONE CHARACTER
PUSHJ P,BATSET ;SET UP BATCH COMMAND IF POSSIBLE
JUMPT BATPRC ;PROCESS COMMAND IF NO ERRORS
TXNE R,RL.JIE ;JOB IN ERROR?
JRST LABUSR ;YES - LOOK FOR ERROR PACKETS
JRST MONCMD ;SEND THE LINE TO THE MONITOR
MONM.2: TXNE R,RL.JIE ;IS THE JOB IN ERROR?
JRST LABUSR ;YES - SEARCH FOR ERROR PACKETS
PUSHJ P,B$SETB## ;RESET THE BYTE POINTER
JRST USRMOD ;SEND THE LINE AT USER MODE
MONCMD: TXNN J,JL.UDI ;CAN JOB DO REAL INPUT?
POPJ P, ;NO - DON'T FORCE IT TO MONITOR MODE
PUSHJ P,B$SETB## ;YES - RESET THE BYTE POINTER
TXNE J,JL.UDI ;CAN JOB DO REAL INPUT?
JRST MONM.3 ;YES - GO DO IT
TXO F,FL.RCL ;NO - RE-EAT THE COMMAND LINE
POPJ P, ;DON'T FORCE TO MONITOR MODE AFTER ALL
MONM.3: LDB S1,[POINT 7,.JSCTL(R),6] ;GET THE FIRST CHARACTER
CAXN S1,MONCHR ;A NORMAL LINE?
ILDB S1,.JSCTB(R) ;YES - EAT THE PROMPT CHARACTER
TXZE R,RL.DRT ;WAS RESPONSE BUFFER OUTPUT DELAYED?
PUSHJ P,B$RTYO ;YES - OUTPUT IT NOW
PUSHJ P,P$STOP## ;PUT THE JOB IN MONITOR MODE
SKIPE .JLTIM(R) ;DO WE NEED A TIME STAMP?
TXNE F,FL.SIL ;YES - SUBJOB SILENCED?
SKIPA ;DON'T DO THE TIME STAMP
PUSHJ P,L$LSTP## ;INCLUDE THE TIME STAMP
PJRST B$XFER## ;TRANSFER THE LINE TO THE PTY
SUBTTL Batch step mode
STPMOD: AOSN .JSSPP(R) ;IS STEP PROCESSING PENDING?
JRST STPM.1 ;YES
$IDENT (HEADER,<^T/.JSCTL(R)/>) ;FAKE A LINE IN THE CONTROL FILE
$IDENT (BATMOS,<? More than one job step encountered - job canceled>)
JRST CLOSJB## ;DISMISS THE JOB
STPM.1: PUSHJ P,B$SETB## ;RESET THE BYTE POINTER
TXO R,RL.DRT ;DELAY THE RESPONSE BUFFER OUTPUT
PUSHJ P,STPPRC## ;CALL THE JOB STEP PROCESSOR
PUSHJ P,B$RTYO## ;OUTPUT THE RESPONSE BUFFER
$RETT ;RETURN SUCESSFUL
SUBTTL C$OPEN - Open the control file
C$OPEN::TXNE F,FL.KST ;KSYS STREAM?
POPJ P, ;RETURN
MOVEI S1,.JQCFD(R) ;GET FD FOR CTL
MOVEM S1,.JCFOB+FOB.FD(R) ;STORAGE AREA
MOVX S1,FB.LSN ;NO LINE SEQ NUMBERS
ADDI S1,7 ;PLACE BYTE SIZE IN S1
MOVEM S1,.JCFOB+FOB.CW(R) ;SAVE CONTROL WORD
MOVX S1,FP.SPL ;GET THE SPOOLED BIT
TDNE S1,.JQCFP+.FPINF(R) ;/DISP:REN?
JRST OPEN.1 ;YES
TOPS10 <
MOVE S1,.JQPPN(R) ;GET PPN FOR USER
MOVEI S2,0 ;MAKE ZERO FOR CONSISTENCY
>;END TOPS10
TOPS20 <
HRROI S1,.JQNAM(R) ;USER NAME FROM CREATE
HRROI S2,.JQCON(R) ;CONNECTED DIRECTORY
>;END TOPS20
MOVEM S1,.JCFOB+FOB.US(R) ;SAVE USER IN BEHALF
MOVEM S2,.JCFOB+FOB.CD(R) ;SAVE IN FOB
MOVEI S1,FOB.SZ ;SIZE OF THE BLOCK
MOVX T1,EQ.PRV ;GET PRIVILEGE FLAG
TDNE T1,.JQJBB+JIB.SQ(R) ;WAS IT SET
OPEN.1: MOVEI S1,FOB.MZ ;NO IN BEHALF NEEDED
MOVEI S2,.JCFOB(R) ;ADDRESS OF THE BLOCK
$CALL F%IOPN ;OPEN THE FILE
JUMPF FNDC.E ;ERROR EXIT
MOVEM S1,.JCIFN(R) ;Save IFN
POPJ P, ;Return
; Fix up CTL filespec (remove generation number)
;
C$FILE::
TOPS10 <POPJ P,> ;NOT NEEDED FOR TOPS-10
TOPS20 < ;TOPS-20 ONLY
MOVX S1,GJ%SHT ;SHORT FORM
HRROI S2,.JQCFD+.FDSTG(R) ;POINT TO FILESPEC
GTJFN ;GET A JFN
POPJ P, ;CAN'T
MOVE S2,S1 ;COPY THE JFN
HRROI S1,.JQCFD+.FDSTG(R) ;POINT TO THE FILESPEC
MOVE T1,[1B2+1B5+1B8+1B11+JS%PAF] ;GET SOME FLAGS
JFNS ;EXTRACT ALL BUT THE GENERATION NUMBER
ERJMP .+1 ;CAN'T
MOVE S1,S2 ;GET THE JFN
RLJFN ;RELEASE IT
JFCL ;IGNORE ERRORS
POPJ P, ;RETURN
> ;END OF TOPS-20 CONDITIONAL
; Here on CTL file open errors
;
FNDC.E: $IDENT (BATCFE,<Control file error for ^F/.JQCFD(R)/ - ^E/[-1]/>)
$IDENT (BATBJC,<[Batch job has been canceled]>)
SETZM .JLTIM(R) ;NO TIME STAMP
JRST B$ABOR## ;ABORT THE JOB
SUBTTL Control file positioning routines
; Save the current position in the control file
;
C$SPOS::SKIPN S1,.JCIFN(R) ;IS CTL FILE OPEN?
JRST SPOS.1 ;NO - DO IT NOW
$CALL F%CHKP ;TAKE CHECKPOINT
JUMPF POSERR ;CAN'T
MOVEM S1,.JCPOS(R) ;SAVE RELATIVE POSITION
POPJ P, ;RETURN TO PROCESSING
SPOS.1: PUSHJ P,C$OPEN ;OPEN THE CTL FILE
SETZM .JCPOS(R) ;POSITION TO BEGINNING
POPJ P, ;RETURN TO MAINLINE
; Reposition to saved location in the CTL file
;
C$RPOS::SKIPN S1,.JCIFN(R) ;GET IFN (UNLESS NOT OPENED)
PJRST SPOS.1 ;GO OPEN FILE AND RETURN
MOVE S2,.JCPOS(R) ;GET RELATIVE POSITION
$CALL F%POS ;POSITION FILE TO PROPER PLACE
JUMPF POSERR ;CAN'T
POPJ P, ;RETURN
; Rewind the control file
;
C$ZPOS::MOVE S1,.JCIFN(R) ;GET IFN
MOVEI S2,.-. ;BYTE 0
$CALL F%POS ;REWIND THE FILE
JUMPF POSERR ;CAN'T
POPJ P, ;RETURN
; Here on positioning errors
;
POSERR: $WTO (<Batch error>,<^R/.JQJBB(R)/^I/POSTXT/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
$RETF ;RETURN FAILURE
POSTXT: ITEXT (<
Control file positioning error ^E/[-1]/ for file ^F/.JQCFD(R)/; job canceled>)
SUBTTL C$DISP - Dispose of control file at EOJ
C$DISP::TXNE F,FL.PST!FL.KST ;PRESCAN OR KSYS STREAM?
POPJ P, ;YES
MOVX S2,FP.DEL!FP.REN ;GET /DISP:DEL AND /DISP:REN
SKIPE S1,.JCIFN(R) ;IS THE FILE OPENED?
TDNN S2,.JQCFP+.FPINF(R) ;WANT TO DELETE FILE?
POPJ P, ;NO - RETURN
$CALL F%DREL ;RELEASE AND DELETE FILE
SETZM .JCIFN(R) ;MARK THE IFN CLOSED
POPJ P, ;RETURN
SUBTTL C$CLOS - Close control file
C$CLOS::TXNN F,FL.KST ;KSYS STREAM?
SKIPN S1,.JCIFN(R) ;IS THE FILE OPENED?
POPJ P, ;NO - RETURN
$CALL F%REL ;RELEASE CONTROL FILE
SETZM .JCIFN(R) ;MARK THE IFN CLOSED
SKIPT ;ERRORS CLOSING CHANNEL OR JFN?
$WTO (<Batch error>,<^R/.JQJBB(R)/^I/CLSTXT/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
POPJ P, ;RETURN
CLSTXT: ITEXT (<^M^JErrors closing ^F/.JQCFD(R)/>)
SUBTTL C$READ - Read a line from the control file
C$READ::PUSHJ P,B$CINI## ;INITIALIZE THE COMMAND BUFFER
READ.1: PUSHJ P,GETCHR ;READ A CHARACTER FROM THE CONTROL FILE
JUMPF READ.5 ;EOF
CAIE S1,"^" ;WAS IT AN UP-ARROW?
JRST READ.3 ;NO
PUSHJ P,GETCHR ;YES - GET ANOTHER CHARACTER
JUMPF READ.5 ;EOF
CAIN S1,"^" ;ANOTHER UP-ARROW?
JRST READ.3 ;YES - THEN USE IT
CAIG S1,"Z"+40 ;NEED TO CONVERT
CAIGE S1,"A"+40 ; TO LOWER CASE?
SKIPA ;NO
SUBI S1," " ;YES - DO IT
CAIG S1,"_" ;CAN THIS CHARACTER BE
CAIGE S1,"A" ; A CONTROL CHARACTER?
JRST READ.2 ;NO - SEND UP-ARROW AND NEW CHARACTER
TRZ S1,"@" ;YES - CONVERT IT
JRST READ.3 ;SEND CONTROL CHARACTER
READ.2: PUSH P,S1 ;SAVE SECOND CHARACTER
MOVEI S1,"^" ;GET AN UP-ARROW
PUSHJ P,B$CPUT## ;SEND THE UP-ARROW
JUMPF READ.4 ;BUFFER MUST BE FULL
POP P,S1 ;RESTORE CHARACTER
READ.3: PUSHJ P,B$CPUT## ;STORE THE CHARACTER
JUMPF READ.4 ;BUFFER MUST BE FULL
CAXG S1,.CHFFD ;CHECK FOR A LINE TERMINATOR
CAXGE S1,.CHLFD ;CAN BE <LF>, <VT>, OR <FF>
JRST READ.1 ;LOOP FOR MORE
MOVX S1,.CHNUL ;GET A <NUL>
PUSHJ P,B$CPUT## ;TERMINATE STRING
PUSHJ P,B$SETB## ;SET UP THE BYTE POINTER
LDB S1,[POINT 7,.JSCTL(R),6] ;GET THE FIRST CHARACTER IN THE LINE
$RETT ;RETURN WITH TEXT IN .JSCTL(R)
READ.4: $IDENT (BATLEL,<? Control file line exceeds ^D/[CTLSIZ]/ characters, job canceled^A>)
JRST CLOSJB## ;DISMISS THE JOB
READ.5: SKIPE .JSCTL(R) ;DID WE GET A PARTIAL LINE?
$IDENT (BATILL,<% Incomplete last line in control file>)
$RETF ;RETURN UNSUCESSFUL
SUBTTL C$STRT - Find the starting point in the control file
C$STRT::SKIPN S1,.JBCRQ+1(R) ;GET STARTING PARAMETER
MOVE S1,.JQCFP+.FPFST(R) ;GET /BEGIN OR /TAG VALUE (NO CHKPNT)
TLNN S1,777777 ;IS IT A RESTART LABEL?
JRST STRT.1 ;NO - TRY A LINE NUMBER
MOVEM S1,.JLABL(R) ;SAVE FOR LABEL SEARCH
$IDENT (BATBLA,<[Beginning processing at label ^W/.JLABL(R)/]^A>)
PUSHJ P,LABCHK ;CHECK FOR LEGAL LABEL
TXO R,RL.DRT ;DELAY RESPONSE BUFFER OUTPUT
TXO F,FL.FIN ;THIS SEARCH MAY SKIP %FIN LABEL
PUSHJ P,LABSRC ;SEARCH FOR THE LABEL
TXO F,FL.RCL ;RE-EAT THE COMMAND LINE
POPJ P, ;RETURN
STRT.1: CAIG S1,1 ;IS THE STARTING LINE GREATER THAN 1?
POPJ P, ;NO - JUST A NORMAL START
MOVEM S1,.JLABL(R) ;STORE LINE COUNT
$IDENT (BATBLI,<[Beginning processing at line ^D/.JLABL(R)/]^A>)
TXO R,RL.DRT ;DELAY RESPONSE BUFFER OUTPUT
STRT.2: SOSG .JLABL(R) ;DID WE EAT ENOUGH LINES YET?
POPJ P, ;YES
PUSHJ P,C$READ ;NO - READ A LINE
SKIPF ;EOF?
JRST STRT.2 ;GO BACK FOR MORE
SKIPN S1,.JBCRQ+1(R) ;GET STARTING PARAMETER
MOVE S1,.JQCFP+.FPFST(R) ;GET /BEGIN OR /TAG VALUE (NO CHKPNT)
$IDENT (BATECF,<? End of control file while searching for line ^D/S1/>)
PJRST CLOSJB## ;DISMISS JOB
SUBTTL C$COPY - Re-copy a command line
; This routine will copy a portion of a command back into the command buffer
; using .JSCTB(R) as a pointer to the first character and terminating on a
; <NUL>. After the copy is completed, .JSCTB(R) will be reset to the start of
; the command buffer and FL.RCL in AC 'F' (re-eat command line) will be turned
; on so that the next command scan will use the command in core.
;
C$COPY: MOVE S1,[POINT 7,.JSCTL(R)] ;POINT TO START OF THE COMMAND BUFFER
COPY.1: ILDB S2,.JSCTB(R) ;GET A CHARACTER
IDPB S2,S1 ;PUT A CHARACTER
JUMPN S2,COPY.1 ;LOOP BACK
PUSHJ P,B$SETB## ;RESET THE BYTE POINTER
TXO F,FL.RCL ;REMEMBER TO RE-EAT THE COMMAND
JRST .POPJ1 ;Return sucessful
; Read a character from the control file
;
GETCHR: SKIPN S1,.JCIFN(R) ;IS CONTROL FILE OPEN?
PUSHJ P,C$OPEN ;NO - OPEN IT NOW
$CALL F%IBYT ;READ A BYTE
JUMPF GETC.E ;PROCESS ERROR
JUMPE S2,GETCHR ;FLUSH <NUL>
MOVE S1,S2 ;PUT CHARACTER IN A BETTER PLACE
$RETT ;RETURN SUCESSFUL
GETC.E: SKIPN .JBSPS(R) ;DOING ONLY A STEP HEADER SCAN?
CAXN S1,EREOF$ ;WAS IT EOF?
$RETF ;YES - JUST RETURN FALSE
$IDENT (BATCFE,<? ^I/CTLTXT/>)
$IDENT (BATBJC,<[Batch job has been canceled]>)
$WTOJ (<Batch error>,<^R/.JQJBB(R)/^M^J^I/CTLTXT/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
JRST CLOSJB## ;DISMISS JOB
CTLTXT: ITEXT (<Control file error for ^F/.JQCFD(R)/ - ^E/[-1]/>)
SUBTTL Miscellaneous scanner routines
; Get a character from the text buffer
;
; On return, S1 will contain a character. The following will have
; happened:
; a) All nulls stripped out
; b) Carriage returns ignored
; c) Lower case converted to upper case
;
TYI:: ILDB S1,.JSCTB(R) ;LOAD A CHARACTER
JUMPE S1,TYI ;IGNORE <NUL>
CAXN S1,.CHCRT ;<CR>?
JRST TYI ;YES - IGNORE IT
CAXN S1,.CHTAB ;<TAB>?
MOVEI S1," " ;YES - CONVERT TO A SPACE
CAIG S1,"Z"+40 ;CHECK FOR A LOWER CASE
CAIGE S1,"A"+40 ; CHARACTER THAT NEEDS TO BE
SKIPA ; CONVERTED TO AN UPPER CASE
TRZ S1," " ; CHARACTER
POPJ P, ;RETURN
; Test for End Of Line
; Returns .POPJ1 if no EOL, .POPJ if EOL
;
EOLTST: CAIG S1,.CHFFD ;CHECK FOR <LF>, <VT>
CAIGE S1,.CHLFD ; OR <FF>
SKIPA ;NOT EOL
POPJ P, ;RETURN
CAIE S1,.CHBEL ;BELL
CAIN S1,.CHCNZ ;CONTROL-Z
POPJ P, ;EOL
CAIE S1,.CHESC ;ESCAPE
CAIN S1,.CHCNC ;CONTROL-C
POPJ P, ;EOL
JRST .POPJ1 ;NOT EOL
; Flush leading spaces and tabs (always returns .POPJ1)
;
FLUSH: PUSHJ P,TYI ;GET A CHARACTER
CAIN S1," " ;SPACE?
JRST FLUSH ;YES - EAT IT
JRST .POPJ1 ;SKIP ALWAYS
; Back up the text byte pointer 1 character
;
BACKUP: MOVE S1,.JSCTB(R) ;GET THE BYTE POINTER
ADD S1,[XWD 70000,0] ;BACK UP 1 CHARACTER
SKIPG S1 ;OVER A WORD BOUNDRY?
SUB S1,[XWD 430000,1] ;YES - ADJUST POINTER
MOVEM S1,.JSCTB(R) ;STORE NEW BYTE POINTER
LDB S1,.JSCTB(R) ;LOAD THE PREVIOUS CHARACTER
POPJ P, ;RETURN
; Input a sixbit word into S1, terminating character into S2
;
; Destroys ACs T1 and T2
;
SIXINP: MOVE T1,[POINT 6,T2] ;BYTE POINTER TO STORE WORD
SETZB S2,T2 ;CLEAR COUNTER AND DESTINATION
PUSHJ P,FLUSH ;EAT LEADING SPACES AND TABS
SIXI.1: PUSHJ P,TYI ;GET A CHARACTER
CAIN S1,"%" ;SPECIAL CHECK
JRST SIXI.2 ;GO STORE IT
CAIL S1,"0" ;RANGE CHECK THE CHARACTER
CAILE S1,"9"
CAIL S1,"A"
CAILE S1,"Z"
JRST SIXI.3 ;NO MATCH - FINISH UP
SIXI.2: CAIL S2,6 ;TOO MANY CHARACTERS?
JRST SIXI.1 ;YES - IGNORE THE REST
SUBI S1," " ;CONVERT TO SIXBIT
IDPB S1,T1 ;STORE CHARACTER
AOJA S2,SIXI.1 ;LOOP FOR MORE
SIXI.3: MOVE S2,S1 ;SAVE TERMINATING CHARACTER
MOVE S1,T2 ;GET RESULTS
POPJ P, ;RETURN
; Input a keyword into the address pointed to by S1
; Call: MOVE S1,address to store string
; MOVE S2,maximum length of string
; PUSHJ P,KEYINP
; <return>
;
; On return, S1 will contain the terminating character and S2 the number
; of characters input. ACs T1, T2, and T3 are destroyed.
;
KEYINP: DMOVE T1,S1 ;GET ARGUMENTS
HRLI T1,(POINT 7) ;MAKE A BYTE POINTER
SETZ T3, ;CLEAR CHARACTER COUNT
PUSHJ P,FLUSH ;EAT LEADING TABS AND SPACES
KEYI.1: PUSHJ P,TYI ;GET A CHARACTER
CAIN S1,"%" ;SPECIAL CHECK
JRST KEYI.2 ;GO STORE IT
CAIL S1,"0" ;RANGE CHECK THE CHARACTER
CAILE S1,"9"
CAIL S1,"A"
CAILE S1,"Z"
JRST KEYI.3 ;NO MATCH - GO FINISH UP
KEYI.2: CAML T3,T2 ;IS THERE ROOM IN THE BUFFER?
JRST KEYI.1 ;NO - IGNORE IT
IDPB S1,T1 ;STORE CHARACTER
AOJA T3,KEYI.1 ;NO - LOOP
KEYI.3: CAXE S1,.CHTAB ;A TAB?
CAIN S1," " ;OR A SPACE?
SKIPA ;YES TO EITHER
PUSHJ P,BACKUP ;NOPE - BACKUP 1 CHARACTER
MOVX S2,.CHNUL ;GET A <NUL>
IDPB S2,T1 ;STORE IT
MOVE S2,T3 ;GET CHARACTER COUNT
POPJ P, ;RETURN
SUBTTL Batch command set up and dispatching
; Set up a Batch command
;
BATSET: MOVEI S1,.JSKEY(R) ;ADDRESS TO STORE KEYWORD
MOVEI S2,^D10 ;MAXIMUM NUMBER OF CHARACTERS
PUSHJ P,KEYINP ;INPUT A KEYWORD
MOVEI S1,BATCMD ;POINT TO COMMAND TABLE
MOVEI S2,.JSKEY(R) ;POINT TO KEYWORD
$CALL S%TBLK ;SEARCH THE TABLE
TXNN S2,TL%ABR!TL%EXM ;ABBREVIATION OR EXACT MATCH?
$RETF ;NOPE
LDB TF,[POINT 7,.JSKEY(R),13] ;GET SECOND CHARACTER OF COMMAND
TXNE S2,TL%ABR ;ABBREVIATED COMMAND?
JUMPE TF,.RETF ;AND MUST BE NON-ZERO OR THATS ILLEGAL
HRRZ S2,(S1) ;GET TABLE INDEX
MOVE S1,BATDSP(S2) ;GET THE FLAGS AND DISPATCH ADDRESS
HRRZM S1,.JSCDP(R) ;STORE IT
HLLZM S1,.JSCFL(R) ;STORE FLAGS
TXNE S1,BC.KJB ;SPECIAL KJOB PROCESSING?
TXO F,FL.UKJ ;REMEMBER USER REQUESTED KJOB
TXNN S1,BC.ERR ;IS COMMAND LEGAL IF JOB IN ERROR?
TXNN R,RL.JIE ;NOT VALID, IS THE JOB IN ERROR?
$RETT ;NO - RETURN SUCESSFUL
$RETF ;CAN'T PROCESS THIS COMMAND
; Here on a Batch command. The following is set up:
; a) .JSCTL(R) contains the command line.
; b) .JSCTB(R) contains the byte pointer to the command line.
; and it points to the character immediately following the
; last character of the command.
; c) .JSCDP(R) contains the command processor address.
; d) S1 contains the command flags.
;
BATPRC: HRLZI S1,.JSKEY(R) ;GET ADDRESS OF KEYWORD BUFFER
HRRI S1,.JSCNM(R) ;GET ADDRESS OF THE COMMAND NAME BUFFER
BLT S1,.JSCNM+<KEYSIZ/5>(R) ;COPY COMMAND NAME
MOVE S1,.JSCFL(R) ;GET COMMAND FLAGS
TXNN S1,BC.MON ;IS THIS REALLY A MONITOR COMMAND?
JRST BATP.1 ;NO
PUSHJ P,B$SETB## ;RESET THE BYTE POINTER
ILDB S1,.JSCTB(R) ;EAT THE MONITOR PROMPT CHARACTER
PJRST MONCMD ;YES
BATP.1: TXNN S1,BC.NEC ;"NOECHO" THIS COMMAND?
$IDENT (BATCH,<^T/.JSCTL(R)/^A>) ;NO - ECHO BATCH COMMAND LINE
TXO R,RL.DRT ;DELAY THE RESPONSE BUFFER OUTPUT
PJRST @.JSCDP(R) ;DISPATCH TO THE COMMAND PROCESSOR
SUBTTL Macros to generate Batch command tables
; Batch command flags
;
BC.ERR==1B0 ;COMMAND IS LEGAL IF JOB IN ERROR
BC.CIC==1B1 ;PARSE COMMAND IN CORE ON COMMAND EXIT
BC.NEC==1B2 ;"NOECHO" BATCH COMMAND LINE BY BATPRC
BC.MON==1B3 ;MONITOR COMMAND
BC.KJB==1B4 ;KJOB
; Macro to generate Batch command tables
;
DEFINE $BAT,<
DEFINE $MKBAT,<
$ ABORT,.ABORT,<BC.ERR>
$ BACKSPACE,,<BC.MON>
$ BACKTO,.BACKTO,<BC.CIC>
$ CHKPNT,.CHKPNT,0
$ DU,.DUMP,<BC.ERR>
$ DUMP,.DUMP,<BC.ERR>
$ ER,.ERROR,0
$ ERROR,.ERROR,0
$ GO,.GOTO,<BC.CIC>
$ GOTO,.GOTO,<BC.CIC>
$ I,,<BC.MON>
$ IF,.IF,<BC.ERR!BC.NEC>
TOPS10 < $ KJOB,,<BC.KJB!BC.MON>
$ KJO,,<BC.KJB!BC.MON>
$ KJ,,<BC.KJB!BC.MON>
$ K,,<BC.KJB!BC.MON>
> ;END TOPS10
TOPS20 < $ LOGOUT,,<BC.KJB!BC.MON>>
$ NOERROR,.NOERROR,0
$ NOOPERATOR,.NOOPERATOR,<BC.ERR>
$ OPERATOR,.OPERATOR,0
$ PLEASE,.PLEASE,0
$ REQUEUE,.REQUEUE,0
$ REVIVE,.REVIVE,0
$ SILENCE,.SILENCE,0
$ START,,<BC.MON>
$ STATUS,.STATUS,0
> ;END OF $MKBAT MACRO
...BA1==0 ;CLEAR COUNTER
DEFINE $ (NAME,DISP,FLAGS),<
...BA1==...BA1+1 ;COUNT ENTRIES
> ;END OF $ MACRO
$MKBAT ;BUILD THE COMMAND NAME TABLE
...BA2==0 ;CLEAR COUNTER
BATCMD: XWD ...BA1,...BA1 ;TABLE LENGTH
DEFINE $ (NAME,DISP,FLAGS),<
XALL
[ASCIZ |NAME|],,...BA2 ;'NAME COMMAND TABLE
SALL
...BA2==...BA2+1 ;COUNT ENTRIES
> ;END OF $ MACRO
$MKBAT ;BUILD THE COMMAND TABLE
BATDSP: DEFINE $ (NAME,DISP,FLAGS),<
XALL
EXP FLAGS+DISP ;'NAME DISPATCH TABLE
SALL
> ;END OF $ MACRO
$MKBAT ;BUILD THE FLAG TABLE
> ;END OF $BAT MACRO
SUBTTL Batch command tables
$BAT
SUBTTL Batch commands -- ABORT and STATUS
; ABORT command
;
.ABORT: $IDENT (ABORT,<?Job aborted by batch ABORT command>)
TXOA R,RL.JIE ;FLAG ERROR CONDITION
.STATUS:TXZ R,RL.JIE ;NON-FATAL
PUSHJ P,B$WINI## ;INIT WTO BUFFER
PUSHJ P,FLUSH ;EAT SPACES
ABOR.1: ILDB S1,.JSCTB(R) ;GET A CHAR
JUMPE S1,ABOR.2 ;END
PUSHJ P,B$WPUT## ;STASH IT IN WTO BUFFER
JRST ABOR.1 ;AND LOOP
ABOR.2: PUSHJ P,B$WEOL## ;END WTO MESSAGE
TXO F,FL.TXT ;MESSAGE TEXT AVAILABLE
TXZE R,RL.JIE ;AVOID CLOSE/DUMP
TXOA F,FL.UHE ;UNEXPECTED ERROR, TEXT AVAILABLE
TXZA F,FL.UHE ;NO ERRORS
JRST B$CLOSE## ;AND FINISH OFF THE JOB
JRST .POPJ1 ;RETURN SUCESSFUL
SUBTTL Batch commands -- BACKTO and GOTO
; BACKTO command
;
.BACKTO:
PUSHJ P,LABARG ;GET A LABEL ARGUMENT
SKIPN .JLABL(R) ;WAS THERE ONE
PJRST LABERR ;NO - GIVE AN ERROR
HRRZ S1,J ;GET THE MONITOR JOB NUMBER
MOVX S2,JI.RTM ;GET THE RUNTIME
PUSHJ P,I%JINF ;GET THE JOB INFO
CAMG S2,.JBRTM(R) ;USER MUST DO SOMETHING TO GET RUNTIME
JRST BACK.1 ;OTHERWISE COULD BE A::.BACKTO A
MOVEM S2,.JBRTM(R) ;SAVE FOR NEXT BACKTO COMMAND
TXO F,FL.FIN ;OK TO PASS %FIN DURING SEARCH
PUSHJ P,C$ZPOS ;REWIND THE CONTROL FILE
JRST LABSRC ;GO FIND THE LABEL
BACK.1: $IDENT (BATEPL,<? BACKTO command has entered a possible loop>)
JRST BATERR ;ENTER COMMON BATCH COMMAND ERROR CODE
; GOTO command
;
.GOTO: PUSHJ P,LABARG ;GET A LABEL ARGUMENT
SKIPN .JLABL(R) ;WAS THERE A LABEL?
PJRST LABERR ;NO - ISSUE LABEL ERROR
PJRST LABSRC ;SEARCH FOR LABEL
SUBTTL Batch commands -- CHKPNT and REQUEUE
; CHKPNT command
;
.CHKPNT:
PUSHJ P,LABARG ;GET A LABEL ARGUMENT
MOVX S1,BA.CHK ;GET CHECKPOINT FLAG
IORM S1,.JBCRQ(R) ;TURN ON CHECKPOINT FLAG IN CHECK WORDS
SKIPN S1,.JLABL(R) ;WAS THERE A LABEL
JRST LABERR ;NO, IS AN ERROR
MOVEM S1,.JBCRQ+1(R) ;STORE THE RESTART LABEL
TXO F,FL.CHK ;UPDATE CHECKPOINT DATA TO DISK
SETZM .JBCHK(R) ;FORCE A CHECKPOINT
PUSHJ P,QTS## ;WAIT A SCHEDULER PASS
JRST .POPJ1 ;RETURN SUCESSFUL
; REQUEUE command
;
.REQUEUE:
PUSHJ P,LABARG ;GET A LABEL ARGUMENT
MOVX S1,BA.URQ ;GET REQUEUE BY USER
IORM S1,.JBCRQ(R) ;STORE IT
SKIPE S1,.JLABL(R) ;WAS A LABEL SPECIFIED?
MOVEM S1,.JBCRQ+1(R) ;YES - STORE FOR QUASAR
$IDENT (BATJRQ,<[Job requeued by user]>)
MOVEI S1,REQTIM ;GET REQUEUE TIME
STORE S1,.JBRQF(R),RQ.TIM ;SET IT
MOVX T1,%REQUE ;GET REQUEUE CODE
PUSHJ P,B$UPDA## ;UPDATE QUASAR
$WTOJ (<Requeue request queued by user>,<^R/.JQJBB(R)/>,.JQOBJ(R),<$WTNOD(.JQLOC(R))>)
TXO R,RL.REQ ;MARK JOB AS BEING REQUEUED
JRST B$CLOS## ;DISMISS JOB
; Here on label argument errors
;
LABERR: $IDENT (BATNLS,<? No label specified or illegal syntax>)
; Here on Batch command errors
;
BATERR: TXO F,FL.LSL ;LIST LINES SKIPPED
PJRST LABFIN ;SEARCH FOR %FIN
SUBTTL Batch commands -- DUMP
; DUMP command
;
.DUMP:: $IDENT (DUMP,< -- Batch Stream and Job Data -->)
$IDENT (DUMP,<Stream:^A>)
SETZ P1, ;CLEAR INDEX
DUMP.1: SKIPN DMPTAB(P1) ;END OF TABLE?
JRST DUMP.2 ;YES
HLLZ S1,DMPTAB(P1) ;GET BITS TO TEST
HRRZ S2,DMPTAB(P1) ;GET ADDRESS OF ASCIZ TEXT
TDNE R,S1 ;BIT SET?
$IDENT (DUMP,< ^T/(S2)/^A>) ;OUTPUT TEXT
AOJA P1,DUMP.1 ;LOOP FOR MORE
DUMP.2: SKIPN T1,.JBECH(R) ;GET THE ERROR CHARACTER
MOVEI T1," " ;NONE - LOAD A SPACE
SKIPN T2,.JBOCH(R) ;GET THE OPERATOR CHARACTER
MOVEI T2," " ;NONE - LOAD A SPACE
MOVEI T3,[ASCIZ /No/] ;ASSUME NOT SILENCED
TXNE F,FL.SIL ;JOB SILENCED?
MOVEI T3,[ASCIZ /Yes/] ;YES
$IDENT (DUMP,< Error: ^7/T1/ Operator: ^7/T2/ Silenced: ^T/(T3)/^A>)
$IDENT (DUMP,< Processing node: ^N/.JQOBJ+OBJ.ND(R)/^A>)
$IDENT (DUMP,< Last step: ^W/.JLSTP(R)/^A>)
$IDENT (DUMP,< Last label: ^W/.JLLBL(R)/^A>) ;[4707]
$IDENT (DUMP,< Last CHKPNT: ^W/.JBCRQ+1(R)/^A>)
$IDENT (DUMP,< Last line to job: ^T/.JSCTL(R)/^A>)
$IDENT (DUMP,< Last line from job: ^T/.JBRSP(R)/^A>)
$IDENT (DUMP,< Last line to OPR: ^T/.JWTOP(R)/^A>)
$IDENT (DUMP,< Last line from OPR: ^T/.JWFOP(R)/^A>)
$IDENT (DUMP,< Last Batch command: ^T/.JSCNM(R)/^A>)
$IDENT (DUMP,<Job:^A>)
HRRZ S1,J ;GET JOB NUMBER
$IDENT (DUMP,< Job: ^D/S1/^A>) ;DISPALY IT
MOVEI P1,JOBTAB ;POINT TO THE JOB TABLE
DUMP.3: SKIPN T1,(P1) ;END OF TABLE?
JRST DUMP.X ;YES
HRRZ S1,J ;LOAD JOB NUMBER
HLRZ S2,(P1) ;LOAD I%JINF ARGUMENT
$CALL I%JINF ;READ A VALUE
SKIPT ;ANY ERRORS?
AOJA P1,DUMP.3 ;YES - IGNORE IT
HRRZ T1,(P1) ;GET ITEXT BLOCK POINTER
$IDENT (DUMP,< ^I/(T1)/^A>) ;OUTPUT SOME DATA
AOJA P1,DUMP.3 ;LOOP FOR MORE
DUMP.X: $IDENT (DUMP,< -- End of Dump -->)
JRST .POPJ1 ;RETURN SUCESSFUL
; Table of bits to test and messages to output
; Format: bits in LH AC 'R',[asciz string]
;
DMPTAB: EXP RL.OPR+[ASCIZ /Waiting for operator response/]
EXP RL.JIE+[ASCIZ /Job in error/]
EXP RL.KJB+[ASCIZ /Logout in pending/]
EXP RL.LGI+[ASCIZ /Login in progress/]
EXP RL.DIA+[ASCIZ /Job in dialogue mode/]
EXP RL.STP+[ASCIZ /Stopped by the operator/]
EXP RL.MIP+[ASCIZ /Operator message being processed/]
EXP RL.FLS+[ASCIZ /Request to flush job/]
EXP 0 ;END TABLE WITH A ZERO WORD
; Table of job parameter values
; Format: XWD I%JINF arguments,[ITEXT (string)]
;
JOBTAB: XWD JI.TNO,[ITEXT (TTY^O/S2/)]
XWD JI.USR,[ITEXT (User: ^P/S2/)]
XWD JI.PRG,[ITEXT (Program: ^W/S2/)]
XWD JI.LOC,[ITEXT (Located at: ^N/S2/)]
XWD 0,0 ;End table with a zero word
SUBTTL Batch commands -- ERROR and OPERATOR
; ERROR command
;
.ERROR: TXZ F,FL.NER ;CLEAR NOERROR STATE
SETZ T1, ;DEFAULT CHARACTER
MOVEI T2,.JBECH(R) ;STORAGE ADDRESS
PJRST CHRSET ;GO ENTER COMMON ERROR/OPERATOR CODE
; OPERATOR command
;
.OPERATOR:
MOVEI T1,"$" ;DEFAULT CHARACTER
MOVEI T2,.JBOCH(R) ;STORAGE ADDRESS
; Common character setting routine
;
CHRSET: MOVEM T1,(T2) ;STORE DEFAULT CHARACTER
PUSHJ P,FLUSH ;FLUSH LEADING TABS AND SPACES
JFCL ;ALWAYS SKIPS
PUSHJ P,EOLTST ;OR TERMINATING CHARACTER?
JRST .POPJ1 ;YES - RETURN
CAIE S1,";" ;OLD STYLE COMMENT?
CAIN S1,"!" ;NEW STYLE COMMENT?
JRST .POPJ1 ;YES - RETURN
CAIG S1," " ;NON-CONTROL NON-SPACE CHARACTER?
JRST ILLCHR ;ILLEGAL CHARACTER
MOVEM S1,(T2) ;STORE IT
JRST .POPJ1 ;RETURN
; Here on an illegal character
;
ILLCHR: SETZM (T2) ;CLEAR DEFAULT CHARACTER CURRENTLY SET
$IDENT (BATICS,<? Illegal character specified for ^T/.JSCNM(R)/ command^A>)
JRST LABFIN ;GO SEARCH FOR %FIN
SUBTTL Batch commands -- IF
; Perform error testing
;
.IF: PUSHJ P,FLUSH ;EAT LEADING TABS AND SPACES
JFCL ;ALWAYS SKIPS
CAIE S1,"(" ;NEED THE OPENING PARENTHESIS
JRST IF.ERR ;BAD IF COMMAND
MOVEI S1,.JSKEY(R) ;POINT TO STORAGE LOCATION
MOVEI S2,KEYSIZ ;MAXIMUM NUMBER OF CHARACTERS
PUSHJ P,KEYINP ;READ A KEYWORD
PUSHJ P,FLUSH ;EAT LEADING TABS AND SPACES
JFCL ;ALWAYS SKIPS
CAIE S1,")" ;NEED THE CLOSING PARENTHESIS
JRST IF.ERR ;BAD IF COMMAND
MOVEI S1,IFTAB ;POINT TO KEYWORD TABLE
MOVEI S2,.JSKEY(R) ;POINT TO KEYWORD
$CALL S%TBLK ;SCAN THE TABLE
TXNN S2,TL%ABR!TL%EXM ;ABBREVIATION OR EXACT MATCH?
JRST IF.ERR ;NOPE
HRRZ S1,(S1) ;GET DISPATCH ADDRESS
JRST (S1) ;PROCESS THE IF COMMAND
IF.ERR: $IDENT (BATIIC,<? Illegal IF command argument or syntax error>)
JRST BATERR ;TAKE ERROR RETURN
; Here on IF (ERROR)
;
IFERRO: TXZN R,RL.JIE ;JOB IN ERROR?
JRST IFFALS ;NO - IF (ERROR) IS FALSE
; Here if condition tested is TRUE
;
IFTRUE: $IDENT (TRUE,<^A>) ;IDENTIFY THE LINE
PUSHJ P,IFCOPY ;COPY THE IF COMMAND AND ARGUMENTS
TXO R,RL.DRT ;DELAY THE RESPONSE BUFFER OUTPUT
PJRST C$COPY ;RE-COPY COMMAND AND RETURN SUCESSFUL
; Here on IF (NOERROR)
;
IFNOER: TXZN R,RL.JIE ;JOB IN ERROR?
JRST IFTRUE ;NO - IF (NOERROR) IS TRUE
; Here if condition tested is FALSE
;
IFFALS: $IDENT (FALSE,<^A>) ;IDENTIFY THE LINE
TXO R,RL.DRT ;DELAY THE RESPONSE BUFFER OUTPUT
PUSHJ P,IFCOPY ;COPY THE IF COMMAND AND ARGUMENTS
JRST .POPJ1 ;RETURN SUCESSFUL
; Copy the IF command and arguments
;
IFCOPY: PUSHJ P,B$SETB## ;RESET BYTE POINTER TO START OF LINE
IFCO.1: ILDB S1,.JSCTB(R) ;GET A CHARACTER
PUSHJ P,L$PLOG## ;LOG IT
CAIE S1,")" ;END OF CONDITIONAL?
JRST IFCO.1 ;NO - LOOP BACK
PUSHJ P,L$CRLF## ;END THE LINE
PUSHJ P,FLUSH ;GET NEXT CHARACTER (NO SPACES OR TABS)
JFCL ;ALWAYS SKIPS
PUSHJ P,EOLTST ;AT EOL ALREADY?
POPJ P, ;YES - THEN DON'T BACKUP
PJRST BACKUP ;BACKUP 1 CHARACTER AND RETURN
; Macros to generate the IF argument tables
;
DEFINE $IF,<
DEFINE $MKIF,<
$ ERROR,IFERRO
$ NOERROR,IFNOER
> ;END OF $MKIF MACRO
...IF==0 ;CLEAR COUNTER
DEFINE $ (NAME,DISP),<
...IF==...IF+1 ;COUNT THE ENTRY
> ;END OF $ MACRO
$MKIF ;BUILD THE ARGUMENT NAME TABLE
IFTAB: XWD ...IF,...IF ;TABLE LENGTH
DEFINE $ (NAME,DISP),<
XALL
[ASCIZ |'NAME|],,DISP ;'NAME ARGUMENT
SALL
> ;END OF $ MACRO
$MKIF ;BUILD THE ARGUMENT TABLE
> ;END OF $IF MACRO
; Invoke the IF argument table building macros
;
$IF
SUBTTL Batch commands -- MESSAGE and PLEASE
; MESSAGE and PLEASE commands
;
.MESSAGE:
.PLEASE:
PUSHJ P,B$WINI## ;SET UP WTO/WTOR BUFFER
PUSHJ P,FLUSH ;EAT LEADING SPACES AND TABS
PLEA.1: ILDB S1,.JSCTB(R) ;GET A CHARACTER
CAIN S1,.CHESC ;ESCAPE?
JRST PLEA.2 ;YES - SEND LINE TO OPERATOR
PUSHJ P,B$WPUT## ;STORE IN THE WTO/WTOR BUFFER
JUMPE S1,PLEA.3 ;END OF LINE
JRST PLEA.1 ;LOOP BACK FOR ANOTHER
PLEA.2: PUSHJ P,B$WEOL## ;END THE LINE
PUSHJ P,B$WTO## ;DO A WTO
JRST .POPJ1 ;RETURN SUCESSFUL
PLEA.3: PUSHJ P,B$WEOL## ;End the line
PUSHJ P,B$WTOR## ;Do a WTOR
PUSHJ P,B$WRSP## ;GET OPERATOR RESPONSE
$IDENT (OPERAT,<From operator: ^T/.JWFOP(R)/^A>)
JRST .POPJ1 ;RETURN SUCESSFUL
SUBTTL Batch commands -- NOERROR, NOOPERATOR, REVIVE, and SILENCE
; NOERROR command
;
.NOERROR:
TXO F,FL.NER ;SET NOERROR IN EFFECT
JRST .POPJ1 ;RETURN SUCESSFUL
; NOOPERATOR command
;
.NOOPERATOR:
SETZM .JBOCH(R) ;CLEAR THE DIALOGUE CHARACTER
JRST .POPJ1 ;RETURN SUCESSFUL
; REVIVE command
;
.REVIVE:
TXZA F,FL.SIL ;CLEAR SILENCE MODE
; SILENCE command
;
.SILENCE:
TXO F,FL.SIL ;SET SILENCE MODE
JRST .POPJ1 ;RETURN SUCESSFUL
SUBTTL MOUNT parser -- ALLOCATE and MOUNT command syntax tables
;ALLOCATE and MOUNT syntax tables
MOU010:: ;Mount and allocate share common syntax
ALL010::$SWITCH(,MOU011,$ALTER(MOU015))
MOU015: $CRLF ($ALTER (MOU020))
MOU020: $FIELD(MOU022,<volume set name>,$BREAK(VSNBRK))
MOU022: $TOKEN(MOU023,<(>,$ALTER(MOU026))
MOU023: $FIELD(MOU024,<volume identifier>)
MOU024: $COMMA(MOU023,$ALTER(MOU025))
MOU025: $TOKEN(MOU026,<)>)
MOU026: $TOKEN(MOU030,<:>,$ALTER(MOU030))
MOU030: $FIELD(MOU032,<logical name>)
MOU032: $TOKEN(MOU040,<:>,$ALTER(MOU040))
MOU040: $SWITCH(,MOU041,$ALTER(MOU050))
MOU050: $COMMA(MOU020,$ALTER(MOU060))
MOU060: $CRLF
;Character set allowed for VOLUME-SET-NAME
VSNBRK::
777777,,777760 ;Break on all control
777754,,001760 ;Allow - and 0-9
400000,,000760 ;Allow A-Z
400000,,000760 ;Allow LC A-Z
SUBTTL MOUNT parser -- MOUNT and ALLOCATE option tables
MOU011: $STAB
DSPTAB(MOU010,MO$CHE,<CHECK>)
DSPTAB(MOU010,MO$DIS,<DISK>)
DSPTAB(,HELPER,<HELP>)
DSPTAB(MOU010,MO$NNT,<NONOTIFY>)
DSPTAB(MOU010,MO$NOT,<NOTIFY>)
DSPTAB(MOU010,MO$NOW,<NOWAIT>)
DSPTAB(MOU010,MO$TAP,<TAPE>)
DSPTAB(MOU010,MO$WAI,<WAIT>)
$ETAB
MOU041: $STAB
DSPTAB(MOU040,MO$ACT,<ACTIVE>)
DSPTAB(MOU040,MO$CRE,<CREATE>)
DSPTAB(M$DEN1,MO$DEN,<DENSITY>)
DSPTAB(M$FLD1,MO$DEV,<DEVICE>)
DSPTAB(MOU040,MO$DIS,<DISK>)
DSPTAB(MOU040,MO$EXC,<EXCLUSIVE>)
DSPTAB(M$LAB1,MO$LAB,<LABEL-TYPE>)
DSPTAB(MOU040,MO$SHA,<MULTI>) ;Ala SHARABLE
DSPTAB(MOU040,MO$NEW,<NEW-VOLUME-SET>)
DSPTAB(MOU040,MO$NOC,<NOCREATE>)
DSPTAB(MOU040,MO$NNT,<NONOTIFY>)
DSPTAB(MOU040,MO$NOT,<NOTIFY>)
DSPTAB(MOU040,MO$NOW,<NOWAIT>)
DSPTAB(MOU040,MO$PAS,<PASSIVE>)
DSPTAB(M$PRO1,MO$PRO,<PROTECTION>)
DSPTAB(MOU040,MO$QTA,<QUOTA>)
DSPTAB(MOU040,MO$REA,<READ-ONLY>)
DSPTAB(M$VOL1,MO$VOL,<REELID>) ;Ala VOLID
DSPTAB(M$REM1,MO$REM,<REMARK>)
DSPTAB(MOU040,MO$REA,<RONLY>) ;Ala READ-ONLY
DSPTAB(MOU040,MO$SCR,<SCRATCH>)
DSPTAB(MOU040,MO$SHA,<SHARABLE>)
DSPTAB(MOU040,MO$EXC,<SINGLE>) ;Ala EXCLUSIVE
DSPTAB(MOU040,MO$TAP,<TAPE>)
DSPTAB(M$TRA1,MO$TRA,<TRACKS>)
DSPTAB(M$REM1,MO$REM,<VID>) ;Ala REMARK
DSPTAB(M$VOL1,MO$VOL,<VOLID>)
DSPTAB(MOU040,MO$WAI,<WAIT>)
DSPTAB(MOU040,MO$WRI,<WENABLE>) ;Ala WRITE-ENABLE
DSPTAB(MOU040,MO$REA,<WLOCK>) ;Ala READ-ONLY
DSPTAB(M$WRI1,MO$WRI,<WRITE-ENABLE>) ;Also WRITE:YES and WRITE:NO
$ETAB
;ALLOCATE and MOUNT options syntax tables
M$DAT1: $DATE(MOU040)
M$DEN1: $KEY(MOU040,M$DEN2)
M$DEN2: $STAB
KEYTAB(.TFD16,<1600-BPI>)
KEYTAB(.TFD20,<200-BPI>)
KEYTAB(.TFD55,<556-BPI>)
KEYTAB(.TFD62,<6250-BPI>)
KEYTAB(.TFD80,<800-BPI>)
$ETAB
M$FLD1: $FIELD(MOU040)
M$LAB1: $KEY(MOU040,M$LAB2)
M$LAB2: $STAB
KEYTAB(%TFANS,<ANSI>)
KEYTAB(%TFLBP,<BLP>)
KEYTAB(%TFLBP,<BYPASS-LABEL-PROCESSING>)
KEYTAB(%TFEBC,<EBCDIC>)
KEYTAB(%TFEBC,<IBM>)
KEYTAB(%TFUNL,<NOLABELS>)
KEYTAB(%TFUNL,<NONE>)
KEYTAB(%TFUNL,<UNLABELED>)
KEYTAB(%TFUNV,<USER-EOT>)
$ETAB
M$NUM1: $NUMBER(MOU040,^D10)
M$PRO1: $NUMBER(MOU040,^D8)
M$REM1: $QUOTE(MOU040,,$ALTER(M$REM2))
M$REM2: $FIELD(MOU040,,$BREAK(REMBRK))
REMBRK: 777777,,777760 ;Break on all control
777754,,001760 ;Allow - and 0-9
400000,,000760 ;Allow A-Z
400000,,000760 ;Allow LC A-Z
M$TRA1: $KEY(MOU040,M$TRA2)
M$TRA2: $STAB
KEYTAB(.TMDR7,<7-TRACK>)
KEYTAB(.TMDR9,<9-TRACK>)
$ETAB
M$VOL1: $TOKEN(M$VOL2,<(>,$ALTER(M$VOL5))
M$VOL2: $FIELD(M$VOL3)
M$VOL3: $COMMA(M$VOL2,$ALTER(M$VOL4))
M$VOL4: $TOKEN(MOU040,<)>,$ALTER(MOU040))
M$VOL5: $FIELD(MOU040)
M$WRI1: $KEY(MOU040,M$WRI2,<$DEFAULT(YES),$ALTER(MOU040)>)
M$WRI2: $STAB
KEYTAB(FALSE,<NO>)
KEYTAB(TRUE,<YES>)
$ETAB
;MOUNT and ALLOCATE commands
;These routines will parse a MOUNT or an ALLOCATE command.
; The parse blocks are built in a page of data supplied by the caller
;Call -
; S1/ Adrs of a page into which the mount message
; will be built
;Return -
; TRUE always.
; If there are ANY errors, these routines pull a $ERR macro
; which JSPs to a caller-defined ERROR label (external from here)
; which should handle the error condition.
.ALLOC::
TDZA F,F ;CLEAR FLAG WORD
.MOUNT::
MOVX F,FL.MOU+FL.WAT ;Set Mount and Wait flags
$SAVE <P1,P2,P3,P4> ;Preserve some AC's
$SAVE <T1,T2,T3,T4> ;SAVE THE TEMP ACS
MOVE P1,S1 ;Save the incoming page adrs
MOVE S1,['MOUNT '] ;Assume mount
TXNN F,FL.MOU
MOVE S1,['ALLOCA']
MOVEM S1,CMDNAM ;Save incase /HELP was typed
MOUN05: PUSHJ P,P$CFM ;Try to get EOL
SKIPF ;User didn't type CRLF yet
TXO F,FL.LST ;Default to /LIST if EOL already
$CALL DOSWS ;Parse leading switches
MOVEM F,DEFSWS ;Save sticky options
MOVEI P2,.MMHSZ(P1) ;P2 contains first free address
MOVEI S2,.QOMNT ;Get mount message type
STORE S2,.MSTYP(P1),MS.TYP ;Save in the message
MOVX S2,MF.ACK ;Get ACK request flag
MOVEM S2,.MSFLG(P1)
$CALL P$CFM ;Get confirmation
JUMPT MOUN80 ;Yes..just return
JUMPE S1,MOUN80 ;Return at end of command (MOUNT/CHECK)
HRROI T1,.GTNM1 ;Get user name
GETTAB T1, ;May I?
SETZ T1, ;No..
HRROI T2,.GTNM2 ;Get second half
GETTAB T2, ;May I?
SETZ T2, ;No..
DMOVEM T1,.MMUSR(P1) ;Store in message
MOVEI T1,2 ;Get arg count for account
SETO T2, ;My Job
HRROI T3,.MMUAS(P1) ;Store in message
MOVE S2,[.ACTRD,,T1] ;Get the account
ACCT. S2,
JFCL
MOUN10: INCR .MMARC(P1) ;Increment total message arg count
MOVE P3,P2 ;P3 points to current entry
ADDI P2,.MEHSZ ;P2 points to first free word
MOVE F,DEFSWS ;Get default options
SETZ S1, ;Initially, no flags
TXNN F,FL.MOU ;Is this a mount request?
MOVX S1,ME%ALC ;Get the allocate-only bit
MOVEM S1,.MEFLG(P3) ;Stash the flags
SETZM VOLCNT ;Clear the count of VOLIDS
MOUN20: $CALL P$FLD ;Was VSN specified?
SKIPN ARG.DA(S1) ;Make sure its not null
$ERR (<Volume set name must be specified>)
MOVEM S1,VSNADR ;Save address of Volume set name
HRROI S1,ARG.DA(S1) ;Point to volume set name string
$CALL DEVCHK ;See if actual device name given
MOVEM S2,VSNAME ;Save SIXBIT volume set name
MOVE T1,S2 ;Save Device name
CAIN S1,.TYDSK ;Is it a disk?
DEVNAM T1, ;Yes, translate logical name.
JRST MOUN21 ;Failed, or not a disk.
MOVE T3,VSNADR ;Get device name address.
MOVEI T2,2 ;Arg block is only 2 long now.
STORE T2,ARG.HD(T3),AR.LEN ;So stuff it.
SETZM ARG.DA(T3) ;Zap the current name
ADD T3,[POINT 7,ARG.DA] ;Make into byte pointer
TRZ T1,7777 ;Ensure only 4 characters
MOLO: SETZ T2, ;Loop to change SIXBIT to ASCIZ
ROTC T1,6 ;Shift a character into T2
ADDI T2,"A"-'A' ;Make into ASCII
IDPB T2,T3 ;Stuff into name
JUMPN T1,MOLO ;Continue until done
MOUN21: TXNE F,FL.TAP!FL.DSK ;Request type known?
JRST MOUN25 ;Yes..then allow it
JUMPF [CAIN S1,ER$EZD ; ersatz device?
$ERR(<Ersatz device ^W/S2/ may not be mounted>)
CAIN S1,ER$PLD ; pathological name?
$ERR(<Pathological device ^W/S2/ may not be mounted>)
CAIN S1,ER$ASN ; ambigious?
$ERR(<Ambigious structure name ^W/S2/>)
CAIN S1,ER$ISN ; illegal?
$ERR(<Illegal structure name ^W/S2/>)
CAIN S1,ER$GDN ; generic?
$ERR(<Generic device ^W/S2/ may not be mounted>)
JRST MOUN25] ;No..process as VSN
CAIN S1,.TYMTA ;Yes..was it tape?
TXO F,FL.TAP ;Yes..specify tape
CAIN S1,.TYDSK ;Was it disk?
TXO F,FL.DSK
MOUN25: $CALL P$TOK ;Was it terminated by a token?
JUMPF MOUN30 ;No..on to parse logical name
MOVE S1,ARG.DA(S1) ;Get the token
CAMN S1,[ASCIZ/:/] ;Was VSN: specified?
JRST MOUN30 ;Yes..on to get logical name
$CALL P$PREV ;Backup to token again
$CALL MO$VOL ;Process VOLID list
JRST MOUN25 ;See if VSN(list): was specified!
MOUN30: $CALL P$SIXF ;Get locical name
JUMPF MOUN40 ;Don't store junk
MOVEM S1,LOGNAM ;Save logical name
$CALL P$TOK ;Get optional ":"
MOUN40: $CALL DOSWS
TXNN F,FL.DSK ;Is this a disk request ?
TXNE F,FL.TRK ;Was /TRACK specified ?
JRST MOUN41 ;Yes, skip this
SETZM S1 ;clear S1
MOVE S2,VSNAME ;Get the volume set name in sixbit
CAMN S2,[SIXBIT/M9/] ;Did he specify M9 ?
MOVX S1,.TMDR9 ;Yes, get 9 track code
CAMN S2,[SIXBIT/M7/] ;Did he specify M7 ?
MOVX S1,.TMDR7 ;Yes, get 7 track code
JUMPE S1,MOUN41 ;Neither,,skip this
MOVEI S2,.TMDRV ;Get /TRACK: block type
PUSHJ P,ADDSUB ;Add /TRACK:x to message
MOUN41: PUSHJ P,BLDVSN ;Build the VSN
PUSHJ P,LOGCHK ;No - check out the logical name
SETZ S1, ;Clear entry flags
TXNE F,FL.SCR ;Scratch volume wanted?
TXO S1,TM%SCR!TM%WEN ;Yes
TXNE F,FL.NEW ;New volume set wanted?
TXO S1,TM%NEW!TM%WEN ;Yes
TXNE F,FL.WRT ;Write enabled?
TXO S1,TM%WEN ;Yes
TXNE F,FL.WLK ;Write locked?
TXO S1,TM%WLK ;Yes
TXNE F,FL.BYP ;Bypass labels?
TXO S1,TM%BYP ;Yes
TXNE F,FL.PAS ;Was /PASSIVE specified?
TXO S1,SM%PAS ;Yes
TXNE F,FL.NOC ;Was /NOCREATE specified?
TXO S1,SM%NOC ;Yes
TXNE F,FL.EXC ;Was /EXCLUSIVE specified?
TXO S1,SM%EXC ;Yes
TXNE F,FL.QTA ;Was /QUOTA specified?
TXO S1,SM%ARD ;Yes
IORM S1,.MEFLG(P3) ;Save the entry flags
MOVEI S1,.MNUNK ;Get unknown entry type
TXNE F,FL.TAP ;Was it a tape request?
MOVEI S1,.MNTTP ;Yes..then use tape entry type
TXNE F,FL.DSK ;Was it a disk request?
MOVEI S1,.MNTST ;Yes..then use disk entry type
MOUN52: STORE S1,ARG.HD(P3),AR.TYP ;Save request type
MOVE S1,P2 ;Close current entry
SUB S1,P3 ;Compute entry length
STORE S1,ARG.HD(P3),AR.LEN ;Save in entry header
$CALL P$COMMA ;No..then must be a comma
JUMPT MOUN10 ;Yes..Back to try again
$CALL P$CFM ;Confirmed?
JUMPT MOUN80 ;Yes..send what we have
$ERR (<Unrecognized command syntax>)
MOUN80: SETZB S1,.MMFLG(P1) ;Clear message flag word
TXNE F,FL.WAT ;Want to wait for the mount?
TXO S1,MM.WAT ;Yes..light the flag
TXNE F,FL.NOT ;Want terminal notification?
TXO S1,MM.NOT ;Yes..light the flag
MOVEM S1,.MMFLG(P1) ;Set the message flags
SUB P2,P1 ;Compute message length
STORE P2,.MSTYP(P1),MS.CNT ;Save it
MOVEI S1,PAGSIZ ;Send of the page
MOVE S2,P1
$RETT
;MOUNT option processors
DOSWS:: $CALL P$SWIT ;Get a switch if any
$RETIF ;No, return
$CALL 0(S1) ; Else call the processor
JRST DOSWS ;Process next switch
;ACTIVE option places disk in jobs active search list
MO$ACT: MOVX S1,TXT(/ACTIVE) ;Get error prefix
$CALL DSKCHK ;Must be disk
TXZ F,FL.PAS ;Clear Passive flag
$RETT
;CHECK option lists the mount queues
MO$CHE: TXO F,FL.CHK ;Set the flag
$RETT
;CREATE option
MO$CRE: MOVX S1,TXT(/CREATE) ;Get error prefix
$CALL DSKCHK ;Must be disk
TXZ F,FL.PAS!FL.NOC ;Clear Passive and Nocreate
$RETT
;DENSITY option requests specific tape density
MO$DEN: MOVX S1,TXT(/DENSITY) ;Get error prefix
$CALL TAPCHK ;Must be tape
$CALL P$KEYW ;Get proper density
MOVEI S2,.TMDEN
PJRST ADDSUB
;DEVICE option requests specific device type
MO$DEV: $CALL P$SIXF ;Get requested device
$RETT
;DISK option declares disk devices
MO$DIS: MOVX S1,TXT(/DISK)
$CALL DSKCHK ;Must be disk request
$RETT
;EXCLUSIVE option declares that exclusive ownership is requested
MO$EXC: MOVX S1,TXT(/EXCLUSIVE)
$CALL DSKCHK ;Must be disk
TXO F,FL.EXC ;Set the flag
$RETT
;LABEL-TYPE option
MO$LAB: MOVX S1,TXT(/LABEL-TYPE) ;Get error prefix
$CALL TAPCHK ;Must be a tape request
$CALL P$KEYW ;Get the LABEL type
MO$LA1: CAXN S1,%TFLBP ;Was it BYPASS?
TXO F,FL.BYP ;Yes..set the flag
TXO F,FL.LAB ;Note that something was said
MOVEI S2,.TMLT ;Create label type entry
PJRST ADDSUB
;NEW-VOLUME-SET option
MO$NEW: MOVX S1,TXT(/NEW-VOLUME-SET)
$CALL TAPCHK ;Tape requests only
TXO F,FL.NEW ;Set the flag
$RETT
;NOCREATE option
MO$NOC: MOVX S1,TXT(/NOCREATE)
$CALL DSKCHK ;Disk requests only
TXO F,FL.NOC
$RETT
;NOWAIT option
;
;NOTIFY option
MO$NOW: TXZ F,FL.WAT ;Clear the wait flag,,imply notify
MO$NOT: TXOA F,FL.NOT ;Notify on completion
MO$NNT: TXZ F,FL.NOT ;No notify
$RETT
;PASSIVE option
MO$PAS: MOVX S1,TXT(/PASSIVE) ;Get error prefix
$CALL DSKCHK ;Must be dsk
TXO F,FL.PAS ;Set the PASSIVE flag
$RETT
;PROTECTION option
MO$PRO: MOVX S1,TXT(/PROTECTION) ;Get error prefix
$CALL TAPCHK ;Must be tape
$CALL P$NUM ;Get the value
CAIL S1,0 ;Check the range
CAILE S1,MAXPRO
$ERR (<Protection out of range>)
MOVEI S2,.TMVPR ;Create protection entry
PJRST ADDSUB ; and return
;QUOTA option
MO$QTA: MOVX S1,TXT(/QUOTA) ;Get error prefix
PUSHJ P,DSKCHK ;Must be dsk
TXO F,FL.QTA ;Set the quota flag
$RETT
;READ-ONLY option
MO$REA: TXO F,FL.WLK ;Set write lock flag
$RETT
;REMARK option
MO$REM: TXO F,FL.REM ;Remember we saw it
$CALL P$QSTR ;Get quoted string
SKIPT
$CALL P$FLD ;Or simple field
$CALL CPYSUB ;Create .TMRMK subentry
MOVEI S1,.TMRMK ;Make entry type remark
STORE S1,ARG.HD(S2),AR.TYP
$RETT
;SCRATCH option
MO$SCR: MOVX S1,TXT(/SCRATCH) ;Get error prefix
$CALL TAPCHK ;Must be tape
TXO F,FL.SCR ;Set the flag
$RETT
;SHARABLE option
MO$SHA: MOVX S1,TXT(/SHARABLE)
$CALL DSKCHK ;Must be disk
TXZ F,FL.EXC ;Clear Exclusive
$RETT
;TAPE option
MO$TAP: MOVX S1,TXT(/TAPE)
$CALL TAPCHK
$RETT
;TRACKS option
MO$TRA: MOVX S1,TXT(/TRACKS) ;Get error prefix
$CALL TAPCHK ;Must be tape
$CALL P$KEYW ;Get the track type
TXO F,FL.TRK ;Set /TRACK: flag
MOVEI S2,.TMDRV
PJRST ADDSUB
;WAIT option
MO$WAI: TXO F,FL.WAT ;Set the flag
$RETT
;WRITE-ENABLE option
MO$WRI: $CALL P$KEYW ;Get YES or NO
JUMPF [TXO F,FL.WRT ;Default is WRITE:YES
$RETT]
JUMPE S1,[TXO F,FL.WLK ;Set write lock if WRITE:NO
$RETT]
TXO F,FL.WRT ;Set write enable if WRITE:YES
$RETT
;VOLID option
MO$VOL: MOVX S1,TXT(Volume identifier) ;Get the error prefix
SKIPE VOLCNT ;Have we been here before?
$ERR (<Only one volume identifier list is allowed>)
INCR .MECNT(P3) ;Bump subentry count
MOVE P4,P2 ;Save free address
ADDI P2,1 ;Reserve a word for header
$CALL P$TOK ;Get optional list token
JUMPF [$CALL MO$VO3 ;Allow only one volume
JRST MO$VO2] ;If no token is found
MO$VO1: $CALL MO$VO3 ;Get volume identifier
$CALL P$COMMA ;More to come?
JUMPT MO$VO1 ;Yes..get the whole list
$CALL P$TOK ;Check optional list token
JUMPF [$ERR(<Missing volume identifier list terminator>)]
MO$VO2: MOVE S1,P2 ;Get final free address
SUB S1,P4 ;Compute argument length
MOVS S1,S1 ;Put length in Left half
HRRI S1,.TMVOL ;Get Volume subtype entry
MOVEM S1,ARG.HD(P4) ;Store in subentry header
MOVE S1,P4 ;Point to argument
$CALL UNICHK ;Check VOLID uniqueness
SKIPT ;All OK?
$ERR (<Volume identifiers must be unique>)
$RETT
;Routine to store and individual volume identifier
MO$VO3: $CALL P$SIXF ;Get the first volume
JUMPF [$ERR(<Invalid volume identifier>)]
JUMPE S1,[$ERR(<Volume identifier must not be null>)]
MOVEM S1,0(P2) ;Store the volume name
AOS VOLCNT ;Increment volume count
ADDI P2,1 ;Increment free address
$RETT
SUBTTL MOUNT parser -- General routines
;ADDARG - Routine to add a 2 word argument to general message
;ADDSUB - Routine to add a 2 word subentry argument to MOUNT message
;ACCEPTS S1/ Data word to be stored in message
; S2/ argument type code
; P1/ Address of message header
; P2/ Address of first free word in message
; P3/ Address of current mount entry
ADDARG::
AOSA .OARGC(P1) ;Increment message arg count
ADDSUB::
INCR .MECNT(P3) ;Increment subargument count
MOVEM S1,ARG.DA(P2) ;Store data word
HRLI S2,ARG.SZ ;Get size of 2
MOVEM S2,ARG.HD(P2) ;Store in header
ADDI P2,ARG.SZ ;Point to next free word
$RETT
;CPYARG - Routine to copy argument to general message
;CPYSUB - Routine to copy subargument to MOUNT message
;ACCEPTS S1/ Address of argument header word
; S2/ Number of words in argument
;RETURNS S2/ Address of argument header in message
CPYARG::
AOSA .OARGC(P1) ;Increment message arg count
CPYSUB::
INCR .MECNT(P3) ;Increment subargument count
MOVS S1,S1 ;Create BLT pointer
HRR S1,P2
ADD S2,P2 ;Get Next Free address
BLT S1,-1(S2) ;Copy the whole argument
EXCH P2,S2 ;P2 points to next free address
$RETT ;S2 points to stored argument
;CPYSTR - routine to store asciz string
;ACCEPTS S1/ Pointer to source string
; S2/ Pointer to destination string
CPYSTR::
ILDB TF,S1
IDPB TF,S2
JUMPN TF,CPYSTR
$RETT
;TAPCHK - routine to ensure that we are processing a tape request
;DSKCHK - routine to ensure that we are processing a disk request
;ACCEPTS S1/ Pointer to error prefix
TAPCHK: TXNE F,FL.DSK ;Disk request?
$ERR (<^Q/S1/ is only valid for tape>)
TXO F,FL.TAP ;Remember we have a tape request
$RETT
DSKCHK: TXNE F,FL.TAP ;Tape request?
$ERR (<^Q/S1/ is only valid for disk>)
TXO F,FL.DSK ;Remember we have a disk request
$RETT
;LOGCHK - check and add LOGICAL name to mount request
LOGCHK: SKIPN S1,LOGNAM ;See if logical name
$RETT ;No--Just return
TXNE F,FL.DSK ;Disk request?
JRST LOGC.1 ;Yes--No logical name
DEVCHR S1, ;See if logical name in use
JUMPE S1,LOGC.2 ;No--Thats OK
TXNN S1,DV.ASC!DV.ASP ;Assigned by console or program?
JRST LOGC.2 ;No
SKIPE BATJOB ;Batch job?
$TEXT (,<% Specified logical name "^W/LOGNAM/" already in use>) ;Yes--Tell him
MOVX S1,<INSVL.(.FORED,FO.FNC)!FO.ASC>;Get a new channel
MOVEM S1,FBLK+.FOFNC ;Store
SETZM FBLK+.FOIOS ;No mode
MOVE S1,LOGNAM ;Get device
MOVEM S1,FBLK+.FODEV ;Store device
SETZM FBLK+.FOBRH ;And no buffers
MOVE S1,[.FOBRH+1,,FBLK] ;Point to FILOP.
FILOP. S1, ;Open the device
JRST LOGC.2 ;Cant
LOAD S1,FBLK+.FOFNC,FO.CHN ;Get channel
MOVEI S2,0 ;Clear logical name
DEVLNM S1, ;Zap it
JFCL ;We tried
MOVX S1,.FOREL ;Release function
STORE S1,FBLK+.FOFNC,FO.FNC ;Store it
MOVE S1,[1,,FBLK] ;Point to FILOP.
FILOP. S1, ;Release channel
JFCL ;Cant
LOGC.2: MOVE S1,LOGNAM ;Get logical name
MOVX S2,.TMLNM ;And block type
$CALL ADDSUB ;Add it
$RETT ;And return
LOGC.1: SKIPE BATJOB ;Batch job?
$TEXT (,<% Logical name "^W/LOGNAM/" ignored on disk structure ^W/VSNAME/:>) ;
$RETT ;Error and return
; Routine to build a volume set name into a MOUNT message block
; Call: PUSHJ P,BLDVSN
; <return>
;
; If the VSN is a generic device, then a VSN of DEV-xxxxxx (where xxxxxx
; is a random alpha-numeric value guaranteed to be unique) will be created.
; Otherwise, the existing VSN will be used.
;
BLDVSN: MOVEI TF,0 ;Clear character count
MOVEI S1,.TMSET ;Get subentry type
STORE S1,ARG.HD(P2),AR.TYP ;Store it
INCR .MECNT(P3) ;Increment subargument count
MOVEI S2,@VSNADR ;Get atring address - ARG.DA
ADD S2,[POINT 7,ARG.DA] ;Get byte pointer to read characters
MOVEI T1,ARG.DA(P2) ;Get storage address
HRLI T1,(POINT 7) ;Make a byte pointer
BLDV.1: ILDB S1,S2 ;Get a character
JUMPE S1,BLDV.2 ;Done ?
PUSHJ P,BLDV.C ;Store it
JRST BLDV.1 ;Loop back for another
BLDV.2: TXNE F,FL.GDV ;Generic device ?
PUSHJ P,BLDV.3 ;Yes - generate a special VSN
MOVX S1,.CHNUL ;Get a <NUL>
PUSHJ P,BLDV.C ;Store it
IDIVI TF,5 ;Count words in the VSN
ADDI TF,ARG.DA+1 ;Round up to the next full word
HRLM TF,(P2) ;Update word count
ADD P2,TF ;Get new first free word pointer
POPJ P, ;Return
BLDV.3: TXNE F,FL.MOU ;If ALLOCATE,,thats an error
SKIPN BATJOB ;If a batch pre-scan,,thats an error
$ERR (<Illegal volume set name specified for MOUNT/ALLOCATE command>)
MOVEI S1,"-" ;Get a funny character
PUSHJ P,BLDV.C ;Store it
$CALL I%NOW ;Get the current time
MOVEI T2,6 ;Only 6 characters
BLDV.4: IDIVI S1,^D36 ;Radix 36
PUSH P,S2 ;Save the remainder
SOSE T2 ;Count characters
PUSHJ P,BLDV.4 ;Recurse if not done
POP P,S1 ;Get a digit
ADDI S1,"0" ;Make it ASCII
CAILE S1,"9" ;A number ?
ADDI S1,"A"-"9"-1 ;No - make it a letter
BLDV.C: IDPB S1,T1 ;Store it
ADDI TF,1 ;Count characters
POPJ P, ;Return
;UNICHK - routine to ensure uniqueness among argument entries
;ACCEPTS S1/ Address of argument header
UNICHK: LOAD T2,ARG.HD(S1),AR.LEN ;Get argument length
MOVE T1,S1 ;Save beginning address
ADDI T2,-1(S1) ;Compute end test address
UNICH1: ADDI T1,1 ;Compute next address
CAML T1,T2 ;Done?
$RETT ;Yes..all are unique
MOVEI S2,1(T1) ;S2 points to comparision entry
MOVE S1,0(T1) ;Get entry to check
UNICH2: CAMLE S2,T2 ;Finished checking this entry?
JRST UNICH1 ;Yes..back for next
CAME S1,0(S2) ;No..is it unique?
AOJA S2,UNICH2 ;Yes..back to check next entry
$RETF ;No..return the failure
;DEVCHK - routine to ensure device string is valid
;ACCEPTS S1/ Pointer to device name string
;RETURNS S1/ Device type (.TYDSK or .TYMTA)
; S2/ Sixbit device name (abbrv of name string)
;ERRORS ER$IDN Invalid device name
; ER$NSD No such device
; ER$USD Unsupported device
; ER$EZD Ersatz device
; ER$PLD Pathological device
; ER$ASN Ambigious structure name
; ER$ISN Illegal structure name
; ER$GDN Generic device name
DEVCHK: $CALL S%SIXB ;Convert to sixbit
ILDB S1,S1 ;Get terminator
JUMPN S1,[$RETER(ER$IDN)] ;Invalid device name
$SAVE <S2,P1,P2,P3> ;Save sixbit for return
MOVE P1,S2 ;Save the device name
MOVE TF,[1,,P1] ;Yes, get DSKCHR parms
DSKCHR TF, ;Get structure status bits
JRST DEVC.1 ;Not a disk
LOAD TF,TF,DC.TYP ;Get the device type
CAXN TF,.DCTAB ;Ambigious?
$RETER(ER$ASN) ;Yes, say so
CAXE TF,.DCTUF ;Unit within strcuture?
CAXN TF,.DCTCN ;Controller class?
$RETER(ER$ISN) ;Yes, illegal structure
CAXE TF,.DCTCC ;Controller class?
CAXN TF,.DCTPU ;Physical unit?
$RETER(ER$ISN) ;Yes, illegal structure
CAXN TF,.DCTDS ;Generic or ersatz?
JRST DEVC.2 ;Yes, check it out some more
MOVX S1,.TYDSK ;Its a disk
$RETT ;And return
DEVC.2: MOVE TF,[3,,P1] ;Get PATH. args
PATH. TF, ;Find out some more
$RETT ;Ignore any error
TXNE P2,PT.DLN!PT.EDA ;Pathological name?
$RETER(ER$PLD) ;Yes, say so
TXNE P2,PT.IPP ;Implied PPN? (ersatz)
$RETER(ER$EZD) ;Yes, say so
$RETER(ER$GDN) ;Else call it generic
DEVC.1: DEVTYP S2, ;Get device type
$RETER(ER$NSD) ;Unknown device
JUMPE S2,[$RETER(ER$NSD)] ;Unknown device
TXNE S2,TY.GEN ;A generic device ?
TXO F,FL.GDV ;Yes - remember it
LOAD S1,S2,TY.DEV ;Load the device type
CAIE S1,.TYMTA ;Is it a tape??
$RETER(ER$USD) ;No,,Unsupported device
;(DSKCHR would win if a disk)
$RETT ;Yes,,return
SUBTTL MOUNT parser -- Data Storage
XLIST ;Turn listing off
LIT ;Dump literals
LIST ;Turn listing on
$DATA DEFSWS,1 ;Sticky mount switches
$DATA VOLCNT,1 ;Number of volume identifiers specifed
$DATA LOGNAM,1 ;Logical name
$DATA FBLK,.FOMAX ;FILOP. UUO block
;Global data
$GDATA VSNAME,1 ;6bit Volume set name
$GDATA VSNDEV,1 ;6 bit device name
$GDATA VSNADR,1 ;Address of ASCIZ Volume set name argnt
$GDATA CMDNAM,1 ;Address of parsed command name
$GDATA BATJOB,1 ;Batch job flag (0 = batch job)
SUBTTL End
END