Google
 

Trailing-Edge - PDP-10 Archives - ap-c796e-sb - batcon.mac
There are 39 other files named batcon.mac in the archive. Click here to see a list.
	SUBTTL	Assembly Parameters (Set Batch Configuration)

;***Copyright 1974,1975,1976 Digital Equipment Corp., Maynard, Mass ***

IFNDEF	ONESEG,<ONESEG==0>	;NORMALLY A 2 SEGMENT PROGRAM
IFNDEF	FTOPR,<FTOPR==1>	;0=BATCON+BATOPR, 1=BATCON ONLY, -1=BATOPR ONLY

LSTING==0			;NORMAL MODE IS LISTING ON

IFN  ONESEG,<FTOPR==0>		;IF ONE SEGMENT, ASSEMBLE FOR BOTH
IFGE FTOPR <TITLE BATCON - MPB Batch Controller. October 1976  C.D.O'Toole/CDO>
IFL  FTOPR,<TITLE BATOPR - MPB Operator Communication Module
	IF2,<LSTOFF>>		;DON'T LIST THE ASSEMBLY PARAMETERS IN BATOPR

VWHO==0
VBATCH==13	;BATCH VERSION NUMBER
VMINOR==0	;MINOR VERSION NUMBER
VEDIT==1071	;EDIT NUMBER
	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

EDIT 1050  Become Version 12A

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

EDIT 1052  "K" may be a unique command on in-house systems, but may not be in the field.
		(SPR 16152)

EDIT 1053  Implement assembly option SPLMBC, "Minutes Between Checkpoints".
		This feature is used in GALAXY-10 for traditional spooler checkpoints
		and by BATCON to force out the internal LOG file buffers to
		insure that they are updated.  Default SPLMBC to 5 Minutes.
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)

EDIT 1056  REQUEUE time was not quite right.  Use ASHC instead of LSHC.

EDIT 1057  Become version 13

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 1062  Always send /VR: to KJOB, 0 is a valid priority.

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 1065  If system has PSISER, enable TTY Input interrupts, avoid lots of SKPINL's.

EDIT 1066  GALAXY BATCON defaults the CORE Command to 1.5 times the
		available memory, do the same here.

EDIT 1067  Access date on artifically preserved CTL files not updated.
		(SPR 18822)

EDIT 1070  Plug a security hole.

EDIT 1071  BATCON version 13 released to the field October 1976

	\
	SUBTTL	Assembly Parameters (Define the Options)

DEFINE	PARMS<

;;TYPE 1 OPTIONS - DEFINE STATIC PARAMETERS

	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,1	;;TIMER IN MINUTES FOR JOBS IN OPERATOR WAIT
	X	JOBMSG,0	;; 1 IF JOB STARTED/ENDED MESSAGES ARE DESIRED
	X	LOGSWS,0	;; 1 IF LOGIN ACCEPTS SWITCHES (e.g. /TIME:n)
	X	WHKSYS,0	;; 1 IF BATCH IS TO WATCH THE KSYS TIME
	X	OLDALT,0	;; 1 IF RECOGNIZE OLD ALTMODES TOO

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

	X	JOBMAX,^D14	;;ABSOLUTE MAXIMUM BATCON CAN HANDLE
	X	DEFMJB,^D5	;;DEFAULT VALUE OF 'MJOB' WHEN STARTED
	X	REQTIM,^D10	;;DEFAULT REQUEUE TIME IN MINUTES

;;TYPE 3 OPTIONS - DEFINE DEFAULT LIMITS OF A SUBJOB

	X	DEFTIM,^D5*^D60	;;DEFAULT TIME ESTIMATE IN SECONDS
	X	DEFCOR,0*^D1024	;;DEFAULT CORE LIMIT IN WORDS
	X	DEFPAG,^D200	;;DEFAULT PAGE ESTIMATE
	X	DEFCDS,0	;;DEFAULT CARD ESTIMATE
	X	DEFPTP,0	;;DEFAULT PAPER TAPE ESTIMATE
	X	DEFPLT,0	;;DEFAULT MINUTES OF PLOTTING TIME

;;TYPE 4 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	SLPINT,^D30	;;STANDARD SLEEP INTERVAL
	X	NJNINT,^D4	;;MINUTES TO WAIT IF JOB CAPACITY IS EXCEEDED
	X	SPLMBC,^D5	;;MINUTES BETWEEN CHECKPOINTS OF THE LOG FILE
	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
;CONSISTENCY CHECK FOR ASSEMBLY PARAMETERS

	IFG	<JOBMAX-^D14>,<
		PRINTX JOBMAX.GT.14, 14 ASSUMED
		JOBMAX==^D14>

	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>

	IFL	<SPLMBC-1>,<
		PRINTX CHECKPOINT INTERVAL .LT. 1 MINUTE, 1 MINUTE ASSUMED
		SPLMBC==1>

	IFL	<SLPINT-^D15>!<^D60-SLPINT>,<
		PRINTX BAD VALUE FOR STANDARD SLEEP INTERVAL, 30 SECONDS ASSUMED
		SLPINT==^D30>

	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)

G==0		;GLOBAL BATCON FLAGS
R==1		;RELOCATION FOR STREAM DATA BASE (LH ARE FLAGS)
S==2		;STREAM INDEX

T1==3		;AC'S 3 TO 17 ARE SAVED FOR EACH STREAM IN .JREGS(R)
T2==4		;ALL AC'S TN ARE TEMPORARY

F==6		;ADDITIONAL FLAG REGISTER

A==7		;BEGINNING OF 4 REGS FOR LOOKUP/ENTER AND FRIENDS
B==10		;CAN BE GENERALLY USED IF AWARE THEY MAY BE CLOBBERED
C==11		;BY THE PTY, LOG, AND CTL HANDLERS
D==12

IO1==13		;REGISTERS USED BY THE I/O HANDLER
IO2==14

J==15		;JOBSTS FOR STREAM

CH==16		;RANDOM CHARACTER HOLDER

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




;DEFINE SOME CONSTANTS AFTER CONSISTENCY CHECKS

DSKBLK==^D128		;WORDS IN A DISK BLOCK
PTYBLK==23		;WORDS IN A PTY BUFFER
HIBERP==60		;HIBERNATE UUO PARAMETER BITS
CTLCHR==<DSKBLK*5>*CTLBFR ;NUMBER OF CHARACTERS BUFFERED FOR CTL FILE
LOGCHR==<DSKBLK*5>*LOGBFR ;NUMBER OF CHARACTERS BUFFERED FOR LOG FILE
;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.PTA==040000	;ANY SUBJOB DID PTY ACTIVITY
GL.ALL==020000	;SUBJOB SPECIFIED WAS ALL
GL.RMT==010000	;THE MONITOR HAS REMOTE STATION FEATURE
GL.SLP==004000	;USE A TIMER FOR THE HIBERNATE UUO
GL.EXI==002000	;OPERATOR EXIT COMMAND IN EFFECT
GL.MJB==001000	;MJOB HAS JUST DECREASED OR EXIT/RESET JUST TYPED
GL.NLI==000400	;SCHED BITS SAY NO LOGINS
GL.UC0==000200	;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

;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.FLL==004000	;FIRST LOOK AT THE LOG FILE

;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

;FLAGS SET WHEN USING QUEUER TO GET A HIGH SEGMENT

QC.PHY==1B0	;USE PHYSICAL ONLY GETSEG
QC.HGH==1B1	;RH OF AC1 POINTS TO THE HIGH SEGMENT TO GET (NOT QMANGR)
QC.PDL==1B2	;DON'T RELOCATE THE PUSH DOWN LIST
QC.COR==1B3	;RETAIN ANY CORE ACQUIRED TO SAVE CORE UUOS

;JBSET. UUO FUNCTIONS

.STSPL==5	;FUNCTION TO SET SPOOL BITS
.STWAT==6	;FUNCTION TO SET WATCH BITS
.STCOR==12	;FUNCTION TO SET CORE LIMIT
.STTIM==13	;FUNCTION TO SET TIME LIMIT

;CHKACC UUO ARGUMENTS

.ACREN==1	;RENAME A FILE
.ACAPP==4	;APPEND TO A FILE
.ACRED==5	;READ A FILE
.ACCRE==7	;CREATE IN A UFD

;PI-SYSTEM BITS

PS.FON==1B2	;TURN ON THE INTERRUPT SYSTEM
PS.FAC==1B6	;ADD SPECIFIED CONDITION
PS.RID==1B19	;INPUT DONE INTERRUPTS
;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
.GTLIM==40	;BATCH STATUS AND LIMITS
	JB.LSY==1B11	;BIT INDICATING PROGRAM CAME FROM SYS

;GETTAB ELEMENTS

%CNSTS==17,,11	;STATES WORD
	ST%NRL==1B34	;BIT PROHIBITING REMOTE LOGINS
	ST%NLG==1B35	;BIT PROHIBITING ANY LOGINS

%CNMMX==116,,11	;WHAT /CORE:1K WILL REALLY GET
%NSCMX==10,,12	;OPERATOR SETTING OF CORMAX
%NSNXM==34,,12	;AVAILABLE USER CORE
%NSKTM==35,,12	;COUNT DOWN TIMER FOR KSYS
%ODK4S==1,,15	;AVAILABLE SWAPPING(VIRTUAL) CORE
%LDMFD==0,,16	;OWNER OF ALL UFDS
%LDQUE==4,,16	;OWNER OF THE QUEUES

;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.A2==175	;OLD ALTMODE
CHR.A3==176	;OLD ALTMODE
;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>
	>

;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

;SET UP FOR BALANCE OF ASSEMBLY

IFE ONESEG,<TWOSEG>	;ASSEMBLING MULTI SEGMENT PROGRAM

IFGE FTOPR,<
IF2,<IFNDEF .QUEER,<EXTERNAL .QUEER>> ;DEFINE .QUEER IF NOT YET DEFINED

	LOC	41
	PUSHJ	P,UUOCON	;UUO INTERRUPT

>

	LOC	137
	BYTE	(3)VWHO (9)VBATCH (6)VMINOR (18)VEDIT

	RELOC	0

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

	IFGE	FTOPR,<	;CONDITIONALLY ASSEMBLE BATCON
			;THIS CONDITION IS NOT TERMINATED UNTIL THE OPERATOR SECTION

BATCON:	JFCL			;NO CCL ENTRY POINT
	RESET
	MOVE	A,.JBFF##	;RESET CORE IF REENTERED BY RESET COMMAND
	CORE	A,		;MAY ALSO BE A USELESS CORE UUO
	  JFCL			;BUT IT'S ONLY DONE ONCE AND CAN HELP
	MOVE	P,[IOWD TPSIZE,TOPPDL]
	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,TTYBLK	;INTERRUPT VECTOR
	PIINI.	A,		;SET IT
	  JRST	NOPISY		;NOT IN THIS MONITOR
	MOVEI	A,PSITTY	;INTERRUPT ROUTINE
	MOVEM	A,TTYBLK	;INTO INTERRUPT BLOCK
	MOVE	A,[PS.FON+PS.FAC+B] ;ON, ADD CONDITIONS
	MOVSI	B,'TTY'		;FOR CONTROLLING TTY
	MOVEI	C,PS.RID	;OFFSET = 0 , INPUT READY INTERRUPTS
	SETZ	D,		;CLEAR RESERVED WORD
	PISYS.	A,		;ADD THE CONDITION
NOPISY:	 TDOA	A,[-1]		;INDICATE NO PI SYSTEM
	  SETZ	A,		;GOT IT
	MOVEM	A,TTYFLG	;STORE INDICATOR
	SETOM	TTYINT		;PRETEND WE HAD ONE
	MOVEI	S,1		;STREAM 1
	HRRZ	R,.JBFF##	;FIRST LOCATION FREE
	MOVEM	R,BASTBL-1(S)	;INITIALIZE DATA BASE ADDRESSES
	MOVEI	R,.JSIZE(R)	;BUMP TO NEXT
	CAIGE	S,JOBMAX	;NOTICE THE ADDRESS IS SET BUT THERES NO CORE
	  AOJA	S,.-3		;ALLOCATED NOW. WILL BE DONE AT TOP SCHEDULING
	MOVEI	A,DEFMJB	;GET DEFAULT VALUE OF MJOB
	MOVEM	A,MJOB
	GETPPN	A,		;GET MY PPN FOR STRUCTURE CHECKS
	  JFCL			;SILLY SKIP
	MOVEM	A,MYPPN		;SAVE FOR LATER USE
	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
	MOVE	A,[%LDMFD]	;FIND THE OWNER OF ALL UFDS
	GETTAB	A,		;ASK THE MONITOR
	  MOVE	A,[1,,1]	;ASSUME [1,1]
	MOVEM	A,MFDPPN	;SAVE FOR THE ACCESS CHECKS
	MOVE	B,[%LDQUE]	;FIND THE OWNER OF THE QUEUES
	GETTAB	B,		;ASK THE MONITOR AGAIN
	  MOVE	B,[3,,3]	;ASSUME [3,3]
	MOVSI	A,'QUE'		;NOW CHECK FOR USING PRIVATE QUEUE
	DEVCHR	A,		;SEE IF DEVICE QUE EXISTS
	JUMPE	A,SYSQUE	;NO SUCH DEVICE
	TLNN	A,(1B1)		;IS IT A DISK TYPE
	  JRST	SYSQUE		;NOT A DISK, CANNOT USE IT
	MOVSI	A,'QUE'		;THERE IS A QUE STRUCTURE, SEE IF ITS A REAL ONE
	DEVCHR	A,200000	;BUT CHECKING FOR PHYSICAL ONLY QUE
	JUMPN	A,SYSQUE	;THERE REALLY IS A DEVICE QUE, CANNOT BE PRIVATE
	MOVE	B,MYPPN		;USE MY PPN FOR PRIVATE QUEUES
SYSQUE:	MOVEM	B,QUEPPN	;SAVE EITHER MY PPN OF THE RESULT OF THE GETTAB
	HRLOI	A,377777	;SET TIME VALUES VERY LARGE
	MOVEM	A,UTIME		;AS SINGLE JOB MAXIMUM
	MOVEM	A,ATIME		;AND TOTAL OF ALL BATCH

	IFN	DEFCOR,<
	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
	MOVEI	T1,1(T1)	;AND ROUND IT UP
	LSH	T1,-1		;NOW TO K, THE BASIC BATCON UNIT
	MOVEM	T1,MINMAX	;SAVE FOR UPDCON,DECCON, AND THE SCHEDULER
	>
	PUSHJ	P,UPDADD	;SET UP SYSTEM DEFAULTS BEFORE STARTING
	SUBTTL	Dispatch and Time slice Routines

TOPLVL:	PUSHJ	P,OPRCOM	;ATTEND THE OPERATOR
	TLZE	G,GL.MJB	;DID SOMETHING CHANGE MJOB (OR EXIT/RESET)
	  PUSHJ	P,GIVPTY	;YES, GIVE BACK INACTIVE PTYS
	TLZ	G,GL.PTA!GL.SLP	;CLEAR SOME FLAGS
	SKIPE	STACTV		;ANY STREAMS ACTIVE
	  JRST	TOPDIS		;YES, ENTER THE DISPATCH LOOP
	TLNE	G,GL.EXI	;A PENDING EXIT
	  EXIT			;YES, CAN EXIT NOW
	TLNN	G,GL.SSH	;CEASE SCHEDULING (RESET)
	  JRST	DISP.3		;NONE PENDING, TRY A SCHEDULING PASS
	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
TOPDIS:	MSTIME	S,		;GET CURRENT MS TIME
	MOVEM	S,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
	HRLI	17,.JREGS(R)	;GET TO RESTORE PROCESSOR REGS
	HRRI	17,3		;AC'S 3-17 FROM .JREGS
	BLT	17,17		;RESTORE THEM ALL
	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	3,.JREGS(R)	;SAVE ALL THE OTHER REGS
	HRRI	3,.JREGS+1(R)	;BUILD BLT POINTER
	HRLI	3,4
	BLT	3,.JREGS+14(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	;ATTEMPT A TOP LEVEL SCHEDULING PASS
	TLNN	G,GL.SLP!GL.SSH ;REASONS TO SLEEP RATHER THAN HIBERNATE
	SKIPE	T1,STACTV	;WHEN THERE ARE NO ACTIVE JOBS
	  MOVEI	T1,SLPINT*^D1000 ;SET A SLEEP INTERVAL
	HRLI	T1,HIBERP	;SET WAKE UP CONDITIONS
	HIBER	T1,
	  JFCL			;NICE TRY
	JRST	TOPLVL		;REENTER TOP LEVEL LOOP
	SUBTTL	Various Levels of Scheduling Routines

;SCHEDULER CALLED AT TOP LEVEL TO ACTIVATE A STREAM

SCHED1:	TLNN	G,GL.SSH!GL.PTA	;STOP SCHEDULING OR PTY ACTIVITY
	PUSHJ	P,NJNCHK	;NO, CHECK FOR JOB CAPACITY EXCEEDED
	  POPJ	P,		;YES, AVOID THE FOLLOWING
	PUSHJ	P,UPDADD	;UPDATE ANY ADDITIONAL PARMS BEFORE LOOP
	SKIPGE	KSYSTM		;IS TIMESHARING GOING TO STOP
	 SKIPE	NXTJOB		;YES, IS THERE A NEXT'ED JOB
	  TLNE	G,GL.NLI	;DID OPERATOR STOP LOGINS
	   POPJ	P,		;NO SCHEDULING IS ALLOWED
	MOVEI	S,1		;START AT THE BEGINNING
SCH1.0:	MOVE	A,STACTV	;CHECK IF MORE THAN MJOB STREAMS RUNNING
	CAML	A,MJOB		;NOTICE THIS IS IN THE LOOP
	  POPJ	P,		;FINDING A JOB WILL CHANGE STACTV
	SKIPGE	R,BASTBL-1(S)	;IS THIS STREAM ALREADY ACTIVE
	  JRST	SCH1.4		;YES, TRY NEXT
	MOVEI	A,.JSIZE(R)	;SEE IF CORE ASSIGNED TO THIS STREAM
	CAMG	A,.JBFF##
	  JRST	SCH1.1		;YES, STREAM HAS ENOUGH CORE
	MOVEI	B,-1(A)		;HIGHEST LOC NEEDED
	CAMG	B,.JBREL##	;NEED THE CORE UUO
	  JRST	.+3		;NO
	CORE	B,		;ACQUIRE SOME SPACE
	  POPJ	P,		;CANNOT GET IT, TRY LATER
	MOVEM	A,.JBFF##	;UPDATE FIRST FREE
SCH1.1:	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
	PUSHJ	P,CHNPTY	;GET A PTY ASSIGNMENT
	  SKIPA			;NONE, MUST GET A REAL PTY
	JRST	SCH1.2		;HAVE ONE, SET BUFFERS
	JUMPE	IO1,CPOPJ	;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	PTYFAL		;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
	DEVNAM	A,		;FIND THE REAL NAME
	  JRST	PTYFAL		;DEVNAM FAILED?
	MOVEM	A,PTYTAB-1(S)	;SAVE NAME FOR QMANGR
	JRST	SCH1.3		;SKIP STUFF ALREADY DONE
SCH1.2:	HLRZ	A,IO1		;COPY CHANNEL NUMBER
	LSH	A,-^D5		;MAKE IT A NUMBER
	HRRM	A,.JPCHN(R)	;SAVE FOR UUO'S
SCH1.3:	HLLM	IO1,.JPCHN(R)	;SAVE AS A CHANNEL FOR EASIER USE
	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
	>
	PUSHJ	P,SCHDLR	;CALL THE BOTTOM LEVEL SCHEDULER TO FIND A JOB
	SKIPN	Q.DEV(R)	;WAS THERE ANY FOUND
	  JRST	SCH1.5		;NO, EXIT FROM LOOP
	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+3(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)
	PUSHJ	P,UPDCON	;UDPATE SCHEDULING CONSTANTS
	PUSHJ	P,WAKEME	;FOUND A JOB, WAKE ME UP FOR DISPATCH LOOP
SCH1.4:	CAMGE	S,MJOB		;LOOK AT ALL WE CAN
	  AOJA	S,SCH1.0	;NO, TRY ANOTHER STREAM
	POPJ	P,		;RETURN TO DISPATCHER
SCH1.5:	SKIPE	Q.AFTR(R)	;WERE THERE ANY JOBS WITH AFTER PARAMETERS
	  TLO	G,GL.SLP	;YES, SLEEP IF QMANGR CAN'T CALL DAEMON
	POPJ	P,		;RETURN TO DISPATCHER

;SUBROUTINE TO DECREMENT THE SCHEDULING CONSTANTS

DECCON:	SOS	STACTV		;REDUCE ACTIVE STREAM COUNT
	HRRZ	T1,Q.ILIM(R)	;GET THE TIME ESTIMATE
	MOVNS	T1		;NEGATE IT
	ADDM	T1,TOTTIM	;REDUCE TIME SCHEDULED

	IFN	DEFCOR,<
	HLRZ	T1,Q.ILIM(R)	;NOW REDUCE CORE SCHEDULED
	LSH	T1,-^D9		;TO PAGES OF CORE
	MOVEI	T1,1(T1)	;ROUND UP TO K
	LSH	T1,-1		;NOW TO K
	CAMGE	T1,MINMAX	;OVER THE SMALLEST POSSIBLE
	  MOVE	T1,MINMAX	;NO, USE THAT INSTEAD
	MOVNS	T1		;NEGATE THIS TOO
	ADDM	T1,TOTCOR	;DECREMENT
	>
	POPJ	P,
;SUBROUTINE TO UPDATE THE SCHEDULING CONSTANTS

UPDCON:	AOS	STACTV		;ADD A JOB
	HRRZ	T1,Q.ILIM(R)	;GET THE TIME ESTIMATE
	JUMPN	T1,.+3		;ALREADY HAS ONE
	  MOVEI	T1,DEFTIM	;GET THE DEFAULT
	  HRRM	T1,Q.ILIM(R)
	ADDM	T1,TOTTIM	;UPDATE TOTAL TIME SCHEDULED

	IFN	DEFCOR,<
	HLRZ	T1,Q.ILIM(R)	;GET CORE ESTIMATE
	JUMPN	T1,.+3
	  MOVEI	T1,DEFCOR	;GET THE DEFAULT
	  HRLM	T1,Q.ILIM(R)
	LSH	T1,-^D9		;POSITION AS PAGES
	MOVEI	T1,1(T1)	;ROUND UP TO K
	LSH	T1,-1
	CAMGE	T1,MINMAX	;OVER THE SMALLEST POSSIBLE
	  MOVE	T1,MINMAX	;NO, USE THAT INSTEAD
	ADDM	T1,TOTCOR	;UPDATE CORE SCHEDULED
	>
	IFN	DEFPAG,<
	HLRZ	T1,Q.ILIM+1(R)	;GET THE PAGE ESTIMATE
	JUMPN	T1,.+3
	  MOVEI	T1,DEFPAG
	  HRLM	T1,Q.ILIM+1(R)	;STORE THE DEFAULT
	>
	IFN	DEFCDS,<
	HRRZ	T1,Q.ILIM+1(R)	;NUMBER OF PUNCHED CARDS
	JUMPN	T1,.+3
	  MOVEI	T1,DEFCDS	;FILL IN THE DEFAULT
	  HRRM	T1,Q.ILIM+1(R)
	>
	IFN	DEFPTP,<
	HLRZ	T1,Q.ILIM+2(R)	;FEET (METERS) OF PAPER TAPE
	JUMPN	T1,.+3
	  MOVEI	T1,DEFPTP
	  HRLM	T1,Q.ILIM+2(R)	;STORE DEFAULT
	>
	IFN	DEFPLT,<
	HRRZ	T1,Q.ILIM+2(R)	;MINUTES OF PLOTTER TIME
	JUMPN	T1,.+3
	  MOVEI	T1,DEFPLT	;SET THE DEFAULT
	  HRRM	T1,Q.ILIM+2(R)
	>
	POPJ	P,
;BOTTOM SCHEDULER.  NORMALLY CALLED BY JOB PROCESSOR AT END OF REQUEST
;BUT CAN BE CALLED BY TOP LEVEL SCHEDULER TO START INACTIVE STREAMS

SCHDLR:	MOVE	A,MJOB		;GET VALUE OF MJOB
	TLNN	G,GL.SSH!GL.NJN!GL.NLI ;CAN WE SCHEDULE JOBS
	CAILE	S,(A)		;OR IS THIS STREAM OVER MJOB
	  JRST	SCHDLZ		;CANNOT SCHEDULE, RELEASE ANY HELD REQUESTS
	SKIPGE	KSYSTM		;IS TIMESHARING ABOUT TO STOP
	 SKIPE	NXTJOB		;YES, IS THERE A NEXT'ED JOB
	  CAMG	A,STACTV	;OR IS THERE ALREADY ENOUGH STREAMS RUNNING
	   JRST	SCHDLZ		;ONLY DISMISS THIS JOB (IF ANY)
	MOVE	A,[LOWSCD,,QO.SCH]
	SKIPE	Q.DEV(R)	;IS A REQUEST PRESENT
	  HRRI	A,QO.NXT	;YES, INVOKE NXTJOB FUNCTION
QMCALL:	MOVEM	A,Q.OPR(R)	;SAVE REQUEST CODES
	MOVSI	A,'INP'		;QUEUE NAME TO USE
	HLLM	A,Q.DEV(R)
	MOVE	A,PTYTAB-1(S)	;PTY NAME FOR THIS STREAM
	MOVEM	A,Q.PDEV(R)
	MOVEM	R,SAVBAS	;SAVE AC1 ('R') ACROSS CALLS
	MOVEM	S,SAVNDX	;SAVE THE STREAM INDEX ALSO
	HRRI	R,Q.MEM(R)	;START OF PARAMETER AREA
	HRLI	R,Q.LENG!(QC.COR) ;LENGTH OF SAME AND A FLAG
	PUSHJ	P,.QUEER	;CALL THE QMANGR (INDIRECTLY THAT IS)
	MOVE	R,SAVBAS	;RESTORE R
	POPJ	P,		;RETURN TO CALLER
SCHDLZ:	SKIPN	Q.DEV(R)	;ANY REQUEST PRESENT
	  POPJ	P,		;NO, RETURN NOW
	HRRZI	A,QO.COM	;REQUEST COMPLETE
	JRST	QMCALL		;CALL THE QMANGR (IT WILL ZERO THE AREA)
;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+3(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
	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+3(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.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 AVAILABLE 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 UPDATE ADDITIONAL SCHEDULING PARAMETERS JUST PRIOR TO ACTUAL CALL

UPDADD:	MOVE	A,[%CNSTS]	;GET THE STATES WORD FROM THE MONITOR
	GETTAB	A,		;GET IT
	  JRST	UPDA.3		;WHOOPS! NO GETTAB
	TRNN	A,ST%NRL!ST%NLG	;OPERATOR SET NO LOGINS
	  JRST	UPDA.3		;NO, OK TO PROCEED
	TLON	G,GL.NLI	;SET NOT TO TRY A SCHEDULE
	  TLO	G,GL.MJB	;WASN'T SET BEFORE, CLEAN UP CORE AND PTYS
	TLOA	G,GL.SLP	;DON'T SLEEP INFINITELY (AND SKIP THE NEXT)
UPDA.3:	  TLZ	G,GL.NLI	;CLEAR PROHIBITED FLAG

	IFN	WHKSYS,<
	MOVE	A,[%NSKTM]	;GET KSYS TIMER
	GETTAB	A,		;SEE IF TIMESHARING IS ABOUT TO STOP
	  SETZ	A,		;PRETEND NO
	JUMPE	A,UPDA.4	;REALLY NO, SKIP THE REST
	TLO	G,GL.SLP	;SET NOT TO HIBERNATE INFINITLY
	SUBI	A,^D15		;BACK OFF 15 MINUTES FOR BATCH
	IMULI	A,^D60		;CONVERT TO SECONDS
	SKIPN	A		;IS THERE EXACTLY 15 MINUTES LEFT
	  SETO	A,		;YES, DON'T STORE THE ZERO
	SKIPN	KSYSTM		;FIRST TIME WE NOTICED THIS STATE
	  TLO	G,GL.MJB	;YES, CLEAN UP CORE AND INACTIVE PTYS
UPDA.4:	MOVEM	A,KSYSTM	;SAVE FOR THE SCHEDULERS
	>
	IFN	DEFCOR,<
	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,-^D10		;CONVERT TO K
	MOVEM	A,CORMAX	;SAVE FOR THE SCHEDULER
UPDA.1:	SKIPE	ACORE		;IS THERE A VALUE HERE
	  JRST	UPDA.2		;YES, USE IT
	MOVE	A,[%NSNXM]	;GET THE AVAILABLE USER CORE
	GETTAB	A,
	  MOVSI	A,1		;ASSUME 256K
	IMULI	A,3		;COMPUTE 1.5 * AVAILABLE MEMORY
	LSH	A,-^D11		;CONVERT TO K
	MOVEM	A,CORPHY	;SAVE PHYSICAL LIMIT
UPDA.2:
	>
	POPJ	P,		;RETURN FOR A SCHEDULE CALL TO THE QMANGR
;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,

;HERE WHEN MJOB DECREASED (OR EXIT/RESET TYPED FOR THE FIRST TIME)
;GIVE BACK PTYS AND CHANNELS BELONGING TO INACTIVE STREAMS

GIVPTY:	MOVEI	S,1		;START WITH STREAM 1
GIVP.1:	SKIPL	BASTBL-1(S)	;IS THIS STREAM ACTIVE OR
	SKIPN	PTYTAB-1(S)	;DOES IT OWN A PTY
	  JRST	GIVP.2		;STILL ACTIVE OR NO PTY ALLOCATED
	TLO	G,GL.UC0	;RETURN CHANNEL 0 IF NO ASSIGNMENT
	PUSHJ	P,CHNPTY	;FIND OLD PTY CHANNEL
	  JRST	GIVP.2		;FUNNY, IF ENTRY IN PTYTAB, MUST BE IN CHNTBL
	PUSHJ	P,RELPTY	;GIVE IT BACK
GIVP.2:	CAIGE	S,JOBMAX	;PASSED ALL STREAMS
	  AOJA	S,GIVP.1	;LOOK FOR NEXT INACTIVE STREAM
	JRST	CLRA.1		;RETURN CORE AND RETURN
;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
	SKIPN	STACTV		;WAS THIS THE LAST ACTIVE STREAM
	  PUSHJ	P,WAKEME	;YES, SO DISPATCH LOOP CAN FIND EXIT OR RESET
	CAMN	S,HIACTV	;WAS STREAM TO GO IDLE THE HIGHEST ACTIVE
	  PUSHJ	P,FHIACT	;YES, FIND NEW HIACTV
	MOVE	A,MJOB		;GET CURRENT MJOB VALUE
	SKIPN	KSYSTM		;IF SHUTDOWN IS SCHEDULED, CLEAN UP THIS STREAM
	TLNE	G,GL.SSH!GL.NLI	;IF THESE ARE SET THERE IS AN IMPLIED
	  SETZ	A,		;MJOB 0 TO CLEAN UP CORE AND PTY CHANNELS
	CAIL	A,(S)		;WAS THIS STREAM BEYOND MJOB
	  POPJ	P,		;NO, JUST RETURN
	HLLZ	IO1,.JPCHN(R)	;GET PTY CHANNEL ASSIGNMENT
	PUSHJ	P,RELPTY	;RELEASE IT AND THE ASSIGNMENT
	CAMGE	S,HIACTV	;ARE THERE ANY ACTIVE JOBS BEYOND THIS ONE
	  POPJ	P,		;YES, CANNOT RETURN CORE YET
	MOVEI	B,(A)		;RETURN CORE FOR THOSE ABOVE MJOB
	CAMGE	A,HIACTV	;UNLESS THE HIGHEST ACTIVE JOB IS STILL BEYOND MJOB
CLRA.1:	  MOVE	B,HIACTV	;THEN RETURN CORE FOR THOSE BEYOND HIACTV
	HRRZ	A,BASTBL-1(B)	;COMPUTE CORE NEEDED FOR THE B'TH JOB
	MOVEI	A,.JSIZE(A)	;FIRST FREE AFTER IT
	SKIPN	B		;UNLESS REDUCING ALL THE WAY (MJOB = 0)
	  HRRZ	A,BASTBL	;CANCEL THE ABOVE WORK, THERE IS NO ZERO'TH JOB
	MOVEM	A,.JBFF##	;RESET VALUE OF .JBFF
	SOS	A		;COMPUTE LAST LOC NEEDED
	CORE	A,		;RETURN THE UNUSED CORE
	  JFCL			;NICE TRY THOUGH
	POPJ	P,
	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, seq# /]
	MOVE	T1,Q.SEQ(R)	;GET THE SEQUENCE NUMBER
	PUSHJ	P,TTYDEC	;OUTPUT THAT
	PUSHJ	P,TTCRLF	;END THE LINE
	>
	IDENT	MYVERS		;OUTPUT BATCH VERSION INFORMATION

	IFN	VMINOR,<
	MOVEI	CH,VMINOR+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 /]
	MOVE	T1,Q.SEQ(R)	;GET THE SEQUENCE NUMBER
	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

	IFE	LOGSWS,<
	PUSHJ	P,REDUCE	;COUNT THE CHARACTERS IN THE USERS NAME
	  JRST	NEWJ.1		;NULL, SKIP THIS OUTPUT
	TXTLOG	[ASCIZ/ for /]
	MOVE	T1,[POINT 6,Q.USER(R)] ;BEGINNING AT Q.USER, T2 = COUNT OR CHARS
NEWJ.0:	ILDB	CH,T1		;GET A CHARACTER
	MOVEI	CH," "(CH)	;CONVERT SIXBIT TO ASCII
	PUSHJ	P,PUTLOG	;DUMP IT INTO THE BUFFER
	SOJG	T2,NEWJ.0	;GET THE WHOLE NAME
	>
NEWJ.1:	MOVE	A,Q.LSTR(R)	;GET THE STRUCTURE
	DEVPPN	A,200000	;GET THE PPN ASSOCIATED
	  JRST	ILLOGS		;NOT A DISK, ILLEGAL STRUCTURE
	CAME	A,MYPPN		;IS IT A FUNNY DEVICE
	  JRST	ILLOGS		;IS ONE OF THE ERSATZ DEVICES, GIVE ERROR
	MOVE	A,Q.LDIR(R)	;WHERE IS THE LOG FILE TO GO
	CAME	A,Q.PPN(R)	;INTO THE USERS AREA
	  PUSHJ	P,LOGPRV	;NO, NEED TO CHECK ACCESS
	PUSHJ	P,CTLSPC	;GET THE FILE SPEC FOR THE CTL FILE
	MOVEI	T2,[ASCIZ/Input from /] ;STRING TO BE ADDED
	MOVE	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  /]
	MOVE	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
	PUSHJ	P,PUTTAB	;ADD A TAB

	IFN	DEFCOR,<
	TXTLOG	[ASCIZ/Core:/]
	HLRZ	T1,Q.ILIM(R)	;GET JOBS CORE ESTIMATE
	LSH	T1,-^D9		;POSITION AS PAGES
	MOVEI	T1,1(T1)	;ROUND UP
	LSH	T1,-1		;MAKE K OUT OF IT
	PUSHJ	P,LOGDEC	;OUTPUT IT AS DECIMAL
	MOVEI	CH,"K"		;ADD SUFFIX
	PUSHJ	P,PUTLOG
	TXTLOG	[ASCIZ/   /]	;ALIGN THE NEXT PART
	>
	TXTLOG	[ASCIZ/Unique:/]
	LDB	T1,[POINT 2,Q.IDEP(R),2]
	CAILE	T1,1		;IS JOB UNIQUE
	  TLOA	T1,'YES'	;YES, SAY SO
	MOVSI	T1,'NO '	;NO
	PUSHJ	P,LOGSIX	;OUTPUT THE PROPER RESPONSE
	PUSHJ	P,PUTTAB	;ADD A TAB
	TXTLOG	[ASCIZ/Restart:/]
	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
	SETZ	T2,		;WILL DETERMINE Q.AFTR AND Q.DEAD PARMS
	SKIPE	Q.AFTR(R)	;DID JOB HAVE AN AFTER PARAMETER
	  MOVEI	T2,1(T2)	;YES, BUMP COUNT
	SKIPE	Q.DEAD(R)	;DID IT HAVE A DEADLINE PARAMETER
	  MOVEI	T2,1(T2)	;YES, BUMP COUNT
	JUMPE	T2,NEWJ.2	;JOB HAD NEITHER, SKIP OUTPUT
	PUSHJ	P,LGCMNT	;NEW COMMENT LINE
	TXTLOG	[ASCIZ/Job had /]
	SOSE	T2		;DID IT HAVE BOTH
	  TXTLOG [ASCIZ/both /] ;YES, SAY BOTH
	SKIPE	Q.AFTR(R)	;WAS THERE AN AFTER PARAMETER
	  TXTLOG [ASCIZ/an AFTER /]
	SKIPE	T2		;DID IT HAVE BOTH
	  TXTLOG [ASCIZ/and /] ;YES, USE CORRECT ENGLISH
	SKIPE	Q.DEAD(R)	;WAS THERE A DEADLINE
	  TXTLOG [ASCIZ/a DEADLINE /]
	TXTLOG	[ASCIZ/parameter/] ;END THE LINE
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
	TXTJOB	[ASCIZ/LOGIN /]	;SEND THE LOGIN COMMAND
	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
NEWJ.6:	IFN	LOGSWS,<	;SEND SWITCHES ALONG THE LOGIN LINE
	TXTJOB	[ASCIZ\ /SPOOL:ALL/TIME:\]
	HRRZ	T1,Q.ILIM(R)	;GET THE TIME ESTIMATE
	PUSHJ	P,SNDDEC	;OUTPUT IT FOR LOGIN

	IFN	DEFCOR,<
	TXTJOB	[ASCIZ\/CORE:\]	;IF ENFORCING CORE ESTIMATES
	HLRZ	T1,Q.ILIM(R)	;GET THE CORE ESTIMATE IN WORDS
	LSH	T1,-^D9		;CONVERT TO PAGES
	MOVEI	T1,1(T1)	;ROUND UP TO K
	LSH	T1,-1		;NOW CONVERT TO K
	PUSHJ	P,SNDDEC	;OUTPUT DECIMAL VALUE
	>
	HRRZ	C,Q.DEV(R)	;GET THE STATION NUMBER
	TLNE	G,GL.RMT	;THIS MONITOR HAVE REMOTE LOGIC
	CAILE	C,77		;OR AN INVALID STATION
	  JRST	NEWJ.3		;END THE LINE
	JUMPE	C,NEWJ.3	;SKIP STATION 0 ALSO
	TXTJOB	[ASCIZ\/LOCATE:\]
	HRRZ	T1,Q.DEV(R)	;RE-GET THE STATION (C COULD BE KLUNKED)
	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

NEWJ.8:	> ;END OF THE IFN LOGSWS

	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
	IFE	LOGSWS,<	;AVOID THE FOLLOWING IF ALREADY TOLD LOGIN
	PUSHJ	P,INMONM	;PUT THE JOB IN MONITOR MODE
	MOVE	A,[2,,B]	;ARGUMENT LIST
	HRRZ	B,J		;JOB NUMBER
	HRRZ	C,Q.ILIM(R)	;JOB'S TIME ESTIMATE
	HRLI	C,.STTIM	;SET TIME FUNCTION
	JBSET.	A,		;TRY THE EASY WAY
	  PUSHJ	P,SETTIM	;DIDN'T WORK, SEND THE TEXT
	MOVE	A,[2,,B]
	HRRZ	B,J
	MOVE	C,[.STSPL,,37]	;SET SPOOL ALL
	JBSET.	A,
	  PUSHJ	P,SETSPL	;SEND THE TEXT

	IFN	DEFCOR,<
	MOVE	A,[2,,B]
	HRRZ	B,J
	HLRZ	C,Q.ILIM(R)	;GET THE CORE ESTIMATE IN WORDS
	HRLI	C,.STCOR	;SET CORE FUNCTION
	JBSET.	A,		;SET THE LIMIT
	  JFCL			;COULDN'T BUT THERE IS NO SET CORE COMMAND
	>
	HRRZ	C,Q.DEV(R)	;LOCATION OF THIS JOB
	TLNE	G,GL.RMT	;DOES SYSTEM HAVE REMOTE STATION FEATURE
	CAILE	C,77		;OR IS THE STATION TOO LARGE
	  JRST	NORMOT		;DON'T NEED THE LOCATE
	JUMPE	C,NORMOT	;OR ZERO
	TXTJOB	[ASCIZ/LOCATE /] ;SEND THE LOCATE COMMAND
	HRRZ	T1,Q.DEV(R)	;AND THE STATION
	PUSHJ	P,SNDOCT	;IT'S OCTAL
	PUSHJ	P,SNDCLF	;SEND CR-LF
	PUSHJ	P,IOWAIT	;WAIT FOR NEXT INPUT REQUEST

NORMOT:	> ;END OF THE IFE LOGSWS
	TLZ	R,RL.LGI	;CLEAR LOGIN SEQUENCE NOW
	MOVE	T1,Q.IDEP(R)	;GET THE DEPENDENCY WORD
	TLNN	T1,(1B3)	;CHECK THE NON-RESTARTABLE REQUEUED BIT
	  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::
CKPNTS:	MOVE	T1,Q.CBIT(R)	;GET WHERE TO START PARAMETER
	TLZ	T1,770000	;CLEAR ANY QMANGR BITS (ARTIFICALLY PRESERVED)
	TLNN	T1,007777	;IS IT A RESTART LABEL
	  JRST	CKLINE		;NO, TRY A LINE NUMBER
	LSH	T1,6		;POSITION THE 5 CHARACTER LABEL
	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
		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,SJBINF	;TYPE OUT SUBJOB INFORMATION
	OUTSTR	[ASCIZ/OPR--Respond with BL-OPERATOR <LINE>
Waiting...
/]
	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	\VBATCH,		;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	VWHO,<.VERSN \VEDIT,>
	IFN	VWHO,<.VERSN \VEDIT,\VWHO,>
;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,"."		;MONITOR LEVEL
	  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
	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
USRDAT:	JSP	T1,REPOSI	;REPOSITION THE CTL FILE
	TLZ	F,FL.PER	;CLEAR A FLAG
	MOVEI	CH,"."		;WILL SEND A PERIOD TO THE JOB
	JRST	CPYLOP		;THIS LINE IS USER DATA
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
	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
	PUSHJ	P,SETCHK	;SET UP THE CHECKPOINT LABEL
	MOVSI	A,(1B0)		;GET THE "NOT RESTARTABLE" BIT
	ANDCAM	A,Q.IDEP(R)	;AND SET /RESTART:YES
	MOVEI	A,QO.CHK	;QMANGR FUNCTION CHECKPOINT
	PUSHJ	P,QMCALL	;CALL THE QMANGR
	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
	  PUSHJ	P,SETCHK	;SET SET UP AS IF CHECKPOINT
	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,SJBINF	;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 BL-$
Waiting...
/]
	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,SAVGBL	;SAVE IN A TEMP
	PUSHJ	P,BALINE	;ECHO THE BATCH COMMAND
	MSGLOG	[ASCIZ/BTNICS Illegal character specified for /]
	TXTLOG	@SAVGBL		;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
	MOVE	A,[2,,B]	;SET UP FOR JBSET
	HRRZ	B,J		;GET THE JOB NUMBER
	HRLI	C,.STTIM	;SET TIME FUNCTION
	JBSET.	A,		;TRY IT WITH THE UUO
	  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,DECCON	;DECREMENT SCHEDULING CONSTANTS
	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,UPDADD	;UPDATE ANY ADDITIONAL PARMS BEFORE SCHEDULING
	PUSHJ	P,SCHDLR	;SCHEDULE NEW WORK OR JUST GET RID OF THIS ONE
	SKIPN	Q.DEV(R)	;IS THERE A NEW JOB
	  JRST	CLOS.2		;NO, GO INACTIVE
	HRLI	R,RL.INI	;SET NEW JOB FLAGS
	MOVE	F,[FL.INI,,FR.INI] ;INITIALIZE THE OTHER FLAG REG
	PUSHJ	P,UPDCON	;UPDATE CONSTANTS TO REFLECT NEW JOB
	PUSHJ	P,CLRZER	;CLEAR INTERJOB LOCATIONS
	JRST	NEWJOB		;FIRE UP THE NEW JOB
CLOS.2:	SKIPE	Q.AFTR(R)	;ANY JOBS WITH AFTER PARAMETERS LEFT
	  TLO	G,GL.SLP	;DON'T HIBERNATE IF QMANGR CAN'T CALL DAEMON
	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
	CAMN	T1,[SIXBIT/NERROR/] ;KILL WITH NO ERROR RECOVERY
	  JRST	CLOSJB		;YES, GO KJOB THE JOB
	SETZ	T1,		;MUST HAVE BEEN KILL FLUSH
	DPB	T1,[POINT 3,Q.IDEP(R),8] ;SET /Z:0 FOR KJOB
	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
	IMULI	A,^D60*^D1000	;CONVERT TO MILLISECONDS
	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 IS THE ACTUAL SUBROUTINE TO DO THE AUTO KJOB

ATOKJB:	TLZ	F,FL.SIL	;CLEAR SILENCE IF WE ARE GOING TO KJOB THIS JOB
	MOVE	A,[2,,B]	;SET FOR JBSET. UUO
	HRRZ	B,J		;ADD THE JOB NUMBER
	MOVE	C,[.STTIM,,^D30] ;GIVE SOME EXTRA TIME FOR KJOB
	JBSET.	A,		;TRY TO PREVENT TIME EST EXCEEDED DURING KJOB
	  JRST	KJOB.1		;DIDN'T WORK, SKIP SET WATCH NONE TOO
	MOVE	A,[2,,B]	;RESET
	HRRZ	B,J		;THE JOB NUMBER AGAIN
	MOVSI	C,.STWAT	;SET WATCH NONE
	JBSET.	A,		;TO ELIMINATE ANY LOGOUT CHATTER
	  JFCL
KJOB.1:	PUSHJ	P,INMONM	;MAKE SURE THE JOBS IN MONITOR MODE
	TLNE	R,RL.TIM	;NEED A TIME STAMP
	  PUSHJ	P,PUTPER	;YES, OUTPUT A PERIOD, THAT WILL TIME STAMP THE LINE
	TXTJOB	[ASCIZ/KJOB /]	;SEND THE KJOB COMMAND
	SIXJOB	Q.LSTR(R)	;GIVE KJOB THE STRUCTURE
	PUSHJ	P,SNDCOL	;ADD A COLON
	SIXJOB	Q.LNAM(R)	;SEND THE LOG FILE NAME
	PUSHJ	P,SNDPER	;AND A PERIOD
	HLLZ	T1,Q.LEXT(R)	;CLEAR AND POSSIBLE JUNK
	PUSHJ	P,SNDSIX	;SEND THE EXTENSION
	MOVE	T1,Q.LDIR(R)	;WHERE IS THE LOG FILE
	CAMN	T1,Q.PPN(R)	;IN THE LOGGED IN PPN
	 SKIPE	Q.LDIR+1(R)	;YES, BUT IS THERE AN SFD SPEC
	  SKIPA			;MUST SEND THE LOG FILE PPN
	   JRST	KJOB.3		;CAN SKIP THE PPN SPEC
	MOVEI	CH,"["
	PUSHJ	P,SNDCHR	;SEND OPENING OF PPN
	HLRZ	T1,Q.LDIR(R)	;GET PROJECT NUMBER
	PUSHJ	P,SNDOCT	;SEND IN OCTAL
	PUSHJ	P,SNDCMA	;ADD A COMMA
	HRRZ	T1,Q.LDIR(R)	;GET PROGRAMMER NUMBER
	PUSHJ	P,SNDOCT	;SEND THAT
	MOVEI	D,Q.LDIR(R)	;SEE IF AN SFD SPECIFIED
	PUSHJ	P,SETSFD	;SET UP FOR SFD
	TLNE	D,-1		;IS D A PPN
	  JRST	KJOB.4		;YES, WE ALREADY SENT IT
	MOVEM	D,.JLABL(R)	;SAVE FOR NOW
KJOB.5:	AOS	T1,.JLABL(R)	;BUMP TO NEXT SFD LEVEL
	SKIPN	T1,2(T1)	;IS THERE ANY MORE
	  JRST	KJOB.4		;NO, END OF THE SPEC
	PUSHJ	P,SNDCMA	;OUTPUT A COMMA
	PUSHJ	P,SNDSIX	;SEND THE SFD NAME
	JRST	KJOB.5		;CONTINUE FOR ALL LEVELS
KJOB.4:	MOVEI	CH,"]"
	PUSHJ	P,SNDCHR	;SEND END OF PPN
KJOB.3:	TXTJOB	[ASCIZ\=/W/B/Z:\] ;SEND SOME SWITCHES
	LDB	T1,[POINT 3,Q.IDEP(R),8] ;GET /OUTPUT:N PARAMETER
	PUSHJ	P,SNDDEC	;SEND AS DECIMAL
	LDB	T1,[POINT 3,Q.IDEP(R),8] ;GET /OUTPUT:N PARAMETER AGAIN
	SKIPE	T1		;DON'T NEED THE SWITCHES IF /Z:0
	  PUSHJ	P,VSWTCH	;SEND ALL THE /V SWITCHES
	MOVEI	CH,CHR.CR	;GET A CARRIAGE RETURN
	PUSHJ	P,SNDCHR	;SEND HERE INSTEAD OF CALLING SNDCLF
	MOVEI	CH,CHR.LF	;DON'T WANT TO SEND BUFFER
	PUSHJ	P,SNDCHR	;UNTIL WE'VE RELEASED THE LOG FILE
	PUSHJ	P,CLSLOG	;CLOSE OUT THE LOG FILE
	TLO	R,RL.KJB	;MARK KJOB SENT
	PUSHJ	P,PTYSND	;NOW SEND THE PTY BUFFER
KJOB.K:	PUSHJ	P,IOWAIT	;WAIT FOR RETURN TO MONITOR MODE
	TLNN	J,JL.ULI	;DID THE JOB GO AWAY
	  POPJ	P,		;YES, RETURN
	PUSHJ	P,INMONM	;GET BACK TO MONITOR MODE
	TXTJOB	[ASCIZ/DEASSIGN/] ;TRY TO REMOVE ANY LOGICAL NAME CONFLICTS
	PUSHJ	P,SNDCLF	;SEND THAT LINE FIRST
	PUSHJ	P,IOWAIT	;AND WAIT AGAIN
	TXTJOB	[ASCIZ\KJOB/B/Z:4\] ;TRY SOMETHING SIMPLIER
	PUSHJ	P,SNDCLF	;END LINE AND OUTPUT BUFFER
	PUSHJ	P,IOWAIT	;WAIT FOR NEXT INPUT REQUEST
	TLNN	J,JL.ULI	;IS IT STILL LOGGED IN
	  POPJ	P,		;NO, THAT GOT IT
	PUSHJ	P,TTCRLF	;A NEW LINE TO THE OPERATOR
	PUSHJ	P,SJBINF	;TYPE SUBJOB NUMBER AND MONITOR JOB NUMBER
	MSGTTY	[ASCIZ/BATCON unable to KJOB.
OPR--Please attach to the job and kill it. Then respond BL-$
Waiting.../]
	PUSHJ	P,OPRRES	;WAIT FOR THE RESPONSE
	JRST	KJOB.K		;SEE IF JOB IS STILL THERE (OR TRY AGAIN)
;SEND ALL THE /V SWITCHES TO KJOB

VSWTCH:	LDB	T1,[POINT 6,Q.PRI(R),35] ;PRIORITY VALUE
	MOVEI	CH,"R"		;IS /VR:N
	PUSHJ	P,VSWT.4	;SEND THE REAL VALUE
	MOVE	T1,Q.SEQ(R)	;SEQUENCE NUMBER
	MOVEI	CH,"S"		;IS /VS:N
	PUSHJ	P,VSWT.1	;SEND THE SWITCH IF NON-ZERO
	HLRZ	T1,Q.ILIM+1(R)	;PAGES OF OUTPUT
	MOVEI	CH,"L"		;IS /VL:N
	PUSHJ	P,VSWT.1	;SEND THE SWITCH IF NON-ZERO
	HRRZ	T1,Q.ILIM+1(R)	;PUNCHED CARDS
	MOVEI	CH,"C"		;IS /VC:N
	PUSHJ	P,VSWT.1	;SEND THE SWITCH IF NON-ZERO
	HLRZ	T1,Q.ILIM+2(R)	;FEET (METERS) OF PAPER TAPE
	MOVEI	CH,"T"		;IS /VT:N
	PUSHJ	P,VSWT.1	;SEND THE SWITCH IF NON-ZERO
	HRRZ	T1,Q.ILIM+2(R)	;PLOTTER TIME
	MOVEI	CH,"P"		;IS /VP:N
	PUSHJ	P,VSWT.1	;SEND THE SWITCH IF NON-ZERO
	LDB	T1,[POINT 3,Q.LMOD(R),29] ;LOG FILE DISPOSITION
	JUMPE	T1,VSWT.2	;ZERO?? MAKE PRESERVE
	MOVEI	CH,"D"		;DISP = DELETE
	CAIL	T1,3		;WAS IT DELETE OR TOO BIG
	  JRST	VSWT.3		;YES, DELETE THE FILE
	JRST	VSWT.2-1(T1)	;GET THE RIGHT CODE
VSWT.2:	SKIPA	CH,["P"]	;1 = PRESERVE
	MOVEI	CH,"R"		;2 = RENAME
VSWT.3:	PUSH	P,CH		;3 = DELETE
	MOVSI	T1,'/VD'	;SEND /VD
	PUSHJ	P,SNDSIX
	PUSHJ	P,SNDCOL	;AND A COLON
	POP	P,CH		;RESTORE CODE
	JRST	SNDCHR		;SEND PROPER CODE AND RETURN

;SUBROUTINE TO SEND /V AND THE CHARACTER AND THE VALUE

VSWT.1:	JUMPE	T1,CPOPJ	;DON'T SEND IF VALUE IS ZERO
VSWT.4:	PUSH	P,T1		;SAVE VALUE
	PUSH	P,CH		;AND THE CHARACTER
	MOVSI	T1,'/V '	;SEND COMMON CHARACTERS FOR ALL SWITCHES
	PUSHJ	P,SNDSIX
	POP	P,CH		;RESTORE SWITCH CODE
	PUSHJ	P,SNDCHR	;SEND IT
	PUSHJ	P,SNDCOL	;ADD A COLON
	POP	P,T1		;RESTORE VALUE
	JRST	SNDDEC		;SEND IN DECIMAL AND RETURN
	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
	TLO	G,GL.PTA	;INDICATE PTY ACTIVITY
	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.KJB ;MORE DIALOGUE OUTPUT (OR COMMENTS)
	  PUSHJ	P,SJBINF	;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.KJB ;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
	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
	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,SJBINF	;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
	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
	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:	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
	MSTIME	A,		;TIME WHEN NOTICED
	MOVEM	A,NJNTIM	;START THE TIMER RUNNING
	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.MJB	;GIVE MESSAGE ONLY ONCE
	MSGTTY	[ASCIZ/Jobs cannot LOGIN. Stopping further scheduling/]
ANLY.6:	MOVE	A,[REQTIM*^D60*^D1000] ;REQUEUE TIME IN MILLISECONDS
ANLY.2:	SETZ	B,		;CLEAR COUPLED REGISTER
	ASHC	A,-^D17		;CONVERT TO UNIVERSAL DATE/TIME
	DIV	A,[^D86400000]	;MILLISECONDS IN A DAY
	TLO	A,400000	;INDICATE + FORM OF AFTER
	MOVEM	A,Q.AFTR(R)	;QMANGR WILL FIGURE THE REAL TIME OF DAY
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
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
	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
	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
	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
	TXTJOB	[ASCIZ/SET TIME /] ;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 SEND 'SET SPOOL ALL' TO THE JOB

SETSPL:	TXTJOB	[ASCIZ/SET SPOOL ALL/]
	PUSHJ	P,SNDCLF	;END LINE AND SEND BUFFER
	JRST	IOWAIT		;WAIT FOR INPUT REQUEST

;SUBROUTINE TO CLEAR AREA THAT MUST BE ZERO'ED BETWEEN JOBS

CLRZER:	SETZM	.JZERO(R)	;CLEAR THE FIRST
	HRLI	A,.JZERO(R)	;BUILD BLT POINTER
	HRRI	A,.JZERO+1(R)
	BLT	A,.JZRLA-1(R)	;CLEAR THE NEEDED WORDS
	POPJ	P,

;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,DECCON	;REDUCE THE SCHEDULING CONSTANTS
	PUSHJ	P,REMCTL	;REMOVE ANY OLD CTL FILE ASSIGNMENTS
	MOVEI	A,QO.REQ	;FUNCTION REQUEUE
	PUSHJ	P,QMCALL	;CALL THE QMANGR
	HRRZS	R		;CLEAR FLAGS
	PUSHJ	P,QTS		;GO DORMANT, WILL NOT RETURN HERE
;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
	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 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 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 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:	IFN	OLDALT,<
	TLNE	F,FL.PLS	;DONT BOTHER IF NOT PLEASE
	PUSHJ	P,COMTRM	;CHECK FOR TERMINATOR (CONVERT ALTMODES)
	  JFCL
	>
	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 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 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,SJBINF	;THAT WE COULDN'T DO IT
	MSGTTY	[ASCIZ/Job cannot be put in monitor mode.
OPR--Type BL-$ to try again (or after you have killed the job)
Waiting.../]
	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

;SUBROUTINE TO SET THE PARAMETER AREA FOR A CHECKPOINT (T1 IS THE CHECKPOINT LABEL)

SETCHK:	TRNE	T1,77		;CANNOT USE A 6 CHARACTER LABEL
	  JRST	SETC.1		;DID, IT CAN NEVER BE FOUND (NO ROOM IN THE QUEUE)
	LSH	T1,-6		;POSITION
	DPB	T1,[POINT 30,Q.CBIT(R),35] ;STORE THE LABEL
	POPJ	P,		;RETURN
SETC.1:	POP	P,(P)		;REMOVE CALL
	MOVEI	T1,[ASCIZ/BTNCRL CHKPNT or REQUEUE labels cannot be over 5 characters long./]
	JRST	NORM.1		;ISSUE ERROR AND GOTO %FIN::

;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)

CHNLOG:	HRRI	IO2,USELOG	;ENTRY FOR LOG FILE
	JRST	CHNGET
CHNCTL:	HRRI	IO2,USECTL	;ENTRY FOR CTL FILE
	JRST	CHNGET
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
	TRNN	D,USEPTY	;ANOTHER CHECK FOR PTY USAGE
	  JRST	CHNG.2		;NO, LOOK AT THE NEXT ENTRY
	HLRZS	D		;ISOLATE THE STREAM NUMBER
	SKIPL	BASTBL-1(D)	;IS THE PTY USED BY AN INACTIVE STREAM
	  HRLM	IO1,CHNMAY	;YES, SAVE POSSIBLE CHANNEL
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
;HERE WHEN NO CURRENT ASSIGNMENT EXISTS. ALLOCATE A FREE ONE

CHNG.7:	TRNN	IO2,USEPTY	;DO WE WANT THIS FOR A PTY
	  JRST	CHNG.4		;NO, SEE IF ANY FREE CHANNELS
	HLRZ	IO1,CHNMAY	;GET CHANNEL OF INACTIVE PTY
	JUMPN	IO1,CHNG.8	;TAKE IT NOW INSTEAD OF WAITING FOR ALL TO BE USED
CHNG.4:	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:	HLRZ	IO1,CHNMAY	;CAN WE HAVE AN OLD PTY CHANNEL NOW
	JUMPE	IO1,CHNG.6	;YES, BUT THERE WEREN'T ANY
CHNG.8:	HLRZ	D,CHNTBL(IO1)	;GET OWNER OF OLD PTY
	SETZM	PTYTAB-1(D)	;AND CLEAR THE NAME OF THE PTY
	JRST	CHNG.5		;NOW TAKE IT AWAY
CHNG.6:	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 PTY CHANNEL AND ASSIGNMENT

PTYFAL:	TLO	G,GL.SLP	;IF CANNOT GET A PTY, DON'T HIBERNATE
RELPTY:	SETZM	PTYTAB-1(S)	;CLEAR PTY VALUE
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

;HERE TO REMOVE ANY OLD CTL FILE ASSIGNMENTS AT DISMISSAL OF THE JOB

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
	SUBTTL	I/O Handling Routines

;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

;ROUTINE TO OPEN CHANNEL AND LOOKUP CTL FILE

FNDCTL:	MOVE	A,[400000,,17]	;PHYSICAL ONLY,,DUMP MODE
	MOVE	B,Q.CSTR(R)	;STRUCTURE FOR CTL FILE
	TLNN	F,FL.ACC	;NEED AN ACCESS CHECK
	  JRST	FNDC.1		;NO, SKIP THIS CHECK
	DEVPPN	B,200000	;SEE IF DEVICE IS A REAL DISK
	  JRST	ILCTLS		;NO, ILLEGAL CTL STRUCTURE
	MOVE	B,Q.CSTR(R)	;RESTORE STRUCTURE FOR OPEN
FNDC.1:	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
	MOVEM	C,.JPROT(R)	;SAVE THE PROTECTION BITS AFTER EACH LOOKUP
	TLZE	F,FL.ACC	;NEED TO CHECK READ ACCESS
	  PUSHJ	P,CTLPRV	;YES, CHECK THEM BEFORE ANY FURTHUR READING
	SKIPE	.JCUSI(R)	;FIRST CALL FOR NEW LOOKUP
	  TLO	R,RL.UST	;NO, MARK USETI NEEDED
	POPJ	P,

;ROUTINE TO SET 4 WORD LOOKUP BLOCK FOR CTL FILE

CTLSPC:	SETZ	C,
	SKIPE	A,Q.CRNM(R)	;IS FILE RENAMED
	  JRST	[MOVSI B,'QUD'	;YES, SET RENAMED EXTENSION
		MOVE D,QUEPPN	;OWNER OF RENAMED FILES
		POPJ P,]	;RETURN
	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 OPEN CHANNEL AND GET LOG FILE IN UPDATE MODE

FNDLOG:	MOVE	A,[400000,,17]	;PHYSICAL ONLY,,DUMP MODE
	MOVE	B,Q.LSTR(R)
	SETZ	C,
	PUSHJ	P,CHANIO	;OPEN THE CHANNEL
	  OPEN	0,A
	  JRST	LOGOER		;LOG FILE OPEN ERROR
	PUSHJ	P,LOGSPC	;GET THE 4 WORD LOOKUP BLOCK
	PUSHJ	P,CHANIO	;LOOKUP ON CORRECT CHANNEL
	  LOOKUP 0,A
	  JRST	FNDL.1		;WHAT WAS THE ERROR
	TLO	R,RL.UST	;WILL NEED USETO
	HLRE	IO2,D		;GET SIZE OF THE FILE
	JUMPGE	IO2,FNDL.2	;IS ALREADY IN BLOCKS
	MOVNS	IO2
	ADDI	IO2,DSKBLK-1	;ROUND UP TO FULL BLOCK
	PUSH	P,IO2+1		;SAVE REG ABOUT TO BE CLOBBERED BY DIVIDE
	IDIVI	IO2,DSKBLK	;CONVERT WORDS TO BLOCKS
	POP	P,IO2+1		;RESTORE THE REG
FNDL.2:	AOS	IO2		;BUMP TO NEXT BLOCK
	TLNN	F,FL.LUP	;HAS THE LOG FILE BEEN UPDATED
	  MOVEM	IO2,.JLUSI(R)	;NO, SAVE NEW POSITION
	MOVEI	D,Q.LDIR(R)	;POINT TO THE PATH SPEC AGAIN
	PUSHJ	P,SETSFD	;RESET SFD POINTER OR PPN
	PUSHJ	P,CHANIO	;GET IN UPDATE MODE
	  ENTER	0,A
	  JRST	LOGENE		;LOG FILE ENTER ERROR
	POPJ	P,		;RETURN WITH CHANNEL OPENED
FNDL.1:	HRRZ	IO2,B		;COPY ERROR CODE FROM LOOKUP
	JUMPN	IO2,LOGLKE	;REPORT LOOKUP ERROR
	SETZ	C,		;INITIAL CREATE OF THE LOG FILE
	HLLZS	B		;CLEAR OLD DATA
	TLZ	F,FL.LUP	;CLEAR ANY PENDING UPDATES
	JRST	FNDL.2		;AND ENTER THE FILE

;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
;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:	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
	TLNN	R,RL.UST	;NEED THE USETI
	  JRST	GETCT2		;NO
	PUSHJ	P,CHANIO	;POSITION THE FILE
	  USETI	0,@.JCUSI(R)
GETCT2:	MOVE	A,[POINT 7,.JCTLB(R)]
	MOVEM	A,.JCPTR(R)	;SET NEW BYTE POINTER
	MOVEI	A,CTLCHR	;AND COUNT
	MOVEM	A,.JCCNT(R)
	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
	>

;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 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:	LDB	T1,[POINT 3,Q.CMOD(R),29] ;GET /DISP: PARAMETER
	CAIG	T1,1		;WAS IT RENAME OR DELETE
	  JRST	CTLD.1		;NO, CHECK IF ARTIFICALLY PRESERVED
	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
	SETZB	A,B		;CLEAR THE NAME
	SETZB	C,D		;REALLY DELETE IT
CTLD.R:	TLZN	R,RL.DCT	;IN CASE THIS CALL DID THE CHKACC
	  JRST	RELREL		;NO PRIVS, GET OUT NOW
	PUSHJ	P,CHANIO	;EXECUTE THE IO SELECT
	  RENAME 0,A		;DELETE THE FILE
	  JFCL			;NICE TRY
	JRST	RELREL		;RELEASE CHANNEL AND ASSIGNMENT AND RETURN
CTLD.1:	SKIPL	Q.CBIT(R)	;IS IT ARTIFICALLY PRESERVED BY QUEUE
	  POPJ	P,		;NO, RETURN NOW
	TLO	G,GL.UC0	;USE CHANNEL 0 IF NONE ASSIGNED
	PUSHJ	P,CHNCTL	;SEE IF ASSIGNMENT EXISTS
	  PUSHJ	P,FNDCTL	;LOOKUP ON 0 OR OLD CHANNEL
	PUSHJ	P,CHANIO	;CLOSE THE FILE SO THAT ACCESS DATES
	  CLOSE	0,0		; ARE UPDATED CORRECTLY
	PUSHJ	P,CTLSPC	;REBUILD THE LOOKUP BLOCK FOR THE RENAME
	HLLZ	C,.JPROT(R)	;GET THE PROTECTION FROM THE LOOKUP
	TLZ	C,700777	;CHANGE PROTECTION TO 0XX
	JRST	CTLD.R		;DO THE RENAME
;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
;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

CTLPRV:	SKIPE	Q.CRNM(R)	;IS THE FILE RENAMED TO THE QUE
	  JRST	CTLP.1		;IF CAN RENAME THE FILE, OBVIOUSLY CAN DO THE REST
	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
;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 = /]
CTLI.1:	POP	P,T1		;RESTORE STATUS
	PUSHJ	P,LOGOCT	;OUTPUT THAT AS OCTAL
	JRST	CTLABJ		;AND CANCEL THIS JOB

;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 = /]
	JRST	CTLI.1		;OUTPUT ERROR CODE (0(P)) AND CANCEL THE JOB

;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,

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

ILCTLS:	SKIPA	T1,[[ASCIZ/BTNSND CTL file structure is not a disk. Device is /]]
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
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
;HERE TO REPORT VARIOUS LOG FILE ERRORS TO THE OPERATOR AND THEN CANCEL THE JOB

ILLOGS:	SETZ	IO1,		;GET HERE BEFORE ANY ASSIGNMENTS WERE MADE
	MOVEI	IO2,[ASCIZ/Illegal structure/]
ILLO.1:	PUSHJ	P,TTYALL	;TYPE OUT AVAILABLE INFORMATION
	OUTSTR	(IO2)		;APPEND THE ERROR MESSAGE
	OUTSTR	[ASCIZ/ for the LOG file. Structure - /]
	MOVE	T1,Q.LSTR(R)	;GET THE STRUCTURE NAME
	PUSHJ	P,TTYSIX	;OUTPUT THAT TOO
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.KJB	;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

LGOER1:	SETZ	IO1,		;GET HERE BEFORE ANY ASSIGNMENT IS MADE
LOGOER:	MOVEI	IO2,[ASCIZ/OPEN failed/]
	JRST	ILLO.1		;APPEND SOME MORE STUFF AND CANCEL THE JOB

LOGENE:	SKIPA	IO2,[[ASCIZ/ENTER failed/]]
LOGLKE:	MOVEI	IO2,[ASCIZ/LOOKUP error/]
LGLKE1:	PUSHJ	P,TTYALL	;TYPE OUT AVAILABLE INFORMATION
	OUTSTR	(IO2)		;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
	JRST	ILLO.2		;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
;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.KJB	;WAS THE KJOB LINE SENT
	  JRST	[OUTCHR CH	;YES, GIVE THIS TO THE OPERATOR
		POPJ P,]	;AND RETURN
	TLNE	R,RL.TIM	;NEED A TIME STAMP
	  PUSHJ	P,LOGSTP	;YES, DO IT
	SOSGE	.JLCNT(R)	;ROOM IN THIS BUFFER
	  PUSHJ	P,DMPLOG	;NO, MAKE SOME
	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

; IF CALLED BY CLSLOG, COMPUTE THE NUMBER OF WORDS TO BE WRITTEN
;	ON THE LOG.  NO SENSE IN WRITING BLOCKS OF ZEROS.

DMPL.4:	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,DMPL.2	;PROCEED IF NOT CHANNEL 0
	PUSHJ	P,RELCHN	;RELEASE THE TEMP CHANNEL

;  FALL INTO DMPL.2 ON THE NEXT PAGE
; 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-1	;ADJUST FOR THE CHARACTER ABOUT TO BE STORED
	MOVEM	A,.JLCNT(R)	;AND 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
;HERE TO CHECK USERS ACCESS TO THE SPECIFIED LOG FILE
;HAVE ALREADY DETERMINED IT IS NOT IN THE USERS OWN DIRECTORY

LOGPRV:	MOVE	A,[400000,,17]	;DUMP MODE, PHYSICAL ONLY
	MOVE	B,Q.LSTR(R)	;GET THE STRUCTURE
	SETZ	C,		;NO BUFFERS
	OPEN	0,A		;OPEN THE SPECIFIED STRUCTURE
	  JRST	LGOER1		;REPORT THE OPEN ERROR
	PUSHJ	P,LOGSPC	;GET THE LOG FILE SPECIFICATION
	LOOKUP	0,A		;FIND THE FILE
	  JRST	LOGP.1		;WHAT WAS THE LOOKUP ERROR
	LDB	B,[POINT 9,C,8]	;GET THE FILE PROTECTION
	HRLI	B,.ACAPP	;CHECK FOR APPEND ACCESS
	JRST	LOGP.2		;DO THE CHKACC
LOGP.1:	TRNE	B,-1		;ONLY INTERESTED IN ERROR # 0
	  JRST	LOGP.3		;ANYTHING OTHER THAN NON-EXISTANT IS AN ERROR
	MOVEI	D,Q.LDIR(R)	;POINT TO THE PATH SPEC
	PUSHJ	P,SETSFD	;SET UP FOR POSSIBLE SFD
	TLNE	D,-1		;IS D A PPN OR SFD POINTER
	  JRST	LOGP.U		;PPN, LOOKUP THE UFD[1,1]
	MOVEI	B,6		;POSSIBLE DEPTH OF SFD
	SKIPN	A,SFDPAT+1(B)	;FIND LAST SFD LEVEL
	  SOJG	B,.-1		;GUARANTEED OF FINDING ONE
	SETZM	SFDPAT+1(B)	;CLEAR IT (ITS IN A)
	MOVSI	B,'SFD'		;FIND THE SFD IN PATH POINTED TO BY D
	JRST	LOGP.L		;LOOK IT UP AND CHKACC FOR CREATE
LOGP.U:	MOVE	A,Q.LDIR(R)	;GET THE PPN
	MOVSI	B,'UFD'		;FIND THE USERS UFD
	MOVE	D,MFDPPN	;OWNER OF ALL UFDS
LOGP.L:	SETZ	C,		;CLEAR
	LOOKUP	0,A		;FIND THE UFD OR SFD INVOLVED
	  JRST	LOGP.3		;ASSUME THIS MEANS NO ACCESS
	LDB	B,[POINT 9,C,8]	;GET THE UFD/SFD PROTECTION
	LSH	B,^D9		;UFD/SFD BITS IN 18-26
	HRLI	B,.ACCRE	;SEE IF CAN CREATE INTO IT
LOGP.2:	MOVE	C,Q.LDIR(R)	;UFD OWNER
	MOVE	D,Q.PPN(R)	;REQUESTOR
	MOVEI	A,B		;POINT TO THE ARGUMENT BLOCK
	CHKACC	A,		;ASK THE FILE SYSTEM
LOGP.3:	  SETO	A,		;ASSUME NO GOOD
	RELEASE	0,0		;RELEASE THE CHANNEL NOW
	JUMPGE	A,CPOPJ		;ACCESS ALLOWED, RESUME NORMAL PATH
	PUSHJ	P,LOGSPC	;GET SPEC FOR BAD LOG FILE
	PUSH	P,[LOGP.4]	;FAKE OUT A PUSHJ CALL
	PUSH	P,D		;SAVE PPN OR PATH POINTER
	PUSH	P,B		;SAVE EXTENSION
	PUSH	P,A		;AND THE FILE NAME
	MOVE	D,Q.PPN(R)	;GET THE JOBS PPN
	MOVEM	D,Q.LDIR(R)	;STORE USERS PPN AS THE LOG FILE DIRECTORY
	SETZM	Q.LDIR+1(R)	;CLEAR SFD SPEC IF ANY
	MSGLOG	[ASCIZ/BTNCWL Cannot write LOG file /]
	MOVE	T1,Q.LSTR(R)	;GET THE STRUCTURE
	JRST	LOGF.3		;USE PART OF LOGFIL, STACK HAS RETURN ADDRESS
LOGP.4:	PUSHJ	P,LGCMNT	;LOGFIL WILL RETURN HERE, PREPARE FOR ANOTHER COMMENT
	TXTLOG	[ASCIZ/	 File will be in /]
	MOVE	T1,Q.PPN(R)	;GET LOGGED IN DIRECTORY
	PUSHJ	P,LOGF.2	;OUTPUT PPN TO THE NEW LOG FILE
	JRST	LGCLF2		;END LINE, BLANK ONE, AND RETURN
;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
SNDPER:	MOVEI	CH,"."		;A PERIOD
	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,"."		;A PERIOD
	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 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
;SUBROUTINE TO OUTPUT A FILE SPECIFICATION TO THE LOG FILE
;ENTER WITH AC'S A-D THE 4 WORD LOOKUP/ENTER BLOCK
;		T1 = THE STRUCTURE
;		T2 = ADDRESS OF A STRING TO APPEND AFTER 'BAFIL'

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
LOGF.3:	PUSHJ	P,LOGSIX	;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


> ;THIS ENDS THE CONDITIONAL IFGE FTOPR THAT OCCURRED AT THE BEGINNING
	IFL	FTOPR,<LSTON>	;RESUME LISTING IF BATOPR ONLY
	SUBTTL	Operator Communications Section

	IFL	FTOPR,<LSTOFF>	;DON'T LIST THE BATCON CALL
	IFGE	FTOPR,<
OPRCOM:	TLNN	G,GL.STA	;ARE WE JUST STARTING UP
	  JRST	OPRC.1		;YES, GO TO BATOPR RIGHT NOW
	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
OPRC.1:
	>
	IFG	FTOPR,<
	MOVEM	G,SAVGBL	;SAVE THE GLOBAL FLAGS FOR BATOPR
	MOVE	A,[SIXBIT/BATOPR/] ;SEGMENT TO GET
	MOVEM	A,TEMP1		;SAVE IN A TEMPORARY LOCATION
	MOVE	1,[EXP <QC.HGH!QC.COR>+TEMP1] ;QUEUER ARGUMENT BLOCK
	PUSHJ	P,.QUEER	;PUSHSEG TO BATOPR
	MOVE	G,SAVGBL	;RESTORE THE GLOBAL FLAGS
	POPJ	P,		;RETURN TO THE DISPATCHER
	>

	IFG	FTOPR,<LSTOFF>	;IF BATCON ONLY, DON'T LIST BATOPR
	IFL	FTOPR,<LSTON>	;RESTORE LISTING MODE IF BATOPR ONLY

	IFLE	FTOPR,< ;CONDITIONALLY ASSEMBLE BATOPR
			;THIS CONDITION IS NOT TERMINATED UNTIL THE COMMON SECTION

BATOPR:
	IFL	FTOPR,<
	MOVE	G,SAVGBL	;RESTORE THE GLOBAL FLAGS
	>
BAOP.1:	TLNN	G,GL.STA	;BATCH STARTED YET
	  OUTCHR ["/"]		;NO, PROMPT WITH A SLASH
	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	NULCMD		;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,NULCMD	;A NULL COMMAND, SEE IF BL-$
	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:	TLNN	G,GL.STA	;IS BATCH STARTED YET
	  JRST	BAOP.1		;NO, STAY HERE LOOKING FOR A START COMMAND
	OUTCHR	["!"]		;NOTE OUR EXIT
	SETOM	TTYINT		;FORCE ANOTHER LOOK AT THE TERMINAL

	IFL	FTOPR,<
	MOVEM	G,SAVGBL	;SAVE FLAGS FOR BATCON
	>
	POPJ	P,		;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
NULCMD:	CAIE	CH,CHR.A1	;WAS IT BL-$
	  JRST	COMCLR		;NO, IGNORE THE BLANK LINE
	PUSHJ	P,LCNTRL	;SET LOOP CONTROL FOR THE FOLLOWING CODE
	TLZ	R,RL.OPR	;CLEAR WAITING FOR OPERATOR FLAG
	POPJ	P,		;RETURN TO THE LOOP CONTROLLER FOR NEXT SUBJOB
;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 DEFCOR,<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	KILL,	;KILL A SUBJOB
IFN DEFCOR,<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	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!GL.MJB	;SET SOME FLAGS
	SKIPN	STACTV		;ARE THERE STREAMS RUNNING
	  TLO	G,GL.STA	;NO, LET THE DISPATCHER CLEAN UP
	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	COMCLR		;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
	EXCH	T1,MJOB		;STORE NEW, GET OLD
	CAMLE	T1,MJOB		;DID THE VALUE DECREASE
	  TLO	G,GL.MJB	;YES, TELL THE DISPATCHER
	JRST	COMCLR		;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	COMCLR
;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
	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
	MOVEM	T1,UTIME	;STORE VALUE, NO RANGE CHECK
	JRST	COMCLR		;END OF THE COMMAND

;TIME	COMMAND - SET TOTAL TIME FOR ALL BATCH JOBS

DDTIME:	JSP	S,POSNUM	;CHECK IF A NUMBER, GET THE ARGUMENT
	MOVEM	T1,ATIME	;STORE VALUE
	JRST	COMCLR		;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	DEFCOR,<	;COMMANDS THAT EFFECT THE CORE SETTINGS

;MCORE	COMMAND - SET LARGEST SINGLE JOB

DDMCOR:	JSP	S,POSNUM	;GET THE NUMERIC ARGUMENT
	MOVE	T2,[%NSCMX]	;RANGE GOES TO CORMAX
	GETTAB	T2,
	  MOVSI	T2,1		;ASSUME 256K
	LSH	T2,-^D10	;CONVERT TO K
	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	COMCLR		;END OF THE COMMAND

;CORE	COMMAND - SET TOTAL CORE FOR ALL BATCH JOBS

DDCORE:	JSP	S,POSNUM	;GET THE NUMERIC VALUE
	MOVE	T2,[%ODK4S]	;RANGE GOES TO AVAILABLE VIRTUAL CORE
	GETTAB	T2,
	  SETZ	T2,		;CLEAR IT FOR NOW
	HRLOI	S,-2		;NOW DISCOVER OUR CPU TYPE
	AOBJP	S,.+2		;WILL JUMP IF ON A KA-10
	  LSH	T2,-1		;THIS GETTAB IS IN PAGES ON KI-10 MONITORS
	SKIPN	T2		;SO CONVERT TO K CAUSE THATS BATCON UNITS
	  MOVEI	T2,^D256	;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	COMCLR		;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
	CAML	T1,MINMAX	;.GE.MINMAX IS OK ALSO
	  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
	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 DEFCOR 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
	IDIVI	T1,^D60000	;T2=MILLISECONDS
	PUSH	P,T2		;SAVE MILLISECONDS
	IDIVI	T1,^D60		;T1=HOURS, T2=MINUTES
	PUSH	P,T2		;SAVE MINUTES
	JUMPE	T1,WHAT.3	;SKIP OUTPUT IF HOURS = 0
	PUSHJ	P,TYBLD2	;OUTPUT 2 DIGITS AS HH:MM:SS (LEADING BLANK)
	PUSHJ	P,TTYCOL	;ADD A COLON
WHAT.3:	POP	P,T1		;RESTORE MINUTES
	PUSHJ	P,TYBLD2	;OUTPUT 2 DIGITS ALSO (LEADING BLANK)
	PUSHJ	P,TTYCOL	;ADD A COLON
	POP	P,T1		;RESTORE MILLISECONDS
	IDIVI	T1,^D1000	;CONVERT TO SECONDS
	PUSHJ	P,TYDEC2	;OUTPUT SECONDS
	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

	IFN	DEFCOR,<
	OUTSTR	[ASCIZ/CORE:/]
	SKIPN	T1,ACORE	;GET OPERATOR VALUE IF ANY
	  MOVE	T1,CORPHY	;NONE, GET PHYSICAL USER CORE
	PUSHJ	P,TTYDEC	;TYPE IT OUT
	OUTSTR	[ASCIZ/ MCORE:/]
	SKIPN	T1,UCORE	;GET VALUE FOR A SINGLE JOB
	  MOVE	T1,CORMAX	;NONE, USE CORMAX
	PUSHJ	P,TTYDEC	;TYPE IT OUT ALSO
	PUSHJ	P,TTCRLF	;END OF THIS LINE
	>
	OUTSTR	[ASCIZ/TIME:/]
	SKIPLE	T1,KSYSTM	;GET TIME TO KSYS IF ANY
	 CAMLE	T1,ATIME	;USE SMALLER OF OPERATOR PARM OR KSYS
	  MOVE	T1,ATIME	;GET THE TIME VALUE
	PUSHJ	P,CURR.T	;TYPE THE VALUE

	IFN	WHKSYS,<
	SKIPLE	T1,KSYSTM	;SHOULD WE TELL THE OPERATOR WE CHANGED TIME
	 CAMLE	T1,ATIME	;IS KSYS SMALLER THAN HIS (HER) SET PARAMETER
	  SKIPA			;YES, THATS WHAT WAS PRINTED
	   OUTSTR [ASCIZ/ (changed by "KSYS")  /]
	>
	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
CURR.F:	OUTSTR	[ASCIZ/ when active jobs finish/]
	JRST	CURR.4		;OUTPUT CR-LF AND EXIT

CURR.6:	IFN	WHKSYS,<
	SKIPL	KSYSTM		;IS BATCH SHUT DOWN YET
	  JRST	CURR.7		;NO, SKIP THIS OUTPUT
	OUTSTR	[ASCIZ/Batch processing /]
	SKIPN	STACTV		;ARE THERE ANY STREAMS ACTIVE
	  JRST	CURR.8		;NO, SAY HAS ENDED
	OUTSTR	[ASCIZ/will end/]
	JRST	CURR.F		;APPEND WHEN JOB FINISH AND EXIT
CURR.8:	OUTSTR	[ASCIZ/has ended due to "KSYS"/]
	JRST	CURR.4		;END THIS LINE AND EXIT
	>
CURR.7:	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 monitor job numbers, 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:	TLNN	G,GL.NLI	;IS NO LOGINS SET
	  JRST	CURR.E		;NO, EXIT FROM THE CURRENT COMMAND
	OUTSTR	[ASCIZ/"SET SCHED" bits prohibit scheduling of new jobs/]
	JRST	CURR.4		;END THIS LINE AND EXIT

CURR.T:	CAME	T1,[377777,,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
;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	;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
;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

POSNUM:	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,GETNUM	;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

GETNUM:	SETZ	T1,		;EVENTUAL NUMBER
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:	IMULI	T1,^D10		;ACCUMULATE THE NUMBER
	ADDI	T1,-"0"(CH)	;INCLUDE THE NEW DIGIT
	JRST	GETN.1		;GET MORE CHARACTERS
GETN.3:	CAIN	CH," "		;IS IT A SPACE
	  JUMPE	T1,GETN.1	;YES, IGNORE LEADING SPACES
	JRST	CPOPJ1		;NON SPACE OR A BLANK IS A TERMINATOR

;SUBROUTINES TO TYPE OUTPUT WITH A LEADING BLANK OR LEADING ZERO
;NOT CALLED BY BATCON SEGMENT SO DON'T NEED TO BE IN COMMON CODE

TYBLD2:	SKIPA	CH,[" "]	;ENTRY FOR LEADING BLANK
TYDEC2:	MOVEI	CH,"0"		;ENTRY FOR LEADING ZERO
	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 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+3(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+3(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


> ;THIS ENDS THE CONDITIONAL IFLE FTOPR FOR THE BATOPR SEGMENT
	IFL	FTOPR,<LSTOFF>	;DON'T LIST THE COMMON ROUTINES IN BATOPR
	IFG	FTOPR,<LSTON>	;RESTORE LISTING FOR COMMON SUBROUTINES
	SUBTTL	Common Routines for BATCON & BATOPR

	IFN	FTOPR,< ;DON'T FORCE OUT LITERALS IF BOTH BATCON AND BATOPR
	LSTOFF	;DONT NEED TO LIST THEM
	LIT
	LSTON
	RELOC	0
	>

DEFINE	UNDEFS(A,B)<
	LSTOFF
	IF2,<IRP A<IFNDEF A,<A==B>>>
	LSTON>

	UNDEFS	<UUOTXT,UUOSND,UUOSIX,UUOSN6,UUOMTY,UUOMLG,UUOIDN>,UUOERR

CODEON==1			;ASSEMBLE THE FOLLOWING CODE
IFL FTOPR,<IF2,<CODEON==0	;EXCEPT IN PASS 2 OF BATOPR
	BLOCK	<LOWDAT-.>>>	;LET PASS1 DEFINE THE SYMBOLS BUT THE CODE
				;IS REALLY LOADED BY BATCON SEGMENT

REPEAT CODEON,<		;SINCE THE BATOPR SEGMENT ONLY USES THESE ROUTINES
			;NOT LOADS OR REDEFINES THEM, THEY ARE NOT LISTED IN BATOPR
			;NOR IS ANY LOW SEGMENT DATA GENERATED. ONLY THE SYMBOLS
			;ARE DEFINED TO RESOLVE THE REFERENCES IN THE BATOPR CODE

;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
UUOCNT==.-UUOTBL		;NUMBER OF KNOWN UUOS

UUOERR:	OUTSTR	[ASCIZ/? Illegal BATCON UUO/]
	EXIT	1,		;RETURN TO THE MONITOR
	JRST	.-1		;CAN'T CONTINUE FROM THAT

;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 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

	IFN	OLDALT,<
	CAIE	CH,CHR.A2	;OLD ALTMODE
	CAIN	CH,CHR.A3	;OTHER OLD ALTMODE
	  MOVEI	CH,CHR.A1	;YES, MAKE A STD ALTMODE OUT OF THEM
	>
	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:	OUTSTR	[ASCIZ/? /]	;START WITH A QUESTION MARK
	OUTSTR	@.JBUUO##	;APPEND THE MESSAGE
	JRST	TTCRLF		;APPEND A CR-LF AND RETURN TO THE PROGRAM
;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

;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 JOBNAME AND PPN
	OUTSTR	[ASCIZ/  /]	;ALIGN THE REST
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 JOB NAME AND PPN TO THE OPERATOR

TTYJPN:	MOVE	T1,Q.JOB(R)	;GET THE JOB NAME
	PUSHJ	P,TTYSIX	;OUTPUT THAT
	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
	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
	MSTIME	T1,		;GET CURRENT TIME
	SUB	T1,NJNTIM	;TIME WHEN NOTICED
	MOVMS	T1		;JUST THE ABSOLUTE VALUE
	TLO	G,GL.SLP	;ASSUME INTERVAL IS NOT OVER
	SUB	T1,[NJNINT*^D60*^D1000] ;OVER THE INTERVAL
	JUMPL	T1,CPOPJ	;NO, GIVE CANNOT SCHEDULE RETURN
	TLZ	G,GL.NJN!GL.SLP	;CLEAR SOME FLAGS
	JRST	CPOPJ1		;GIVE GOOD RETURN
	SUBTTL	Subroutines to Get / Used by the QMANGR

	IFE	<FTOPR!ONESEG>,< ;SWITCH TO LOW SEGMENT IF APPROPRIATE
	LSTOFF	;FORCE OUT LITERALS BEFORE SWITCHING
	LIT
	LSTON
	RELOC	0
	>

	IFN	ONESEG,<

;SUBROUTINE TO GETSEG THE QMANGR AND CALL IT. RETAINS THE QMANGR FOR RE-USE

	QMANGR==400010		;ENTRY POINT OF THE QMANGR

.QUEER:	MOVEM	17,QRSA+17	;NEED TO SAVE ALL THE REGS FIRST
	MOVEI	17,QRSA
	BLT	17,QRSA+16	;SO QMANGR CAN USE ANY IT WANTS TO
	HRRI	1,.GTPRG	;FIND OUT IF WE ALREADY HAVE THE QMANGR
	HRLI	1,-2		;-2 IS MY HIGH SEGMENT NAME
	GETTAB	1,
	  SETZ	1,		;NO HIGHSEG, MUST GET IT
	CAMN	1,[SIXBIT/QMANGR/] ;SEE IF IT REALLY IS THE QMANGR
	  JRST	QUEU.1		;YES, JUST CALL IT
	MOVEI	1,2		;MUST GETSEG THE QMANGR, COULD HAVE BEEN SUPERSEDED
	MOVSI	2,'SYS'		;WHERE QMANGR LIVES
	MOVE	3,[SIXBIT/QMANGR/] ;HIS(HER) NAME
	SETZB	4,5		;CLEAR OTHER UNINTERESTING ARGUMENTS
	SETZB	6,7		;MORE ARGUMENTS
	GETSEG	1,		;DO THE GETSEG
	  HALT	.		;LET THE MONITOR GIVE THE ERROR
QUEU.1:	MOVE	1,QRSA+1	;NEED AC1 FOR THE QMANGR
	MOVE	17,QRSA+17	;AND A PUSH DOWN LIST
	PUSHJ	17,QMANGR	;CALL THE QMANGR
	MOVSI	17,QRSA		;RESTORE THE REGS
	BLT	17,17		;ALL OF THEM
	POPJ	P,		;RETURN TO THE CALLER

	> ;END OF THE IFN ONESEG
;SUBROUTINE TO COMPUTE A PRIORITY FOR A JOB IN THE INPUT QUEUE.
;CALLED BY THE QMANGR DURING A SCHEDULING PASS. CHANCES ARE THAT
;THE BATCON HIGH SEGMENT IS GONE NOW SO WE CANNOT REFERENCE ANY OF
;THE LABELS BACK THERE. ACCUMULATOR 1 IS THE ADDRESS OF AN ENTRY
;BEGINNING WITH Q.MEM.  RETURN A PRIORITY FOR THIS JOB IN AC1.
;SINCE WE ARE USING THE QMANGR'S REGISTERS, DEFINE NEW SYMBOLIC NAMES.
;CAN USE AC'S 2,3,4 FOR SCRATCH WORK.

QP==1	;POINTER TO THE QUEUE ENTRY
S2==2	;SCRATCH AC
S3==3	;   "    "
S4==4	;   "    "
S5==5	;SCRATCH AFTER SAVING

LOWSCD:	PUSH	P,S5		;SAVE A REGISTER
	SKIPN	STACTV		;ANY STREAMS ACTIVE
	  JRST	LOWS.1		;NO, SKIP THE UNIQUE TEST
	SETZ	S5,		;CLEAR
	LDB	S2,[POINT 2,Q.IDEP(QP),2] ;GET THE UNIQUE PARAMETER
	CAILE	S2,1		;IS IT UNIQUE:0(NO)
	  SETO	S5,		;NO, SET NO OTHER JOBS SAME PPN
	MOVEI	S2,1		;START WITH STREAM 1
UNIQ.1:	CAME	S2,SAVNDX	;ARE WE LOOKING AT OURSELF
	SKIPL	S3,BASTBL-1(S2)	;OR AT AN INACTIVE STREAM
	  JRST	UNIQ.2		;YES, SKIP THIS STREAM
	MOVE	S4,Q.PPN(S3)	;GET PPN OF THE RUNNING STREAM
	CAME	S4,Q.PPN(QP)	;SAME GUY
	  JRST	UNIQ.2		;NO, SKIP THIS STREAM
	JUMPN	S5,REJECT	;IF THIS IS UNIQUE, REJECT IT NOW
	LDB	S4,[POINT 2,Q.IDEP(S3),2] ;GET UNIQUENESS OF THE OTHER JOB
	CAILE	S4,1		;IT TOO MUST BE UNIQUE:0(NO)
	  JRST	REJECT		;WASN'T, REJECT THIS FOR NOW
UNIQ.2:	CAMGE	S2,HIACTV	;PASS OVER ALL ACTIVE STREAMS
	  AOJA	S2,UNIQ.1	;NO, CONTINUE SEARCH
LOWS.1:	MOVE	S2,Q.IDEP(QP)	;SEE IF THE QMANGR WANTS THIS CANCELLED
	TLNE	S2,(1B3)	;IS THE CANCEL BIT TURNED ON
	  JRST	THIS1		;YES, SELECT THIS ONE NOW
	SKIPE	S3,NXTJOB	;OR THE OPERATOR NEXT'ED IT
	 CAME	S3,Q.SEQ(QP)	;SAME AS NEXT SEQUENCE
	  SKIPA			;NOT THE SAME SEQUENCE NUMBER
	   JRST	NEXT1		;SELECT THIS ONE NOW
	SKIPGE	KSYSTM		;RUNNING AFTER KSYS TIME HAS EXPIRED
	  JRST	REJECT		;YES, AND THIS IS NOT THE OPERATORS SELECTION
	IFN	DEFCOR,<
	HLRZ	S3,Q.ILIM(QP)	;GET THE CORE ESTIMATE
	JUMPN	S3,.+2		;NEED A DEFAULT
	  MOVEI	S3,DEFCOR	;YES, PROVIDE ONE
	LSH	S3,-^D9		;CONVERT TO PAGES FIRST
	MOVEI	S3,1(S3)	;ROUND UP TO K
	LSH	S3,-1		;NOW TO K
	CAMGE	S3,MINMAX	;OVER THE SMALLEST POSSIBLE
	  MOVE	S3,MINMAX	;NO, USE THAT INSTEAD
	MOVE	S4,S3		;MAKE A COPY
	ADD	S4,TOTCOR	;SEE IF THIS TAKE US OVER THE TOTAL
	SKIPN	S5,UCORE	;IS THERE A SINGLE JOB MAXIMUM
	  MOVE	S5,CORMAX	;NO, USE CORMAX
	CAIGE	S5,(S3)		;DOES THIS JOB FIT
	  JRST	REJECT		;NO, REJECT THIS JOB
	SKIPN	S5,ACORE	;IS THERE A SUM OF CORE MAXIMUM
	  MOVE	S5,CORPHY	;NO, USE PHYSICAL CORE LIMIT
	CAIGE	S5,(S4)		;DOES THIS FIT WITH ALL THE OTHERS
	  JRST	REJECT		;NO, REJECT THIS JOB
	>
	HRRZ	S2,Q.ILIM(QP)	;GET THE TIME REQUESTED
	JUMPN	S2,.+2		;NEED A DEFAULT
	  MOVEI	S2,DEFTIM	;YES, SUPPLY ONE
	MOVE	S3,S2		;MAKE A COPY
	ADD	S3,TOTTIM	;COMPUTE NEW TOTAL IF WE SELECT THIS JOB
	SKIPE	S4,KSYSTM	;IS THERE A KSYS TIMER RUNNING
	CAMLE	S4,ATIME	;YES, USE THE SMALLER OF THAT OR ATIME
	  MOVE	S4,ATIME	;USE ATIME IF SMALLER OR NO KSYS TIMER
	CAMG	S2,UTIME	;OVER THE SINGLE JOB MAXIMUM
	CAMLE	S3,S4		;OR PUT US OVER THE ACCUMULATED TOTAL
	  JRST	REJECT		;REJECT IF ONE OF THE ABOVE
	MOVNS	S2		;COMPUTE (7200.-TIME)
	ADDI	S2,^D7200
	JUMPGE	S2,.+2
	  SETZ	S2,
	IDIVI	S2,3		;ONE POINT FOR EVERY 3 SECONDS UNDER 2 HRS
	SKIPN	S3,Q.AFTR(QP)	;WHEN DID THIS JOB START AGING
	  MOVE	S3,Q.CREA(QP)	;WHEN IT WAS CREATED
	MOVNS	S3
	ADD	S3,Q.TIME(QP)	;HOW LONG HAS IT BEEN WAITING
	JUMPGE	S3,.+2
	  SETZ	S3,		;PROTECT AGAINST BAD DATA
	IDIVI	S3,^D100	;1 POINT FOR EACH 30 SECONDS OF WAITING
	ADD	S2,S3		;ADD THEM TOGETHER
	LDB	S3,[POINT 6,Q.PRI(QP),35] ;GET THE EXTERNAL PRIORITY
	IMULI	S2,1(S3)	;BUMP FOR HIGHER PRIORITY
	LSH	S2,-1		;BUT NOT BY TOO MUCH
	AOS	QP,S2		;BUMP BY ONE, PUT INTO AC1
	JRST	LOWXIT		;RETURN TO THE QMANGR

NEXT1:	SETZM	NXTJOB		;CLEAR NEXT'ED JOB IF FOUND IT
	JRST	THIS1		;AND GIVE IT BIG PRIORITY
REJECT:	TDZA	QP,QP		;REJECT A JOB, CLEAR AC1
THIS1:	HRLOI	QP,377777	;SELECT THIS ONE, GIVE HIGHEST PRIORITY
LOWXIT:	POP	P,S5		;RESTORE A REGISTER
	POPJ	P,		;BACK TO THE QMANGR
	SUBTTL	BATCON Data Base

	LSTOFF	;FORCE OUT LOW SEGMENT LITERALS NOW
	LIT
	LSTON

> ;THIS ENDS THE REPEAT CODEON FOR THE COMMON ROUTINES

LOWDAT:
BASTBL:	BLOCK	JOBMAX	;STREAM DATA BASE POINTERS (ALSO STREAM AC R)
PTYTAB:	BLOCK	JOBMAX	;PTY NAME ASSIGNED TO A STREAM
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
SAVBAS:	BLOCK	1	;SAVED AC 'R' ACROSS QMANGR CALLS
SAVNDX:	BLOCK	1	;SAVED STREAM INDEX FOR SCHEDULING
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)
TTYBLK:	BLOCK	4	;PI-SYSTEM INTERRUPT VECTOR
UTIME:	BLOCK	1	;SCHEDULING PARAMETER SINGLE JOB MAXIMUM
ATIME:	BLOCK	1	;SCHEDULING PARAMETER SUM OF JOBS
TOTTIM:	BLOCK	1	;SUM OF TIME USED BY CURRENT ACTIVE JOBS
MYPPN:	BLOCK	1	;SAVED PPN WHO IS RUNNING BATCON
SAVGBL:	BLOCK	1	;SAVED GLOBAL FLAGS WHEN CALLING BATOPR (OTHERWISE A TEMP)
TEMP1:	BLOCK	1	;ANOTHER TEMP CELL
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
SFDPAT:	BLOCK	11	;SFD BLOCK - WORDS 0,1, AND 10 ARE ALWAYS ZERO
KSYSTM:	BLOCK	1	;NUMBER OF SECONDS UNTIL BATCH SHUTDOWN IF NON ZERO
QUEPPN:	BLOCK	1	;OWNER OF THE QUEUES
MFDPPN:	BLOCK	1	;OWNER OF ALL UFDS

	IFN	DEFCOR,<
UCORE:	BLOCK	1	;SCHEDULING PARAMETER SINGLE JOB MAXIMUM
ACORE:	BLOCK	1	;SCHEDULING PARAMETER SUM OF JOBS
TOTCOR:	BLOCK	1	;SUM OF CORE USED BY CURRENT ACTIVE JOBS
CORMAX:	BLOCK	1	;OPERATOR SET CORMAX
CORPHY:	BLOCK	1	;AVAILABLE USER CORE
MINMAX:	BLOCK	1	;SMALLEST THE USER WILL GET IN K
	>
	IFN	ONESEG,<
QRSA:	BLOCK	20	;REGISTERS SAVED ACROSS QMANGR CALLS
	>
	SUBTTL	Data Base for Each Batch Stream

LASLOW:
	IFGE	FTOPR,<RELOC BATCON>	;ORG OVER CODE TO SAVE SPACE
	IFL	FTOPR,<RELOC BATOPR>	;ORG OVER CODE TO SAVE SPACE
	PHASE	0

;QUEUE PARAMETER AREA MUST BE FIRST AFTER PHASE 0
;SO LOW SEGMENT SCHEDULER CAN USE SYMBOLIC NAMES EVEN THOUGH
;THE AC POINTS SOMEWHERE ELSE (MAYBE)

Q.MEM:!	 BLOCK	1	;HOLD XWD WINDOW BLOCK,WINDOW WORD INDEX
Q.OPR:!	 BLOCK	1	;OPERATION CODE

	QO.CRE==1	;QMANGR FUNCTION CREATE
	QO.SCH==7	;   "      "     SCHEDULE
	QO.COM==10	;   "      "     REQUEST COMPLETE
	QO.REQ==11	;   "      "     REQUEUE REQUEST
	QO.CHK==13	;   "      "     CHECKPOINT
	QO.NXT==14	;   "      "     RELEASE AND SCHEDULE IN ONE

Q.LEN:!	 BLOCK	1	;LENGTHS IN AREA
Q.DEV:!	 BLOCK	1	;DESTINATION DEVICE
Q.PPN:!	 BLOCK	1	;PPN ORIGINATING REQUEST
Q.JOB:!	 BLOCK	1	;JOB NAME
Q.SEQ:!	 BLOCK	1	;JOB SEQUENCE NUMBER
Q.PRI:!	 BLOCK	1	;EXTERNAL PRIORITY
Q.PDEV:! BLOCK	1	;PROCESSING DEVICE
Q.TIME:! BLOCK	1	;PROCESSING TIME OF DAY
Q.CREA:! BLOCK	1	;CREATION TIME
Q.AFTR:! BLOCK	1	;AFTER PARAMETER
Q.DEAD:! BLOCK	1	;DEADLINE TIMES
Q.CNO:!	 BLOCK	1	;CHARGE NUMBER
Q.USER:! BLOCK	2	;USER'S NAME
Q.IDEP:! BLOCK	1	;DEPENDENCY WORD
Q.ILIM:! BLOCK	3	;JOB LIMITS
Q.IDDI:! BLOCK	6	;JOB'S DIRECTORY
Q.CSTR:! BLOCK	1	;FILE STRUCTURE
Q.CDIR:! BLOCK	6	;ORIGINAL DIRECTORY
Q.CNAM:! BLOCK	1	;ORIGINAL NAME
Q.CEXT:! BLOCK	1	;ORIGINAL EXTENSION
Q.CRNM:! BLOCK	1	;RENAMED FILE NAME (0 IF NOT)
Q.CBIT:! BLOCK	1	;BIT 0=PRESERVED BY QUEUE, REST=STARTING BIT
Q.CMOD:! BLOCK	1	;FILE SWITCHES
Q.LSTR:! BLOCK	1	;FILE STRUCTURE
Q.LDIR:! BLOCK	6	;ORIGINAL DIRECTORY
Q.LNAM:! BLOCK	1	;ORIGINAL NAME
Q.LEXT:! BLOCK	1	;ORIGINAL EXTENSION
Q.LRNM:! BLOCK	1	;RENAMED FILE NAME (0 IF NOT)
Q.LBIT:! BLOCK	1	;BIT 0=PRESERVED BY QUEUE, REST=STARTING BIT
Q.LMOD:! BLOCK	1	;FILE SWITCHES
Q.LENG==.-Q.MEM		;LENGTH OF QUEUE AREA
.JREGS:! BLOCK	15	;JOB PROCESSOR REGS 3-17
.JPLST:! BLOCK	.JPSIZ	;PUSH DOWN LIST FOR JOB PROCESSOR
.JCTLB:! BLOCK	DSKBLK*CTLBFR	;SPACE FOR CTL FILE
.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
.JUPLT:! BLOCK	1	;TIME WHEN LOG FILE CHANGED LAST
.JPROT:! BLOCK	1	;PROTECTION OF THE CTL FILE RETURNED BY LOOKUP

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

.JZERO:!		;THINGS TO BE ZERO'ED BETWEEN JOBS IF SCHEDULED VIA 'NXTJOB'
.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
.JZRLA:!		;FIRST WORD NOT TO BE ZERO'ED

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

	IFGE	FTOPR,<END BATCON>
	IFL	FTOPR,<LSTON
		END>		;NO STARTING ADDRESS FOR BATOPR