Google
 

Trailing-Edge - PDP-10 Archives - bb-d868b-bm_tops20_v3a_2020_dist - 3a-sources/batcon.mac
There are 39 other files named batcon.mac in the archive. Click here to see a list.
TITLE	BATCON  --  GALAXY Batch Job Controller
SUBTTL	C.D.O'Toole/CDO  13 Nov 77

	LSTING==0		;NORMAL MODE IS LISTING ON

	BTNVER==103		;MAJOR VERSION NUMBER
	BTNMIN==0		;MINOR VERSION NUMBER
	BTNEDT==3000		;EDIT NUMBER
	BTNWHO==0		;WHO LAST PATCHED

	SEARCH	QSRMAC		;QUASAR DATA BASE SYMBOLS

	PROLOGUE(BATCON)	;GENERATE THE REST OF THE SYMBOLS

	.REQUIRE CSPQSR		;COMPONENT TO QUASAR INTERFACE
	.REQUIRE CSPMEM		;MEMORY INTERFACE
	.REQUIRE SBSCOM		;COMMON ROUTINES



;COPYRIGHT (C)  1974, 1975, 1976, 1977 BY
;DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;
;
;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.
SUBTTL	Assembly Parameters
IFN FTUUOS,<		;DEFINITIONS FOR TOPS10

	IF1,<PRINTX ASSEMBLING GALAXY-10 BATCON>

DEFINE KJSTR,<[ASCIZ\KJOB/BATCH\]>
DEFINE TIMSTR,<[ASCIZ/SET TIME /]>

>  ;END OF IFN FTUUOS



IFN FTJSYS,<		;DEFINITIONS FOR TOPS20

	IF1,<PRINTX ASSEMBLING GALAXY-20 BATCON>

DEFINE KJSTR,<[ASCIZ\LOGOUT\]>
DEFINE TIMSTR,<[ASCIZ/SET TIME-LIMIT /]>

OPDEF	MONRT.	[HALTF]		;RETURN TO THE MONITOR

	.FDSTR==.FDSTG		;REDEFINE SYMBOL IN FD AREA
	CTLBFR==4		;MUST BE 4 SO THAT BUFFERS = 1 PAGE

>  ;END OF IFN FTJSYS
	SUBTTL	Revision History

	COMMENT	\

EDIT 1000  This was the version sent to In-House Q/A April 1974

EDIT 1001  Correct mixup in the channel allocator if the CTL file is not
		artifically preserved and DISPOSE:PRESERVE is set

EDIT 1002  Have BACKTO give the correct error if the label was not
		found BEFORE the initiating BACKTO command

EDIT 1003  Allow BACKTO and restart labels to skip over %FIN::

EDIT 1004  Allow NEXT command to select a job after the
		KSYS timer has expired

EDIT 1005  Fix interaction of SILENCE & REVIVE commands with
		DIALOGUE mode & QUOTES (")

EDIT 1006  Correct random little annoyances discovered by Q/A

EDIT 1007  On a line with only the label (e.g. FOO::<CR/LF>),
		the <CR/LF> is NOT to be sent to the subjob.  However,
		FOO::*<CR/LF> gives a blank line to the subjob.
		Same for IF (cond)<CR/LF>

EDIT 1010  Reformat WHAT line for the operators

EDIT 1011  Accept TELL, KILL, REQUEUE, etc...  when a job is STOPped

EDIT 1012  More of EDIT 1005, still a problem with SILENCE & REVIVE

EDIT 1013  Reformat DIALOGUE mode output for the operator

EDIT 1014  Include .MESSAGE for the Mini-Batch Standard
		It is the same as PLEASE <message><altmode><CR/LF>

EDIT 1015  Give more information when the user can't use the specified LOG file

EDIT 1016  General cleanup of code and elimination of
		subroutines no longer needed

EDIT 1017  Make more efficient use of old PTY channels.
		Big help when MJOB .GT. 5

EDIT 1020  Correct problem with REQUEUE labels

EDIT 1021  This was the version sent to Field Test June 1974
EDIT 1022  A leading tab was changed into a blank, shouldn't do that

EDIT 1023  Include /NAME:"<name>" on the LOGIN line

EDIT 1024  LOGIN error code 1 is the same as a warning message.
		Treat it as such.

EDIT 1025  Plug a hole in the SFD code

EDIT 1026  Can only force /RESTART:YES on Checkpoint

EDIT 1027  Post-job disposal of the CTL file wasn't done if the job
		was cancelled because of LOGIN

EDIT 1030  Provide some additional information in the CURRENT command output

EDIT 1031  Some more general cleanup

EDIT 1032  Routines that save and restore the CTL file position were being
		thrown off by "^" in strange places

EDIT 1033  Include BTNxxx for all error messages the user receives

EDIT 1034  Using "1H+" for Fortran overprinting would start at the time
		stamp, not at column 17

EDIT 1035  Implement several suggestions

EDIT 1036  QTS was called from one place, remove lots of code and
		change all references to QTS0 to QTS

EDIT 1037  A timing problem was introduced by EDIT 1024, correct it.

EDIT 1040  Implement more suggestions

EDIT 1041  This was the version released to the Field November 1974
Edits made to version 12 by Software Support that are also in version 100

EDIT 1051  GETSTS returns the status in the right half, Teach this to GETCTL. (SPR 15846)

EDIT 1054  Suppress trailing blanks on lines destined for the monitor command decoder.
		This should avoid any problems associated with card input.

EDIT 1055  With edit 477 of LOGIN, LOGMAX is now enforced. Invent error code
		5 to mean requeue this job, shutdown Batch for NJNINT minutes.
		(SPR 16184)




Edits made during the development of version 13 that are also in version 100


EDIT 1060  Separate old and new LOG files with a Form-Feed.
		Do this to more easily recognize when a LOG file is used more than once
		(SPR  several suggestions)

EDIT 1061  Invent a new reserved label %TERR::.  Control is passed to this label
		if TIME LIMIT EXCEEDED is detected.  It follows the same rules of
		precedence as %ERR:: with respect to %FIN::.  The %EXTRA time
		is given but the CLOSE/DUMP is not sent, allowing REENTER to be used for
		program cleanup for intelligent jobs.

EDIT 1063  De-implement the following:
	    (maintained for 1 versions worth of compatability)
		The FORCE Command (use NEXT)
		The old style $ processing for CDRSTK (who?)

EDIT 1064  The correct path wouldn't be sent to LOGIN if there were no
		SFD levels.  Send it if the P,Pn's are different.

EDIT 1070  Plug a security hole.
EDIT 2000  Begin conversion of MPB BATCON (v12) to the GALAXY-10 system

	     Major changes (aside from queueing protocol) include:

		Remove FTOPR options for a separate BATOPR
		Remove all code for LOGSWS conditionals, LOGIN v.57 is required
		De-implement edit 1017
		Redefine AC usage to conform with QUASAR's
		Change ATOKJB to talk to LOGOUT v.100
		CORE/MCORE parameters are P internally but K for the operators.
		Remove WHKSYS conditionals, Work is done by QUASAR
		At the request of our operators, the default value of PROMPT is 5 min.
		Remove all the BATCON assembly parameters that are now
		   defined in the GALGEN dialogue.

	     This was the version sent with GALAXY-10 Field Test,  June 1975

EDIT 2001  Report the P,Pn of the user requesting the cancellation of a job (ABO.DI)

EDIT 2002  Can get a job from QUASAR with EQ.RDE set, turn them around.

EDIT 2003  Quotes (") output from LOGOUT should be typed to the operator.

EDIT 2004  Fix all the code dealing with core limit enforcment.
		INPCOR, the default value of /CORE, is used to conditionally
		assemble the enforcement code.  If defined = 0, code is not assembled
		since NO was answered to the GALGEN question concerning core enforcment.

EDIT 2005  Take advantage of the new routine in CSPQSR.  Call CSPPSI to enable
		terminal input interrupts, avoid lots of SKPINL's.
	   General code cleanup.

EDIT 2006  Become version 101

EDIT 2007  .EQPAT is optional, Check for it.

EDIT 2010  Convert to TOPS20 style LOGIN, File handling, etc...

EDIT 2011  Fix all the bugs caused by edit 2010

EDIT 2012  The TOPS10 code got broken by edits 2010 & 2011, fix that.

EDIT 2013  Implement the new values for /OUTPUT, they are:
		/OUTPUT:NOLOG	Don't print the LOG
		/OUTPUT:LOG	Print it (default)
		/OUTPUT:ERROR	Print it if an unhandled error occurred
EDIT 2014  Some Code Cleanup and Bug Fixes, Specifically:
		Use the PROLOGUE macro to get SBSMAC Symbols.
		Calling sequence to CSPINI has changed.
		6.03 Monitor uses 1B2 of the OPEN of a PTY to indicate
			that jobs on that PTY are Batch.
		A bug in the TOPS20 code that PMAP'ed away my addressing space
			is corrected (a real cute one).
		Another TOPS20 bug that left the Log file JFN hanging around.
		The CHECKPOINT/REQUEUE messages have changed.
		Remove the old MPB restriction of 5 character labels
			for CHKPNT and /TAG.

EDIT 2015  On the -20, before logging a job out delete any spooled
		input files created by SPRINT for it.

EDIT 2050  Become version 102.
	   Begin to eliminate TOPS10 UUOs on TOPS20.

EDIT 2051  More of Edit 2050.

EDIT 2052  Add ROUTE operator command, tell QUASAR of operators request.

EDIT 2053  Removed

EDIT 2054  Start converting to the version 2 database format.

EDIT 2055  Convert to TOPS20 release 2 JSYSes.

EDIT 2056  Do some cleanup work on operator output.

EDIT 2057  Rework LOG file logic to do "in-his-behalf" FILOP on the -10.

EDIT 2060  Include jobname, user id, and sequence number on
	   all messages to the operator.  Fix a problem on the -20
	   where the LOGIN command was not always sent correctly.

EDIT 2061  Remove angle brackets around user name on "cancelled" message
	    on the -20.  Fix some minor problems.

EDIT 2062  Spooled card-reader files were not getting deleted on 20 due
		to a recently introduced bug in DELSPL.

EDIT 2063  Fix a timing problem on -20 which caused BATCON
		to not realize a job had really logged out.

;;First field-test release of GALAXY release 2, Jan, 1977

EDIT 2064  Fix a bad symbol reference in -10 version when core
		enforcement is turned on (%NSMXM). QAR #3.

EDIT 2065  Make log files work on device NUL on the -20.
		Don't CHKAC them and don't send to LPTSPL.
EDIT 2066  Fix a bug caused by edit 2052 which let BATCON start
		processing jobs before a START command was typed.
		(qar #9).

EDIT 2067  Edit 2066 caused some additional problems.  Try again.

EDIT 2070  Context switch in CPYOUT to fix a very elusive timing problem.
		LLN,  11-May-77      SPR #20-10487.

EDIT 3000  Make this version 103.  Insert patch to keep waiting to kill
		a job rather than asking operator for help on -20.

	\
	SUBTTL	Assembly Parameters (Define the Options)

DEFINE	PARMS<

;;TYPE 1 OPTIONS - DEFINE STATIC PARAMETERS

	X	ONESEG,0	;;NORMALLY A TWO SEGMENT PROGRAM
	X	CTLBFR,2	;;NUMBER OF CTL BUFFERS IN CORE
	X	LOGBFR,2	;;NUMBER OF LOG BUFFERS IN CORE
	X	PTYBFR,1	;;NUMBER OF PTY BUFFERS IN THE RING
	X	PROMPT,5	;;TIMER IN MINUTES FOR JOBS IN OPERATOR WAIT
	X	JOBMSG,0	;; 1 IF JOB STARTED/ENDED MESSAGES ARE DESIRED

;;TYPE 2 OPTIONS - DEFINE DEFAULTS AND RANGES FOR OPERATOR COMMANDS

	X	DEFMJB,^D5	;;DEFAULT VALUE OF 'MJOB' WHEN STARTED
	X	REQTIM,^D10	;;DEFAULT REQUEUE TIME IN MINUTES

;;TYPE 3 OPTIONS - DEFINE OTHER PARAMETERS

	X	TPSIZE,50	;;SIZE OF THE TOP LEVEL PUSH DOWN LIST
	X	.JPSIZ,30	;;SIZE OF THE STACK FOR EACH SUBJOB
	X	NJNINT,^D4	;;MINUTES TO WAIT IF JOB CAPACITY IS EXCEEDED
	X	CH.LGI,"/"	;;CHARACTER SENT BETWEEN PROJ AND PROG NUMBERS
	X	%EXTRA,^D10	;;PERCENTAGE OF EXTRA TIME GIVEN TO A JOB
	>

DEFINE	X(A,B)<IFNDEF A,<A==B>> ;;DEFINE THE SYMBOL IF NOT ALREADY DEFINED

	PARMS			;EXPAND THE ASSEMBLY PARAMETERS

	MIN	<^D14,INPNUM>,JOBMAX,	;SMALLEST OF 14 AND GALGEN BATCH STREAMS

	SYSPRM	MONCHR,".","@"	;MONITOR PROMPT CHARACTER
				;USED AS FIRST CHARACTER OF INPUT LINE TO
				;DIRECT LINE TO THE MONITOR
	SYSPRM	OPRPST,<ASCIZ /B/>,<ASCIZ /B-/>  ;OPR PROMPT STRING
;CONSISTENCY CHECK FOR ASSEMBLY PARAMETERS

	IFLE	DEFMJB,<
		PRINTX DEFMJB.LT.1, 1 ASSUMED
		DEFMJB==1>

	IFG	<DEFMJB-JOBMAX>,<
		PRINTX DEFMJB.GT.JOBMAX, JOBMAX ASSUMED
		DEFMJB==JOBMAX>

	IFN	PROMPT,<
	  IFL	<PROMPT-1>,<
		PRINTX PROMPTING INTERVAL .LT. 1 MINUTE, 1 MINUTE ASSUMED
		PROMPT==1>>

	IFL	<NJNINT-1>,<
		PRINTX NO JOB NUMBER WAIT .LT. 1 MINUTE, 1 MINUTE ASSUMED
		NJNINT==1>

	IFLE	CTLBFR,<
		PRINTX CTLBFR.LT.1, 1 ASSUMED
		CTLBFR==1>

	IFLE	LOGBFR,<
		PRINTX LOGBFR.LT.1, 1 ASSUMED
		LOGBFR==1>

	IFLE	PTYBFR,<
		PRINTX PTYBFR.LT.1, 1 ASSUMED
		PTYBFR==1>

	IFL	<%EXTRA-^D10>!<^D100-%EXTRA>,<
		PRINTX BAD VALUE FOR THE PERCENTAGE OF EXTRA TIME, 10% ASSUMED
		%EXTRA==^D10>

	IFLE	REQTIM,<
		PRINTX REQUEUE TIMER .LT. 1 MINUTE, 1 MINUTE ASSUMED
		REQTIM==1>
	SUBTTL	Other Definitions (Bits, AC's, Macros, etc...)

;ACCUMULATOR DEFINITIONS (MUST BE IN THE ORDER DISTRIBUTED)
;THESE DEFINITIONS PARALLEL QUASAR-10 DEFINITIONS

;AC BLOCK 0-13 IS SAVED FOR EACH STREAM IN .JREGS(R)
;AC 17 IS ALSO SAVED

T1==1		;TEMPORARY AC (QUASAR AC 'S1')
T2==2		;    "     "  (QUASAR AC 'S2')

;AC'S (A - D) ARE QUASAR AC'S (T1 - T4)
;AND CAN BE SAVED BY CALLING CO-ROUTINE .SAVET IN CSPMEM

A==3		;BEGINNING OF 4 REGS FOR LOOKUP/ENTER AND THINGS
B==4		;CAN BE USED FOR OTHER THINGS IF UNDERSTOOD
C==5		;THAT THEY CAN BE CLOBBERED BY ANY I/O SELECT
D==6		;FOR THE PTY, CTL FILE, OR LOG FILE

IO1==7		;REGISTERS USED BY THE I/O HANDLER
IO2==10

F==11		;ONE OF THE FLAG WORDS FOR THE STREAM (AC R IS THE OTHER)

J==12		;JOBSTS FOR THE STREAM

CH==13		;RANDOM CHARACTER HOLDER (QUASAR AC 'AP')

;END OF SAVED AC'S FOR EACH STREAM

G==14		;GLOBAL BATCON FLAGS
S==15		;STREAM INDEX
R==16		;RELOCATION FOR THE STREAM (LH ARE STREAM FLAGS)

P==17		;PUSH DOWN LIST POINTER
		;IS USED FOR BOTH TOP LEVEL PDL
		;AND INDIVIDUAL STREAM LISTS




;DEFINE SOME CONSTANTS AFTER CONSISTENCY CHECKS (PS. DON'T EVER CHANGE THESE)

DSKBLK==^D128		;WORDS IN A DISK BLOCK
PTYBLK==23		;WORDS IN A PTY BUFFER
CTLCHR==<DSKBLK*5>*CTLBFR ;NUMBER OF CHARACTERS BUFFERED FOR CTL FILE
LOGCHR==<DSKBLK*5>*LOGBFR ;NUMBER OF CHARACTERS BUFFERED FOR LOG FILE

HIBERP==260,,0		;HIBERNATE UUO PARAMETER BITS

IFN INPCOR,<HIBERP==260,,^D60000>  ;WATCH CORMAX EVERY MINUTE
IFN FTJSYS,<HIBERP==260,,^D15000>  ;WATCH FOR INCOMING JOBS ON TOPS20
;FLAG SETTINGS OF GLOBAL MEANING

;AC G (LH)

GL.STA==400000	;BATCH IS STARTED
GL.SSH==200000	;OPERATOR WANTS TO STOP SCHEDULING
GL.NJN==100000	;NO MONITOR JOB NUMBERS
GL.STC==040000	;SOMETHING CAUSED A STATUS CHANGE
GL.ALL==020000	;SUBJOB SPECIFIED WAS ALL
GL.RMT==010000	;THE MONITOR HAS REMOTE STATION FEATURE
GL.PAG==004000	;LAST MESSAGE WAS PAGED
GL.EXI==002000	;OPERATOR EXIT COMMAND IN EFFECT
GL.CON==001000	;CONTACT WITH QUASAR
GL.UC0==000400	;TURN OFF THE CHANNEL USURPER

;AC G (RH)


;INITIAL SETTINGS FOR G

GL.INI==GL.ALL		;DEFAULT SUBJOB IS ALL
GR.INI==0		;NO RIGHT HALF FLAGS


;FLAGS SETTINGS FOR BATCH STREAMS

;AC R (LH FLAGS ONLY)

RL.ACT==400000	;STREAM IS ACTIVE (MUST BE THE SIGN BIT)
RL.UST==200000	;USETI/USETO NEEDED FOR CTL/LOG FILES
RL.JNA==100000	;JOB NUMBER IS EVER ASSIGNED
RL.OPR==040000	;WAITING FOR OPERATOR RESPONSE
RL.TIM==020000	;TIME STAMP IS NEEDED FOR THE LOG FILE
RL.JIE==010000	;JOB IS IN ERROR STATE
RL.FCI==004000	;FIRST CHARACTER OF INPUT FROM CTL FILE
RL.KJB==002000	;AUTO KJOB LINE HAS BEEN SENT
RL.IGN==001000	;DONT SAVE CHARS FOR THE OPERATOR LINE
RL.DCT==000400	;USER HAS PRIVS TO DELETE THE CTL FILE
RL.CMT==000200	;A COMMENT FROM THE OPERATOR IS READY
RL.LGI==000100	;JOB IS LOGGING IN NOW
RL.EOL==000040	;END OF LINE CHARACTER HAS BEEN SENT
RL.QTS==000020	;QUOTES SEEN
RL.DIA==000010	;USER IS IN DIALOGUE MODE
RL.STP==000004	;JOB IS STOPPED BY THE OPERATOR
RL.NLG==000002	;NO LOG FILE AVAILABLE

;INITIAL SETTINGS FOR R

RL.INI==RL.ACT!RL.LGI	;FOR A NEW JOB SET ACTIVE, LOGIN IN PROGRESS
;AC F (LH)

FL.PER==400000	;MONITOR LEVEL LINE STARTED WITH A PERIOD
FL.NER==200000	;NOERROR IS IN EFFECT
FL.PLS==100000	;DOING A PLEASE COMMAND
FL.SUP==040000	;SUPPRESS THE NULL LINE (=MODE)
FL.LUP==020000	;LOG FILE HAS BEEN UPDATED, USETO POINTERS ARE CORRECT
FL.LAB==010000	;FOUND A LABEL ON THIS LINE
FL.SIL==004000	;SILENCE THE LOG FILE
FL.UPA==002000	;DOING UPARROW PROCESSING
FL.ACC==001000	;NEED TO CHECK READ PRIVLEGES FOR THE CTL FILE
FL.TLE==000400	;TIME LIMIT WAS EXCEEDED
FL.%XT==000200	;%EXTRA TIME HAS BEEN GIVEN
FL.EXM==000100	;OPERATOR WANT TO EXAMINE THE CTL FILE
FL.KIL==000040	;OPREATOR WANTS TO KILL THIS JOB
FL.REQ==000020	;OPERATOR WANTS TO REQUEUE THIS JOB
FL.CRS==000010	;CARRIAGE RETURN SEEN

;AC F (RH)

FR.RSC==400000	;WANT COMMAND SCANNER TO RE-GET LAST CHARACTER
FR.%SG==200000	;A % SIGN IS A LEGAL SIXBIT CHARACTER
FR.FSI==100000	;FORCED USETI IN GETCTL
FR.BAK==040000	;BACKTO IN PROGRESS
FR.LSL==020000	;LIST LINES SKIPPED IN LABEL SEARCHES
FR.FIN==010000	;THIS LABEL SEARCH CAN PASS A %FIN::
FR.ABU==004000	;JOB CANCELLED BY USER /KILL COMMAND
FR.FLL==002000	;FIRST LOOK AT THE LOG FILE
FR.UHE==001000	;AN UNHANDLED ERROR OCCURRED
FR.NBL==000400	;IN GETRDX, A NON-BLANK HAS BEEN FOUND

;INITIAL SETTINGS FOR F

FL.INI==FL.ACC		;FOR A NEW JOB NEED A CHECK
FR.INI==FR.FLL		;FIRST LOOK AT THE LOG FILE
;FLAGS RETURNED BY THE JOBSTS UUO

JL.UJA==400000	;USER JOB NUMBER ASSIGNED
JL.ULI==200000	;USER LOGGED IN
JL.UML==100000	;USER IS AT MONITOR LEVEL
JL.UOA==040000	;USER OUTPUT IS AVAILABLE
JL.UDI==020000	;USER CAN DO INPUT
JL.UJC==010000	;USER HAS JACCT

;CHARACTERS

CHR.CC==3	;CONTROL C
CHR.CG==7	;CONTROL G
CHR.HT==11	;HORIZONTAL TAB
CHR.LF==12	;LINE FEED
CHR.VT==13	;VERTICAL TAB
CHR.FF==14	;FORM FEED
CHR.CR==15	;CARRIAGE RETURN
CHR.CZ==32	;CONTROL Z
CHR.A1==33	;STANDARD ALTMODE
CHR.OA==74	;OPEN ANGLE BRACKET
CHR.CA==76	;CLOSE ANGLE BRACKET
;GETTAB TABLES

.GTSTS==0	;USER JOB STATUS
	ST.RUN==1B0	;JOB IS RUNNABLE NOW
	ST.CMW==1B1	;COMMAND IS WAITING FOR CORE
	ST.SWP==1B7	;JOB IS SWAPPED OR BEING SWAPPED
	ST.CLK==1B18	;JOB HAS A CLOCK REQUEST
	ST.JDC==1B20	;WAITING FOR DUMP
	ST.IRQ==1B22	;WAITING FOR OPERATOR INTERVENTION

.GTPRG==3	;USER PROGRAM NAME
.GTWSN==25	;TABLE OF SIXBIT NAMES FOR WAIT CODES

;OPCODE DEFINITIONS

OPDEF	TXTLOG	[001000,,0]	;BATCON UUO - TEXT TO THE LOG FILE
OPDEF	TXTJOB	[002000,,0]	;BATCON UUO - TEXT TO THE JOB
OPDEF	SIXLOG	[003000,,0]	;BATCON UUO - SIXBIT TEXT TO THE LOG FILE
OPDEF	SIXJOB	[004000,,0]	;BATCON UUO - SIXBIT TEXT TO THE JOB
OPDEF	MSGTTY	[005000,,0]	;BATCON UUO - AN ERROR MESSAGE TO THE TTY
OPDEF	MSGLOG	[006000,,0]	;BATCON UUO - AN ERROR MESSAGE TO THE LOG FILE
OPDEF	IDENT	[007000,,0]	;BATCON UUO - OUTPUT LINE IDENTIFIER
IFN FTJSYS,<
OPDEF	OUTCHR	[010000,,0]	;BATCON UUO - CHARACTER TO THE TTY
OPDEF	OUTSTR	[011000,,0]	;BATCON UUO - STRING TO THE TTY
>  ;END OF IFN FTJSYS
;MACRO DEFINITIONS

DEFINE	LSTOFF<			;MACRO TO TURN OFF THE LISTING
	IFE	LSTING,<
		.XCREF
		XLIST>
	LSTING==LSTING+1	;COUNT XLIST DEPTH
	>

DEFINE	LSTON<			;MACRO TO TURN THE LISTING BACK ON
	LSTING==LSTING-1	;DECREMENT XLIST LEVEL
	IFE	LSTING,<	;DON'T TURN IT ON IF STILL NESTED
		.CREF
		LIST
		SALL>
	>




;SET UP FOR BALANCE OF ASSEMBLY

IFE ONESEG,<TWOSEG>	;ASSEMBLING MULTI SEGMENT PROGRAM

	LOC	41
	PUSHJ	P,UUOCON	;UUO INTERRUPT

	LOC	137
	BYTE	(3)BTNWHO (9)BTNVER (6)BTNMIN (18)BTNEDT

	RELOC	0

IFE ONESEG,<RELOC 400000>	;MULTI SEGMENT PROGRAM, START IN THE HIGH SEG
	SUBTTL	BATCON Entry Section

BATCON:	JFCL			;NO CCL ENTRY POINT
	RESET
	MOVE	P,[IOWD TPSIZE,TOPPDL]
	ZERO	S1		;WANT CSPQSR TO HANDLE THE INTERRUPT SYSTEM
	PUSHJ	P,CSPINI##	;INITIALIZE THE CUSP - QUASAR INTERFACE
	MOVE	G,[GL.INI,,GR.INI] ;SET INITIAL ENTRY FLAGS
	SETZM	LOWDAT		;PREPARE TO CLEAR THE LOW SEG
	MOVE	A,[LOWDAT,,LOWDAT+1]
	BLT	A,LASLOW-1	;CLEAR ALL THE LOW SEGMENT
	MOVEI	A,DEFMJB	;GET DEFAULT VALUE OF MJOB
	MOVEM	A,MJOB
	MOVEI	A,777777	;SET TIME VALUES VERY LARGE
	MOVEM	A,UTIME		;AS SINGLE JOB MAXIMUM
	MOVEM	A,ATIME		;AND TOTAL OF ALL BATCH
	MOVEM	A,CORPHY	;SET UP PHYSICAL MEMORY
	MOVEM	A,CORMAX	;AND SINGLE JOB LIMIT VERY LARGE
	PUSHJ	P,CONTTY	;ENABLE THE COMMAND TERMINAL
	PUSHJ	P,ONCECN	;SET UP ONCE ONLY CONSTANTS
	PUSHJ	P,UPDADD	;SET UP SYSTEM DEFAULTS BEFORE STARTING
	PUSHJ	P,OPRSTA	;PROMPT OPERATOR NOW
	SUBTTL	Dispatch and Time slice Routines

TOPLVL:	PUSHJ	P,OPRCOM	;ATTEND THE OPERATOR
	SKIPN	STACTV		;ANY STREAMS ACTIVE
	  JRST	DISP.3		;NO, SEE IF SCHEDULING HAS HAPPENED
TOPDIS:	PUSHJ	P,GETMST	;GET CURRENT TIME (MS.)
	MOVEM	T1,CURMST	;SAVE FOR TIME STAMPS, TIMERS, ETC..
	MOVEI	S,1		;START AT THE BEGINNING
DISP.1:	SKIPGE	R,BASTBL-1(S)	;IS THIS STREAM ACTIVE
	JSP	A,CHKOPR	;YES, CHECK IF JOB IS IN OPERATOR WAIT
	  JRST	DISP.2		;CANNOT PROCESS THIS STREAM
	MOVSI	17,.JREGS(R)	;SET TO RESTORE PROCESSOR REGS
	BLT	17,13		;RESTORE 0-13
	MOVE	17,.JREGS+14(R)	;AND RESTORE P
	POPJ	P,		;RETURN TO INTERUPTED PROCESS

;RETURN FROM PROCESS IS BY PUSHJ P,QTS.  WHICH SAVES THE REGS AND
;PROCEEDS TO NEXT PROCESS.

QTS:	MOVEM	R,BASTBL-1(S)	;SAVE R FLAGS
	MOVEM	17,.JREGS+14(R)	;SAVE P
	MOVEI	17,.JREGS(R)	;SET TO SAVE THE PROCESSOR REGS
	BLT	17,.JREGS+13(R)	;SAVE THEM ALL
	TLNN	R,RL.ACT	;DID STREAM BECOME INACTIVE
	  JSP	A,CLRACT	;YES, CLEAN UP THE STREAM
DISP.2:	CAMGE	S,HIACTV	;PASSED ALL ACTIVE JOBS
	  AOJA	S,DISP.1	;NO, SKIP TO NEXT
	MOVE	P,[IOWD TPSIZE,TOPPDL] ;RESTORE TOP LEVEL PDL
DISP.3: PUSHJ	P,SCHED1	;SEE IF SCHEDULING HAS OCCURRED
	SKIPN	STACTV		;NOW ARE THERE STREAMS ACTIVE
	  PUSHJ	P,EXIRES	;NO, CHECK EXIT/RESET STATUS
	MOVX	T1,HIBERP	;SET WAKE UP CONDITIONS
	SKIPN	STACTV		;ANY STREAMS ACTIVE
	 TLNE	G,GL.NJN	;OR WAITING FOR JOBS
	  HRRI	T1,^D15*^D1000	;YES, SET A TIMER FOR THE SLEEP
	HIBER	T1,		;TAKE A NAP
	  JFCL			;NICE TRY
	JRST	TOPLVL		;REENTER TOP LEVEL LOOP

EXIRES:	TLNE	G,GL.EXI	;A PENDING EXIT
	  JRST	DOEXIT		;YES, DO THE EXIT
	TLNN	G,GL.SSH	;CEASE SCHEDULING (RESET)
	  JRST	M$CLNC##	;NONE PENDING, RETURN AFTER CLEAN UP
	TLNE	G,GL.CON	;IN CONTACT WITH QUASAR
	  PUSHJ	P,TELQSR	;YES, SAY GOOD-BYE
	PUSHJ	P,TTCRLF	;BLANK LINE
	OUTSTR	[ASCIZ/[BATCON is now RESET]/]
	PUSHJ	P,TTCRLF	;INFORM OF THE RESET
	JRST	BATCON		;SO THE "/" ISN'T A SUPRISE
DOEXIT:	TLNE	G,GL.CON	;IN CONTACT WITH QUASAR
	  PUSHJ	P,TELQSR	;YES, SAY GOOD-BYE
	JRST	EXIT..		;EXIT NOW
	SUBTTL	Scheduling and Stream Control Routines

SCHED1:	PUSHJ	P,NJNCHK	;CHECK FOR TIMER ON NO JOB NUMBERS
	  JFCL			;IGNORE THE RETURN
	PUSHJ	P,UPDADD	;UPDATE ANY ADDITIONAL PARMS BEFORE LOOP
	TLZE	G,GL.STC	;DID MY STATUS CHANGE
	  PUSHJ	P,TELQSR	;YES, TELL QUASAR
	PUSHJ	P,CSPRCV##	;CHECK FOR MESSAGES, RECEIVE ONE IF THERE
	JUMPE	T1,CPOPJ	;NOPE, RETURN TO DISPATCH
	TXNE	T1,1B0		;IS IT A PAGED TYPE
	  TLO	G,GL.PAG	;YES, REMEMBER THAT
	MOVEI	J,(T1)		;COPY MESSAGE ADDRESS
	PUSHJ	P,WAKEME	;POKE THE DISPATCH LOOP
	LOAD	T1,.MSTYP(J),MS.TYP  ;GET THE MESSAGE TYPE
	CAIN	T1,.QONEX	;A NEW JOB FOR ME TO RUN
	  JRST	SCHNXT		;YES, GO START IT
	CAIN	T1,.QOABO	;CANCEL A JOB ALREADY RUNNING
	  JRST	SCHCAN		;YES, GO END IT
	CAIN	T1,.QOCAN	;COUNT ANSWER
	  JRST	SCHCOU		;YES, DISPLAY COUNTS
SCHRET:	TLZN	G,GL.PAG	;WAS THE MESSAGE PAGED
	  POPJ	P,		;NO, RETURN
	LSH	J,-^D9		;CONVERT TO A PAGE NUMBER
	MOVEI	CH,(J)		;COPY INTO 'AP'
	JRST	M$RELP##	;RETURN THE PAGE AND RETURN

; HERE TO START A NEW JOB,  FIRST FIND A FREE STREAM

SCHNXT:	TLNN	G,GL.CON	;ARE WE IN CONTACT NOW (IN CASE OF STATUS CHANGE)
	  JRST	SCHRET		;NO, IGNORE THE RECEIVE QUEUE
	LOAD	S,.EQSEQ(J),EQ.RDE  ;SEE IF THIS IS A REAL JOB
	JUMPN	S,SCHN.3	;JUMP IF REALLY NOT THERE
	MOVEI	S,1		;FIND A FREE STREAM
SCHN.1:	SKIPL	BASTBL-1(S)	;LOOK FOR ONE WITH RL.ACT OFF
	  JRST	SCHN.2		;FOUND ONE
	CAIGE	S,JOBMAX	;OVER THE LIMIT
	  AOJA	S,SCHN.1	;NO, KEEP LOOKING
	TLON	G,GL.SSH!GL.STC	;SET A FEW PANIC FLAGS
	  MSGTTY [ASCIZ/QUASAR sent too many jobs, BATCON will RESET/]
	JRST	SCHRET		;DISMISS THE MESSAGE
SCHN.2:	PUSHJ	P,FIREUP	;START UP A NEW STREAM FROM THE TOP LEVEL
	JRST	SCHRET		;DISMISS THE MESSAGE

; HERE WHEN QUASAR SENT US A JOB WITH EQ.RDE SET, FORGET IT

SCHN.3:	MOVEI	A,QSRMSG	;POINT TO THE MESSAGE BLOCK
	MOVX	B,<INSVL.(REL.SZ,MS.CNT)!INSVL.(.QOREL,MS.TYP)>
	MOVEM	B,.MSTYP(A)	;STORE LENGTH AND TYPE
	MOVE	B,.EQITN(J)	;THE JOB NAME
	MOVEM	B,REL.IT(A)	;FOR THE RELEASE
	PUSHJ	P,SNDQSR##	;TURN THE JOB AROUND
	JRST	SCHRET		;GET RID OF THE PAGE (IF ANY)
;HERE WHEN QUASAR REQUESTED US TO CANCEL A RUNNING JOB

SCHCAN:	MOVE	T1,ABO.IT(J)	;GET THE ITN TO CANCEL
	MOVEI	S,1		;START AT STREAM 1
SCHC.1:	SKIPGE	R,BASTBL-1(S)	;STREAM INACTIVE
	 CAME	T1,Q.ITN(R)	;NO, IS THIS THE SAME ITN
	  JRST	SCHC.2		;NOT THE ONE, TRY NEXT STREAM
	MOVEI	F,FR.ABU	;GET THE CANCELLED FLAG
	IORM	F,.JREGS+F(R)	;SET IN JOB PROCESSOR FLAGS
	MOVE	F,ABO.ID(J)	;GET THE USER THAT REQUESTED THE CANCELLATION
	MOVEM	F,.JKILR(R)	;SAVE SO WE CAN OUTPUT IT
	TLO	R,RL.CMT	;SET INTERVENTION
	MOVEM	R,BASTBL-1(S)	;STORE THE SETTING
SCHC.2:	CAMGE	S,HIACTV	;PASS THE HIGHEST STREAM YET
	  AOJA	S,SCHC.1	;NO, TRY ANOTHER
	JRST	SCHRET		;DISMISS THE MESSAGE



;SUBROUTINE TO START UP A NEW JOB ( EXTRACT VARIABLES, SET RUNABLE)

FIREUP:	MOVEI	T1,.JPAGS	;NUMBER OF PAGES NEEDED FOR THE DATA BASE
	PUSHJ	P,M$AQNP##	;GET A PAGE FOR THE DATA BASE
	MOVEI	R,(CH)		;PUT THE PAGE NUMBER IN R
	LSH	R,^D9		;CONVERT TO AN ADDRESS
	MOVEM	R,BASTBL-1(S)	;SAVE FOR THE DISPATCHER
	SETZM	(R)		;CLEAR JOB DATA BASE
	HRLI	B,(R)		;SET UP FOR BLT
	HRRI	B,1(R)
	BLT	B,.JSIZE-1(R)	;CLEAR IT ALL
FIRE.1:	PUSHJ	P,CHNPTY	;GET A PTY ASSIGNMENT
	 SKIPA			;NONE, MUST GET A REAL PTY
	  JRST	[PUSHJ P,RELREL	;REMOVE IT
		JRST FIRE.1]	;CAUSE THE RING MAY HAVE MOVED
	JUMPE	IO1,FIRE.E	;CANNOT GET A PTY CHANNEL (THIS IS A BUG)
	MOVSI	A,(1B0!1B2)	;WANT ASCII MODE ON A REAL PTY
	MOVSI	B,'PTY'		;GET GENERIC PTY
	HRLI	C,.JPOUT(R)	;XWD OUTPUT,INPUT
	HRRI	C,.JPINP(R)
	PUSHJ	P,CHANIO	;TRY IT INIT THE DEVICE
	  OPEN	0,A
	  JRST	FIRE.N		;CANNOT, RELEASE ASSIGNMENT AND RETURN
	HLRZ	A,IO1		;COPY CHANNEL NUMBER
	LSH	A,-^D5		;AS A NUMBER
	HRRM	A,.JPCHN(R)	;SAVE FOR EASY USAGE
	HLLM	IO1,.JPCHN(R)	;SAVE AS A CHANNEL FOR EASIER USE



;;;  FIREUP IS CONTINUED ON THE NEXT PAGE
IFN FTJSYS,<
	MOVE	T1,[1,,A]	;ONE ARGUMENT IN "A"
	HRL	A,.JPCHN(R)	;THE PTY CHANNEL NUMBER
	HRRI	A,10		;FUNCTION 10 = TOPS10 CHANNEL TO JFN
	COMPT.	T1,		;CONVERT IT
	  JRST	FIRE.N		;BUG IN THE COMPATABILITY PACKAGE, RETURN CHANNEL
	MOVEM	T1,.JPJFN(R)	;SAVE PTY JFN FOR LATER
	MOVEI	T2,.MOBAT	;SET BATCH FUNCTION
	MOVEI	A,.MOJCB	;A = T2 + 1 , SET THE BATCH PTY BIT
	MTOPR			;AFFECTS JOBS LOGGING IN ON THIS PTY
>  ;END OF IFN FTJSYS

	MOVSI	A,400000	;NOT IN USE BIT
	HRRI	A,.JPTYO+1(R)	;FIRST IN RING
	MOVEM	A,.JPOUT(R)	;SET FOR BUFFERED OUTPUT
	HRRI	A,.JPTYI+1(R)	;SAVE FOR INPUT SIDE
	MOVEM	A,.JPINP(R)
	MOVSI	A,(POINT 7,0)	;BYTE SIZES
	MOVEM	A,.JPINP+1(R)
	HRRI	A,.JPTYO+3(R)	;COUNTS ARE ZERO FROM ABOVE BLT
	MOVEM	A,.JPOUT+1(R)	;FOR INPUT AND OUTPUT
	MOVSI	A,PTYBLK-2	;PLACE SIZE-2 IN THE LEFT HALF

	IFE	<PTYBFR-1>,<	;ONLY 1 BUFFER EACH WAY
	HRRI	A,.JPTYO+1(R)	;RING LOOPS ON ITSELF
	MOVEM	A,.JPTYO+1(R)
	HRRI	A,.JPTYI+1(R)	;SAME FOR INPUT
	MOVEM	A,.JPTYI+1(R)
	>
	IFG	<PTYBFR-1>,<	;MULTIPLE BUFFERS
	MOVEI	B,PTYBFR-1	;LOOP COUNT
	HRRI	A,.JPTYO+1+PTYBLK(R) ;POINT TO SECOND BUFFER
	JRST	.+2		;SKIP FOR THE FIRST BUFFER
	HRRI	A,PTYBLK(A)	;POINT TO NEXT BUFFER
	MOVEM	A,-PTYBLK(A)	;STORE ADDR INTO PREVIOUS BUFFER
	SOJG	B,.-2		;DO FOR ALL BUFFERS
	HRRI	A,.JPTYO+1(R)	;POINT BACK TO FIRST
	MOVEM	A,.JPTYO+1+<<PTYBFR-1>*PTYBLK>(R) ;LAST LINKS TO FIRST
	MOVEI	B,PTYBFR-1	;NOW DO THE SAME FOR INPUT SIDE
	HRRI	A,.JPTYI+1+PTYBLK(R) ;AGAIN POINT TO SECOND BUFFER
	JRST	.+2		;SKIP FOR THE FIRST BUFFER
	HRRI	A,PTYBLK(A)	;BUMP TO NEXT
	MOVEM	A,-PTYBLK(A)	;STORE ADDRESS OF THIS IN PREVIOUS
	SOJG	B,.-2		;REPEAT PROCESS FOR ALL BUFFERS
	HRRI	A,.JPTYI+1(R)	;FIRST BUFFER
	MOVEM	A,.JPTYI+1+<<PTYBFR-1>*PTYBLK>(R) ;LINK LAST TO FIRST
	>



;;;  FIREUP IS CONTINUED ON THE NEXT PAGE
	HRLI	T1,.EQITN(J)		;GOING TO USE BLT TO MOVE LOTS OF DATA
	HRRI	T1,Q.ITN(R)		;INTO THE INTERNAL DATA BASE..
	BLT	T1,Q.EBLT(R)		;SO WATCH ORDER IN QSRMAC AND LOW SEG
	LOAD	B,.EQLEN(J),EQ.LOH	;GET LENGTH OF THE REQUEST HEADER

IFN FTUUOS,<	;THE PATH IS OPTIONAL ON TOPS10, CHECK FOR IT
	CAIGE	B,.EQPSZ		;ENOUGH ROOM FOR THE PATH SPEC
	  JRST	FIRE.2			;NO, DON'T BOTHER COPYING IT
	HRLI	T1,.EQPAT(J)		;WHERE IT IS IF PRESENT
	HRRI	T1,Q.IDDI(R)		;INTO INTERNAL BLOCK
	BLT	T1,Q.IDDI+5(R)		;MOVE IT ALL
>  ;END OF IFN FTUUOS

FIRE.2:	ADDI	B,(J)			;FIND FILE PARAMETERS FOR THE CTL FILE
	DMOVE	T1,.FPINF(B)
	DMOVEM	T1,Q.CMOD(R)		;SAVE THE PARAMETERS AND STARTING POINT
	LOAD	C,.FPSIZ(B),FP.FHD	;FIND THE FILE DESCRIPTOR
	ADDI	C,(B)			;AS MESSAGE+LENGTH OF HEADER+LENGTH OF PARMS
	LOAD	D,.FPSIZ(B),FP.FFS	;SIZE OF THE DESCRIPTOR
	ADDI	D,Q.CSTR-1(R)		;END OF THE DATA MOVE
	HRLI	A,.FDSTR(C)		;THE CTL FILE STRUCTURE
	HRRI	A,Q.CSTR(R)		;WHERE FNDCTL WANTS IT
	BLT	A,0(D)			;COPY ALL AND SFD'S IF THERE
	LOAD	D,.FPSIZ(B),FP.FFS	;GET DESCRIPTOR SIZE AGAIN
	ADDI	C,(D)			;C = LOG FILE PARAMETERS
	MOVE	T1,.FPINF(C)		;GET INFO WORD
	MOVEM	T1,Q.LMOD(R)		;AS THE LOG FILE MOD WORD
	LOAD	D,.FPSIZ(C),FP.FHD	;SIZE OF LOG FILE PARM HEADER
	ADDI	D,(C)			;POINT TO LOG FILE DESCRIPTOR
	LOAD	C,.FPSIZ(C),FP.FFS	;SIZE OF LOG FILE DESCRIPTOR
	MOVEM	C,.JLGFD(R)		;SAVE FOR RELEASE MESSAGE
	ADDI	C,Q.LSTR-1(R)		;LAST LOCATION TO MOVE
	HRLI	A,.FDSTR(D)		;THE LOG FILE NOW
	HRRI	A,Q.LSTR(R)		;WHERE THE ROUTINES WANT IT
	BLT	A,0(C)			;MOVE THE FULL SPEC
	HRLI	T1,.EQCHK(J)		;CHECKPOINT/REQUEUE INFORMATION
	HRRI	T1,.JINFO(R)		;KEEP IT IN THE JOB DATA BASE
	BLT	T1,.JINFO+<EQCKSZ-1>(R)	;GET ALL THE WORDS
	HRLI	R,RL.INI		;SET THIS STREAM IS NOW ACTIVE
	MOVEM	R,BASTBL-1(S)		;STORE NEW SETTING
	MOVE	F,[FL.INI,,FR.INI]	;INITIALIZE THE OTHER FLAG REG
	MOVEM	F,.JREGS+F(R)		;STORE NEW SETTINGS
	CAMLE	S,HIACTV		;IS THIS NOW THE HIGHEST ACTIVE STREAM
	  MOVEM	S,HIACTV		;YES, SET NEW VALUE
	HRLI	A,-.JPSIZ		;BUILD PDL FOR THE STREAM
	HRRI	A,.JPLST-1(R)
	PUSH	A,[NEWJOB]		;START STREAM AT 'NEWJOB'
	MOVEM	A,.JREGS+14(R)		;SAVE AS PROCESSOR REGISTER P (17)
	AOS	STACTV			;ADD ANOTHER JOB
	POPJ	P,			;RETURN TO DISPATCHER
; HERE WHEN WE CANNOT GET A PTY FOR A JOB, GIVE IT BACK TO QUASAR
;AT	FIRE.N	IF ALREADY ACQUIRED A PTY CHANNEL BUT NO THE PTY ITSELF
;	FIRE.E	IF COULDN'T GET A PTY CHANNEL (A BUG IN THE CHANNEL ALLOCATOR)

FIRE.N:	PUSHJ	P,RELREL		;RELEASE THE PTY ASSIGNMENT
FIRE.E:	SETZM	.JAFTR(R)		;NO AFTER PARAMETER
	MOVE	T1,.EQITN(J)		;THE ITN INVOLVED
	MOVEM	T1,Q.ITN(R)		;FOR THE CALL TO FUNREQ
	TLO	G,GL.NJN		;PRETEND NO JOB NUMBERS
	PUSHJ	P,GETMST		;GET CURRENT TIME (MS.)
	MOVEM	T1,NJNTIM		;SAVE WHEN NOTICED
	PUSHJ	P,TELQSR		;INFORM OF STATUS CHANGE
	HRLI	A,.EQCHK(J)		;CHECKPOINT/REQUEUE INFORMATION
	HRRI	A,.JINFO(R)		;KEEP IT IN THE JOB DATA BASE
	BLT	A,.JINFO+<EQCKSZ-1>(R)	;SO REQUEUE PUTS IT BACK
	PUSHJ	P,FUNREQ		;NOW REQUEUE THE JOB
	MOVEI	CH,(R)			;DATA BASE ACQUIRED
	LSH	CH,-^D9			;TO A PAGE NUMBER
	MOVEI	T1,.JPAGS		;NUMBER USED
	JRST	M$RLNP##		;RELEASE THEM AND RETURN

;HERE WHEN QUASAR ANSWERED OUR REQUEST FOR COUNTERS

SCHCOU:	OUTSTR	[ASCIZ/QUASAR Uptime /]
	SETZ	T1,			;GET A ZERO
	EXCH	T1,CAN.BL+$$NOW(J)	;GET TIME OF ANSWER
	SUB	T1,CAN.BL+$$STAR(J)	;AND TIME QUASAR STARTED
	SETZM	CAN.BL+$$STAR(J)	;SO DON'T TYPE THEM OUT LATER
	MULI	T1,^D86400		;TO SECONDS
	ASHC	T1,^D17			;BRING TOGETHER
	IMULI	T1,^D1000		;TO MILLISEC FOR TYPEOUT
	PUSHJ	P,HMSTTY		;TYPE HH:MM:SS
	PUSHJ	P,TTCRLF		;AND START A NEW LINE
	MOVEI	B,CAN.BL(J)		;START OF ITEMS
	MOVE	A,[-NUMITM,,ITMSTR]	;AND POINTER TO STRINGS TO TYPE
SCHA.1:	SKIPN	T1,0(B)			;SOMETHING TO TYPE OUT
	  JRST	SCHA.2			;NO, TRY ANOTHER
	OUTSTR	@0(A)			;THE TYPE OF ITEM DISPLAYED
	OUTSTR	[ASCIZ/ - /]		;ALIGN THE NEXT PART
	PUSHJ	P,TTYDEC		;OUTPUT THE VALUE
	PUSHJ	P,TTCRLF		;NEXT LINE
SCHA.2:	AOS	B			;TO NEXT ITEM
	AOBJN	A,SCHA.1		;AND DO THEM ALL
	JRST	SCHRET			;DONE PROCESSING THE MESSAGE

DEFINE X(A,B),<EXP [ASCIZ\B\]>		;FOR $ITEM MACRO

ITMSTR:	$ITEM				;BUILD TABLE OF STRINGS
NUMITM==.-ITMSTR			;NUMBER OF THEM FOR OUTPUT
;SUBROUTINE TO CHECK IF A SUBJOB IS WAITING FOR THE OPERATOR

CHKOPR:	TLNE	R,RL.CMT	;IS A COMMENT READY
	  JSP	B,INTRVN	;PROCESS OPERATOR INTERVENTION
	TLNE	R,RL.STP	;IS THE JOB STOPPED
	  JRST	(A)		;YES, GIVE CANNOT PROCESS THIS JOB RETURN
	TLNN	R,RL.OPR	;IS THE WAITING BIT SET
	  JRST	1(A)		;NO, GIVE OK TO RUN RETURN

	IFN	PROMPT,<
	MOVE	T1,CURMST	;GET NOW
	MOVE	T2,T1		;MAKE A COPY
	SUB	T1,.JWAIT(R)	;HOW LONG HAS THE JOB BEEN WAITING
	MOVMS	T1		;JUST THE MAGNITUDE
	CAMGE	T1,[PROMPT*^D60*^D1000] ;OVER THE INTERVAL REQUESTED
	  JRST	(A)		;NO, GIVE CANNOT PROCESS THIS JOB RETURN
	MOVEM	T2,.JWAIT(R)	;STORE NEW TIME
	MOVE	P,[IOWD TPSIZE,TOPPDL] ;MUST GET A VALID PUSH DOWN LIST
	PUSHJ	P,TTYSJB	;TYPE SUBJOB NUMBER TO THE OPERATOR
	OUTSTR	[ASCIZ/  waiting for response/]
	PUSHJ	P,TTCRLF	;END THE LINE
	>
	JRST	(A)		;GIVE CANNOT PROCESS THIS JOB RETURN

;SUBROUTINE TO PROCESS OPERATOR INTERVENTION

INTRVN:	MOVE	P,[IOWD TPSIZE,TOPPDL] ;NEED A VALID PUSH DOWN LIST FIRST
	PUSH	P,B		;SAVE RETURN ADDRESS
	PUSH	P,A		;SAVE CHKOPR'S RETURN ADDRESS
	MOVE	F,.JREGS+F(R)	;GET THE OTHER FLAG REGISTER
	TLZ	R,RL.CMT	;CLEAR COMMENT IS READY
	TLZE	F,FL.EXM	;WAS THE INTERVENTION FOR EXAMINE
	  JRST	INTR.E		;YES, DO THE EXAMINE COMMAND
	TLZE	F,FL.KIL	;IS KILL SET
	  JRST	INTR.K		;YES, GO KILL THIS JOB
	TLZE	F,FL.REQ	;OR IS REQUEUE SET
	  JRST	INTR.R		;YES, GO REQUEUE THIS JOB
	TRZE	F,FR.ABU	;CANCELLED BY THE USER
	  JRST	INTR.C		;YES, GO HANDLE THAT
	PUSHJ	P,LOGBLK	;OUTPUT A BLANK LINE
	IDENT	[ASCIZ/ BAOPR	/] ;IDENTIFY THE OPERATOR LINE
	SIXLOG	.JWHO(R)	;PLUS THE OPERATOR COMMAND
	MOVEI	CH," "		;NEED A BLANK TO LOOK PRETTY
	PUSHJ	P,PUTLOG	;OUTPUT THE BLANK
	TXTLOG	.JOPER(R)	;ADD THE COMMENT LINE
	PUSHJ	P,LOGBLK	;OUTPUT A BLANK LINE
	MOVE	T1,.JWHO(R)	;GET THE COMMAND THAT STARTED ALL THIS
	CAMN	T1,[SIXBIT/STOP/] ;WAS IT STOP
	  JRST	INTR.S		;YES, TRY TO STOP THIS JOB
INTR.X:	MOVEM	F,.JREGS+F(R)	;SAVE IN CASE IT CHANGED
	MOVEM	R,BASTBL-1(S)	;MUST SAVE, RL.CMT IS NOW OFF
	POP	P,A		;RESTORE CHKOPR RETURN ADDRESS
	POPJ	P,		;RETURN 0(B)
INTR.C:	TLNN	R,RL.LGI!RL.KJB	;ON THE WAY IN OR OUT
	  JRST	INTR.6		;NO, CAN KILL IT NOW
	TLO	R,RL.CMT	;RESET THE BITS
	TRO	F,FR.ABU	;SO I CAN FIND IT IN THE NEXT PASS
	JRST	INTR.X		;EXIT, WILL GET HERE AGAIN
INTR.6:	PUSH	P,[CANCJB]	;ADDRESS OF CANCEL ROUTINE
	JRST	INTR.4		;ENTER COMMON CODE FOR KILL/REQUEUE/CANCEL
INTR.K:	PUSH	P,[KILLJB]	;SAVE ADDRESS OF KILL PROCESSOR
	JRST	INTR.4		;SKIP OVER REQUEUE
INTR.R:	PUSH	P,[REQUJB]	;SAVE ADDRESS OF REQUEUE PROCESSOR
INTR.4:	TLZ	R,RL.OPR!RL.JIE!RL.DIA!RL.STP ;CLEAR SOME FLAGS
	TLZ	F,FL.NER!FL.PLS!FL.SIL ;CLEAR SOME MORE
	HRLI	A,-.JPSIZ	;REBUILD JOB PROCESSOR PUSH DOWN LIST
	HRRI	A,.JPLST-1(R)	;SO SUBJOB HAS A FRESH START
	POP	P,B		;GET THE PROCESS ADDRESS FOR KILL/REQUEUE
	PUSH	A,B		;SAVE ON TOP OF THE LIST
	MOVEM	A,.JREGS+14(R)	;SAVE AS PROCESSOR REGISTER 17 (P)
	JRST	INTR.X		;RETURN TO DISPATCHER TO KILL/REQUEUE THIS JOB
INTR.E:	SKIPN	.JCUSI(R)	;HAS THE FILE BEEN OPENED YET
	  JRST	INTR.X		;NO, SKIP THIS EXAMINE CALL
	JSP	T1,SAVPOS	;SAVE CURRENT POSITION
	PUSHJ	P,TTYALL	;TYPE OUT ALL SUBJOB INFORMATION
INTR.1:	SOSGE	.JCCNT(R)	;IS THERE ANY LEFT IN THE BUFFER
	  JRST	INTR.3		;NO, CAN ONLY EXAMINE WHAT'S IN CORE
	ILDB	CH,.JCPTR(R)	;GET THE NEXT
	JUMPE	CH,INTR.1	;IGNORE NULLS
	OUTCHR	CH		;OUTPUT IT
	CAIG	CH,CHR.FF	;CHECK FOR END OF LINE CHARACTER
	CAIGE	CH,CHR.LF	;SAVE AS CHECK FOR A TIME STAMP NEEDED
	  JRST	INTR.1		;RESUME WITH THIS LINE
	SOSLE	.JWHO(R)	;HAVE WE EXHAUSTED THE COUNT REQUESTED
	  JRST	INTR.1		;NO, RESUME THE OUTPUT
INTR.2:	PUSHJ	P,TTCRLF	;ADD A BLANK LINE ON THE OPERATORS CONSOLE
	JSP	T1,REPOSI	;PUT THE COUNT AND POINTER BACK
	JRST	INTR.X		;RESTORE THE REGS AND RETURN
INTR.3:	PUSHJ	P,TTCRLF	;ANOTHER BLANK LINE
	OUTSTR	[ASCIZ/***END OF BUFFER***/] ;TELL THE OPERATOR THATS ALL
	JRST	INTR.2		;RESTORE COUNTS AND EXIT
INTR.S:	PUSHJ	P,GJBSTS	;GET THE CURRENT JOB STATUS BITS
	MOVEI	B,STOPJB	;ADDRESS OF STOP PROCESSOR
	TLNN	R,RL.LGI	;IS THE JOB JUST LOGGING IN
	TLNE	J,JL.UDI!JL.UJC	;OR DOES THE JOB WANT INPUT OR HAVE JACCT
	  MOVEI	B,JUSTCL	;JUST IGNORE THE JOB REQUEST
	MOVE	A,.JREGS+14(R)	;GET PROCESSOR REG 17 (P)
	PUSH	A,B		;PUT PROCESSOR IN FRONT OF EVERYTHING
	MOVEM	A,.JREGS+14(R)	;PUT AC 17 BACK IN PLACE
	JRST	INTR.X		;LET THE DISPATCHER START THERE
;SUBROUTINE TO FIND NEW HIACTV IF INACTIVE STREAM WAS OLD HIACTV

FHIACT:	PUSH	P,S		;SAVE CURRENT STREAM
	SKIPL	BASTBL-1(S)	;IS THIS STREAM ACTIVE
	  SOJG	S,.-1		;NO, LOOK FOR ONE BELOW
	MOVEM	S,HIACTV	;FOUND 1 OR NONE BUT IS OK
	POP	P,S
	POPJ	P,

;SUBROUTINE TO WAKE ME UP FOR VARIOUS REASONS

WAKEME:	MOVNI	A,1		;JOB -1 IS ME
	WAKE	A,		;ISSUE THE WAKE
	  JFCL			;REALLY CAN'T FAIL
	POPJ	P,

;SUBROUTINE TO CLEAR A STREAM THAT JUST WENT INACTIVE
;CALL BY JSP A,CLRACT FROM THE DISPATCH LOOP

CLRACT:	MOVE	P,[IOWD TPSIZE,TOPPDL] ;GET TOP LEVEL PDL FIRST
	PUSH	P,A		;SAVE RETURN ADDRESS
	SOS	STACTV		;DECREMENT THE STREAM COUNT
	CAMN	S,HIACTV	;WAS STREAM TO GO IDLE THE HIGHEST ACTIVE
	  PUSHJ	P,FHIACT	;YES, FIND NEW HIACTV
	HLLZ	IO1,.JPCHN(R)	;GET PTY CHANNEL ASSIGNMENT
	PUSHJ	P,RELREL	;RELEASE IT AND THE ASSIGNMENT
	MOVEI	CH,(R)		;GET THE DATA BASE
	LSH	CH,-^D9		;CONVERT TO A PAGE NUMBER
	MOVEI	T1,.JPAGS	;NUMBER TO RELEASE
	JRST	M$RLNP##	;RELEASE IT AND RETURN
;SUBROUTINE TO INFORM QUASAR OR A STATUS CHANGE (OR ESTABLISH CONTACT)

TELQSR:	TLNE	G,GL.CON	;IN CONTACT WITH QUASAR
	  JRST	TELQ.1		;YES, SKIP EXIT/RESET CHECK
	TLNE	G,GL.SSH!GL.EXI	;IS EXIT/RESET PENDING
	 SKIPE	STACTV		;YES, ARE WE ABOUT TO DO IT
	  SKIPA			;NO, SET NEW STATUS
	   POPJ	P,		;JUST RETURN IF NOT IN CONTACT
TELQ.1:	MOVEI	A,QSRMSG	;POINT TO THE MESSAGE BLOCK
	MOVX	B,<INSVL.(HEL.SZ,MS.CNT)!INSVL.(.QOHEL,MS.TYP)>
	MOVEM	B,.MSTYP(A)	;STORE HELLO MESSAGE LENGTH AND TYPE
	MOVE	B,[SIXBIT/BATCON/]  ;MY NAME
	MOVEM	B,HEL.NM(A)	;INCLUDE NAME FIELD
	MOVSI	B,'INP'		;QUEUE I WANT
	MOVEM	B,HEL.SD(A)	;AS THE SCHEDULABEL DEVICE
	MOVE	B,[SIXBIT/BATRUN/]
	MOVEM	B,HEL.PD(A)	;A NICE LOOKING NAME
	HRL	B,UTIME		;SINGLE JOB MAX IN LEFT
	HRR	B,ATIME		;TOTAL FOR BATCH IN RIGHT
	MOVEM	B,HEL.I1(A)	;AS INFO WORD 1
	HRL	B,MJOB		;NUMBER OF STREAMS
	HRR	B,NXTJOB	;NEXT REQUEST
	MOVEM	B,HEL.I2(A)	;AS INFO WORD 2
	SKIPN	C,UCORE		;IS THERE AN OPERATOR LIMIT
	  MOVE	C,CORMAX	;NO, USE CORMAX
	SKIPN	B,ACORE		;DO THE SAME FOR SUM OF BATCH
	  MOVE	B,CORPHY	;USE PHYSICAL CORE
	HRL	B,C		;SINGLE JOB LIMIT IF LEFT
	MOVEM	B,HEL.I3(A)	;AS INFO WORD 3
	MOVX	B,<INSVL.(%%.QSR,HELVER)>  ;GET QSRMAC VERSION NUMBER
	TLOE	G,GL.CON	;ALREADY IN CONTACT
	  TXO	B,HELSTC	;YES, THIS IS A STATUS CHANGE
	TLNN	G,GL.SSH!GL.NJN	;STOP SCHEDULING
	  TXO	B,HELSCH	;NO, SET SCHEDUABLE
	TLNE	G,GL.SSH!GL.EXI	;ANOTHER EXIT/RESET CHECK
	 SKIPE	STACTV		;BUT THIS TIME WE ARE IN CONTACT
	  JRST	TELQ.2		;JUST SET THE STATUS
	TXO	B,HELBYE	;SAY GOOD-BYE QUASAR
	TLZ	G,GL.CON	;CLEAR CONTACT
TELQ.2:	MOVEM	B,HEL.ST(A)	;STORE STATUS BITS
	JRST	SNDQSR##	;SEND IT AND RETURN TO CALLER
	SUBTTL	Job Processor - Start the Stream

;ENTRY AT NEWJOB FOR FRESH START. HEADERS,LOGIN,SET COMMANDS...

NEWJOB:	IFN	JOBMSG,<
	PUSHJ	P,TTYSJB	;TYPE THE SUBJOB NUMBER
	PUSHJ	P,TTYJPN	;TYPE OUT THE JOB NAME AND PPN
	OUTSTR	[ASCIZ/ started/]
	PUSHJ	P,TTCRLF	;END THE LINE
	>
	IDENT	MYVERS		;OUTPUT BATCH VERSION INFORMATION

	IFN	BTNMIN,<
	MOVEI	CH,BTNMIN+100	;MAKE A LETTER OUT OF THE MINOR VERSION NUMBER
	PUSHJ	P,PUTLOG	;OUTPUT IT
	>
	TXTLOG	MYVRS1		;ADD EDIT AND WHO AND MORE TEXT
	SIXLOG	Q.JOB(R)	;SEND THE JOB NAME TO THE LOG
	TXTLOG	[ASCIZ/ sequence /]
	LOAD	T1,Q.SEQ(R),EQ.SEQ  ;GET THE SEQUENCE NUMBER
	CAMN	T1,NXTJOB	;SAME AS LAST "NEXT" COMMAND
	  SETZM	NXTJOB		;YES, CLEAR CAUSE WE FOUND IT
	PUSHJ	P,LOGDEC	;OUTPUT THE SEQUENCE NUMBER
	TXTLOG	[ASCIZ/ in stream /]
	MOVE	T1,S		;GET THE STREAM NUMBER
	PUSHJ	P,LOGDEC	;OUTPUT THE STREAM NUMBER
	PUSHJ	P,CTLSPC	;GET THE FILE SPEC FOR THE CTL FILE
	MOVEI	T2,[ASCIZ/Input from /] ;STRING TO BE ADDED
	MOVEI	T1,Q.CSTR(R)	;CTL FILE STRUCTURE
	PUSHJ	P,LOGFIL	;PRINT FILE SPEC TO LOG FILE
	PUSHJ	P,LOGSPC	;GET THE LOG FILE SPECIFICATION
	MOVEI	T2,[ASCIZ/Output to  /]
	MOVEI	T1,Q.LSTR(R)	;LOG FILE STRUCTURE
	PUSHJ	P,LOGFIL	;OUTPUT IT TO THE LOG FILE
	IDENT	[ASCIZ/ BASUM	Job parameters/]
	PUSHJ	P,LGCMNT	;PREPARE FOR A COMMENT
	TXTLOG	[ASCIZ/Time:/]
	HRRZ	T1,Q.ILIM(R)	;GET THE JOBS TIME ESTIMATE
	IMULI	T1,^D1000	;TO MILLISECONDS TO USE LOGTIM
	PUSHJ	P,LOGTI1	;ENTER WITH TIME ALREADY IN T1

	IFN	INPCOR,<
	TXTLOG	[ASCIZ/   Core:/]
	HLRZ	T1,Q.ILIM(R)	;GET JOBS CORE ESTIMATE
	PUSHJ	P,LOGDEC	;OUTPUT IT AS DECIMAL
	MOVEI	CH,"P"		;ADD SUFFIX
	PUSHJ	P,PUTLOG
	>
	TXTLOG	[ASCIZ/   Unique:/]
	LOAD	T1,Q.IDEP(R),EQ.UNI  ;GET THE /UNIQUE VALUE
	CAIE	T1,EQ.UNO	;IS IT UNIQUE
	  TLOA	T1,'YES'	;YES, SAY SO
	MOVSI	T1,'NO '	;NO
	PUSHJ	P,LOGSIX	;OUTPUT THE PROPER RESPONSE
	TXTLOG	[ASCIZ/   Restart:/]
	SKIPE	T1,.JCHRQ(R)	;SEE IF CHECK POINT INFORMATION EXISTS
	 CAMN	T1,[-1]		;YES, -1 = A NON-RESTARTABLE JOB BEING RESTARTED
	  SKIPL	Q.IDEP(R)	;IS NOT RESTARTABLE BIT ON
	   SKIPA T1,[SIXBIT/YES/] ;NO, SAY YES
	MOVSI	T1,'NO '	;YES, SAY NO
	PUSHJ	P,LOGSIX	;PRINT PROPER RESPONSE
	TXTLOG	[ASCIZ/   Output:/]
	LOAD	T1,Q.IDEP(R),EQ.OUT  ;GET /OUTPUT: VALUE
	CAIN	T1,%EQOLE	;/OUT:ERROR
	  MOVE	T1,[SIXBIT/ERROR/]  ;YES
	CAIN	T1,%EQOLG	;/OUT:LOG
	  MOVE	T1,[SIXBIT/LOG/]  ;YES
	TLNN	T1,-1		;ONE OF THE ABOVE
	  MOVE	T1,[SIXBIT/NOLOG/]  ;NO, USE UNDEFINED CASE
	PUSHJ	P,LOGSIX	;ADD IT TO THE LOG
NEWJ.2:	PUSHJ	P,LGCLF2	;END THE LINE AND ADD A BLANK ONE
	PUSHJ	P,SNDUPC	;SEND A ^C
	PUSHJ	P,IOWAIT	;WAIT FOR I/O, RETURN FOR MORE INPUT
	TLNE	R,RL.TIM	;TIMESTAMP NEEDED?
	PUSHJ	P,PUTPER	;YES, ALIGN OUTPUT
	TXTJOB	[ASCIZ/LOGIN /]	;SEND THE LOGIN COMMAND

IFN FTUUOS,<
	HLRZ	T1,Q.PPN(R)	;PROJECT NUMBER
	PUSHJ	P,SNDOCT	;SEND IT IN OCTAL
	MOVEI	CH,CH.LGI	;CHARACTER TO SEND BETWEEN PROJECT AND PROGRAMMER
	PUSHJ	P,SNDCHR	;SEND THE CHARACTER
	HRRZ	T1,Q.PPN(R)	;PROGRAMMER NUMBER
	PUSHJ	P,SNDOCT	;SEND IT IN OCTAL
	MOVEI	D,Q.IDDI(R)	;GET THE LOGIN PATH
	SKIPN	Q.IDDI(R)	;ANY PPN IN THE PATH SPEC
	  JRST	NEWJ.6		;NO, AVOID SENDING BAD DATA
	PUSHJ	P,SETSFD	;SET AS IF AN SFD SPEC
	TLNE	D,-1		;IS D A PPN
	  JRST	[CAMN D,Q.PPN(R)  ;YES, ARE THE PPNS THE SAME
		  JRST NEWJ.6	;YES, SKIP THIS OUTPUT
		MOVEI D,SFDPAT-3  ;INSURE FINDING A ZERO
		JRST .+1]	;RESUME IN-LINE CODE
	MOVEM	D,.JLABL(R)	;SAVE THE POINTER FOR NOW
	TXTJOB	[ASCIZ/ [/]	;START OF SPEC
	MOVE	T1,Q.IDDI(R)	;GET PATH PPN
	CAMN	T1,Q.PPN(R)	;SAME AS LOGGED IN PPN
	  JRST	[PUSHJ P,SNDCMA	;YES, ADD A COMMA
		JRST NEWJ.4]	;GO STRAIGHT TO PATH SPEC
	HLRZ	T1,Q.IDDI(R)	;GET PATH PROJECT NUMBER
	PUSHJ	P,SNDOCT	;OUTPUT IT
	PUSHJ	P,SNDCMA	;AND A COMMA
	HRRZ	T1,Q.IDDI(R)	;GET THE PROGRAMMER NUMBER NOW
	PUSHJ	P,SNDOCT	;OUTPUT THAT
NEWJ.4:	AOS	T1,.JLABL(R)	;BUMP TO NEXT SFD LEVEL
	SKIPN	T1,2(T1)	;IS THERE ANOTHER
	  JRST	NEWJ.5		;NO, END OF THE SPEC
	PUSHJ	P,SNDCMA	;SEND A COMMA
	PUSHJ	P,SNDSIX	;SEND THE SFD NAME
	JRST	NEWJ.4		;CONTINUE FOR ALL LEVELS
NEWJ.5:	MOVEI	CH,"]"		;END OF THE PATH
	PUSHJ	P,SNDCHR	;SEND IT


;;;CODE IS CONTINUED ON THE NEXT PAGE AND STILL UNDER FTUUOS CONDITIONAL
NEWJ.6:	TXTJOB	[ASCIZ\ /DEFER/SPOOL:ALL/TIME:\]
	HRRZ	T1,Q.ILIM(R)	;GET THE TIME ESTIMATE
	PUSHJ	P,SNDDEC	;OUTPUT IT FOR LOGIN

	IFN	INPCOR,<
	TXTJOB	[ASCIZ\/CORE:\]	;IF ENFORCING CORE ESTIMATES
	HLRZ	T1,Q.ILIM(R)	;GET THE CORE ESTIMATE
	PUSHJ	P,SNDDEC	;OUTPUT DECIMAL VALUE
	MOVEI	CH,"P"		;GET SUFFIX
	PUSHJ	P,SNDCHR	;INDICATE UNITS
	>
	TLNN	G,GL.RMT	;THIS MONITOR HAVE REMOTE LOGIC
	  JRST	NEWJ.3		;END THE LINE
	TXTJOB	[ASCIZ\/LOCATE:\]
	LOAD	T1,Q.SEQ(R),EQ.DSN  ;GET THE STATION NUMBER FROM QUASAR
	PUSHJ	P,SNDOCT	;SEND THE OCTAL STATION NUMBER
NEWJ.3:	PUSHJ	P,REDUCE	;COUNT THE CHARACTERS IN THE USERS NAME
	  JRST	NEWJ.8		;NULL, SKIP THIS SWITCH
	TXTJOB	[ASCIZ\/NAME:"\] ;SEND THE SWITCH NAME
	MOVE	T1,[POINT 6,Q.USER(R)] ;POINT TO THE STRING
NEWJ.7:	ILDB	CH,T1		;FETCH A CHARACTER, T2 IS COUNT OF REAL ONES
	MOVEI	CH," "(CH)	;CONVERT TO ASCII
	CAIN	CH,""""		;DOES THE NAME HAVE A QUOTE IN IT
	  PUSHJ	P,SNDCHR	;YES, SEND 2 SO SCAN WONT COMPLAIN
	PUSHJ	P,SNDCHR	;SEND THE CHARACTER
	SOJG	T2,NEWJ.7	;SEND ALL THE CHARACTERS
	MOVEI	CH,""""		;GET CLOSURE FOR THE QUOTED STRING
	PUSHJ	P,SNDCHR	;SEND IT
>  ;END OF IFN FTUUOS
IFN FTJSYS,<
	TXTJOB	Q.USNM(R)		;SEND THE USER NAME
	TLO	F,FL.SIL		;MUST PROVIDE PASSWORD FIELD
	TXTJOB	[ASCIZ/ FOO/]		;EVEN THOUGH IT'S NOT VALIDATED
	TLZ	F,FL.SIL		;SO DON'T LET USER SEE "FOO"
	TXTJOB	[ASCIZ/ /]		;DELIMIT FIELDS
	MOVEI	T1,Q.ACCT(R)		;POINT TO ACCOUNT STRING
	SKIPN	(T1)			;ONE PROVIDED
	  MOVEI	T1,[ASCIZ/10300/]	;NO, USE MY OLD ONE
	TXTJOB	(T1)			;SEND TO THE JOB
>  ;END OF IFN FTJSYS

NEWJ.8:	PUSHJ	P,SNDCLF		;END THE LINE
	PUSHJ	P,IOWAIT		;WAIT FOR NEXT INPUT REQUEST
	TLNE	R,RL.JIE		;DID LOGIN FAIL
	  PUSHJ	P,ANALYZ		;YES, ANALYZE THE LOGIN ERROR
	PUSHJ	P,CLSLOG		;FORCE OUT SOME OF THE LOG FILE NOW

IFN FTJSYS,<
	MOVX	T1,AC%CON+3		;FLAGS,,LENGTH IN 1
	MOVEI	T2,A			;ADR IN 2
	HRROI	A,Q.CNDI(R)		;ADR POINTS TO STR-DIR STRING
	HRROI	B,[ASCIZ / /]		;ADR+1 POINTS TO PSW (DUMMY)
	HRRZ	C,J			;ADR+2 POINTS TO JOB NUMBER
	ACCES				;CONNECT THE JOB
	ERJMP	NEWJ.9			;DON'T WAIT IF IT FAILED
	PUSHJ	P,IOWAIT		;GET RESPONSE FROM CNDIR JSYS
NEWJ.9:	HRRZ	T1,J			;GET THE JOB NUMBER
	MOVEI	T2,.SJDFS		;SET DEFAULT SPOOLING
	MOVEI	A,.SJSPD		;A = T2 + 1, SET DEFERRED
	SETJB				;SET IT FOR THE JOB
	HRRZ	C,Q.ILIM(R)		;GET JOBS TIME LIMIT
	PUSHJ	P,SETTIM		;SET IT
>  ;END OF IFN FTJSYS
	TLZ	R,RL.LGI	;CLEAR LOGIN SEQUENCE NOW
	SKIPN	T1,.JCHRQ(R)	;IS THERE CHECKPOINT/REQUEUE INFO
	  JRST	NORM.2		;FIRST TIME I SAW THIS JOB, SEE IF RESTARTABLE THERE
	CAME	T1,[-1]		;CHKPNT = -1 MEANS RESTART OF NON-RESTARTABLE JOB
	  JRST	CKPNTS		;OK SO FAR, CHECK FOR CHKPNT START
	MOVEI	T1,[ASCIZ/BTNJNR Job cancelled after a restart, it is not restartable./]
NORM.1:	PUSHJ	P,LGEMSG	;OUTPUT THE ERROR MESSAGE
	PUSHJ	P,LGCLF2	;END THE LINE AND ADD A BLANK ONE
	TRO	F,FR.LSL	;LIST LINES SKIPPED (THE WHOLE CTL FILE)
	JRST	FINSRC		;GO TO %FIN::
NORM.2:	SKIPL	Q.IDEP(R)	;IS THIS JOB RESTARTABLE
	  JRST	CKPNTS		;YES, GO GET STARTING POINT
	SETOM	.JCHRQ(R)	;FLAG TO MEAN FIRST TIME A NON-RESTARTABLE JOB
	PUSHJ	P,FUNCHK	;HAS BEEN SCHEDULED, NEXT TIME HE'S DEAD
	SETZM	.JCHRQ(R)	;IN CASE OF LATER REQUEUE OR CHECKPOINT
CKPNTS:	SKIPN	T1,.JCHRQ(R)	;GET WHERE TO START PARAMETER
	  MOVE	T1,Q.CBIT(R)	;GET /TAG OR /START VALUE IF NO CHECKPOINT
	TLNN	T1,777777	;IS IT A RESTART LABEL
	  JRST	CKLINE		;NO, TRY A LINE NUMBER
	MOVEM	T1,.JLABL(R)	;SAVE FOR LABFND
	PUSHJ	P,LGCMNT	;PREPARE FOR A COMMENT
	TXTLOG	[ASCIZ/BTNBLA Beginning processing at label /]
	SIXLOG	.JLABL(R)	;OUTPUT THE LABEL
	PUSHJ	P,LGCLF2	;END THE LINE AND ADD A BLANK ONE
	TRO	F,FR.FIN	;THIS SEARCH MAY SKIP A %FIN::
	JRST	LABSRC		;SEARCH FOR THE LABEL
CKLINE:	CAIG	T1,1		;IS STARTING LINE .G.1
	  JRST	HONORJ		;NO, START THE JOB NOW
	MOVEM	T1,.JLABL(R)	;SAVE THE COUNT OF LINES
	PUSHJ	P,LGCMNT	;PREPARE FOR A COMMENT
	TXTLOG	[ASCIZ/BTNBLI Beginning processing on line /]
	MOVE	T1,.JLABL(R)	;RE-GET THE COUNT
	PUSHJ	P,LOGDEC	;OUTPUT THAT
	PUSHJ	P,LGCLF2	;END THE LINE AND ADD A BLANK ONE
CKLI.1:	SOSG	.JLABL(R)	;PASSED OVER ENOUGH YET
	  JRST	HONORJ		;YES, START HERE
	PUSHJ	P,GETCTL	;GET A CHARACTER
	PUSHJ	P,CMNT.3	;USE THE SILENCED COPY COMMENT
	JRST	CKLI.1		;SKIP OVER JUST ENOUGH
	SUBTTL	Job Processor - Honor Job's Input Request

HONORJ:	PUSHJ	P,IOWAIT
	TLNN	J,JL.UJA	;IS THERE A JOB STILL THERE
	  JRST	[PUSHJ P,CLSLOG	;NO, MUST HAVE DONE HIS OWN KJOB OR LOGOUT
		TLO R,RL.NLG	;SUPPRESS PRINTING OF THE LOG FILE
		JRST CLOS.1]	;SO JUST DISMISS THIS JOB
	TLNE	F,FL.TLE	;DID THIS JOB EXCEED ITS TIME LIMIT
	  JRST	TIMERR		;YES, CANCEL OR GIVE EXTRA TIME
	TLNE	R,RL.DIA	;DOES JOB WANT DIALOGUE MODE INPUT
	  JRST	REDOPR		;YES, READ NEXT LINE FROM THE OPERATOR
HONO.1:	TLZ	F,FL.LAB	;CLEAR A LABEL FOUND FLAG
	TLO	R,RL.FCI	;LOOKING FOR THE FIRST CHARACTER
	PUSHJ	P,GETCTL	;GET THE FIRST CHARACTER OF THIS LINE
HONO.2:	TLZ	R,RL.FCI!RL.EOL	;CLEAR SOME FLAGS
	PUSHJ	P,CLASSF	;CLASSIFY THE CHARACTER WE HAVE
	  JRST	CNTLLI		;LINE TERMINATORS ARE ALSO SPEC. ACTION
	  JRST	CNTLLI		;SPECIAL ACTION CHARACTER
	  JRST	CPYLOP		;LINE STARTS WITH A NUMBER, IS USER DATA
	PUSHJ	P,DECRBP	;A LETTER, CHECK FOR A LABEL
	JSP	T1,SAVPOS	;SAVE CURRENT CTL FILE POSITION
	MOVE	T1,[PUSHJ P,GETCTL] ;HOW TO GET A CHARACTER
	MOVEM	T1,COMFIL
	PUSHJ	P,GETSIX	;GET THE POSSIBLE LABEL
	TLON	F,FL.LAB	;ALREADY FIND 1 LABEL ON THIS LINE
	CAIE	CH,":"		;DID IT END WITH A COLON
	  JRST	NOTLAB		;NO, CANNOT BE A LABEL
	PUSHJ	P,GETCTL	;GET THE NEXT CHARACTER
	CAIE	CH,":"		;IS IT LABEL::
	  JRST	NOTLAB		;NO, THAT IS THE ONLY KIND WE CAN 'FALL INTO'
	POP	P,(P)		;CLEAN UP AFTER SAVPOS, WE ARE AT THE RIGHT PLACE
	POP	P,(P)		;...
	MOVEM	T1,(P)		;RE-USE ONE WORD TO SAVE THE LABEL
	IDENT	[ASCIZ/ BLABL	/] ;IDENTIFY THE LABELED LINE
	POP	P,T1		;RESTORE THE LABEL
	PUSHJ	P,LOGSIX	;OUTPUT 'T1' (THE LABEL)
	PUSHJ	P,PUTCOL	;ADD BOTH COLONS
	PUSHJ	P,PUTCOL
	PUSHJ	P,LOGCLF	;END THE LINE
HONO.3:	PUSHJ	P,SKPBL1	;SKIP ANY BLANKS AFTER THE LABEL
HONO.4:	TLO	F,FL.LAB	;NO MORE LABELS ON THIS LINE
	CAIE	CH,CHR.CR	;IS THIS A NULL STATEMENT
	  JRST	HONO.2		;NO, TREAT THIS AS A LINE IDENTIFIER
	PUSHJ	P,GETCTL	;CHEW UP THE LINE FEED TOO
	JRST	HONO.1		;NOW MAY HAVE A LABEL
;HERE WHEN A LINE DOES NOT BEGIN WITH A LABEL

NOTLAB:	TLNE	J,JL.UML	;NOT A LABEL, IS USER AT MONITOR LEVEL
	  JRST	MONLIN		;YES, T1=MONIOR COMMAND OR BATCH COMMAND
	JSP	T1,REPOSI	;REPOSITION THE POINTERS
	PUSHJ	P,GETCTL	;GET THE FIRST CHARACTER OF THE LINE
	JRST	CPYLOP		;COPY TO THE USER JOB

;HERE WHEN DIALOGUE MODE IS IN EFFECT, READ FROM THE OPERATOR

REDOPR:	PUSHJ	P,TTCRLF	;OUTPUT A BLANK LINE
	PUSHJ	P,TTYALL	;TYPE OUT SUBJOB INFORMATION
	OUTSTR	[ASCIZ/OPR--Respond with /]
	MOVEI	T1,[ASCIZ /OPERATOR <LINE>
Waiting...
/]
	PUSHJ	P,SJBLIN	;TYPE LINE WITH SJB NUMBER
	PUSHJ	P,CLSLOG	;CLOSE OUT THE LOG FILE BEFORE WAITING
	PUSHJ	P,OPRRES	;GET THE RESPONSE
	TLNN	J,JL.UJA	;IS THERE A JOB STILL THERE
	  JRST	CLOS.1		;NO, JUST DISMISS IT
	TLNE	R,RL.DIA	;IS THE JOB STILL WAITING
	  JRST	REDOPR		;YES, OPERATOR MUST RESPOND
	IDENT	[ASCIZ/ BAOPR	OPERATOR /] ;IDENTIFY THE OPERATOR RESPONSE
	PUSH	P,F		;SAVE F IN CASE SILENCE IS SET
	TLZ	F,FL.SIL	;THIS LINE MUST GO TO THE LOG FILE
	TXTJOB	.JOPER(R)	;SEND THE RESPONSE (INCLUDES TERMINATOR)
	POP	P,T1		;RESTORE OLD F
	TLNE	T1,FL.SIL	;WAS SILENCE SET
	  TLO	F,FL.SIL	;YES, SET IT AGAIN
	PUSHJ	P,PTYSND	;OUTPUT THE PTY BUFFER
	TLO	R,RL.EOL	;INDICATE AN END OF LINE SENT
	TLZ	R,RL.QTS	;CLEAR QUOTES FOR GOOD MEASURE
	JRST	HONORJ		;END THIS DIALOGUE

;DEFINE MY VERSION MACROS AND GENERATE THE TEXT FOR THE LOG FILE

DEFINE	.VERSN(A)<
	LSTOFF
	ASCIZ	\ BAJOB	BATCON version A\
	LSTON
	>

MYVERS:	.VERSN	\BTNVER,		;GENERATE HEADER LINE FOR THIS VERSION

DEFINE	.VERSN(A,B)<
	LSTOFF
	IFB	<B>,<ASCIZ\(A) running \>
	IFNB	<B>,<ASCIZ\(A)-B running \>
	LSTON
	>

MYVRS1:	IFE	BTNWHO,<.VERSN \BTNEDT,>
	IFN	BTNWHO,<.VERSN \BTNEDT,\BTNWHO,>
;HERE IF LINE STARTS WITH A SPECIAL ACTION CHARACTER. DETERMINE WHICH ONE

CNTLLI:	TLZ	F,FL.PER	;CLEAR A FLAG
	CAIE	CH,CHR.FF	;IS IT VERTICAL PAPER MOTION IN CLOUMN 1
	CAIN	CH,CHR.VT	;LOOK FOR FORM FEED AND VERTICAL TAB
	  JRST	VERTMO		;YES, PRETEND COLUMN 2 IS COLUMN 1
	CAIE	CH,";"		;A COMMENT LINE
	CAIN	CH,"!"		;AS DEFINED BY THE STANDARD
	  JRST	CMNTLI		;YES, COPY THE COMMENT LINE
	CAIN	CH,"*"		;CUSP OR USER INPUT
	  JRST	USRINP		;YES, IS USER MODE INPUT
	CAIN	CH,"="		;SPECIAL USER LINES
	  JRST	EQUINP		;YES, IS USER MODE DATA
	CAIN	CH,"%"		;ONE OF THE RESERVED LABELS
	  JRST	DECLAB		;YES, SET UP SEARCH FOR A DIGITAL LABEL
	CAIE	CH,MONCHR	;MONITOR LEVEL ( . OR @ )
	  JRST	CPYLOP		;IF NONE OF THE ABOVE SPECIALS, IS USER DATA
	TLO	F,FL.PER	;REMEMBER A PERIOD WAS SEEN
	JSP	T1,SAVPOS	;SAVE THE CURRENT POSITION
	MOVE	T1,[PUSHJ P,GETCTL] ;HOW TO GET A CHARACTER
	MOVEM	T1,COMFIL	;SAVE FOR THE SCANNERS
	PUSHJ	P,GETSIX	;GET A COMMAND

IFE <MONCHR-".">,<		;IF PROMPT IS A DOT, RESLVE THE AMBIGUITY OF .NUM
	JUMPN	T1,MONLIN	;SOMETHING IS PRESENT, SEE IF A BATCH COMMAND
	CAIG	CH,"9"		;SEE IF LINE IS .NUMBER
	CAIGE	CH,"0"		;SEE IF THE TERMINATOR IS A VALID DIGIT
	  JRST	MONSND		;SEND THE LINE TO THE MONITOR
	JSP	T1,REPOSI	;REPOSITION THE CTL FILE
	TLZ	F,FL.PER	;CLEAR A FLAG
	MOVEI	CH,MONCHR	;WILL SEND A PERIOD TO THE JOB
	JRST	CPYLOP		;THIS LINE IS USER DATA
>  ;END OF IFE

MONLIN:	TLNN	T1,007700	;CANNOT BE A BATCH COMMAND IF 1 LETTER
	  JRST	MONSND		;SEND SINGLE LETTER COMMANDS TO THE MONITOR
	MOVE	A,[-NBACMD,,BACMDS] ;AOBJN FOR TABLE LOOKUP
	PUSHJ	P,TABSRC	;DO THE TABLE SEARCH FOR COMMAND IN T1
	  JRST	MONSND		;NOT FOUND, GIVE TO THE MONITOR
	  JRST	MONSND		;GIVE AMBIGUOUS ONES TO THE MONITOR ALSO
	SKIPL	C,BADISP(C)	;GET DISPATCH, SEE IF VALID IF JOB IS IN ERROR
	TLNN	R,RL.JIE	;NOT VALID, IS THE JOB IN ERROR
	  JRST	(C)		;OK TO DO THE COMMAND
MONSND:	JSP	T1,REPOSI	;REPOSITION THE FILE
	TLNE	R,RL.JIE	;IS THE JOB IN ERROR NOW
	  JRST	USRERR		;YES, BUT NO .IF(XXXX) STUFF, LOOK FOR ERROR PACKETS
	PUSHJ	P,INMONM	;MAKE SURE THE JOB'S IN MONITOR MODE
	TLNE	F,FL.SIL	;IS THIS OUTPUT TO BE SILENCE
	  TLZ	F,FL.PER	;YES, CLEAR POSSIBLE PERIOD FLAG
	TLZE	F,FL.PER	;DID THE LINE START WITH A PERIOD
	  PUSHJ	P,PUTPER	;YES, ECHO A PERIOD FOR CLEANLINESS
	JRST	MONSUP		;COPY THE REST OF THE LINE (SUPPRESS TRAILING BLANKS)
;RULES FOR THE COMMAND TABLE
;	1)COMMANDS ARE UNIQUE IN 4 LETTERS
;	  1.1)EXCEPT BACKTO AND BACKSPACE (MONITOR COMMAND TAKES PRECEDENCE)
;	2)IF THE SECOND ARGUMENT IS PRESENT, THE COMMAND CAN BE EXECUTED
;	  EVEN IF THE JOB IS IN ERROR
;	3)IF THE THIRD ARGUMENT IS PRESENT, IT IS THE DISPATCH ADDRESS

DEFINE	CMDTBL<
	LSTOFF
	X	BACKSP,,MONSND	;SEND ANY ABBREVIATION OF BACKSP TO THE MONITOR
	X	BACKTO,		;GOTO A PRIOR LABEL
	X	CHKPNT,		;TAKE A CHECK POINT
	X	ERROR,		;DEFINE AN ADDITIONAL ERROR CHARACTER
	X	GOTO,		;PROCEED AT ANOTHER PLACE
	X	IF,E		;ERROR TESTING
	X	MESSAG,		;$MESSAGE FOR MINI-BATCH STANDARD
	X	NOERRO,		;TURN OFF ALL ERRORS (EXCEPT TIME EST EXCEEDED)
	X	NOOPER,E	;LEAVE DIALOGUE MODE
	X	OPERAT,		;ENTER DIALOGUE MODE WITH A SPECIFIC CHARACTER
	X	PLEASE,		;TRAP SYSTEM PLEASE COMMANDS
	X	REQUEU,		;REQUEUE THIS JOB
	X	REVIVE,		;RESUME NORMAL LISTING MODE
	X	SILENC,		;TURN OFF ALL OUTPUT
	LSTON
	>

DEFINE	X(A,B,C)<
	<SIXBIT\A\>
	>
BACMDS:	CMDTBL		;GENERATE THE COMMAND TABLE
NBACMD==.-BACMDS	;NUMBER OF COMMANDS

DEFINE	X(A,B,C)<
	IFB <C>,<
		IFB <B>,<EXP BB'A>
		IFNB <B>,<XWD 400000,BB'A>>
	IFNB <C>,<
		IFB <B>,<EXP C>
		IFNB <B>,<XWD 400000,C>>
	>
BADISP:	CMDTBL		;GENERATE THE DISPATCH TABLE
;HERE IF LINE IS FOR USER LEVEL INPUT

EQUINP:	TLO	F,FL.SUP	;SET SUPPRESSION OF FINAL CR-LF
USRINP:	JSP	T1,ISCMNT	;SEE IF THIS LINE IS A COMMENT TO THE LOG FILE
	TLNN	F,FL.SIL	;IS THE LOG FILE SILENCED
	  PUSHJ	P,PUTLOG	;NO, ECHO THE CHARACTER
CPYLIN:	PUSHJ	P,GETCTL	;GET THE NEXT CHARACTER
CPYL.1:	TLNE	F,FL.SUP	;WANT TO SUPPRESS THE CR-LF
	  JRST	CPYL.2		;YES, SEE IF THIS IS THE LINE FEED
CPYSND:	PUSHJ	P,CHKSND	;SEND IT TO THE JOB, CHECK RESULT
	CAIE	CH,CHR.LF	;DID WE SEND THE LINE FEED
	  JRST	CPYLIN		;NO, CONTINUE COPY
CPYOUT:	TLO	R,RL.EOL	;MARK END OF LINE SENT
	PUSHJ	P,PTYSND	;SEND THE PTY BUFFER
	PUSHJ	P,QTS		;GIVE JOB TIME TO READ IT
	JRST	HONORJ		;AND WAIT FOR NEXT INPUT REQUEST
CPYL.2:	CAIE	CH,CHR.LF	;YES, SEE IF THIS IS THE LINE FEED
	CAIN	CH,CHR.CR	;OR THE CARRIAGE RETURN
	  SKIPA			;YES, SUPPRESS THEM
	JRST	CPYSND		;NO, SEND THIS CHARACTER
	CAIE	CH,CHR.LF	;ANOTHER CHECK
	  JRST	CPYLIN		;IGNORE THE CARRIAGE RETURN
	TLZ	F,FL.SUP	;CLEAR SUPPRESSION ON THE LINE FEED
	JRST	CPYOUT		;OUTPUT THE CURRENT BUFFERS
VERTMO:	JSP	T1,ISCMNT	;SEE IF THIS LINE IS A COMMENT TO THE LOG FILE
	PUSHJ	P,SNDCHR	;SEND THE FF OR VT
	JRST	CPYOUT		;SEND THE BUFFER AND WAIT
;HERE TO SUPPRESS TRAILING BLANKS ON A MONITOR COMMAND LINE

MONSUP:	TLNE	R,RL.TIM	;NEED A TIME STAMP
	 TLNE	F,FL.SIL	;YES BUT IS THE OUTPUT SILENCED
	  SKIPA			;NEVER MIND THE STAMP
	   PUSHJ P,LOGSTP	;OUTPUT ONE NOW
	SETZ	T1,		;WILL COUNT BLANKS
MONS.1:	PUSHJ	P,GETCTL	;GET A CHARACTER FROM THE CTL FILE
	CAIE	CH,CHR.LF	;END OF THE LINE
	 CAIN	CH,CHR.CR	;THE CARRIAGE RETURN
	  JRST	CPYSND		;YES, SEND THAT, THE LINE FEED, AND DONE
	CAIN	CH," "		;A BLANK TO SUPPRESS
	  AOJA	T1,MONS.1	;YES, COUNT IT AND GET ANOTHER
	JUMPE	T1,MONS.2	;JUMP IF NO BLANKS PRECEEDED IT
	MOVE	T2,CH		;SAVE THE CHARACTER
	MOVEI	CH," "		;GET A BLANK
	PUSHJ	P,CHKSND	;SEND IT TO THE JOB, CHECK RESULT
	SOJG	T1,.-1		;SEND AS MANY AS NEEDED, CLEAR THE COUNTER
	MOVE	CH,T2		;GET THE ORIGINAL BACK
MONS.2:	PUSHJ	P,CHKSND	;SEND IT TO THE JOB, CHECK RESULT
	JRST	MONS.1		;GET ANOTHER

;HERE TO DETERMINE IF THIS LINE IS A COMMENT OR TO BE SENT AS USER DATA

CPYLOP:	MOVEI	T1,CPYL.1	;FAKE OUT A JSP
ISCMNT:	TLNN	R,RL.JIE	;IS THE JOB IN ERROR STATE
	TLNE	J,JL.UML	;OR IS THE JOB AT MONITOR LEVEL
	  JRST	CMNTLI		;YES, THIS LINE IS A COMMENT
	JRST	(T1)		;NO, SEND THIS LINE TO THE USER JOB

;HERE TO COPY A COMMENT LINE TO THE LOG FILE (CH IS THE FIRST CHARACTER)

CMNTLI:	PUSHJ	P,CPYCMT	;USE THE SUBROUTINE FOR THIS
	TLZ	F,FL.SUP	;IF COPIED A COMMENT LINE, CLEAR SUPRESSION
	JRST	HONO.1		;RESUME READING THE CTL FILE

;HERE TO SEND A CHARACTER TO THE SUBJOB, CHECK IF JOB IS STILL AROUND

CHKSND:	PUSHJ	P,SNDCHR	;FIRST, SEND THE CHARACTER, LOG IT
	TLNE	J,JL.UJA	;IS THE JOB STILL THERE
	  POPJ	P,		;YES, RETURN FOR MORE DATA
	PUSHJ	P,SNDUPC	;NO, ADD CONTROL C AND DUMP THE BUFFER
	PUSHJ	P,IOWAIT	;WAIT FOR MONITOR TO TYPE "?"
	PUSHJ	P,CLSLOG	;EMPTY THE LOG FILE BUFFERS
	JRST	CLOS.1		;AND DISMISS THE JOB
	SUBTTL	Job Processor - Execute Batch Commands

;GOTO COMMAND - PROCEED AT ANOTHER PLACE

BBGOTO:	PUSHJ	P,GETLAB	;GET A LABEL AND ECHO THE BATCH COMMAND LINE
	SKIPE	.JLABL(R)	;WAS THERE ONE
	  JRST	LABSRC		;YES, GO LOOKING
GOTO.1:	MOVEI	T1,[ASCIZ/BTNNLS No label specified or illegal syntax./]
	JRST	NORM.1		;OUTPUT ERROR AND GO TO %FIN::

;BACKTO COMMAND - GOTO A PRIOR LABEL

BBBACK:	MOVN	T1,.JCCNT(R)	;REMEMBER WHERE THIS COMMAND IS (APP.)
	HRL	T1,.JCUSI(R)	;BLOCK NUMBER,,(- COUNT LEFT)
	TLZ	T1,(1B0)	;IN CASE BLOCK IS END OF FILE
	MOVEM	T1,.JBAKP(R)	;SAVE FOR LABEL SEARCH
	PUSHJ	P,GETLAB	;GET A LABEL AND ECHO THIS LINE
	SKIPN	.JLABL(R)	;WAS THERE ONE
	  JRST	GOTO.1		;NO GIVE AN ERROR
	HRRZ	T1,J		;GET THE MONITOR JOB NUMBER
	RUNTIM	T1,		;GET AMOUNT OF CPU TIME USED
	CAMG	T1,.JRUNT(R)	;USER MUST DO SOMETHING TO GET RUNTIME
	  JRST	BACK.1		;OTHERWISE COULD BE A::.BACKTO A
	MOVEM	T1,.JRUNT(R)	;SAVE FOR NEXT BACKTO COMMAND
	TRO	F,FR.BAK!FR.FSI!FR.FIN	;SET SOME SEARCH FLAGS
	SETZM	.JCUSI(R)	;CLEAR A BLOCK NUMBER
	SETZM	.JCCNT(R)	;START AS A FRESH FILE
	JRST	LABSRC		;GO FIND THE LABEL
BACK.1:	MOVEI	T1,[ASCIZ/BTNBPL Your use of BACKTO has caused a possible loop./]
	JRST	NORM.1		;ISSUE ERROR AND GOTO %FIN::

;CHKPNT COMMAND - TAKE A CHECKPOINT

BBCHKP:	PUSHJ	P,GETLAB	;GET THE REQUEUE LABEL AND ECHO THIS LINE
	SKIPN	T1,.JLABL(R)	;WAS THERE A LABEL
	  JRST	GOTO.1		;NO, IS AN ERROR
	MOVEM	T1,.JCHRQ(R)	;STORE THE RESTART LABEL
	PUSHJ	P,FUNCHK	;PREFORM THE CHECKPOINT CALL
	PUSHJ	P,CLSLOG	;EMPTY OUT THE LOG FILE
	JRST	HONO.1		;RESUME READING THE CTL FILE

;REQUEUE COMMAND - REQUEUE THIS JOB (OPTIONAL RESTART LABEL)

BBREQU:	PUSHJ	P,GETLAB	;GET THE OPTIONAL LABEL, ECHO THIS LINE
	SKIPE	T1,.JLABL(R)	;WAS THERE A LABEL
	  MOVEM	T1,.JCHRQ(R)	;STORE THE RESTART LABEL
	JRST	ANLY.6		;GIVE AN AFTER, LOGOUT, AND REQUEUE
;NOERROR COMMAND - TURN OFF ALL ERRORS (EXCEPT TIME EST EXCEEDED)

BBNOER:	TLO	F,FL.NER	;SET NOERROR IN EFFECT
BAEXIT:	PUSHJ	P,BALINE	;ECHO THE BATCH COMMAND
	JRST	HONO.1		;RESUME READING THE CTL FILE

;NOOPERATOR COMMAND - LEAVE DIALOGUE MODE

BBNOOP:	SETZ	T1,		;CLEAR THE DIALOGUE CHARACTER
	DPB	T1,LDOPCH	;CLEAR IT
	JRST	BAEXIT		;AND EXIT THROUGH COMMON CODE

;ERROR COMMAND - DEFINE AN ADDITIONAL ERROR CHARACTER

BBERRO:	TLZ	F,FL.NER	;CLEAR NOERROR MODE
	JSP	T1,ER..OP	;CALL COMMON ROUTINE FOR ERROR/OPERATOR
	XWD	0,[ASCIZ/ERROR/] ;DEFAULT CHARACTER,,STRING NAME OF CALLER
LDERCH:	POINT	9,.JERCD(R),8	;HOW TO LOAD/STORE THE CHARACTER

;OPERATOR COMMAND - ENTER DIALOGUE MODE WITH THE SPECIFIED CHARACTER

BBOPER:	JSP	T1,ER..OP	;CALL THE COMMON PROCESS (IT WILL NO RETURN HERE)
	XWD	"$",[ASCIZ/OPERATOR/] ;DEFAULT IS $,CALLER IS OPERATOR
LDOPCH:	POINT	9,.JERCD(R),17	;HOW TO LOAD/STORE THE CHARACTER

;PLEASE COMMAND - OUTPUT A MESSAGE TO THE OPERATOR (OPTIONALLY WAIT)
;MESSAGE COMMAND - THE PLEASE COMMAND FOR THE MINI-BATCH STANDARD

BBMESS:
BBPLEA:	TLO	F,FL.PLS	;SET PLEASE IN PROGRESS
	PUSHJ	P,TTYALL	;GIVE A HEADER TO THE OPERATOR
	PUSHJ	P,BALINE	;ECHO LINE TO THE LOG AND TO THE OPERATOR
	TLZN	F,FL.PLS	;IS PLEASE STILL SET
	  JRST	[PUSHJ P,TTCRLF	;END THE TTY LINE
		JRST HONO.1]	;RESUME READING THE CTL FILE
	OUTSTR	[ASCIZ/OPR--Respond /]
	MOVEI	T1,[ASCIZ /GO (or KILL)
Waiting...
/]
	PUSHJ	P,SJBLIN	;TYPE #-STUFF
	PUSHJ	P,CLSLOG	;UPDATE THE LOG FILE BEFORE WAITING
	PUSHJ	P,OPRRES	;GET THE OPERATOR RESPONSE
	JRST	HONORJ		;START AT THE BEGINNING

;SILENCE COMMAND - TURN OFF THE LOG FILE
;REVIVE COMMAND - TURN IT BACK ON

BBSILE:	TLOA	F,FL.SIL	;SET SILENCE MODE
BBREVI:	  TLZ	F,FL.SIL	;CLEAR SILENCE MODE
	JRST	BAEXIT		;END OF THESE COMMANDS
;IF COMMAND - DO SOME ERROR TESTING

BBIF:	PUSHJ	P,SKPBLK	;SKIP OVER ANY BLANKS
	CAIE	CH,"("		;NEED THE OPENING PAREN
	  JRST	IF...E		;BAD IF COMMAND
	PUSHJ	P,GETSIX	;GET THE ARGUMENT
	JUMPE	T1,IF...E	;BAD COMMAND
	PUSHJ	P,SKPBLK	;SKIP MORE BLANKS
	CAIE	CH,")"		;BETTER BE THE CLOSURE
	  JRST	IF...E		;REAL BAD COMMAND
	MOVE	A,[-NIFCMD,,IFCMDS] ;AOBJN FOR TABLE LOOKUP
	PUSHJ	P,TABSRC	;LOOK FOR THE COMMAND IN T1
	  JRST	IF...E		;NOT FOUND
	  JRST	IF...E		;AMBIGUOUS
	JRST	@IFDISP(C)	;PROCESS THE IF COMMAND
IF...E:	PUSHJ	P,BALINE	;OUTPUT THE LINE
	MOVEI	T1,[ASCIZ/BTNIIC Illegal IF command argument or syntax error./]
	JRST	NORM.1		;GIVE ERROR AND GOTO %FIN::


;DEFINE THE LEGAL ARGUMENTS FOR IF COMMANDS. RULES:
;	1)COMMANDS ARE UNIQUE IN 4 LETTERS

DEFINE	CMDTBL<
	LSTOFF
	X	ERROR,	;TEST IF AN ERROR OCCURRED
	X	NOERRO,	;TEST IF NO ERRORS HAVE OCCURRED
	LSTON
	>

DEFINE	X(A)<
	<SIXBIT\A\>
	>

IFCMDS:	CMDTBL		;GENERATE THE ARGUMENT TABLE
NIFCMD==.-IFCMDS	;NUMBER OF THEM

DEFINE	X(A)<
	EXP	FF'A
	>

IFDISP:	CMDTBL		;GENERATE THE DISPATCH TABLE
;HERE TO PROCESS THE IF COMMAND

;FFERRO PROCESSES THE .IF(ERROR)statement FORM

;FFNOER PROCESSES THE .IF(NOERROR)statement FORM

;EXIT IS VIA IFTRUE IF THE CONDITION IS TRUE AND THE STATEMENT IS TO BE EXECUTED
;OR IFFALS IF THE CONDITION IS FALSE AND THE STATEMENT IS TO BE SKIPPED

FFERRO:	TLZN	R,RL.JIE	;DID AN ERROR OCCUR
	  JRST	IFFALS		;NO, IF(ERROR) IS FALSE
IFTRUE:	IDENT	[ASCIZ/ TRUE	/] ;IDENTIFY TRUE LINE
	JSP	T1,REPOSI	;BACK TO THE START OF THIS LINE
	TLZE	F,FL.PER	;NEED A PERIOD
	  PUSHJ	P,PUTPER	;YES, ECHO ONE FOR CLEANLINESS
IFTR.1:	PUSHJ	P,GETCTL	;CAN COPY EVERYTHING UP TO THE CLOSE PAREN
	PUSHJ	P,PUTLOG	;OUTPUT THIS ONE
	CAIE	CH,")"		;ALL AFTER THAT IS ANOTHER COMMAND
	  JRST	IFTR.1		;CONTINUE
	PUSHJ	P,LOGCLF	;END THIS LINE
	JRST	HONO.3		;FIND THE OBJECT STATEMENT AND EXECUTE IT

FFNOER:	TLZN	R,RL.JIE	;DID AN ERROR OCCUR
	  JRST	IFTRUE		;NO, .IF(NOERROR) IS TRUE
IFFALS:	IDENT	[ASCIZ/ FALSE	/] ;IDENTIFY THE FALSE LINE
	JSP	T1,REPOSI	;BACK UP THE LINE
	PUSHJ	P,BALI.1	;COPY THE ENTIRE LINE AS A COMMENT
	JRST	HONO.1		;PROCESS THE NEXT STATEMENT

;HERE TO GET A LABEL FOR COMMANDS LIKE GOTO (AND ECHO A BATCH COMMAND LINE)

GETLAB:	TRO	F,FR.RSC	;ALREADY HAVE CH
	PUSHJ	P,GETSIX	;GET A SIXBIT LABEL
	MOVEM	T1,.JLABL(R)	;STORE IT (EVEN IF NONE)
BALINE:	IDENT	[ASCIZ/ BATCH	/] ;IDENTIFY THIS LINE
	POP	P,TEMP1		;SAVE RETURN CAUSE STACK HAS CTL FILE POINTERS
	JSP	T1,REPOSI	;REPOSITION TO THE BEGINNING OF THE LINE
	PUSH	P,TEMP1		;PUT RETURN BACK ON
BALI.1:	TLZE	F,FL.PER	;DID LINE START WITH A PERIOD
	  PUSHJ	P,PUTPER	;YES, ECHO ONE FOR CLEANLINESS
	PUSHJ	P,GETCTL	;GET THE CHARACTER
	JRST	CMNT.1		;ECHO IT AND THE LINE, THEN RETURN
;HERE TO GET THE CHARACTER FOR .ERROR AND .OPERATOR
;CALL VIA JSP T1,ER..OP (DOES NOT RETURN TO CALLER)
;	0(T1) = XWD DEFAULT CHARACTER , [ASCIZ/CALLERS NAME/]
;	1(T1) = POINT STATEMENT TO STORE THE CHARACTER

ER..OP:	HLR	T2,(T1)		;GET THE DEFAULT CHARACTER
	DPB	T2,1(T1)	;STORE IT NOW
	PUSHJ	P,SKPBLK	;SKIP OVER ANY BLANKS (TABS)
	CAIE	CH,CHR.CR	;IS IT THE CARRIAGE RETURN
	PUSHJ	P,COMTRM	;THIS IS THE SAME CHECK AS IN GETONE
	  JRST	BAEXIT		;YES, RETURN WITH DEFAULT SET
	CAIE	CH,";"		;LINE HAVE A COMMENT
	CAIN	CH,"!"		;OTHER COMMENT CHARACTER
	  JRST	BAEXIT		;YES, STOP NOW
	CAIG	CH,40		;ONLY VALID IF ABOVE 40 OCTAL
	  JRST	ER...1		;BAD CHARACTER SPECIFIED
	DPB	CH,1(T1)	;STORE THE SPECIFIED CHARACTER
	JRST	BAEXIT		;AND RETURN THROUGH COMMON CODE
ER...1:	SETZ	T2,		;ON ERROR, CLEAR ANY DEFAULT CHARACTER
	DPB	T2,1(T1)	;STORE A NULL CHARACTER
	HRRZ	T1,(T1)		;GET ADDRESS OF CALLERS NAME
	MOVEM	T1,TEMP2	;SAVE IN A TEMP
	PUSHJ	P,BALINE	;ECHO THE BATCH COMMAND
	MSGLOG	[ASCIZ/BTNICS Illegal character specified for /]
	TXTLOG	@TEMP2		;APPEND THE CALLERS NAME
	PUSHJ	P,LGCLF2	;COUPLE OF BLANK LINES
	JRST	FINSRC		;GOTO %FIN::

;HERE FOR THE FIRST LOOK AT DIGITAL RESERVED LABELS (%XXXXX::)

USRERR:	TLZE	F,FL.PER	;ENTERED AT USRERR FROM MONSND
DECLAB:	  PUSHJ	P,DECRBP	;BACK UP OVER THE % SIGN (OR .)
	TRO	F,FR.LSL	;LIST LINES SKIPPED
	TLNN	R,RL.JIE	;IS THE JOB IN ERROR
	  JRST	FINSRC		;NO, LOOK FOR % FIN
	PUSHJ	P,SYSPRG	;WHERE DID THE PROGRAM COME FROM
	  SKIPA	T1,[SIXBIT/%CERR/] ;SYS
	MOVE	T1,[SIXBIT/%ERR/] ;USER
	MOVEM	T1,.JLABL(R)	;SAVE THE LABEL
	JRST	LABSRC		;NOW SEARCH FOR IT

;HERE TO SET UP FOR A SEARCH FOR %FIN:: OR %TERR::

TIMERR:	TLOE	F,FL.%XT	;TIME EST EXCEEDED GIVE EXTRA TIME
	  JRST	CLOSJB		;ALREADY DID, KLUNK THE JOB NOW
	TRO	F,FR.LSL	;LIST LINES SKIPPED FOR TIME LIMIT EXCEEDED
	SKIPA	T1,[SIXBIT/%TERR/]  ;SET UP FOR SEARCH
FINSRC:	MOVE	T1,[SIXBIT/%FIN/] ;LABEL WE WANT
	MOVEM	T1,.JLABL(R)
	JRST	LABSRC		;NOW SEARCH FOR IT
;HERE TO ACTUALLY DO THE LABEL SEARCH.  .JLABL(R) HAS THE LABEL

LABSRC:	TRO	F,FR.%SG	;INCLUDE % SIGNS IN LABELS
	TLO	R,RL.FCI	;FAKE OUT CLOSJB IF WE NEVER FIND THE LABEL
	MOVE	T1,[PUSHJ P,GETCTL] ;HOW TO GET A CHARACTER
	MOVEM	T1,COMFIL	;STORE FOR GETONE
LABS.0:	TRNE	F,FR.LSL	;LISTING SKIPPED LINES
	  JSP	T1,SAVPOS	;YES, SAVE OUT CURRENT POSITION
	PUSHJ	P,GETONE	;GET THE FIRST CHARACTER OF THIS LINE
	  JRST	LABS.5		;END OF LINE CHARACTER
	  CAIE	CH,"%"		;SPECIAL CHARACTER, IS IT % SIGN
	  JRST	LABS.4		;A NUMBER OR OTHER SPECIAL, IS NOT A LABEL
	TRO	F,FR.RSC	;LINE STARTS WITH A LETTER, RE-GET IT IN GETSIX
	PUSHJ	P,GETSIX	;GET A POSSIBLE LABEL
	CAIN	CH,":"		;FIELD END WITH A COLON
	  JRST	LABFND		;YES, FOUND A LABEL
LABS.4:	TRNE	F,FR.LSL	;IS THE POSITION ON THE STACK
	  JRST	LABS.3		;YES, LIST THE SKIPPED LINE
	SKIPA			;MIGHT ALREADY BE A TERMINATOR
LABS.1:	PUSHJ	P,GETCTL	;GET THE NEXT CHARACTER
	CAIE	CH,CHR.LF	;END OF THIS LINE YET
	  JRST	LABS.1		;IGNORE MORE CHARACTERS
LABS.2:	TRNN	F,FR.BAK	;END OF A LINE, DOING A BACKTO
	  JRST	LABS.0		;NO, CHECK FOR A LABEL ON THIS LINE
	MOVN	T1,.JCCNT(R)	;BUILD SAME TYPE OF POSITION AS BACKTO DID
	HRL	T1,.JCUSI(R)	;TO SEE IF WE PASSED THE ORIGINAL BACKTO
	TLZ	T1,(1B0)	;IN CASE BLOCK IN END OF FILE
	CAML	T1,.JBAKP(R)	;PASS IT UP YET
	  JRST	CLOSJB		;YES, REPORT THE ERROR
	JRST	LABS.0		;NO, LOOK FOR A LABEL ON THIS LINE
LABFND:	TRNN	F,FR.FIN	;CAN WE SKIP OVER A %FIN::
	 CAME	T1,[SIXBIT/%FIN/] ;NO, IS THIS %FIN::
	  SKIPA			;SEE IF LABEL WE ARE SEARCHING FOR
	   JRST	FINFND		;FOUND A %FIN::, SEARCH IS COMPLETED
	CAME	T1,.JLABL(R)	;IS IT THE ONE WE WERE LOOKING FOR
	  JRST	LABS.4		;NO, CONTINUE SEARCH
	CAMN	T1,[SIXBIT/%TERR/]  ;LOOKING FOR TIME LIMIT RECOVERY
	  JRST	FINF.2		;YES, AND THIS IS IT, GIVE %EXTRA
LABF.1:	TRNN	F,FR.LSL	;IS THE CURRENT POSITION ON THE STACK
	  JRST	LABF.2		;NO, LABEL THIS LINE
	POP	P,(P)		;CLEAN UP AFTER SAVPOS, WE ARE AT THE RIGHT PLACE
	POP	P,(P)		;...
	POP	P,(P)		;...
LABF.2:	IDENT	[ASCIZ/ BLABL	/] ;IDENTIFY LABELED LINE
	SIXLOG	.JLABL(R)	;OUTPUT THE LABEL FOUND
	PUSHJ	P,PUTCOL	;ADD A COLON
	PUSHJ	P,GETCTL	;GET THE NEXT CHARACTER (MAYBE ANOTHER COLON)
	PUSH	P,CH		;SAVE IT FOR NOW
	CAIN	CH,":"		;WAS IT A COLON
	  PUSHJ	P,PUTLOG	;YES, OUTPUT IT
	PUSHJ	P,LOGCLF	;END THE LINE
	TRZ	F,FR.%SG!FR.BAK!FR.LSL!FR.FIN	;CLEAR SEARCH TYPE FLAGS
	TLZ	R,RL.JIE!RL.DIA	;AFTER A SUCCESSFUL FIND, CLEAR JOB IN ERROR
	POP	P,CH		;RESTORE THAT CHARACTER
	CAIN	CH,":"		;WAS IT THE SECOND COLON
	  JRST	HONO.3		;YES, FIND THE OBJECT STATEMENT AND EXECUTE IT
	PUSHJ	P,SKPBLK	;SKIP THIS IF A BLANK (AND ANY OTHERS)
	JRST	HONO.4		;NOW EXECUTE THE OBJECT STATEMENT
LABS.3:	JSP	T1,REPOSI	;REPOSITION THE CTL FILE
	PUSHJ	P,GETCTL	;GET THE FIRST CHARACTER
	PUSHJ	P,CPYCMT	;COPY IT AND THE REST AS A COMMENT LINE
	JRST	LABS.2		;RETURN TO BACKTO CHECK
LABS.5:	CAIE	CH,CHR.FF	;CHECK EOL CHARACTER FOR FORM FEED-VERTICAL TAB
	CAIN	CH,CHR.VT	;CHARACTER AFTER THEM CAN START A NEW LABEL
	  MOVEI	CH,CHR.LF	;PRETEND A LINE FEED TO END THIS LINE
	JRST	LABS.4		;IF LISTING LINES, IT WILL COME OUT A FF OR VT
;HERE WHEN A %FIN:: HAS BEEN FOUND   T1=SIXBIT/%FIN/

FINFND:	CAMN	T1,.JLABL(R)	;WERE WE SEARCHING FOR %FIN::
	  JRST	FINF.1		;YES, SKIP THE MESSAGE
	PUSHJ	P,LOGBLK	;GET A BLANK LINE IN THE LOG FILE
	PUSHJ	P,LGCMNT	;PREPARE A COMMENT LINE
	TXTLOG	[ASCIZ/BTNFFS Found %FIN while searching for /]
	SIXLOG	.JLABL(R)	;OUTPUT THE LABEL
	TXTLOG	[ASCIZ/, proceeding from %FIN/]
	PUSHJ	P,LGCLF2	;ISOLATE THE MESSAGE FROM THE LABEL
	MOVE	T1,[SIXBIT/%FIN/]  ;NEED TO RESET THE LABEL SEARCHED FOR
	MOVEM	T1,.JLABL(R)	;SO WE CAN PRINT IT OUT AT LABF.2
FINF.1:	PUSHJ	P,CHKCLS	;SEE IF A CLOSE/DUMP IS NEEDED
FINF.2:	TLZN	F,FL.TLE	;DID THE JOB EXCEED THE TIME LIMIT
	  JRST	LABF.1		;NO, RESUME NORMAL ROUTE
	PUSHJ	P,INMONM	;MAKE SURE THE JOBS IN MONITOR MODE
	HRRZ	C,Q.ILIM(R)	;GET THE JOBS TIME EST
	IMULI	C,%EXTRA	;COMPUTE THE EXTRA TIME AVAILABLE
	IDIVI	C,^D100		;AS A PERCENTAGE OF THE ORIGINAL EST
	CAIGE	C,%EXTRA	;BUT LETS BE REASONABLE ABOUT IT
	  MOVEI	C,%EXTRA	;USING %EXTRA HERE IS PROBABLY OK

IFN FTUUOS,<
	MOVE	A,[2,,B]	;SET UP FOR JBSET
	HRRZ	B,J		;GET THE JOB NUMBER
	HRLI	C,.STTLM	;SET TIME FUNCTION
	JBSET.	A,		;TRY IT WITH THE UUO
>  ;END OF IFN FTUUOS

	  PUSHJ	P,SETTIM	;SEND THE COMMAND IF THAT FAILED
	JRST	LABF.1		;AND RETURN TO NORMAL SEARCH
	SUBTTL	Job Processor - Perform Auto KJOB and Dismiss the Job

CLOSJB:	TLNE	R,RL.KJB	;WHAT ARE WE DOING HERE
	  JRST	CLOS.3		;IN LOTS OF TROUBLE, GO DISMISS THE JOB
	TRNN	F,FR.%SG	;WAS A LABEL SEARCH IN PROGRESS
	  JRST	CLOS.0		;NO, SKIP THE ERROR MESSAGE
	LDB	T1,[POINT 6,.JLABL(R),5] ;GET THE FIRST SIXBIT CHARACTER
	CAIN	T1,'%'		;WAS IT ONE OF THE % LABELS
	  JRST	CLOS.4		;YES, GIVE A DIFFERENT MESSAGE
	MSGLOG	[ASCIZ/BTNCNF Could not find label /]
CLOS.5:	SIXLOG	.JLABL(R)	;OUTPUT THE LABEL WE COULDN'T FIND
	PUSHJ	P,LGCLF2	;ADD A FEW BLANKS
CLOS.0:	TLNE	R,RL.FCI	;HIT EOF WHILE LOOKING FOR FIRST CHARACTER
	TLNN	J,JL.UML	;IS JOB AT MONITOR LEVEL
	  PUSHJ	P,INMO.1	;JUNK SENT OR AT USER LEVEL, GET TO THE MONITOR
	PUSHJ	P,CHKCLS	;CHECK IF A CLOSE/DUMP IS NEEDED
	PUSHJ	P,ATOKJB	;PERFORM THE AUTO KJOB

CLOS.1:	IFN	JOBMSG,<
	PUSHJ	P,TTYSJB	;TYPE OUT THE SUBJOB NUMBER
	OUTSTR	[ASCIZ/finished/]
	PUSHJ	P,TTCRLF
	>
	PUSHJ	P,CTLDIS	;DISPOSE OF THE CTL FILE (MAYBE)
CLOS.3:	HRLI	P,-.JPSIZ	;RESET JOB PROCESSOR PDL
	HRRI	P,.JPLST-1(R)	;RESET IT BEFORE THE CALL TO QMANGR
	PUSHJ	P,REMCTL	;REMOVE ANY OLD CTL FILE ASSIGNMENTS
	PUSHJ	P,DELSPL	;REMOVE ANY SPOOLED FILES FOR THIS JOB
	MOVEI	A,QSRMSG	;POINT TO THE MESSAGE BLOCK
	MOVX	B,<INSVL.(REL.FD,MS.CNT)!INSVL.(.QOREL,MS.TYP)>
	MOVEM	B,.MSTYP(A)	;STORE LENGTH AND TYPE
	MOVE	B,Q.ITN(R)	;TASK NAME GIVEN BY QUASAR
	MOVEM	B,REL.IT(A)	;STORE IT
	MOVE	B,.JJOBN(R)	;GET THE JOB NUMBER
	MOVE	C,Q.LMOD(R)	;GET THE LOG FILE BITS
	TXNE	C,FP.DEL	;TO BE DELETED
	  TXO	B,RL.DLG	;YES, SET A BIT
	LOAD	C,Q.IDEP(R),EQ.OUT  ;GET /OUTPUT: VALUE
	CAIE	C,%EQOLG	;PRINT THE LOG
	 CAIN	C,%EQOLE	;OR PRINT IT IF AN UNHANDLED ERROR
	  SKIPA			;ONE OF THE ABOVE
	   JRST	CLOS.8		;NEITHER, DON'T REQUEST PRINTING
	TRNN	F,FR.UHE	;AN UNHANDLED ERROR OCCUR
	 CAIN	C,%EQOLG	;NO, WANT IT ANYWAY
	  TXO	B,RL.PRL	;MUST PRINT THE LOG
CLOS.8:	MOVEM	B,REL.BJ(A)	;STORE FLAGS AND JOB NUMBER
	TLNE	R,RL.NLG	;WAS THERE A LOG FILE
	  JRST	CLOS.6		;NO, CANCEL THE ABOVE WORK



;;;  CLOSJB IS CONTINUED ON THE NEXT PAGE
IFN FTUUOS,<
	MOVE	B,Q.LSTR(R)	;GET THE LOG FILE STRUCTURE
	CAMN	B,[SIXBIT/NUL/]	;HAVE I BEEN WRITING ON NUL:
	  JRST	CLOS.6		;YES, SKIP THE SPEC
	MOVEI	B,Q.LSTR(R)	;START AT THE STRUCTURE
	MOVEI	C,REL.FD(A)	;MOVE TO RELEASE BLOCK
CLOS.2:	CAIG	B,Q.LDIR(R)	;COPY EVERYTHING TO THE PATH
	  JRST	CLOS.7		;ALWAYS INCLUDE THOSE
	CAIE	B,Q.LMOD(R)	;LAST LOC TO TRY FOR
	 SKIPN	(B)		;OR STOP AT THE FIRST ZERO (IN THE PATH)
	  JRST	CLOS.6		;END OF THE SPEC
CLOS.7:	MOVE	D,(B)		;GET THE DATA
	MOVEM	D,(C)		;STORE THE WORD
	LOAD	D,.MSTYP(A),MS.CNT  ;GET THE COUNT FOR AOS
	AOS	D
	STORE	D,.MSTYP(A),MS.CNT  ;STORE ADJUSTED COUNT
	AOJA	B,.+1		;BUMP B
	AOJA	C,CLOS.2	;BUMP C AND GO
>  ;END OF IFN FTUUOS

IFN FTJSYS,<
	MOVE	B,.JLDEV(R)	;GET LOGFILE DEVICE
	CAMN	B,[ASCII /NUL/]	;IS IT "NUL"?
	JRST	CLOS.6		;YES, IGNORE ALL OF THIS
	HRLI	B,Q.LSTR(R)	;WHERE THE LOG FILE DESCRIPTOR IS
	HRRI	B,REL.FD(A)	;FOR THE RELEASE MESSAGE
	MOVE	C,.JLGFD(R)	;LENGTH OF THE FD
	ADDI	C,REL.FD-1(A)	;LAST LOC TO MOVE INTO
	BLT	B,0(C)		;APPEND THE LOG FILE TO THE RELEASE
	LOAD	B,.MSTYP(A),MS.CNT  ;GET THE CURRENT SIZE WITHOUT THE FD
	ADD	B,.JLGFD(R)	;LENGTH JUST MOVED
	STORE	B,.MSTYP(A),MS.CNT  ;ADJUST FOR IT
>  ;END OF IFN FTJSYS

CLOS.6:	PUSHJ	P,SNDQSR##	;SEND IT O QUASAR
	HRRZS	R		;CLEAR ALL FLAGS
	PUSHJ	P,QTS		;GO DORMANT, WILL NOT RETURN HERE
CLOS.4:	PUSHJ	P,LOGBLK	;GET A BLANK LINE BEFORE THE MESSAGE
	PUSHJ	P,LGCMNT	;PREPARE THE LOG FILE FOR A COMMENT
	TXTLOG	[ASCIZ/BTNECF End of the Control File while searching for /]
	JRST	CLOS.5		;ADD THE LABEL AND AUTO KJOB THIS JOB
;HERE TO PROCESS OPERATOR REQUEST TO KILL THIS JOB

KILLJB:	PUSHJ	P,INMO.1	;FORCE JOB TO MONITOR MODE
	PUSHJ	P,LOGBLK	;OUTPUT A BLANK LINE
	IDENT	[ASCIZ/ BAOPR	KILL /] ;IDENTIFY THIS LINE
	SIXLOG	.JWHO(R)	;APPEND OPERATORS OPTION FOR KILL
	MOVEI	CH," "		;APPEND A BLANK
	PUSHJ	P,PUTLOG	;OUTPUT IT
	TXTLOG	.JOPER(R)	;APPEND ANY OPERATOR COMMENT
	PUSHJ	P,LOGBLK	;ANOTHER BLANK LINE
	TLO	R,RL.JIE!RL.FCI	;SET ERROR IN JOB FLAG PLUS ANOTHER
	MOVE	T1,.JWHO(R)	;GET THE OPERATORS OPTION FOR KILL
	CAMN	T1,[SIXBIT/ERROR/] ;KILL WITH ERROR RECOVERY
	  JRST	HONORJ		;YES, JIE IS SET, RESUME WITH THE CTL FILE
	TLZ	R,RL.JIE	;CLEAR THE FLAG TO AVOID CLOSE/DUMP
	TRO	F,FR.UHE	;AN UNEXPECTED CONDITION
	JRST	CLOSJB		;GO KILL THE JOB

;HERE TO PROCESS OPERATOR REQUEST TO REQUEUE THIS JOB

REQUJB:	PUSHJ	P,INMO.1	;FORCE JOB TO MONITOR MODE NOW
	PUSHJ	P,LOGBLK	;OUTPUT A BLANK LINE
	IDENT	[ASCIZ/ BAOPR	REQUEUE /] ;IDENTIFY OPERATORS REQUEUE
	SKIPN	T1,.JWHO(R)	;GET THE TIMER REQUESTED
	  MOVEI	T1,REQTIM	;USE THE DEFAULT
	IDIVI	T1,^D60		;HOURS IN T1, MINUTES IN T2
	PUSH	P,T2		;SAVE MINUTES
	PUSHJ	P,LGDEC2	;OUTPUT HH
	PUSHJ	P,PUTCOL	;ADD A COLON
	POP	P,T1		;RESTORE MINUTES
	PUSHJ	P,LGDEC2	;AND OUTPUT MM
	PUSHJ	P,LOGBLK	;ADD ANOTHER BLANK LINE
	SKIPN	A,.JWHO(R)	;GET THE REQUEUE TIME AGAIN
	  JRST	ANLY.6		;SET UP THE DEFAULT
	JRST	ANLY.2		;GIVE IT AN AFTER AND REQUEUE THIS JOB
;HERE TO PROCESS OPERATOR REQUEST TO STOP THIS JOB

STOPJB:	PUSHJ	P,INMO.1	;FORCE THE JOB TO MONITOR MODE
	PUSHJ	P,JUSTCL	;CLOSE LOG AND WAIT FOR GO
	IDENT	[ASCIZ/ BATCH	./] ;LET THE USER KNOW WE'RE CONTINUING THE JOB
	TXTJOB	[ASCIZ/CONTINUE/] ;TELL THE MONITOR CONTINUE
	JRST	SNDCLF		;END THE LINE, SEND THE BUFFER, AND RETURN
JUSTCL:	PUSHJ	P,CLSLOG	;CLOSE OUT THE LOG FILE
	TLO	R,RL.STP	;INDICATE STOPPED
	JRST	QTS		;RETURN TO PROCESS WHEN OPERATOR SAYS 'GO'

;HERE TO PROCESS USER REQUEST TO KILL THE JOB

CANCJB:	PUSHJ	P,INMO.1	;FORCE TO MONITOR LEVEL
	PUSHJ	P,LOGBLK	;ALIGN THE OUTPUT
	IDENT	[ASCIZ/ BAUSR	Job Cancelled by User Request/]
	PUSHJ	P,LGCMNT	;PREPARE FOR ANOTHER COMMENT
	TXTLOG	[ASCIZ/  Requesting user was /]

IFN FTUUOS,<
	MOVE	T1,.JKILR(R)	;GET THE PPN WHO DID IT
	PUSHJ	P,LOGF.2	;OUTPUT IT TO THE LOG FILE
>  ;END OF IFN FTUUOS

IFN FTJSYS,<
	HRROI	T1,TEMP3	;BLOCK FOR DIR TO NAME CONVERSION
	LOAD	T2,.JKILR(R)	;DIRECTORY OF KILLER
	DIRST			;PLACE DIRECTORY NAME IN TEMP3
	  HALT	.		;;;SHOULDN'T HAPPEN
	TXTLOG	TEMP3		;OUTPUT DIRECTORY TO THE LOG FILE
>  ;END OF IFN FTJSYS

	PUSHJ	P,LOGBLK	;ISOLATE THAT LINE
	TLO	R,RL.FCI	;SET A FLAG FOR CLOSJB
	TLZ	R,RL.JIE	;AVOID THE CLOSE/DUMP PAIR
	TRO	F,FR.UHE	;AN UNEXPECTED CONDITION
	JRST	CLOSJB		;CANCEL IT NOW
;HERE IS THE ACTUAL SUBROUTINE TO DO THE AUTO KJOB

ATOKJB:	TLZ	F,FL.SIL	;CLEAR SILENCE IF WE ARE GOING TO KJOB THIS JOB
	PUSHJ	P,PREKJB	;SET UP FOR AUTO LOGOUT
	PUSHJ	P,INMONM	;MAKE SURE THE JOBS IN MONITOR MODE
	TLNE	R,RL.TIM	;NEED A TIME STAMP
	  PUSHJ	P,PUTPER	;YES, OUTPUT (SOMETHING), THAT WILL STAMP IT
KJOB.K:	TLNN	J,JL.ULI	;IS THE JOB THERE NOW
	  POPJ	P,		;NO, THAT WAS EASY
	TLO	R,RL.KJB	;MARK ON THE WAY OUT
	MOVEI	T1,""""		;GET A QUOTE
	DPB	T1,LDOPCH	;SET AS DIALOGUE MODE SIGNAL
	TXTJOB	KJSTR		;SEND THE KJOB STRING
	PUSHJ	P,SNDCLF	;END THE LINE
KJOB.1:	PUSHJ	P,IOWAIT	;WAIT FOR RETURN TO MONITOR MODE
	TLNN	R,RL.NLG	;IS THERE A LOG FILE
	  PUSHJ	P,CLSLOG	;YES, CLOSE IT NOW
	TLNN	J,JL.ULI	;DID THE JOB GO AWAY
	  POPJ	P,		;YES, RETURN

IFN FTJSYS,<
	PUSHJ	P,QTS		;NO, CONTEXT SWITCH
	JRST	KJOB.1		;AND TRY AGAIN
>  ;END IFN FTJSYS

KJOB.2:	TLZ	R,RL.DIA	;NO, CLEAR OUTPUT TO THE OPERATOR
	PUSHJ	P,INMONM	;GET BACK TO MONITOR MODE
	PUSHJ	P,TTCRLF	;A NEW LINE TO THE OPERATOR
	PUSHJ	P,TTYALL	;TYPE SUBJOB NUMBER AND MONITOR JOB NUMBER
	MSGTTY	[ASCIZ/BATCON unable to KJOB.
OPR--Please attach to the job and kill it. Then respond /]
	MOVEI	T1,[ASCIZ /GO
Waiting.../]
	PUSHJ	P,SJBLIN	;TYPE SJB NUMBER AND A LINE
	PUSHJ	P,OPRRES	;WAIT FOR THE RESPONSE
	JRST	KJOB.K		;SEE IF JOB IS STILL THERE (OR TRY AGAIN)
	SUBTTL	Job Processor - Copy and Interrogate User Output

IOW.01:	SKIPE	CH,.JUPLT(R)	;IS A LOG FILE UPDATE TIMER RUNNING
	 TLNE	R,RL.LGI!RL.KJB	;YES, BUT IS THE JOB ON THE WAY IN OR OUT
	  JRST	IOW.02		;IGNORE THE TIMER REQUEST
	SUB	CH,CURMST	;HOW LONG HAS IT BEEN RUNNING
	MOVMS	CH		;IGNORE SIGN PROBLEMS
	CAML	CH,[SPLMBC*^D60*^D1000] ;THE REQUESTED INTERVAL
	  PUSHJ	P,CLSLOG	;TIME TO FLUSH THE BUFFERS
IOW.02:	PUSHJ	P,QTS		;WAIT FOR NEXT WAKE UP
IOWAIT:	PUSHJ	P,GJBSTS	;GET THE STATUS OF THE JOB
	TLNN	J,JL.UDI!JL.UOA	;JOB WANT INPUT OR HAS OUTPUT
	  JRST	IOW.01		;NO, GO BACK AND WAIT
	TLNN	J,JL.UOA	;WAS IT OUTPUT AVAILABLE
	  JRST	[TLNE F,FL.SIL	;JOB WANTS INPUT, IN SILENCE MODE
		  TLO R,RL.TIM	;YES, KEEP THE OUTPUT ALIGNED
		 POPJ P,]	;RETURN TO THE CALLER
	PUSHJ	P,INPPTY	;INPUT THE BUFFER
	TLNE	R,RL.DIA!RL.QTS!RL.NLG ;MORE DIALOGUE OUTPUT (OR COMMENTS)
	  PUSHJ	P,TTYALL	;YES, OUTPUT AN IDENTIFIER
READPY:	PUSHJ	P,GETPTY	;GET A CHARACTER
	  JRST	READ.3		;END OF THE BUFFER, LOOK FOR MORE DIALOGUE OUTPUT
READ.0:	TLZN	R,RL.EOL	;HAS A LINE TERMINATOR BEEN SENT
	TLNE	R,RL.TIM	;OR IS THIS THE FIRST CHARACTER OF A LINE
	  PUSHJ	P,ERRCHK	;YES, CHECK FOR ERROR INDICATORS
	TLNE	R,RL.JIE	;DID ERRCHK FIND AN ERROR
	  TLZ	F,FL.SIL	;YES, CLEAR SILENCE FOR THIS JOB
	TLNE	R,RL.QTS!RL.DIA	;SHOULD THE OPERATOR SEE THIS CHARACTER
	  OUTCHR CH		;YES, TYPE IT OUT
	TLNE	F,FL.SIL	;IS THE JOB OUTPUT TO BE SUPPRESSED
	  JRST	READ.2		;YES, DON'T INCLUDE IN THE LOG FILE
	PUSHJ	P,PUTLOG	;ECHO THE CHARACTER
READ.1:	TLNE	R,RL.TIM	;END OF A LINE SENT
	  TLZ	R,RL.QTS	;YES, CLEAR QUOTES FLAG
	JRST	READPY		;CONTINUE READING
READ.2:	TLZ	R,RL.TIM	;CLEAR TIME STAMP NEEDED
	CAIG	CH,CHR.FF	;DO VERTICAL PAPER MOTION CHECK HERE
	CAIGE	CH,CHR.LF	;SO ERRCHK CAN BE CALLED EVEN IF SILENCE IS SET
	  JRST	READ.1		;NOT ONE OF LF,VT,FF RESUME NORMAL PATH
	TLO	R,RL.TIM	;SET TIME STAMP TO RECOGNIZE COLUMN 1
	JRST	READ.1		;RESUME
READ.3:	TLNN	R,RL.DIA!RL.QTS!RL.NLG ;JOB IN DIALOGUE MODE OR STILL NEED <CR/LF>
	  JRST	IOWAIT		;NO, JUST GO TO SLEEP, LET WAKE GET US BACK
	MOVEI	T1,1		;TAKE A QUICK NAP
	SLEEP	T1,		;LET THE SUBJOB GET ANOTHER BUFFER READY
	PUSHJ	P,INPPTY	;TRY TO FILL A NEW BUFFER
	PUSHJ	P,GETPTY	;SEE IF ANYTHING THERE
	  JRST	IOWAIT		;NO, GO BACK TO SLEEP
	JRST	READ.0		;GO FROM HERE
;HERE TO CHECK PTY OUTPUT FOR ERROR INDICATORS/QUOTES/DIALOGUE MODE

ERRCHK:	CAIE	CH,"?"		;STANDARD ERROR CHARACTER
	  JRST	ERRC.2		;NO, LOOK FOR ADDITIONAL CHARACTER
	TLNE	R,RL.LGI	;HERE DURING LOGIN SEQUENCE
	  JRST	ERRLGI		;YES, GET LOGIN ERROR CODE
	PUSHJ	P,GJTIML	;GET SUBJOBS REMAINING TIME LIMIT
	JUMPN	T1,ERRC.1	;JUMP IF NOT TIME LIMIT EXCEEDED
	TLOA	F,FL.TLE	;SET THE TIME LIMIT FLAG
ERRC.1:	 TLNN	F,FL.NER	;IGNORE ERRORS ?
	  TLO	R,RL.JIE	;NOPE (OR TIME LIMIT EXCEEDED), SET ERROR IN JOB
	JRST	ERRC.3		;AVOID DUPLICATE WORK
ERRC.2:	TLNE	F,FL.NER	;IGNORE ERRORS ?
	  JRST	ERRC.3		;YES, LOOK FOR QUOTES, OPERATOR
	LDB	T1,LDERCH	;LOAD THE ERROR CHARACTER INTO T1
	CAIN	CH,(T1)		;IS THIS THE ONE
ERRC.4:	  TLO	R,RL.JIE	;YES, SET ERROR FLAG
ERRC.3:	LDB	T1,LDOPCH	;GET THE DIALOGUE MODE SIGNAL
	CAIN	CH,(T1)		;IS THIS IT
	  TLO	R,RL.DIA!RL.QTS	;YES, SET JOB IN DIALOGUE MODE
	CAIN	CH,""""		;IS IT A COMMENT TO THE OPERATOR
	  TLO	R,RL.QTS	;YES, SET QUOTES MODE
	TLNN	R,RL.QTS	;NEED TO IDENTIFY THE OUTPUT TO THE OPERATOR
	  POPJ	P,		;NO, RETURN
	PUSH	P,CH		;SAVE A CHARACTER
	PUSHJ	P,TTYALL	;TYPE OUT SUBJOB INFORMATION NOW
	POP	P,CH		;RESTORE
	POPJ	P,		;AND RETURN
;HERE TO GET THE ERROR CODE FROM LOGIN IN THE FORM ?(n)LGNxxx message

ERRLGI:	PUSHJ	P,PUTLOG	;SEND THE ?
	SETZ	T1,		;EVENTUAL ERROR CODE

IFN FTUUOS,<
	PUSHJ	P,NXTPTY	;GET THE NEXT CHARACTER
	CAIE	CH,"("		;ERROR CODE FOLLOWS?
	  JRST	ERRSTO		;NO, STORE 0 AND RETURN
ERRL.1:	PUSHJ	P,PUTLOG	;OUTPUT THE (
	PUSHJ	P,NXTPTY	;GET THE CODE NUMBER
	MOVEI	T2,-"0"(CH)	;CONVERT TO BINARY
	CAILE	T2,^D9		;WAS IT A DIGIT
	  JRST	ERRSTO		;NO, STORE ERROR SO FAR AND RETURN
	IMULI	T1,^D10		;POSITION OTHER DIGITS
	ADDI	T1,(T2)		;INCLUDE THIS DIGIT
	JRST	ERRL.1		;ECHO THIS DIGIT AND GET MORE
ERRSTO:	CAIN	T1,1		;IS IT LOGIN ERROR # 1
	  POPJ	P,		;YES, THATS A WARNING, EXIT NOW
>  ;END OF IFN FTUUOS

	TLO	R,RL.JIE	;INDICATE JOB IN ERROR
	HRRM	T1,.JERCD(R)	;STORE THE ERROR CODE
	POPJ	P,		;RETURN TO INLINE CODE
	SUBTTL	Job Processor - Error Analysis, Processing, and Reporting

;HERE TO INTERROGATE THE LOGIN FAILURE

ANALYZ:

IFN FTUUOS,<
	TLNE	R,RL.JNA	;DID A JOB NUMBER EVER GET ASSIGNED
	  JRST	ANLY.1		;YES, LOOK AT THE ERROR CODE
ANLY.4:	TLNE	J,JL.ULI	;USER LOGGED IN NOW
	  POPJ	P,		;YES, THAT'S INCONSISTENT
	TLO	G,GL.NJN	;SET NO MONITOR JOB NUMBERS
	PUSHJ	P,GETMST	;GET TIME WHEN NOTICED (MS.)
	MOVEM	T1,NJNTIM	;START THE TIMER RUNNING
	PUSHJ	P,TELQSR	;QUICK, SEND A STATUS CHANGE
	JRST	ANLY.3		;GO REQUEUE THIS JOB
ANLY.1:	HRRZ	T1,.JERCD(R)	;GET THE ERROR CODE FROM LOGIN
	CAIE	T1,4		;IS THE SYSTEM AVAILABLE
	  JRST	ANLY.5		;YES, LOOK FURTHUR
	TLNE	J,JL.ULI	;IS THE USER LOGGED IN NOW
	  POPJ	P,		;THAT TOO IS INCONSISTENT
	TLON	G,GL.SSH!GL.STC	;GIVE MESSAGE ONLY ONCE
	MSGTTY	[ASCIZ/Jobs cannot LOGIN. Stopping further scheduling/]
	JRST	ANLY.6		;GO REQUEUE THE JOB
ANLY.5:	CAIN	T1,5		;LOGMAX EXCEEDED
	  JRST	ANLY.4		;YES, TREAT AS "JOB CAPACITY EXCEEDED"
	CAIN	T1,2		;IS IT JOB SEMI-FATAL
	  JRST	ANLY.6		;YES, REQUEUE THE JOB
>  ;END OF IFN FTUUOS

	TLNE	J,JL.ULI	;ALL OTHERS KLUNK THE JOB, IS IT LOGGED IN NOW
	  JRST	CLOSJB		;YES, LEAVE JIE SET AND KILL THE JOB
	MSGLOG	[ASCIZ/BTNJBC Job has been cancelled/]
	PUSHJ	P,LGCLF2	;END THE LINE AND ADD A BLANK ONE
	PUSHJ	P,CLSLOG	;CLOSE OUT THE LOG FILE
	JRST	CLOS.1		;AND DISMISS THE JOB

ANLY.6:	MOVEI	A,REQTIM	;LOAD THE DEFAULT
ANLY.2:	MOVEM	A,.JAFTR(R)	;STORE FOR REQUEUE BLOCK
ANLY.3:	PUSHJ	P,LOGBLK	;GET A BLANK LINE ON THE LOG FILE
	PUSHJ	P,LGCMNT	;GET READY FOR A COMMENT
	TXTLOG	[ASCIZ/BTNJRQ Job requeued/]
	PUSHJ	P,LGCLF2	;END THE LINE AND ADD A BLANK ONE
	TLNN	J,JL.ULI	;IS THE JOB LOGGED IN NOW
	  PUSHJ	P,CLSLOG	;NO, CLOSE THE LOG FILE NOW
	JRST	REQUEU		;PERFORM THE REQUEUE
	SUBTTL	Job Processor - Random Little Routines

;SUBROUTINE TO GET JOB STATUS AND SET BITS AS NEEDED

GJBSTS:	HRRZ	J,.JPCHN(R)	;GET THE PTY CHANNEL NUMBER
	JOBSTS	J,		;GET THE STATUS
	  HALT	.		;;;BUG HALT
	MOVEM	J,.JSTAT(R)	;SAVE FOR BATOPR IF IT WANTS IT
	SKIPN	.JJOBN(R)	;IS THERE A JOB NUMBER STORED
	  HRRZM	J,.JJOBN(R)	;NO, SAVE THIS ONE FOR RELEASE OPERATION
	TLNE	J,JL.UJA	;USER JOB NUMBER ASSIGNED
	  TLO	R,RL.JNA	;YES, REMEMBER IT GOT AT LEAST THAT FAR
	POPJ	P,		;RETURN TO CALLER

;SUBROUTINE TO SEND 'SET TIME N' TO THE JOB

SETTIM:	TLZ	C,-1		;CLEAR LEFT HALF
	PUSH	P,C		;SAVE VALUE
	TLNE	R,RL.TIM	;NEED TO ALIGN THE OUTPUT
	  PUSHJ	P,PUTPER	;YES, OUTPUT A DOT (OR SOMETHING)
	TXTJOB	TIMSTR		;SEND THE SET TIME COMMAND
	POP	P,T1		;RESTORE NUMBER
	PUSHJ	P,SNDDEC	;SEND DECIMAL VALUE
	PUSHJ	P,SNDCLF	;SEND CR-LF AND FORCE BUFFER
	JRST	IOWAIT		;WAIT FOR NEXT INPUT BEFORE RETURNING

;SUBROUTINE TO REQUEUE A JOB (UPDATE ANYTHING BEFORE CALL)

REQUEU:	TLNE	J,JL.ULI	;IS THE JOB NOW LOGGED IN
	  PUSHJ	P,ATOKJB	;YES, AUTO KJOB THE JOB FIRST

	IFN	JOBMSG,<
	PUSHJ	P,TTYSJB	;TYPE OUT THE SUBJOB NUMBER
	OUTSTR	[ASCIZ/requeued/]
	PUSHJ	P,TTCRLF	;MENTION THAT THIS JOB IS GONE NOW
	>
	PUSHJ	P,REMCTL	;REMOVE ANY OLD CTL FILE ASSIGNMENTS
	PUSHJ	P,FUNREQ	;REQUEUE THIS JOB
	HRRZS	R		;CLEAR FLAGS
	PUSHJ	P,QTS		;GO DORMANT, WILL NOT RETURN HERE
;SUBROUTINE TO PLACE A JOB IN OPERATOR WAIT

OPRRES:	TLO	R,RL.OPR	;MARK WAITING FOR THE OPERATOR

	IFN	PROMPT,<
	MOVE	CH,CURMST	;GET TIME WHEN OPERATOR WAIT STARTED
	MOVEM	CH,.JWAIT(R)	;STORE FOR DISPATCH LOOP PROMPTING
	>
	PUSHJ	P,QTS		;WAIT FOR HIS(HER) RESPONSE
	JRST	GJBSTS		;GET THE STATUS AND RETURN

;SUBROUTINE TO COPY A COMMENT LINE TO THE LOG FILE

CPYCMT:	TLNE	F,FL.SIL	;IS THE OUTPUT TO BE SUPPRESED
	  JRST	CMNT.3		;YES, DONT OUTPUT COMMENT LINES EITHER
	CAIE	CH,CHR.FF	;SEE IF THE FIRST CHARACTER IS FF OR VT
	CAIN	CH,CHR.VT	;IF SO, THEN A ONE CHARACTER COMMENT LINE
	  JRST	[TLZ R,RL.TIM	;CLEAR TIME STAMP NEEDED
		JRST PUTLOG]	;OUTPUT FORM FEED OR VERTICAL TAB AND RETURN
CMNT.0:	PUSH	P,CH		;SAVE FIRST CHARACTER
	PUSHJ	P,LGCMNT	;PREPARE LOG FILE FOR A COMMENT
	POP	P,CH
CMNT.1:	TLNE	R,RL.TIM	;DID ONE OF THE CHARS MOVE THE PAPER
	  JRST	CMNT.0		;YES, START A FRESH COMMENT LINE
	PUSHJ	P,PUTLOG	;DEPOSIT INTO THE LOG FILE
	TLNN	F,FL.PLS	;DOING A PLEASE COMMAND
	  JRST	CMNT.2		;NO, AVOID THE FOLLOWING
	CAIE	CH,CHR.A1	;IS IT AN ALTMODE
	  JRST	CMNT.5		;NO, JUST OUTPUT THIS CHARACTER
	TLZ	F,FL.PLS	;YES, CLEAR PLEASE COMMAND
	MOVEI	CH,"$"		;ECHO THE ALTMODE AS A $
CMNT.5:	OUTCHR	CH		;OUTPUT THIS CHARACTER TO THE OPERATOR
CMNT.2:	CAIN	CH,CHR.LF	;END OF A LINE YET
	  POPJ	P,		;YES, RETURN TO READING OF CTL FILE
	PUSHJ	P,GETCTL	;GET ANOTHER CHARACTER
	JRST	CMNT.1		;CONTINUE COPYING
CMNT.3:	CAIE	CH,CHR.FF	;DOES THE LINE START WITH A FORM FEED
	CAIN	CH,CHR.VT	;OR A VERTICAL TAB
	  POPJ	P,		;YES, THAT IS A ONE CHARACTER COMMENT LINE
CMNT.4:	CAIN	CH,CHR.LF	;END OF THE COMMENT LINE YET
	  POPJ	P,		;YES, RETURN TO CALLER
	PUSHJ	P,GETCTL	;GET ANOTHER CHARACTER TO IGNORE
	JRST	CMNT.4		;ANY SEE IF DONE YET
;SUBROUTINE TO PUT A JOB INTO MONITOR MODE

INMONM:	TLNE	J,JL.UML	;IS IT ALREADY THERE
	  POPJ	P,		;YES, RETURN
INMO.1:	TLNN	J,JL.UDI	;NO, IS IT IN INPUT WAIT
	  PUSHJ	P,SNDUPC	;NO, SEND 2 CONTROL C'S
	PUSHJ	P,SNDUPC
	PUSHJ	P,IOWAIT	;WAIT FOR RESPONSE
	TLNE	J,JL.UML	;IS IT NOW AT MONITOR LEVEL
	  POPJ	P,		;YES, RETURN
	PUSHJ	P,TTCRLF	;TELL THE OPERATOR
	PUSHJ	P,TTYALL	;THAT WE COULDN'T DO IT
	MSGTTY	[ASCIZ/Job cannot be put in monitor mode.
OPR--Type /]
	MOVEI	T1,[ASCIZ /GO to try again (or after you have killed the job)
Waiting.../]
	PUSHJ	P,SJBLIN	;AND TYPE IT
	PUSHJ	P,OPRRES	;WAIT FOR OPERATOR RESPONSE
	TLNN	J,JL.ULI	;IS THE JOB STILL THERE
	  JRST	CLOS.1		;NO, DISMISS THE JOB
	JRST	INMONM		;YES, TRY TO DO IT AGAIN

;SUBROUTINES TO INFORM QUASAR OF CHECKPOINT OR REQUEUE

FUNCHK:	MOVX	B,<INSVL.(CHE.SZ,MS.CNT)!INSVL.(.QOCHE,MS.TYP)>
	SKIPA			;SKIP OVER REQUEUE
FUNREQ:	MOVX	B,<INSVL.(REQ.SZ,MS.CNT)!INSVL.(.QOREQ,MS.TYP)>
	MOVEI	A,QSRMSG	;THE MESSAGE
	MOVEM	B,.MSTYP(A)	;STORE THE TYPE AND LENGTH
	MOVE	B,Q.ITN(R)	;THE TASK NAME
	MOVEM	B,REQ.IT(A)	;STORE
	HRLI	B,.JINFO(R)	;CHECKPOINT/REQUEUE INFORMATION
	HRRI	B,REQ.IN(A)	;INTO THE MESSAGE
	BLT	B,REQ.IN+<EQCKSZ-1>(A)  ;MOVE ALL THE WORDS
	MOVE	B,.JAFTR(R)	;GET AFTER PARAMETER IF THIS IS REQUEUE
	MOVEM	B,REQ.AF(A)	;WILL NOT SEND IT IF THIS IS CHECKPOINT
	JRST	SNDQSR##	;TELL QUASAR

;SUBROUTINE TO SKIP BLANKS(TABS) IN THE CTL FILE

SKPBL1:	PUSHJ	P,GETCTL	;ENTER HERE IF CH IS NOT SET AT THE FIRST
SKPBLK:	CAIE	CH," "		;A BLANK
	CAIN	CH,CHR.HT	;OR A TAB
	  JRST	SKPBL1		;SKIP OVER THEM
	POPJ	P,		;RETURN WITH THE FIRST NON-BLANK CHARACTER
	SUBTTL	Channel Allocation Routines

;ROUTINES TO GET CHANNEL ASSIGNMENT FOR LOG,CTL, OR PTY
;CALLED BY: PUSHJ P,CHN??? (WHERE ??? IS LOG,CTL,OR PTY
;RETURNS +1 IF CHANNEL ASSIGNMENT IS NEW
;	 +2 IF CHANNEL ASSIGNMENT IS OLD (PERMANENT)
;IN EITHER CASE AC 'IO1' HAS CHANNEL NUMBER IN AC FIELD
;IF GL.UC0 IS SET AT THE CALL, THE PRIORITY USURPER IS DISABLED

	USELOG==1B35	;BIT INDICATING LOG FILE USAGE
	USECTL==1B34	;BIT FOR CTL FILE
	USEPTY==1B33	;BIT FOR PTY (PERMANENT ASSIGNMENT)

IFN FTUUOS,<
CHNLOG:	HRRI	IO2,USELOG	;ENTRY FOR LOG FILE
	JRST	CHNGET
CHNCTL:	HRRI	IO2,USECTL	;ENTRY FOR CTL FILE
	JRST	CHNGET
>  ;END OF IFN FTUUOS
CHNPTY:	HRRI	IO2,USEPTY	;ENTRY FOR PTY
CHNGET:	HRL	IO2,S		;INCLUDE STREAM NUMBER
	SETZM	CHNMAY		;CLEAR SOME WORDS
	SETZM	CHNFRE
	MOVSI	IO1,-20		;NUMBER OF CHANNELS AVAILABLE
CHNG.1:	CAMN	IO2,CHNTBL(IO1)	;LOOK FOR OLD ASSIGNMENT
	  JRST	[ANDI IO1,17	;FOUND ONE, ISOLATE CHANNEL NUMBER
		LSH IO1,^D23	;POSITION IN AC FIELD
		TLZ G,GL.UC0	;CLEAR A FLAG
		JRST CPOPJ1]	;GIVE OLD FILE RETURN
	SKIPN	D,CHNTBL(IO1)	;GET TABLE ENTRY
	  HRRM	IO1,CHNFRE	;FOUND A FREE CHANNEL
	JUMPLE	D,CHNG.2	;IF FREE OR RESERVED SKIP OTHER TESTS
	TRNN	D,USEPTY	;USED BY SOME PTY
	  HRLM	IO1,CHNFRE	;NO, REMEMBER NON-PTY CHANNEL
	TRNE	D,USECTL	;USED BY SOME CTL FILE
	  HRRM	IO1,CHNMAY	;YES, MAY BE FREE FOR PTY'S OR LOG
CHNG.2:	AOBJN	IO1,CHNG.1	;LOOK AT ALL CHANNELS
	TLZN	G,GL.UC0	;DOES CALLER WANT CHANNEL 0 INSTEAD
	  JRST	CHNG.7		;NO, GO TAKE A FREE ONE FROM SOMBODY (MAYBE)
	SETZ	IO1,		;RETURN CHANNEL 0
	POPJ	P,		;RETURN AS NEW ASSIGNMENT

IFN FTJSYS,<
CHNCTL:	TLO	R,RL.UST	;ALWAYS FORCE POSITIONING
	SKIPE	.JCJFN(R)	;DOES THE CTL FILE JFN EXIST
	  AOS	(P)		;YES, GIVE OLD ASSIGNMENT RETURN
	JRST	CHNXIT		;CLEAR SOME THINGS AND RETURN
CHNLOG:	SKIPE	.JLJFN(R)	;LOG FILE JFN EXIST
	  AOS	(P)		;YES, GIVE OLD ASSIGNMENT RETURN
CHNXIT:	TLZ	G,GL.UC0	;CLEAR USURPER BIT
	SETZ	IO1,		;NEVER RETURN A CHANNEL NUMBER
	POPJ	P,		;RETURN TO CALLER
>  ;END OF IFN FTJSYS
;HERE WHEN NO CURRENT ASSIGNMENT EXISTS. ALLOCATE A FREE ONE

CHNG.7:	HRRZ	IO1,CHNFRE	;ENCOUNTER ANY FREE CHANNELS
	JUMPE	IO1,CHNG.3	;NO, ONLY FREE WAS 0 (GUARANTEED)
	MOVEM	IO2,CHNTBL(IO1)	;TAKE THE FREE CHANNEL
	LSH	IO1,^D23	;POSITION CHANNEL NUMBER
	POPJ	P,		;GIVE NEW FILE RETURN

;HERE WHEN NO FREE CHANNELS WERE FOUND (EXCEPT CHANNEL 0)

CHNG.3:	TRNE	IO2,USECTL	;ARE WE LOOKING FOR A CTL FILE
	  POPJ	P,		;YES, USE TEMPORARY CHANNEL
	HRRZ	IO1,CHNMAY	;GET CHANNEL FOR OTHER CTL FILES
	JUMPN	IO1,CHNG.5	;TAKE IT AWAY FROM THE OTHER STREAM
	TRNE	IO2,USELOG	;WANT IT FOR THE LOG FILE
	  POPJ	P,		;YES, ONLY FREE IS CHANNEL 0
	HLRZ	IO1,CHNFRE	;GET NON-PTY CHANNEL
	JUMPE	IO1,CPOPJ	;IMPOSSIBLE (MEANS MJOB.GT.^D14)
CHNG.5:	MOVEM	IO2,CHNTBL(IO1)	;TAKE THE CHANNEL AWAY
	LSH	IO1,^D23	;POSITION CHANNEL NUMBER
RELCHN:	PUSHJ	P,CHANIO	;MUST CLOSE OLD FILE
	  CLOSE	0,0		;CHANIO EXECUTES THIS
	PUSHJ	P,CHANIO
	  RELEASE 0,0		;GIVE THE OLD ASSIGNMENT BACK
	POPJ	P,		;RETURN WITH NEW CHANNEL FOR THIS STREAM

;HERE TO RELEASE THE A CHANNEL AND ASSIGNMENT

RELREL:	PUSHJ	P,CHANIO	;GIVE BACK TYPE CHANNEL
	  RELEASE 0,0
RELASS:	LSH	IO1,-^D23	;POSITION CHANNEL AS INDEX
	SETZM	CHNTBL(IO1)	;RETURN ASSIGNMENT
	POPJ	P,		;RETURN TO DISPATCHER
	SUBTTL	I/O Handling Routines - Simulation and Specification Blocks

;ROUTINE TO EXECUTE I/O SELECT FOR A CHANNEL (IN AC 'IO1')
;CALLED BY: PUSHJ P,CHANIO
;		  IO SELECT INSTRUCTION
;RETURNS +2 IF NON-SKIP RETURN FROM I/O SELECT
;	 +3 IF SKIP RETURN

CHANIO:	JUMPE	IO1,CPOPJ	;IF CHANNEL IS ZERO, DO INLINE INST.
	MOVE	IO2,@(P)	;FETCH INSTRUCTION TO BE EXECUTED
	IOR	IO2,IO1		;INSERT CHANNEL NUMBER
	AOS	(P)		;MUST SKIP IN LINE INST.
	XCT	IO2		;DO THE SELECT
	  POPJ	P,		;GIVE NON-SKIP RETURN
	AOS	(P)		;SKIP RETURN
	POPJ	P,		;RETURN TO CALLER

;SUBROUTINES TO GET THE LOG/CTL FILE SPECIFICATIONS INTO THE 4 WORD
;	LOOKUP/ENTER FORMAT.  4 WORD BLOCK IS IN AC'S A-D

IFN FTUUOS,<

;ROUTINE TO SET 4 WORD LOOKUP BLOCK FOR CTL FILE

CTLSPC:	SETZ	C,
	MOVE	A,Q.CNAM(R)	;REAL FILE NAME
	HLLZ	B,Q.CEXT(R)	;AND EXTENSION
	MOVEI	D,Q.CDIR(R)	;POINT TO THE PATH SPECIFICATION
	JRST	SETSFD		;SET UP SFD POINTER OR PPN IF NONE

;ROUTINE TO GET 4 WORD LOOKUP BLOCK FOR THE LOG FILE

LOGSPC:	MOVE	A,Q.LNAM(R)	;FILE NAME
	HLLZ	B,Q.LEXT(R)	;EXTENSION
	SETZ	C,
	MOVEI	D,Q.LDIR(R)	;POINT TO THE LOG FILE SFD SPECIFICATION
SETSFD:	SKIPN	1(D)		;IS THERE ANY SFD SPECIFIED
	  JRST	[MOVE D,(D)	;NO, SET D TO THE PPN
		TLNN D,-1	;IS PPN = XWD 0,#
		 HRLOI D,377777	;YES, SOMEBODY MADE A BAD QUE FILE
		POPJ P,]	;AND RETURN
	HRLI	D,(D)		;SOURCE OF THE PATH
	HRRI	D,SFDPAT+2	;TO THE PATH BLOCK
	BLT	D,SFDPAT+7	;MOVE THE WHOLE SPEC
	MOVEI	D,SFDPAT	;POINT TO IT FOR THE UUOS
	POPJ	P,		;AND RETURN
>  ;END OF IFN FTUUOS

IFN FTJSYS,<
CTLSPC:
LOGSPC:	POPJ	P,		;THESE ROUTINES ARE NOT NEEDED
>  ;END OF IFN FTJSYS
	SUBTTL	I/O Handling Routines - The Control File

;SUBROUTINE TO GET A CHARACTER FROM THE CTL FILE

GETCTL:	SOSGE	.JCCNT(R)	;ANY IN THIS BUFFER
	  JRST	GETCT1		;NO, RE-FILL IT
	ILDB	CH,.JCPTR(R)	;GET NEXT
	JUMPE	CH,GETCTL	;IGNORE NULLS
	MOVE	A,@.JCPTR(R)	;GET THE DATA WORD
	TRNN	A,1		;IS THIS A LINE NUMBERED FILE
	  JRST	GETCT4		;NO, LOOK FOR UPARROWS
	AOS	.JCPTR(R)	;BUMP TO NEXT DATA WORD
	MOVNI	A,5		;ADJUST COUNT FOR THE NEXT 5 CHARS TO BE
	ADDB	A,.JCCNT(R)	;THROWN AWAY, CHECK IF CROSSED A BLOCK BOUNDRY
	JUMPGE	A,GETCTL	;MORE LEFT, GET ONE AND RETURN
	TLO	F,FL.UPA	;GET EXACTLY ONE CHARACTER FOR THE REFILL
	PUSHJ	P,GETCTL	;BUFFER IS EMPTY, REFILL IT
	JRST	GETCTL		;AND THROW AWAY ANOTHER CHAR TO KEEP COUNT RIGHT

GETCT1:	IFN FTUUOS,<IFG	<CTLBFR-1>,<
	SKIPGE	.JCUSI(R)	;END OF FILE HIT YET
	  JRST	CLOSJB		;YES, TIME TO CLOSE OUT THIS JOB
	SETZM	.JCTLB(R)	;BEGIN TO CLEAR BUFFERS
	HRLI	A,.JCTLB(R)	;SET UP BLT
	HRRI	A,.JCTLB+1(R)
	BLT	A,.JCTLB+<DSKBLK*CTLBFR>-1(R)
	>>
	TRZE	F,FR.FSI	;FORCE A USETI?
	  TLOA	R,RL.UST	;SET IT IS NEEDED
	TLZ	R,RL.UST	;CLEAR FLAG
	PUSHJ	P,CHNCTL	;CONNENT TO CTL CHANNEL
	  PUSHJ	P,FNDCTL	;NEW CHANNEL ASSIGNMENT, FIND THE FILE
	SKIPN	A,.JCUSI(R)	;GOT A COUNT
	  HRREI	A,<1-CTLBFR>	;SET UP FOR FIRST INPUT
	ADDI	A,CTLBFR	;FIRST BLOCK TO READ THIS TIME
	MOVEM	A,.JCUSI(R)	;SAVE
	TLNE	R,RL.UST	;NEED THE USETI
	  PUSHJ	P,POSCTL	;YES, POSITION THE FILE
	MOVE	A,[POINT 7,.JCTLB(R)]
	MOVEM	A,.JCPTR(R)	;SET NEW BYTE POINTER
	MOVEI	A,CTLCHR	;AND COUNT
	MOVEM	A,.JCCNT(R)
IFN FTJSYS,<JRST GETCTL>	;RESUME READING
IFN FTUUOS,<
	HRLI	A,-<DSKBLK*CTLBFR>
	HRRI	A,.JCTLB-1(R)	;BUILD IOWD FOR INPUT
	SETZ	B,
	PUSHJ	P,CHANIO	;READ THE FILE
	  IN	0,A
	  SKIPA			;NORMAL RETURN
	  JRST	GETCT3		;SOME SORT OF I/O ERROR
	JUMPN	IO1,GETCTL	;IF NOT CHANNEL 0, RESUME READING
	PUSHJ	P,RELCHN	;RELEASE CHANNEL 0
	JRST	GETCTL		;RESUME

;HERE IF IN UUO GAVE AN ERROR RETURN

GETCT3:	PUSHJ	P,CHANIO	;FIND THE ERROR TYPE
	  GETSTS 0,A
	TRNE	A,740000	;ANY ERROR BITS ON
	  JRST	CTLIOE		;YES, REPORT ERROR

	IFG	<CTLBFR-1>,<
	SETOM	.JCUSI(R)	;MARK END OF FILE
	JRST	GETCTL		;RESUME FROM THE BUFFER
	>
	IFE	<CTLBFR-1>,<
	JRST	CLOSJB		;FINISH THE JOB NOW
	>
>  ;END OF IFN FTUUOS

;HERE TO CONVERT UPARROWS TO CONTROL CHARACTERS (MAYBE)

GETCT4:	TLZN	F,FL.UPA	;HERE THE SECOND TIME FOR THIS CALL
	CAIE	CH,"^"		;NO, IS THIS AN UPARROW
	  POPJ	P,		;RETURN WITH THIS CHARACTER
	TLO	F,FL.UPA	;MARK RECURSIVE CALL
	PUSHJ	P,GETCTL	;GET THE NEXT AFTER THE UPARROW
	CAIN	CH,"^"		;TWO IN A ROW
	  POPJ	P,		;YES, RETURN ONLY ONE
	CAIG	CH,172		;CONVERT TO UPPER CASE
	CAIGE	CH,141
	  SKIPA			;NOT A LOWER CASE LETTER
	SUBI	CH," "		;MAKE UPPER CASE OUT OF IT
	CAIG	CH,137		;NOW SEE IF THIS CHAR CAN BE A CONTROL CHAR
	CAIGE	CH,"A"
	  JRST	GETCT5		;NO, MUST BACK SOME STUFF UP
	SUBI	CH,100		;MAKE A CONTROL CHARACTER
	POPJ	P,		;RETURN WITH IT
GETCT5:	PUSHJ	P,DECRBP	;BACK UP OVER THE OTHER CHARACTER
	MOVEI	CH,"^"		;GET THE ORIGINAL UPARROW
	POPJ	P,		;AND RETURN WITH IT
;SUBROUTINE TO POSITION THE CTL FILE TO THE CONTENTS OF .JCUSI
;CALLED WITH IO1 CONTAINING THE CTL FILE CHANNEL (FOR CHANIO)

IFN FTUUOS,<
POSCTL:	PUSHJ	P,CHANIO	;EXECUTE THE FOLLOWING
	  USETI	0,@.JCUSI(R)	;POSITION THE FILE
	POPJ	P,		;AND RETURN
>  ;END OF IFN FTUUOS

IFN FTJSYS,<
POSCTL:	DMOVEM	T1,C		;SAVE T1 AND T2 IN C AND D
	MOVE	T1,.JCUSI(R)	;GET THE BLOCK NUMBER
	SOS	T1		;FOR MOD 4 ARITHMETIC
	IDIVI	T1,CTLBFR	;CONVERT TO FILE PAGE NUMBER
	CAML	T1,.JCPSZ(R)	;OFF THE END OF THE FILE
	  JRST	CLOSJB		;YES, END OF THE JOB
	HRL	T1,.JCJFN(R)	;RH = PAGE NUMBER, LH = JFN
	MOVEI	T2,.JCTLB(R)	;BUFFERS
	LSH	T2,-^D9		;CONVERT TO PAGE NUMBER
	HRLI	T2,.FHSLF	;THIS FORK
	MOVX	A,PM%RD		;A = T2 + 1, READ ACCESS
	PMAP			;MAP THE PAGE
	DMOVE	T1,C		;RESTORE T1 AND T2
	POPJ	P,		;AND RETURN
>  ;END OF IFN FTJSYS
;SUBROUTINE TO PERFORM POST JOB DISPOSAL OF THE CTL FILE

CTLDIS:	TLNE	F,FL.ACC	;HAVE WE EVER CHECKED THE ACCESS RIGHTS
	  JRST	CTLD.0		;NO, LETS DO IT NOW
	TLNN	R,RL.DCT	;USER HAVE PRIVS TO DELETE THE FILE
	  POPJ	P,		;NO, DONT EVEN TRY TO DO ANYTHING
CTLD.0:	LOAD	T1,Q.CMOD(R),FP.DEL  ;CHECK DELETE BIT
	JUMPE	T1,CPOPJ	;DON'T BOTHER IF NOT DELETE
	TLO	G,GL.UC0	;USE CHANNEL 0 IF NONE ASSIGNED
	PUSHJ	P,CHNCTL	;SEE IF ASSIGNMENT EXISTS
	  PUSHJ	P,FNDCTL	;USE EITHER 0 OR OLD CHANNEL ASSIGNMENT
	TLZN	R,RL.DCT	;IN CASE THIS CALL DID THE CHKACC
	  JRST	RELREL		;NO PRIVS, GET OUT NOW
IFN FTUUOS,<
	SETZB	A,B		;CLEAR THE NAME
	SETZB	C,D		;REALLY DELETE IT
	PUSHJ	P,CHANIO	;EXECUTE THE IO SELECT
	  RENAME 0,A		;DELETE THE FILE
	  JFCL			;NICE TRY
	JRST	RELREL		;RELEASE CHANNEL AND ASSIGNMENT AND RETURN
>  ;END OF IFN FTUUOS
IFN FTJSYS,<
	PUSH	P,.JCJFN(R)	;SAVE THE JFN
	MOVX	T1,DF%NRJ	;"DON'T RELEASE JFN" BIT
	IORM	T1,.JCJFN(R)	;FOR CLOSE
	PUSHJ	P,REMCTL	;REMOVE THE CONTROL FILE
	POP	P,T1		;GET THE ORIGINAL JFN IN T1
	TXO	T1,DF%EXP	;REALLY DELETE IT
	DELF			;DELETE THE FILE
	  JFCL			;IGNORE FAILURES
	POPJ	P,		;AND RETURN
>  ;END OF IFN FTJSYS
;HERE TO REMOVE ANY OLD CTL FILE ASSIGNMENTS AT DISMISSAL OF THE JOB

IFN FTUUOS,<
REMCTL:	TLO	G,GL.UC0	;WANT CHANNEL 0 IF NONE
	PUSHJ	P,CHNCTL	;GET A CTL FILE ASSIGNMENT
	  POPJ	P,		;WAS NONE, RETURN
	JRST	RELREL		;RETURN THE CHANNEL AND ASSIGNMENT, THE RETURN
>  ;END OF IFN FTUUOS

IFN FTJSYS,<
REMCTL:	SKIPE	T1,.JLJFN(R)	;GET ANY LOG FILE JFN HANGING AROUND
	 CLOSF			;CLOSE IT IF THERE IS ONE
	  JFCL			;IGNORE FAILURES
	MOVE	T1,.JCJFN(R)	;GET THE FILE JFN
	JUMPE	T1,CPOPJ	;RETURN IF NONE THERE
	SETO	T1,		;INDICATE PMAPing THE PAGE AWAY
	MOVEI	T2,.JCTLB(R)	;THE PAGE FOR THE CTL BUFFERS
	LSH	T2,-^D9		;CONVERT TO A PAGE NUMBER
	HRLI	T2,.FHSLF	;FROM MY ADDRESSING SPACE
	SETZ	A,		;A = T2 + 1, NO FLAGS
	PMAP			;GOOD-BYE PAGE
	MOVE	T1,.JCJFN(R)	;GET THE JFN AGAIN
	CLOSF			;CLOSE THE FILE
	  JFCL			;IGNORE THE ERROR
	SETZM	.JCJFN(R)	;CLEAR THE JFN
	POPJ	P,		;AND RETURN
>  ;END OF IFN FTJSYS
;ROUTINES TO SAVE THE CURRENT CTL FILE POSITION OR REPOSITION IT
;BOTH ARE CALLED BY JSP T1,ROUTINE
;	0(P) = .JCUSI(R)
;	1(P) = .JCPTR(R)
;	2(P) = .JCCNT(R)

SAVPOS:	SKIPN	.JCUSI(R)	;HAS THE FILE BEEN STARTED YET
	  JRST	[PUSH P,T1	;SAVE RETURN
		TLO F,FL.UPA	;GET EXACTLY ONE CHARACTER
		PUSHJ P,GETCTL	;GET THE FIRST CHARACTER (FILL THE BUFFERS)
		PUSHJ P,DECRBP	;BACK UP THE POINTERS BEFORE SAVING THEM
		POP P,T1	;RESTORE RETURN
		JRST .+1]	;AND RETURN TO INLINE CODE
	PUSH	P,.JCCNT(R)	;SAVE THE COUNT
	PUSH	P,.JCPTR(R)	;AND THE BYTE POINTER
	PUSH	P,.JCUSI(R)	;AND THE USETI WORD
	JRST	(T1)		;RETURN

REPOSI:	POP	P,CH		;RESTORE .JCUSI(R)
	CAMN	CH,.JCUSI(R)	;IS THE BLOCK WE WANT IN CORE
	  JRST	REPO.1		;YES, JUST RESTORE
	SUBI	CH,CTLBFR	;ADJUST FOR ADD TO BE DONE BY GETCTL
	JUMPGE	CH,.+2		;BACK UP TOO FAR
	  SETZ	CH,		;YES, GET A ZERO
	MOVEM	CH,.JCUSI(R)	;STORE
	TRO	F,FR.FSI	;FORCE A USETI TO BE DONE
	PUSHJ	P,GETCT1	;GET A RANDOM CHARACTER BUT REFILL WITH PROPER BUFFER
REPO.1:	POP	P,.JCPTR(R)	;RESTORE THE BYTE POINTER
	POP	P,.JCCNT(R)	;AND THE COUNT
	JRST	(T1)		;RETURN

;ROUTINE TO BACK UP THE CTL FILE POINTERS TO GET THE LAST CHARACTER OVER AGAIN
;ONLY BACKS UP THE POSITION FIELD OF THE BYTE POINTER AND CANNOT REALLY 
;GO BACK OVER MORE THAN 1 CHARACTER

DECRBP:	AOS	.JCCNT(R)	;ADJUST THE COUNT
	LDB	CH,[POINT 6,.JCPTR(R),5] ;GET THE REMAINING BITS
	MOVEI	CH,7(CH)	;ADJUST FOR THE CHARACTER
	DPB	CH,[POINT 6,.JCPTR(R),5] ;STORE NEW POSITION
	POPJ	P,
;ROUTINE TO OPEN CHANNEL AND LOOKUP CTL FILE

IFN FTUUOS,<
FNDCTL:	MOVE	A,[400000,,17]	;PHYSICAL ONLY,,DUMP MODE
	MOVE	B,Q.CSTR(R)	;STRUCTURE FOR CTL FILE
	SETZ	C,		;NO BUFFERS FOR DUMP MODE
	PUSHJ	P,CHANIO
	  OPEN	0,A		;OPEN THE CORRECT CHANNEL
	  JRST	CTLOER		;CTL FILE OPEN ERROR
	PUSHJ	P,CTLSPC	;GET THE 4 WORD LOOKUP BLOCK
	PUSHJ	P,CHANIO	;LOOKUP ON CORRECT CHANNEL
	  LOOKUP 0,A
	  JRST	CTLLKE		;CTL FILE LOOKUP ERROR
	SKIPE	.JCUSI(R)	;FIRST CALL FOR NEW LOOKUP
	  TLO	R,RL.UST	;NO, MARK USETI NEEDED
	TLZN	F,FL.ACC	;NEED TO CHECK READ ACCESS
	  POPJ	P,		;NO, RETURN FOR NORMAL READING

;HERE TO CHECK USERS READ PRIVLEGES. ALSO NOTE WHETHER PRIVLEGES TO DELETE
;THE CTL FILE EXIST. FILE IS ALREADY LOOKED UP AND AC'S A-D ARE THE RETURNED ACS

	LOAD	B,Q.SEQ(R),EQ.PRV ;GET PRIVS OF CREATOR AT CREATION OF REQUEST
	JUMPN	B,CTLP.1	;IF WHEELED, OPERATOR, ALLOW EVERYTHING
	LDB	B,[POINT 9,C,8]	;GET THE FILE PROTECTION
	MOVE	C,Q.CDIR(R)	;OWNER OF THE FILE
	MOVE	D,Q.PPN(R)	;REQUESTOR
	CAMN	C,D		;ARE THEY THE SAME PPN
	  JRST	CTLP.1		;YES, DON'T NEED THE CHKACC
	HRLI	B,.ACRED	;CHECK FOR READ ACCESS
	MOVEI	A,B		;POINT TO THE ARGUMENT BLOCK
	CHKACC	A,		;ASK THE FILE SYSTEM
	  POPJ	P,		;IF NO CHKACC, ASSUME READ BUT NO DELETE
	JUMPL	A,[MOVEI B,2	;NO READ ACCESS, FUDGE ERROR CODE 2
		JRST CTLLKE]	;PRETEND IT WAS A LOOKUP ERROR
	MOVEI	A,B		;RESET ARGUMENT POINTER
	HRLI	B,.ACREN	;SEE IF CAN DELETE AT END OF JOB
	CHKACC	A,		;ASK THE FILE SYSTEM AGAIN
	  POPJ	P,		;ASSUME NO
	JUMPL	A,CPOPJ		;REALLY NO
CTLP.1:	TLO	R,RL.DCT	;NOTE DELETE PRIVS
	POPJ	P,		;RETURN TO READING LOOP
>  ;END OF IFN FTUUOS

;;;THE TOPS20 VERSION OF THIS ROUTINE IS ON THE NEXT PAGE
IFN FTJSYS,<
FNDCTL:	DMOVEM	T1,C			;SAVE T1 & T2 IN C & D
	MOVX	T1,<GJ%OLD!GJ%SHT>	;SHORT CALL, OLD FILE ONLY
	HRROI	T2,Q.CSTR(R)		;FILE DESCRIPTOR
	GTJFN				;GET THE FILE
	  JRST	FNDC.E			;ERROR GETTING THE FILE
	MOVEM	T1,.JCJFN(R)		;SAVE THE JFN ACQUIRED
	TLZN	F,FL.ACC		;NEED TO CHECK READ ACCESS
	  JRST	CTLP.2			;NO, AVOID THE ACCESS CHECKS
	LOAD	B,Q.SEQ(R),EQ.PRV	;GET CALLERS PRIVS AT CREATE TIME
	JUMPN	B,CTLP.1		;IF WHEELED, OPERATOR, ALLOW ANYTHING
	MOVEM	T1,TEMP3+.CKAUD		;STORE JFN
	MOVX	T1,.CKARD		;ACCESS TYPE READ
	MOVEM	T1,TEMP3+.CKAAC		;AS ACCESS WANTED
	HRROI	T1,Q.USNM(R)		;POINT TO USER ID
	MOVEM	T1,TEMP3+.CKALD		;SAVE AS LOGGED-IN USER
	HRROI	T1,Q.CNDI(R)		;POINT TO CONNECTED DIRECTORY
	MOVEM	T1,TEMP3+.CKACD		;SAVE IT
	SETZM	TEMP3+.CKAEC		;NO ENABLE CAPABILITIES
	MOVX	T1,<CK%JFN+.CKAUD+1>	;FLAGS,,ARG-LENGTH
	MOVEI	T2,TEMP3		;WHERE THE ARGS ARE
	CHKAC				;CHECK FOR READ ACCESS BY THIS USER
	  JRST	FNDC.E			;OH WELL!!
	JUMPE	T1,FNDC.N		;JUMP IF NO ACCESS ALLOWED
	MOVX	T1,.CKAWT		;ACCESS WRITE (USE FOR DELETE)
	MOVEM	T1,TEMP3+.CKAAC		;AS REQUESTED ACCESS
	MOVX	T1,<CK%JFN+.CKAUD+1>	;GIVEN A JFN,,NUMBER OF WORDS
	MOVEI	T2,TEMP3		;WHERE THE ARGS ARE
	CHKAC				;CHECK FOR RIGHTS TO DELETE THE FILE
	  SETZ	T1,			;PRETEND NO
	JUMPE	T1,CTLP.2		;JUMP IF CANNOT DELETE THE FILE
CTLP.1:	TLO	R,RL.DCT		;MAY DELETE THE FILE IF REQUESTED
CTLP.2:	MOVE	T1,.JCJFN(R)		;GET THE JFN FOR THE CONTROL FILE
	MOVX	T2,<OF%RD+^D36B5>	;READ A 36 BIT BYTE FILE
	OPENF				;OPEN THE FILE
	  JRST	FNDC.E			;ERROR OPENING THE FILE
	MOVE	T1,.JCJFN(R)		;THE JFN AGAIN
	MOVX	T2,<1,,.FBBYV>		;WANT THE FILE SIZE
	MOVEI	A,B			;A = T2 + 1, GET DATA INTO B
	GTFDB				;GET THE FILE SIZE
	HRRZM	B,.JCPSZ(R)		;SAVE FILE SIZE FOR POSCTL
	DMOVE	T1,C			;RESTORE T1 AND T2
	POPJ	P,			;AND RETURN FOR NORMAL READING

FNDC.N:	MOVEI	T1,OPNX4		;ERROR FOR NO READ ACCESS
FNDC.E:	HRRZ	B,T1			;COPY GTJFN/OPENF ERROR CODE
	JRST	CTLLKE			;SIMULATE A LOOKUP ERROR
>  ;END OF IFN FTJSYS
;HERE TO PROCESS LOOKUP ERRORS ON THE CTL FILE

CTLLKE:	TLNE	R,RL.KJB	;HERE AFTER KJOB SENT
	  JRST	CLOSJB		;YES, GO KILL THE JOB
	HRRZS	B		;ISOLATE THE LOOKUP ERROR CODE
	PUSH	P,B		;SAVE IT FOR NOW
	MSGLOG	[ASCIZ/BTNCFC Cannot find the CTL file. Error code = /]
CTLI.1:	POP	P,T1		;RESTORE STATUS
	PUSHJ	P,LOGOCT	;OUTPUT THAT AS OCTAL
CTLABJ:	MOVEI	T1,[ASCIZ/BTNJBC Job has been cancelled/]
	PUSHJ	P,LGMSG1	;ADDITIONAL COMMENT
	PUSHJ	P,LGCLF2	;END THE LINE ADD A BLANK ONE
	PUSHJ	P,REMCTL	;REMOVE ANY OLD CTL FILE ASSIGNMENTS
	JRST	CLOSJB		;AUTO KJOB THE JOB

IFN FTUUOS,<

;HERE TO REPORT I/O ERROR WHILE READING THE CTL FILE
;GETSTS CHN,A WAS DONE PRIOR TO CALL

CTLIOE:	TLNE	R,RL.KJB	;HERE AFTER KJOB SENT
	  JRST	CLOSJB		;YES, GO KILL THE JOB
	PUSH	P,A		;SAVE IT FOR NOW
	MSGLOG	[ASCIZ/BTNEWR Error while reading the CTL file. Status = /]
	JRST	CTLI.1		;OUTPUT ERROR CODE (0(P)) AND CANCEL THE JOB

;HERE TO PROCESS OPEN ERRORS OR ILLEGAL STRUCTURES FOR THE CTL FILE

CTLOER:	MOVEI	T1,[ASCIZ/BTNCOD Cannot OPEN device /]
	TLNE	R,RL.KJB	;HERE AFTER KJOB SENT
	  JRST	CLOSJB		;YES, GO KILL THE JOB
	PUSHJ	P,LGEMSG	;OUTPUT THE ERROR
	SIXLOG	Q.CSTR(R)	;INCLUDE STRUCTURE THAT WOULDN'T OPEN
	PUSHJ	P,PUTCOL	;ADD A COLON
	JRST	CTLABJ		;AND CANCEL THIS JOB

>  ;END OF IFN FTUUOS
	SUBTTL	I/O Handling Routines - The LOG File

;ROUTINE TO OPEN CHANNEL AND GET LOG FILE IN UPDATE MODE

IFN FTUUOS,<

FNDLOG:	MOVE	A,IO1			;GET IO CHANNEL
	LSH	A,-5			;RIGHT JUSTIFIED IN LH
	IOR	A,[FO.PRV+.FOAPP]	;APPEND AND USE PRIVS
	MOVEM	A,.JLFLB+.FOFNC(R)	;STORE FUNCTION WORD
	MOVX	A,<UU.PHS+.IODMP>	;DUMP MODE AND PHYS ONLY
	MOVEM	A,.JLFLB+.FOIOS(R)	;STORE IT
	MOVE	A,Q.LSTR(R)		;GET STRUCTURE NAME
	MOVEM	A,.JLFLB+.FODEV(R)	;SAVE IT
	SETZM	.JLFLB+.FOBRH(R)	;NO BUFFER RING HEADERS
	SETZM	.JLFLB+.FONBF(R)	;NO BUFFERS
	MOVE	A,Q.PPN(R)		;GET THE PPN
	MOVEM	A,.JLFLB+.FOPPN(R)	;MAKE THE UUO IN HIS BEHALF
	MOVEI	A,.JLLEB(R)		;LOAD ADDRESS OF LOOKUP BLOCK
	MOVS	B,A			;GET ADR,,0
	HRRI	B,1(A)			;GET ADR,,ADR+1
	SETZM	0(A)			;CLEAR THE FIRST WORD
	BLT	B,.RBSIZ(A)		;CLEAR THE REST
	MOVEI	B,.RBSIZ		;GET BLOCK LENGTH
	MOVEM	B,.RBCNT(A)		;STORE IT
	MOVE	B,Q.LNAM(R)		;GET FILENAME
	MOVEM	B,.RBNAM(A)		;SAVE IT
	HLLZ	B,Q.LEXT(R)		;GET EXTENSION
	MOVEM	B,.RBEXT(A)		;STORE IT AWAY
	MOVEI	D,Q.LDIR(R)		;GET ADDRESS OF PATH
	PUSHJ	P,SETSFD		;SETUP THE SFD
	MOVEM	D,.RBPPN(A)		;AND STORE RIBPPN
	MOVEM	A,.JLFLB+.FOLEB(R)	;STORE ADDRESS OF LOOKUP BLOCK
	MOVEI	B,.JLFLB(R)		;LOAD THE ADDRESS
	HRLI	B,.FOPPN+1		;AND LOAD THE COUNT
	FILOP.	B,			;ENTER THE LOG!!
	  JRST LOGOER			;FAIL?
	TLO	R,RL.UST		;FORCE POSITIONING
	MOVE	A,.JLLEB+.RBSIZ(R)	;GET FILE SIZE
	ADDI	A,DSKBLK-1		;ROUND UP
	IDIVI	A,DSKBLK		;AND CONVERT TO BLOCKS
	AOS	A			;INCRMENT
	TLNN	F,FL.LUP		;LOG UP DONE?
	MOVEM	A,.JLUSI(R)		;NO, SET BLOCK NUMBER
	POPJ	P,			;AND RETURN
>  ;END IFN FTUUOS

;;;THE TOPS20 VERSION OF THIS ROUTINE IS ON THE NEXT PAGE
IFN FTJSYS,<
FNDLOG:	DMOVEM	T1,C			;SAVE T1 AND T2 IN C AND D
	MOVX	T1,<GJ%SHT!GJ%OLD>	;SHORT CALL, OLD FILE ONLY
	HRROI	T2,Q.LSTR(R)		;THE LOG FILE NAME
	GTJFN				;GET IT
	  JRST	FNDL.0			;FAILED, MUST CREATE ONE
	MOVEI	T2,^D10			;SET FOR DMPLOG
	MOVEM	T2,.JLUSI(R)		;SEE "DMPL.1" + a couple
	JRST	FNDL.1			;OK, OPEN IT
FNDL.0:	MOVX	T1,<GJ%SHT!GJ%FOU>	;SHORT, FOR OUTPUT
	HRROI	T2,Q.LSTR(R)		;THE LOG FILE NAME
	GTJFN				;TRY THAT
	  JRST	FNDL.E			;BIG LOSER
FNDL.1:	MOVEM	T1,.JLJFN(R)		;SAVE LOG FILE JFN
	TRNN	F,FR.FLL		;FIRST LOOK AT THE LOG FILE
	  JRST	FNDL.2			;NO, SKIP THE ACCESS CHECKS
	HRROI	T1,.JLDEV(R)		;POINT TO BLOCK FOR LOG DEVICE
	MOVE	T2,.JLJFN(R)		;GET THE JFN OF THE LOG
	MOVX	A,1B2			;DEVICE ONLY
	JFNS				;GET IT
	MOVE	T1,.JLDEV(R)		;GET THE DEVICE NAME
	CAMN	T1,[ASCII /NUL/]	;IS IT NUL?
	JRST	FNDL.2			;YES, IGNORE ACCESS CHECK
	LOAD	B,Q.SEQ(R),EQ.PRV	;GET CALLERS PRIVS AT CREATE TIME
	JUMPN	B,FNDL.2		;IF WHEELED, OPERATOR, ALLOW ANYTHING
	MOVE	T1,.JLJFN(R)		;GET THE JFN
	MOVEM	T1,TEMP3+.CKAUD		;STORE JFN
	MOVX	T1,.CKAAP		;ACCESS TYPE APPEND
	MOVEM	T1,TEMP3+.CKAAC		;AS ACCESS WANTED
	HRROI	T1,Q.USNM(R)		;POINT TO USER ID
	MOVEM	T1,TEMP3+.CKALD		;SAVE AS LOGGED-IN USER
	HRROI	T1,Q.CNDI(R)		;POINT TO CONNECTED DIRECTORY
	MOVEM	T1,TEMP3+.CKACD		;SAVE IT
	SETZM	TEMP3+.CKAEC		;NO ENABLE CAPABILITIES
	MOVX	T1,<CK%JFN+.CKAUD+1>	;FLAGS,,ARG-LENGTH
	MOVEI	T2,TEMP3		;WHERE THE ARGS ARE
	CHKAC				;CHECK USERS APPEND ACCESS
	  JRST	FNDL.E			;OH WELL!!
	JUMPE	T1,FNDL.N		;JUMP IF NO ACCESS
FNDL.2:	MOVE	T1,.JLJFN(R)		;GET THE LOG FILE JFN AGAIN
	MOVX	T2,<OF%APP+^D36B5>	;36 BIT APPEND MODE
	OPENF				;OPEN THE FILE
	  JRST	FNDL.E			;GIVE AN ERROR MESSAGE
	DMOVE	T1,C			;RESTORE T1 AND T2
	POPJ	P,			;AND RETURN

FNDL.N:	MOVEI	T1,OPNX4		;ERROR IF NO ACCESS
FNDL.E:	MOVE	B,T1			;GET THE ERROR CODE IN B
	MOVEI	IO2,[ASCIZ\GTJFN/OPENF failed\]
	JRST	LGLKE1			;GIVE APPROPRIATE ERROR
>  ;END OF IFN FTJSYS
;HERE TO REPORT VARIOUS LOG FILE ERRORS TO THE OPERATOR AND THEN CANCEL THE JOB

IFN FTUUOS,<
LOGOER:	MOVEI	IO2,[ASCIZ/OPEN failed/]
	JRST	LGLKE1		;CANCEL THE JOB

LOGIOE:	PUSHJ	P,CHANIO	;GET THE LOG STATUS BITS
	  GETSTS 0,B		;GET INTO B FOR OUTPUT
	MOVEI	IO2,[ASCIZ/OUTPUT failed/]
	JRST	LGLKE1		;REPORT THE ERROR AND CANCEL THE JOB
>  ;END OF IFN FTUUOS

LGLKE1:	MOVEM	IO2,TEMP1	;SAVE ERROR MESSAGE ADDRESS
	PUSHJ	P,TTYALL	;TYPE OUT ALL SUBJOB INFORMATION
	OUTSTR	@TEMP1		;APPEND THE ERROR MESSAGE
	OUTSTR	[ASCIZ/ for the LOG file. Error code - /]
	HRRZ	T1,B		;GET THE ERROR CODE
	PUSHJ	P,TTYOCT	;OUTPUT IT AS AN OCTAL NUMBER
ILLO.2:	PUSHJ	P,TTCRLF	;END THIS LINE
	MSGTTY	[ASCIZ/Cancelling this job.  No output generated./]
	TLZ	R,RL.OPR!RL.DIA	;CLEAR SOME POSSIBLE FLAGS
	TLZ	F,FL.SIL	;CLEAR SILENCE MODE
	TLO	R,RL.NLG	;INDICATE NO LOG FILE OUTPUT (THERE'S NO LOG FILE)
	PUSHJ	P,RELREL	;GET RID OF THE ASSIGNMENT (IO1 HAS THE CHANNEL)
	PUSHJ	P,SNDUPC	;SEND A ^C
	PUSHJ	P,SNDUPC	;SEND ANOTHER ^C FOR GOOD MEASURE
	PUSHJ	P,KJOB.K	;SEND A SIMPLE KJOB STRING TO GET RID OF THE JOB
	JRST	CLOS.1		;AND DISMISS IT
;SUBROUTINE TO DEPOSIT A CHARACTER INTO THE LOG FILE

PUTLOG:	CAIL	CH,40		;IS THIS A CONTROL CHARACTER
	  JRST	PUTL.0		;NO, OUTPUT AS IS
	CAIG	CH,CHR.CR	;CODES 011-015 ARE IMAGE OUTPUT ALSO
	CAIGE	CH,CHR.HT	;LINE PRINTERS KNOW ABOUT THOSE
	  SKIPA			;NOT ONE OF THOSE, PRINT ^CHAR
	JRST	PUTL.0		;OUTPUT THEM AS IMAGE ALSO
	HRLM	CH,(P)		;SAVE THE ORIGINAL
	MOVEI	CH,"^"		;GET AN UPARROW
	PUSHJ	P,PUTL.0	;OUTPUT IT
	HLRZ	CH,(P)		;GET THE ORIGINAL
	MOVEI	CH,100(CH)	;MAKE THE APPROPRIATE CHARACTER
	PUSHJ	P,PUTL.0	;AND OUTPUT IT
	HLRZ	CH,(P)		;GET THE ORIGINAL AGAIN FOR THE CALLER
	POPJ	P,		;AND RETURN
PUTL.0:	TLZN	F,FL.CRS	;WAS LAST CHARACTER A CARRIAGE RETURN
	  JRST	PUTL.3		;NO, JUST OUTPUT IT
	CAIG	CH,CHR.FF	;CHECK FOR CR NOT FOLLOWED BY VERTICAL MOTION
	CAIGE	CH,CHR.LF	;SAME CHECK AS BELOW FOR TIME STAMP
	  SKIPA			;NOT VERTICAL MOTION, OUTPUT 2 TABS
	JRST	PUTL.3		;OUTPUT THE MOTION CHARACTER
	HRLM	CH,(P)		;SAVE THE CHARACTER ON THE STACK
	PUSHJ	P,PUT2TB	;OUTPUT 2 TABS
	HLRZ	CH,(P)		;RESTORE THE CHARACTER AND OUTPUT IT
PUTL.3:	TLNE	R,RL.NLG	;IS THERE A LOG FILE
	  JRST	[OUTCHR CH	;NO, GIVE THIS TO THE OPERATOR
		POPJ P,]	;AND RETURN
	TLNE	R,RL.TIM	;NEED A TIME STAMP
	  PUSHJ	P,LOGSTP	;YES, DO IT
	SOSL	.JLCNT(R)	;ROOM IN THIS BUFFER
	  JRST	PUTL.4		;YES, GO STUFF THE CHARACTER
	PUSHJ	P,DMPLOG	;NO, MAKE SOME
	SOS	.JLCNT(R)	;NOW ADJUST FOR THE CHARACTER
PUTL.4:	CAIN	CH,CHR.CR	;IS THIS A CARRAIGE RETURN
	  TLO	F,FL.CRS	;YES, MARK IT FOR OVERPRINTING CHECK
	IDPB	CH,.JLPTR(R)	;STORE THE CHARACTER
	CAIG	CH,CHR.FF	;CHECK IF IT WAS VERTICAL PAPER MOTION
	CAIGE	CH,CHR.LF	;THOSE CAUSE A TIME STAMP
	  JRST	PUTL.1		;WAS NOT, SAVE THIS CHAR IN THE OPER LINE
	TLO	R,RL.TIM	;YES, NEXT LINE NEEDS A TIME STAMP
	SETZM	.JOUTC(R)	;SET TO REFILL THE OPERATOR LINE NEXT
	POPJ	P,
PUTL.1:	TLNE	R,RL.IGN	;SKIP SAVING THESE CHARACTERS
	  POPJ	P,		;YES, RETURN TO CALLER
	SOSL	.JOUTC(R)	;ANY ROOM LEFT
	  JRST	PUTL.2		;YES, SAVE THIS CHARACTER
	HRLM	CH,(P)		;SAVE CALLERS CH
	SETZM	.JOUTL(R)	;CLEAR THE LINE SO BATOPR CAN OUTSTR IT
	HRLI	CH,.JOUTL(R)	;SET UP FOR THE BLT
	HRRI	CH,.JOUTL+1(R)	;CLEAR THE OLD LINE BUFFER
	BLT	CH,.JOUTL+^D19(R) ;CLEAR THE LINE
	MOVEI	CH,^D98		;RESET COUNT (ADJUST FOR THE ONE ABOUT TO STORE)
	MOVEM	CH,.JOUTC(R)	;STORE
	MOVE	CH,[POINT 7,.JOUTL(R)] ;REBUILD BYTE POINTER TOO
	MOVEM	CH,.JOUTP(R)	;STORE THAT TOO
	HLRZ	CH,(P)		;NOW GET THE CHARACTER BACK
PUTL.2:	IDPB	CH,.JOUTP(R)	;STORE THE CHARACTER FOR THE OPERATOR
	POPJ	P,		;AND RETURN TO CALLER
;HERE TO DUMP THE CURRENT BUFFERS TO THE LOG FILE

DMPLOG:	SKIPN	.JLUSI(R)	;WAS LOG FILE EVER STARTED
	  JRST	DMPL.3		;NO, START IT NOW (JUST THE BUFFERS)
	TLZ	R,RL.UST	;CLEAR A FLAG
	PUSHJ	P,CHNLOG	;FIND THE CHANNEL ASSIGNED TO THIS LOG FILE
	  PUSHJ	P,FNDLOG	;WAS NEW ASSIGNMENT, FIND THE FILE
	TLNN	R,RL.UST	;NEED A USETO
	  JRST	DMPL.1
	PUSHJ	P,CHANIO	;POSITION THE LOG FILE
	  USETO	0,@.JLUSI(R)
DMPL.1:	TRZN	F,FR.FLL	;FIRST TIME WE'VE TOUCHED THE LOG FILE
	  JRST	DMPL.4		;SO, SKIP THIS MESS

; THE FOLLOWING IS IN RESPONSE TO SEVERAL SUGGESTIONS TO SEPARATE THE
;	NEW LOG FILE FROM ANY OLD ONE CREATED DURING A PREVIOUS
;	INCARNATION OF THIS JOB.  NEWJOB STARTS THE LOG WITH A <CR><LF>
;	(INDIRECTLY WITH IDENT UUO) WHICH COULD GET REPLACED WITH A <FF>

	MOVE	A,.JLUSI(R)	;WHAT IS THE CURRENT SIZE OF THE LOG FILE
	CAIG	A,2		;INITIAL CREATE OR SMALL ONE FROM SPRINT-10
	  JRST	DMPL.4		;YES, <CR><LF> IS ALL THAT IS NEEDED
	MOVSI	A,(BYTE (7)177,177,0) ;MASK FOR 2 ASCII CHARACTERS
	ANDCAM	A,.JLOGB(R)	;CLEAR <CR><LF> PAIR
	MOVSI	A,(BYTE (7)0,CHR.FF,0) ;INSERT NULL, FORM FEED INSTEAD
	IORM	A,.JLOGB(R)	;TO SEPARATE OLD FROM NEW RUN OF SAME JOB
DMPL.4:	PUSHJ	P,DMPOUT	;OUTPUT THE BUFFERS

; IF CALLED BY CLSLOG, THERE IS MORE ROOM IN THE BUFFERS
;	SO DON'T UPDATE THE INTERNAL BUFFER POINTERS AND COUNTS

DMPL.2:	SKIPL	.JLCNT(R)	;IS THERE STILL SOME ROOM
	  POPJ	P,		;YES, RETURN TO CLSLOG
	TLZ	F,FL.LUP	;CLEAR ANY PENDING UPDATES
	MOVE	A,.JLUSI(R)	;GET THE BLOCK
	ADDI	A,LOGBFR	;ADJUST FOR NEXT TIME
	MOVEM	A,.JLUSI(R)
	MOVE	A,[POINT 7,.JLOGB(R)]
	MOVEM	A,.JLPTR(R)	;SET NEW BYTE POINTER
	MOVEI	A,LOGCHR	;FULL BUFFER SIZE
	MOVEM	A,.JLCNT(R)	;AS COUNT
	SETZM	.JLOGB(R)	;CLEAR THE BUFFERS
	HRLI	A,.JLOGB(R)
	HRRI	A,.JLOGB+1(R)
	BLT	A,.JLOGB+<DSKBLK*LOGBFR>-1(R) ;CLEAR ALL THE BUFFERS
	POPJ	P,		;RETURN TO STORE THE NEW CHARACTER
DMPL.3:	HRREI	A,<1-LOGBFR>	;FAKE BLOCK 1
	MOVEM	A,.JLUSI(R)
	JRST	DMPL.2		;SET UP INITIAL BUFFERS
;SUBROUTINE TO OUTPUT THE INTERNAL LOG FILE BUFFERS

IFN FTUUOS,<
DMPOUT:	IFG	<LOGBFR-1>,<	;AVOID EXTRA BLOCKS IF MORE THAN 1 BUFFER
	MOVEI	A,LOGCHR	;LARGEST COUNT
	SUB	A,.JLCNT(R)	;COMPUTE CHARACTERS STORED
	ADDI	A,^D4		;COMPUTE MODULO 5
	IDIVI	A,^D5		;CONVERT TO WORDS
	MOVNS	A		;GET - COUNT
	HRLS	A		;WANT COUNT IN LEFT HALF
	SKIPGE	.JLCNT(R)	;AS WITH ALL GOOD COUNTERS, ARE WE OFF BE A FEW
	>
	  HRLI	A,-<DSKBLK*LOGBFR> ;YES, GET COUNT FOR FULL BUFFERS
	HRRI	A,.JLOGB-1(R)
	SETZ	B,
	PUSHJ	P,CHANIO	;OUTPUT THE CURRENT BUFFER
	  OUT	0,A
	  SKIPA			;NORMAL RETURN
	JRST	LOGIOE		;LOG FILE I/O ERROR
	JUMPN	IO1,CPOPJ	;PROCEED IF NOT CHANNEL 0
	JRST	RELCHN		;RELEASE THE TEMP CHANNEL AND RETURN
>  ;END OF IFN FTUUOS

IFN FTJSYS,<
DMPOUT:	DMOVEM	T1,C		;SAVE T1 AND T2 IN C AND D
	MOVEI	A,LOGCHR	;LARGEST COUNT
	SUB	A,.JLCNT(R)	;COMPUTE CHARACTERS STORED
	JUMPE	A,DMPO.0	;RARE, BUT COULD HAPPEN
	ADDI	A,^D4		;COMPUTE MODULO 5
	IDIVI	A,^D5		;CONVERT TO WORDS
	MOVNS	A		;GET - COUNT
	SKIPGE	.JLCNT(R)	;AS WITH ALL GOOD COUNTERS, ARE WE OFF BE A FEW
	  HRROI	A,-<DSKBLK*LOGBFR> ;YES, GET COUNT FOR FULL BUFFERS
	MOVE	T1,.JLJFN(R)	;THE LOG FILE JFN
	MOVSI	T2,(POINT 36,0)	;36 BIT BYTES
	HRRI	T2,.JLOGB(R)	;WHERE THEY ARE, A = T2 + 1, -WORD COUNT
	SOUT			;APPEND TO THE FILE
	SKIPGE	.JLCNT(R)	;BUFFERS FILLED OR WAS IT CLSLOG
	  JRST	DMPO.1		;FILLED, LEAVE THE FILE OPENED
DMPO.0:	SETZ	T1,		;GET A ZERO
	EXCH	T1,.JLJFN(R)	;GET JFN, INDICATE CLOSED
	CLOSF			;CLOSE THE FILE
	  JFCL			;IGNORE FAILURES
	SETOM	.JLCNT(R)	;RE-PRIME THE BUFFERS
DMPO.1:	DMOVE	T1,C		;RESTORE T1 AND T2
	POPJ	P,		;AND RETURN
>  ;END OF IFN FTJSYS
	SUBTTL	I/O Handling Routines - Random PTY and LOG File things

;SUBROUTINES TO DO INPUT/OUTPUT FROM/TO THE PTY/LOG
;THESE ROUTINES TEND TO BE VERY SMALL AND SPECIALIZED
;A SINGLE CHARACTER MUST PASS THROUGH MANY ROUTINES TO FINALLY
;GET TO/FROM THE JOB AND ECHO'ED TO THE LOG FILE

;SUBROUTINE TO INPUT A BUFFER FROM THE PTY

INPPTY:	HLLZ	IO1,.JPCHN(R)	;GET THE PTY CHANNEL NUMBER
	PUSHJ	P,CHANIO
	  INPUT	0,0		;INPUT A BUFFER
	POPJ	P,

;SUBROUTINE TO OUTPUT A BUFFER TO THE JOB

SNDUPC:	MOVEI	CH,CHR.CC	;SET A ^C
	PUSHJ	P,PUTPTY	;SEND THE ^C AND FALL INTO FORCE THE BUFFER
PTYSND:	HLLZ	IO1,.JPCHN(R)	;GET THE CHANNEL NUMBER
	PUSHJ	P,CHANIO
	  OUTPUT 0,0		;OUTPUT IT
	POPJ	P,

;SUBROUTINE TO GET A SINGLE CHARACTER FROM THE PTY INPUT BUFFER

GETPTY:	SOSGE	.JPINP+2(R)	;IS THERE A CHARACTER
	  POPJ	P,		;NO, GIVE NON SKIP RETURN
	ILDB	CH,.JPINP+1(R)	;GET THE NEXT
	JUMPN	CH,CPOPJ1	;NOT A NULL, GIVE GOOD RETURN
	JRST	GETPTY		;IGNORE NULLS

;SUROUTINE TO PUT A SINGLE CHARACTER INTO THE OUTPUT PTY BUFFER

PUTPTY:	SOSGE	.JPOUT+2(R)	;IS BUFFER FULL
	  JRST	PUTP.1		;YES, SEND THE BUFFER
	IDPB	CH,.JPOUT+1(R)	;STORE IT
	POPJ	P,
PUTP.1:	PUSHJ	P,PTYSND	;SEND THIS BUFFER TO THE JOB
	TLO	R,RL.EOL	;FAKE AN EOL SENT SO ANY ERRORS CAN BE FOUND
	PUSH	P,CH		;SAVE THE CHARACTER I WANT TO SEND
	PUSH	P,T1		;SAVE OTHER REGS ALSO
	PUSH	P,T2		;...
	PUSHJ	P,IOWAIT	;AND WAIT UNTIL THE JOB WANT'S MORE INPUT
	TLNE	R,RL.TIM	;IS THERE A TIME STAMP NEEDED
	TLNE	F,FL.SIL	;YES, BUT ARE WE SILENCED
	  SKIPA			;DON'T OUTPUT A TIME STAMP
	PUSHJ	P,LOGSTP	;OUTPUT ONE BEFORE RESTORING T1 AND T2
	TLZ	R,RL.EOL	;CLEAR THE FLAG JUST IN CASE IT'S LEFT ON
	POP	P,T2		;RESTORE
	POP	P,T1		;...
	POP	P,CH		;RESTORE THE CHARACTER TO SEND
	JRST	PUTPTY		;NOW STORE IT INTO THE BUFFER
;SUBROUTINE TO SEND A STRING POINTED TO BY 'T1' TO THE JOB

UUOSND:	HRR	T1,.JBUUO##	;ENTER HERE IF FROM UUO CALL
SNDSTR:	HRLI	T1,(POINT 7,0)	;MAKE A BYTE POINTER OUT OF IT
	ILDB	CH,T1		;GET ONE
	JUMPE	CH,CPOPJ	;IS AN ASCIZ STRING
	PUSHJ	P,SNDCHR	;SEND IT AND ECHO
	JRST	SNDSTR+1	;LOOP ON THE STRING

;SUBROUTINE TO SEND <CR>-<LF> AND FORCE OUT THE BUFFER

SNDCLF:	MOVEI	CH,CHR.CR	;A CARRIAGE RETURN
	PUSHJ	P,SNDCHR	;SEND THE CHARACTER
	MOVEI	CH,CHR.LF	;A LINE FEED
	PUSHJ	P,SNDCHR	;SEND IT TOO
	JRST	PTYSND		;SEND THE BUFFER AND RETURN

;SUBROUTINE TO SEND 'T1' AS A DECIMAL NUMBER TO THE JOB

SNDDEC:	IDIVI	T1,^D10		;STANDARD BINARY TO DECIMAL CONVERSION
	HRLM	T2,(P)		;SAVE A WORD ON THE PDL
	JUMPE	T1,.+2		;ALL DONE?
	PUSHJ	P,SNDDEC	;NO, KEEP GOING
	HLRZ	CH,(P)		;RETRIEVE CHARACTER
SNDBIN:	MOVEI	CH,"0"(CH)	;MAKE ASCII
SNDCHR:	PUSHJ	P,PUTPTY	;PUT INTO THE OUTPUT BUFFER
	CAIN	CH,CHR.LF	;WAS THAT THE LINE FEED I SENT
	  TLO	R,RL.EOL	;YES, SET A FLAG FOR ERROR CHECKING
	TLNE	F,FL.SIL	;IS THE LINE TO BE SILENCED
	  POPJ	P,		;YES, EXIT NOW
	JRST	PUTLOG		;ECHO IN THE LOG FILE

;SUBROUTINE TO SEND 'T1' AS AN OCTAL NUMBER TO THE JOB

SNDOCT:	LSHC	T1,-^D3		;BREAK IT APART
	HLLM	T2,(P)		;PUT IT ON THE STACK
	JUMPE	T1,.+2
	PUSHJ	P,SNDOCT	;DO THE REST
	HLRZ	CH,(P)		;GET THE CHARACTER
	LSH	CH,-^D15	;POISTION IT
	JRST	SNDBIN		;MAKE ASCII AND SEND IT

;SUBROUTINE TO SEND SIXBIT AC T1 TO THE JOB

UUOSN6:	MOVE	T1,@.JBUUO##	;ENTER HERE IF FROM UUO CALL
SNDSIX:	MOVE	T2,[POINT 6,T1]	;POINT TO THE TEXT
	ILDB	CH,T2		;GET A CHARACTER
	JUMPE	CH,CPOPJ	;STOP ON A NULL
	MOVEI	CH," "(CH)	;MAKE ASCII
	PUSHJ	P,SNDCHR	;SEND THE CHARACTER
	TLNN	T2,770000	;GET ALL SIX YET
	  POPJ	P,		;YES, RETURN
	JRST	SNDSIX+1	;LOOP FOR ALL CHARACTERS
;LITTLE ROUTINES TO SEND SINGLE CHARACTERS TO THE JOB

SNDCMA:	SKIPA	CH,[","]	;A COMMA
SNDCOL:	MOVEI	CH,":"		;A COLON
	JRST	SNDCHR		;SEND IT

;ROUTINE TO PUT A TIME STAMP ON THE LINE OF OUTPUT

LOGTIM:	MOVE	T1,CURMST	;GET CURRENT TIME
	SKIPN	.JUPLT(R)	;NEED TO RE-START THE TIMER
	  MOVEM	T1,.JUPLT(R)	;YES, MARK TIME OF CHANGE
	TLZ	R,RL.TIM	;CLEAR THE NEEDED FLAG
	TLO	R,RL.IGN	;DON'T SAVE THE TIME STAMP FOR THE OPERATOR
LOGTI1:	IDIVI	T1,^D60000	;BREAK INTO COMPONENTS
	PUSH	P,T2
	IDIVI	T1,^D60		;HOURS IN T1, MINUTES IN T2
	PUSH	P,T2		;SAVE MINUTES
	PUSHJ	P,LGDEC2	;DECIMAL TO LOG FILE (MIN. 2 CHARS)
	PUSHJ	P,PUTCOL	;OUTPUT A COLON
	POP	P,T1		;RESTORE SECONDS
	PUSHJ	P,LGDEC2	;OUTPUT IT TOO
	PUSHJ	P,PUTCOL	;ANOTHER COLON
	POP	P,T1		;RESTORE MILLISECONDS
	IDIVI	T1,^D1000
	PUSHJ	P,LGDEC2	;OUTPUT IN 2 DIGITS
	TLZ	R,RL.IGN	;RESUME SAVING FOR THE OPERATOR
	POPJ	P,		;LET HIM (HER) SEE THE LINE IDENTIFIER

;SUBROUTINE TO OUTPUT T1 AS A DECIMAL NUMBER ONTO THE LOG FILE
;ENTER AT LGDEC2 IF 2 CHARACTERS MINIMUM. WILL SUPPLY A LEADING ZERO

LGDEC2:	MOVEI	CH,"0"		;DO WE NEED A LEADING ZERO
	CAIG	T1,^D9
	  PUSHJ	P,PUTLOG	;YES, SEND LEADING ZERO
LOGDEC:	IDIVI	T1,^D10		;ANOTHER BINARY TO DECIMAL ROUTINE
	HRLM	T2,(P)
	JUMPE	T1,.+2		;ALL DONE
	PUSHJ	P,LOGDEC	;GET THE WHOLE NUMBER
	HLRZ	CH,(P)		;RESTORE THE BINARY VALUE
LOGBIN:	MOVEI	CH,"0"(CH)	;TO ASCII
	JRST	PUTLOG		;DEPOSIT INTO THE LOG FILE
;SUBROUTINE TO SEND AN ASCIZ STRING TO THE LOG FILE

UUOIDN:	TLNN	R,RL.TIM	;NEED TO END THE PREVIOUS LINE
	  PUSHJ	P,LOGCLF	;YES, DO SO
	PUSHJ	P,LOGTIM	;ADD A TIME STAMP AND FALL INTO UUOTXT
UUOTXT:	HRR	T1,.JBUUO##	;ENTER HERE IF FROM UUO CALL
LOGSTR:	HRLI	T1,(POINT 7,0)	;MAKE A BYTE POINTER
	ILDB	CH,T1
	JUMPE	CH,CPOPJ	;IS AN ASCIZ STRING
	PUSHJ	P,PUTLOG	;DEPOSIT THIS CHARACTER
	JRST	LOGSTR+1	;COPY THE WHOLE STRING

;SUBROUTINE TO PUT A CARRIAGE RETURN - LINE FEED ON THE LOG FILE

LOGBLK:	TLNN	R,RL.TIM	;NEED TO END THE PREVIOUS LINE
LGCLF2:	  PUSHJ	P,LOGCLF	;OUTPUT A CR-LF
	TLZ	R,RL.TIM	;CLEAR FLAG TO ADD ANOTHER ONE
LOGCLF:	MOVEI	CH,CHR.CR	;THE CARRIAGE RETURN
	PUSHJ	P,PUTLOG	;OUTPUT IT
	MOVEI	CH,CHR.LF	;AND THE LINE FEED
	JRST	PUTLOG		;AND EXIT THROUGH PUTLOG

;SUBROUTINE TO SEND T1 AS AN OCTAL NUMBER TO THE LOG FILE

LOGOCT:	LSHC	T1,-^D3		;SAME AS SNDOCT FOR PTY
	HLLM	T2,(P)
	JUMPE	T1,.+2		;GET IT ALL YET
	PUSHJ	P,LOGOCT	;NO, CONTINUE FOR ALL DIGITS
	HLRZ	CH,(P)		;RESTORE CHARACTER
	LSH	CH,-^D15	;POSITION DIGIT
	JRST	LOGBIN		;CONVERT TO ASCII AND RETURN
;SUBROUTINE TO SEND SIXBIT IN AC T1 TO THE LOG FILE

UUOSIX:	MOVE	T1,@.JBUUO##	;ENTER HERE IF FROM UUO CALL
LOGSIX:	MOVE	T2,[POINT 6,T1]	;GET A BYTE POINTER
	ILDB	CH,T2		;GET A CHARACTER
	JUMPE	CH,CPOPJ	;PUT ALL SIX OR STOP ON A BLANK
	MOVEI	CH," "(CH)	;MAKE ASCII
	PUSHJ	P,PUTLOG	;OUTPUT IT
	TLNN	T2,770000	;GOT IT ALL
	  POPJ	P,		;YES, RETURN
	JRST	LOGSIX+1	;GET THE NEXT

;LITTLE ROUTINES TO OUTPUT SINGLE CHARACTERS

PUTCMA:	SKIPA	CH,[","]	;A COMMA
PUTCOL:	MOVEI	CH,":"		;A COLON
	JRST	PUTLOG		;SEND THE CHARACTER

;SUBROUTINE TO PREPARE FOR A COMMENT LINE

LGCMNT:	TLNN	R,RL.TIM	;NEED TO END THE PREVIOUS LINE
	  PUSHJ	P,LOGCLF	;YES, DO IT
	TLZ	R,RL.TIM	;NO TIME STAMP NEEDED
PUT2TB:	PUSHJ	P,PUTTAB	;OUTPUT A TAB
PUTTAB:	SKIPA	CH,[CHR.HT]	;AND ANOTHER ONE
PUTPER:	MOVEI	CH,MONCHR	;A PERIOD (OR SOMETHING LIKE THAT)
	JRST	PUTLOG
;SUBROUTINE TO CLOSE OUT THE LOG FILE

CLSLOG:	TLO	G,GL.UC0	;USE 0 IF NONE, WE ARE GOING TO CLOSE IT ANYWAY
	PUSHJ	P,DMPLOG	;OUTPUT THE PARTIAL BUFFER
	SETZM	.JUPLT(R)	;CLEAR UPDATE TIMER REQUEST
	TLO	F,FL.LUP	;SET LOG FILE HAS BEEN UPDATED
	JUMPE	IO1,CPOPJ	;DONE IF THE LOG FILE ON A TEMP CHANNEL
	PUSHJ	P,RELCHN	;NO, CLOSE AND RELEASE THE FILE
	JRST	RELASS		;NOW RELEASE THE ASSIGNMENT

;SUBROUTINE TO TIME STAMP THE LOG FILE AND IDENTIFY USER OR MONITOR OUTPUT

LOGSTP:	PUSH	P,CH		;SAVE NEXT CHARACTER TO STORE
	PUSHJ	P,LOGTIM	;PUT TIME STAMP IN LOG FILE
	MOVEI	T1,[ASCIZ/ MONTR	/]
	TLNN	J,JL.UML	;WAS JOB AT MONITOR LEVEL
	  MOVEI	T1,[ASCIZ/ USER	/] ;NO, SAY USER MODE
	PUSHJ	P,LOGSTR	;SEND STRING TO LOG FILE
	POP	P,CH		;RESTORE CHARACTER
	POPJ	P,		;NOW OUTPUT IT

;SUBROUTINE TO OUTPUT AN ERROR MESSAGE TO THE LOG FILE

UUOMLG:	HRR	T1,.JBUUO##	;ENTER HERE IF FROM UUO CALL
LGEMSG:	PUSHJ	P,LOGBLK	;ISOLATE THE ERROR MESSAGE
LGMSG1:	PUSHJ	P,LGCMNT	;PREPARE A COMMENT LINE
	MOVEI	CH,"?"		;OUTPUT A QUESTION MARK
	PUSHJ	P,PUTLOG	;OUTPUT IT
	MOVEI	CH," "		;AND A SPACE
	PUSHJ	P,PUTLOG
	JRST	LOGSTR		;OUTPUT STRING AND RETURN
;SUBROUTINE TO OUTPUT A FILE SPECIFICATION TO THE LOG FILE
;ENTER WITH AC'S A-D THE 4 WORD LOOKUP/ENTER BLOCK
;		T1 = ADDRESS OF THE STRUCTURE
;		T2 = ADDRESS OF A STRING TO APPEND AFTER 'BAFIL'

IFN FTUUOS,<

LOGFIL:	PUSH	P,D		;SAVE PPN
	PUSH	P,B		;EXTENSION
	PUSH	P,A		;FILE NAME
	PUSH	P,T1		;STRUCTURE
	PUSH	P,T2		;MESSAGE
	IDENT	[ASCIZ/ BAFIL	/] ;IDENTIFY LINE
	POP	P,T1		;GET MESSAGE
	PUSHJ	P,LOGSTR	;SEND IT ALSO
	POP	P,T1		;RESTORE STRUCTURE ADDRESS
LOGF.3:	SIXLOG	0(T1)		;SEND IT AS SIXBIT
	PUSHJ	P,PUTCOL	;ADD A COLON
	POP	P,T1		;GET FILE NAME
	PUSHJ	P,LOGSIX	;IS SIXBIT ALSO
	PUSHJ	P,PUTPER	;ADD A PERIOD
	POP	P,T1		;GET EXTENSION
	PUSHJ	P,LOGSIX	;SIXBIT AGAIN
	MOVEI	CH,"["		;BEGINNING OF PPN
	PUSHJ	P,PUTLOG
	EXCH	J,(P)		;GET PPN OR POINTER, SAVE J
	TLNE	J,-1		;IS IT A PPN
	  JRST	LOGF.1		;JUST OUTPUT THE PPN
	MOVE	T1,2(J)		;GET THE REAL PPN
	PUSHJ	P,LOGF.2	;OUTPUT THAT PART
LOGF.0:	MOVE	T1,3(J)		;GET NEXT SFD SPECIFICATION
	JUMPE	T1,LOGF.E	;END OF THE FILE SPEC
	PUSHJ	P,PUTCMA	;OUTPUT A COMMA
	PUSHJ	P,LOGSIX	;AND ADD THE SFD NAME
	AOJA	J,LOGF.0	;CONTINUE FOR ALL LEVELS
LOGF.E:	POP	P,J		;RESTORE J
	MOVEI	CH,"]"		;GET CLOSURE OF PPN
	JRST	PUTLOG		;OUTPUT THAT AND RETURN TO CALLER
LOGF.1:	MOVE	T1,J		;COPY THE PPN TO T1
	PUSHJ	P,LOGF.2	;OUTPUT IT
	JRST	LOGF.E		;CLEAN UP AND RETURN
LOGF.2:	HRLM	T1,(P)		;SAVE PROGRAMMER NUMBER
	HLRZS	T1		;POSITION PROJECT NUMBER
	PUSHJ	P,LOGOCT	;OUTPUT AN OCTAL NUMBER
	PUSHJ	P,PUTCMA	;ADD A COMMA
	HLRZ	T1,(P)		;RETREIVE PROGRAMMER NUMBER
	JRST	LOGOCT		;OUTPUT THAT AND RETURN

>  ;END OF IFN FTUUOS

;;;TOPS20 COUNTERPART OF THIS ROUTINE IS ON THE NEXT PAGE
;SUBROUTINE TO OUTPUT A FILE SPECIFICATION TO THE LOG FILE
;		T1 = THE ADDRESS OF THE FILE STRING
;		T2 = ADDRESS OF A STRING TO APPEND AFTER 'BAFIL'

IFN FTJSYS,<

LOGFIL:	PUSH	P,T1		;STRING ADDRESS
	PUSH	P,T2		;MESSAGE
	IDENT	[ASCIZ/ BAFIL	/] ;IDENTIFY LINE
	POP	P,T1		;GET MESSAGE
	PUSHJ	P,LOGSTR	;SEND IT ALSO
	POP	P,T1		;RESTORE FILE SPEC ADDRESS
	JRST	LOGSTR		;APPEND IT AND RETURN

>  ;END OF IFN FTJSYS
	SUBTTL	Operator Communications Section

OPRCOM:	MOVE	T1,TTYFLG	; 0 = HAVE AN INTERRUPT SYSTEM, -1 = DON'T
	EXCH	T1,TTYINT	;CLEAR INTERRUPT, GET OLD STATUS
	JUMPE	T1,CPOPJ	;NO INTERRUPT, RETURN
	SKPINL			;IS THERE INPUT TO READ
	  POPJ	P,		;NO, RETURN
	MOVE	T1,[INCHWL CH]	;HOW TO GET A CHARACTER
	MOVEM	T1,COMFIL	;INTO THE FILLER WORD
	SETZ	F,		;CLEAR FLAGS USED BY GETXXX ROUTINES
BAOP.2:	PUSHJ	P,GETONE	;GET THE FIRST CHARACTER OF THE COMMAND
	  JRST	COMC.2		;A TERMINATOR, IGNORE THE LINE
	  JRST	[CAIE CH," "	;IGNORE LEADING SPACES
		   JRST COMERR	;WASN'T, IS COMMAND ERROR
		JRST BAOP.2]	;TRY THE NEXT CHARACTER
	  JRST	BAOP.N		;IS IS A NUMBER
	CAIE	CH,"B"		;IT WAS A LETTER, WAS IT MY NAME (FROM OPSER)
	  JRST	[TRO F,FR.RSC	;NO, MAYBE A COMMAND, ALREADY HAVE THE LETTER
		JRST BAOP.C]	;TRY TO FIND IT IN THE COMMAND TABLE
	PUSHJ	P,GETONE	;WHAT'S AFTER THE B
	  JRST	COMERR		;STILL CAN'T BE A TERMINATOR
	  JRST	BAOP.S		;SPECIAL, CAN BE A DASH OR SPACE
	  JRST	BAOP.N		;A SUBJOB NUMBER
	CAIE	CH,"A"		;ANOTHER LETTER, WAS IT AN A
	  JRST	COMERR		;NO, COMPLAIN
DDALL:	TLO	G,GL.ALL	;SET THE 'ALL' FLAG
	TRO	F,FR.RSC	;ALREADY HAVE A CH
BAOP.3:	PUSHJ	P,GETONE	;FIND THE DASH OR SPACE AFTER ALL
	  JRST	COMERR		;CAN'T BE A TERMINATOR
	  JRST	BAOP.S		;A SPECIAL
	  JFCL			;IGNORE NUMBERS
	JRST	BAOP.3		;KEEP LOOKING
BAOP.N:	TRO	F,FR.RSC	;ALREADY HAVE CH
	PUSHJ	P,GETNUM	;GET THE NUMERIC VALUE
	  JRST	ILLNUM		;BAD FORMAT
	JUMPE	T1,ILLSJB	;0 IS AN ILLEGAL NUMBER
	CAILE	T1,JOBMAX	;SO IS ANYTHING OVER JOBMAX
	  JRST	ILLSJB
	MOVEM	T1,DEFSJB	;STORE THE DEFAULT SUBJOB NUMBER
	TLZ	G,GL.ALL	;CLEAR THE ALL FLAG
BAOP.S:	CAIE	CH," "		;ONLY VALID TERMINATORS HERE
	CAIN	CH,"-"		;ARE SPACE AND DASH
	  SKIPA			;DELIMITOR IS OK
	JRST	COMERR		;GIVE AN ERROR
	PUSHJ	P,GETONE	;WHAT IS THE NEXT CHAR
	  JRST	COMCLR		;A NULL COMMAND
	  SKIPA			;A SPECIAL
	  JRST	BAOP.N		;NUMBER, COULD BE B-L-COMMAND
	TRO	F,FR.RSC	;ALREADY HAVE CH, LOOK UP THE COMMAND
BAOP.C:	PUSHJ	P,GETSIX	;GET THE COMMAND
	JUMPE	T1,COMCLR	;A NULL COMMAND, IGNORE IT
	MOVE	A,[-NCMDS,,OPRCMD] ;AOBJN FOR TABLE SEARCH
	PUSHJ	P,TABSRC	;SEARCH FOR THE COMMAND IN T1
	  JRST	COMERR		;BAD COMMAND
	  JRST	OPRD.2		;TELL THE OPERATOR IT IS NOT UNIQUE
	JRST	@DISCMD(C)	;DISPATCH TO THE COMMAND
COMERR:	MSGTTY	[ASCIZ/Unknown BATCON command/]
COMCLR:	TRO	F,FR.RSC	;ALREADY HAVE A CH
COMC.1:	PUSHJ	P,GETONE	;GET A CHARACTER
	  JRST	COMC.2		;TERMINATOR
	  JFCL
	  JFCL
	JRST	COMC.1		;CONTINUE UNTIL A LINE TERMINATOR
COMC.2:	SETOM	TTYINT		;FORCE ANOTHER LOOK AT THE TERMINAL
	JRST	OPRSTA		;RE-PROMPT AND RETURN

OPRD.2:	MSGTTY	[ASCIZ/Command is ambiguous/]
	JRST	COMCLR		;CONSUME THE REST OF THE INPUT LINE
ILLNUM:	MSGTTY	[ASCIZ/Illegal number format/]
	JRST	COMCLR		;CONSUME THE REST OF THE LINE
ARGERR:	MSGTTY	[ASCIZ/Missing argument or illegal delimiter/]
	JRST	COMCLR		;CANCEL THE INVALID LINE
RANGER:	MSGTTY	[ASCIZ/Argument is out of range/]
	JRST	COMCLR		;FLUSH THE RESET OF THE COMMAND
ILLSJB:	MSGTTY	[ASCIZ/Illegal subjob specified/]
	JRST	COMCLR		;CANCEL THE REST OF THE LINE
;RULES FOR THE COMMAND TABLE
;	1)NO COMMANDS BEGIN WITH THE LETTER "A" (EXCEPT ALL)
;	2)NO COMMANDS BEGIN WITH THE LETTER "B" (OPSER'S NAME FOR BATCON)
;	3)COMMANDS ARE UNIQUE IN 4 LETTERS OR LESS

DEFINE	CMDTBL<
	LSTOFF
	X	ALL,	;ALL IS A POSSIBLE COMMAND (MUST BE THE FIRST COMMAND)
IFN INPCOR,<X	CORE,	;SET TOTAL CORE>
	X	CURREN,	;DISPLAY CURRENT SETTINGS AND STATUS
	X	EXAMIN,	;LOOK AT A JOBS CONTROL FILE
	X	EXIT,	;WIND DOWN PROCESSING AND RETURN TO THE MONITOR
	X	GO,	;CONTINUE A STOPPED SUBJOB
	X	HELP,	;TRADITIONAL HELP COMMAND
	X	INFORM,	;REPORT QUASAR INFORMATION
	X	KILL,	;KILL A SUBJOB
IFN INPCOR,<X	MCORE,	;SET SINGLE USER CORE FOR SCHEDULING>
	X	MJOB,	;SET MAXIMUM CONCURRENT STREAMS
	X	MONJOB,	;TYPE A SUBJOBS MONITOR JOB NUMBER
	X	MTIME,	;SET SINGLE USER TIME FOR SCHEDULING
	X	NEXT,	;SELECT SEQUENCE N TO BE THE NEXT TO RUN
	X	OPERAT,	;GIVE A RESPONSE TO DIALOGUE MODE
	X	REQUEU,	;REQUEUE A SUBJOB
	X	RESET,	;WIND DOWN PROCESSING AND RETURN TO INITIAL STATE
	X	ROUTE,	;CHANGE ROUTING FOR A STATION
	X	ST,	;ABBREVIATION FOR "START"
	X	START,	;BEGIN PROCESSING OR CANCEL RESET,PAUSE, AND EXIT
	X	STOP,	;STOP A SUBJOB
	X	TELL,	;GIVE THE USER A MESSAGE
	X	TIME,	;SET TOTAL TIME
	X	WHAT,	;DISPLAY SUBJOB STATUS
	LSTON
	>

DEFINE	X(A)<
	<SIXBIT\A\>
	>
OPRCMD:	CMDTBL		;GENERATE THE COMMAND TABLE
NCMDS==.-OPRCMD		;NUMBER OF COMMANDS

DEFINE	X(A)<
	EXP	DD'A
	>
DISCMD:	CMDTBL		;GENERATE THE DISPATCH TABLE
;EXIT	COMMAND - SET EXIT AND STOP SCHEDULING FLAGS
;RESET	COMMAND - SET STOP SCHEDULING FLAG

DDEXIT:	TLO	G,GL.EXI	;SET THE EXIT REQUEST AND FALL INTO RESET
DDRESE:	TLO	G,GL.SSH	;SET SOME FLAGS
STSCHG:	TLNE	G,GL.STA	;SKIP IF NOT STARTED
	TLO	G,GL.STC	;INDICATE A STATUS CHANGE
	JRST	COMCLR		;END OF COMMAND PROCESSING

;START	COMMAND - CLEAR RESET AND EXIT. START BATCH
;ST	COMMAND - ABBREVIATION FOR "START"

DDST:
DDSTAR:	TLZ	G,GL.SSH!GL.EXI	;CLEAR THE FLAGS
	TLO	G,GL.STA	;SET BATCH IS STARTED
	JRST	STSCHG		;END OF COMMAND PROCESSING

;MONJOB	COMMAND - TYPE OUT THE SUBJOB NUMBER AND MONITOR JOB NUMBER

DDMONJ:	PUSHJ	P,LCNTRL	;SET THE LOOP CONTROL FOR THE FOLLOWING
	MOVE	T1,S		;GET THE STREAM NUMBER
	PUSHJ	P,TTYDEC	;OUTPUT IT AS DECIMAL
	PUSHJ	P,TTYTAB	;ADD A TAB
	HRRZ	T1,.JSTAT(R)	;GET THE JOB NUMBER FROM THE JOBSTS UUO
	JUMPE	T1,[OUTCHR ["*"] ;DON'T KNOW ONE, TYPE AN ASTERISK
		JRST TTCRLF]	;END THE LINE
	PUSHJ	P,TTYDEC	;OUTPUT THE JOB NUMBER
	JRST	TTCRLF		;END THE LINE AND RETURN TO LOOP CONTROL

;MJOB	COMMAND - SET MAXIMUM CONCURRENT STREAMS

DDMJOB:	JSP	S,POSNUM	;POSITION AT A NUMBER FIELD AND GET THE ARG
	JUMPL	T1,RANGER	;MJOB 0 IS USEFUL, NEGATIVE IS AN ERROR
	CAILE	T1,JOBMAX	;IS IT TOO LARGE
	  JRST	RANGER		;YES, COMPLAIN
	MOVEM	T1,MJOB		;STORE NEW
	JRST	STSCHG		;END OF THIS COMMAND

;NEXT	COMMAND - FORCE A JOB TO BE SELECTED

DDNEXT:	JSP	S,POSNUM	;POSITION AT A NUMBER FIELD AND GET THE ARG
	MOVEM	T1,NXTJOB	;SAVE FOR THE SCHEDULER
	JRST	STSCHG
;HELP	COMMAND - TRADITIONAL HELP COMMAND, LIST COMMANDS AVAILABLE

DDHELP:	PUSH	P,CH		;SAVE TERMINATOR
	OUTSTR	[ASCIZ/Commands available:/]
	MOVSI	A,-NCMDS	;NUMBER IN THE TABLE
	SETZ	B,		;NEED A CR-LF
	JRST	HELP.2		;SKIP OVER "ALL" (FIRST IN THE TABLE)
HELP.1:	JUMPN	B,.+3		;NEED A CR-LF YET
	  PUSHJ	P,TTCRLF	;YES, OUTPUT ONE
	  MOVEI	B,7		;RESET LINE COUNT
	MOVE	T1,OPRCMD(A)	;GET A COMMAND FROM THE TABLE
	CAMN	T1,[SIXBIT/ST/]	;THE ACCEPTED ABBREVIATION FOR START
	  JRST	HELP.2		;YES, DON'T LIST IT
	PUSHJ	P,TTYSIX	;TYPE OUT SIXBIT
	PUSHJ	P,TTYTAB	;ALIGN THE OUTPUT
	SOS	B		;DECREASE LINE COUNT
HELP.2:	AOBJN	A,HELP.1	;TYPE OUT ALL COMMANDS
	PUSHJ	P,TTCRLF	;END THE LINE
	POP	P,CH		;RESTORE CH
	JRST	COMCLR		;END OF THIS COMMAND

;MTIME	COMMAND - SET SINGLE JOB TIME MAXIMUM

DDMTIM:	JSP	S,POSNUM	;MAKE SURE A NUMBER FOLLOWS, GET IT
	TLNE	T1,-1		;DID IT OVERFLOW
	  JRST	RANGER		;YES, GIVE AN ERROR
	MOVEM	T1,UTIME	;STORE VALUE, NO RANGE CHECK
	JRST	STSCHG		;END OF THE COMMAND

;TIME	COMMAND - SET TOTAL TIME FOR ALL BATCH JOBS

DDTIME:	JSP	S,POSNUM	;CHECK IF A NUMBER, GET THE ARGUMENT
	TLNE	T1,-1		;DID IT OVERFLOW
	  JRST	RANGER		;YES, GIVE AN ERROR
	MOVEM	T1,ATIME	;STORE VALUE
	JRST	STSCHG		;END OF THE COMMAND

;EXAMINE COMMAND - LOOK AT THE NEXT 'N' LINES OF THE CTL FILE

DDEXAM:	JSP	S,POSNUM	;NUMBER MUST FOLLOW, GET IT
	JUMPLE	T1,COMCLR	;IGNORE IF ZERO
	PUSHJ	P,LCNTRL	;CALL THE LOOP CONTROLLER
	MOVEM	T1,.JWHO(R)	;SAVE THE COUNT OF LINES
	TLO	F,FL.EXM	;SET EXAMINE REQUESTED
	TLO	R,RL.CMT	;SET INTERVENTION REQUIRED
	POPJ	P,		;RETURN TO THE LOOP CONTROLLER
	IFN	INPCOR,<	;COMMANDS THAT EFFECT THE CORE SETTINGS

;MCORE	COMMAND - SET LARGEST SINGLE JOB

DDMCOR:	JSP	S,POSNUM	;GET THE NUMERIC ARGUMENT
	LSH	T1,1		;CONVERT K TO P
	MOVE	T2,[%NSCMX]	;RANGE GOES TO CORMAX
	GETTAB	T2,
	  MOVSI	T2,1		;ASSUME 256K
	LSH	T2,-^D9		;CONVERT TO P
	CAILE	T1,(T2)
	  JRST	RANGER		;OUT OF RANGE
	PUSHJ	P,CHKMIN	;SEE IF WE NEED THE MINIMUM VALUE
	MOVEM	T1,UCORE	;STORE FOR THE SCHEDULER
	JRST	STSCHG		;END OF THE COMMAND

;CORE	COMMAND - SET TOTAL CORE FOR ALL BATCH JOBS

DDCORE:	JSP	S,POSNUM	;GET THE NUMERIC VALUE
	LSH	T1,1		;CONVERT K TO P
	MOVE	T2,[%ODK4S]	;RANGE GOES TO AVAILABLE VIRTUAL CORE
	GETTAB	T2,
	  MOVEI	T2,^D512	;ASSUME ONLY 256K
	CAILE	T1,(T2)
	  JRST	RANGER		;OUT OF RANGE
	PUSHJ	P,CHKMIN	;SEE IF WE NEED THE MINIMUM VALUE
	MOVEM	T1,ACORE	;STORE FOR SCHEDULER
	JRST	STSCHG		;END OF THIS COMMAND

;ROUTINE TO CHECK IF OPERATOR SET VALUE IS SMALLER THAN MINMAX

CHKMIN:	JUMPE	T1,CPOPJ	;CORE OR MCORE 0 IS OK
	TLNE	T1,-1		;CHECK FOR OVERFLOW
	  MOVEI	T1,-1		;SET TO MAXIMUM POSSIBLE
	CAML	T1,MINMAX	;.GE.MINMAX IS OK
	  POPJ	P,		;LET THE CALLER STORE THE VALUE
	PUSH	P,CH		;SAVE TERMINATION CHARACTER
	OUTSTR	[ASCIZ/System minimum of /]
	MOVE	T1,MINMAX	;GET THE VALUE FOR TYPEOUT
	LSH	T1,-1		;CONVERT TO K FOR TYPEOUT
	PUSHJ	P,TTYDEC	;TYPE THE NUMBER
	OUTSTR	[ASCIZ/K will be used/]
	POP	P,CH		;RESTORE TERMINATION CHARACTER
	MOVE	T1,MINMAX	;GET THE VALUE FOR STORING
	JRST	TTCRLF		;END THE LINE AND RETURN TO CALLER

	> ;END OF THE IFN INPCOR AT THE TOP OF THIS PAGE
;WHAT	COMMAND - TELL THE OPERATOR WHAT A STREAM IS DOING

DDWHAT:	PUSHJ	P,LCNTRL	;LOOP ON THE FOLLOWING
	PUSHJ	P,TTCRLF	;START A NEW LINE
	MOVE	T1,S		;GET THE STREAM NUMBER
	PUSHJ	P,TYBLD2	;OUTPUT 2 DIGITS, LEADING BLANK
	OUTCHR	[" "]		;ADD A BLANK
	HRRZ	J,.JSTAT(R)	;GET THE JOB NUMBER WILL NEED LATER
	MOVE	T1,J		;MAKE A COPY
	JUMPE	T1,[OUTCHR ["*"] ;DON'T KNOW JOB NUMBER
		JRST .+2]	;SKIP TTY OUTPUT
	PUSHJ	P,TYBLD2	;OUTPUT 2 DIGITS, LEADING BLANK
	PUSHJ	P,TTYTAB	;ALIGN THE OUTPUT
	PUSHJ	P,TTYJPN	;TYPE OUT JOB NAME AND PPN
	PUSHJ	P,TTYTAB	;AND ANOTHER TAB
	TLNE	R,RL.OPR	;IS JOB WAITING FOR A RESPONSE
	  JRST	WHAT.1		;YES, OUTPUT A MESSAGE TO THAT EFFECT
	TLNE	R,RL.STP	;IS THE JOB STOPPED
	  JRST	WHAT.5		;YES, TELL HER THAT TOO
	HRL	T1,J		;GET THE JOB NUMBER
	HRRI	T1,.GTPRG	;GET THE PROGRAM RUNNING
	GETTAB	T1,
	  JRST	.+2		;SHOULDN'T FAIL   BUT.....
	PUSHJ	P,TTYSIX	;OUTPUT THE NAME
	PUSHJ	P,TTYTAB	;ADD A TAB
	HRL	A,J		;JOB NUMBER AGAIN
	HRRI	A,.GTSTS	;GET THE JOB STATUS
	GETTAB	A,		;GET IT
	  SETZ	A,		;SHOULDN'T FAIL EITHER
	MOVSI	T1,'^W '	;SEE IF JOB IS IN COMMAND DECODER WAIT
	TLNE	A,(ST.RUN)	;IS JOB RUNNABLE
	  MOVSI	T1,'CW '	;YES, MAYBE OTHER COMMAND WAIT TYPE
	TLNE	A,(ST.CMW)	;WAS IT REALLY COMMAND WAIT
	  JRST	WHAT.2		;YES, OUTPUT PROPER CODE
	MOVSI	T1,'OW '	;NOW LETS LOOK FOR OPERATOR WAIT
	TRNE	A,ST.IRQ	;CHECK INTERVENTION REQUIRED
	  JRST	WHAT.2		;THAT WAS IT, TYPE IT OUT
	MOVSI	T1,'^D '	;DUMP WAIT ?
	TRNE	A,ST.JDC	;WAITING FOR DCORE
	  JRST	WHAT.2		;YEP, TYPE OUT ^D
	MOVSI	T1,'^C '	;IN CASE NO JOB NUMBER
	JUMPGE	A,WHAT.2	;TYPE OUT ^C IF NO STATS OR RN BIT OFF
	LDB	T1,[POINT 5,A,14] ;GET THE WAIT CODE
	IDIVI	T1,3		;SET UP FOR NEXT GETTAB
	HRLI	T1,(T1)		;T2 = ITEM IN RESULT OF NEXT GETTAB
	HRRI	T1,.GTWSN	;CONVERT CODES TO SIXBIT OUTPUT
	GETTAB	T1,		;ASK THE MONITOR FOR THE CODE WORD
	  SETZ	T1,
	LDB	T1,[POINT 12,T1,11  ;STATE 0
		    POINT 12,T1,23  ;STATE 1
		    POINT 12,T1,35](T2) ;STATE 2
	LSH	T1,^D24		;POSITION IT FOR OUTPUT
	CAME	T1,[SIXBIT/SL/]	;JOB IN THE SLEEP QUEUE
	  JRST	WHAT.2		;NO, JUST TYPE OUT STATE CODE
	TRNN	A,ST.CLK	;IS THE A SLEEP TIME
	  MOVSI	T1,'HB '	;NO, SAY HIBERNATE
WHAT.2:	PUSHJ	P,TTYSIX	;OUTPUT IT TO THE OPERATOR
	TLNE	A,(ST.SWP)	;IS THE JOB SWAPPED
	  OUTSTR [ASCIZ/ SW/]	;YES, SAY SO
	PUSHJ	P,TTYTAB	;ALIGN THE OUTPUT
	SKIPE	T1,J		;IS THERE A JOB NUMBER
	  RUNTIM T1,		;YES, GET THE RUNTIME, ELSE OUTPUT 0
	PUSHJ	P,HMSTTY	;OUTPUT HH:MM:SS
	JRST	WHAT.4		;APPEND LAST LINE OF INPUT/OUTPUT
WHAT.5:	OUTSTR	[ASCIZ/Stopped by the operator/]
	JRST	WHAT.4		;APPEND LAST LINE OF OUTPUT
WHAT.1:	OUTSTR	[ASCIZ/Waiting for response/]
WHAT.4:	PUSHJ	P,TTCRLF	;END THE PREVIOUS LINE
	PUSHJ	P,TTYTAB	;START WITH A TAB
	OUTSTR	.JOUTL(R)	;OUTPUT WHATEVERS THERE
	JRST	TTCRLF		;END THE LINE AND RETURN FOR NEXT STREAM
;CURRENT COMMAND - TYPE OUT ALL THE BATCH PARAMETERS AND STATUS

DDCURR:	PUSH	P,CH		;SAVE THE LINE TERMINATOR
	PUSHJ	P,UPDADD	;INCLUDE ANY CHANGES

	IFN	INPCOR,<
	OUTSTR	[ASCIZ/CORE:/]
	SKIPN	T1,ACORE	;GET OPERATOR VALUE IF ANY
	  MOVE	T1,CORPHY	;NONE, GET PHYSICAL USER CORE
	LSH	T1,-1		;CONVERT TO K FOR TYPEOUT
	PUSHJ	P,TTYDEC	;TYPE IT OUT
	OUTSTR	[ASCIZ/K  MCORE:/]
	SKIPN	T1,UCORE	;GET VALUE FOR A SINGLE JOB
	  MOVE	T1,CORMAX	;NONE, USE CORMAX
	LSH	T1,-1		;CONVERT TO K FOR TYPEOUT
	PUSHJ	P,TTYDEC	;TYPE IT OUT ALSO
	OUTCHR	["K"]		;ADD SUFFIX
	PUSHJ	P,TTCRLF	;END OF THIS LINE
	>
	OUTSTR	[ASCIZ/TIME:/]
	PUSHJ	P,CURR.K	;CHECK KSYS TIMER
	 CAMLE	T1,ATIME	;OPERATOR VALUE LESS THAN KSYS TIMER
	  JRST	CUR.01		;YES, TYPE HERS
	PUSHJ	P,CURR.T	;TYPE TIME
	OUTSTR	CHGSTR		;OUTPUT CORRECT MESSAGE
	JRST	CUR.02		;AND GO TO MTIME VALUE
CUR.01:	MOVE	T1,ATIME	;GET THE TIME VALUE
	PUSHJ	P,CURR.T	;TYPE THE VALUE
CUR.02:	OUTSTR	[ASCIZ/ MTIME:/]
	MOVE	T1,UTIME	;GET TIME FOR A SINGLE JOB
	PUSHJ	P,CURR.T	;TYPE IT OUT
	SKIPN	T1,NXTJOB	;IS THERE A PENDING NXTJOB
	  JRST	CURR.1		;NO, SKIP THE OUTPUT
	OUTSTR	[ASCIZ/ NEXT:seq#/]
	PUSHJ	P,TTYDEC	;OUTPUT THE SEQUENCE NUMBER
CURR.1:	PUSHJ	P,TTCRLF	;END OF THIS LINE
	OUTSTR	[ASCIZ/Default subjob:/]
	TLNE	G,GL.ALL	;IS ALL FLAG SET
	  JRST	CURR.A		;YES, OUTPUT ALL
	MOVE	T1,DEFSJB	;NO, GET THE SUBJOB NUMBER
	PUSHJ	P,TTYDEC	;OUTPUT IT
CURR.2:	OUTSTR	[ASCIZ/   MJOB:/]
	MOVE	T1,MJOB		;GET THE MJOB VALUE
	PUSHJ	P,TTYDEC	;OUTPUT IT
	PUSHJ	P,TTCRLF	;END OF THIS LINE
	SKIPN	T1,STACTV	;AND STREAMS ACTIVE
	  JRST	CURR.N		;NO, TYPE OUT NO
	PUSHJ	P,TTYDEC	;OUTPUT THE NUMBER
CURR.3:	OUTSTR	[ASCIZ/ streams active/]
	PUSHJ	P,TTCRLF	;END OF THIS LINE
	TLNE	G,GL.STA	;ARE WE STARTED
	  JRST	CURR.5		;YES, SKIP THIS OUTPUT
	OUTSTR	[ASCIZ/Waiting for a "START" command/]
CURR.4:	PUSHJ	P,TTCRLF	;END THIS LINE
CURR.E:	POP	P,CH		;RESTORE THE TERMINATOR
	JRST	COMCLR		;END OF THE CURRENT COMMAND
CURR.5:	TLNN	G,GL.SSH	;IS STOP SCHEDULING SET
	  JRST	CURR.6		;NO, SKIP THIS OUTPUT ALSO
	OUTSTR	[ASCIZ/Batch will /]
	MOVE	T1,[SIXBIT/EXIT/] ;ASSUME SET FOR AN EXIT
	TLNN	G,GL.EXI	;IS EXIT SET
	  MOVE	T1,[SIXBIT/RESET/] ;NO, MUST BE A RESET
	PUSHJ	P,TTYSIX	;TYPE OUT WHAT WE WILL DO
	OUTSTR	[ASCIZ/ when active jobs finish/]
	JRST	CURR.4		;OUTPUT CR-LF AND EXIT
CURR.6:	PUSHJ	P,NJNCHK	;SEE IF JOB CAPACITY EXCEEDED
	  SKIPA			;YES, T1=WHEN TO TRY AGAIN
	JRST	CURR.9		;NO, SKIP THIS OUTPUT
	MOVMS	T1		;MAKE POSITIVE
	IDIVI	T1,^D1000	;CONVERT TO SECONDS
	IDIVI	T1,^D60		;MINUTES IN T1, SECONDS IN T2
	PUSH	P,T2		;SAVE SECONDS
	OUTSTR	[ASCIZ/No job numbers or PTYs, will try again in /]
	JUMPE	T1,CUR.10	;LESS THAN 1 MINUTE
	PUSHJ	P,TTYDEC	;NO, OUTPUT NUMBER OF MINUTES
	OUTSTR	[ASCIZ/ min /]
CUR.10:	POP	P,T1		;RESTORE SECONDS
	JUMPE	T1,CURR.4	;WHOLE MINUTES, END THE LINE
	PUSHJ	P,TTYDEC	;TYPE SECONDS
	OUTSTR	[ASCIZ/ sec/]
	JRST	CURR.4		;AND DONE
CURR.9:	PUSHJ	P,CURR.S	;CHECK THE SCHED BITS
	JRST	CURR.E		;EXIT FROM THE CURRENT COMMAND

CURR.T:	CAIE	T1,777777	;IS THERE ANY EFFECTIVE LIMIT
	  JRST	TTYDEC		;YES, OUTPUT IT
	OUTSTR	[ASCIZ/no limit   /]
	POPJ	P,

CURR.A:	OUTSTR	[ASCIZ/ALL/]	;OUTPUT ALL IF DEFAULT SUBJOB IS ALL
	JRST	CURR.2		;RESUME WITH THE OUTPUT

CURR.N:	OUTSTR	[ASCIZ/NO/]	;OUTPUT NO IF THERE AREN'T ANY ACTIVE SUBJOBS
	JRST	CURR.3		;RESUME WITH NORMAL OUTPUT
IFN FTUUOS,<
CURR.S:	MOVE	T1,[%CNSTS]	;GET THE STATES WORD
	GETTAB	T1,		;GET IT
	  POPJ	P,		;OH WELL!!
	TRNN	T1,ST%NRL+ST%NLG  ;CHECK THE BITS QUASAR DOES
	  POPJ	P,		;OK TO RUN JOBS
	OUTSTR	[ASCIZ/"SET SCHED" bits prohibit scheduling of new jobs/]
	JRST	TTCRLF		;END THE LINE AND RETURN

CURR.K:	MOVE	T1,[%NSKTM]	;KSYS TIMER
	GETTAB	T1,		;GET IT
	  JRST	CPOPJ1		;OH WELL!!
	JUMPE	T1,CPOPJ1	;JUMP IF NOT SCHEDULED
	IMULI	T1,^D60		;CONVERT TO SECONDS REMAINING
	SKIPG	T1		;IS IT ALREADY OVER
	  SETZ	T1,		;YES, TYPE TIME:0
	POPJ	P,		;AND RETURN
CHGSTR:	ASCIZ/(Changed by "KSYS")  /
>  ;END OF IFN FTUUOS

IFN FTJSYS,<
CURR.S:	MOVX	T1,.SFPTY	;CHECK IF PTY LOGINS ARE ALLOWED
	TMON			;TEST MONITOR SETTINGS
	JUMPN	T2,CPOPJ	;JUMP IF OK TO RUN JOBS
	OUTSTR	[ASCIZ/PTY LOGINs are not allowed/]
	JRST	TTCRLF		;END THE LINE AND RETURN

CURR.K:	MOVE	T1,[SIXBIT/DWNTIM/]  ;GET SYSTEM TABLE NAME
	SYSGT			;GET NUMBER AND ENTRY 0
	JUMPGE	T2,CPOPJ1	;JUMP IF THE TABLE ISN'T THERE
	JUMPE	T1,CPOPJ1	;JUMP IF NOT S CHEDULED
	MOVE	T2,T1		;COPY THE TIME OF SHUTDOWN
	GTAD			;GET CURRENT TIME
	EXCH	T2,T1		;REVERSE THE ORDER
	SUB	T1,T2		;COMPUTE TIME REMAINING
	IDIVI	T1,3		;APPROXIMATE SECONDS REMAINING
	SKIPG	T1		;IS IT ALREADY OVER
	  SETZ	T1,		;YES, TYPE TIME:0
	POPJ	P,		;OUTPUT IT
CHGSTR:	ASCIZ/(Changed by "CEASE")  /
>  ;END OF IFN FTJSYS
;OPERATOR COMMAND - RESPOND TO A JOB IN DIALOGUE MODE

DDOPER:	PUSHJ	P,GTOPER	;GET AN OPERATOR RESPONSE LINE

;WITH LINE STORED AS INTERMEDIATE TEXT, NOW CALL THE LOOP CONTROLLER

	PUSHJ	P,LCNTRL	;REPEAT FOR ALL SPECIFIED SUBJOBS
	TLNE	R,RL.DIA	;IS THE JOB IN DIALOGUE MODE
	TLNN	R,RL.OPR	;YES, IS THE JOB WAITING
	  POPJ	P,		;NO, IGNORE THE CALL
	TLZ	R,RL.OPR!RL.DIA	;CLEAR SOME FLAGS AFTER RESPONSE
OPRBLT:	HRRI	A,.JOPER(R)	;MOVE INTERMEDIATE TEXT TO THE DATA BASE
	HRLI	A,OPRLIN	;NECESSARY IF SPECIFIED "ALL"
	BLT	A,.JOPER+^D15(R) ;MOVE TO THE DATA BASE FOR THIS STREAM
	POPJ	P,		;RETURN TO THE LOOP CONTROLLER

;TELL COMMAND - ENTER A COMMENT ONTO THE JOBS LOG FILE

DDTELL:	PUSHJ	P,GTOPER	;GET THE COMMENT
	PUSHJ	P,LCNTRL	;CALL THE LOOP CONTROLLER AFTER THE COMMENT
	MOVE	T1,[SIXBIT/TELL/] ;NAME OF THIS COMMAND
TELL.1:	MOVEM	T1,.JWHO(R)	;SAVE TO IDENTIFY THE COMMENT
	TLO	R,RL.CMT	;MARK A COMMENT IS READY
	JRST	OPRBLT		;MOVE TO JOB DATA BASE AND RETURN

;STOP COMMAND - HALT THE SUBJOB

DDSTOP:	PUSHJ	P,GTOPER	;GET ANY ASSOCIATED COMMENTS
	PUSHJ	P,LCNTRL	;CALL THE LOOP CONTROLLER FOR ALL SPECIFIED JOBS
	TLNE	R,RL.OPR!RL.STP!RL.KJB ;STOPPED, WAITING, OR ON THE WAY OUT
	  POPJ	P,		;YES, DON'T STOP TWICE
	MOVE	T1,[SIXBIT/STOP/] ;THIS COMMAND
	JRST	TELL.1		;SET UP NAME AND MOVE COMMENT TO JOB DATA BASE

;GO COMMAND - CONTINUE AFTER STOPPED

DDGO:	PUSHJ	P,GTOPER	;GET ANY COMMENT FOR THE USER
	PUSHJ	P,LCNTRL	;CALL THE LOOP CONTROLLER
	TLZN	R,RL.STP!RL.OPR	;CLEAR STOP, WAS IT SET
	  POPJ	P,		;NO, RETURN
	MOVE	T1,[SIXBIT/GO/]	;NAME OF THIS COMMAND
	JRST	TELL.1		;MOVE COMMENT, SET INTERVENTION, STORE NAME
;KILL COMMAND - CANCEL THE SPECIFIED JOB

DDKILL:	TRO	F,FR.RSC	;ALREADY HAVE A CHARACTER
	PUSHJ	P,GETSIX	;GET THE KILL ARGUMENT
	JUMPE	T1,[SETZ C,	;NONE SPECIFIED, USE FIRST COMMAND IN TABLE
		JRST KILL.1]	;AND PRETEND ONE FORND
	MOVE	A,[-NKILLR,,KILLCM] ;SET UP FOR TABLE SEARCH
	PUSHJ	P,TABSRC	;SEARCH FOR THE COMMAND IN T1
	  JRST	COMERR		;BAD COMMAND
	  JRST	COMERR		;SAME HERE
KILL.1:	PUSHJ	P,GTOPER	;GET ANY OPERATOR COMMENTS
	PUSHJ	P,LCNTRL	;NOW LOOP FOR ALL SPECIFIED SUBJOBS
	TLNE	R,RL.LGI!RL.KJB	;ON THE WAY IN OR THE WAY OUT
	  POPJ	P,		;YES, CANNOT KILL IT NOW
	TLO	F,FL.KIL	;SET KILL REQUEST
	TLO	R,RL.CMT	;SET INTERVENTION REQUESTED
	MOVE	T1,KILLCM(C)	;GET THE FULL ARGUMENT NAME
	MOVEM	T1,.JWHO(R)	;STORE FOR THE KILL PROCESSOR
	JRST	OPRBLT		;MOVE THE COMMENT (IF ANY) AND RETURN TO LOOP

KILLCM:	SIXBIT	/ERROR/		;KILL WITH FULL ERROR RECOVERY
	SIXBIT	/NERROR/	;KILL WITH NO ERROR RECOVERY
	SIXBIT	/FLUSH/		;KILL WITH NO ERROR RECOVERY, NO OUTPUT
NKILLR==.-KILLCM		;NUMBER OF KILL COMMANDS

;REQUEUE COMMAND - PUT THIS JOB BACK INTO THE QUEUE

DDREQU:	SETZB	A,B		;CLEAR REQUEUE TIME IN CASE NONE GIVEN
	TRO	F,FR.RSC	;ALREADY HAVE A CHARACTER
	PUSHJ	P,GETNUM	;GET THE HH PART (IF THERE)
	  JRST	ILLNUM		;BAD COMMAND
	MOVE	B,T1		;SAVE FIRST PART AS MINUTES
	CAIE	CH,":"		;WAS IT HH:MM
	  JRST	REQU.1		;NO, REGS ARE SET RIGHT
	PUSHJ	P,GETNUM	;GET REAL MM
	  JRST	ILLNUM		;BAD COMMAND
	MOVE	A,B		;MOVE FIRST SET AS HOURS
	MOVE	B,T1		;MOVE THIS PART AS MINUTES
REQU.1:	IMULI	A,^D60		;CONVERT HOURS TO MINUTES
	ADD	A,B		;INCLUDE MINUTES
	PUSHJ	P,LCNTRL	;NOW LOOP FOR ALL SUBJOBS SPECIFIED
	TLNE	R,RL.LGI!RL.KJB	;ON THE WAY IN OR OUT
	  POPJ	P,		;YES, CANNOT REQUEUE IT NOW
	MOVEM	A,.JWHO(R)	;SAVE REQUEUE TIME (COULD BE ZERO)
	TLO	F,FL.REQ	;SET REQUEUE REQUESTED
	TLO	R,RL.CMT	;SET INTERVENTION REQUESTED
	POPJ	P,		;LET THE DISPATCHER FIGURE THE REST
;ROUTE COMMAND - CHANGE QUASAR'S ROUTING INFORMATION

DDROUT:	JSP	S,POSOCT	;GET OCTAL ARGUMENT
	TLNN	T1,-1		;OVERFLOW
	 CAILE	T1,^D63		;OR TOO LARGE
	  JRST	RANGER		;YES, RANGE ERROR
	STORE	T1,QSRMSG+ROU.ST,RO.ORG  ;ORIGINAL STATION (INDICES)
	TRO	F,FR.RSC	;ALREADY HAVE A CHARACTER
	PUSHJ	P,GETSIX	;GET NEXT WORD
	CAME	T1,[SIXBIT/TO/]	;BUZZ WORD MUST BE PRESENT
	  JRST	ARGERR		;WASN'T
	JSP	S,POSOCT	;ANOTHER OCTAL NUMBER
	TLNN	T1,-1		;OVERFLOW
	 CAILE	T1,^D63		;OR TOO LARGE
	  JRST	RANGER		;YES, RANGE ERROR
	STORE	T1,QSRMSG+ROU.ST,RO.NEW  ;AS NEW ROUTING FOR ORIGINAL
	MOVX	A,<INSVL.(ROU.SZ,MS.CNT)!INSVL.(.QOROU,MS.TYP)!MS.ACK>
ROUT.1:	MOVEM	A,QSRMSG+.MSTYP  ;STORE LENGTH AND TYPE OF MESSAGE
	MOVEI	A,QSRMSG	;POINT TO IT
	PUSHJ	P,SNDQSR##	;INFORM QUASAR OF OPERATORS CHANGE
	JRST	COMCLR		;END OF THE ROUTE COMMAND

;INFORMATION COMMAND - DISPLAY QUASAR'S INTERNAL COUNTERS

DDINFO:	MOVX	A,<INSVL.(COU.SZ,MS.CNT)!INSVL.(.QOCOU,MS.TYP)!MS.ACK>
	JRST	ROUT.1		;SEND TO QUASAR, GET ANSWER IN SCHEDULER
;SUBROUTINE TO GET THE OPERATOR RESPONSE AND STORE IN INTERMEDIATE LINE

GTOPER:	MOVE	A,[POINT 7,OPRLIN] ;POINTER TO INTERMEDIATE TEXT
	SETZ	B,		;COUNT OF CHARACTERS
	TRO	F,FR.RSC	;RE-GET LAST CHARACTER
OPER.1:	PUSHJ	P,GETONE	;GET A CHARACTER
	  JRST	OPER.E		;A TERMINATOR
	  JRST	OPER.S		;A SPECIAL
	  JFCL			;INCLUDE NUMBERS
OPER.2:	AOS	B		;BUMP CHARACTER COUNT
	IDPB	CH,A		;STORE THE NEW CHARACTER
	CAIGE	B,^D75		;RESTRICTED LENGTH
	  JRST	OPER.1		;OK, GET SOME MORE
OPER.3:	MOVEI	B,CHR.CR	;OVER THE LIMIT, INSERT A CR-LF-NULL
	IDPB	B,A		;STORE THE CR
	MOVEI	B,CHR.LF	;AND THE LINE FEED
	IDPB	B,A		;STORE
OPER.4:	SETZ	B,		;GET THAT NULL BYTE
	IDPB	B,A		;STORE THAT
	POPJ	P,		;RETURN TO CALLER

;SPECIAL CHECKS FOR ACTION CHARACTERS

OPER.E:	CAIN	CH,CHR.LF	;LINE TERMINATOR, IS IT A LINE FEED
	  JRST	OPER.3		;YES, INCLUDE CR FIRST
	IDPB	CH,A		;STORE THE CHARACTER
	JRST	OPER.4		;AND STORE THE NULL BYTE

OPER.S:	CAIN	CH," "		;SPECIAL, WAS IT A BLANK
	  JUMPE	B,OPER.1	;YES, SKIP LEADING BLANKS
	JRST	OPER.2		;INCLUDE IF AFTER ANY OTHER CHARACTER
;SUBROUTINE TO POSITION THE COMMAND AT A NUMBER FIELD AND RETURN THE ARGUMENT
;	ENTER AT POSOCT FOR OCTAL INPUT

POSOCT:	SKIPA	T2,[^D8]	;HERE FOR OCTAL CONVERSION
POSNUM:	MOVEI	T2,^D10		;FOR GETRDX LATER
	TRO	F,FR.RSC	;HAVE A CH
POSN.1:	PUSHJ	P,GETONE	;GET A CHARACTER
	  JRST	ARGERR		;CANNOT BE A TERMINATOR IF LOOKING FOR A NUMBER
	  JRST	POSN.2		;A SPECIAL, SEE IF A BLANK
	  SKIPA			;A NUMBER
	JRST	ILLNUM		;ILLEGAL LETTER IN NUMBER FIELD
	TRO	F,FR.RSC	;LET GETNUM RE-GET THIS CHARACTER
	PUSHJ	P,GETRDX	;GET THE VALUE
	  JRST	ILLNUM		;BAD NUMBER FORMAT
	JRST	(S)		;RETURN TO MY CALLER
POSN.2:	CAIE	CH," "		;SKIP OVER ANY BLANKS HERE
	  JRST	ARGERR		;NOT A BLANK, GIVE ERROR
	JRST	POSN.1		;SKIP THIS BLANK

;SUBROUTINE TO GET A NUMBER FROM THE OPERATOR COMMAND
;	ENTER AT GETRDX WITH RADIX IN T2

GETNUM:	MOVEI	T2,^D10		;HERE FOR RADIX 10 INPUT
GETRDX:	SETZ	T1,		;EVENTUAL NUMBER
	TRZ	F,FR.NBL	;CLEAR LEADING BLANK FOUND FLAG
GETN.1:	PUSHJ	P,GETONE	;GET A CHARACTER
	  JRST	CPOPJ1		;STOP ON A TERMINATOR
	  JRST	GETN.3		;A SPECIAL, LOOK FOR BLANKS
	  JRST	GETN.2		;A NUMBER
	POPJ	P,		;ILLEGAL CHARACTER IN THE FIELD
GETN.2:	TRO	F,FR.NBL	;FOUND A NON-BLANK CHARACTER
	CAIL	CH,"0"(T2)	;RADIX RANGE CHECK
	  POPJ	P,		;BAD DIGIT IN FIELD
	IMULI	T1,(T2)		;ACCUMULATE THE NUMBER
	ADDI	T1,-"0"(CH)	;INCLUDE THE NEW DIGIT
	JRST	GETN.1		;GET MORE CHARACTERS
GETN.3:	TRNN	F,FR.NBL	;NON-BLANK ALREADY FOUND
	 CAIE	CH," "		;NO, IS THIS A SPACE
	  JRST	CPOPJ1		;NON SPACE OR A BLANK IS A TERMINATOR
	JRST	GETN.1		;IGNORE THIS LEADING BLANK
;SUBROUTINE TO SET UP LOOP CONTROL FOR COMMANDS THAT USE A SUBJOB
;CODE FOLLOWING THE PUSHJ WILL BE EXECUTED FOR A SPECIFIC SUBJOB
;OR ALL ACTIVE SUBJOBS.  CODE IS PUSHJ'ED TO SO SHOULD CONTAIN A POPJ AT THE END

LCNTRL:	PUSH	P,CH		;SAVE LAST CHARACTER OF COMMAND
	SKIPN	STACTV		;ANY STREAMS ACTIVE
	  JRST	LCNT.6		;NO, TELL THE OPERATOR
	MOVEI	S,1		;START AT STREAM 1
	TLNN	G,GL.ALL	;UNLESS SPECIFIC SUBJOB WAS REQUESTED
	  MOVE	S,DEFSJB	;THERE WAS ONE, USE THAT INSTEAD
LCNT.3:	SKIPGE	R,BASTBL-1(S)	;GET FLAGS, CHECK IF ACTIVE
	  JRST	LCNT.4		;STREAM IS ACTIVE
	TLNE	G,GL.ALL	;INACTIVE STREAM, WAS ALL SPECIFIED
	  JRST	LCNT.5		;YES, SKIP OVER THIS STREAM
	MSGTTY	[ASCIZ/Subjob is not active/]
	JRST	LCNT.2		;END OF THE COMMAND
LCNT.4:	MOVE	F,.JREGS+F(R)	;GET THE OTHER FLAG REG
	PUSHJ	P,@-1(P)	;CALL THE PROCESS FOR THIS STREAM
	MOVEM	R,BASTBL-1(S)	;STORE FLAGS IN CASE THEY CHANGED
	MOVEM	F,.JREGS+F(R)	;STORE NEW SETTINGS
LCNT.5:	TLNN	G,GL.ALL	;WAS ALL SPECIFIED
	  JRST	LCNT.2		;NO, END OF THE COMMAND
	CAMGE	S,HIACTV	;PASSED OVER ALL THE ACTIVE STREAMS
	  AOJA	S,LCNT.3	;NO, DO THE NEXT STREAM
	JRST	LCNT.2		;END OF THE COMMAND
LCNT.6:	OUTSTR	[ASCIZ/No subjobs are active/]
	PUSHJ	P,TTCRLF	;END THE LINE
LCNT.2:	POP	P,CH		;RESTORE LAST CHARACTER
	POP	P,(P)		;REMOVE CALL
	SETZ	F,		;CLEAR ANY LEFT OVER FLAGS
	JRST	COMCLR		;END OF THE COMMAND
	SUBTTL	Common Routines for BATCON & BATOPR

;BATCON UUO PROCESSOR

UUOCON:	HLRZ	IO2,.JBUUO##	;GET THE OPCODE
	LSH	IO2,-^D9	;POSITION IT
	CAILE	IO2,UUOCNT	;NUMBER OF KNOWN UUOS
	  JRST	UUOERR		;ILLEGAL UUO ?
	JRST	@UUOTBL-1(IO2)	;DISPATCH THE UUO
UUOTBL:	JRST	UUOTXT		;OPCODE 001 - ASCIZ  TEXT TO THE LOG FILE
	JRST	UUOSND		;OPCODE 002 - ASCIZ  TEXT TO THE JOB
	JRST	UUOSIX		;OPCODE 003 - SIXBIT TEXT TO THE LOG FILE
	JRST	UUOSN6		;OPCODE 004 - SIXBIT TEXT TO THE JOB
	JRST	UUOMTY		;OPCODE 005 - ERROR MESSAGE TO THE OPERATOR
	JRST	UUOMLG		;OPCODE 006 - ERROR MESSAGE TO THE LOG FILE
	JRST	UUOIDN		;OPCODE 007 - IDENTIFIER TO THE LOG FILE
	JRST	UUOCHR		;OPCODE 010 - CHARACTER TO THE TTY
	JRST	UUOSTR		;OPCODE 011 - STRING TO THE TTY
UUOCNT==.-UUOTBL		;NUMBER OF KNOWN UUOS

UUOERR:	OUTSTR	[ASCIZ/? Illegal BATCON UUO/]
EXIT..:	MONRT.			;RETURN TO THE MONITOR
	JRST	.-1		;CAN'T CONTINUE FROM THAT
;SUBROUTINE TO CREATE A MASK INTO AC B FOR THE COMMAND IN AC T1

MASKIT:	MOVE	T2,T1		;COPY THE COMMAND
	SETO	B,		;EVENTUAL MASK (COMPLEMENT FORM)
	LSH	B,-6		;SHIFT THE MASK
	LSH	T2,6		;SHIFT THE COMMAND THE OTHER WAY
	JUMPN	T2,.-2		;CONTINUE UNTIL HAVE SHIFTED ALL THE CHARACTERS
	POPJ	P,		;RETURN WITH MASK IN B

;SUBROUTINE TO CHECK IF CHARACTER IN CH IS A LINE TERMINATOR

COMTRM:	CAIG	CH,CHR.FF	;LOOK FOR PAPER MOTION CHARACTERS
	CAIGE	CH,CHR.LF
	  SKIPA			;NO, LOOK FOR OTHERS
	POPJ	P,		;GIVE TERMINATOR RETURN
	CAIE	CH,CHR.CG	;^G
	CAIN	CH,CHR.CZ	;^Z
	  POPJ	P,		;THEY ARE TERMINATORS
	CAIE	CH,CHR.A1	;IS IT THE STANDARD ALTMODE
	CAIN	CH,CHR.CC	;^C
	  POPJ	P,		;RETURN
	JRST	CPOPJ1		;NOT ONE OF THE ABOVE, NOT A TERMINATOR

;SUBROUTINE TO GET A SIXBIT COMMAND INTO T1

GETSIX:	MOVE	T2,[POINT 6,T1]	;POINTER TO THE STRING
	SETZ	T1,		;EVENTUAL DESTINATION
GETS.1:	PUSHJ	P,GETONE	;GET A CHARACTER
	  POPJ	P,		;STOP AT A LINE TERMINATOR
	  JRST	GETS.2		;SPECIAL, CHECK FOR BLANKS
	  JRST	GETS.4		;DON'T INCLUDE LEADING NUMBERS
GETS.3:	SUBI	CH," "		;CONVERT TO SIXBIT
	TLNE	T2,770000	;ALREADY HAVE ENOUGH
	  IDPB	CH,T2		;NO, INCLUDE THIS CHARACTER
	JRST	GETS.1		;GET MORE INPUT
GETS.2:	CAIN	CH," "		;IS IT A BLANK
	  JUMPE	T1,GETS.1	;YES, IGNORE LEADING BLANKS
	TRNE	F,FR.%SG	;ARE % SIGNS VALID CHARACTERS
	CAIE	CH,"%"		;YES, WAS IT ONE
	  POPJ	P,		;RETURN IF SPECIAL OR BLANK AS A TERMINATOR
	JRST	GETS.3		;INCLUDE THE % SIGN
GETS.4:	JUMPE	T1,CPOPJ	;STOP IF THE NUMBER IS FIRST
	JRST	GETS.3		;INCLUDE IF AFTER THE FIRST
;SUBROUTINE TO GET A CHARACTER FORM THE COMMAND LINE
;INSTRUCTION IN COMFIL DETERMINES HOW TO GET ONE INTO CH
;CALL IS:
;	PUSHJ	P,GETONE
;	  HERE IF A LINE TERMINATOR
;	  HERE IF A SPECIAL CHARACTER
;	  HERE IF A NUMBER
;	  HERE IF A LETTER

GETONE:	TRZE	F,FR.RSC	;CALLER ALREADY HAVE CH
	  JRST	CLASSF		;YES, CLASSIFY IT AND GIVE IT BACK
	XCT	COMFIL		;GET A CHARACTER SOMEHOW
	JUMPE	CH,GETONE	;THROUGH AWAY NULLS
	CAIN	CH,CHR.CR	;AND IGNORE CARRIAGE RETURNS
	  JRST	GETONE
	CAIN	CH,CHR.HT	;A TAB
	  MOVEI	CH," "		;YES, CONVERT TABS TO BLANKS
CLASSF:	CAIE	CH,CHR.CR	;CARRIAGE RETURN IF FROM BATCON LABEL PROCESSOR
	PUSHJ	P,COMTRM	;IS IT A LINE TRMINATOR
	  POPJ	P,		;YES, RETURN NOW
	CAIG	CH,"9"
	CAIGE	CH,"0"		;IS IT A DIGIT
	  SKIPA
	JRST	CPOPJ2		;YES, GIVE APPROPRIATE RETURN
	CAIG	CH,172		;LOWER CASE "Z"
	CAIGE	CH,141		;LOWER CASE "A"
	  SKIPA
	SUBI	CH," "		;MAKE UPPER CASE
	CAIG	CH,"Z"
	CAIGE	CH,"A"		;IS IT A LETTER
	  JRST	CPOPJ1		;NO, MUST BE A SPECIAL
CPOPJ3:	AOS	(P)		;LETTER EXIT
CPOPJ2:	AOS	(P)		;DIGIT EXIT
CPOPJ1:	AOS	(P)		;SPECIAL CHARACTER EXIT
CPOPJ:	POPJ	P,		;LOTS OF SKIP RETURNS

;ROUTINES TO OUTPUT SINGLE CHARACTERS TO THE OPERATOR

TTYTAB:	SKIPA	CH,[CHR.HT]	;OUTPUT A TAB
TTYCOL:	MOVEI	CH,":"		;OUTPUT A COLON
TTYCHR:	OUTCHR	CH		;OUTPUT IT
	POPJ	P,		;AND RETURN

TTYCMA:	SKIPA	CH,[","]	;GET A COMMA
TTYPER:	MOVEI	CH,"."		;OR A PERIOD
	JRST	TTYCHR

;UUO LEVEL ROUTINE TO OUTPUT AN ERROR MESSAGE TO THE OPERATOR

UUOMTY:	PUSH	P,.JBUUO##	;ALLOW RECURSION
	OUTSTR	[ASCIZ/? /]	;START WITH A QUESTION MARK
	POP	P,.JBUUO##	;PUT IT BACK
	OUTSTR	@.JBUUO##	;APPEND THE MESSAGE
	JRST	TTCRLF		;APPEND A CR-LF AND RETURN TO THE PROGRAM
;ROUTINE TO OUTPUT SIXBIT AC 'T1' TO THE OPERATOR

TTYSIX:	MOVE	T2,[POINT 6,T1]	;SET BYTE POINTER
	ILDB	CH,T2		;GET ONE FROM T1
	JUMPE	CH,CPOPJ	;STOP ON A BLANK
	MOVEI	CH," "(CH)	;MAKE ASCII
	OUTCHR	CH		;OUTPUT IT
	TLNN	T2,770000	;DID WE GET ALL SIX
	  POPJ	P,		;YES, ALL DONE
	JRST	TTYSIX+1	;OUTPUT SOME MORE

;SUBROUTINE TO OUTPUT JOB INFORMATION TO THE OPERATOR

TTYALL:	PUSHJ	P,TTYJPN	;TYPE OUT JOB NAME AND PPN
	OUTSTR	[ASCIZ/  /]	;ALIGN AND FALL INTO SUBJOB, JOB NUMBER
SJBINF:	PUSHJ	P,TTYSJB	;TYPE OUT SUBJOB NUMBER TO THE OPERATOR
	OUTSTR	[ASCIZ/Job #/]
	HRRZ	T1,J		;GET MONTIOR JOB NUMBER
	PUSHJ	P,TTYDEC	;OUTPUT THAT ALSO
TTCRLF:	OUTSTR	[ASCIZ/
/]
	POPJ	P,

;SUBROUTINE TO TYPE OUT SUBJOB NUMBER TO THE OPERATOR

TTYSJB:	OUTSTR	[ASCIZ/Subjob #/]
	MOVE	T1,S		;COPY STREAM NUMBER
	PUSHJ	P,TTYDEC	;OUTPUT AS DECIMAL
	OUTSTR	[ASCIZ/  /]	;ALIGN THE OUTPUT
	POPJ	P,		;AND RETURN

;SUBROUTINE TO TYPE OUT hh:mm:SS FROM T1 = MILLISECONDS

HMSTTY:	IDIVI	T1,^D60000	;T2=MILLISECONDS
	PUSH	P,T2		;SAVE MILLISECONDS
	IDIVI	T1,^D60		;T1=HOURS, T2=MINUTES
	PUSH	P,T2		;SAVE MINUTES
	JUMPE	T1,HMST.1	;SKIP OUTPUT IF HOURS = 0
	PUSHJ	P,TYBLD2	;OUTPUT 2 DIGITS AS HH:MM:SS (LEADING BLANK)
	PUSHJ	P,TTYCOL	;ADD A COLON
	SKIPA	T2,[TYDEC2]	;LEADING 0 IF THERE ARE HOURS
HMST.1:	MOVEI	T2,TYBLD2	;ELSE LEADING BLANK
	POP	P,T1		;RESTORE MINUTES
	PUSHJ	P,(T2)		;AND CALL OUTPUT ROUTINE
	PUSHJ	P,TTYCOL	;ADD A COLON
	POP	P,T1		;RESTORE MILLISECONDS
	IDIVI	T1,^D1000	;CONVERT TO SECONDS

;SUBROUTINES TO TYPE OUTPUT WITH A LEADING BLANK OR LEADING ZERO

TYDEC2:	SKIPA	CH,["0"]	;ENTRY FOR LEADING ZERO
TYBLD2:	MOVEI	CH," "		;ENTRY FOR LEADING BLANK
	CAIG	T1,^D9		;IS IT A SINGLE DIGIT
	  OUTCHR CH		;YES, OUTPUT THE SPACE OR ZERO
	JRST	TTYDEC		;NO TYPE T1 AS DECIMAL AND RETURN
;SUBROUTINE TO TYPE OUT JOB NAME AND USER ID TO THE OPERATOR

TTYJPN:	MOVE	T1,Q.JOB(R)	;GET THE JOB NAME
	PUSHJ	P,TTYSIX	;OUTPUT THAT

IFN FTUUOS,<
	OUTCHR	["["]		;GOING TO OUTPUT THE PPN
	HLRZ	T1,Q.PPN(R)
	PUSHJ	P,TTYOCT	;OUTPUT THE PROJECT
	PUSHJ	P,TTYCMA	;AND A COMMA
	HRRZ	T1,Q.PPN(R)	;GET THE PROGRAMMER NUMBER
	PUSHJ	P,TTYOCT	;AND OUTPUT THAT
	OUTCHR	["]"]		;ADD CLOSURE
>  ;END IFN FTUUOS

IFN FTJSYS,<
	OUTSTR	[ASCIZ / User:/]
	OUTSTR	Q.USNM(R)	;AND TYPE USER NAME
>  ;END IFN FTJSYS

	OUTSTR	[ASCIZ / Seq #/] ;ADD THE SEQUENCE NUMBER
	LOAD	T1,Q.SEQ(R),EQ.SEQ ;GET IT
	PUSHJ	P,TTYDEC	;TYPE IT
	POPJ	P,

;SUBROUTINE TO DO A TABLE LOOKUP FOR THE COMMAND IN T1
;ON CALL  A = XWD -COUNT , TABLE ADDRESS
;RETURNS  CPOPJ  IF NOT FOUND
;	  CPOPJ1 IF AMBIGUOUS
;	  CPOPJ2 IF A GOOD COMMAND  C = RELATIVE INDEX INTO THE TABLE

;CLOBBERS AC'S T2,A,B,C,D

TABSRC:	PUSHJ	P,MASKIT	;CREATE A MASK IN B
	SETZ	C,		;CLEAR FOUND ONE INDICATOR
	MOVEI	D,(A)		;SAVE TABLE START ADDRESS
TABS.1:	MOVE	T2,(A)		;GET ONE FROM THE TABLE
	CAMN	T1,T2		;AN EXACT MATCH
	  JRST	[MOVEI C,(A)	;YES, COMPUTE OFFSET
		JRST TABS.3]	;AND EXIT NOW
	ANDCM	T2,B		;MASK TO AS MANY CHARS AS IN T1
	CAME	T1,T2		;FOUND A MATCH
	  JRST	TABS.2		;NO, CONTINUE SEARCH
	JUMPN	C,CPOPJ1	;IF ALREADY FOUND ONE, GIVE AMBIGUOUS RETURN
	MOVEI	C,(A)		;SAVE ADDRESS OF THIS ONE
TABS.2:	AOBJN	A,TABS.1	;LOOK FOR A MATCH
	JUMPE	C,CPOPJ		;RETURN IF NEVER FOUND ONE
TABS.3:	SUBI	C,(D)		;COMPUTE RELATIVE OFFSET
	JRST	CPOPJ2		;GIVE LOTS OF SKIP RETURNS
;HERE TO SEE IF TIMER HAS EXPIRED FOR 'JOB CAPACITY EXCEEDED'
;RETURNS VIA CPOPJ IF STILL TIME TO GO, T1 = -(MS.REMAINING)
;	 VIA CPOPJ1 IF OK TO SCHEDULE JOBS

NJNCHK:	TLNN	G,GL.NJN	;HAVE WE NOTICED NO JOB NUMBERS
	  JRST	CPOPJ1		;NO, AVOID THE CHECK
	PUSHJ	P,GETMST	;GET CURRENT TIME (MS.)
	SUB	T1,NJNTIM	;TIME WHEN NOTICED
	MOVMS	T1		;JUST THE ABSOLUTE VALUE
	SUB	T1,[NJNINT*^D60*^D1000] ;OVER THE INTERVAL
	JUMPL	T1,CPOPJ	;NO, GIVE CANNOT SCHEDULE RETURN
	TLZ	G,GL.NJN	;CLEAR SOME FLAGS
	TLO	G,GL.STC	;OK NOW CHANGES OUR STATUS
	JRST	CPOPJ1		;GIVE GOOD RETURN

;SUBROUTINE TO OUTPUT CORRECT OPERATOR PROMPT CHARACTER

OPRSTA:	MOVEI	T1,"!"		;ASSUME STARTED
	TLNN	G,GL.STA	;WAS THAT A GOOD ASSUMPTION
	  MOVEI	T1,"/"		;NO, USE SLASH INSTEAD
	OUTCHR	T1		;PROMPT OPERATOR
	POPJ	P,		;AND RETURN


;SUBROUTINE TO SPECIFY SJJB # FOR OPERATOR PROMPT.  CALL WITH T1
;CONTAINING ADR OF ASCIZ STRING, GENERATES:
;	(B-)#-STRING

SJBLIN:	PUSH	P,T1		;SAVE ADDRESS OF STRING
	OUTSTR	[OPRPST]	;FOR OPSER AND PTYCON
	MOVE	T1,S		;GET STREAM NUMBER
	PUSHJ	P,TTYDEC	;AND TYPE IT
	OUTCHR	["-"]		;AND A DASH
	POP	P,T1		;RESTORE ADDRESS
	OUTSTR	(T1)		;TYPE THE LINE
	POPJ	P,		;AND RETURN
SUBTTL	System Dependent Subroutines

;TO AVOID EXCESSIVE FEATURE TESTING IN THE MAIN CODE FOR TOPS10 OR TOPS20,
;	SYSTEM DEPENDENT SUBROUTINES ARE INCLUDED HERE, AS A SEPARATE SECTION.


;	CONTTY	ENABLE INTERRUPTS ON THE CONTROLLING TERMINAL AND SET A
;		FLAG WHEN THE INTERRUPT OCCURS.
;	GETMST	GET CURRENT TIME OF DAY INTO T1 (MILLISECONDS)
;	GJTIML	GET SUBJOB (J) REMAINING TIME LIMIT INTO T1
;	ONCECN	SET UP ONCE ONLY CONSTANTS
;	UPDADD	CHECK FOR CHANGES TO OPERATOR DEFAULTS
;	PREKJB	SET UP FOR AUTO LOGOUT OF A JOB
;	CHKCLS	DETERMINE IF CLOSE/DUMP/UNHANDLED ERROR
;	SYSPRG	DETERMINE IF CURRENT PROGRAM CAME FROM SYS:.  USED FOR
;		%CERR:: OR %ERR:: DECISION
;	REDUCE	COUNT CHARACTERS IN USERS SIXBIT NAME (TOPS10 ONLY)

;	UUOCHR & UUOSTR  LUUO HANDLERS (TOPS20 ONLY)
;	TTYDEC & TTYOCT  OUTPUT CONVERSION ROUTINES
SUBTTL	TOPS10 Subroutines

IFN FTUUOS,<		;A LARGE FEATURE TEST FOR TOPS10 VERSION

;ROUTINES NOT NEEDED ON TOPS10

	UUOCHR==UUOERR	;USE THE TTCALL INSTEAD
	UUOSTR==UUOERR	; "   "    "       "
	DELSPL==CPOPJ	;NO SPOOLED FILES TO DELETE

;SUBROUTINE TO ENABLE CONTROLLING TERMINAL INTERRUPTS

CONTTY:	MOVSI	A,'TTY'		;MY TELETYPE
	MOVEI	B,PS.RID	;INPUT READY INTERRUPTS
	MOVEI	C,PSITTY	;INTERRUPT ROUTINE
	PUSHJ	P,CSPPSI##	;ENABLE THE CONDITION
	SKIPE	A		;HAVE AN INTERRUPT BLOCK ADDRESS
	 TDZA	A,A		;YES, SET TO WATCH FOR INTERRUPTS
	  SETO	A,		;NO, MUST LOOK AT THE LINE INSTEAD
	MOVEM	A,TTYFLG	;STORE THE EXCHANGE DATA
	SETOM	TTYINT		;FORCE AT LEAST 1 LOOK AT THE TELETYPE
	POPJ	P,		;RETURN TO INITIALIZATION SEQUENCE

;HERE WHEN AN INPUT READY INTERRUPT OCCURRED ON OUR TERMINAL

PSITTY:	SETOM	TTYINT		;NOTE THE INTERRUPT
	DEBRK.			;CATCH IT IN THE MAIN LOOP
	  HALT	.		;WHAT, NOT IMPLEMENTED!!
	  HALT	.		;WHAT, NOT AT INTERRUPT LEVEL!!

;SUBROUTINE TO GET CURRENT TIME OF DAY (MS) INTO T1

GETMST:	MSTIME	T1,		;ASK THE MONITOR
	POPJ	P,		;AND RETURN

;SUBROUTINE TO GET SUBJOB (J) REMAINING TIME LIMIT INTO T1

GJTIML:	HRL	T1,J		;GET THE JOB NUMBER
	HRRI	T1,.GTLIM	;THE LIMIT TABLE
	GETTAB	T1,		;GET THE JOB LIMIT WORD
	  JFCL			;BATCH NEEDS THAT TABLE
	TLZ	T1,777700	;CLEAR ALL BUT TIME REMAINING
	POPJ	P,		;RETURN WITH REMAINING LIMIT

;SUBROUTINE TO SET UP FOR AUTO LOGOUT ABOUT TO HAPPEN

PREKJB:	MOVE	A,[2,,B]	;SET FOR JBSET. UUO
	HRRZ	B,J		;ADD THE JOB NUMBER
	MOVE	C,[.STTLM,,^D30] ;GIVE SOME EXTRA TIME FOR KJOB
	JBSET.	A,		;TRY TO PREVENT TIME EST EXCEEDED DURING KJOB
	  JFCL
	POPJ	P,		;AND RETURN
;SUBROUTINE TO REDUCE THE POSSIBLE 12 CHARACTER NAME TO THE PROPER COUNT

REDUCE:	MOVE	A,Q.USER(R)	;LOAD THE FIRST HALF
	MOVE	B,Q.USER+1(R)	;AND THE SECOND
	JUMPN	A,.+2		;IS THERE A FIRST PART
	  JUMPE	B,CPOPJ		;NO, AND IF NO SECOND EITHER, GIVE EMPTY RETURN
	MOVEI	T2,^D12		;AND THE MAXIMUM NUMBER OF CHARACTERS
REDU.1:	TRNE	B,77		;NOW LETS SUPPRESS TRAILING BLANKS
	  JRST	CPOPJ1		;FOUND A NON-BLANK, T2=COUNT OF REAL CHARACTERS
	LSHC	A,-6		;SHIFT OUT THE BLANK
	SOJG	T2,REDU.1	;AND KEEP TESTING
	POPJ	P,		;NO NAME SPECIFIED, GIVE NON-SKIP RETURN

;SUBROUTINE TO OUTPUT AC T1 AS A DECIMAL NUMBER TO THE OPERATOR

TTYDEC:	IDIVI	T1,^D10		;ANOTHER ONE OF THOSE DECIMAL OUTPUT ROUTINES
	HRLM	T2,(P)		;SAVE A DIGIT
	JUMPE	T1,.+2		;ALL DONE YET
	PUSHJ	P,TTYDEC	;NO, GET ALL THE DIGITS
	HLRZ	CH,(P)		;RESTORE DIGIT TO OUTPUT
TTYBIN:	MOVEI	CH,"0"(CH)	;TO ASCII
	OUTCHR	CH		;OUTPUT IT
	POPJ	P,

;SUBROUTINE TO OUTPUT AC T1 AS AN OCTAL NUMBER TO THE OPERATOR

TTYOCT:	LSHC	T1,-^D3		;SEPARATE A DIGIT
	HLLM	T2,(P)		;SAVE FOR LATER
	JUMPE	T1,.+2		;GET THE WHOLE NUMBER YET
	PUSHJ	P,TTYOCT	;NO, SEPARATE MORE
	HLRZ	CH,(P)		;GET A DIGIT
	LSH	CH,-^D15	;POSITION
	JRST	TTYBIN		;CONVERT TO ASCII AND OUTPUT IT
;SUBROUTINE TO SET UP ONCE ONLY CONSTANTS

ONCECN:	MOVSI	A,'OPR'		;TEST IF SYSTEM HAS REMOTE STATION FEATURE
	WHERE	A,		;BY SEEING IF THIS WHERE UUO FAILS
	  SKIPA			;IT DID, NO LOCATE COMMAND FOR NEW JOBS
	TLO	G,GL.RMT	;MARK REMOTE STATIONS PRESENT
IFN INPCOR,<
	MOVE	T1,[%CNMMX]	;FIND OUT THE VALUE OF MINMAX
	GETTAB	T1,		;SO JOBS WITH /CORE:1K DON'T CONFUSE BATCON
	  MOVEI	T1,^D12*^D1024	;THIS IS THE VALUE SUGGESTED FOR 507 MONITORS
	LSH	T1,-^D9		;CONVERT TO PAGES
	MOVEM	T1,MINMAX	;SAVE FOR LATER
>  ;END OF IFN INPCOR
	POPJ	P,		;AND RETURN

;SUBROUTINE TO NOTICE CHANGES IN VALUES NEEDED BY QUASAR

UPDADD:	IFN	INPCOR,<
	SKIPE	UCORE		;IS THERE AN OPERATOR VALUE
	  JRST	UPDA.1		;YES, USE IT
	MOVE	A,[%NSCMX]	;GET SYSTEM CORMAX VALUE
	GETTAB	A,
	  MOVSI	A,1		;ASSUME 256K
	LSH	A,-^D9		;CONVERT TO P
	TLNE	A,-1		;CHECK FOR OVERFLOW
	  MOVEI	A,-1		;SET TO MAXIMUM
	CAME	A,CORMAX	;HAS IT CHANGED SINCE THE LAST TIME
	  TLO	G,GL.STC	;YES, NEED TO TELL QUASAR
	MOVEM	A,CORMAX	;SAVE FOR HELLO MESSAGE AND "CURRENT"
UPDA.1:	SKIPE	ACORE		;IS THERE A VALUE HERE
	  JRST	UPDA.2		;YES, USE IT
	MOVX	A,%NSMXM	;GET THE AVAILABLE USER CORE
	GETTAB	A,
	  MOVSI	A,1		;ASSUME 256K
	IMULI	A,3		;COMPUTE 1.5 * AVAILABLE MEMORY
	LSH	A,-^D10		;CONVERT TO P
	TLNE	A,-1		;CHECK FOR OVERFLOW
	  MOVEI	A,-1		;SET TO MAXIMUM
	CAME	A,CORPHY	;HAS IT CHANGED SINCE THE LAST TIME
	  TLO	G,GL.STC	;YES, NEED TO TELL QUASAR
	MOVEM	A,CORPHY	;SAVE PHYSICAL LIMIT
UPDA.2:	>  ;END OF IFN INPCOR
	POPJ	P,		;RETURN
;SUBROUTINE TO CHECK IF A CLOSE/DUMP COMMAND IS NEEDED

CHKCLS:	TLNN	R,RL.JIE	;IS THE JOB IN ERROR STATE
	  POPJ	P,		;NO, DON'T NEED THE CLOSE
	TRO	F,FR.UHE	;AN UNEXPECTED CONDITION
	PUSHJ	P,INMONM	;MAKE SURE THE JOBS IN MONITOR MODE
	TLNE	R,RL.TIM	;TIME STAMP NEEDED
	  PUSHJ	P,PUTPER	;YES, SEND A PERIOD, THAT WILL TIME STAMP IT
	TXTJOB	[ASCIZ/CLOSE/]	;SEND THE CLOSE COMMAND
	PUSHJ	P,SNDCLF	;END THE LINE AND SEND THE BUFFER
	PUSHJ	P,IOWAIT	;WAIT UNTIL COMPLETE
	PUSHJ	P,SYSPRG	;DID PROGRAM COME FROM SYS
	  POPJ	P,		;YES, NO DUMP
	HRL	T1,J		;GET THE JOB NUMBER
	HRRI	T1,.GTPRG	;GET THE PROGRAM NAME
	GETTAB	T1,
	  POPJ	P,		;DON'T KNOW, NO DUMP
	JUMPE	T1,CPOPJ	;RUN OR GET ERROR, NO DUMP
	TXTJOB	[ASCIZ/DUMP/]	;NOW SEND THE DUMP COMMAND
	PUSHJ	P,SNDCLF	;END THE LINE
	PUSHJ	P,IOWAIT	;WAIT FOR NEXT INPUT REQUEST
	JRST	INMONM		;MAKE SURE AGAIN THEN RETURN TO CALLER

;SUBROUTINE TO DETERMINE IF PROGRAM CAME FROM SYS

SYSPRG:	HRL	T1,J		;GET THE JOB NUMBER
	HRRI	T1,.GTLIM	;GET THE JBTLIM TABLE
	GETTAB	T1,
	  POPJ	P,		;CAN'T GET IT, SAY YES
	TLNE	T1,(JB.LSY)	;CHECK GOTTEN FROM SYS BIT
	  POPJ	P,		;IT DID
	JRST	CPOPJ1		;A USER PROGRAM

;SUBROUTINE TO GET NEXT CHARACTER FROM THE PTY EVEN IF CROSSES A BUFFER

NXTPTY:	PUSHJ	P,GETPTY	;GET A CHARACTER
	  SKIPA			;BUFFER IS EMPTY, REFILL IT
	POPJ	P,		;GOT ONE, TURN
	PUSHJ	P,QTS		;WAIT FOR NEXT WAKE-UP
	PUSHJ	P,INPPTY	;GET A FRESH BUFFER
	JRST	NXTPTY		;TRY NOW


>  ;;;END OF IFN FTUUOS
SUBTTL	TOPS20 Subroutines

IFN FTJSYS,<		;A LARGE FEATURE TEST FOR TOPS20 VERSION

;ROUTINES NOT NEEDED ON TOPS20

	UPDADD==CPOPJ	;DOES NOTHING
	SYSPRG==CPOPJ1	;ALL ERRORS TRAP TO %ERR::

;THIS DOESN'T DO MUCH UNTIL FULLY CONVERTED

CONTTY:	SETOM	TTYFLG		;ALWAYS POLL THE TERMINAL
	SETOM	TTYINT		;FORCE THE PROCESS
	POPJ	P,		;AND RETURN

;SUBROUTINE TO GET CURRENT TIME OF DAY (MS) INTO T1

GETMST:	SETO	T2,		;T2 = AC2 = USE CURRENT TIME
	SETZ	B,		;B  = AC4 = NO FLAGS
	ODCNV			;GET CURRENT DATE/TIME (LOCAL)
	MOVEI	T1,^D1000	;CONVERSION CONSTANT
	IMULI	T1,(B)		;CONVERT LOCAL SECONDS TO MILLISECONDS
	POPJ	P,		;AND RETURN

;SUBROUTINE TO GET SUBJOB (J) REMAINING TIME LIMIT INTO T1

GJTIML:	MOVEI	T1,(J)		;GET THE JOB NUMBER
	HRROI	T2,T1		;ONE WORD INTO T1 (E.G. -1,,T1)
	MOVX	A,.JIRTL	;A = T2 + 1, WANT RUN TIME LIMIT
	GETJI			;GET IT
	  SETO	T1,		;OH WELL!
	POPJ	P,		;RETURN WITH TIME IN T1

;SUBROUTINE TO SET UP ONCE ONLY CONSTANTS

ONCECN:	SETZM	MINMAX		;THERE IS NO SYSTEM MINIMUM
	MOVX	T1,RC%EMO	;EXACT MATCH ONLY
	HRROI	T2,[ASCIZ /PS:<SPOOL>/]
	RCDIR			;GET SPOOL DIRECTORY NUMBER
	MOVEM	A,SPLNUM	;SAVE AWAY THE ANSWER
	POPJ	P,		;AND RETURN

;SUBROUTINE TO SET UP FOR AUTO LOGOUT ABOUT TO BE DONE

PREKJB:	PUSHJ	P,SNDUPC	;JUST FOR GRINS
	JRST	IOWAIT		;WAIT FOR THAT TO WORK, THEN RETURN

;SUBROUTINE TO DETERMINE IF AN UNHANDLED ERROR OCCURRED

CHKCLS:	TLNE	R,RL.JIE	;DID AN ERROR OCCUR
	  TRO	F,FR.UHE	;YES, AN UNEXPECTED CONDITION
	POPJ	P,		;NEVER DO CLOSE/DUMP
;HERE TO DELETE SPOOLED INPUT FILES:
;
;FILES ARE NAMED:
;	DSK:<SPOOL>CDR-XXX.YYYYY.*

;WHERE XXX IS THE USER'S DIRECTORY NUMBER
;      YYYYY IS A STRING MADE OF THE JOBNAME CONCATENATED WITH A
;		RANDOM 4 CHARS CURRENTLY PASSED BY SPRINT IN Q.DEAD.

DELSPL:	SKIPN	Q.DEAD(R)		;IS THERE A SPOOLED INPUT NAME?
	POPJ	P,			;NO, JUST RETURN
	MOVE	T2,[ASCII /PS:<S/]
	MOVEM	T2,TEMP3
	MOVE	T2,[ASCII /POOL>/]
	MOVEM	T2,TEMP3+1
	MOVE	T2,[ASCII /CDR-/]
	MOVEM	T2,TEMP3+2
	MOVX	T1,RC%EMO		;EXACT MATCH ONLY
	HRROI	T2,Q.USNM(R)		;POINT TO USER NAME
	RCUSR				;RECOGNIZE IT & PUT # IN T2+1=A
	HRRZS	A			;GET RH ONLY
	MOVE	T1,[POINT 7,TEMP3+2,27]	;POINTER FOR REST OF STRING
	PUSHJ	P,DELS.1		;CONVERT TO OCTAL STRING
	JRST	DELS.2			;AND CONTINUE ON

DELS.1:	IDIVI	A,10			;DIVIDE BY 8
	PUSH	P,B			;PUSH THE REMAINDER
	SKIPE	A			;DONE YET?
	PUSHJ	P,DELS.1		;NO, RECURSE
	POP	P,A			;GET BACK A DIGIT
	ADDI	A,"0"			;CONVERT TO ASCII
	IDPB	A,T1			;DEPOSIT IT INTO STRING
	POPJ	P,			;AND RETURN

DELS.2:	MOVEI	A,"."			;LOAD A DOT
	IDPB	A,T1			;AND DEPOSIT IT
	MOVE	T2,[POINT 6,Q.JOB(R)]	;POINT TO THE JOB NAME
	PUSHJ	P,DELS.3		;DEPOSIT IN STRING
	MOVE	T2,[POINT 6,Q.DEAD(R)]	;POINT TO SUFFIX
	PUSHJ	P,DELS.3		;AND DEPOSIT IT ALSO
	JRST	DELS.4			;CONTINUE ON

DELS.3:	ILDB	A,T2			;GET A CHARACTER
	JUMPE	A,CPOPJ			;NULL, DONE
	ADDI	A,40			;CONVERT 6BIT TO ASCII
	IDPB	A,T1			;DEPOSIT IT
	TLNE	T2,770000		;AM I DONE?
	JRST	DELS.3			;NO, LOOP SOME
	POPJ	P,			;DONE, RETURN


				;CONTINUED ON NEXT PAGE
				;CONTINUED FROM PREVIOUS PAGE


DELS.4:	MOVEI	A,"."			;LOAD A DOT
	IDPB	A,T1			;DEPOSIT IT
	MOVEI	A,"*"			;LOAD AN ASTERISK
	IDPB	A,T1			;GET ALL GENERATIONS
	MOVEI	A,0			;LOAD A NULL
	IDPB	A,T1			;TERMINATE THE STRING
	MOVX	T1,GJ%OLD!GJ%IFG!GJ%SHT	;LOAD GTJFN BITS
	HRROI	T2,TEMP3		;POINT TO FILE-NAME
	GTJFN				;GET A JFN
	  POPJ	P,			;FAILED, RETURN
	JRST	DELS.6			;JUMP INTO THE LOOP

DELS.5:	GNJFN				;GET THE NEXT FILE
	  JRST	DELS.7			;DONE EXPUNGE THE AREA
DELS.6:	MOVE	A,T1			;SAVE THE JFN
	TLZ	T1,-1			;CLEAR LEFT HALF OF JFN WORD
	TXO	T1,DF%NRJ		;DONT RELEASE THE JFN
	DELF				;DELETE THE FILE
	  JFCL				;IGNORE THE ERROR
	MOVE	T1,A			;RELOAD INDEXABLE JFN
	JRST	DELS.5			;GET THE NEXT ONE

DELS.7:	MOVEI	T1,0			;NO SPECIAL FLAGS
	MOVE	T2,SPLNUM		;GET DIRECTORY NUMBER OF <SPOOL>
	DELDF				;EXPUNGE IT
	POPJ	P,			;AND RETURN
;TTY OUTPUT PACKAGE  CHARACTER OUTPUT, STRING OUTPUT, DECIMAL AND OCTAL CONVERSION

;UUOCHR AND UUOSTR ARE CALLED BY THE LOCAL UUO HANDLER

UUOCHR:	MOVE	IO2,@.JBUUO##	;GET THE CHARACTER TO TYPE
	EXCH	T1,IO2		;SAVE ORIGINAL T1, GET DATA THERE
	PBOUT			;TYPE THE ASCII CHARACTER
	JRST	XCHXIT		;PUT THE REGS BACK AND RETURN

UUOSTR:	HRRO	IO2,.JBUUO##	;GET POINTER TO THE STRING
	EXCH	T1,IO2		;COPY POINTER, SAVE ORIGINAL T1
	PSOUT			;OUTPUT THE STRING
XCHXIT:	MOVE	T1,IO2		;PUT T1 BACK
	POPJ	P,		;AND RETURN

;SUBROUTINES TO OUTPUT 'T1' TO THE OPERATOR IN THE PROPER RADIX

TTYDEC:	PUSH	P,A		;A = T2 + 1; SAVE CALLERS
	MOVEI	A,^D10		;GET RADIX FOR DECIMAL OUTPUT, NO FLAGS
TTYD.1:	MOVE	T2,T1		;MOVE OVER THE NUMBER
	MOVEI	T1,.PRIOU	;TO PRIMARY OUTPUT
	NOUT			;OUTPUT IT
	  JFCL			;CAN'T REALLY FAIL
	POP	P,A		;RESTORE CALLERS
	POPJ	P,		;AND RETURN

TTYOCT:	PUSH	P,A		;A = T2 + 1; SAVE CALLERS
	MOVE	A,[NO%MAG+^D8]	;RADIX 8, OUTPUT MAGNITUDE ONLY
	JRST	TTYD.1		;USE COMMON CODE NOW


>  ;;;END OF IFN FTJSYS
	SUBTTL	BATCON Data Base

	LSTOFF	;FORCE OUT LITERALS NOW
	LIT
	LSTON

IFE ONESEG,<RELOC 0>	;SWITCH TO LOW SEGMENT IF APPROPRIATE

LOWDAT:
BASTBL:	BLOCK	JOBMAX	;STREAM DATA BASE POINTERS (ALSO STREAM AC R)
TOPPDL:	BLOCK	TPSIZE	;TOP LEVEL PUSH DOWN LIST
HIACTV:	BLOCK	1	;HIGHEST STREAM NUMBER ACTIVE
STACTV:	BLOCK	1	;NUMBER OF ACTIVE STREAMS
CHNTBL:	BLOCK	20	;CHANNEL ALLOCATION TABLES
CHNFRE:	BLOCK	1	;USED BY THE CHANNEL ALLOCATOR
CHNMAY:	BLOCK	1	;USED BY THE CHANNEL ALLOCATOR
MJOB:	BLOCK	1	;MAXIMUM CONCURRENT ACTIVE STREAMS
NJNTIM:	BLOCK	1	;TIME WHAN NOTICED NO JOB NUMBERS AVAILABLE
CURMST:	BLOCK	1	;CURRENT MSTIME OF THIS PASS THROUGH THE DISPATCHER
TTYINT:	BLOCK	1	;SET IF A LINE IS PROBABLY AVAILABLE TO BATOPR
TTYFLG:	BLOCK	1	;WHAT TO EXCHANGE WITH TTYINT (-1 = NO PSI)
UTIME:	BLOCK	1	;SCHEDULING PARAMETER SINGLE JOB MAXIMUM
ATIME:	BLOCK	1	;SCHEDULING PARAMETER SUM OF JOBS
TEMP1:	BLOCK	1	;TEMP CELL USED DURING 'BALINE'
TEMP2:	BLOCK	1	;TEMP CELL USED DURING '.ERROR' AND '.OPERATOR'
DEFSJB:	BLOCK	1	;SUBJOB TO USE IF NONE SPECIFIED
COMFIL:	BLOCK	1	;INSTRUCTION TO EXECUTE TO GET ANOTHER CHARACTER
NXTJOB:	BLOCK	1	;SEQUENCE NUMBER OF NEXT JOB TO RUN (NEXT COMMAND)
OPRLIN:	BLOCK	^D16	;INTERMEDIATE TEXT OF OPERATOR RESPONSE TO DIALOGUE MODE
UCORE:	BLOCK	1	;SCHEDULING PARAMETER SINGLE JOB MAXIMUM
ACORE:	BLOCK	1	;SCHEDULING PARAMETER SUM OF JOBS
CORMAX:	BLOCK	1	;OPERATOR SET CORMAX
CORPHY:	BLOCK	1	;AVAILABLE USER CORE
MINMAX:	BLOCK	1	;SMALLEST THE USER WILL GET IN K

IFN FTJSYS,<
TEMP3:	BLOCK	<^D39/^D5>+1  ;SPACE FOR DIRECTORY NUMBER TO NAME CONVERSION
SPLNUM:	BLOCK	1	;DIRECTORY NUMBER OF <SPOOL>
>  ;END OF IFN FTJSYS
IFN FTUUOS,<
SFDPAT:	BLOCK	11	;SFD BLOCK - WORDS 0,1, AND 10 ARE ALWAYS ZERO
>  ;END OF IFN FTUUOS

MAX <HEL.SZ,REL.BL,REQ.SZ,CHE.SZ,ROU.SZ,COU.SZ>
QSRMSG:	BLOCK	MAXSIZ	;RESERVE SPACE FOR LARGEST MESSAGE I WILL SEND
	SUBTTL	Data Base for Each Batch Stream

LASLOW:
	RELOC	BATCON		;ORG OVER CODE TO SAVE SPACE
	PHASE	0

;DON'T CHANGE THE ORDER OF THE Q.xxx SYMBOLS (FILLED IN BY BLT)
; THEIR ORDER IS DEPENDENT ON THE FORMAT OF QUASAR'S DATA BASE

Q.ITN:!	 BLOCK	1	;INTERNAL TASK NAME
Q.LEN:!	 BLOCK	1	;FILLER
Q.DEV:!	 BLOCK	1	;FILLER
Q.JOB:!	 BLOCK	1	;JOB NAME
Q.SEQ:!	 BLOCK	1	;JOB SEQUENCE NUMBER
Q.SPC:!	 BLOCK	1	;FILLER
Q.AFTR:! BLOCK	1	;AFTER PARAMETER
Q.DEAD:! BLOCK	1	;DEADLINE TIMES
Q.IDEP:! BLOCK	1	;DEPENDENCY WORD
Q.ILIM:! BLOCK	4	;JOB LIMITS (INCLUDING EXTRA)
Q.CHKP:! BLOCK	5	;.EQ CHECKPOINT BLOCK
Q.ACCT:! BLOCK	10	;ACCOUNT STRING

IFN FTUUOS,<
Q.USER:! BLOCK	2	;USER'S NAME
Q.PPN:!	 BLOCK	1	;PPN ORIGINATING REQUEST
>  ;END IFN FTUUOS

IFN FTJSYS,<
Q.USNM:! BLOCK	10	;USER NAME STRING
Q.CNDI:! BLOCK	12	;CONNECTED DIRECTORY STRING
>  ;END IFN FTJSYS

	Q.EBLT==.-1	;BLT .EQ UP TILL HERE

Q.CMOD:! BLOCK	1	;CTL FILE SWITCHES
Q.CBIT:! BLOCK	1	;STARTING INFORMATION
Q.LMOD:! BLOCK	1	;LOG FILE SWITCHES

IFN FTUUOS,<		;VALUES PROVIDED FOR TOPS10 ONLY
Q.IDDI:! BLOCK	6	;JOB'S PATH
Q.CSTR:! BLOCK	1	;CTL FILE STRUCTURE
Q.CNAM:! BLOCK	1	;NAME
Q.CEXT:! BLOCK	1	;EXTENSION
Q.CDIR:! BLOCK	6	;DIRECTORY
Q.LSTR:! BLOCK	1	;LOG FILE STRUCTURE
Q.LNAM:! BLOCK	1	;NAME
Q.LEXT:! BLOCK	1	;EXTENSION
Q.LDIR:! BLOCK	6	;DIRECTORY
>  ;END OF IFN FTUUOS

IFN FTJSYS,<
Q.CSTR:! BLOCK	FDXSIZ	;STRING FOR CTL FILE NAME
Q.LSTR:! BLOCK	FDXSIZ	;   "    "  LOG   "   "
>  ;END OF IFN FTJSYS


;;; END OF AREA BUILT FROM THE "NEXT JOB" FUNCTION

;;; THE JOB DATA BASE IS CONTINUED ON THE NEXT PAGE
.JREGS:! BLOCK	15	;JOB PROCESSOR REGS 0-13,17
.JPLST:! BLOCK	.JPSIZ	;PUSH DOWN LIST FOR JOB PROCESSOR
.JLOGB:! BLOCK	DSKBLK*LOGBFR	;SPACE FOR LOG FILE
.JPTYI:! BLOCK	PTYBLK*PTYBFR	;SPACE FOR PTY BUFFER RING
.JPTYO:! BLOCK	PTYBLK*PTYBFR	;SPACE FOR PTY BUFFER RING
.JPINP:! BLOCK	3	;RING HEADER FOR INPUT
.JPOUT:! BLOCK	3	;RING HEADER FOR OUTPUT
.JCPTR:! BLOCK	1	;POINTER INTO .JCTLB
.JLPTR:! BLOCK	1	;POINTER INTO .JLOGB
.JPCHN:! BLOCK	1	;SAVED 'IO1' WITH PTY CHANNEL NUMBER (PERMANENT ASSIGNMENT)
.JLABL:! BLOCK	1	;LABEL BEING SEARCHED FOR
.JOPER:! BLOCK	^D16	;SPACE FOR OPERATOR RESPONSE TO DIALOGUE MODE/COMMENTS
.JWHO:!  BLOCK	1	;IDENTIFIER FOR OPERATOR COMMENTS
.JBAKP:! BLOCK	1	;LOCATION OF THE CURRENT BACKTO COMMAND
.JKILR:! BLOCK	1	;PPN THAT REQUESTED THAT THE JOB BE CANCELLED
.JUPLT:! BLOCK	1	;TIME WHEN LOG FILE CHANGED LAST
.JLGFD:! BLOCK	1	;SIZE OF LOG FILE FD GIVEN BY QUASAR
.JINFO:! BLOCK	EQCKSZ	;CHECKPOINT/REQUEUE INFORMATION
	.JCHRQ==.JINFO ;WORD 0 IS THE CHECKPOINT/REQUEUE LABEL
.JAFTR:! BLOCK	1	;AFTER PARAMETER FOR REQUEUE
.JJOBN:! BLOCK	1	;JOB NUMBER SAVED FOR RELEASE MESSAGE
.JCCNT:! BLOCK	1	;BYTE COUNT
.JCUSI:! BLOCK	1	;USETI/USETO COUNT (-1 IF END OF FILE)
.JLCNT:! BLOCK	1	;BYTE COUNT
.JLUSI:! BLOCK	1	;USETI/USETO COUNT
.JERCD:! BLOCK	1	;BYTE (9).ERROR CHAR, .OPERATOR CHAR  (18)ERROR CODE
.JSTAT:! BLOCK	1	;SAVE RESULT OF JOBSTS UUO, FOR BATOPR
.JRUNT:! BLOCK	1	;JOBS RUNTIME, USED BY BACKTO
.JOUTL:! BLOCK	^D20	;LAST LINE OF INPUT/OUTPUT FOR THIS SUBJOB
.JOUTC:! BLOCK	1	;NUMBER OF CHARS LEFT (0=REFILL)
.JOUTP:! BLOCK	1	;POINTER INTO .JOUTL

	IFN	PROMPT,<
.JWAIT:! BLOCK	1	;TIME WHEN JOB WENT INTO OPERATOR WAIT
	>

IFN FTUUOS,<
.JLFLB:! BLOCK	.FOPPN+1  ;FILOP BLOCK FOR LOG FILE
.JLLEB:! BLOCK	.RBSIZ+1  ;LOOKUP BLOCK FOR LOG FILE
>  ;END IFN FTUUOS

IFN FTJSYS,<
.JLWAT:! BLOCK	1	;TIME WAITNG FOR LOGOUT
.JPJFN:! BLOCK	1	;PTY JFN
.JCJFN:! BLOCK	1	;CONTROL FILE JFN
.JLJFN:! BLOCK	1	;LOG FILE JFN
.JLDEV:! BLOCK	1	;LOG FILE DEVICE
.JCPSZ:! BLOCK	1	;SIZE OF THE CTL FILE IN PAGES
	 BLOCK	<<<<.-1>!777>+1>-<.-Q.ITN>> ;PAGE ALIGN THE BUFFERS
;***	.JCTLB MUST FOLLOW  ***;
>  ;END OF IFN FTJSYS
.JCTLB:! BLOCK	DSKBLK*CTLBFR	;SPACE FOR CTL FILE

.JSIZE:!		;SIZE OF THE DATA BASE FOR EACH STREAM
	DEPHASE

.JPAGS==1+<<.JSIZE-1>/1000>	;NUMBER OF PAGES NEEDED FOR THE DATA BASE

	END	BATCON