Google
 

Trailing-Edge - PDP-10 Archives - BB-BT99V-BB_1990 - 10,7/mon/comcon.mac
Click 10,7/mon/comcon.mac to see without markup as text/plain
There are 13 other files named comcon.mac in the archive. Click here to see a list.
TITLE COMCON - COMMAND DECODER AND SAVEGET ROUTINES - V1754
SUBTTL /PFC/RCC/DAL/JBS		02-OCT-90

	SEARCH	F,S,DEVPRM
	$RELOC
	$HIGH
	SALL
	.DIRECT	FLBLST

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
;  OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986,1988,1990.
;ALL RIGHTS RESERVED.

.CPYRT<1973,1990>

XP VCOMCN,1754		;THIS MACRO PUTS VERSION NO. IN STORAGE MAP AND GLOB

COMCON::ENTRY	COMCON	;ALWAYS LOAD COMCON IF LIBRARY SEARCH

;CALLED FROM CLOCK ROUTINE WHEN 'COMCNT' IS GREATER THAN 0
;AS SET BY TTY SERVICE ROUTINE
;ALL AC'S HAVE BEEN SAVED BY CLOCK CHANNEL
;THE COMMAND DECODER CALLS TTYCOM WHICH SCANS FOR TTY WHICH TYPED
SUBTTL	TABLE OF CONTENTS
;               TABLE OF CONTENTS FOR COMCON
;
;
;                        SECTION                                   PAGE
;    1. TABLE OF CONTENTS.........................................   1
;    2. INTRODUCTION..............................................   3
;    3. COMMAND SETUP AND DISPATCH................................   5
;    4. COMMAND RETURN AND CLEANUP................................  12
;    5. COMMAND TABLE.............................................  14
;    6. CORE 0 COMMAND............................................  20
;    7. PJOB & KJOB COMMANDS......................................  21
;    8. START GROUP (START,CSTART,REE,DDT)........................  23
;    9. DUMP & DCORE COMMANDS.....................................  25
;   10. CONTROL-C PROCESSING......................................  26
;   11. SET COMMAND AND UUO
;        11.1   DISPATCH..........................................  29
;        11.2   JBSET.............................................  30
;        11.3   PRIVILEGE TESTS...................................  31
;        11.4   CORMAX AND CORMIN.................................  35
;        11.5   DAYTIME AND SCHED.................................  40
;        11.6   OPR, LOGMIN&MAX BATMIN&MAX........................  41
;        11.7   WATCH.............................................  42
;        11.8   DATE..............................................  44
;        11.9   SPOOL.............................................  45
;        11.10  DEFER/NODEFER.....................................  47
;        11.11  CDR...............................................  48
;        11.12  DISK STUFF........................................  49
;        11.13  ROUTINE TO READ DATE..............................  51
;        11.14  ROUTINES TO PRINT WATCH INFO......................  53
;   12. CONTINUE, CCONT AND JCONT.................................  57
;   13. CORE COMMAND..............................................  60
;   14. CONTROL-T PRINTOUT........................................  65
;   15. SAVE, SSAVE AND GET - COMMAND SETUP.......................  70
;   16. COMMANDS WHICH RUN PROGRAMS...............................  72
;   17. ASSIGN, DEASSIGN AND REASSIGN COMMANDS....................  75
;   18. ATTACH AND DETACH COMMANDS................................  92
;   19. DATASET CONNECT & SYSTEM START............................  99
;   20. DAYTIME COMMAND........................................... 100
;   21. RUNTIME ROUTINE (TIME COMMAND)............................ 101
;   22. SEND COMMAND.............................................. 102
;   23. VERSION COMMAND & PRVERS SUBROUTINE....................... 107
;   24. EXAMINE AND DEPOSIT COMMAND............................... 109

;CONTINUED ON NEXT PAGE
;   25. TTY COMMAND AND SET TTY COMMAND........................... 113
;   26. FINISH AND CLOSE COMMANDS................................. 123
;   27. SUBROUTINES
;        27.1   COMMAND SETUP..................................... 126
;        27.2   GET A WORD........................................ 127
;        27.3   GET CHARACTER..................................... 129
;        27.4   TYPE OUT ROUTINES................................. 130
;   28. SAVGET
;        28.1   PARAMETERS........................................ 143
;        28.2   COMMAND SCAN...................................... 144
;        28.3   RUN AND GETSEG UUO'S.............................. 147
;        28.4   SAVE A JOB........................................ 148
;        28.5   "EXE" SAVE FILES.................................. 151
;        28.6   GET AND RUN COMMANDS.............................. 177
;        28.7   RUN UUO........................................... 179
;        28.8   GETSEG UUO........................................ 182
;        28.9   COMMON CODE....................................... 183
;        28.10  GET FILE FROM DEVICE (R,RUN,GET,GETSEG)........... 186
;        28.11  IO ROUTINES....................................... 192
;        28.12  EXPAND COMPRESSED FILES........................... 195
;        28.13  SUBROUTINES....................................... 201
	SUBTTL	INTRODUCTION

;THE COMMAND AND THEN DISPATCHES(PUSHJ) TO APPROPRIATE
;COMMAND SETUP ROUTINE WITH AC'S SET AS:
;J = JOB NUMBER
;F = ADDRESS OF DEVICE DATA BLOCK TYPING COMMAND, IF ANY
;R = ADDRESS OF JOB'S CORE AREA, = 0 IF NO CORE
;S IS SET TO 0, USED FOR ADDRESS OF SUBSEQUENT CALLS
;U = ADDRESS OF LINE DATA BLOCK OF TTY TYPING COMMAND
;W = ADDRESS OF JOB'S PDB
;P4 = JOB STATUS WORD (C(JBTSTS(J)))
;P1 = 0 (USED FOR SAVGET FLAGS)
;P2 = COMMAND NAME (2ND NAME IF SET)
;THE PUSHDOWN LIST CONTAINS:
;LH(M) = 1B0=1B1= 1 (FLAG FOR COMMAND AT COMMAND LEVEL)
;      = 1B8-17= COMMAND TABLE ENTRY
;-1 (P) = U = ADDRESS OF LDB
;THE FOLLOWING GLOBAL USAGE PREVAILS:
;T3 LAST INPUT CHARACTER
;   ALSO TYPE OUT CHARACTER
;IN GENERAL, T1 - T4 AND P2 - 4 ARE SCRATCH
;AT COMMAND RETURN, IF J = 0 AND A
;  JOB WAS REQUIRED, AN ERROR IS ASSUMED.
;  ALL OTHER ACS CAN HAVE BEEN CHANGED
;UPON RETURN FROM COMMAND SETUP ROUTINE, A CR-LF IS ADDED TO
;MESSAGE AND TTY IS STARTED ON TTY SPECIFIED BY -1(P)
;SEVERAL COMMAND FLAGS ARE CHECKED BEFORE DISPATCHING TO
;COMMAND SETUP ROUTINES TO SEE IF COMMAND IS LEGAL AT THIS TIME
;SEVERAL MORE FLAGS ARE CHECKED UPON RETURN FROM COMMAND SETUP
;ROUTINES(UNLESS AN ERROR HAS OCCURRED) FOR STANDARD
;COMMAND RESPONSE
;IF AN ERROR OCCURS, THE JOB NO.(J) SHOULD BE 0 ON RETURN
;SO THAT JOB WILL NOT BE INITIALIZED IF FIRST COMMAND.
;ERRMES ROUTINE WILL SET J TO 0

;SINCE THE COMMAND DECODER IS CALLED FROM THE CLOCK ROUTINE
;COMMAND SETUP ROUTINE MUST RUN TO COMPLETION QUICKLY
;IF A COMMAND FUNCTION CANNOT DO THIS, IT MUST JUST SET
;THE JOB TO RUNABLE STATUS AND RETURN IMMEDIATELY
;OR DELAY THE COMMAND FOR LATER EXECUTION
;THE FOLLOWING AC USAGE PREVAILS FOR TTY IN/OUT:
;
;INPUT:	U=LDB, T3=CHARACTER		CLOBBERS T1
;
;	CTEXT CLOBBERS W, RETURNS T2=NAME
;	SKIPS		  RETURNS T2=0
;	DEC/OCT IN CLOBBERS P4, RETURNS T2=NUMBER
;	PJPGNO CLOBBERS T2,P4, RETURNS P2=USER
;
;
;OUTPUT:U=LDB, T3=CHARACTER		CLOBBERS T1,S
;
;	CONMES POINTER IN T1
;	OCTPNT/PRTDI8/RADX10 NUMBER IN T1
;		(PRTDI8 CLOBBERS T2)
;	PRNAME NAME IN T2

;P1 ASSIGNMENTS:
;
;PHONLY==1B0			;PHYSICAL ONLY
;INCREMENT==777777		;STARTING ADDRESS OFFSET
	SUBTTL	COMMAND SETUP AND DISPATCH

COMMAN::SE1ENT			;ENTER SECTION 1
	PUSHJ	P,TTYCOM##	;SETUP F,U,J, AND W
				; FOR ANY TTY WHICH HAS TYPED A COMMAND
	  JRST	[AOS CMNOTF##	;NONE FOUND, COUNT THE BUG
		 SOS COMCNT##	;ADJUST COUNT
		 POPJ P,]	;RETURN
IFN FTMP,<MOVEM J,COMJOB##>	;TO AVOID JOBSTS UUO RACE
	PUSHJ	P,SVEUB##	;SAVE EBR AND UBR AND SETUP UBR FOR
				; THE JOB THE COMMAND IS BEING EXECUTED FOR
	PUSH	P,U		;SAVE TTY LINE DATA BLOCK ADDRESS
	LDB	T1,LDPCMX##	;GET FORCED COMMAND INDEX, IF ANY
	MOVEM	T1,.CPLFC##	;SAVE IT FOR COMPARISON
	MOVSI	T2,LDBCMF##	;IS COMMAND FORCED?
	TDNN	T2,LDBCOM##(U)	; ..
	JRST	COM1		;NO, TRY USER COMMANDS
	MOVE	T2,TTFCOM##(T1)	;YES. GET SIXBIT NAME OF COMMAND
	JRST	COM1S		;GO FIND IT
COM1:	PUSHJ	P,CTEXT		;SCAN COMMAND NAME, RETURN IT IN T2
COM1Z:	CAIE	T3,"C"-100	;BREAK ON CONTROL-C?
	JRST	COM10		;NO, TRY LOGICAL NAMES
	MOVE	T2,HALTXT##	;YES--TURN COMMAND INTO HALT
	MOVEI	T1,HALTXT##-COMTAB## ;CALCULATE OFFSET IMMEDIATELY
	MOVE	P3,[XWD UNQTAB##,DISP##] ;SET P3=UNIQNESS BITS, DISPATCH TABLE
	MOVE	P4,[XWD -DISPL##,COMTAB##] ;SET P4=-LENGTH,TABLE LOC
	JRST	COM1E		;GO JOIN COMMON CODE
COM10:	CAMN	P4,[XWD -DISPL2##,COMTB2##] ;IN THE MIDDLE OF A SET COMMAND?
	JRST	COM1A		;YES, DON'T SEARCH LOGICAL NAMES
	JUMPE	T2,COM1S	;BLANK COMMAND CANNOT BE REDEFINED
	JUMPE	W,COM1S		;NO USER DEFINED COMMANDS IF NO PDB
	SKIPN	.PDCMN##(W)	;ANY USER DEFINED COMMANDS TO SEARCH THROUGH?
	JRST	COM1S		;THEN USE SYSTEM TABLES
	MOVE	T3,JBTSTS##(J)	;NEED TO SEARCH PATHOLOGICAL NAMES
	TLNN	T3,SWP!SHF	;IS JOB ON DISK OR ON ITS WAY?
	JRST	COM11		;NO, PROCEED
	HRRI	M,DLYCM		;YES, SET TO SWAP JOB IN
	PUSH	P,(P)		;KEEP THE STACK RIGHT
	JRST	COMDIS		;WAIT FOR IT TO COME IN
COM11:	CAMN	T2,[SIXBIT \R\]	;USER TYPED R COMMAND?
	JRST	COM1S		;YES, THIS CAN'T BE REDEFINED
	MOVE	P4,.PDCMN##(W)	;GET AOBJN POINTER TO COMMAND NAMES
	MOVE	P3,.PDUNQ##(W)	;GET POINTER TO UNIQNESS BITS
	MOVSI	T1,1		;FLAG INDICATING THIS IS USER-COMMAND SEARCH
	PUSHJ	P,FNDABV	;SEE IF WE CAN FIND A MATCH
	  JRST	COM1S		;NO, DEFAULT TO MONITOR'S COMMANDS
;HERE WE SEARCH MONITOR TABLE TO MAKE SURE NO UNIQUENESS CONFLICTS RESULT.
	TRNE	T3,CEXACT!CUNIQ	;DID WE MATCH EXACTLY OR UNIQUELY?
	JRST	COM11C		;YES, DON'T BOTHER WITH MONITOR COMMANDS
	PUSH	P,T1		;SAVE THE FLAGS,,DISPATCH
	PUSHJ	P,FNDCOM	;GO FIND THE COMMAND IN TABLES
	  JRST	COM11A		;ERROR, TAKE USER'S COMMAND
	POP	P,(P)		;ADJUST THE STACK
	JRST	COM1B		;GO JOIN COMMON CODE
				;HERE FOR USER COMMAND
COM11A:	POP	P,T1		;RESTORE THE DISPATCH AND FLAGS
	TRNE	T3,CAMBIG	;WAS THE COMMAND AMBIGUOUS?
	JRST	COM1A0		;YES, IT STILL IS
COM11C:	HLRZ	T3,T1		;SAVE BITS
	ADD	T1,.PDUNQ##(W)	;POINT TO DISPATCH FOR THIS COMMAND
	HRRZS	T1		;CLEAR SECTION CRUD
	HRL	P3,(T1)		;AND SAVE THE DISPATCH IN LH P3
	HRRI	P3,DISP##	;FOR LATER USE
	MOVEI	T1,PLNTXT##-COMTAB## ;SET UP FOR PATHOLOGICAL RUN COMMAND
	MOVE	P4,[XWD -DISPL##,COMTAB##] ;POINT BACK TO MAIN TABLES
	MOVE	P2,PLNTXT##	;GET SIXBIT COMMAND NAME
	JRST	COM1E		;GO JOIN COMMON CODE

;HERE TO SEARCH MAIN COMMAND TABLES
;	WITH	T2/	COMMAND
COM1S:	PUSHJ	P,FNDCOM	;FIND THE COMMAND IN THE TABLES
	  JRST	COM1A0		;NOT FOUND, SEE IF ON FRCLIN
	JRST	COM1B		;GO IF NO ERROR

;ENTRY POINT FOR "SET" COMMAND
COM1A:	SETZ	T1,		;NO FLAGS FOR FULL WORD LDB POINTER
	PUSHJ	P,FNDABV	;LOOK IT UP
	  TRNA			;ERROR
	JRST	COM1B		;GO IF NO ERROR
COM1A0:	MOVE	P2,LINTAB##+FRCLIN## ;GET LDB ADDRESS OF FRCLIN
	CAME	P2,U		;UNKNOWN COMMAND TYPED ON FRCLIN?
	JRST	NOSUCH		;USER MISTYPED
	MOVEI	T1,.RNTXT##-COMTAB## ;GET OFFSET OF .RUN COMMAND
	MOVE	P2,T2		;GET SIXBIT PROG NAME
COM1E:	HRL	M,UNQTAB##(T1)	;GET PREDISPATCH BITS
	HRR	M,DISP##(T1)	;AND GET THE DISPATCH ADDRESS
	MOVE	T2,UNQTAB##(T1)	;GET THE UNIQUENESS BITS
	CAME	P2,PLNTXT##	;USER-DEFINED COMMAND?
	JRST	COM1C		;NO, JOIN COMMON CODE
	TRZE	T3,CM.SAC##	;AUTO-PUSH FLAG LIT?
	TLO	T2,SACFLG	;YES, PROPAGATE
	JRST	COM1C		;AND RE-JOIN COMMON CODE
COM1B:	CAIL	T1,COMPIL##-COMTAB## ;COMPIL-CLASS COMMAND
	CAILE	T1,LASCCL##-COMTAB##
	TRNA			;NO
	MOVEI	T1,COMPIL##-COMTAB## ;FUDGE DISPATCH OFFSET FOR COMPIL
	MOVE	P2,T1		;CALCULATE THE OFFSET
	ADDI	P2,(P4)		; INTO THE COMMAND TABLE
	MOVE	P2,(P2)		;AND GET THE SIXBIT PROG NAME OR COMMAND
	HRRZ	M,P3		;GET DISPATCH
	ADDI	M,(T1)
	HRR	M,(M)
	HLRZ	T2,P3		;NOW POINT TO UNIQUENESS TABLE
	ADDI	T2,(T1)		;POINT TO THE COMMAND ENTRY
	HRL	M,(T2)		;GET THE BITS
	MOVE	T2,(T2)		;GET THE DISPATCH BITS
COM1C:	EXCH	T2,(P)		;SAVE TABLE OFFSET ON THE STACK
	PUSH	P,T2		; BUT KEEP U ON TOP
	ADDI	P3,(T1)		;POINT P3 TO DISPATCH ENTRY
	SKIPGE	T1		;SEE IF ERROR
	MOVEI	P3,COMERD##	;YES--SET DISPATCH
	HRRZ	P4,P3		;CLEAR LEFT HALF JUNK
	HRR	M,(P4)		;GET DISPATCH TABLE ENTRY
	MOVE	P4,JBTSTS##(J)	;JOB STATUS WORD FOR THIS JOB
;THE FOLLOWING CODE IS THE LAST NOSTALGIC VESTIGE OF FT2741
	TLNE	P4,JLOG		; WHILE NOT LOGGED IN?
	JRST	NT2741		;NO--LEAVE ALONE
	JUMPGE	T1,NT2741	;JUMP IF NOT COMMAND ERROR
	CAMN	T2,[SIXBIT .YQAOS.] ;DID HE TYPE LOGIN WITH WRONG BALL?
	HRRI	M,SET987	;YES--SET TTY ELEMENT 987
	CAMN	T2,[SIXBIT .VI.] ;MAYBE THE LEFT ONE?
	HRRI	M,SET988	;YES--SET TTY ELEMENT 988
	SET987==CPOPJ1##
	SET988==CPOPJ1##

NT2741:	TRNE	P4,JS.DEP	;IS JOB BEING STOPPED ON ERROR SO DAEMON CAN LOG?
	JRST	CHKDLY		;YES, DELAY COMMAND UNTIL DAEMON IS FINISHED LOGGING
	TLNE	P4,JLOG		;IS JOB LOGGED IN?
	JRST	CHKNO		;YES, PROCEED
	TLNN	M,NOLOGIN	;NO, CAN COMMAND PROCEED WITH NO LOGIN?
	JRST	LOGPLE		;NO, TYPE "LOGIN PLEASE"
	SKIPE	[M.RCMP##]	;MAYBE. ARE WE BEING PERMISSIVE?
	TLNE	M,NORCMP	;OR IS THIS COMMAND ALLOWED ANYWAY?
	JRST	CHKNO		;YES, PROCEED
	MOVEI	T1,LDRRMT##	;REMOTE BIT
	TDNN	T1,LDBDCH##(U)	;SEE IF DONE ON A LOCAL TERMINAL
	JRST	CHKNO		;YES, IT'S LEGAL
LOGPLE:	JSP	T1,COMER	;NO, TYPE "LOGIN PLEASE"
LOGPLM::ASCIZ	/LOGIN please
/
CHKNO:	SETZB	P1,R		;CLEAR PHYSICAL I/O FLAG, AND CORE LOCATION
	JUMPN	J,CHKRUN	;JOB NUMBER ALREADY ASSIGNED?
	TLNE	M,NOJOBN	;NO, DOES THIS COMMAND NEED A JOB NUMBER?
	JRST	COMGO		;NO
	MOVEI	J,1		;YES, SCAN FOR ONE STARTING WITH 1
NUMLOP:	HLLZ	P4,JBTST2##(J)	;FOR JS.SIP
	HLR	P4,JBTSTS##(J)	;FOR OTHER BITS
	TDNN	P4,[JS.SIP+JNA+JRQ+CMWB] ;OR ONE OF THESE?
IFN FTMP,<
	PUSHJ	P,ANYRUN##	;RUNNABLE ANYWHERE?
	  JRST	NUMLO1		;YES, JOB ISN'T REALLY AVAILABLE
	MOVE	P4,JBTSTS(J)	;KEEP REST OF CODE HAPPY
>
IFE FTMP,<
	SKIPA	P4,JBTSTS(J)	;KEEP OTHER CODE HAPPY
	  JRST	NUMLO1		;JOB ISN'T AVAILABLE
>
	JRST	NEWJOB
NUMLO1:	CAIGE	J,JOBMAX##	;YES, IS THE MAX. JOB NO.?
	AOJA	J,NUMLOP	;NO, KEEP LOOKING
	SKIPG	ARFLAG##	;SYSTEM STARTING UP?
	JRST	CHKDLY		;YES--DELAY IT
IFN FTNET,<
	MOVSI	T1,LDBCMF##	;WAS THIS COMMAND FORCED?
	TDNN	T1,LDBCOM##(U)
	JRST	NEWJER		;NO, OKAY TO COMPLAIN
	SKIPGE	LDBTTW##(U)	;IF ANF THEN PROBABLY .HELLO/.NETLD
	JRST	CHKDLY		;SO DELAY IT
>
NEWJER:	JSP	T1,COMER	;YES, NONE LEFT, PRINT "JOB CAPACITY EXCEEDED"
	ASCIZ	/Job capacity exceeded
/
NEWJED:	JSP	T1,COMER	;PRINT "NO FREE DDBs"
	ASCIZ	/Job capacity exceeded (No free TTY DDBs)
/
NEWJEP:	JSP	T1,COMER	;Not enough core
	ASCIZ	/Job capacity exceeded (No core for a PDB)
/
;EVEN THOUGH THIS IS A NEW JOB NUMBER
;IT MAY HAVE CORE ASSIGNED NOW BECAUSE IT WAS DELAYED
;UNTIL IT COULD BE SWAPPED IN(LOGIN WITH CORE FULL)

NEWJOB:	SKIPE	F,TTYTAB##(J)	;ANY TTY DDB?
	PUSHJ	P,TTYKIL##	;YES--KILL IT OFF
	SETZB	F,TTYTAB##(J)	;KEEP TTYATI HAPPY
	MOVE	U,(P)		;RESTORE U
	PUSHJ	P,TTYATI##	;TRY TO ATTACH TTY TO THIS JOB NUMBER
	  JRST	NEWJED		;IF CAN'T, NO DDB'S. SAY NO FREE DDBs
	PUSHJ	P,CREPDB##	;CREATE A PDB FOR THIS JOB
	  JRST	[PUSHJ	P,TTYKIL##  ;KILL TTY DDB OBTAINED ABOVE
		 JRST	NEWJEP]	;CAN'T GET A PDB, SAY SO
	SETZM	JBTPRG##(J)
	PUSHJ	P,CLRJBT##	;GO CLEAR ALL THE JOB TABLES AND PDB
	PUSHJ	P,ASICPT##	;ASSIGN INITIAL IN CORE PROTECT
	MOVE	T2,DATE##
	MOVEM	T2,JBTJLT##(J)
IFN FTMDA,<
	MOVEM	T2,.PDSTM##(W)	;INITIAL SETTING OF LAST RESET
> ;IFN FTMDA
	SKIPE	JBTADR##(J)	;CONTACT BOUNCE ON DLYCM?
	PUSHJ	P,MKADD##	;YES, MAKE SURE JOB IS ADDRESSABLE
IFN FTMP,<
	MOVEM	J,COMJOB##	;FOR PTYSER
>
	PUSHJ	P,CTLJBU##	;GET PTY DDB IF THERE IS ONE
	JUMPL	T1,NEWJB1	;JUMP IF NOT PTY CONTROLLED
	MOVSI	T1,DVDIBP	;GET BATCH PTY BIT
	MOVSI	T2,(JB.LBT)	;GET A BATCH JOB BIT
	TDNE	T1,DEVCHR(F)	;IS IT A BATCH PTY ?
	IORM	T2,JBTLIM##(J)	;YES, THEN ITS A BATCH JOB
NEWJB1:	HRRZ	F,LDBDDB##(U)	;RESTORE TTY DDB
	MOVEI	T1,BPTBIT##	;GET INITIAL VALUE OF JS.BPT
	DPB	T1,BPTPTR	;SET IT

	MOVE	T1,TIME##	;INITIALIZE TO TIME OF DAY
	TLO	T1,M.WCH##	;OR IN INITIAL SET WATCH BITS
				; (IN CASE THIS JOB GETS AUTOMATIC LOGIN)
	MOVEM	T1,JBTWCH##(J)	;STORE FOR THIS JOB
	CAMLE	J,HIGHJB##	;HIGHEST JOB NUMBER ASSIGNED?
	MOVEM	J,HIGHJB##	;YES,SAVE IT FOR SCHEDULER SCAN OF JOBS
IFN FTNET,<
	PUSHJ	P,FNDSTA##	;WHERE IS HE?
	DPB	T1,PDVSTA##	;THAT IS WHERE HIS TTY IS NOW
	HRRZM	T1,JBTLOC##(J)	;AND LOCATE HIM THERE
>
CHKRUN:
IFN FTMP,<
	TLNE	M,NORUN		;CAN COMMAND BE EXECUTED WHILE RUNNING?
	TLNE	P4,RUN		;YES, IS IT
	JRST	CHKRU1		;YES
	PUSHJ	P,ANYRUN##	;RUN BIT COULD BE OFF BUT THE JOB
	  JRST	CHKDLY		; COULD STILL BE THE CURRENT JOB ON ANOTHER CPU
>
CHKRU1:	TLNE	P4,RUN		;RUN BIT ON IN JOB STATUS?
	TLNN	M,NORUN		;YES, DOES THIS COMMAND REQUIRE A JOB?
	JRST	CHKBAT		;NO
	JSP	T1,COMER	;YES.
RUNERR::ASCIZ	/Please type ^C first
/

CHKBAT:	MOVE	T1,JBTLIM##(J)	;GET BATCH BIT
	TLNE	T1,(JB.LBT)	;SEE IF BATCH JOB
	TLNN	M,NBATCH	;YES--SEE IF ILLEGAL COMMAND
	JRST	CHKXO		;NO--OK TO PROCEED
	JSP	T1,COMER	;YES--BOMB USER
BATMSG:	ASCIZ	/Illegal in batch job
/


CHKXO:	TRNE	P4,JS.XO!JS.RUU	;SEE IF EXECUTE ONLY JOB
	TLNN	M,NXONLY	;YES--SEE IF ILLEGAL COMMAND
	JRST	CHKACT		;NO--OK TO PROCEED
	JSP	T1,COMER	;YES--BOMB USER
ILLXOM:	ASCIZ	/Illegal when execute only
/
CHKACT:	MOVE	R,JBTADR##(J)	;XWD PROTECTION,RELOCATION
	TLNE	M,INCORE	;MUST JOB NOT BE SWAPPING OR
				; IF JOB HAS CORE ASSIGNED, MUST IT BE
				; IN PHYSICAL CORE (RATHER THAN DISK OR ON ITS WAY)
	TLNN	P4,SWP!SHF	;YES, IS JOB ON DISK OR ON ITS WAY?
	JRST	CHKCO2		;NO
	HRRI	M,DLYCM		;ASSUME JOB MUST BE IN PHY CORE
				; SO SET TO SWAP JOB IN
	JRST	COMDIS		;WAIT FOR JOB
CHKDLY:	HRRI	M,DLYCM1	;NO, JUST DELAY COMMAND UNTIL SWAP OUT OR IN IS FINISHED
	JRST	COMDIS		;AND DISPATCH TO DELAY COMMAND

CHKCO2:	TLNE	M,NOACT		;CAN COMMAND BE PERFORMED WITH ACTIVE DEVICES?
	PUSHJ	P,RUNCHK	;NO, RETURN IF JOB STOPPED AND NO ACTIVE DEVICES
	TLNE	M,NOCORE	;DOES THIS COMMAND NEED CORE?
	JRST	COMGO		;NO. GO DISPATCH
	JUMPN	R,CHKXPN	;YES, IS CORE IN MEMORY?
	JSP	T1,COMER	;NO, PRINT "NO CORE ASSIGNED"
	ASCIZ	/No core assigned
/
CHKXPN:	TLNN	M,INCORE	;DOES THIS COMMAND NEED CORE TO BE EXPANDED?
	JRST	COMGO		;NO
	HLRE	S,USRHCU##	;YES, IS CORE STILL COMPRESSED(SAVE DID NOT GO
				; TO COMPLETION)
	JUMPGE	S,COMGO		;LH=-2 DURING SAVE, WHEN CORE COMPRESSED
				;LH=-1 DURING SAVE OF HIGH SEG, OR GET OF LOW
				; OR HIGH SEG
	CAME	P2,FCOTXT##	;IS THIS A FORCED CONTINUE?
	CAMN	P2,CONTXT##	; OR CONTINUE COMMAND?
	JRST	COMGO		;YES, DON'T EXPAND (LET SAVE FINISH)
	PUSHJ	P,CLRASA	;CLEAR EXEC MODE UUO FLAG
	AOJGE	S,COMGO		;JUMP IF DON'T NEED TO EXPAND
	S0PSHJ	EXPAND		;NO, EXPAND CORE FIRST
	  JFCL			;IGNORE ADDRESS CHECK ERROR, WE TRIED
	MOVSI	T1,JERR		;SET JERR SO CONT WON'T WIN
	IORM	T1,JBTSTS##(J)	; (WOULD GET ADR CHK IF ATTEMPTED)
	JRST	CHKDLY		;DELAY COMMAND BECAUSE COMMAND DECODER ACS ARE
				; ALL GONE, NEXT TIME JOBHCU WILL BE 0


NOSUCH:	PUSH	P,(P)		;SO COMDIS DOESN'T SCREW UP THE STACK
	SKIPA	M,[NOCOM]	;GET THE ERROR ROUTINE
COMER::	HRRI	M,ERRMES	;CALL ERROR MESSAGE ROUTINE
	HRLI	M,NOINCK!CMDERR ;SET APPROOPRIATE BITS

COMGO:	TLNN	P4,CMWB		; WAS JOB IN COMM WAIT
	TLZ	M,CMWRQ		;NO, CLEAR REQUEUE BIT IN DISP. FLAGS
	MOVSI	S,CMWB		;CLEAR CMWB
	ANDCAM	S,JBTSTS##(J)
	TLNE	P4,CMWB		;IF NOT IN COMMAND WAIT,
	SKIPN	.PDCMN##(W)	;OR NO USER-DEFINED COMMANDS,
	JRST	COMDIS		;THEN DON'T NEED THIS
	MOVSI	T2,LDBCMF##	;COMMAND FORCED BIT
	TDNN	T2,LDBCOM##(U)	;SEE IF ON
	TLO	M,CMWRQ		;NO, DEMAND A REQUEUE TO FIX UP AFTER DLYCOM

COMDIS:	POP	P,T2		;GET BACK THE OFFSET FROM THE STACK
	EXCH	T2,(P)		;KEEPING U THERE
	TLNE	M,CMDERR	;COMING IN FROM AN ERROR?
	JRST	COMDS1		;YES, JUST DISPATCH
	TLNN	M,CMWRQ		;CMWRQ ON IN PREDISPATCH? (SEE COMGO)
	TLZA	T2,CMWRQ	;NO, CLEAR IT IN POST DISPATCH FLAGS
	TLO	T2,CMWRQ	;YES, SET IT IN POST DISPATCH FLAGS
	HLL	M,T2		;NO, GET THE REAL FLAGS
COMDS1:	MOVEI	S,0		;CLEAR S FOR SETTING DISPATCH ADDRESSES
	TLO	M,FLMCOM!FLMCLV	;SET COMMAND AT COMMAND LEVEL FLAGS
	MOVEM	P,.CPISF##	;SAVE PDL FOR DLYCOM & ABORTC
	S0PSHJ	<(M)>		;DISPATCH TO COMMAND IN SECTION 0
	  JFCL			;IGNORE ERROR RETURN
	SUBTTL	COMMAND RETURN AND CLEANUP

;RETURN FROM COMMAND SETUP ROUTINE

COMRET:	NTDBUG	NO,EITHER	;STOP IF NETWORK INTERLOCK NOT RELEASED
	MOVE	T1,.CPLFC##	;GET FORCED COMMAND INDEX BACK
	POP	P,U		;RESTORE TTY LDB ADDRESS
	HRRZ	F,LDBDDB##(U)	;RESTORE TTY DDB IF ANY
	PUSHJ	P,TTYCMR##	;TELL SCNSER COMMAND IS COMPLETED
	SOS	COMCNT##
	AOS	COMTOT##	;KEEP COUNT OF TOTAL COMMANDS PROCESSED
				; (DO NOT COUNT DELAYED COMMANDS UNTIL PROCESSED)
	MOVSI	T1,1		;ALSO KEEP COUNT OF COMMANDS PROCESSED
	ADDM	T1,LDBBCT##(U)	;ON A PER-TERMINAL BASIS FOR ACCOUNT PURPOSES
	TLNN	M,ERRFLG	;ERROR?
	JRST	COMRT1		;NO, PROCEED
	SETZM	J		;YES, CLEAR J
	TLZ	M,NOFLM!NOCRLF!NOPER!TTYRNU!TTYRNC!TTYRNW!NOMESS	;ERROR--CLEAR PROBLEM BITS
	TLO	M,NOINCK+CMWRQ	;YES, JOB NUMBER REQUIRED, BUT NONE IN J.
				; PRINT ERROR MESSAGE ONLY, AND
				; REQUEUE JOB IF NECESSARY.

COMRT1:	MOVSI	P4,JNA		;JOB STATUS WORD
	TLNN	M,NOINCK	;SUPPRESS JOB INIT. CHECK?
	TDOE	P4,JBTSTS##(J)	;NO, IS JOB INIT BIT ALREADY SET?
	JRST	PCRLFA		;YES.
	MOVSI	P4,JNA		;GET JNA BIT AGAIN
	IORB	P4,JBTSTS##(J)	;NO, SO SET IT THIS COMMAND
	PUSHJ	P,TTYATI##	;ATTACH TTY TO JOB
	  JFCL			;IGNORE IF CAN NOT(SHOULD NEVER HAPPEN)
PCRLFA:	MOVEI	T1,JDCON	;CLEAR JDCON SO THAT A RUNNING JOB
	TLNE	M,TTYRNU!TTYRNC!TTYRNW	;WILL NOT BE THE "JCONT INVABLE" FROM
	ANDCAM	T1,JBTSTS##(J)	;ANOTHER TTY

	TLNE	M,NOMESS	;SEE IF MESSAGE SUPPRESSED
	JRST	PCRLF0		;YES--SKIP WATCH
	TLNE	M,TTYRNU!TTYRNC!TTYRNW	;COMMAND START JOB UP (TTY IN EITHER MODE)?
	S0PSHJ	WCHBEG		;YES, PRINT [HH:MM:SS] STARTED TO WAIT FOR RESPONSE
PCRLF0:	TLNN	M,NOFLM!NOCRLF	;SUPRESS CRLF?
	PUSHJ	P,CRLF		;NO
	TLNE	M,NOPER		;SUPRESS PRINTING PERIOD?
	JRST	PCRLF2		;YES
	PUSHJ	P,PRDOTM	;NO, GIVE A "."
	PUSHJ	P,CLRPCT##	;RESET STOP COUNTER
	PUSHJ	P,STRTDL##	;ALLOW A DEFERRED LINE TO ECHO IF NEEDED
PCRLF2:	JUMPE	J,PCRLF1	;JOB DOES NOT RUN IF ERROR OR NO JOB NO. ASSIGNED
	TLNE	M,TTYRNU	;JOB TO RUN WHEN TTY FINISHED TYPING?
				; COMMAND RESPONSE (TTY TO USER MODE)?
	PUSHJ	P,TTYUSR##	;YES, CALL SCANNER AND SCHEDULER ROUTINES
	TLNE	M,TTYRNW	;COMMAND RESTART TTY RESPECTING IO WAIT?
	PUSHJ	P,TTYUSW##	;YES. CALL SCANNER ROUTINE AND SCHEDULER
	TLNE	M,TTYRNC	;NO, JOB TO RUN AND REMAIN IN MONITOR MODE?
	PUSHJ	P,SETRUN##	;YES, CALL SCHEDULER ROUTINE
PCRLF1:	TLNN	M,NOMESS	;IS THERE A MESSAGE?
	PUSHJ	P,TTYSTR##	;YES, START TTY TYPING IT OUT
	TLNE	M,ERRFLG	;WAS AN ERROR?
	PUSHJ	P,TSETBI##	;YES--CLEAR TYPE-AHEAD
	JUMPE	F,PCRLF5	;DON'T KILL NON-EXISTENT DDBS
	TLNN	M,NOJOBN	;WAS NO JOB NUMBER NEEDED?
	TLNE	M,ERRFLG	;OR DID AN ERROR OCCUR?
	CAIA
	JRST	PCRLF5
	MOVSI	T1,JNA		;GET JNA
	LDB	T2,PJOBN##	;AND JOB NUMBER
	SKIPE	T2		;HAVE A JOB?
	TDNE	T1,JBTSTS##(T2)	;AND IS JOB NUMBER ASSIGNED?
	JRST	PCRLF4		;KILL OFF TTY IF IDLE
	MOVEI	J,(T2)		;COPY JOB NUMBER
	SETZM	TTYTAB##(J)	;ZAP TTY DDB POINTER
	PUSHJ	P,TTYKIL##	;RETURN TTY DDB TO FREE POOL
	PUSHJ	P,KILPDB##	;GIVE BACK PDB CORE
	TDZA	J,J		;DON'T CONFUSE THINGS
PCRLF4:	PUSHJ	P,TTYKLQ##	;KILL OFF TTY IF IDLE
PCRLF5:	PUSHJ	P,DECHJB##	;DECREMENT HIGHJB IF APPROPRIATE
IFN FTMP,<
	SETOM	COMJOB##	;NO JOB IN COMCON NOW
>
	JUMPE	F,CPOPJ##	;IF NO JOB, QUIT
	MOVSI	T1,LDBDET##	;SHOULD LINE BE DETACHED?
	TDNN	T1,LDBCOM##(U)	;DELAYED BECAUSE OF CMW
	JRST	PCRLF3
	ANDCAM	T1,LDBCOM##(U)
	PUSHJ	P,PTYDET##	;YES, DO IT NOW
PCRLF3:	LDB	J,PJOBN##	;GET ATTACHED JOB # FROM TTY DDB
	JUMPE	J,CPOPJ##
	CAME	J,.CPJOB##	;NEVER SET JRQ FOR CURRENT JOB!
	TLNN	M,CMWRQ		;REQUEUE JOB AFTER COMMAND WAIT OR ERROR?
	POPJ	P,
	JRST	REQUE##		;YES
	SUBTTL	CORE 0 COMMAND

COR0:	JUMPE	R,CPOPJ##	;RETURN IF JOB DOES NOT HAVE CORE

IFN FTFDAE,<
	PUSHJ	P,CHKXTM	;SEE IF AN "EXIT" MESSAGE SHOULD
				; BE SENT TO THE FILE DAEMON AND IF
				; SO, SEND IT.
>
	JSP	T2,MONJOB##	;SET TO RUN MONITOR JOB(PC IN EXEC MODE)
				; RETURN HERE AT UUO LEVEL(NO ACS SET UP)
	MOVEI	T2,ESTOP##	;PUT ERROR STOP ON END OF PDL
	JSP	T1,MONSTR##	;START MONITOR JOB BY SETTING UP ACS AND
JOB1::	MOVSI	T1,JERR		;TURN OFF JERR
	ANDCAM	T1,JBTSTS##(J)	;..
	PUSHJ	P,RESET##	;RELEASE ALL IO DEVICES ASSIGNED TO THIS JOB
IFN FTFDAE,<
	PUSHJ	P,CALLF		;NEED TO CALL FILDAE FOR THIS JOB?
	  PUSHJ	P,SNDFXM	;YES, SEND FILDAE AN EXIT MESSAGE
>
JOB1A::	MOVSI	T1,JERR		;TURN OFF JERR
	ANDCAM	T1,JBTSTS##(J)	;..
	PUSHJ	P,TTYFNU##	;FIND TTY FOR THIS JOB(SETUP J WITH JOB NO.)
IFN FTMP,<
	PUSHJ	P,UPMM##	;MUST HAVE THE MM RESOURCE
	JRST	ZAPPG1		;ZAP THE PROGRAM (UUO LEVEL STYLE)
>
ZAPPGM::
IFN FTMP,<
	PUSHJ	P,GETMM##	;GET MEMORY MANAGEMENT RESOURCE
	  JRST	.-1		;MUST WAIT IF NOT AVAILABLE
>
ZAPPG1:	PUSHJ	P,KILHGA##	;HIGH SEG FOR THIS USER, RETURN CORE
				; REMOVE HIGH SEG FROM THIS USER
				; LOGICAL ADDRESSING SPACE
				; IF NO OTHER USERS IN CORE ARE USING IT
				; RETURN DISK SPACE IF NO LONGER SHARABLE HIGH SEG
	PUSHJ	P,INTLVL##	;AT CLOCK LEVEL?
	  PUSHJ	P,DSKFLS##	;NO, UUO, CLOBBER ANY POSSIBLE DISK PAGES
	PUSHJ	P,NOCORQ##	;PUT JOB IN NO CORE Q
	PUSHJ	P,CLRTAB	;CLEAR BITS AND TABLE ENTRIES
	MOVSI	T1,(PD.LGO)	;IF A LOGOUT UUO IS IN PROGRESS,
	TDNE	T1,.PDDFL##(W)	; ..
	JRST	JOB2		; ALWAYS DELETE ALL CORE
	MOVSI	T1,JLOG		;IF NOT LOGGED IN
	SKIPN	.CPISF##	; OR COMING FROM ERRCON
	TDNN	T1,JBTSTS##(J)
	JRST	JOB2		;ALWAYS DELETE FUNNY PAGES
	LDB	T1,NFYPGS##	;ANY MONITOR FREE CORE PAGES?
	CAIN	T1,UPMPSZ##+1
	JRST	JOB2		;NO, RETURN CORE
	MOVE	T1,[.JDAT,,.JDAT+1] ;ZERO JOB DATA AREA
	SETZM	.JDAT		;JOBSA, JOBDDT, ETC.
	SETZM	USRDDT##	;AND REMEMBERED COPY
	BLT	T1,.JDAT+PG.BDY ; AND THE REST OF PAGE 0 IN CASE XO
IFE FTMP,<
	POPJ	P,		;YES, JUST RETURN
>
IFN FTMP,<
	PJRST	GIVMM##
>
JOB2:	SKIPE	T1,JBTADR##(J)	;SKIP THIS IF NO CORE
	PUSHJ	P,VMSIZE##	;VIRTUAL SIZE OF THE JOB
	LDB	T2,NFYPGS##	;NUMBER OF FUNNY PAGES
	ADDI	T1,-UPMPSZ##(T2) ;VMSIZE ADDED UPMP SIZE
	ADDM	T1,VIRTAL##	;VIRTUAL CORE RETURNED
	PUSHJ	P,ZERSWP##	;RETURNED SWAPPING SPACE
	PUSHJ	P,FNDPDS##	;MAKE SURE W POINTS TO PDB
	SETZM	.PDCMN##(W)	;CLEAR POINTER TO COMMAND NAMES
	SETZM	.PDUNQ##(W)	;CLEAR POINTER TO UNIQNESS BITS
	PUSHJ	P,UUOLVL##	;AT UUO LEVEL?
	  JRST	JOB3		;NO
	MOVE	T1,(P)		;YES, CAN'T USE STACK IN THE
	MOVE	P,.CPNPD##	; UPMP AFTER GIVING THE
	PUSH	P,T1		; UPMP BACK TO FREE CORE
JOB3:	PUSHJ	P,KCORE1##
	SETZM	.CPADR##
	SETZM	JBTIMI##(J)	;NO VIRTUAL CORE
	SETZM	JBTIMO##(J)	;...
	SETZM	JBTSWP##(J)
IFN FTMP,<
	PJRST	GIVMM##		;RETURN THE MM RESOURCE
>
IFE FTMP,<
	POPJ	P,
>
	SUBTTL	PJOB & KJOB COMMANDS

; "PJOB" PRINT JOB NUMBER OF JOB TTY IS ATTACHED TO


PJOB::	MOVE	T1,J		;JOB NO.
DECLF::	PUSHJ	P,RADX10	;PRINT T1 AS DEC. THEN CRLF
	JRST	CRLF


;THIS PRINTS OUT:
;
; JOB N USER NAME [P,PN] TTY#
;
PJOBX:: PUSHJ	P,SAVJW##	;SAVE J(W GETS A RIDE)
	PUSHJ	P,GETJOB	;GET JOB NUMBER TO DO PJOB ON
	  SKIPA			;NO JOB NUMBER SO USE CURRENT JOB
	MOVE	J,T2		;PUT REQUESTED JOB NUMBER IN AC(J)
	JUMPE	J,ATT4		;ERROR IF NO JOB ASSIGNED
	PUSHJ	P,INLMES	;GIVE FOLLOWING MESSAGE
	ASCIZ	\Job \		;
	MOVE	T1,J		;PRINT THE
	PUSHJ	P,RADX10	; JOB NUMBER
	PUSHJ	P,INLMES	;GIVE FOLLOWING MESSAGE
	ASCIZ	\   User \		;
	PUSHJ	P,FNDPDB##	;SEE IF A PDB AND POINT AC(W) TO IT
	  JRST	PJOBX2		;NO PDB, SO CAN'T PRINT USERS NAME
	MOVE	T2,.PDNM1##(W)	;GET FIRST PART OF USERS NAME
	SKIPN	.PDNM2##(W)	;PRINT IT
	  JRST	PJOBX1		;GET USERS NAME
	PUSHJ	P,PRSIXB	;IF LAST PART IS NULL WE'RE DONE
				; WITH THE NAME PRINTOUT
	MOVE	T2,.PDNM2##(W)	;DOES FIRST NAME END WITH A SPACE?
PJOBX1:	PUSHJ	P,PRNAME
PJOBX2:	PUSHJ	P,PR3SPC	;GIVE A SPACE
	MOVE	T2,JBTPPN##(J)	;GET PPN
	PUSHJ	P,PRTPPN	;PRINT PPN
	PUSHJ	P,PR3SPC
	MOVE	T2,@TTYTAB##(J)	;GET TTY NAME
	TLNN	T2,-1		;DETACHED?
	HRLI	T2,'DET'	;YES
	PUSHJ	P,PRNAME	;PRINT THE TTY NAME
	PJRST	CRLF		;END WITH A CRLF
; "KJOB" KILL ATTACHED JOB

KJOB::	SKIPE	J		;WAS JOB INITIALIZED?
	TLNN	P4,JNA		;JOB ASSIGNED?
	SKIPA			;NO
	JRST	KJOB3		;GO RUN LOGOUT
	SE1ENT			;ENTER SECTION ONE
IFN FTNET,<
	SKIPGE	LDBREM##(U)	;IF SET HOST IN PROGRESS,
	JRST	KJOB2		;JUST BE QUIET ABOUT IT
> ;END IFN FTNET
	PUSHJ	P,SKIPS1	;EAT LEADING SPACES AND TABS
	  JRST	KJOB1		;EOL
	CAIE	T3,"/"		;WE EXPECT A SWITCH AT THIS POINT
	JRST	COMERA		;CONFUSED USER
	PUSHJ	P,CTEXT		;GET A KEYWORD
	JUMPE	T2,COMERA	;CONFUSED USER
	MOVE	T1,[-1,,[SIXBIT/DISCON/]] ;TABLE POINTER
	PUSHJ	P,FNDNAM	;AND SEARCH IT
	  JRST	COMERA		;AMBIGUOUS OR UNKNOWN
KJOB1:	PUSHJ	P,TOPDSF##	;HANG UP THE DATASET
	  JFCL			;CAN'T
IFN FTNET,<
	PUSHJ	P,TOPDNT##	;DO A NETWORK DISCONNECT
	  JFCL			;CAN'T
	SKIPGE	LDBREM##(U)	;IF SET HOST,
KJOB2:	TLOA	M,NOCRLP!NOFLM	;BE SILENT
> ;END IFN FTNET
	TLO	M,ERRFLG	;EXIT COMMAND PROCESSING CLEANLY
	MOVEI	J,0		;DITTO
	POPJ	P,		;DONE

KJOB3:	TLNN	P4,JLOG		;TEST JLOG ALSO IN CASE JOB NOT LOGGED IN
	JRST	KJOB4		;IF JOB NOT LOGGED IN
	PUSHJ	P,TTYATI##	;ATTACH TTY
	  JFCL
	TLO	M,TTYRNU	;SET TTYRNU FOR COMRET
	MOVSI	P1,PHONLY	;SET PHYSICAL I/O FORCE SYSTEM KJOB
	MOVSI	T1,(JS.BPR)	;SET BYPASS PROGRAM TO RUN
	IORM	T1,JBTST2##(J)	;TO INSURE KJOB REALLY RUNS

IFN FTMP,<
	PUSHJ	P,ALLJSP##	;SET CPU SPECIFICATION TO MAKE JOB RUNNABLE
				; ON ALL CPU'S. THIS ALSO LEAVES A REASONABLE
				; SPECIFICATION FOR THE NEXT USER WHO GETS
				; THIS JOB NUMBER
> ;END IFN FTMP
	HRRZ	T1,.PDCVL##(W)	;GET PHYSICAL LIMIT
	TRZ	T1,400000	;IGNORE LIMIT/GUIDELINE
	SKIPN	T1		;IF NO LIMIT HERE,
	HRRZ	T1,.PDMVL##(W)	;GET MPPL
	SKIPN	T1		;IF NOT LIMITED,
	MOVEI	T1,LOGSIZ##	;FIX THE COMPARE BELOW
	MOVEI	T2,LOGSIZ##	;GET SIZE TO RUN LOGIN
	CAIGE	T1,(T2)		;IF NOT ENOUGH,
	HRRM	T2,.PDCVL##(W)	;MAKE IT ENOUGH
	MOVE	P2,LGINAM##	;GET 'LOGIN'
	JRST	RUNAME		;GO RUN CUSP

KJOB4:	PUSHJ	P,GETCIC	;GET MINIMAL JOB AREA ON DISK OR CORE
IFN FTNET,<
	SE1ENT
	SKIPGE	LDBREM##(U)	;IF SET HOST IN PROGRESS,
	TLO	M,NOCRLP!NOFLM	;DON'T DO TYPEOUT
> ;END IFN FTNET
	JSP	T2,MONJOB##	;SCHEDULE MONITOR JOB (PC IN EXEC MODE)
				; RETURN HERE AT UUO LEVEL WHEN SCHEDULED
JOBKL::
IFN FTXMON,<JRST @[0,,.+1]> 	;MUST RUN IN SECTION 0
	MOVEI	T2,ESTOP##	;PUT ESTOP ON END OF PDL
	JSP	T1,MONSTR##	;GO SETUP ACS AND PD LIST AT UUO LEVEL
				;RETURN HERE AT UUO LEVEL AFTER BEING SCHEDULED
	MOVSI	T1,JERR		;TURN OFF JERR
	ANDCAM	T1,JBTSTS##(J)	;..
	SETZM	.JDAT+.JBINT##	;NO OLD-STYLE TRAPPING EITHER
	PUSHJ	P,RESET##	;ZAP PSI, IPCF STUFF, ETC.  HANDLE ^C CORRECTLY
IFN FTMP,<	                ;IF SMP
 	PUSHJ	P,ONCPU0##	;MAKE SURE WE CAN'T MESS UP COMMAND PROCESSING
>; END IFN FTMP
	PUSHJ	P,CTXLGO##	;DELETE ALL IDLE CONTEXTS
IFN FTSCA,<
	PUSHJ	P,SCSLGO##	;TELL SCSUUO JOB IS GONE
>; END IFN FTSCA
	PUSHJ	P,ENQLGO##	;TELL QUESER THAT ETERNAL LOCKS GO AWAY NOW
IFN FTDECNET,<
IFE FTXMON,<DNCALL (SCULGO##)>	;TELL SCMUUO THAT JOB IS GOING AWAY
IFN FTXMON,<SNCALL (SCULGO##,MS.HGH)> ;TELL SCMUUO THAT JOB IS GOING AWAY
>; END IFN FTDECNET
	PUSHJ	P,DSKKJB##	;CLEAR UP CORE BLOCKS ON A KJOB COMMAND
				; MAY GO INTO WAIT, SO DO BEFORE GIVING UP USER CORE

	JUMPE	W,JOBKL1	;IF THIS JOB HAS A PDB,
IFN FTKL10,<
	PUSHJ	P,BRKDEC	;MAKE SURE ADDRESS BREAK COUNT IS DECREMENTED,
				; IF NEED BE.
>
	PUSHJ	P,KILJSL##	;DESTROY THE JSL (GET MOUNT COUNTS RIGHT)
JOBKL1:	PUSHJ	P,DEASTY	;DEASSIGN ALL BUT TTY
	PUSHJ	P,IPCLGO##	;TELL [SYSTEM] INFO THAT JOB IS GONE
	PUSHJ	P,JOB1		;FLUSH CORE AFTER RELEASING DEVICES
	PUSHJ	P,FNDPDS##	;TAPUUO COULD USE W
	PUSHJ	P,TTYSRC##	;FIND THE TTY FOR THIS JOB
	  SETZ	F,		;NONE?
	SKIPE	F		;IF THERE'S A TTY DDB,
	PUSHJ	P,TTYKIL##	;RETURN TTY TO VIRGIN STATE
	JRST	KSTOP##		;CLEAR JOB STATUS WORD AND STOP JOB
	SUBTTL	START GROUP (START,CSTART,REE,DDT)

; "START L" OR "START" - START AT LOC. L OR STARTING ADDRESS

START::				;SAME AS CSTART, DIFF BY COMTAB BITS
				; WHICH PUT TTY IN MONITOR OR USER MODE

; "CSTART L" OR  "CSTART" - START AT LOC. L(TTY IN COMMAND MODE)


STARTC::MOVE	P3,P4		;SAVE STATUS
	PUSHJ	P,OCTPAR	;READ A NUMBER IF PRESENT
	  JRST	SNOARG		;NO ARG SPECIFIED RETURN
	TLNN	P3,JLOG		;IS IT LOGGED IN?
	JRST	STARTE		;NO--ERROR
	TRNE	P3,JS.XO!JS.RUU	;SEE IF EXECUTE ONLY
	JRST	ILLXO		;YES -- BOMB USER
	PUSHJ	P,CHKMED##	;CHECK TO SEE IF HIGH SEG WHICH IS SHARABLE
				; IF YES, TURN ON USER MODE WRITE PROTECT
				; FOR THIS USER, AND SET MEDDLE BIT SO HE CANNOT
				; TURN UWP OFF.
	JRST	STARTN		;START IN USER MODE

STARTE:	MOVEI	T1,LOGPLM	;SETUP ERROR MESSAGE
	PJRST	ERRMES		;GO ISSUE IT

ILLXO:	MOVEI	T1,ILLXOM	;GET ERROR MESSAGE
	PJRST	ERRMES		;GO ISSUE IT
;"REENTER" - REENTER USER PROGRAM


REENTE::SKIPN	T2,JBTADR##(J)
	JRST	CHKPCM		;NO ADDRESS IF NO CORE
	HRRZ	T2,.JDAT+.JBREN##	;GET ADDRESS FROM JOBDAT
	SKIPN	T1,.USUSA	;ANY SORT OF ENTRY VECTOR?
	JRST	CHKPCM		;NO, GO CHECK FOR /USE SECTION
	JUMPE	J,STARTE	;YES, BUT MUSTN'T ALLOW THIS IF NOT A JOB
	HLL	T2,T1		;HAVE ONE, MERGE IN ITS SECTION
	TLNN	T2,370000	;IS THIS JUST A START ADDRESS?
	JRST	STARTN		;YES, ONLY WANT ITS SECTION NUMBER
	AOS	T2,T1		;NO, OFFSET TO REENTRY ADDRESS IN ENTRY VECTOR
	TLNN	T2,360000	;IS THE VECTOR LONG ENOUGH?
	TDZA	T2,T2		;NO, CLEAR THE ADDRESS
	TLZ	T2,770000	;YES, ISOLATE THE ADDRESS FROM ITS BITS
	JUMPE	T2,CHKSTR	;BOMB USER IF NO ADDRESS
	PJRST	SNOAR2		;GET ADDRESS AT UUO LEVEL AND START THE USER

; "DDT" - START EXECUTION AT DDT IN USER AREA


DDTGO::	JUMPE	R,STARTE	;ERROR IF NO CORE (NOT A JOB)

	HRRZ	T2,.JDAT+JOBDDT##	;DDT STARTING ADR. IN JOB DATA AREA
IFN FTXMON,<
	HLLZ	T1,.USUSA	;GET ENTRY VECTOR SECTION
	TLZ	T1,770000	;CLEAR OUT BITS
	SKIPE	T2		;PRESERVE ZERO
	ADD	T2,T1		;OFFSET DDT TO THAT SECTION
> ;END IFN FTXMON
	SKIPN	.USUSA		;IF THERE IS NO ENTRY VECTOR,
	JUMPN	T2,CHKPCM	;OK IF WE HAVE DDT
	JUMPN	T2,STARTN	;IGNORE /USE SECTION IF ENTRY VECTOR
	TLNN	P4,JLOG		;MAKE SURE LOGGED IN
	JRST	CHKPCM		;NOT BOMB HIM
	TRNN	P4,JS.XO!JS.RUU ;SKIP IF EXECUTE ONLY
	PJRST	GETDDT##	;MERGE IN DDT


CHKPCM:	JUMPE	J,STARTE	;ERROR IF NOT A JOB (DDT,REENTER)
	JUMPE	T2,CHKSTR	;IS A START ADR SPECIFIED? (ERROR IF 0)
IFN FTXMON,<
	MOVE	T1,.USUSN	;GET SECTION #
	LSH	T1,P2WLSH	;POSITION
	ADD	T2,T1		;MAKE FULL WORD ADDRESS
> ;END IFN FTXMON
STARTN:	MOVE	T1,USRPC##	;YES, GET JOB'S PC
	HLR	T1,JBTSTS##(J)	;AND JOB STATUS BITS
	TDNE	T1,[XWD USRMOD,JERR]	;IS JOB IN USER MODE, OR STOPPED ON AN ERROR?
	JRST	USTART##	;YES, START HIM UP NOW
	MOVE	T1,T2		;GET START ADDRESS
	PUSHJ	P,SETUTP##	;SETUP UUO TRAP
	  JRST	USTART##	;START USER
	JRST	RSTART##	;CLEAR STATUS FLAGS AND START JOB
				; IN MIDDLE OF MONITOR WHERE IT STOPPED

;HERE TO START USER WHEN NO START ADR TYPED IN
SNOARG:	SKIPN	T2,JBTADR##(J)
	JRST	CHKSTR		;NO START ADDR IF NOT IN CORE
	SKIPE	T2,.USUSA	;START ADDR SPECIFIED ON GET/RUN COMMAND?
	JRST	SNOAR1		;YES, SEE ABOUT USING IT
	HRRZ	T2,.JDAT+JOBSA##	;START ADR. SPECIFIED BY LINKING LOADER
				; FROM END STATEMENT
	JUMPE	T2,CHKSTR	;IF ZERO, FORGET IT
IFN FTXMON,<
	MOVE	T1,.USUSN	;SECTION NUMBER USER SPECIFIED
	LSH	T1,P2WLSH	;WHERE IT BELONGS
	ADD	T2,T1		;30 BIT START ADDRESS
	TLZ	T2,770000	;CLEAR POSSIBLE BITS
> ;END IFN FTXMON
	HLLZM	T2,.USUSA	;SAVE FOR NEXT TIME
				;FALL INTO CHKSTR
;HERE TO CHECK TO SEE IF STARTING ADDRESS IS NON-ZERO, AND START USER IF OK

CHKSTR:	JUMPE	J,STARTE	;ERROR IF NOT A JOB
	TLZ	T2,770000	;CLEAR SPECIFIED BY COMMAND BIT
	JUMPN	T2,USTART##	;IS IT NON-ZERO?, IF YES
				; STORE OLD PC IN JOBOPC IN JOB DATA AREA
				; THEN START WITH PC IN USER MODE
	JSP	T1,ERRMES	;NO, PRINT "NO START ADR"
MESNSA:	ASCIZ	/No start address
/

SNOAR1:	CAIN	T2,1		;IS THIS SPECIAL S0 JOBDAT
	HRRZ	T2,.JDAT+.JBSA## ;YES, FIX IT
	TRNE	T2,-1		;IS THIS A FAKE JOBDAT ENTRY?
	TLNE	T2,370000	;OR A REAL ENTRY VECTOR?
	TRNA			;YES OR YES, NEED SAVCTX
	JRST	CHKSTR		;NO, JUST A START ADDRESS, SO TRY IT
SNOAR2:	MOVE	S,T2		;YES, SAVE ACROSS SAVCTX
	JSP	T2,SAVCTX##	;GET TO UUO LEVEL
	MOVE	T2,S		;RESTORE ENTRY VECTOR ADDRESS
	PUSHJ	P,GSADDR	;GET THE RIGHT START ADDRESS
	;PJRST	STARTV

STARTV:	SETZ	F,		;FOR USRXIT (AVOID IME)
	TRNE	T2,777700	;REASONABLE ADDRESS?
	JRST	STARTU		;YES, USE IT
	PUSHJ	P,PPQCRL	;NO, START UP AN ERROR MESSAGE
	PJRST	URUNSB		;COMPLAIN OF 'NO START ADDRESS'

GSADDR::PUSH	P,M		;SAVE FOR SAVCTX RETURN
	MOVE	M,T2		;PUT WHERE FETCH ROUTINES EXPECT IT
	TLZ	M,770000	;CLEAR OUT JUNK
	JUMPE	M,GSADD0	;DON'T FETCH IF JUNK
	CAIN	T2,1		;IF S0 JOBDAT,
	SETZ	T2,		;FIX IT UP
	TDNN	T2,[BYTE (6)37(12)(18)-1] ;IF NO LENGTH AND NO IN-SECTION ADDRESS,
	HRRI	M,.JBSA##	;FIX UP THE REFERENCE ADDRESS
	PUSHJ	P,PFHMWD##	;READ A WORD FROM THE USER'S ADDRESS SPACE
	  SETZB	T1,M		;INVALID ADDRESS
	TDNN	T2,[BYTE (6)37(12)(18)-1] ;IF SPECIAL JOBDAT REFERENCE,
	HLL	T1,M		;FIX UP SECTION NOW
	SKIPL	T1		;POSSIBLE IFIW?
	TLNE	T1,^-<(SECMSK)> ;NO, IS IT A VALID ADDRESS?
	TLNN	T1,377777	;IFIW, IS IT PURE?
	SKIPA	T2,T1		;YES, USE INDIRECTED ADDRESS
	MOVE	T2,M		;NO, USE ORIGINAL ADDRESS
	SKIPGE	T2		;IS IT AN IFIW?
	HLL	T2,M		;YES, UPDATE THE SECTION NUMBER
	TRNN	T2,^-17		;TRYING TO START IN THE ACS?
GSADD0:	SETZ	T2,		;YES, DON'T ALLOW THAT
	JRST	MPOPJ##		;RETURN THE DESIRED ADDRESS TO THE CALLER
	SUBTTL	.BPT (CONTROL-D) COMMAND

;HERE WHEN THE USER TYPES A ^D TO FORCE AN "UNSOLICITED" DDT BREAKPOINT.
;
;THE EFFECT IS TO "EXECUTE" A "JSR @.JBBPT" ON BEHALF OF THE CURRENTLY
;RUNNING USER PROGRAM; THE USER WILL THEN BE IN DDT, AND CAN "$P" TO
;RESUME THE USER PROGRAM WHERE IT WAS INTERRUPTED BY THE BREAKPOINT.

CDBPT::	JUMPE	J,ATT4		;BOMB COMMAND IF NO JOB
	JUMPGE	P4,BPTER2	; OR IF THE JOB IS ^C'ED
IFN FTMP,<			;IF MORE THAN ONE PROCESSOR,
	PUSHJ	P,SPSTOP##	;MAKE SURE NOT RUNNING ANYWHERE ELSE
	  JRST	DLYCM		;OOPS, WE WERE, WAIT TILL OTHER CPU LETS GO
IFN FTKL10,<			;IF NON-WRITE-THROUGH CACHES EXIST,
	PUSHJ	P,SBCCSH##	;NOT RUNNING, BUT MIGHT BE IN OTHER CPU'S CACHE
	  CAIA			;OK WRT CACHE
	JRST	DLYCM		;STUCK IN OTHER CPU'S CACHE, WAIT
> ;END IFN FTKL10
> ;END IFN FTMP
	PUSHJ	P,SIMCHK##	;SEE IF JOB IN GOOD STATE TO BE STOPPED
	  CAIA			;CAN STOP JOB NOW
	JRST	DLYCM		;CAN'T STOP JOB (EXEC PC), WAIT
	SKIPG	T2,.JDAT+JOBBPT##  ;ADDRESS OF BREAKPOINT TRAP ENTRY
	JRST	BPTER3		;NO BREAKPOINT TRAP ADDRESS
	PUSHJ	P,FLTTC##	;CHECK VALIDITY OF ADDRESS
	  JRST	BPTER5		;ERROR: OUT OF BOUNDS
	  JRST	BPTER6		;ERROR: PAGED OUT/INACCESSIBLE
	MOVE	T1,.JDAT+JOBBPT## ;ADDRESS AGAIN
	PUSHJ	P,IADCKL##	;I/O-LEGAL ADDRESS?
	  JRST	BPTER7		;NO
	  JRST	BPTER6		;PAGED OUT
	PUSHJ	P,CDBRK##	;ALL SET, LET CLOCK1 PLAY WITH THE USER'S PC
	  JFCL			;FAILED???
IFN FTMP,<			;IF WE CALLED SPSTOP ABOVE,
	PUSHJ	P,CLRCCB##	;THEN UNDO THE CALL TO SPSTOP HERE
> ;END IFN FTMP
	TLO	M,NOPER		;NO DOT PLEASE
	POPJ	P,		;.BPT COMMAND COMPLETED
;.BPT COMMAND ERRORS

BPTER1:	JSP	T1,BPTERM
	ASCIZ	\Breakpoint trapping is illegal when execute-only\

BPTER2:	JSP	T1,BPTERM
	ASCIZ	\Program is not running\

BPTER3:	SKIPE	.JDAT+JOBDDT##
	JRST	BPTER4
	JSP	T1,BPTERM
	ASCIZ	\DDT is not loaded\

BPTER4:	JSP	T1,BPTERM
	ASCIZ	\No breakpoint trap address\

BPTER5:	JSP	T1,BPTERM
	ASCIZ	\Breakpoint trap address out of bounds\

BPTER6:	JSP	T1,BPTERM
	ASCIZ	\Breakpoint trap address paged out\

BPTER7:	JSP	T1,BPTERM
	ASCIZ  \Invalid breakpoint trap address\




;COMMON BPT COMMAND ERROR MESSAGE PROCESSOR

BPTERM:	PUSH	P,T1		;SAVE ERROR MESSAGE ADDRESS
	PUSHJ	P,CRLF		;TYPE A CRLF
	POP	P,T1		;GET ADDR BACK
	PUSHJ	P,ERRMES	;PRINT THE ERROR MESSAGE
	TLZ	M,ERRFLG	;DEFEAT ERRMES
	SE1XCT	<MOVE T1,LDBDCH##(U)> ;GET TTY CHARACTERISTICS WORD
	TLNE	T1,LDLCOM##	;AT COMMAND LEVEL?
	TLOA	M,ERRFLG	;YES
	TLO	M,NOPER		;ELSE SUPPRESS THE DOT
	POPJ	P,		;"ERROR" RETURN
; PROCESS A "SET EDDT BREAKPOINT" COMMAND
;
SETEBP::SE1XCT	<LDB T1,LDPLNO>	;GET LINE NUMBER
IFE FTMP,<CAIE T1,TCONLN##>
IFN FTMP,<
	CAILE	T1,FRCLIN##	;IS IT A CTY?
	CAILE	T1,TCONLN##	;...
>
	JRST	COMERA1		;NO
	PUSHJ	P,SAVE1##	;SAVE P1
	MOVEI	P1,0		;JOB 0
	JRST	SETBP1		;ENTER COMMON CODE


; PROCESS A "SET DDT BREAKPOINT" COMMAND
;
SETBPT::PUSHJ	P,SAVE1##	;SAVE P1
	MOVE	P1,J		;GET OUR JOB NUMBER

SETBP1:	PUSHJ	P,CTEXT		;GET A KEYWORD
	JUMPE	T2,SETBP3	;IF NO ARGUMENT, JUST TYPE CURRENT SETTING
	MOVE	T1,[-3,,BPTTAB]	;POINT TO TABLE
	PUSHJ	P,FNDNAM	;AND SEARCH IT
	  JRST	COMERA		;AMBIGUOUS OR UNKNOWN KEYWORD
	SKIPE	T1		;USER INCLUDE "BREAKPOINT" CHATTER?
	SOJA	T1,SETBP2	;NO--JUST STORE ON/OFF VALUE
	PUSHJ	P,CTEXT		;GET "ON" OR "OFF"
	JUMPE	T2,SETBP3	;INFORM CONFUSED USER OF .BPT STATE
	MOVE	T1,[-2,,BPTTB1]	;POINT TO ON/OFF TABLE
	PUSHJ	P,FNDNAM	;SCAN IT
	  JRST	COMERA		;AMBIGUOUS OR UNKNOWN KEYWORD
SETBP2:	DPB	T1,BPTPT1	;TURN .BPT ON OR OFF
SETBP3:	MOVEI	T1,[ASCIZ |[Control-D breakpoint facility is turned |]
	PUSHJ	P,CONMES	;TYPE TEXT
	LDB	T1,BPTPT1	;GET THE BIT
	MOVEI	T1,[ASCIZ |off|
		    ASCIZ |on|](T1)
	PUSHJ	P,CONMES	;TYPE ON OR OFF
	MOVEI	T1,[ASCIZ | for exec mode debugging|] ;INCASE "SET EXEC CTRLD"
	SKIPN	P1		;JOB 0?
	PUSHJ	P,CONMES	;YES
	MOVEI	T3,"]"		;GET MESSAGE TERMINATOR
	PJRST	COMTYO		;TYPE IT AND RETURN


; PROCESS SETUUO FUNCTIONS .STEBP AND .STBPT
;
SETEBU:	MOVEI	J,0		;SET EDDT SETUUO FUNCTION
SETUBU:	ANDI	T2,1		;SET DDT SETUUO FUNCTION (FOR USERS)
	DPB	T2,BPTPTR	;TURN .BPT ON OR OFF
	MOVE	J,.CPJOB##	;RELOAD OUR JOB NUMBER
	JRST	CPOPJ1##	;AND RETURN

BPTPTR:	POINT 1,JBTSTS##(J),^L<JS.BPT>
BPTPT1:	POINT 1,JBTSTS##(P1),^L<JS.BPT>
BPTTAB:	SIXBIT	/BREAKP/
BPTTB1:	SIXBIT	/OFF/
	SIXBIT	/ON/
SNDTXS:	MOVE	P3,[POINT 7,(T4)] ;TO COPY THE STRING
	MOVEI	T3,7		;GET A BELL
	IDPB	T3,P3		;STORE IN MESSAGE
	SUBI	P1,1		;ADJUST CHAR COUNT
SNDTX1:	PUSHJ	P,COMTYI##	;NEXT CHARACTER
	IDPB	T3,P3		;STORE IT FOR THE ACTDAE
	CAIE	T3,12		;END OF LINE?
	CAIN	T3,3
	TDZA	P1,P1
	SOJG	P1,SNDTX1	;OR USED ALL THE SPACE?
	IDPB	P1,P3		;ASCIZIZE
	MOVE	T1,P4		;ACTDAE
	MOVE	T4,P2		;LENGTH,,ADDRESS
	PJRST	SNDFFC##	;SEND IT

	SUBTTL	CONTROL-C PROCESSING

; "HALT" OR "<CONTROL>C"
;SCANNER ROUTINES DUMMY UP HALT WHEN CONTROL C TYPED IN
;STOP MUST BE DELAYED IF THIS JOB IS SYSTEM TAPE USER
;AND SYSTEM TAPE IS ACTIVE. OTHERWISE, THE JOB WILL NOT BE
;STOPPED WHEN DONE USING THE SYSTEM TAPE.
;IF JOB IS IN MONITOR MODE AND NOT IN TTY WAIT THIS JOB CANNOT BE STOPPED YET
;IN THIS CASE SET A BIT IN JOB STATUS WORD (CNTRLC) WHICH WILL BE CHECKED
;WHEN JOB RETURNS TO USER MODE


STOP::	MOVE	P2,HALTXT##
STOPF::
IFN FTNET,<
	SE1XCT	<SKIPGE LDBREM##(U)> ;IF SET HOST IN PROGRESS,
	TLO	M,NOCRLP!NOFLM	;DON'T TYPE OUT
> ;END IFN FTNET
	JUMPE	J,STOPB
	TLNE	P4,JACCT	;JACCT AND WAITING
	TRNN	P4,JDCON	;..
	JRST	STOPD		;NO--PROCEED
	JUMPL	P4,STOPD	;JUMP IF RUN BIT IS SET
	TLO	M,NOCRLP	;KILL THE DOT
	POPJ	P,0		;PUNT THE COMMAND
STOPD:	MOVEI	T1,JDCON	;CLEAR JCONT.ABLE (DEV OK?) BIT
	ANDCAM	T1,JBTSTS##(J)	; SO USER CAN STOP ONCE-A-MINUTE STUFF

IFN FTMP,<
	PUSHJ	P,SPSTOP##	;TEST IF JOB ON SLAVE, IF SO SIGNAL TO STOP IT,
	  JRST	DLYCM1		;  AND DELAY COMMAND
>

	PUSHJ	P,SIMCHK##	;OK TO "STOP IN MONITOR"?
	  JRST	STOPA		;YES, STOP JOB
	MOVSI	T1,CNTRLC	;NO, FLAG THAT USER MUST BE STOPPED WHEN
	IORB	T1,JBTSTS##(J)	; RETURNING TO USER MODE IN UUO HANDLER
	TLNE	M,CMWRQ		;IS JOB IN COMMAND WAIT?
	PUSHJ	P,REQUE##	;YES. PUT HIM BACK IN RUNNABLE QUEUE
	JRST	DLYCM1		;THEN DELAY COMMAND (IE ECHO CR-LF, DOT)
				;UNTIL SWAPPED IN
STOPA:	MOVSI	T1,SWP!SHF	;IS THE JOB SWAPPED?
	TDNE	T1,JBTSTS##(J)	;IF SO, DELAY THE CONTROL C SINCE
	PJRST	DLYCM		; THE JOB DATA AREA MUST BE IN CORE
				; TO SEE IF THE JOB IS INTERCEPTING
				; CONTROL C'S
	MOVSI	T1,CNTRLC+CMWB	;DELAYED CONTROL C+ COMMAND WAIT
	ANDCAM	T1,JBTSTS##(J)	;CLEAR THEM
	SKIPL	JBTSTS##(J)	;IS RUN BIT ALREADY OFF?
	JRST	STOPAA		;IF YES, DO NOT PRINT [XXXX] AGAIN
	PUSHJ	P,STOPX		;STOP JOB
	TLNN	M,NOPER		;IF NO PERIOD, SKIP [XXX]
	PUSHJ	P,WCHEND	;PRINT [XXXX] CRLF IF USER IS WATCHING RESPONSES
	JRST	STOPAB		;GO FINISH

STOPAA:	PUSHJ	P,STOPX		;STOP JOB
STOPAB:	SKIPGE	T1,JBTSTS##(J)	;GET JOB STATUS
	JRST	STOPB		;IF NOT STOPPED, DON'T KJOB
	TLNN	T1,JLOG		;IS JOB LOGGED IN?
	PUSHJ	P,TTKJOB##

STOPB:	SKIPL	JBTSTS##(J)	;RUNNING?
	PUSHJ	P,FNDPDB##	;FIND PDB
	  POPJ	P,
	MOVEI	T1,TTFCXI##	;FORCE .INITIA
	MOVEI	T2,JS.RPC	;IF JS.RPC = 1
	SKIPE	.PDPGM##(W)	;AND PROGRAM TO RUN
	TDNN	T2,JBTST2##(J)	; ..
	POPJ	P,0
	PUSHJ	P,TTFORC##
	PJRST	DLYCM

STOPX:	MOVSI	T1,(JS.SAC)	;BIT TO TEST
	TDNE	T1,JBTST2##(J)	;DOING AN AUTO-RESTORE ON PROGRAM EXIT?
	TLO	M,NOCRLP	;YES, DON'T TYPE CRUFT
	PJUMPL	P2,STOP1C##	;IF "HALT", STOP REGARDLESS
	PJRST	STOP1##		;IF "^C^C", STOP IF POSSIBLE
;MONITOR COMMAND LEVEL RESPONSE ROUTINES
;FIVE MULTIPLE ENTRY SUBROUTINES TO PRINT SYSTEM RESPONSE DATA FOR A JOB
;CONTROL REACHES ONE OF THESE ROUTINES ON ANY OF THE FOLLOWING:
;1. USER TYPES CONTROL C
;2. PROGRAM HALTS
;3. PROGRAM CALLS EXIT, OR CALL N,EXIT
;4. DEVICE BECOMES UNREADY  DEVICE XXX OK?
;5. ERROR IN JOB MESSAGE

;PRRSP1 - PRINT CRLF CRLF
;PRRSP3 - PRINT [XXXX] CRLF IF USER WATCHING SYSTEM DATA RESPONSE
;PRRSP4 - PRINT CRLF
;PRRSP5 - PRINT PERIOD


PRRSP1::PUSHJ	P,CRLF		;PRINT CR-LF
PRRSP3::PUSHJ	P,WCHEND	;PRINT SYSTEM RESPONSE DATA IF USER IS WATCHING
PRRSP4::PUSHJ	P,CRLF		;PRINT CR-LF
PRRSP5::PUSHJ	P,FNDPDB##	;ENSURE W IS SETUP
	  PJRST	PRDOTC		;?
	MOVEI	T1,JS.RPC	;RUN PROGRAM BIT
	SKIPE	.PDPGM##(W)	;ANY TO RUN?
	TDNN	T1,JBTST2##(J)	;DOES HE WANT IT RUN
	PJRST	PRDOTC		;NO, PRINT DOT
	POPJ	P,		;YES, DONT PRINT DOT
	SUBTTL	SET COMMAND AND UUO  -- DISPATCH

;SET COMMAND/UUO

SET::	MOVE	P3,[XWD UNQTB2##,DISP2##] ;UNIQUENESS PLUS START OF SET-TABLE
	MOVE	P4,[XWD -DISPL2##,COMTB2##] ;LENGTH, NAME
	MOVE	P,.CPISF##	;RESTORE P TO VALUE AT COMGO
	XJRST	[MCSEC1+COM1]	;GO INTERPRET 2ND PART OF THE COMMAND (IN SECTION 1)

;SUBROUTINE TO SEE IF A SYSTEM-WIDE SET COMMAND IS LEGAL
;SKIP RETURN IF LEGAL, ELSE NON-SKIP

SETLGF==FUPOPJ##
SETLGK==FUPOJ1##
SETLGL::MOVE	T3,LINTAB##+FRCLIN##
	CAMN	T3,U
	JRST	CPOPJ1##
	PUSHJ	P,OPRLGL	;OPR?
	  SKIPA	T2,JBTPPN##(T1)	;NO, CHECK FURTHER
	JRST	CPOPJ1##	;YES, OK
	CAMN	T2,FFAPPN##	;1,2?
	AOS	(P)		;YES, OK
	POPJ	P,		;RETURN
OPRLGL:	PUSH	P,U		;PRESERVE LINE
	PUSH	P,F		;AND F
	MOVE	T1,J
	MOVE	T3,OPRLDB##	;SEE IF OPR
	CAMN	T3,U		;ALSO OPR
	JRST	SETLGK		;WE WIN
	MOVE	T2,JBTSTS##(J)	;GET JOB STATUS
	TLNE	T2,JLOG		;A JOB ON THE TTY?
	JRST	SETLGF		;YES. COMMAND LOSES
	SE1XCT	<LDB T2,LDPLNO##> ;GET LINE NUMBER
	PUSHJ	P,CTLJB##	;LOSE -- SEE IF PTY
	JUMPLE	T1,SETLGF	;NO --- GIVE UP
	HRRZ	U,TTYTAB##(T1)	;OK -- GET DDB
	MOVE	U,DDBLDB##(U)	;THEN GET LDB
	JUMPE	U,SETLGF	;IF CONTROL JOB DETACHED STOP SCAN AND FAIL
	MOVSI	T2,DVDIBP	;GET BATCH JOB BITS
	TDNE	T2,DEVCHR(F)
	JRST	SETLGF		;YES. COMMAND LOSES
	CAMN	T3,U		;OR HIS TTY?
	JRST	SETLGK		;YES. COMMAND WINS
	JRST	SETLGF		;LOSE
	SUBTTL	SET COMMAND AND UUO -- JBSET.

;HERE FROM UUOCON ON JBSET. UUO
;CALL:	MOVE	AC,[+N,,BLK]
;	CALLI	AC,JBSET.
;	  ERROR RETURN AC=0
;	NORMAL RETURN
;BLK:	JOB	NUMBER
;	XWD	FUNCTION,VALUE
UJBSET::PUSHJ	P,PRVJ		;ARE WE A GOOD GUY
	  JRST	JBSET1		;YES--GO DO THE SET
	JRST	RTZER##		;NO--RETURN 0

JBSET1:	PUSH	P,M		;SAVE M
	HRRI	M,(T1)		;GET ADDRESS OF BLK
	PUSHJ	P,GETWDU##	;PICK UP JOB#
	MOVE	J,T1		;PUT JOB NUMBER IN J
	PUSHJ	P,LGLPRC##	;SKIP IF LEGAL JOB NUMBER
	  JRST	JBSET2		;NO, GIVE UP
	MOVSI	T1,JNA		;SEE IF JOB EXISTS
	TDNN	T1,JBTSTS##(J)	;  AND EXISTENT
	JRST	JBSET2		;  YES--GIVE UP
	MOVE	T4,J		;SAVE NEW JOB
	PUSHJ	P,GETWD1##	;GET NEXT WORD(XWD) PUT IT IN T1
	MOVE	J,T4		;RESTORE NEW JOB
	NOSCHED
	PUSH	P,JBTPPN##(J)	;SAVE PPN
	MOVE	T2,FFAPPN##	;GET A GOOD PPN
	MOVEM	T2,JBTPPN##(J)	;FAKE OUT PRIVJ AND PRVBIT
	PUSH	P,J
	PUSH	P,W		;PRESERVE W
	PUSHJ	P,FNDPDS##	;GET THE PDB FOR THE TARGET JOB
	PUSHJ	P,SETUUO	;DO IT
	  TDZA	T1,T1		;NOTE BAD RETURN
	SETO	T1,		;GOOD RETURN
	POP	P,W		;RESTORE W
	POP	P,J
	POP	P,JBTPPN##(J)	;RESTORE PPN
	SCHEDULE
	POP	P,M
	JUMPN	T1,CPOPJ1##	;PASS THE GOOD WORD ON
	JRST	STOTAC##	;ELSE RETURN ZERO

JBSET2:	POP	P,M		;RESTORE AC
	JRST	RTZER##		;GIVE ERROR
	SUBTTL	SET COMMAND AND UUO -- PRIVILEGE TESTS

;DISPATCH HERE (FROM UUOCON) ON A SETUUO
;CALL:	MOVE AC,[XWD FUNCTION,ARGUMENT]
;	CALLI AC,SETUUO
NEDPRV==1			;BIT ON IN DISPATCH TABLE IF PRIVS NEEDED
NLOGOK==2			;BIT ON IS DISPATCH IF OK WHEN NOT LOGGED IN
SETUUO::HRRZ	T2,T1		;ARGUMENT
	HLRES	T1		;FUNCTION
	CAML	T1,[SETTBC-SETTBL] ;A LEGAL CUSTOMER FUNCTION?
	CAILE	T1,SETLEN	;A LEGAL FUNCTION?
	POPJ	P,		;NO, RETURN DOING NOTHING
	MOVE	T1,SETTBL(T1)	;YES, GET TABLE WORD
	TLNE	T1,NEDPRV	;NEED SPECIAL PRIVS TO DO IT?
	PUSHJ	P,PRVJ		;YES, JOB HAVE PRIVS?
	  PJRST (T1)		;YES, DISPATCH
	TLNE	T1,NLOGOK	;NO PRIVS, IS IT OK IF NOT LOGGED IN?
	TLNE	T3,JLOG		;YES, IS JOB LOGGED IN?
	JRST	ECOD0##		;LOGGED IN OR NO PRIVS, ERROR RETURN
	PJRST	(T1)		;DISPATCH FUNCTION
;SUBROUTINE TO SEE IF A JOB HAS PRIVILEGE:
;CALL:	MOVE T1,BIT TO BE TESTED IN PRIVILEGE WORD
;	MOVE J,JOB NUMBER
;	PUSHJ P,PRVBIT
;	  RETURN IF PRIVILEGED BY BIT, [1,2], OR JACCT
;	RETURN IF NOT PRIVILEGED
;RESPECTS T2

PRVBIT::TDNE	T1,JBTPRV##(J)	;IS REQUESTED BIT ON IN TABLE?
	POPJ	P,		;YES. OK RETURN
;	PJRST	PRVJ		;NO. CHECK FOR JACCT OR FSFPPN


;SUBROUTINE TO TEST FOR [1,2] OR JACCT PRIVILEGES.
;NEEDED IF A SETUUO FOR A SYSTEM-PARAMETER IS DONE.
;RETURNS CPOPJ IF HAVE PRIVS, CPOPJ1 IF DON'T.
;RESPECTS T2

PRVJ::	MOVE	T3,JBTSTS##(J)	;JBTSTS WORD
	SKIPGE	M		;COMMAND LEVEL?
	TLZA	T3,JACCT	;YES--CLEAR JACCT
PRVJC::	MOVE	T3,JBTSTS##(J)	;IF AT UUO LEVEL AND THE SIGN BIT OF M COULD BE ON
	MOVE	T4,JBTPPN##(J)	;JOB'S PRJ-PRG
	CAME	T4,FFAPPN##	;=1,2?
	TLNE	T3,JACCT	;NO, JACCT ON?
	POPJ	P,		;YES, OK
	PJRST	CPOPJ1##	;NO, ERROR RETURN
;TABLE FOR SETUUO.  NEGATIVE FUNCTIONS ARE CUSTOMER DEFINED.
;POSITIVE FUNCTIONS ARE RESERVED FOR DEC.

SETTBC:				;MINIMUM CUSTOMER DEFINED FUCTION
IFN FTPATT,<
	EXP	CPOPJ##		;ROOM FOR PATCHING
>; END IFN FTPATT
SETTBL:	XWD	NEDPRV,SETMX1	;(0) - SET CORMAX
	XWD	NEDPRV,SETMN1	;(1) - SET CORMIN
	XWD	NEDPRV,SETDA1	;(2) - SET DAYTIME
	XWD	NEDPRV,SETSC1	;(3) - SET SCHED
	EXP	SETSPI		;(4) - SET CDR
	EXP	SETSPB		;(5) - SET SPOOL
	EXP	SETWTU		;(6) - SET WATCH
	XWD	NEDPRV,SETDT1	;(7) - SET DATE
	XWD	NEDPRV,SETOP1	;(10) - SET OPR (INDIRECT)
	XWD	NEDPRV,SETKSY	;(11) - SET KSYS
	XWD	NEDPRV,CORELM##
	EXP	SETIM1		;(13) - SET TIME LIMIT
	EXP	SETCPU##	;(14) - SET USER CPU SPECIFICATION
	XWD	NEDPRV,SETCRN##	;(15) - SET CPU RUNABILITY
	XWD	NEDPRV,SETLMX	;(16) - SET LOGMAX
	XWD	NEDPRV,SETBMX	;(17) - SET BATMAX
	XWD	NEDPRV,SETBMN	;(20) - SET BATMIN
	EXP	DSKFUL		;(21) - SET DSKFUL- PAUSE OR ERROR
	XWD	NEDPRV,SETVM1##	;(22) - SET VMMAX (SYSTEM-WIDE)
	XWD	NEDPRV,CPOPJ1##	;(23) - HISTORICAL
	XWD	NEDPRV+NLOGOK,SETUVL##	;(24) - SET VM MAXIMA (USER)
	EXP	SETUV1##	;(25) - SET CURRENT VM MAXIMA (USER)
	EXP	SETVTM##	;(26) - SET TIME FOR VIRTUAL TIME INTERRUPTS
	EXP	SETABR		;(27)-SET ADDRESS BREAK
	EXP	SETPGM		;(30)-SET PROGRAM TO RUN
	EXP	SETDFU		;(31)-SET DEFERED SPOOLERS
IFN FTNET,<
	XWD	NEDPRV,HOST.U##	;(32)-SET HOST
>
IFE FTNET,<
	EXP	CPOPJ##		;(32)-SET HOST - NOT DEFINED
>
	EXP	SETDLU		;(33)-SET DEFAULTS
	EXP	SETPRV		;(34)-SET PRIVILEGES
	XWD	NEDPRV,SETBSN	;(35) SET BATCH STREAM NUMBER
	XWD	NEDPRV,SETWTO	;(36) SET WTO CAPABALITIES
	XWD	NEDPRV,SETCDN##	;(37) SET CPU UP/DOWN STATUS
IFN FTKL10,<
IFN FTMP,<
	XWD	NEDPRV,SETCSB##	;(40) SET/CLEAR CACHE BITS
>
IFE FTMP,<
	EXP 	CPOPJ##		;(40) SET/CLEAR CACHE BITS - NOT DEFINED
>
> ;END IFN FTKL10
IFN FTKS10,<
	EXP 	CPOPJ##		;(40) SET/CLEAR CACHE BITS - NOT DEFINED
>; END IFN FTKS10
	EXP	SETFPS##	;(41) SET/CLEAR FLOATING POINT SIMULATION
	XWD	NEDPRV+NLOGOK,SETOPP ;(42) SET OPERATOR PRIVS
	XWD	NEDPRV,SETQST	;(43) SET QUEUE STRUCTURE
	XWD	NEDPRV,CSHSIZ##	;(44) SET DISK BLOCK CACHE SIZE
	XWD	NEDPRV,SETEBU	;(45) SET EDDT BREAKPOINT ON/OFF
	EXP	SETUBU		;(46) SET DDT BREAKPOINT ON/OFF
	XWD	NEDPRV,SETDA0	;(47) SET TIME OF DAY IN SECONDS
	XWD	NEDPRV,SETMXP	;(50) SET CORMAX IN PAGES
	XWD	NEDPRV,SETMNP	;(51) SET CORMIN IN PAGES
IFN FTMP,<
	EXP	SETPCP##	;(52) SET POLICY CPU
>; END IFN FTMP
IFE FTMP,<
	EXP 	CPOPJ##		;(52) SET POLICY - UNDEFINED IF NOT FTMP
>; END IFE FTMP
	XWD	NEDPRV,SETDJB##	;(53) SET DAEMON JOB NUMBER
	EXP	SETITP##	;(54) SET INTERVAL TIMER PATCH
IFN FTPATT,<
	EXP	CPOPJ##		;ROOM FOR PATCHING
>; END IFN FTPATT
SETLEN==.-SETTBL-1


IFE FTLOCK,<
SETMN1==CPOPJ##
SETMNP==CPOPJ##
>; END IFE FTLOCK
	SUBTTL	SET COMMAND AND UUO -- CORMAX AND CORMIN

SETMXP:	AOS	T3,T2		;COMPUTE HIGHEST ADDRESS
	ANDI	T3,400000	;PRESERVE SOFT CORMAX FLAG
	TRZ	T2,400000	;KEEP ONLY NUMBER OF PAGES
	LSH	T2,P2WLSH	;CHANGE TO WORDS
	SOSA	T2		;CONTINUE
SETMX1:	SETZ	T3,		;HARD CORMAX FOR OLD FUNCTION CODE
IFN FTLOCK,<
	SKIPE	LOCK##		;JOB BEING LOCKED?
	JRST	ECOD0##		;YES - CAN'T CHANGE CORMAX
>
	JRST	SETMX2		;ENTER COMMON CODE

SETMAX::PUSHJ	P,CORLGL	;GET DECIMAL ARG IF LEGAL
IFN FTLOCK,<
	SKIPE	LOCK##		;IF A JOB IS BEING LOCKED,
	JRST	DLYCM1		;WAIT TILL LATER
>
	SETZ	T3,		;FORCE HARD CORMAX FOR COMMAND

SETMX2:	PUSH	P,T3		;SAVE HARD/SOFT CORMAX FLAG
	MOVE	T1,RMCMAX##	;REAL MAXIMUM CORMAX, INCLUDING FUNNY SPACE
	CAMG	T2,T1		;TRY TO SET IT TOO HIGH?
	JRST	SETAOK		;NO
	JUMPGE	M,SETMXE	;RETURN ERROR IF UUO
	PUSHJ	P,INLMES
	ASCIZ	/
%Exceeds physical maximum-/
	MOVE	T1,RMCMAX##	;GET REAL MAXIMUM
	LSH	T1,W2PLSH	;SET UP FOR P OR K
	PUSHJ	P,PRCORE	;TELL WHAT IT IS
	MOVE	T2,RMCMAX##	;REDUCE PHYSICAL LIMIT
SETAOK:	CAIL	T2,MINMAX##	;TOO SMALL?
	JRST	SETIOK		;NO
	JUMPGE	M,SETMXE	;RETURN ERROR IF UUO
	PUSHJ	P,INLMES
	ASCIZ	/
%Below minimum-/
	MOVEI	T1,MINMAX##	;GET MINIMUM
	LSH	T1,W2PLSH
	PUSHJ	P,PRCORE	;REPORT IT
	MOVEI	T2,MINMAX##
SETIOK:	POP	P,T3		;GET FLAG BACK
	JUMPN	T3,SETMXF	;CONTINUE IF SOFT CORMAX
	CAMGE	T2,CORMAX##	;DECREASING?
	PUSHJ	P,CHKMAX	;YES. CHECK JOB SIZES
SETMXF:	MOVEM	T2,CORMAX##	;SAVE NEW VALUE
	LSH	T2,W2PLSH	;REDUCE TO N
	HRRM	T2,CORLIM##	;SAVE IN RH(CORLIM)
	JRST	CPOPJ1##	;AND SKIP RETURN
SETMXE:	POP	P,(P)		;PHASE STACK
	JRST	ECOD0##		;RETURN ERROR CODE 0 (BAD ARGUMENT)

CHKMAX:	PUSHJ	P,SAVE3##	;SEE IF NEW CORMAX
	SETZ	P1,0		;IS TOO SMALL FOR
	PUSH	P,J		;JOBS NOW RUNNING
	MOVE	P2,T2		;SAVE DESIRED NEW VALUE
	MOVEI	J,1		;SCAN ALL JOBS
CHKMX1:	MOVE	T2,JBTSTS##(J)	;DON'T COUNT LOCKED JOBS
	TLNE	T2,NSHF!NSWP
	TDZA	T2,T2		;THIS JOB IS LOCKED
	PUSHJ	P,SEGSIZ	;GET LOW SEG SIZE
	PUSH	P,J		;SAVE JOB #
	HRRZ	T3,JBTSGN##(J)	;SEE IF USER HAS ANY HIGH SEGS
	JUMPE	T3,CHKMX2	;NO
CHKM1A:	SKIPLE	J,.HBSGN(T3)	;IS THIS HIGH SEG REAL?
	TLNE	J,NSWP!NSHF	;AND NOT LOCKED?
	JRST	CHKM1B		;LOCKED OR SPY
	MOVE	P3,T2		;SAVE CURRENT SUM
	PUSHJ	P,SEGSIZ	;GET HISEG SIZE
	ADDI	T2,(P3)		;TOTAL
CHKM1B:	HRRZ	T3,.HBLNK(T3)	;POINT TO NEXT HIGH SEG
	JUMPN	T3,CHKM1A
CHKMX2:	LSH	T2,P2WLSH	;TOTAL WORDS
	CAMLE	T2,P1		;BIGGEST SO FAR?
	MOVE	P1,T2		;YES
	POP	P,J		;GET BACK JOB #
	CAMGE	J,HIGHJB##	;ALL JOBS SCANNED?
	AOJA	J,CHKMX1	;NO
	CAMG	P1,P2		;BIGGEST JOB FIT NEW CORMAX?
	JRST	CHKMX3		;YES. OK AS IS
	MOVE	P2,P1		;NO. ADJUST REQUEST
	JUMPGE	M,CHKMX3
	PUSHJ	P,INLMES
	ASCIZ	/
%Too small for current job(s)-/
	MOVE	T1,P2		;GET SIZE OF LARGEST JOB
	LSH	T1,W2PLSH
	PUSHJ	P,PRCORE	;REPORT IT
CHKMX3:	MOVE	T2,P2
	POP	P,J		;BALANCE STACK
	JRST	ECOD0##		;RETURN ERROR


IFN FTLOCK,<
SETMNP:	LSH	T2,P2WLSH	;CONVERT TO WORDS
	TROA	T2,PG.BDY	;CONVERT TO HIGHEST LEGAL ADDRESS
SETMIN::PUSHJ	P,CORLGL	;GET DECIMAL ARG IF LEGAL
SETMN1:	CAMLE	T2,CORMAX##	;CORMIN CAN'T
	MOVE	T2,CORMAX##	;EXCEED CORMAX
	MOVEM	T2,CORMIN##	;SET NEW VALUE IN CORMIN
	JRST	CPOPJ1##	;AND SKIP RETURN
>
;SUBROUTINE TO GET CORE ARGUMENT AND CHECK FOR LEGALITY
; DOES NOT RETURN IF NOT LEGAL
CORLGL::PUSHJ	P,SETLGL	;TEST FOR LEGALITY
	  JRST	COMERP		;NOT LEGAL
	PUSHJ	P,CORARG	;GET THE CORE ARGUMENT
	  JRST	NOTENP		;NOT ENOUGH ARGUMENTS
	AOS	T2,T1		;CONVERT TO NUMBER OF WORDS
	POPJ	P,		;RETURN


;SUBROUTINE TO TEST FOR LEGALITY, RETURN NEXT TYPED ARGUMENT IF LEGAL
;DOES NOT RETURN IF NOT LEGAL
DECLGL::PUSHJ	P,SETLGL	;TEST FOR LEGALITY
	  JRST	COMERP		;NOT LEGAL
	PUSHJ	P,DECIN1	;LEGAL - GET DECIMAL NUMBER
	  PJRST NOTENP		;NOT ENOUGH ARGS
	  PJRST COMERP		;NOT A NUMBER
	POPJ	P,		;OK - RETURN
;HERE TO SET MEMORY ON OR OFF LINE
SETMEM::PUSHJ	P,SETLGL	;MUST BE PRIVILEGED
	  JRST	COMERA		;NOT PRIVLEGED, LOSE
;	PUSHJ	P,SAVE2##
	PUSHJ	P,CTEXT		;GET MODIFIER
	JUMPE	T2,NOTENF	;MUST BE ONE
	MOVE	T1,[-2,,[SIXBIT /ON/
			 SIXBIT /OFF/]]
	PUSHJ	P,FNDNAM	;LOOK FOR EITHER "ON" OR "OFF"
	  JRST	COMERA		;IF NEITHER, LOSE
	MOVE	P1,T1		;REMEMBER WHETHER HE SAID ON OR OFF
	PUSHJ	P,SKIPS1	;SKIP SPACES, TABS, ETC.
	  JFCL			;IGNORE NON-SKIP RETURN
	CAIN	T3,"-"		;ALLOW "-LINE"
	PUSHJ	P,COMTYS	;IF A MINUS SIGN WAS TYPED, SKIP IT
	MOVE	T1,[-2,,[SIXBIT /LINE/
			 SIXBIT /FROM/]]
	PUSHJ	P,TXTARG	;ALLOW NOISE WORDS
	  JRST	SETME0		;NONE WAS TYPED
	JUMPN	T1,SETME0	;SKIP ON IF "FROM" WAS TYPED
	HRROI	T1,[SIXBIT/FROM/]
	PUSHJ	P,TXTARG	;"LINE" WAS TYPED, EAT "FROM" IF ITS THERE
	  JFCL			;DON'T CARE WHETHER IT WAS ON NOT
SETME0:	PUSHJ	P,DECIN1	;READ AN ARGUMENT (DEFAULT IS DECIMAL)
	  JRST	NOTENF		;THERE MUST BE ONE
	  PUSHJ	P,[CAIE	T3,"K"	;NUMBER ENDED WITH A NON-DIGIT,
		   CAIN	T3,"P"	; WAS IT "P" OR "K"?
		   CAIA		;YES
		   JRST	COMERP	;NO, COMPLAIN
		   MOVEI T1,P2WLSH
		   CAIE	T3,"P"	;ARGUMENT SPECIFIED IN PAGES?
		   MOVEI T1,K2WLSH
		   LSH	T2,(T1)	;CONVERT TO WORDS
		   JRST	COMTYS]	;AND EAT THE "P" OR "K"
	MOVE	P2,T2		;SAVE THE LOWER BOUND
	HRROI	T1,[SIXBIT/TO/]
	PUSHJ	P,TXTARG	;ALLOW THE NOISE WORD "TO"
	  JFCL			;DON'T CARE IF IT ISN'T THERE
	PUSHJ	P,DECIN1	;READ THE SECOND ARGUMENT
	  JRST	NOTENF		;THERE MUST BE ONE
	  PUSHJ	P,[PUSHJ P,[CAIE T3,"K"
		   CAIN	T3,"P"	;ONCE AGAIN, ALLOW ARGUMENT TO BE
		   CAIA		; QUALIFIED BY "P" OR "K"
		   JRST	COMERP	;HOWEVER, NOTHING ELSE WILL DO
		   MOVEI T1,P2WLSH
		   CAIE	T3,"P"	;PAGES?
		   MOVEI T1,K2WLSH
		   LSH	T2,(T1)	;CONVERT TO WORDS
		   JRST	COMTYS]	;AND THROW AWAY THE CHARACTER
		   SOJA T2,CPOPJ##]
	CAMG	P2,T2		;FIRST ARGUMENT MUST BE .LT. THE SECOND
	CAIE	T3,12		;AND THE LINE MUST BE PROPERLY TERMINATED
	JRST	COMERA		;GRUMBLE
	MOVE	T1,P2		;RESTORE FROM ARGUMENT
	TRZ	T1,PG.BDY	;ROUND TO A PAGE BOUNDARY
	TRZ	T2,PG.BDY	; ..
	ADDI	T2,PAGSIZ	;ROUND UP
	LSHC	T1,W2PLSH	;CONVERT FROM WORDS TO PAGES
;HERE T1 = LOWEST PAGE NUMBER (K NUMBER) OPR TYPED
;     T2 = HIGHEST PAGE NUMBER (K NUMBER) + 1 OPR TYPED
;P1 = 0 IF SET MEMORY ON LINE
;P1 = 1 IF SET MEMORY OFF LINE
;DISPATCH TO ROUTINE TO SET MEMORY ON OR OFF LINE
	JUMPN	P1,SETME1
;HERE TO SET MEMORY ON LINE, T1 = FIRST PAGE TO SET ON LINE, T2 = LAST
; PAGE + 1
MEMONL::HRLZ	S,T1		;STARTING PAGE TO SET ON LINE
	HRR	S,T2		;HIGHEST PAGE TO SET ON LINE
	JSP	T2,SAVCTX##	;SAVE THE JOB'S CONTEXT AND RETURN AT UUO LEVEL
				; (THE JOB'S CONTEXT MUST BE SAVED BECAUSE
				; IF SETTING THE MEMORY ON LINE CAUSES
				; A NXM, THE JOB'S CONTEXT WILL BE DESTROYED)
	HLRZ	T1,S		;RESTORE THE STARTING PAGE TO SET ON LINE
	HRRZ	T2,S		;AND THE HIGHEST PAGE TO SET ON LINE

;JOIN HERE FOR RECON. UUO TO SET MEMORY ON LINE
MEMONU::SE1ENT			;ENTER SECTION 1, TO LOOK AT PAGTAB.
	MOVE	T3,[NXMTAB##,,OLDNXM##] ;SET UP BLT TO COPY NXMTAB
	BLT	T3,NXMTAB##+NXMTBL##-1 ;MAKE "OLD" COPY OF ERROR LOGGING
	MOVE	T3,MEMSIZ##	;CURRENT HIGHEST ADDRESS IN THE MACHINE
	MOVE	T4,NWCORE##	;HIGHEST ADDRESS THAT CAN BE SET ON LINE
				; (CANNOT MAKE PAGTAB AND MEMTAB BIGGER)
	LSHC	T3,W2PLSH	;CONVERT TO PAGES
	CAMG	T3,T4		;PICK THE BIGGER OF THE TWO AS THE
	MOVE	T3,T4		; HIGHEST ADDRESS THAT CAN BE SET ON LINE
	TRZE	T3,PG.BDY	;ROUND UP TO A 256K BOUNDARY (IF NOT
	ADDI	T3,PAGSIZ	; ALREADY ON A 256K BOUNDARY
	CAMG	T3,T2		;IF ASKING FOR MEMORY ON LINE ABOVE THE
				; HIGHEST WHICH CAN BE DONE,
	MOVE	T2,T3		; SET ON UP TO THE HIGHEST THAT CAN BE DONE
	CAML	T1,T2		;LOWEST PAGE ABOVE THE HIGHEST PAGE?
	POPJ	P,		;YES, NOTHING TO SET ON LINE
	MOVE	P1,T1		;LOWEST PAGE TO SET ON LINE
	IDIVI	P1,^D36		;COMPUTE BIT POSITION AND WORD NUMBER WITHIN NXMTAB
	MOVNI	P2,-^D35(P2)	;BIT POSITION BYTE POINTER STYLE
	HRLI	P1,(POINT 1,0,0);FORM A 1 BIT BYTE POINTER TO NXMTAB
	DPB	P2,[POINT 6,P1,5]
	ADDI	P1,NXMTAB##	;BYTE POINTER TO BIT CORRESPONDING TO FIRST PAGE TO SET ON
	SETZB	T4,P2		;INITIALIZE FIRST AND HIGHEST NON-EXISTANT PAGES SEEN
	MOVEI	P3,PAGSIZ	;TO UPDATE MAXMAX ON EACH PAGE SET ON LINE
IFN FTMP,<
	PUSHJ	P,UPMM##	;GET THE MM RESOURCE
>
MEMON6:	MOVE	T3,@[IW MS.MEM,PAGTAB(T1)] ;PAGE DESCRIPTOR BITS
	TLNE	T3,NXMBIT	;IS THIS PAGE NON-EXISTANT?
	TLNE	T3,MONTRB	;IF AN UNMAPPED MONITOR PAGE SKIP IT TOO
	JRST	MEMON8		;NO, ITS ALREADY ON LINE
	DPB	P3,P1		;INDICATE THIS PAGE EXISTS IN NXMTAB
	PUSHJ	P,MEMOZR	;ZERO OUT THE PAGE AND CHECK FOR NXM
	  JRST	MEMON8		;GOT AN NXM
	ADDM	P3,MAXMAX##	;INCREASE THE MAXIMUM VALUE FOR CORMAX
	ADDM	P3,RMCMAX##	;INCREASE REAL MAX VALUE FOR CORMAX
	SKIPN	P2		;SKIP IF NOT THE FIRST PAGE SET ON LINE
	MOVE	P2,T1		;REMEMBER THE FIRST PAGE SET ON LINE
	JUMPE	T4,MEMON7	;JUMP IF FIRST PAGE
	HRRZM	T1,@[IW MS.MEM,PAGTAB(T4)] ;LINK PAGES BEING SET ON LINE TOGETHER
MEMON7:	MOVE	T4,T1		;REMEMBER LAST PAGE
MEMON8:	IBP	P1		;BUMP BYTE POINTER TO NEXT PAGE IN NXMTAB
	CAIE	T1,-1(T2)	;LOOKED AT THE ENTIRE RANGE OF PAGES TO SET ON LINE?
	AOJA	T1,MEMON6	;NO, LOOK AT THE NEXT PAGE
IFE FTMP,<
	JUMPE	P2,CPOPJ##	;RETURN DOING NOTHING IF ALL PAGES WERE ALREADY
>				; ON LINE
IFN FTMP,<
	PJUMPE	P2,DWNMM##	;GIVE UP THE MM
>
	SETZM	@[IW MS.MEM,PAGTAB(T4)] ;INDICATE END OF THE LIST OF PAGES SET ON LINE
;HERE WHEN MEMORY HAS BEEN MARKED ON LINE AND CHECKED FOR NXM.
;ADD ALL PAGES WHICH WERE OFF LINE TO THE FREE CORE LIST.

	MOVE	T1,P2		;FIRST PAGE IN THE LIST OF PAGES SET ON LINE
	MOVE	P1,T4		;LAST PAGE FREED
	LSH	T4,P2WLSH	;HIGHEST ADDRESS SET ON LINE
	ADDI	T4,PAGSIZ	;ADDRESS OF PAGE FOLLOWING HIGHEST SET ON LINE
	CAMLE	T4,MEMSIZ##	;IS THAT GREATER THAN CURRENT MEMORY SIZE?
	MOVEM	T4,MEMSIZ##	;YES, SAVE NEW HIGHEST ADDRESS IN MEMORY + 1
	MOVE	T4,MEMSIZ##	;HIGHEST ADDRESS IN MEMORY + 1
	LSH	T4,W2PLSH	;CONVERT TO HIGHEST PAGE
	MOVE	T2,T4		;NEW HIGHEST PAGE
	TRZE	T2,PG.BDY	;ROUND UP
	ADDI	T2,PP256K##	;TO A 256K BOUNDARY
	IDIVI	T2,^D36		;BITS/WORD
	MOVNI	T2,1(T2)	;NEGATIVE LENGTH OF NXMTAB
	HRLM	T2,NXMPTR##	;UPDATE NXMPTR TO REFLECT ADDITIONAL MEMORY
	MOVEI	T4,PAGTAB-1(T4)	;BYTE POINTER TO HIGHEST PAGE IN MEMORY
	SSX	T4,MS.MEM	;GIVE IT A SECTION NUMBER
	MOVEM	T4,CORLST##	;STORE THAT FOR CHKTAL
	SSX	T1,MS.MEM	;CLEAR BACK POINTER SO
	HLLZS	PT2TAB(T1)	;GVPAGS DOESN'T GET CONFUSED
	PUSHJ	P,GVPAGS##	;ADD THE PAGES SET ON LINE TO THE FREE CORE LIST

;FINISH UP

	PUSHJ	P,CPINXF##	;FIX CORE ALLOCATION VARIABLES
	  JFCL			;CORMAX MAY HAVE CHANGED, BUT ALL JOBS WILL STILL FIT
IFN FTMP,<
	PUSHJ	P,DWNMM##	;GIVE UP THE MM
>; END IFN FTMP

	MOVEI	T1,.CSCMO	;CONFIG STATUS CODE
	PJRST	MEMELG##	;MAKE AN ERROR LOG ENTRY
;ROUTINE TO ZERO THE PAGE BEING SET ON-LINE AND CHECK FOR NXM.
;CALL WITH T1=PAGE NUMBER, P1=BYTE POINTER TO NXMTAB
;RETURNS CPOPJ IF NXM, CPOPJ1 IF PAGE OK.
;MUST BE CALLED WITH MM, RETURNS WITH MM.
;PRESERVES T1-T4.

MEMOZR:	PUSHJ	P,SAVT##	;SAVE T1-T4
	HRRZ	T3,T1		;GET PAGE NUMBER
	MOVE	T4,.CPMAP##	;GET ADDRESS OF EXEC MAP
	HRLI	T3,(<PM.DCD>B2+PM.WRT) ;ACCESSIBLE AND WRITABLE
	MOVEM	T3,.EUPMP/PAGSIZ(T4) ;SET NEW MAPPING FOR PAGE
	CLRPT	.EUPMP		;FLUSH PAGE TABLE SO NEW MAPPING IS IN EFFECT
IFN FTMP,<
	PUSHJ	P,DWNMM##	;GIVE UP THE MM IN CASE NXM HAPPENS
>; END IFN FTMP
	MOVEI	T4,1000		;TIME TO WAIT FOR NXM TO CAUSE AN INTERRUPT
	MOVEM	J,MOFLPG##	;FLAG WE ARE SETTING MEMORY OFF-LINE
	SETZM	.EUPMP		;ZERO FIRST WORD OF PAGE
	SOJG	T4,.		;WAIT LONG ENOUGH FOR NXM INTERRUPT TO HAPPEN
	LDB	T3,P1		;GET BIT FROM NXMTAB
	JUMPN	T3,MEMOZ1	;JUMP IF NXM HAPPENED
	MOVE	T3,[XWD .EUPMP,.EUPMP+1] ;SET TO CLEAR REMAINDER OF PAGE
	MOVEI	T4,1000		;TIME TO WAIT FOR NXM TO CAUSE AN INTERRUPT
	BLT	T3,.EUPMP+PG.BDY ;ZERO THE REMAINDER OF THE PAGE
	SOJG	T4,.		;WAIT LONG ENOUGH FOR NXM INTERRUPT TO HAPPEN
	LDB	T3,P1		;GET BIT FROM NXMTAB
	SKIPN	T3		;DID NXM HAPPEN?
	AOS	(P)		;NO, SET UP SKIP RETURN
MEMOZ1:	SETZM	MOFLPG##	;NO LONGER CHECKING FOR OFFLINE PAGE
IFN FTMP,<
	PUSHJ	P,UPMM##	;GET BACK THE MM
>; END IFN FTMP
	POPJ	P,		;RETURN
SETME1:	SKIPN	[M.LOK##]	;MUST HAVE THE LOCK UUO TO SET MEMORY OFF
	JRST	COMERA		;ERROR IF LOKCON NOT LOADED
	PUSHJ	P,CKMOL##	;CHECK THAT RANGE DOESN'T OVERLAP THE MONITOR
	  JRST	SETME6		;IT DOES SO WE CAN'T DO IT
	LDB	T3,[POINT 14,NWCORE##,26] ;GET TOTAL SIZE (ON OR OFF)
	CAIL	T1,(T3)		;LOWER BOUND BEYOND END?
	POPJ	P,		;YES, IT'S ALREADY OFF
	CAIL	T2,(T3)		;UPPER BOUND BEYOND END?
	MOVE	T2,T3		;YES,CHANGE UPPER BOUND
	PUSH	P,T1		;SAVE LOWER BOUND
	PUSH	P,T2		;AND UPPER BOUND
	MOVEI	P1,[ASCIZ /?Job(s) too big to continue to run/]
	PUSHJ	P,NEWCMX##	;SEE IF ALL JOBS CAN CONTINUE TO RUN
	JUMPLE	T1,[POP P,(P)	;IF .LE. 0, TRYING TO SET MONITOR MEMORY OFF LINE
		    POP P,(P)
		    JRST SETME6];GO EXPLAIN THE PROBLEM
	PUSH	P,J		;SAVE J FOR COMRET
	MOVEI	J,0		;STARTING WITH JOB 0,
SETME3:	PUSHJ	P,JBSTBG##	;MAKE SURE ALL JOBS CAN STILL RUN (I.E., NONE IS TOO BIG)
	  JRST	SETME4		;NONE ARE
	PUSHJ	P,MOLMS		;TELL THE OPR ABOUT THIS JOB
	JRST	SETME3		;AND LOOK FOR MORE THAT ARE TOO BIG
SETME4:	JUMPE	P1,SETME7	;EXIT IF SOME JOBS WERE TO BIG
	MOVEI	P1,[ASCIZ /?Attempt to set memory containing locked jobs off-line/]
	MOVEI	J,0		;STARTING WITH JOB 0,
	MOVE	T1,-2(P)	;LOWER BOUND,
SETME5:	MOVE	T2,-1(P)	;UPPER BOUND,
	PUSHJ	P,CKLJB##	;SEE IF RANGE OVERLAPS SOME LOCKED JOB
	  JRST	SETME7		;IT DOESN'T SO ALL IS WELL
	PUSHJ	P,MOLMS		;TELL THE OPR ABOUT THIS JOB
	JRST	SETME5		;AND LOOP TO SEE IF THERE ARE ANY MORE IN THE WAY
SETME6:	JSP	T1,ERRMES	;PRINT THE ERROR MESSAGE
	ASCIZ	/Attempt to set monitor memory off-line/
SETME7:	POP	P,J		;RESTORE J FOR COMRET
	POP	P,T2		;RESTORE UPPER BOUND
	POP	P,T1		;AND LOWER BOUND
	JUMPE	P1,PCRLF	;EXIT IF THERE WAS AN ERROR
	PJRST	MEMOFL##	;GO SET THE MEMORY OFF-LINE

MOLMS:	PUSH	P,T1		;SAVE T1
	SKIPE	T1,P1		;SKIP IF ERROR MESSAGE WAS ALREADY TYPED
	PUSHJ	P,CONMES	;TYPE THE ERROR MESSAGE
	MOVEI	T1,[ASCIZ/
?Problem with job(s)/]
	SKIPE	P1		;SAY PROBLEM WITH JOBS ONCE
	PUSHJ	P,CONMES	;TYPE THAT
	MOVEI	P1,0		;FLAG AN ERROR AND DON'T PRINT ERROR HEADING TWICE
	TLO	M,ERRFLG	;TELL COMRET THAT THERE WAS AN ERROR
	PUSHJ	P,PRJBNM##	;DISPLAY INFO. ABOUT THE PROBLEM JOB
	JRST	TPOPJ##		;RESTORE T1, AND RETURN
	SUBTTL	SET COMMAND AND UUO -- DAYTIME AND SCHED

SETDAY::PUSHJ	P,SETLGL
	  JRST	COMERA
	PUSHJ	P,RDTIM		;GET TIME OF DAY
	  PJRST	ERRCRL		;ISSUE CRLF/ERROR MESSAGE AND RETURN
	JRST	SETDA3		;SKIP AROUND SETUUO CHECK

SETDA0:
IFN FTMP,<	                ;IF SMP
 	PUSHJ	P,ONCPU0##	;RUN ON POLICY CPU
>; END IFN FTMP
	CAIL	T2,<^D24*^D60*^D60> ;RANGE CHECK IT
	JRST	ECOD3##		;ILLEGAL TIME (GREATER THAN 23:59:59)
	MOVE	T1,T2		;SHUFFLE TIME TO SAME AC RDTIM USES

SETDA3::MOVE	T4,T1		;SAVE RESULT
	IDIVI	T1,^D60*^D60	;T1:= HOURS
	IDIVI	T2,^D60		;T2:= MINUTES, T3:= SECONDS
	MOVEM	T1,LOCHOR##	;SAVE HOURS
	MOVEM	T2,LOCMIN##	;SAVE MINUTES
	MOVEM	T3,LOCSEC##	;SAVE SECONDS
	IMUL	T4,TICSEC##	;CONVERT TO JIFFIES
	MOVEM	T4,TIME##	;SAVE IT
	MOVEM	T4,.CPTML##	;SAVE TIME AT THE LAST CLOCK TIC
	MOVEI	T1,.C0CDB##	;POINT AT FIRST CDB
	MOVN	T2,T3		;GET -SECONDS
	ADDI	T2,^D60		;GET SECONDS 'TIL NEXT MINUTE
	MOVE	T3,TICSEC##	;TIME TO NEXT SECOND
	JRST	SETDA2		;ENTER COMMON CODE

SETDA1:
IFN FTMP,<			;IF SMP
	PUSHJ	P,ONCPU0##	;RUN ON POLICY CPU
>;END IFN FTMP
        IDIVI	T2,^D100	;HOURS INTO T2
	MOVEM	T3,LOCMIN##
	MOVEM	T2,LOCHOR##
	SETZM	LOCSEC##	;ZERO SECOND COUNTER
	IMULI	T2,^D60		;CONVERT HOURS TO MINS
	ADD	T2,T3		;+ORIGINAL MINS
	IMUL	T2,TICMIN##	;CONVERT TO JIFFIES
	MOVEM	T2,TIME##	;SAVE AS NEW TIME
	MOVEM	T2,.CPTML##
	MOVEI	T1,.C0CDB##	;POINT AT FIRST CDB
	MOVEI	T2,^D60		;TIME TO NEXT MINUTE
	MOVE	T3,TICSEC##	;TIME TO NEXT SECOND
SETDA2:	MOVEM	T2,.CPSEC##-.CPCDB##(T1) ;STORE IN THIS CDB
	MOVEM	T3,.CPHTM##-.CPCDB##(T1) ;TIME TO NEXT SECOND
	HLRZ	T1,.CPCDB##-.CPCDB##(T1) ;STEP TO NEXT
	JUMPN	T1,SETDA2	;LOOP FOR ALL
	PUSHJ	P,OMSTIM##	;RECOMPUTE OPR MESSAGE TIME
	PJRST	SETDT2		;FIXUP 'DATE' & SKIP RETURN

SETSCD::PUSHJ	P,SETLGL	;CHECK FOR LEGALITY
	  JRST	COMERA		;NOT LEGAL
	PUSHJ	P,OCTIN1	;OK - GET OCTAL NUMBER
	  PJRST NOTENF		;NOT ENOUGH ARGS
	  PJRST COMERA		;ILLEGAL NUMBER
SETSC1:	HRRZ	T1,STATES##	;GET OLD SCHEDULE
	HRRM	T2,STATES##	;SET NEW SCHEDULE
	CAIE	T1,(T2)		;OLD AND NEW THE SAME?
	PUSHJ	P,SNDSCM##	;NO, TELL QUASAR IT CHANGED
	  JFCL
	JRST	CPOPJ1##	;AND SKIP RETURN

SETIM1:	IMUL	T2,TICSEC##	;CONVERT TO JIFFIES
	MOVSI	T3,(JB.LBT)	;GET BATCH BIT
	TDNN	T3,JBTLIM##(J)	;BATCH JOB?
	JRST	SETIM2		;NO, GO STORE
	LDB	T3,JBYLTM##	;YES, LAST CHANCE
	JUMPE	T3,SETIM2	;CAN ALWAYS ADD RESTRICTIONS
	PUSHJ	P,PRVJC		;IS HE [1,2] OR JACCT?
	  JRST	SETIM2		;LET HIM THROUGH
	PJRST	RTZER##		;NO, BOMB HIM

SETRTM::PUSHJ	P,DECIN1	;GET DECIMAL NO OF SECS
	  PJRST NOTENF		;NOT ENOUGH ARGS
	  PJRST COMERA		;NOTA NUMBER
	IMUL	T2,TICSEC##	;CONVERT TO JIFFIES
	TLNE	T2,(-JB.LTM-1)	;SEE IF TOO BIG
	PJRST	COMERA		;YES. ERROR
	MOVEI	T1,BATMSG
	LDB	T3,JBYLTM##
	JUMPE	T3,SETIM2
	MOVE	T3,JBTLIM##(J)
	TLNE	T3,(JB.LBT)
	JRST	ERRMES
SETIM2:	DPB	T2,JBYLTM##
	JRST	CPOPJ1##	;AND RETURN
	SUBTTL	SET COMMAND AND UUO -- OPR, LOGMIN&MAX BATMIN##&MAX

SETOPR::PUSHJ	P,SETLGL	;SEE IF SET OPR LEGAL
	  JRST	COMERA		;NOT LEGAL
	PUSHJ	P,CTEXT1	;GET NAME OF DEVICE
	MOVE	T1,T2		;MOVE FOR STDOPR
	PUSHJ	P,STDOPR##	;SET IT
	  PJRST	COMERA		;NO GOOD
	POPJ	P,0		;GOOD

SETOP1:	HRR	M,T2		;UUO, GET ADDRESS
	PUSHJ	P,GETWDU##	;GET CONTENTS IF LEGAL

	PUSHJ	P,STDOPR##	;CHANGE DEVICE
	  JRST ECOD0##		;ERROR RETURN
	JRST	CPOPJ1##	;GOOD RETURN


;LOGIN CONTROL PARAMETERS

SETLMX:	CAIL	T2,1		;LOGMAX MUST BE .GE. 1
	CAILE	T2,M.JOB##	;  AND .LE. M.JOB
	JRST	ECOD0##
	MOVEM	T2,LOGMAX##
	JRST	CPOPJ1##

SETBMX:	CAIL	T2,0		;BATMAX MUST BE .GE. 0
	CAILE	T2,M.JOB##	;  AND .LE. M.JOB
	JRST	ECOD0##
	MOVEM	T2,BATMAX##
	JRST	CPOPJ1##

SETBMN:	CAIL	T2,0		;BATMIN MUST BE .GE. 0
	CAMLE	T2,BATMAX##	;  AND .LE. BATMAX
	JRST	ECOD0##
	MOVEM	T2,BATMIN##
	JRST	CPOPJ1##

;SET QUEUE STRUCTURE
SETQST:	HRR	M,T2		;GET ADDR OF USER'S ARG
	PUSHJ	P,GETWDU##	;GET THE ARGUMENT
	SKIPE	T1		;WEED OUT JUNK
	PUSHJ	P,SRSTR##	;MAKE SURE ITS A KNOWN STR
	  PJRST	ECOD2##		;LOSE - ILLEGAL STRUCTURE
	MOVEM	T1,QUESTR##	;SAVE FOR % LDQUS GETTAB
	JRST	CPOPJ1##	;RETURN
	SUBTTL	SET COMMAND AND UUO -- WATCH

SETWAT::PUSHJ	P,SAVE1##	;SAVE P1
	MOVE	P1,[IORM T2,JBTWCH##(J)]	;WE'RE CHANGING JBTWCH(J)
	PUSHJ	P,CTEXT		;GET 1ST ARG
	JUMPE	T2,WATLP1	;ERROR IF MISSING
	SKIPA	T1,[-WATLEN-NOTLEN,,WATTAB]	;SCAN BOTH TABLES 1ST TIME
WATLOP:	MOVE	T1,[-WATLEN,,WATTAB]	;POINT TO TABLE
	PUSHJ	P,FNDNAM	;LOOK FOR ABBREV.
	  JRST	WATLP1		;ERROR
	CAIL	T1,NOTTAB-WATTAB	;SEE IF IN NOTTAB
	JRST	WATCH2		;YES, MUST BE NO, ALL, NONE
	MOVNI	T1,(T1)		;-NO. OF ENTRY IN TABLE
	MOVSI	T2,JW.WCX	;FIRST BIT
	ROT	T2,(T1)		;ROTATE RIGHT TO PROPER POSITION
WATCH1:	XCT	P1		;ANDCAM OR IORM T2,JBTWCH(J)
	PUSHJ	P,CTEXT		;GET NEXT ARG
	JUMPE	T2,CPOPJ##	;0 IF FINISHED OR NONE
	JRST	WATLOP		;AND SET A BIT FOR IT
WATCH2:	SUBI	T1,WATLEN	;RELATIVE TO NOTTAB
	TRNN	T1,1		;NO OR NONE?
	HRLI	P1,(ANDCAM T2,(J))	;YES
	MOVSI	T2,WCHALL	;READY FOR ALL,NONE
	JUMPN	T1,WATCH1	;YES IT IS
	PUSHJ	P,CTEXT		;GET ARG OF NO
	JUMPN	T2,WATLOP	;SEE IF VALID


WATLP1:	JSP	T1,ERRMES	;NO, TELL USER THE LEGAL ONES
	ASCIZ	/Args are: contexts,day,run,wait,read,write,version,mta,files,all,none/
$LOW
WATTAB::<SIXBIT /CONTEXTS/>
	<SIXBIT /DAY/>
	<SIXBIT	/RUN/>
	<SIXBIT	/WAIT/>
	<SIXBIT	/READS/>
	<SIXBIT	/WRITES/>
	<SIXBIT	/VERSION/>
	<SIXBIT	/MTA/>
	<SIXBIT	/FILES/>
;ADD NEW ITEMS HERE AND IN ERROR COMMENT AND IN S.MAC
WATLEN==.-WATTAB
WTCMXL==:<WATLEN-1>B26

;THIS TABLE MUST BE IN ORDER NO, ALL, NONE
;AND MUST FOLLOW WATTAB

NOTTAB:	<SIXBIT	/NO/>
	<SIXBIT	/ALL/>
	<SIXBIT	/NONE/>
NOTLEN==.-NOTTAB
	$HIGH
	SUBTTL	SET COMMAND AND UUO -- DATE


SETDAT::PUSHJ	P,SETLGL	;TEST FOR LEGALITY
	  JRST	COMERA		;NOT PRIVILEGED
	PUSHJ	P,SAVE3##	;FRE UP SOME ACS
	MOVE	P1,LOCYER##	;SAVE THE OLD DATE
	MOVE	P2,LOCMON##
	MOVE	P3,LOCDAY##
	MOVEI	T1,LOCYER##
	PUSHJ	P,GTDATE	;ACCEPT E.G. 3-JAN-72
	JRST	[MOVEM P1,LOCYER## ;RESTORE OLD DATE
		 MOVEM P2,LOCMON##
		 MOVEM P3,LOCDAY##
		 JRST COMERR]	;BAD DATA
SETDT2:	AOS	(P)		;SKIP RETURN
	PUSH	P,DATE##	;SAVE OLDDAE
	PUSHJ	P,SUDATE##	;RECOMPUTE UNIV. DATE
	POP	P,T1		;GET OLD DATE BACK
	SUB	T1,DATE##	;SUBTRACT NEW FROM OLD
	MOVNS	T1		;MAKE IT ADDITIVE
	MOVEM	T1,DTCVAL	;SAVE DATE/TIME CHANGE VALUE
	MOVE	T2,HIGHJB##	;GET HIGHEST JOB ASSIGNED
SETDT3:	SKIPE	JBTJLT##(T2)	;ANYTHING THERE?
	ADDM	T1,JBTJLT##(T2)	;YES, ADJUST IT
	HRRZ	T3,JBTPDB##(T2)	;GET PDB ADDR
	CAIE	T3,0		;SEE IF THERE
	ADDM	T1,.PDSTM##(T3)	;YES ADJUST IT
	SOJG	T2,SETDT3	; AND LOOP
	SKIPE	RSDTTM##	;LAST CPU ROLE SWITCH?
	 ADDM	T1,RSDTTM##	;YES--UPDATE IT
IFN FTNSCHED,<
	SKIPE	SCDSTS##	;LAST SETTING OF SCHEDULER PARAMETERS?
	 ADDM	T1,SCDSTS##	;YES--UPDATE IT
>;END IFN FTNSCHED
	SKIPE	SCDSET##	;..
	 ADDM	T1,SCDSET##	;YES
	PUSHJ	P,FILSDT##	;TELL FILSER TO FIX THINGS UP
	PUSHJ	P,ENQSDT##	;AND QUESER
	PUSHJ	P,PSISDT##	;SIGNAL USERS TOO

	SETZ	T1,		;CAUSE SEB ALLOCATION TO HAPPEN
	XMOVEI	T2,DTCTBL	;POINT TO TRANSFER TABLE
	PUSHJ	P,XFRSEB##	;FILL AND QUEUE UP RECORD
	  JFCL			;NO CORE
IFN FTKL10,<
	PUSHJ	P,THSDA##	;RECOMPUTE 12 BIT DATE
	PJRST	COMSDT##	;TELL ANY FRONT ENDS ABOUT D/T CHANGE
>;END IFN FTKL10
IFN FTKS10,<PJRST THSDA##>	;RECOMPUTE 12 BIT DATE AND RETURN


;DATE/TIME CHANGE TRANSFER TABLE FOR ERROR.SYS LOGGING
DTCTBL:	SEBTBL	(.ERCSC,DTCEND,<EX.QUE>)
	MOVE	DTCVAL		;(R00) OFFSET TO NEW DATE/TIME
	MOVE	DATE##		;(R01) CURRENT DATE/TIME
	MOVSI	.CSCTC		;(R02) REASON CODE
DTCEND:!			;END OF TABLE

	$LOW
DTCVAL:	EXP	0		;DATE/TIME CHANGE VALUE
	$HIGH
SETDT1:
IFN FTMP,<			;IF SMP
	PUSHJ	P,ONCPU0##	;RUN ON POLICY CPU
>;END IFN FTMP
	IDIVI	T2,^D31		;DECOMPOSE 12 BIT DATE INTO LOCYER...
	AOS	T3
	MOVEM	T3,LOCDAY##
	IDIVI	T2,^D12
	AOS	T3
	MOVEM	T3,LOCMON##
	ADDI	T2,^D1964
	MOVEM	T2,LOCYER##
	JRST	SETDT2		;GO MAKE & STORE THSDAT & DATE


SETKSY::
IFN FTMP,<			;IF SMP
	PUSHJ	P,ONCPU0##	;RUN ON POLICY CPU
>; END IFN FTMP
	CAIN	T2,-1		;KSYS NOW?
	SETOM	T2		;YES
	MOVEM	T2,SYSKTM##	;STORE VALUE FOR CLOCK1
	PUSHJ	P,PSIKSY##	;TELL EVERYONE OF CHANGE
	JRST	CPOPJ1##	;RETURN
	SUBTTL	SET COMMAND AND UUO -- SPOOL

SETSPL::PUSHJ	P,SAVE2##	;SAVE P1
	MOVE	P1,[IORM T2,JBTSPL##(J)]	;WE'RE CHANGING JBTSPL
	PUSHJ	P,CTXDEV	;GET 1ST ARG
	JUMPE	T2,NOTENF	;NOT ENOUGH ARGS
	MOVE	T1,[-NOTLEN,,NOTTAB]
	PUSHJ	P,FNDNAM	;SEE IF NO. ALL, NONE
	  JRST	SETSP0		;NO, SEE IF DEVICE
	TRNN	T1,1		;IS IF NO OR NONE
	HRLI	P1,(ANDCAM T2,(J))	;YES, TURN OFF BIT
	JUMPN	T1,SETSP3	;ALL OR NONE?
	PUSHJ	P,CTXDEV	;NO, GET ARG FOR NO
	JUMPE	T2,NOTENF	;NOT ENOUGH ARGS
SETSP0:	MOVEI	F,SPLTAB##	;POINT TO SPOOL TABLE
	TRNN	T2,-1		;DID HE SPEC A PHYS DEV?
	JRST	SETSP1		;NO ALL IS OK
	JSP	T1,ERRMES	;YES, GIVE A MESSAGE
	ASCIZ	/Cannot spool a physical device
/

SETSP1:	CAMN	T2,SPLNAM##(F)	;HATCH?
	JRST	SETSP2		;YES!
	ADDI	F,SPLLEN##	;BUMP TO NEXT CARRY
	CAIGE	F,SPLTOP##	;DONE?
	JRST	SETSP1		;NO, LOOP
	JSP	T1,ERRMES	;YES, NOT FOUND
	ASCIZ	/Not a spoolable device
/
SETSP2:	HRRZ	T2,SPLBIT##(F)	;GET THE SPOOL BIT
	SKIPA			;SKIP ALTERNATE ENTRY
SETSP3:	MOVEI	T2,.SPALL	;ALL OR NONE

	TLNE	P1,20000	;P1 AN ANDCAM?
	JRST	SETSP4		;NO - ALWAYS ALLOWED TO SET SPOOLING
	MOVSI	T1,PVNSPL	;PRIV?
	TSNN	T1,STATES##	;OR SCHED BIT?
	PUSHJ	P,PRVBIT	;90 SEC.
;NOTE THIS CODE DEPENDS ON PVNSPL=ST.NSP
IFN PVNSPL-ST.NSP,<PRINTX ST.NSP DOESN'T=PVNSPL>
	JRST	SETSP4		;YES - OK
	JSP	T1,ERRMES	;NO - TYPE THE MESSAGE:
	ASCIZ	/No privs to unspool
/
SETSP4:	XCT	P1		;TURN ON/OFF SPOOL BIT(S)
	MOVE	F,LDBDDB##(U)	; AND F
	PUSHJ	P,CTXDEV	;GET NEXT DEV
	JUMPE	T2,CPOPJ##	;RETURN IF NOTHING
	JRST	SETSP0		;AND SET ITS BIT
	SUBTTL	SET COMMAND AND UUO -- DEFER/NODEFER - BATCH STREAM - WTO - OPER PRIV
;ENTER HERE ON SETUUO FOR DEFER/NODEFER
SETDFU:	JUMPE	T2,SETNDC	;ZERO MEANS NO-DEFERED
				; ELSE FALL INTO DEFER

;ENTER HERE ON SET DEFER COMMAND
SETDFC::MOVEI	T2,JB.DFR	;GET DEFER BIT
	IORM	T2,JBTSPL##(J)	;SET IT
	JRST	CPOPJ1##	;RETURN

;ENTER HERE ON SET NODEFER COMMAND
SETNDC::MOVEI	T2,JB.DFR	;GET DEFER BIT
	ANDCAM	T2,JBTSPL##(J)	;CLEAR IT
	JRST	CPOPJ1##	;RETURN

;ENTER HERE ON SETUUO FOR BATCH-STREAM-NUMBER

SETBSN:	MOVSI	T1,(JB.BSS)	;LOAD "ALREADY SET" BIT
	TDNE	T1,.PDOBI##(W)	;TEST IT
	JRST	ECOD0##		;SET ALREADY!
	DPB	T2,PDYBSN##	;STORE VALUE
	IORM	T1,.PDOBI##(W)	;SET BIT
	JRST	CPOPJ1##	;RETURN

;ENTER HERE ON SETUUO FOR WTO CAPABILITIES

SETWTO:	DPB	T2,PDYWTO##	;STORE VALUE
	JRST	CPOPJ1##	;AND RETURN


;ENTER HERE ON SET OPER PRIVILEGE
SETOPP:	DPB	T2,PDYOPP##
	JRST	CPOPJ1##
	SUBTTL	SET COMMAND AND UUO -- DEFAULTS

SETDFL::PUSHJ	P,CTEXT		;GET DEFAULT ARGUMENT MODIFIER
	JUMPE	T2,NOTENF	;MUST BE ONE
	MOVE	T1,[-DFLTTL,,DFLTTB]	;ARGUMENT FOR FNDNAM
	PUSHJ	P,FNDNAM	;SEE IF A LEGAL MODIFIER WAS SPECIFIED
	  JRST	COMERA		;BAD ARGUMENT
	TLNN	P4,JLOG
	SKIPGE	DFLCTB(T1)
	JRST	@DFLCTB(T1)	;DISPATCH TO SET THE DEFAULT
	JRST	STARTE

;HERE ON SET DEFAULT UUO
SETDLU:	HRR	M,T2		;ADDRESS OF FUNCTION CODE
	PUSHJ	P,GETWDU##	;GET THE FUNCTION CODE
	HLRZ	T2,T1		;NUMBER OF ARGUMENTS
	HRRZS	T1		;FUNCTION CODE
	CAILE	T1,DFLUTL	;IS IT A DEFINED FUNCTION CODE?
	JRST	ECOD0##		;NO, ERROR RETURN
	JRST	@DFLUTB(T1)	;DISPATCH TO SET THE DEFAULT

DEFINE NAMES<
	C	PROTECTION,DFLPRT,0
	C	BUFFERS,DFLBFN,0
	C	ACCOUNT,DFLACS,400000
	C	BIGBUF,DFLBBC,0

>
DEFINE C(A,B,D,E)<
IFNB<E>,<E:>
	<SIXBIT /A/>
>
XALL
DFLTTB::NAMES
DFLTTL==.-DFLTTB
DFLMXL==:<DFLTTL-1>B26
DEFINE C(A,B,D,E)<
	XWD	D,B
>
DFLCTB:	NAMES
DFLUTB:	EXP	DFLPRU
	EXP	DFLBFU
	EXP	DFLDAU
	EXP	DFLBBU
DFLUTL==.-DFLUTB-1
SALL
;HERE ON SET DEFAULT PROTECTION COMMAND
DFLPRT:	MOVE	T1,[-2,,[SIXBIT /ON/
		         SIXBIT /OFF/]]
	PUSHJ	P,TXTARG	;WAS "ON OR OFF" TYPED?
	  JRST	DFLPR0		;NO
	JUMPE	T1,DFLPR1	;JUMP IF ON WAS TYPED
	MOVSI	T1,(PD.DPS)	;YES, CLEAR THE BIT WHICH SAYS
	ANDCAM	T1,.PDDFL##(W)	; DEFAULT PROTECTION WAS SET
	POPJ	P,		;AND RETURN
DFLPR0:	PUSHJ	P,SKIPS1	;SKIP BLANKS, TABS, ETC.
	  JFCL			;IGNORE
	CAIN	T3,074		;WAS A BRACKET TYPED ?
	PUSHJ	P,COMTYS	;YES, FLUSH IT.
	PUSHJ	P,OCTIN1	;READ THE PROTECTION VALUE
	  JRST	NOTENF		;IT MUST BE THERE
	  JRST	COMERA		;ILLEGAL CHARACTER
	TDNE	T2,[-1,,777000]	;LEGAL PROTECTION VALUE ?
	JRST	COMERA		;NO, COMPLAIN
	DPB	T2,PDYDPT##	;STORE DEFAULT PROTECTION
	JRST	DFLPR1		;AND INDICATE A DEFAULT WAS SPECIFIED

;HERE ON SET DEFAULT PROTECTION UUO
DFLPRU:	PUSHJ	P,GETWD1##	;GET THE PROTECTION VALUE
	TDNE	T1,[-1,,777000]	;LEGAL ?
	JRST	ECOD0##		;NO, ERROR RETURN
	DPB	T1,PDYDPT##	;STORE DEFAULT PROTECTION
DFLPR1:	MOVSI	T1,(PD.DPS)	;DEFAULT PROTECTION SPECIFIED BIT
	IORM	T1,.PDDFL##(W)	;LITE THAT
	JRST	CPOPJ1##	;AND GIVE GOOD RETURN

;HERE ON SET DEFAULT NUMBER OF BUFFERS COMMAND
DFLBFN:	PUSHJ	P,DECIN		;READ NUMBER
	  JRST	NOTENF		;NOT THERE
	  JRST	COMERA		;NOT A NUMBER
	TDNE	T2,[-1,,777000]	;IN RANGE?
	JRST	COMERA		;NO, ERROR
	SKIPA	T1,T2		;YES, STORE DEFAULT NUMBER
;HERE ON SET DEFAULT BUFFERS UUO
DFLBFU:	PUSHJ	P,GETWD1##	;GET ARGUMENT
	TDNE	T1,[-1,777000]	;IN RANGE?
	JRST	ECOD0##		;NO, ERROR
	DPB	T1,PDYBFN##	;STORE DEFAULT NUMBER OF DISK BUFFERS
	JRST	CPOPJ1##	;AND GIVE GOOD RETURN
;HERE ON SET DEFAULT DON'T ASK ABOUT DETACHED JOBS UUO
DFLDAU:	PUSHJ	P,GETWD1##	;GET ARGUMENT
	MOVE	T2,.PDDFL##(W)	;DEFAULT WORD
	SKIPN	T1		;SET?
	TLZA	T2,(PD.DAD)	;NO, CLEAR
	TLO	T2,(PD.DAD)	;YES
	MOVEM	T2,.PDDFL##(W)	;STORE ANSWER
	JRST	CPOPJ1##	;AND GIVE GOOD RETURN
;HERE TO SET DEFAULT ACCOUNT STRING (USED FOR JOBS LOGGED IN ON FRCLIN)
DFLACS:	PUSHJ	P,SETLGL	;MUST BE OPR
	  JRST	COMERA		;NOT, COMPLAIN
	PUSHJ	P,SAVE2##	;WORKING ACS
	HRRZ	P1,JBTPDB##+0	;NULL JOB'S PDB
	ADD	P1,[POINT 7,.PDACS##] ;WHERE TO STORE DEFAULT
	HRREI	P2,5*ACTSTL##-1	;LENGTH OF ACCOUNT STRING
	JUMPLE	P2,COMERA	;FORGET IT IF ZERO LENGTH
DFLAC1:	PUSHJ	P,COMTYI##	;NEXT CHARACTER
	CAIE	T3,12		;LINEFEED?
	CAIN	T3,3		;OR CONTROL C
	JRST	DFLAC2		;YES, THAT'S ALL FOLKS
	IDPB	T3,P1		;NO, STORE THE CHARACTER
	SOJG	P2,DFLAC1	;LOOP FOR MORE
DFLAC2:	MOVEI	T1,0		;ASCIZIZE
	IDPB	T1,P1
	POPJ	P,		;RETURN


;HERE ON SET DEFAULT BIGBUF COMMAND
DFLBBC:	PUSHJ	P,DECIN		;GET THE NUMBER OF BLOCKS PER BUFFER
	  JRST	NOTENF		;NOT THERE
	  JRST	COMERA		;NOT A NUMBER
	MOVE	T1,T2
	CAILE	T1,LIMBBF	;IN RANGE?
	JRST	COMERA		;NO, ERROR
	TLO	M,400000	;SET THAT IT GETS SET PERMANENTLY
	JRST	DFLBB2

;HERE ON SET DEFAULT BIGBUF UUO
DFLBBU:	PUSHJ	P,GETWD1##
	TLNN	T1,-1		;SET JOB-WIDE DEFAULT?
	JRST	DFLBB1		;NO, CONTINUE
	HLRZS	T1		;YES, MAKE IT AN RH QUANTITY
	TLO	M,400000	;PRETEND WE HAVE A COMMAND
DFLBB1:	CAILE	T1,LIMBBF##	;IN RANGE?
	JRST	ECOD0##		;NO, ERROR
DFLBB2:	LSH	T1,BLKLSH##	;YES, CONVERT TO NUMBER OF WORDS
	SKIPE	T1		;CLEAR IT IF ARGUMENT IS 0
	ADDI	T1,1
	SKIPL	M		;UUO?
	HRLM	T1,.PDLBS##(W)	; SAVE IN PDB
	SKIPGE	M		;COMMAND?
	HRRM	T1,.PDLBS##(W)	; SAVE IN PBD
	JRST	CPOPJ1##	;AND TAKE GOOD RETURN
SUBTTL	SET COMMAND AND UUO -- BREAK

IFN FTKS10,<
;NO ADDRESS BREAK
	XP	SETBRK,COMERA
	XP	SETABR,CPOPJ##
	XP	CLRBRK,CPOPJ##
>

IFN FTKL10,<

;HERE IF THE USER TYPED SET BREAK
SETBRK::PUSHJ	P,SAVE2##	;SAVE P1,P2
	PUSHJ	P,FNDPDS##	;FIND THE PDB FOR THIS USER
	MOVSI	P1,400000	;NO NUMBER SEEN YET
	PUSHJ	P,OCTPRG	;SEE IF FIRST ARGUMENT IS A NUMBER
	  JRST	SETBR2		;NOT A NUMBER, LOOK FOR LEGAL TEXT
SETBR1:	MOVE	P1,T2		;NUMBER TO P1
	CAIG	P1,17		;WEED OUT REFERENCES
	CAIGE	P1,1		;  TO THE ACS
	CAMLE	P1,[MXSECN,,-1]	;REPORT THIS AS AN ERROR RATHER THAN CONFUSING USER
	JRST	COMERA		;COMPLAIN
	DPB	P1,[POINT 23,.PDABS##(W),35] ;STORE BREAK ADDRESS
	PUSHJ	P,SGSEND	;SEE IF EOL
	  JRST	SETBR2		;NO, READ NEXT ARGUMENT
	SKIPN	P2,P1		;BREAK ADDRESS ZERO?
	JRST	SETB10		;YES, TREAT SET BREAK 0 WITH NO CONDITION LIKE NONE
	HLLZ	P2,.PDABS##(W)	;GET PREVIOUS CONDITIONS IF ANY
	TLZ	P2,(OC.BSU)	;CLEAR SET BY UUO
SETB1A:	TLNN	P2,(OC.BCI+OC.BCD+OC.BCW+OC.BCM) ;WERE THERE ANY PREVIOUSLY?
	TLO	P2,(OC.BCI+OC.BCD+OC.BCW) ;NO, ASSUME ALL
	JRST	SETBR8		;ENABLE BREAK, STORE CONDITIONS, AND GO AWAY
SETBR2:	MOVE	T1,[-4,,BRKLS1]	;TABLE LENGTH,,ADDRESS OF THE TABLE
	PUSHJ	P,TXTARG	;RECOGNIZABLE TEXT ARGUMENT?
	  JRST	SETBR5		;NO, POSSIBLY IN ANOTHER CONTEXT
	MOVE	P2,T1		;INDEX INTO BRKTBL
	JUMPN	T1,SETBR3	;JUMP IF THE USER DIDN'T TYPE 'NONE'
;HERE WHEN THE USER TYPED 'NONE'
	JUMPGE	P1,COMERA	;IF A NUMBER WAS TYPED WE SHOULDN'T BE HERE
	JRST	SETB10		;GO CLEAR BREAK CONDITIONS
SETBR3:	PUSHJ	P,SGSEND	;AT END OF LINE?
	  CAIA			;NO
	JRST	NOTENF		;IF WE'RE HERE THERE HAS TO BE ONE
	JRST	.(P2)		;DISPATCH TO THE APPROPRIATE PROCESSOR
	JRST	SETBR4		;USER TYPED 'AT'
	JRST	SETBR5		;USER TYPED 'ON'
	JRST	SETBR6		;USER TYPED 'NO'
;HERE WHEN THE USER TYPED 'AT'
SETBR4:	JUMPGE	P1,COMERA	;NO PREVIOUS NUMBERS ALLOWED IF WE GET HERE
	PUSHJ	P,OCTPRG	;READ A NUMBER
	  JRST	COMERA		;IT MUST BE A NUMBER BUT ISN'T SO COMPLAIN
	JRST	SETBR1		;LOOK FOR THE NEXT TEXT ARGUMENT
;HERE WHEN THE USER TYPED 'ON'
SETBR5:	SKIPA	P1,[TDO P2,BRKTBL-1(T1)]
;HERE WHEN THE USER TYPED 'NO'
SETBR6:	MOVE	P1,[TDZ P2,BRKTBL-1(T1)]
	HLLZ	P2,.PDABS##(W)	;GET CURRENT BREAK CONDITIONS
	TLZ	P2,(OC.BSU)	;CLEAR SET BY UUO
SETBR7:	MOVE	T1,[-7,,BRKLS2]	;TABLE LENGTH,,TABLE ADDRESS
	PUSHJ	P,TXTARG	;GET A BREAK CONDITION
	  JRST	COMERA		;IT CAN'T BE ANYTHING ELSE
	JUMPE	T1,SETB11	;JUMP IF 'USERS'
	CAIN	T1,AFTERX
	JRST	SETB12
	XCT	P1		;SET OR CLEAR THE CONDITION
	PUSHJ	P,SGSEND	;LAST ARGUMENT?
	  JRST	SETBR7		;NO, CHECK NEXT ARGUMENT
	TLZ	P2,(OC.ABE+OC.FUP) ;ASSUME NO CONDITIONS
	TLNN	P2,(OC.BCI+OC.BCD+OC.BCW+OC.BCM) ;ANY CONDITIONS DESIRED?
	JRST	SETB10		;NO, DECREMENT NUMBER OF USERS USING ADDRESS BREAK
SETBR8:	PUSHJ	P,BRKAV		;SEE IF ADDRESS BREAK IS AVAILABLE AND INCREMENT
				; THE COUNT OF USERS USING IT IF SO
	  JRST	NOBRAK		;NOT AVAILABLE, COMPLAIN
SETBR9:	TLOA	P2,(OC.ABE+OC.FUP) ;ENABLE THE USER FOR ADDRESS BREAK
SETB10:	PUSHJ	P,BRKDEC	;DECREMENT THE COUNT OF USERS USING ADDRESS BREAK
	LSH	P2,-^D23	;POSITION BITS
	DPB	P2,[POINT 13,.PDABS##(W),12] ;STORE NEW CONDITIONS
	POPJ	P,		;AND RETURN TO COMCON
;HERE WHEN THE USER TYPED 'USERS', MUST BE PRIVILEGED
SETB11:	PUSHJ	P,SETLGL	;USER SUFFICIENTLY PRIVILEGED TO MONOPOLIZE
				; ADDRESS BREAK?
	  JRST	COMERA		;NO, COMPLAIN
	PUSHJ	P,FDNJP		;FIND THE NULL JOB'S PDB
	MOVSI	T2,400000	;SET TO TURN ON OR OFF ADDRESS BREAK
	CAME	P1,[TDZ P2,BRKTBL-1(T1)] ;WAS 'USERS' WITHOUT A 'NO' TYPED?
	JRST	[ANDCAM	T2,.PDABS##(T1)	;YES, ALLOW USERS TO USE ADDRESS BREAK
		 POPJ	P,]	;RETURN
;HERE WHEN THE USER TYPED 'NO USERS'
	SKIPLE	.PDABS##(T1)	;IS ADDRESS BREAK CURRENTLY BEING USED?
	JRST	NOBRAK		;DON'T ALLOW HIM TO YANK IT OUT FROM UNDER THEM
	IORM	T2,.PDABS##(T1)	;DON'T ALLOW USERS TO USE ADDRESS BRAEK
	POPJ	P,		;RETURN TO COMCON

;HERE WHEN THE USER TYPED 'AFTER'
SETB12:	PUSHJ	P,DECIN		;GET THE NEXT ARGUMENT
	  PJRST	NOTENF		;THERE MUST BE ONE
	  JRST	COMERA		;NOTHING BUT A NUMBER IS LEGAL
	CAILE	T2,^D510	;IS IT TOO BIG?
	JRST	COMERA		;YES
	ADDI	T2,1
	DPB	T2,[POINT 9,.PDTMI##(W),17] ;SAVE THE REPEAT COUNT
	JRST	SETB1A		;STORE IT AND GO AWAY
;HERE ON A SET ADDRESS BREAK UUO
SETABR::PUSHJ	P,SAVE2##	;SAVE P1,P2
	HRR	M,T2		;ADDRESS OF USER'S ARGUMENT
	PUSHJ	P,GETWDU##	;GET THE ARGUMENT
	LDB	P1,[POINT 9,T1,17] ;GET PROCEED COUNT
	DPB	P1,[POINT 9,.PDTMI##(W),17] ;STORE IT
	LDB	P1,[POINT 5,T1,8];GET SECTION NUMBER
	DPB	P1,[POINT 14,T1,17] ;STORE THAT
	DPB	T1,[POINT 23,.PDABS##(W),35] ;STORE BREAK ADDRESS
	MOVE	P2,T1		;P2 = BREAK CONDITIONS
	TLO	P2,(OC.BSU)	;INDICATE SET BY UUO
	AOS	(P)		;PREPARE TO GIVE GOOD RETURN
	TLNN	P2,(OC.BCI+OC.BCD+OC.BCW+OC.BCM)
	JRST	[PUSHJ P,SETB10	;TURNING OFF BREAK
		 PJRST SETRL1##]
	PUSHJ	P,BRKAV		;IS ADDRESS BREAK AVAILABLE?
	  SOSA	(P)		;NO, ERROR RETURN
	JRST	[PUSHJ P,SETBR9	;YES, SETUP BREAK CONDITIONS
		 PJRST SETRL1##]
	JRST	ECOD0##		;GIVE ERROR RETURN
;HERE ON RESET TO CLEAR BREAK ADDRESS AND CONDITIONS
; IF SET BY UUO
CLRBRK::SKIPE	T1,.PDABS##(W)	;BREAK IN USE AT ALL?
	TLNN	T1,(OC.BSU)	;AND SET BY UUO?
	POPJ	P,		;NO
	PUSHJ	P,BRKDEC	;YES, DECREMENT COUNT OF USERS
	SETZM	.PDABS##(W)	;CLEAR ADDRESS AND CONDITIONS
	POPJ	P,		;AND RETURN
;THE ORDER OF AND THE NUMBER OF ENTRIES
; IN THE FOLLOWING TABLES CANNOT BE CHANGED
; WITHOUT CHANGING THE CODE IN SETBRK

BRKLS1:	SIXBIT	/NONE/
	SIXBIT	/AT/
	SIXBIT	/ON/
	SIXBIT	/NO/
BRKLS2:	SIXBIT	/USERS/
	SIXBIT	/EXECUT/
	SIXBIT	/READ/
	SIXBIT	/WRITE/
	SIXBIT	/MUUO/
	SIXBIT	/ALL/
BRKLS3:	SIXBIT	/AFTER/
AFTERX==BRKLS3-BRKLS2
;THE ENTRIES IN THIS TABLE CORRESPOND IN ORDER
; TO THE ENTRIES IN THE ABOVE TABLE
BRKTBL:	EXP	OC.BCI
	EXP	OC.BCD
	EXP	OC.BCW
	EXP	OC.BCM
	EXP	OC.BCI+OC.BCD+OC.BCW
;SUBROUTINE TO DETERMINE WHETHER ADDRESS BREAK IS AVAILABLE TO USERS
;CALLING SEQUENCE:
;	PUSHJ	P,BRKAV
;NON-SKIP RETURN IF NOT AVAILABLE BECAUSE MEMORY
; INDICATORS ARE DISABLED OR ADDRESS BREAK IS BEING
; USED BY SYSTEM PROGRAMMERS FOR MONITOR DEBUGGING
;SKIP RETURN IF ADDRESS BREAK IS AVAILABLE TO USERS, COUNT OF THE NUMBER
;OF USERS USING ADDRESS BREAK HAS BEEN UPDATED
;PRESERVES T2

BRKAV:	PUSHJ	P,FDNJP		;FIND THE NULL JOB'S PDB
IFN FTMP,<
	PUSHJ	P,CP0RC##	;SEE IF THE JOB IS RUNNABLE ON CPU0
	  TLNN	P2,(OC.BCM)	;ITS NOT, BUT IF HE IS ENABLED FOR UUOS, SOME
>
				; MUST HAPPEN ON CPU0
	SKIPGE	.PDABS##(T1)	;HAS ADDRESS BREAK BEEN DISABLED BY THE OPR?
	POPJ	P,		;YES, LOSE
	MOVE	T3,.PDABS##(W)	;GET HIS CURRENT ADDRESS BREAK SETTINGS
	TLNN	T3,(OC.ABE)	;IS HE ALREADY BREAKING?
	AOS	.PDABS##(T1)	;NO, COUNT UP THE NUMBER OF USERS USING ADDRESS BREAK
	JRST	CPOPJ1##	;AND GIVE THE HAPPY RETURN

;SUBROUTINE TO DECREMENT THE COUNT OF THE NUMBER
; OF USERS USING ADDRESS BREAK

BRKDEC:	MOVE	T1,.PDABS##(W)	;GET HIS CURRENT BREAK SETTINGS
	TLNN	T1,(OC.ABE)	;IS HE ENABLED FOR ADDRESS BREAK?
	POPJ	P,		;NO, NOTHING TO DO
	PUSHJ	P,FDNJP		;FIND THE PDB FOR THE NULL JOB
	SOS	.PDABS##(T1)	;DECREMENT THE COUNT OF USERS USING ADDRESS BREAK
	POPJ	P,		;AND RETURN

NOBRAK:	PJSP	T1,CONMES	;SORRY FOLKS!
	ASCIZ	/?Not available
/

;SUBROUTINE TO RETURN THE ADDRESS OF THE NULL JOB'S PDB IN T1
;PRESERVES T2-T4

FDNJP::	MOVEI	T1,0		;NULL JOB'S JOB NUMBER
	PUSHJ	P,FPDBT1##	;FIND THE NULL JOB'S PDB, RETURN ITS ADDRESS IN T1
	  JFCL			;IT MUST HAVE ONE
	POPJ	P,		;RETURN TO THE CALLER

>;END IFN FTKI10!FTKL10
	SUBTTL	SET COMMAND AND UUO -- PRIVILEGE WORDS

;HERE FOR UUO TO CHANGE PRIVILEGES

SETPRV:	HRRI	M,(T2)		;POINT TO FIRST ARGUMENT
	PUSH	P,J		;SAVE JOB NUMBER
	PUSHJ	P,GETWDU##	;PICK UP FUNCTION CODE
	SKIPL	T2,T1		;SEE IF NEGATIVE
	CAILE	T2,SPRVMX	;OR TOO LARGE
	JRST	[POP P,J	;BALANCE THE STACK
		 JRST ECOD0##]	;YES, ERROR RETURN
	ADDI	M,1
	PUSHJ	P,GTWST2##	;GET ARGUMENT INTO T1
	POP	P,J		;RESTORE JOB NUMBER
	JRST	@SPRVTB(T2)	;DISPATCH

SPRVTB:	EXP	SPRVWD		;(0) SET PRIVILEGE WORD
	EXP	SPRVON		;(1) SET BITS IN PRIV WORD
	EXP	SPRVOF		;(2) CLEAR BITS IN PRIV WORD
	EXP	SCAPWD		;(3) SET CAPABILITY WORD
	EXP	SCAPON		;(4) SET BITS IN CAPABILITY WORD
	EXP	SCAPOF		;(5) CLEAR BITS IN CAPABILITY WORD

	SPRVMX==.-SPRVTB-1	;HIGHEST FUNCTION

SPRVOF:	ANDCAB	T1,JBTPRV##(J)	;CLEAR REQUESTED BITS
	JRST	STOTC1##	;AND STORE RESULT

SPRVON:	IOR	T1,JBTPRV##(J)	;INCLUDE BITS HE ALREADY HAS
SPRVWD:	MOVE	T2,.PDCAP##(W)	;GET CAPABILITIES
	ANDCB	T2,JBTPRV##(J)	;GET BITS HE CAN'T GET
	TDNE	T1,T2		;TRYING TO SET BITS HE CAN'T HAVE?
	PUSHJ	P,PRVJ		;YES, BUT SEE IF PRIVILEGED
	  SKIPA			;OK TO SET BITS
	JRST	ECOD0##		;LOSE, ERROR RETURN
	MOVEM	T1,JBTPRV##(J)	;SET NEW PRIVILEGE WORD
	JRST	STOTC1##	;AND STORE FOR USER TO SEE

SCAPOF:	ANDCAB	T1,.PDCAP##(W)	;CLEAR REQUESTED BITS
	JRST	STOTC1##	;AND RETURN RESULT

SCAPON:	IOR	T1,.PDCAP##(W)	;INCLUDE BITS ALREADY OWNED
SCAPWD:	SETCM	T2,.PDCAP##(W)	;GET BITS HE CAN'T SET
	TDNE	T1,T2		;NOT SETTING ANY NEW BITS?
	PUSHJ	P,PRVJ		;OR IS PRIVILEGED USER?
	  SKIPA			;YES, OK
	JRST	ECOD0##		;NO, LOSES
	MOVEM	T1,.PDCAP##(W)	;SET NEW CAPABILITY WORD
	JRST	STOTC1##	;AND GIVE TO USER
;HERE FOR COMMANDS TO ENABLE OR DISABLE PRIVILEGES.
;ONLY THE WHOLE WORD CAN BE MODIFIED NOW.

DISABL::SETZM	JBTPRV##(J)	;CLEAR WORD
	POPJ	P,		;AND RETURN.

ENABLE::MOVE	T1,.PDCAP##(W)	;GET CAPABILITIES
	IORM	T1,JBTPRV##(J)	;ADD TO PRIVILEGE WORD
	POPJ	P,		;DONE
	SUBTTL	SET COMMAND AND UUO -- CDR

;ENTER HERE ON SET CDR UUO
SETSPI:	HRLOS	T2		;GET NAME, -1
	AOS	(P)		;AND SKIP COMMAND ENTRY AND FORCE SUCCESS RETURN
	JRST	SETCD2
;SET CDR COMMAND
SETCDR::PUSHJ	P,CTEXT1	;GET FILE NAME
	JUMPE	T2,NOTENF	;NONE SPECIFIED
	TRNE	T2,-1		;MORE THAN 3 CHARACTERS?
	JRST	COMERA		;YES. NO GOOD.
SETCD2:	HLLM	T2,JBTSPL##(J)	;SAVE NAME
	POPJ	P,		;AND RETURN



;HERE TO SET SPOOL BITS BY UUO
SETSPB:	SETCM	T3,T2		;-BITS HE WANTS ON
	ANDI	T3,.SPALL
	TDNN	T3,JBTSPL##(J)	;CLEARING SOME BITS FROM JBTSPL?
	JRST	SETSPC		;NO - OK
	MOVSI	T1,PVNSPL	;PRIV?
	TSNN	T1,STATES##	;OR SCHED BIT?
	PUSHJ	P,PRVBIT	;GO SEE
;NOTE THIS CODE DEPENDS ON PVNSPL=ST.NSP
IFN PVNSPL-ST.NSP,<PRINTX ST.NSP DOESN'T=PVNSPL>
	  JRST SETSPC		;YES. GO DO IT.
	JRST	ECOD0##		;NO. FAILURE RETURN
SETSPC:	DPB	T2,[POINT 5,JBTSPL##(J),35]	;YES, DO IT
	JRST	CPOPJ1##	;SUCCESS RETURN
DSKSIL::PUSHJ	P,SETLGL	;LEGAL?
	  JRST	COMERA		;NO
	PUSHJ	P,CTEXT1	;YES, GET DRIVE NAME
	MOVE	T1,T2		;INTO T1
	CAMN	T2,[SIXBIT 'PDP11']	;DOES HE WANT TO STOP PDP-11 MESSAGE?
	PJRST	D76SIL##	;YES--GO SHUT HIM UP
IFN FTKS10,<
	CAMN	T2,[SIXBIT 'MEMORY'] ;DOES HE WANT TO STOP MEMORY ERROR MESSAGES?
	PJRST	MEMSIL##	;YES--GO SHUT HIM UP
>; END IFN FTKS10

	PUSHJ	P,TPMSIL##	;SEE IF A TAPE KONTROLLER
	  PJRST	CPOPJ1##	;YES - EXIT
	PUSHJ	P,DSKQUI##	;STOP MESSAGES FOR THIS DRIVE
	  JRST	COMERA		; NO SUCH UNIT, OR WRONG STATUS
	PJRST	CPOPJ1##	;OK
	SUBTTL	SET COMMAND AND UUO -- DISK STUFF

;SET DSKPRI N
DSKPRI::TLZA	P4,-1		;CLEAR LH(P4)
DSKPR2:	TLO	P4,-1		;MINUS, SET LH(P4)=-1
	PUSHJ	P,SKIPS		;GET FIRST CHAR
	  JRST	NOTENF
	CAIN	T3,"-"		;-?
	JUMPE	T2,DSKPR2	;YES, SET LH(P4), TRY AGAIN
	PUSHJ	P,DECIN1	;NO, GET THE NUMBER
	  JRST	NOTENF
	  JRST	COMERA
	SKIPGE	P4		;- SEEN?
	MOVNS	T2		;YES
	PUSHJ	P,PRICOM##	;CALL FILSER TO CHECK PRIUS
	  SKIPA
	POPJ	P,

PRIERR::JSP	T1,ERRMES
	ASCIZ	/No privileges to set priority that high
/
;SET DSKFUL PAUSE (ERROR)
FULSTP::PUSHJ	P,CTEXT
	MOVE	T1,[-2,,STPNST]	;LOOK AT ARGUMENT
	PUSHJ	P,FNDNAM
	  PJRST	COMERA
STPSET:	MOVEI	T2,JS.SFL
	XCT	STPXCT(T1)	;TURN THE PAUSE-BIT ON OR OFF
	PJRST	CPOPJ1##
STPNST:	SIXBIT	/PAUSE/
	SIXBIT	/ERROR/
STPXCT:	IORM	T2,JBTSTS##(J)
	ANDCAM	T2,JBTSTS##(J)
;SET DSKFUL UUO (0=PAUSE, 1=ERROR, OTHER=READ)
DSKFUL:	CAILE	T2,1		;SETTING?
	JRST	DSKFU1		;NO
	MOVE	T1,T2		;YES, T1=FUNCTION
	JRST	STPSET		;GO SET OR CLEAR THE BIT
DSKFU1:	MOVEI	T2,JS.SFL	;READING THE BIT
	TDNE	T2,JBTSTS##(J)	;IS HE SET TO PAUSE?
	TDZA	T1,T1		;NO - 0
	MOVEI	T1,1		;YES - 1
	PJRST	STOTC1##	;STOTAC, THEN CPOPJ1
;UUO TO SET PROGRAM TO RUN
SETPGM:	PUSHJ	P,PRVJ		;PRIV'D JOB?
	  JRST	SETPG1		;YES, ALLOW IT
	MOVE	T3,JBTLIM##(J)
	TLNN	T3,(JB.LBT)	; IN A BATCH JOB?
	TLNN	T3,(JB.LSY)	;FROM SYS: ?
	JRST	ECOD0##		;NO, ERROR
SETPG1:	HRR	M,T2		;COPY ADDRESS
	PUSH	P,J
	PUSHJ	P,GETWDU##	;GET THE WORD
	MOVE	J,(P)
	MOVEI	T2,JS.RPC	;CLEAR BIT
	ANDCAM	T2,JBTST2##(J)	; ..
	SKIPGE	T1		;WANT IT SET?
	IORM	T2,JBTST2##(J)	;YES
	PUSHJ	P,GETWD1##	;GET NAME
	POP	P,J
	PUSHJ	P,FNDPDS##
	MOVEM	T1,.PDPGM##(W)
	JRST	CPOPJ1##
	SUBTTL	SET COMMAND AND UUO -- ROUTINE TO READ DATE

;GTDATE-ACCEPTS DATE IN FORM 21-JAN-72 OR
;	JAN-21-72 OR 5-JAN OR JAN-5 GIVING
;	CREATION YEAR AS DEFAULT
;	STORES YEAR (E.G. 1972), MONTH (1-12), DAY (1-31) IN 3 WORD
;	VALVE BLOCK POINTED TO BY T1.
;
;CALL	T1:=ADDRESS
;	PUSHJ	P,GTDATE
;	ERROR, RETURN
;	SUCCESS RETURN


GTDATE::PUSHJ	P,SAVE2##	;SAVE POINTER
	MOVEI	P1,2		;SET LOOP COUNT
	MOVE	P2,T1
	SETZM	1(P2)		;NO MONTH TYPED YET
DATE01:	PUSHJ	P,CTEXT		;READ NEXT ARGUMENT
	MOVE	T1,[-MLEN,,MONTHS]
	PUSHJ	P,FNDNAM	;SCAN FOR A MONTH
	  JRST GTDAY
	ADDI	T1,1		;FORM MONTH INDEX
	MOVEM	T1,1(P2)	;STORE MONTH
	SOJG	P1,DATE01	;LOOP IF DAY NEXT
	JRST	GTYEAR

GTDAY:	JUMPN	T1,CPOPJ##	;ERROR, AMBIGOUS MONTH
	SETZM	T3		;CLEAR FOR SUM
DATE02:	SETZ	T1,
	LSHC	T1,6		;GET NEXT DIGIT
	JUMPE	T1,DATE03	;DONE, IT 0
	TRC	T1,20		;FORM OCTAL REPRESENTATION
	CAILE	T1,^D9
	POPJ	P,		;NOT A DIGIT
	IMULI	T3,^D10
	ADDI	T3,(T1)		;FORM SUM
	JRST	DATE02
DATE03:	SKIPN	1(P2)		;IF NO MONTH WAS TYPED,
	MOVEM	T3,1(P2)	; STORE IT AS MONTH ALSO SO OLD FORMAT WILL WIN
	MOVEM	T3,2(P2)	;STORE DAY
	SOJG	P1,DATE01	;LOOP IF MONTH NEEDED
GTYEAR:	PUSHJ	P,DECIN		;GET YEAR (IF TYPED)
	  SKIPA	T2,MONYER	;CREATION YEAR IF MONITOR
	  POPJ	P,		;BAD TERMINATOR
	CAIGE	T2,^D100	;IF JUST 2 CHAR'S TYPED
	ADDI	T2,^D1900	;  ADD 1900
	MOVEM	T2,(P2)		;STORE YEAR
	JRST	CPOPJ1##	;SUCCESS
DEFINE	.MONTH	(A),
	<IRP A
	<SIXBIT/A/>>

MONTHS:	.MONTH<JANUAR,FEBRUA,MARCH,APRIL,MAY,JUNE,JULY,AUGUST,SEPTEM,OCTOBE,NOVEMB,DECEMB>

MLEN==.-MONTHS
MONYER:	M.YEAR##		;YEAR OF MONITOR CREATION
	SUBTTL	SET COMMAND AND UUO -- ROUTINES TO PRINT WATCH INFO

;SUBROUTINE TO PRINT TIME OF DAY USER STARTS TO WAIT FOR RESPONSE
; IF HE HAS ENABLED IT WITH "WATCH DAY"
;CALL:	MOVE J,JOB NO.
;	PUSHJ P,WCHBEG
;	ALWAYS RETURN HERE

;THIS SUBROUTINE IS ALWAYS CALLED FROM THE COMMAND DECODER
;WHEN USER IS ABOUT TO WAIT FOR A RESPONSE


WCHBEG:	MOVE	T2,JBTWCH##(J)
	MOVE	T1,TIME##	;TIME OF DAY IN JIFFIES
	TLNE	T2,JW.WWT
	DPB	T1,JBYWCH##	;STORE FOR JOB
	TLNN	T2,JW.WDY	;DOES USER WANT TO SEE THIS?
	POPJ	P,		;NO.
	PUSHJ	P,PRLBK		;YES, PRINT LEFT BRACKET
	MOVE	T1,TIME##	;TIME OF DAY IN JIFFIES
	PUSHJ	P,PRTIM		;PRINT HH:MM:SS(NO CRLF)
				;FALL INTO PRRBKC
;SUBROUTINE TO PRINT RIGHT BRACKET,CRLF

PRRBKC::PJSP	T1,CONMES
	ASCIZ	/]
/
;SUBROUTINE TO PRINT LEFT BRACKET


PRLBK::	PJSP	T1,CONMES
	ASCIZ	/[/

;SUBROUTINE TO PRINT RIGHT BRACKET


PRRBK::	PJSP	T1,CONMES	;PRINT AND RETURN
	ASCIZ	/]/
;SUBROUTINE TO PRINT SYSTEM RESPONSE STATISTICS EACH TIME
;USER FINISHES WAITING FOR SYSTEM
;PRINT INCREMENTAL RUN TIME, WAIT TIME, # DISK BLKS READ, #DISK BLKS WRITTEN
;CALL:	MOVE J,JOB NUMBER
;	PUSHJ P,WCHEND
;	ALWAYS RETURN HERE


WCHEND::MOVSI	T1,JW.WRN!JW.WWT!JW.WDR!JW.WDW	;USER WANT ANY RESPONSE DATA?
	TDNN	T1,JBTWCH##(J)	; ..
	POPJ	P,		;NO.
	PUSHJ	P,SAVE1##	;SAVE P1
	PUSHJ	P,PRLBK		;YES, PRINT LEFT BRACKET
	PUSHJ	P,FNDPDS##	;FIND PDB ADDRESS. HALT IF NONE
	MOVSI	P1,-WCHLEN	;LOOP THRU ALL RESPONSE DATA ITEMS
WCHLOP:	HLLZ	T1,WCHTAB(P1)	;GET BIT ASSOCIATED WITH THIS FIELD
	HRRZ	T2,WCHTAB(P1)	;GET DISPATCH ADDRESS
	TDZE	T1,JBTWCH##(J)	;DOES USER WANT TO WATCH IT?
	PUSHJ	P,(T2)		;YES, PRINT IT OUT
	AOBJP	P1,WCH1		;FINISHED ALL FIELDS?
	PUSHJ	P,PRSPC		;NO, PRINT A SPACE
WCH1:	JUMPL	P1,WCHLOP	;LOOP IF MORE BITS TO CONSIDER
	PJRST	PRRBKC		;APPEND RIGHT BRACKET, CRLF, AND RETURN

;TABLE OF ROUTINES TO PRINT RESPONSE DATA

WCHTAB:	XWD	JW.WRN,PRTWRN	;PRINT RUN TIME
	XWD	JW.WWT,PRTWWT	;PRINT WAIT TIME

	XWD	JW.WDR,PRTWDR##	;PRINT # DISK BLOCKS READ
	XWD	JW.WDW,PRTWDW##	;PRINT # DISK BLOCKS WRITTEN

				;ADD NEW DATA HERE
WCHLEN==.-WCHTAB
;ROUTINE TO PRINT INCREMENTAL RUNTIME(NO CRLF)
;CALL:	MOVEI T1,0
;	PUSHJ P,PRTWRN


PRTWRN:	EXCH	T1,.PDRTM##(W)	;CLEAR INCREMENTAL RUN TIME
	PJRST	PRTIM		;PRINT AS HH:MM:SS, MM::SS OR SS.HH (NO CRLF)

;ROUTINE TO PRINT WAIT TIME (NO CRLF)
;CALL:	PUSHJ P,PRTWWT


PRTWWT:	LDB	T1,JBYWCH##	;TIME OF DAY USER STARTED TO WAIT
	SUB	T1,TIME##	;-CURRENT TIME OF DAY = -WAIT TIME
	SKIPLE	T1		;IS IT REALLY MINUS?
	SUB	T1,MIDNIT##	;NO. MUST HAVE BEEN WAITING ACROSS MIDNIGHT
				; SO SUBTRACT A DAY TO GET IT NEGATIVE
	MOVNS	T1		;NOW MAKE IT PLUS WAIT TIME
	PJRST	PRTIM		;TYPE OUT TIME (NO CRLF)


SETWTU:	HLRZ	T1,JBTWCH##(J)	;GET CLOCK OVERFLOW
	ANDI	T1,77		;(ENOUGH FOR 24.*60.*60.*60.)
	TRZ	T2,77		;CLEAR REQUEST JUNK
	IOR	T2,T1		;INCLUDE OVERFLOW
	HRLM	T2,JBTWCH##(J)	;SAVE WATCH BITS
	JRST	CPOPJ1##	;AND RETURN
	SUBTTL	CONTINUE, CCONT AND JCONT

; "CONTC" - CONTINUE EXECUTION(TTY REMAINS IN COMMAND MODE)

CONTC::				;SAME AS CONT

; "CONT" - CONTINUE EXECUTION FROM WHERE LEFT OFF

CONT::	JUMPE	J,STARTE	;COMPLAIN IF NO JOB
	LDB	T1,JBYDEB##	;DEFERRED ECHO BITS
	SE1XCT	<DPB T1,LDPDEB##> ;RESTORE FOR CONTINUE
	TLNN	P4,JERR		;IS JOB ERROR BIT SET?
	JRST	CONT1		;COMMAND DECODER WILL DO THE REST
	JSP	T1,ERRMES	;YES, PRINT CANT CONTINUE

	ASCIZ	/Can't continue
/
CONT1:
IFN FTMP,<
	MOVE	T1,USRPC##	;PC
	TLNE	T1,(XC.USR)	;USER MODE?
	PJRST	DPXST##		;YES, MAKE RUNNABLE ON ALL CPUS
>
	POPJ	P,		;*** NO

;JOB CONTINUE COMMAND
;FORCES A CONTINUE COMMAND FOR JOB Y

JCONT::	PUSHJ	P,GETJOB	;GET JOB TO CONTINUE
	  JRST	NOTENF		;MUST HAVE ARGUMENT
	TRNN	T3,JDCON	;JOB WAITING FOR CONT?
	JRST	JCERR2		;NO
	CAMN	T2,J		;SEE IF FOR US
	PJRST	FCONT		;YES, GO DO IT
	MOVE	T1,T2		;GET JOB # IN CORRECT AC FOR FCONRQ
	PUSHJ	P,FCONRQ	;GO REQUEST CONT BE FORCED FOR JOB
	POPJ	P,		;RETURN - SUCCESSFUL
	PJRST	SNDBSI		;NOT ENTERED - GO TYPE "BUSY"

;CALLED TO SET UP FORCED COMMAND FOR JOB CONTINUE
;JOB NUMBER IN T1
;SKIP RETURN IF COMMAND WAS NOT ENTERED BECAUSE ALREADY A
;FORCED COMMAND PENDING


FCONRQ::MOVEI	T2,TTFCXJ##	;INDEX FOR FORCED CONTINUE
;SUBROUTINE TO FORCE COMMAND
;ARGS	T1=JOB NUMBER
;	T2=INDEX OF FORCED COMMAND


COMFRC::SE1ENT			;ENTER SECTION 1
	PUSH	P,U		;SAVE THIS AC
	PUSH	P,J		;SAVE THIS JOB NUMBER
	MOVE	J,T1		;GET HIS JOB NUMBER
	PUSHJ	P,TTYSRC##	;SET UP LINE (LDB)
	  JRST	JCONDM		;SEE IF ATTACHED
	JRST	COMFR2
COMFRL::SE1ENT			;ENTER SECTION 1
	PUSH	P,U		;SAVE ACS
	PUSH	P,J
COMFR2:	JUMPE	U,JCONDM	;CAN'T FORCE TO DETACHED LINE.
	MOVSI	T1,LDBCMF##	;ANY FORCED COMMAND
	SCNOFF
	TDNE	T1,LDBCOM##(U)	;FOR THIS JOB ALREADY
	JRST	JCONDL		;YES
	DPB	T2,LDPCMX##	;STORE COMMAND INDEX
	MOVSI	T1,LDBCMR##+LDBCMF## ;BITS FOR FORCE
	PUSHJ	P,COMSTF##	;WAKE COMCON (RETURNS WITH SCAN ON)
	POP	P,J		;RESTORE JOB
	PJRST	LPOPJ##		;RETURN

;HERE IF JOB ALREADY HAS FORCED COMMAND PENDING, DELAY THIS COMMAND

JCONDL:	SCNON
JCONDM:	POP	P,J		;RESTORE JOB NUMER
	JRST	LPOPJ1##	;CAN'T ENTER - SKIP RETURN
;HERE IF JOB NOT WAITING FOR CONTINUE

JCERR2:	JSP	T1,ERRMES
	ASCIZ	/Job not waiting/


;FORCED CONTINUE COMMAND
;NO TTY OUTPUT UNLESS COMMAND IS REALLY EXECUTED - IT WILL NOT BE
; IF USER HAS TYPED A COMMAND IN THE MEAN TIME.

FCONT::	MOVE	P4,JBTSTS##(J)	;GET JOB STATUS
	TLNN	P4,JERR		;CAN WE CONTINUE
	TRNN	P4,JDCON	;IS JOB WAITING
	POPJ	P,
	TLO	M,TTYRNW	;SET FOR RESCHEDULE
	TLZ	M,NOCRLF!NOMESS ;RESET NOMESS
	PUSHJ	P,INLMES	;TELL USER HE'S CONT
	ASCIZ	/Continued by OPR/
	POPJ	P,
	SUBTTL	CORE COMMAND

; "CORE  #" - ASSIGNS #*1024 WORDS OF CORE TO JOB
; "CORE" WITH NO ARG. WILL PRINT NO OF FREE BLOCKS LEFT
;	WITHOUT AFFECTING CURRENT ASSIGNMENT OF CORE
;	JOB NOT IN MIDDLE OF SWAPPING
;	EITHER ON DISK OR CORE OR NEITHER PLACE



CORE::	PUSHJ	P,CORARG	;GET HIGHEST RELATIVE ADDRESS USER SPECIFIED
	JRST	COR5		;NO ARG. SPECIFIED, JUST TYPE FREE BLOCK LEFT
	TLNE	T1,-1		;NO ARG GREATER THAN A SECTION ALLOWED
	JRST	COR4
	JUMPL	P4,[MOVEI T1,RUNERR	;RUNNING?
		JRST ERRMES]	;YES, LOSE
	JUMPE	T1,COR1		;RELEASE DEVICES IF USER ASKING FOR 0 CORE
	TRNE	P4,JS.XO!JS.RUU	;SEE IF EXECUTE ONLY
	PJRST	ILLXO		;YES -- GO GIVE ERROR
	HRRZ	T2,JBTSGN##(J)	;CLEAR JUNK IN LH
	JUMPE	T2,COR1		;THERE REALLY ISN'T A HIGH SEG
COR3:	SKIPG	T3,.HBSGN(T2)	;IS THIS A REAL SEGMENT?
	TLOA	T3,-1		;NO, FLAG SUCH
	HLLZ	T3,JBTADR##(T3)	;GET SIZE OF SEGMENT
	HLRES	T3		;IN THE CORRECT HALF
	SUBI	T1,1(T3)	;ROUND UP AND SUBTRACT OUT
	JUMPL	T1,COR3D	;IF WENT NEGATIVE, ARG IS TOO SMALL
	HRRZ	T2,.HBLNK(T2)	;NEXT SEGMENT
	JUMPN	T2,COR3		;CHECK IT OUT
COR1:	SKIPE	T1
	SKIPN	JBTADR##(J)
	PUSHJ	P,COR15		;CALL UNLOCK, GETMIN, ET ALL
	JUMPE	T1,COR0
	SKIPE	JBTADR##(J)	;IF DIDN'T GET CORE IN CORE.
	JRST	COR2
	LDB	T2,IMGOUT##	;DID WE GET CORE ON DSK?
	JUMPE	T2,COR4		;ERROR IF NONE
	JRST	DLYCM
COR2:
IFN FTMP,<
	PUSHJ	P,GETMM##	;GET THE MM
	  JRST	DLYCM		;NOT AVAILABLE, DELAY
>
	SKIPE	PAGIPC##	;PAGING IN PROGRESS?
IFN FTMP,<
	JRST	[PUSHJ P,GIVMM##
		 JRST  DLYCM  ]	;YES, DELAY
>
IFE FTMP,<
	JRST	DLYCM
>
	PUSHJ	P,CORE0##	;GET CORE
IFN FTMP,<
	  JRST	[PUSHJ P,GIVMM## ;NONE AVAILABLE
		 JRST COR4]
	PUSHJ	P,GIVMM##	;GIVE UP THE MM.
>
IFE FTMP,<
	  JRST	COR4		;CORE NOT AVAILABLE, GO PRINT MESSAGE
>
	LDB	T1,PJBSTS##
	CAIE	T1,NULQ##	;IN THE NO CORE Q?
	POPJ	P,		;NO
	MOVEI	T1,STOPQ##	;YES, OK RETURN, CORE ASSIGNED ON DISK OR MEMORY
	DPB	T1,PJBSTS##	;PUT JOB IN THE STOP Q SINCE IT NOW HAS CORE
	PJRST	REQUE##
COR3D:	PUSHJ	P,INLMES	;TOO SMALL AN ARG.
ASCIZ	/?Try larger arg.
/

COR4:	PUSHJ	P,TTYFND##	;RE-FIND TTY LINE
	JUMPE	U,CPOPJ##	;GIVE UP IF GOT DETACHED
	PUSHJ	P,PRQM		;TYPE ? FOR BATCH
	PUSHJ	P,COR11		;PRINT USAGE/LIMIT SUMMARY
	TLO	M,ERRFLG	;SET ERROR FLAG
	POPJ	P,

;HERE TO GIVE CURRENT CORE SIZE FOR VM USER
COR5:	PUSHJ	P,FNDPDS##	;FIND PDB FOR JOB
	SKIPN	JBTADR##(J)	;DON'T BOTHER IF NO CORE
	JRST	COR11		;JUST SHOW LIMITS
	JSP	T2,SAVCTX##	;WE COULD HAVE A LOT OF OUTPUT
	PUSHJ	P,SAVE4##	;SAVE WORKING ACS
	PUSHJ	P,INLMES	;PRINT HEADER
	ASCIZ	/Page number	Page status	Origin

/
	MOVEI	P1,1		;START WITH PAGE 1, PAGE 0 ALWAYS EXISTS
	PUSH	P,U		;GTPACC CLOBBERS U
	MOVEI	T1,0		;PAGE 0
	PUSHJ	P,GTPACC##	;GET PAGE 0 ACCESSABILITY
	POP	P,U		;RESTORE LDB
	TDZ	T1,[<(PA.CPO+PA.OUT+PA.AA+PA.VSP)>,,-1] ;CLEAR DON'T CARE
	MOVE	P2,T1		;FOR THE LOOP
	MOVEI	P3,0		;END OF REGION
	MOVEI	P4,1		;COUNT OF PAGES
COR6:	MOVE	T1,P1		;CURRENT PAGE NUMBER
	LSH	T1,P2SLSH	;JUST SECTION NUMBER
	SKIPN	T2,.UPMP+SECTAB(T1) ;SECTION EXIST?
	JRST	COR9		;NEXT SECTION
	LDB	T1,[POINT 3,T2,2] ;GET POINTER TYPE
	CAIE	T1,PM.ICD	;INDIRECT?
	JRST	COR8		;NO
	MOVEI	T1,[ASCIZ /Section /]
	PUSHJ	P,CONMES	;PRINT THAT
	MOVE	T1,P1		;PAGE NUMBER
	LSH	T1,P2SLSH	;SECTION NUMBER
	PUSH	P,T2		;PRTDI8 CLOBBERS T2
	PUSHJ	P,PRTDI8	;PRINT SECTION NUMBER
	MOVEI	T1,[ASCIZ / @section /]
	PUSHJ	P,CONMES	;INDIRECT
	POP	P,T2		;RESTORE POINTER
	HLRZ	T1,T2		;RIGHT HALF
	ANDI	T1,MXSECN	;ISOLATE SECTION NUMBER
	PUSHJ	P,PRTDI8	;PRINT INDIRECT SECTION NUMBER
	PUSHJ	P,CRLF		;CRLF
COR7:	TRO	P1,PG.BDY	;NEXT SECTION
	JRST	COR10		;CONTINUE
COR8:	MOVE	T1,P1		;PAGE NUMBER
	PUSH	P,U		;GETPAC CLOBBERS U
	PUSHJ	P,GTPACC##	;GET PAGE ACCESSIBILITY
	POP	P,U		;RESTORE LDB
	TDZ	T1,[<(PA.OUT+PA.CPO+PA.AA+PA.VSP)>,,-1]	;DON'T CARE ABOUT IN, OUT, OR TARGET
	TLNN	T1,(PA.GSP)	;A SPY PAGE?
	SKIPGE	T1		;DOES PAGE EXIST?
	CAIA			;DON'T COUNT NON-EXISTANT OR SPY PAGES IN TOTAL
	AOS	P4		;UPDATE TOTAL PAGE COUNT
	CAMN	T1,P2		;SAME AS PREVIOUS PAGE?
	JRST	COR10		;YES, LOOK AT NEXT PAGE
COR9:	PUSH	P,T1		;SAVE NEW ACCESSIBILITY BITS
	SKIPL	P2		;PREVIOUS PAGES NON-EXISTANT?
	PUSHJ	P,PRTACC	;NO, REPORT THEM
	POP	P,P2		;NEW ACCESSIBILITY BITS
	MOVE	P3,P1		;START OF RANGE
	MOVE	T1,P1		;PAGE NUMBER
	LSH	T1,P2SLSH	;CURRENT SECTION NUMBER
	SKIPE	.UPMP+SECTAB(T1);DOES IT EXIST?
	JRST	COR10		;YES, LOOK AT IT
	TLO	P2,400000	;NO, PREVIOUS PAGE NON-EXISTANT
	JRST	COR7		;NEXT SECTION
COR10:	CAIGE	P1,HLGPGS	;LOOKED AT ALL SECTIONS?
	AOJA	P1,COR6		;NO, LOOP ON
	SKIPL	P2		;PREVIOUS PAGES NON-EXISTANT?
	PUSHJ	P,[AOJA P1,PRTACC] ;NO, REPORT THEM
	MOVEI	T1,[ASCIZ /
Total of /]
	PUSHJ	P,CONMES	;SUMMARY
	MOVE	T1,P4		;TOTAL NUMBER OF "REAL" PAGES SEEN
	PUSHJ	P,RADX10	;OUTPUT THAT
	MOVEI	T1,[ASCIZ / page/]
	PUSHJ	P,CONMES	;FINISH UP
	CAIN	P4,1		;SINGULAR?
	SKIPA	T1,[[ASCIZ /

/]]
	MOVEI	T1,[ASCIZ /s
/]				;NOTE THAT THIS IS <LF><CRLF> SO FITS IN 1 WORD
	PUSHJ	P,CONMES	;OUTPUT

;CONTINUED ON NEXT PAGE
COR11:	HLRZ	T1,.PDMVL##(W)	;GET MVPL
	JUMPE	T1,COR13	;SKIP FIRST LINE IF ZERO
	MOVEI	T1,[ASCIZ "Virt. mem. assigned "]
	PUSHJ	P,CONMES	;PRINT TITLE
	PUSHJ	P,VMSIZE##	;GET SIZE OF JOB
	JUMPE	T2,[PUSHJ P,PRCORE	;IF JUST A LOWSEG
		    JRST  COR12]; PRINT ONLY 1 NUMBER
	PUSH	P,T2		;SAVE SIZE OF HISEG
	PUSHJ	P,RADX10	;PRINT SIZE OF LOWSEG
	PUSHJ	P,PRTPLS
	POP	P,T1		;SIZE OF HISEG
	PUSHJ	P,PRCORE	;PRINT THAT
COR12:	HLRZ	T4,.PDCVL##(W)	;GET CVPL
	PUSHJ	P,PRCXPL	;PRINT THAT
	HLRZ	T4,.PDMVL##(W)	;GET MVPL
	SKIPN	T4
	MOVEI	T4,1000
	PUSHJ	P,PRMXPL	;PRINT THAT
	PUSHJ	P,INLMES	;ADD ) CRLF
	ASCIZ	/)
/
COR13:	PUSHJ	P,INLMES
	ASCIZ	/Phys. mem. assigned /
	PUSHJ	P,PRTSEG	;PRINT LOWSEG SIZE
	MOVEI	T1,JBTSGN##-.HBLNK(J) ;START OF CHAIN
COR13A:	SKIPN	T1,.HBLNK(T1)	;NEXT SEGMENT DATA BLOCK
	JRST	COR13B		;NO MORE
	SKIPG	T2,.HBSGN(T1)	;SPY SEG?
	JRST	COR13A
	PUSHJ	P,PRTHGH##	;PRINT SIZE OF HISEG
COR13B:	PUSHJ	P,PRPORK	;PRINT P OR K
	HRRZ	T4,.PDCVL##(W)	;GET CPPL
	TRZN	T4,400000
	JRST	[PUSHJ P,PRCPGL
		 JRST  .+2]
	PUSHJ	P,PRCXPL	;PRINT IT
	MOVEI	T4,0
	MOVSI	P1,PHONLY
	PUSH	P,.PDCVL##(W)
	MOVEI	T1,400000
	ANDCAM	T1,.PDCVL##(W)
	PUSHJ	P,PRMXPL	;PRINT IT
	POP	P,.PDCVL##(W)
;CONTINUED ON NEXT PAGE
	PUSHJ	P,INLMES	;ADD NOISE WORDS
	ASCIZ	/)
Swap space left: /
	MOVE	T1,VIRTAL##	;GET THAT NUMBER
	PUSHJ	P,PRCORE	;PRINT IN RADIX 10
	PJRST	CRLF		;ADD IN A CRLF AND RETURN

COR15:	PUSH	P,T1		;SAVE T1
	PUSHJ	P,UNLOCK##	;SO CALLING GETMIN DOES SOMETHING
	  JFCL			;OOPS
	PUSHJ	P,CLRLPG##	;CLEAR LOCKED PAGES
	PUSHJ	P,GETMIN
	PJRST	TPOPJ##		;AND RETURN


;ROUTINE TO PRINT CURRENT AND MAX LIMITS

PRCPGL:	MOVEI	T1,[ASCIZ " (Guideline: "]
	JRST	PRXXPL
PRCXPL:	SKIPA	T1,[[ASCIZ " (Current limit: "]]
PRMXPL:	MOVEI	T1,[ASCIZ " Max limit: "]
PRXXPL:	PUSH	P,T4
	PUSHJ	P,CONMES	;PRINT THE TITLE
	PUSHJ	P,CORBND##	;GET MAX CORE
	LSH	T1,W2PLSH	;IN PAGES
	SKIPN	(P)		;ANYTHING GIVEN?
	MOVEM	T1,(P)		;CHOOSE GOOD MAX
	POP	P,T1		;RESTORE NUMBER
PRCORE:	PUSHJ	P,RADX10	;PRINT IN DECIMAL
	PJRST	PRPORK		;GIVE UNITS
;ROUTINE TO PRINT PAGE ACCESSIBILITY. CALL WITH P1=HIGHEST PAGE NUMBER IN REGION,
; P2=BITS RETURNED FROM GETPAC (ALTERED!), P3=FIRST PAGE NUMBER IN REGION
PRTACC:	MOVE	T1,P3		;FIRST PAGE IN REGION
	PUSHJ	P,PRTDI8	;PRINT THAT
	CAIN	P1,1(P3)	;EXACTLY 1 PAGE?
	JRST	PRTAC1		;YES, SKIP NEXT
	PUSHJ	P,INLMES	;PRINT A MINUS SIGN
	ASCIZ	/-/
	MOVEI	T1,-1(P1)	;HIGHEST PAGE IN REGION
	PUSHJ	P,PRTDI8	;PRINT THAT
PRTAC1:	MOVEI	T1,[ASCIZ /	/]
	PUSHJ	P,CONMES	;LINE THINGS UP
	MOVEI	T2,-1(P1)	;FIX OFF BY ONE ABOVE
	CAIE	T2,(P3)		;ALWAYS TAB IF NO RANGE
	TRNN	T2,777000	;SEVEN OR MORE CHARACTERS ALREADY BEEN OUTPUT?
	PUSHJ	P,CONMES	;NO, NEED ANOTHER TAB
	MOVEI	T2,0		;COUNT CHARACTERS
	MOVEI	T1,[ASCIZ /EX /];IF ITS NOT A SPY PAGE, ITS EXECUTABLE
	TLNN	P2,(PA.GSP)	;A SPY PAGE?
	PUSHJ	P,[AOJA T2,CONMES] ;NO, OUTPUT
	MOVEI	T1,[ASCIZ /RD /];ASSUME IT CAN BE READ
	TLNE	P2,(PA.RED)	;CAN IT BE
	PUSHJ	P,[AOJA T2,CONMES] ;YES, OUTPUT THAT
	MOVEI	T1,[ASCIZ /WR /];ASSUME IT CAN BE WRITTEN
	TLNE	P2,(PA.WRT)	;CAN IT BE
	PUSHJ	P,[AOJA T2,CONMES] ;YES, OUTPUT THAT
	MOVEI	T1,[ASCIZ /AZ /];ASSUME ABZ
	TLNE	P2,(PA.ZER)	;IS IT?
	PUSHJ	P,[AOJA T2,CONMES] ;YES, OUTPUT THAT
	MOVEI	T1,[ASCIZ /SH /];ASSUME ITS SHARABLE
	TLNN	P2,(PA.GSP)	;WOULD YOU BELIEVE THAT SPY PAGES ARE SHARABLE?
	TLNN	P2,(PA.GSH)	;IS IT?
	CAIA			;NO
	PUSHJ	P,[AOJA T2,CONMES] ;YES, OUTPUT THAT
	MOVEI	T1,[ASCIZ /LK /] ;ASSUME LOCKED
	TLNE	P2,(PA.LCK)	;IS IT?
	PUSHJ	P,[AOJA T2,CONMES] ;YES, OUTPUT THAT
	MOVEI	T1,[ASCIZ /	/]
	TLNN	P2,(PA.GSH)	;NEED A TAB IF SHARABLE
	CAIG	T2,2		;ALSO IF LESS THAT 2 ATTRIBUTES
	PUSHJ	P,CONMES	;LINE THINGS UP
	TLNN	P2,(PA.GSP)	;SPY PAGES?
PRTA1A:	SKIPA	T1,[[ASCIZ /	Private/]] ;NO, ASSUME IT'S PRIVATE
	MOVEI	T1,[ASCIZ /	Spy/] ;SPY
	TLZE	P2,(PA.GSH)	;PRIVATE
	TLNE	P2,(PA.GSP)	;OR SPY?
	JRST	PRTAC4		;YES, WE HAVE AN ATTRIBUTE
	PUSHJ	P,SAVE1##	;SAVE P1
	PUSHJ	P,SAVJW##	;AND J (W ALONG FOR THE RIDE)
	MOVE	P1,P3		;GET PAGE # OF FIRST PAGE
	LSH	P1,P2SLSH	;GET SECTION
	SETZ	T1,		;FIRST SEG THAT SECTION
PRTA1B:	PUSHJ	P,NXSSP1##	;GET NEXT SEGMENT IN THAT SECTION
	  JRST	PRTA1A		;HUH (BITS ZEROED ABOVE)
	SKIPG	J,.HBSGN(T1)	;GET SEGMENT NUMBER
	JRST	PRTA1B		;SPY
	HRRZS	J		;CLEAR JUNK
	LDB	T2,JBYHSO##	;GET ORIGIN OF THAT HIGH SEG
	XOR	T2,P3		;SEE IF IT'S THIS PAGE
	TRNE	T2,HLGPNO	;?
	JRST	PRTA1B		;NO, CHECK NEXT SEGMENT
	MOVE	T2,JBTDEV##(J)	;DEVICE NAME
	PUSHJ	P,PRNAME	;PRINT THAT
	MOVEI	T1,[ASCIZ /:/]	;DEVICE DELIMITER
	PUSHJ	P,CONMES	;PRINT THAT
	MOVE	T2,JBTNAM##(J)	;GET HIGH SEGMENT NAME
	PUSHJ	P,PRNAME	;PRINT THAT
	MOVE	J,JBTPPN##(J)	;GET PPN
	TLNE	J,-1		;PATH OR PPN?
	SKIPA	T2,J		;PPN
	MOVE	T2,(J)		;PATH, PPN IS STORE HERE
	PUSHJ	P,PRTPP1	;PRINT THE LEFT BRACKET, P,PN
	TLNE	J,-1		;IF ONLY A PPN, DONE
	JRST	PRTAC3		;GO PRINT THE RIGHT BRACKET
PRTAC2:	SKIPN	T2,1(J)		;NEXT SFD
	JRST	PRTAC3		;NO MORE, DONE
	PUSHJ	P,PRCOM		;PRINT A COMMA
	PUSHJ	P,PRNAME	;PRINT THE SFD NAME
	AOJA	J,PRTAC2	;NEXT SFD
PRTAC3:	PUSHJ	P,PRTRBK	;PRINT RIGHT BRACKET
	PJRST	CRLF		;PRINT A CRLF AND RETURN

PRTAC4:	PUSHJ	P,CONMES	;OUTPUT WHAT WE HAVE
	CAIN	P1,1(P3)	;EXACTLY ONE PAGE?
	SKIPA	T1,[[ASCIZ / page
/]]
	MOVEI	T1,[ASCIZ / pages
/]
	PJRST	CONMES
;ROUTINE TO PRINT ACCOUNT STRING
CACCT::	MOVEI	T1,.PDACS##(W)	;ADDRESS OF USER'S ACCOUNT STRING
	PUSHJ	P,CONMES	;TYPE IT
	PJRST	PCRLF		;<CRLF>
	SUBTTL	CONTROL-T PRINTOUT

;SUBROUTINE TO PRINT A 1 TO 3 LINE USE STATUS REPORT
;CALLED FROM USESTAT COMMAND IT PRINTS A 1 LINE
; STATUS REPORT OF THE FORM:
;	INCREMENTAL DAY TIME
;	INCREMENTAL RUN TIME
;	INCREMENTAL DISK READS
;	INCREMENTAL DISK WRITES
;	PROGRAM NAME
;	CORE SIZE
;	JOB STATE
;	PC
;
USECOM::TLNN	P4,JNA		;IS THIS A JOB?
	PJRST	ATT4		;NO--SAY "NOT A JOB"
	MOVEI	T1,[ASCIZ 'Day: ']
	PUSHJ	P,CONMES
	PUSHJ	P,PRTWWT	;INCREMENTAL DAYTIME
	MOVE	T1,TIME##	;RESET THE TIMER FOR
	DPB	T1,JBYWCH##	; THE NEXT TIME
	PUSHJ	P,UDCPUT##	;UPDATE RUN TIME IF NECESSARY
	MOVEI	T1,[ASCIZ ' Run: ']
	PUSHJ	P,CONMES
	MOVEI	T1,0		;CLEAR INCREMENTAL RUNTIME
	EXCH	T1,.PDRTM##(W)	; AND PICK UP OLD RUN TIME
	PUSHJ	P,PRTIM		;PRINT THAT
	MOVEI	T1,[ASCIZ ' Rd:']
	PUSHJ	P,CONMES
	PUSHJ	P,PRTWDR##	;DISK READS
	MOVEI	T1,[ASCIZ ' Wr:']
	PUSHJ	P,CONMES
	PUSHJ	P,PRTWDW##	;DISK WRITES
	PUSHJ	P,PRSPC		;ANOTHER SPACE
	MOVE	T2,JBTPRG##(J)	;PROGRAM NAME
	PUSHJ	P,PRNAME	;PRINT THE NAME
	PUSHJ	P,USEHSG	;PRINT JOB'S HIGH SEGMENTS
	PUSHJ	P,PRSPC		;ANOTHER SPACE
	PUSHJ	P,PRTSEG	;LOW SEG SIZE
	PUSHJ	P,PRTHGH##	;HIGH SEG SIZE
	PUSHJ	P,PRPORK	;PRINT P OR K
	PUSHJ	P,CTXPRT##	;PRINT CURRENT CONTEXT NUMBER
	PUSHJ	P,PRSPC		;ANOTHER SPACE
	MOVSI	T2,'^C'		;ASSUME CONTROL-C STATE
	JUMPG	P4,USECM1	;JUMP IF TRUE
	LDB	T1,PJBSTS##	;PICK UP JOB STATE
	IDIVI	T1,3		;DIVIDE BY 3 TO GET WORD NUMBER
	IMULI	T2,^D12		;MULTIPLY REMAINDER BY 12 TO GET POSITION
	MOVE	T3,STSTBL##(T1)	;PICK UP ENTRY
	ROT	T3,(T2)		;GET CORRECT THIRD
	MOVSI	T2,777700	;ONLY LOOK AT TOP 12 BITS
	AND	T2,T3		;COPY STATE
USECM1:	PUSHJ	P,PRNAME	;PRINT THAT
IFN FTLOCK,<
	MOVEI	T3,"&"		;ASSUME LOCKED
	TLNE	P4,NSWP		;SEE IF LOCKED
	PUSHJ	P,PRCHR		;YES, LOCKED
>;END IFN FTLOCK
	MOVEI	T3,"*"		;ASSUME CURRENT JOB
	PUSHJ	P,ANYCPU##	;ARE WE THE CURRENT JOB?
	  PUSHJ	P,PRCHR		;YES--PRINT *
	PUSHJ	P,PRSPC		;ANOTHER SPACE
	MOVSI	T2,'SW '	;ASSUME SWAPPED
	TLNE	P4,SWP!SHF	;IS JOB IN CORE?
	PUSHJ	P,[SKIPE JBTADR##(J)	;ANY PHYS MEM?
		   MOVSI T2,'SW*'	;YES--ADD * TO MEAN SWAPPING
		   PJRST PRNAME]	;PRINT SW OR SW*
	MOVEI	T1,[ASCIZ ' PC:']
	PUSHJ	P,CONMES
	MOVE	T2,JBTPC##(J)	;GET CURRENT PC
	PUSHJ	P,UDPCP##	;PRINT PC IN OCTAL
USECPU:
IFN FTMP,<
	SKIPE	T2,[M.CPU##-1]	;SKIP IF FTMP ON BUT SINGLE CPU MONITOR
	HRRZ	T2,JBTST3##(J)	;GET CDB OF LAST CPU WE RAN ON
	JUMPE	T2,USECP1	;SKIP THIS IF A SINGLE CPU OR NO CORE FOR JOB
	PUSHJ	P,PRSPC		;SPACE OVER
	MOVE	T2,.CPLOG##-.CPCDB##(T2) ;GET CPU NAME
	PUSHJ	P,PRNAME	;PRINT IT
USECP1:
> ;END IFN FTMP
	SKIPN	JBTADR##(J)
	JRST	USECM3
	MOVSI	T1,SWP!SHF	;BIT INDICATING SWAPPED OR BEING SWAPPED
	SKIPE	.USVRT		;VIRTUAL?
	TDNE	T1,JBTSTS##(J)	;AND IN CORE?
	JRST	USECM3		;NO, SKIP THIS
	MOVEI	T1,[ASCIZ /
Faults - IW: /]
	PUSHJ	P,CONMES	;PRINT THE TEXT
	MOVE	T1,.USVCT	;REPORT INCREMEMTAL IN WORKING SET FAULTS
	SUB	T1,.USICT
	HRRZS	T1
	PUSHJ	P,RADX10
	MOVEI	T1,[ASCIZ / NIW: /]
	PUSHJ	P,CONMES	;PRINT TEXT
	MOVE	T1,.USVCT	;REPORT INCREMENTAL NOT IN WORKING SET FAULTS
	SUB	T1,.USICT
	HLRZS	T1
	PUSHJ	P,RADX10
	MOVE	T1,.USVCT	;UPDATE INCREMENTAL STATISTICS
	MOVEM	T1,.USICT
	MOVEI	T1,[ASCIZ / Virt core: /]
	PUSHJ	P,CONMES	;PRINT TEXT
	LDB	T1,LOVSIZ##	;LOW SEGMENT VIRTUAL CORE
	PUSHJ	P,RADX10	;REPORT LOW SEGMENT VIRTUAL CORE
	PUSHJ	P,PRTPLS	;PRINT A PLUS SIGN
	LDB	T1,HIVSIZ##	;HIGH SEG
	PUSHJ	P,PRCORE	;REPORT HIGH SEGMENT VIRTUAL CORE
	MOVEI	T1,[ASCIZ / Page rate: /]
	PUSHJ	P,CONMES	;PRINT TEXT
	MOVE	T1,J
	PUSHJ	P,FPDBT1##
	  TDZA	T3,T3
	HLRZ	T3,.PDVRT##(T1)	;GET PAGING RATE
	SETZB	T1,T2		;ASSUME A RATE OF ZERO
	JUMPE	T3,USECM2	;JUMP IF THE RATE IS ZERO
	MOVEI	T1,RTUPS##	;COMPUTE THE JOBS PAGING RATE
	IDIVI	T1,(T3)
	IMULI	T2,^D100
	IDIVI	T2,(T3)
USECM2:	PUSH	P,T2		;SAVE THE REMAINDER
	PUSHJ	P,RADX10	;PRINT THE RATE
	PUSHJ	P,PRPER		;AND A DOT
	POP	P,T1		;RESTORE THE REMAINDER
	MOVEI	T3,"0"		;ASSUME THE REMAINDER IS IN HUNDREDTHS
	CAIG	T1,^D9		;IS IT?
	PUSHJ	P,PRCHR		;YES, PRINT A LEADING ZERO
	PUSHJ	P,RADX10	;AND PRINT DIGITS FOLLOWING THE DECIMAL PLACE
USECM3:	HRRZ	F,JBTDDB##(J)	;GET DDB ADDRESS
	JUMPE	F,USECM5	;ALL DONE IF NO DDB
IFN FTMP,<
	DDBSRL			;LOCK DDB SEARCH
	MAP	T1,(F)		;MAP DDB ADDRESS
	PUSHJ	P,FLTCHK##	;STILL AROUND?
	  JRST	USECM4		;NO
>
	MOVE	T1,JBTSTS##(J)	;GET STATUS
	CAMLE	F,SYSSIZ##	;DDB IN THE MONITOR?
	TLNN	T1,SWP!SHF	;NO, IS THE JOB IN CORE?
	TRNA			;YES, PROCEED
	JRST	USECM4		;NO, DON'T TRY TO REPORT DEVICE INFO
	MOVE	T3,DEVMOD(F)	;GET DEVICE TYPE FOR TEST
	TRNE	T1,JS.XO	;EXECUTE ONLY?
	TLNN	T3,DVDSK!DVDTA	;AND DISK OR DECTAPE?
	SKIPA	T2,DEVIOS(F)	;NO, TYPE DDB INFO
	JRST	USECM4		;YES TO BOTH, SKIP DDB PRINTOUT
	MOVEI	T1,[ASCIZ "
Input"]
	TLNE	T3,DVTTY	;IS IT A TTY?
	TLNE	T3,DVDSK	;AND NOT NUL:?
	JRST	USECMA		;NO, GO DO NORMAL DEVICE
	TLNE	T2,TTYOUW##	;OUTPUT DIRECTION?
	MOVEI	T1,[ASCIZ "
Output"]
	JRST	USECMB		;TYPE THE MESSAGE
USECMA:	TLNE	T2,IO		;OUTPUT DIRECTION?
	MOVEI	T1,[ASCIZ "
Output"]
USECMB:	PUSHJ	P,CONMES	;PRINT THE TEXT
	MOVEI	T1,[ASCIZ " wait for "]
	PUSHJ	P,CONMES
	PUSHJ	P,PRTDDB	;PRINT FILE SPEC
	MOVE	T1,DEVMOD(F)	;GET DEVICE BITS
	TLNE	T1,DVDSK	;IS THIS A DISK?
	PUSHJ	P,DSKCTT##	;YES -- PRINT GOOD STUFF
	MOVE	T1,DEVMOD(F)	;IS THIS A
	TLNE	T1,DVMTA	; TAPE?
	PUSHJ	P,TPMCTT##	;YES--PRINT FILE & RECORD
USECM4:
IFN FTMP,<
	DDBSRU			;UNLOCK DDB
>
USECM5:	SE1ENT			;LDB'S ARE IN SECTION MUMBLE.
	HRRZ	F,LDBDDB##(U)	;GET DDB ADDRESS
	MOVE	T1,LDBDCH##(U)	;GET DEVICE BITS FOR TTY
	TLNE	T1,LDLCOM##	;COMMAND LEVEL?
	TLZ	M,NOPER		;YES--PRINT A PERIOD
	MOVSI	T2,LDBCMF##	;ALWAYS CALL TTYSTR IF
	TDNE	T2,LDBCOM##(U)	;USESTAT COMMAND (NOT ^T)
	TRNN	T1,LDROSU##	;CONTROL-O IN EFFECT
	TLZ	M,NOMESS	;NO--CLEAR NOMESS
	POPJ	P,0		;RETURN
;SUBROUTINE TO PRINT JOB'S HIGH SEGMENT(S) FOR CONTROL-T COMMAND
;CALL WITH:
;	J/ JOB NUMBER

USEHSG:				;WRAPS THE LINE AND TOO LATE FOR DOCUMENTATION
	POPJ	P,		;PATCH TO JFCL TO ENABLE THIS NIFTY FEATURE
	PUSHJ	P,SAVE2##	;FREE UP A FEW ACS
	SETZ	P1,		;START WITH FIRST HIGH SEGMENT
USEHS1:	MOVE	T1,P1		;COPY HSB ADDRESS
	PUSHJ	P,GNXHSB##	;GET NEXT HSB
	  POPJ	P,		;NONE, RETURN
	MOVE	P1,T1		;REMEMBER FOR POSTERITY
	SKIPG	P2,.HBSGN(P1)	;IS THERE A REAL SEGMENT THERE?
	JRST	USEHS1		;NO, SKIP THIS HSB
	PUSHJ	P,PRTPLS	;PRINT A "+"
	MOVE	T2,JBTPRG##(P2)	;GET NAME OF HIGH SEGMENT
	CAME	T2,JBTPRG##(J)	;UNLESS LOW AND HIGH SEG ARE SAME NAME,
	PUSHJ	P,PRNAME	; PRINT NAME OF HIGH SEGMENT
	JRST	USEHS1		;KEEP LOOPING
;SUBROUTINE TO PRINT A FILESPEC FOR A DDB
;CALL WITH:
;	F = DDB ADDRESS
;	U = LDB ADDRESS (OR FIX COMTOA)
;	PUSHJ	P,PRTDDB
;	RETURN HERE
;
PGMMRG:	SKIPA	T1,[[ASCIZ/Merged /]]
PGMFIL:	MOVEI	T1,[ASCIZ/ from /]
	SKIPE	F,USRJDA##+0	;SEE IF DDB AND GET ADDRESS
	TLNN	F,INPB		;WAS AN INPUT DONE?
	POPJ	P,		;NO
	PUSHJ	P,CONMES
PRTDDB::PUSHJ	P,SAVE1##	;SAVE P1
	MOVE	P1,DEVMOD(F)	;GET DEVICE TYPE BITS
	MOVSI	T2,'NUL'	;ASSUME NUL
	PUSHJ	P,NULTST##	;IS IT THE NUL DEVICE?
	  JRST	PRTDD1		;YES
	MOVE	T2,DEVNAM(F)	;GET DEVICE NAME
	HRRZ	T3,DEVUNI##(F)	;UDB POINTER
	JUMPE	T3,PRTDD1	;NO UNIT IF A KNOWN SEGMENT
	TLNN	P1,DVDSK	;IS THIS A DISK?
	JRST	PRTDD1		;NO
	SKIPN	T2,UNILOG(T3)	;YES, PART OF STR?
	MOVE	T2,UDBNAM(T3)	;NO
PRTDD1:	PUSHJ	P,PRNAME	;PRINT IT
	MOVEI	T3,":"		;ADD A COLON
	PUSHJ	P,PRCHR		; ..
	TLNN	P1,DVDSK!DVDTA	;FILE AND EXT?
	JRST	PRTDD2		;NO
	MOVE	T2,DEVFIL(F)	;GET FILE NAME
	JUMPE	T2,CPOPJ##	;PUNT IF NO NAME
	HLRZ	T3,DEVEXT(F)	;IS THIS A UFD
	TLNE	P1,DVDSK	;ON DISK
	CAIE	T3,'UFD'
	JRST	PRTDD3		;NO
	PUSHJ	P,PRTPPN	;YES -- PRINT FILE NAME AS [M,N]
	JRST	PRTDD4		;AND NOT SIXBIT
PRTDD2:
IFE FTTLAB,<POPJ P,>		;RETURN
IFN FTTLAB,<
	TLNE	P1,DVMTA	;IS THIS A MAGTAPE?
	SKIPN	%SITLP##	;AND IS TAPE LABELER RUNNING?
	POPJ	P,		;NO TO EITHER--RETURN
	PUSH	P,U		;SAVE U
	MOVE	U,TDVUDB##(F)	;UDB ADDRESS
	LDB	T1,TUYLTP##	;GET LABEL TYPE
	POP	P,U		;RESTORE U
	JUMPE	T1,CPOPJ##	;RETURN IF NOT A LABELED TAPE
	SKIPN	T2,DEVFIL(F)	;ELSE GET FILE NAME
	POPJ	P,		;UNLESS THERE ISN'T ONE
> ;END IFN FTTLAB
PRTDD3:	PUSHJ	P,PRNAME	;PRINT IT
PRTDD4:	PUSHJ	P,PRPER		;ADD IN A DOT
	HLLZ	T2,DEVEXT(F)	;GET EXTENSION
	PUSHJ	P,PRNAME	;PRINT IT
	TLNE	P1,DVDSK	;IS THIS THE DISK?
	SKIPN	T2,DEVPPN(F)	;FALL INTO PRTPPN IF PPN
	POPJ	P,		;ELSE RETURN
;	PJRST	PRTPTH		;PRINT PATH (NEXT PAGE)
;ROUTINE TO TYPE A PATH WITH SFD'S IF NEEDED

PRTPTH:	PUSHJ	P,PRTPP1	;PROJ, PROG PART OF PATH
	HRRZ	P1,DEVSFD##(F)	;PATH POINTER
	JUMPE	P1,PRTRBK	;IF NO SFD'S
	PUSH	P,[0]		;MARK END OF PATH
PRTPT1:	PUSH	P,NMBNAM##(P1)	;SAVE THE SFD NAME
PRTPT2:	HLRZ	P1,NMBPPB##(P1)	;BACK ONE LEVEL
	TRZN	P1,NMPUPT##	;NAME SHOULD BE OUTPUT?
	JUMPN	P1,PRTPT2	;NO, GET NEXT LEVEL IF NOT AT END
	JUMPN	P1,PRTPT1	;YES, SAVE NAME AND GET NEXT LEVEL
PRTPT3:	POP	P,T2		;RESTORE SFD NAME
	JUMPE	T2,PRTRBK	;IF END, TYPE RIGHT BRACKET AND RETURN
	PUSHJ	P,PRCOM		;PRINT COMMA
	PUSHJ	P,PRNAME	;PRINT THIS SFD NAME
	JRST	PRTPT3		;LOOP OVER WHOLE PATH

PRTPPN::PUSHJ	P,PRTPP1
	PJRST	PRTRBK

PRTPP1:	PUSH	P,T2		;SAVE PPN
	MOVEI	T3,"["		;PRINT [
	PUSHJ	P,PRCHR
	HLRE	T1,(P)
	JUMPGE	T1,PRTPP2	;WILDCARD?
	MOVEI	T3,"*"		;YES
	PUSHJ	P,COMTYO
	SKIPA
PRTPP2:	PUSHJ	P,PRTDI8	;PROJECT
	PUSHJ	P,PRCOM		;COMMA
	HRRE	T1,(P)
	AOJN	T1,PRTPP3	;WILDCARD?
	MOVEI	T3,"*"		;YES
	PUSHJ	P,COMTYO
	JRST	T2POPJ##
PRTPP3:	HRRZ	T1,(P)		;GET PROGRAMMER HALFWORD AGAIN
	PUSHJ	P,PRTDI8	;PRINT IT
	JRST	T2POPJ##

PRTRBK:	MOVEI	T3,"]"
	PJRST	P,PRCHR
	SUBTTL	NETWORK COMMANDS -- LOCATE


CLOCAT::JSP	T2,SAVCTX	;MUST SCHEDULE THIS COMMAND
	SE1ENT			;ENTER SECTION ONE
	PUSHJ	P,CTEXT1	;GET THE ARGUMENT IN SIXBIT
	NETDBJ			;INTERLOCK THIS CODE WITH NETSER
	SKIPN	T1,T2		;COPY TO T1
	SKIPA	T2,JBTLOC##	;USE LOCAL STATION
	PUSHJ	P,CVTOCT##	;TRY TO CONVERT TO OCTAL
	  MOVE	T1,T2		;CAN'T-GET THE NAME BACK
	PUSH	P,T1		;SAVE THE ARG
IFN FTNET,<
	SKIPE	[M.ANF##]	;ANF-10 SOFTWARE?
	PUSHJ	P,SRCNDB##	;SEARCH FOR THE NODE BLOCK
	  JRST	LOCERR		;DOES NOT EXIST
	HLRZ	T2,NDBNNM##(W)	;YES, GET THE NODE NUMBER
	MOVEI	T1,[ASCIZ/Node number out of range/]
	CAILE	T2,77		;KEEP IT REASONABLE FOR BATCH
	JRST	[POP  P,(P)	;CLEAN STACK
		 JRST ERRMES]	;GIVE ERROR
	MOVEM	T2,JBTLOC##(J)	;LOCATE HIM WHERE HE WANTS
	POP	P,(P)		;RESTORE THE STACK
	PUSHJ	P,TYPNDB##	;TYPE THE NODE NAME
	JSP	T1,CONMES	;AND FINISH UP
	ASCIZ	/ located
/
> ;END IFN FTNET
LOCERR:	POP	P,T2		;GET NUMBER BACK
	CAIG	T2,77		;IS IT A NUMBER
	JUMPG	T2,LOCER1	;YES, WILL ALLOW THE LOCATE TO HAPPEN
IFN FTNET,<PJRST UNDERR>	;UNDEFINED NETWORK NODE
IFE FTNET,<
	MOVEI	T1,[ASCIZ \Invalid station address\] ;NO.
	PJRST	ERRMES		;TYPE IT
> ;END IFE FTNET

LOCER1:	MOVEM	T2,JBTLOC##(J)	;STORE THE LOCATION
IFN FTNET,<
	MOVEI	T1,[ASCIZ /%Node (/]
	SKIPN	[M.ANF##]	;ANF-10 SOFTWARE?
> ;END IFN FTNET
	MOVEI	T1,[ASCIZ /Station /]
	PUSHJ	P,CONMES	;PRINT TEXT
	HRRZ	T1,JBTLOC##(J)	;GET THE NUMBER
	PUSHJ	P,PRTDI8	;PRINT THE NUMBER
IFN FTNET,<
	MOVEI	T1,[ASCIZ /) located but offline/]
	SKIPN	[M.ANF##]	;ANF-10 SOFTWARE?
> ;END IFN FTNET
	MOVEI	T1,[ASCIZ / located/]
	PUSHJ	P,CONMES	;PRINT TEXT
	PJRST	PCRLF		;END LINE WITH A CRLF
	SUBTTL	NETWORK COMMANDS -- WHERE


CWHERE::SE1ENT			;ENTER SECTION ONE
IFE FTNET!FTKL10!FTDECNET!FTENET,<
	MOVSI	T1,JLOG		;IF NOT
	TDNN	T1,JBTSTS##(J)	;LOGGED IN
	DPB	T1,PJOBN##	;DON'T LEAVE GHOST JOB
	JSP	T1,ERRMES	;CAN'T DO THESE IF NO NETWORK
	ASCIZ	/No network, DAS78, or DN60 software
/
> ;END IFN FTNET!FTKL10!FTDECNET!FTENET
IFN FTNET!FTKL10!FTDECNET!FTENET,<
	JSP	T2,SAVCTX##	;SAVE THE CONTEXT OF THE JOB
	PUSHJ	P,CTEXT1	;GET FIRST ARG = SIXBIT DEV NAME
IFN FTNET,<
	NETDBJ			;INTERLOCK WITH NETSER
	PUSHJ	P,NETASG##	;TRY TO ASSIGN "NODE_DEVICE"
	  POPJ	P,		;ERROR IN ARGUMENTS (MESSAGE PRINTED)
>;END IFN FTNET
	PUSH	P,T2		;SAVE 6 BIT
	PUSHJ	P,FNDSTA##	;GET OUR STATION
	POP	P,T2		;GET 6 BIT NAME
	MOVE	T1,T2		;INTO T1
	PUSH	P,U		;SAVE U
	PUSHJ	P,DVCNSG##	;SEARCH FOR PHYSICAL DEV NAME
	PJRST	NOTDV1		;PRINT "NO SUCH DEVICE"
	PUSHJ	P,FNDDEV##	;FIND LOCATION
	LDB	T2,PDVTYP##	;GET DEVICE TYPE
IFN FTKL10,<
	CAIN	T2,.TYD78	;IS IT A DAS78?
	PJRST	CWHD78##	;LET D78INT HANDLE IT
> ;END IFN FTKL10
IFN FTNET,<
	CAIE	T2,.TYTTY	;IS IT A TTY?
	PJRST	CWHANF##	;LET NETSER HANDLE NON-TTY DEVICES
> ;END IFN FTNET
	MOVE	U,DDBLDB##(F)	;GET TARGET TTY'S LDB
	MOVE	T4,LDBTTW##(U)	;GET THE TTY USE FLAGS
	TLNN	T4,LTLUSE##	;IS TTY IN USE?
	JRST	CWHNCN		;NO, JUST SAY "NOT CONNECTED"
IFN FTNET,<
	TLNE	T4,LTLANF##	;IF ANF-10,
	PJRST	CWHANF##	;LET NETSER TYPE IT OUT
> ;END IFN FTNET
IFN FTDECNET,<			;IF DECNET,
	TLNE	T4,LTLNRT##	;IF NRT/CTERM
	JRST	CWHNRT##	;LET NRTSER TYPE IT OUT
> ;END IFN FTDECNET
IFN FTENET,<			;IF ETHERNET/LAT
	TLNE	T4,LTLLAT##	;IF LAT TERMINAL
	PJRST	CWHLAT##	;LET LATSER TYPE IT OUT
> ;END IFN FTENET
	TLNE	T4,LTLREM##	;REMOTE?
	PJRST	CWHNCN		;YES, BUT DON'T KNOW WHAT FLAVOR
IFE FTNET,<JRST UPOPJ##>	;GIVE UP
IFN FTNET,<PJRST CWHANF##>	;SAY LOCAL STATION
CWHNCN::PUSHJ	P,INLMES	;DEVICE IS NOT CONNECTED . . .
	ASCIZ	\Device	\
	MOVE	T2,DEVNAM(F)	;GRAB THE DEVICE NAME
	PUSHJ	P,PRNAME	;AND TYPE IT OUT
	PUSHJ	P,INLMES	;NOT CONNECTED
	ASCIZ	/ not connected
/
	PUSHJ	P,TTYKLQ##	;ZAP THE USELESS DDB
        POP	P,U
	POPJ	P,		;RETURN

> ;END IFN FTNET!FTKL10!FTDECNET!FTENET
	SUBTTL	NETWORK COMMANDS -- NODE


CNODE::	SE1ENT			;ENTER SECTION ONE
	JSP	T2,SAVCTX##	;SAVE CONTEXT, RUN AT UUO LEVEL
IFE FTNET!FTDECNET,<
	MOVEI	T1,[ASCIZ /No network support/]
	PJRST	ERRMES		;REPORT ERROR AND RETURN
> ;END IFE FTNET!FTDECNET
IFN FTNET!FTDECNET,<
	SKIPN	[M.NET##]	;NETWORK SUPPORT IN MONITOR?
	JRST	[MOVEI T1,[ASCIZ /No network support/] ;NO
		PJRST ERRMES]	;REPORT ERROR AND RETURN
	PUSHJ	P,CTEXT1	;GET THE ARGUMENT
IFN FTNET,<
	PUSHJ	P,NODE.A##	;ANF-10 NODE?
	  SKIPA			;NO
	POPJ	P,		;DONE
> ;END IFN FTNET
IFN FTDECNET,<
	PUSHJ	P,NODE.D##	;DECNET NODE?
	  SKIPA			;NO
	POPJ	P,		;DONE
>; END IFN FTDECNET

UNDERR::MOVEI	T1,[ASCIZ /Undefined network node/]
	PJRST	ERRMES		;PRINT ERROR MESSAGE AND RETURN
> ;END IFN FTNET!FTDECNET
	SUBTTL	SAVE, SSAVE AND GET - COMMAND SETUP

; "SSAVE DEVICE:FILNAM.EXT [PROJ,R] CORE"
;WORKS LIKE SAVE, EXCEPT THAT HIGH SEG IS SAVED AS SHARABLE(EXT=SHR)
;INSTEAD OF NON-SHARABLE(EXT=HGH)


; "SAVE DEVICE:FILE-NAME[PROJ.,PROG.] CORE" - SAVES JOB AREA ON RETRIEVABLE DEVICE
;ONLY A SAVE OR A GET IN PROGRESS FOR EACH JOB
;NO ATTEMPT IS MADE TO SAVE DEVICE ASSIGNMENTS, AC'S, OR PC
NSAVE::	TLO	S,NSRBIT	;SET FLAG FOR SAVE
NSSAVE::MOVSI	T1,(JS.EXE)	;GET EXE BIT
	IORM	T1,JBTST2##(J)	;SET IT IN JOB STATUS WORD
	JRST	SSAVE2		; AND CONTINUE AS BEFORE

SAVEO::	TLO	S,NSRBIT	;OLD SAVE
	JRST	SSAVE1
CSAVE::	TLO	S,NSRBIT	;SET FLAG FOR NON-SHARABLE EXT(HGH)

SSAVE::	MOVE	T1,CNFST2##	;CHECK CONFIG BIT FOR EXE FILE SAVES
	TRNE	T1,ST%EXE	;IF ON,...
	JRST	NSSAVE		;... PROCEED AS IN "NSAVE"

SSAVE1::MOVSI	T1,(JS.EXE)	;GET EXE BIT
	ANDCAM	T1,JBTST2##(J)	;CLEAR IT JUST FOR SAFETY
SSAVE2:	TLO	P1,GTSAV	;FLAG THAT DOING A SAVE
	HRRI	S,SAVJOB	;SETUP TO RUN SAVJOB (S CLEARED BEFORE CALL)
	JRST	SGSETD



; SAVE UUO - CALLED LIKE RUN AND GETSEG UUOS

USAVE::	MOVE	T2,JBTSTS##(J)	;GET JOB STATUS
	TLNE	T2,JLOG		;LOGGED IN?
	 JRST	USAVE1		;YES, OK
	MOVEI	T1,NLIERR	;NOT LOGGED IN ERROR
	PUSHJ	P,SGRELE	;TRY TO TELL USER
	MOVEI	T1,LOGPLM	;ADDRESS OF ERROR TEXT
	JRST	PHOLD##		;START TTY AND STOP JOB
USAVE1:	MOVSI	T2,(JS.EXE)	;EXE-STYLE SAVE BIT
	IORM	T2,JBTST2##(J)	;SET FOR THIS USER
	TLO	P1,GTSAV	;DON'T KILL HISEG IF GETARG ABORTS
	MOVEM	P1,.JDAT+SGAEND	;A SAFER PLACE TO BE
	PUSHJ	P,GETARG	;GET USER'S ARGUMENTS
	SKIPGE .JDAT+SGANEW	;EXTENDED CORE ARG GIVEN?
	JRST	IUUAGL##	;YES, MUSN'T DO THAT FOR SAVE (YET)
	MOVE	T1,DEVMOD(F)	;GET DEVICE TYPE
	TLNN	T1,DVDSK	;IS IT A DISK?
	JRST	[MOVEI T1,ILUERR	;GET ERROR CODE
		 PUSHJ P,SGRELE	;TRY TO TELL USER
		 PJSP T1,PHOLD##	;GIVE UP
		 ASCIZ\SAVE. UUO only valid for disks\]
	TLNE	T1,DVTTY	;IS IT NUL?
	JRST	[POP P,(P)	;POP OFF JUNK
		 JRST CPOPJ1]	;AND GIVE GOOD RETURN
	MOVE	T1,.JDAT+JOBPD1##+1 ;GET UUO RETURN ADDR
	TRNN	T1,^-17		;FROM THE ACS?
	 HRRZS	.JDAT+JOBPD1##	;YES, SAY NOT FROM USER
IFN FTMP,<
	PUSHJ	P,CLRJSP##	;ENSURE MONITOR RUNS ON MASTER CPU
>
	OPEN	0,SGAMOD	;OPEN THE SPECIFIED DEVICE
	 JRST	SGERRU		;DEVICE WENT AWAY
	SKIPL	.JDAT+JOBPD3##+1	;DID USER SPECIFY SHARABLE?
	 TLO	S,NSRBIT	;NO, MAKE IT NONSHARABLE
	MOVEI	T2, 'EXE'	;GET THE LEGAL EXTENSION
	HRLM	T2,.JDAT+SGAEXT	;STORE IN ENTER BLOCK
	PUSHJ	P,SETEXT##	;AND SET UP SGALOW AND SGAHGH
	MOVE	T1,.JDAT+JOBPD1## ;OUR NOMINAL RETURNING FLAGS
	TLNN	T1,USRMOD	;WILL WE EVER RETURN?
	 JRST	USAVE2		;NO, SO SKIP THIS
	PUSH	P,.PDTMI##(W)	;SAVE SOME VM LOCS
	PUSH	P,.PDTMC##(W)
USAVE2:	HLRZ	T1,JBTADR##(J)	;GET HIGHEST ADDRESS IN LOW SEG
	HRRZS	T2,.JDAT+SGANEW	;CLEAR JUNK FROM LH (FOR COMPATABILITY)
	CAMGE	T1,T2		;COMPARE WITH USER STORED CORE ARG
	MOVE	T1,T2		;USER'S WAS LARGER, USE IT
	HRRM	T1,.JDAT+JOBCOR##	;AND SET UP JOBCOR.
	PUSHJ	P,RMVPFH##	;GET RID OF PFH
	PUSHJ	P,ADJCOR##	;SET UP GOOD CORE ARG
	PJRST	SAVEXE		;GO SAVE A FILE
	SUBTTL	SEGOP. UUO

;
;CALL:	XMOVEI	AC,ARGLIS
;	SEGOP.	AC,
;	  ERROR CODE IN AC
;	SUCCESS, AC UNCHANGED
;
;
SEGOP::	PUSHJ	P,SXPCS##	;VALIDATE THE ARG BLOCK POINTER
	  JRST	SOPADC		;ADDRESS ERROR
	MOVE	M,T1		;COPY FOR FETCHING
	PUSHJ	P,GETEWD##	;GET LENGTH,,FCN
	  JRST	SOPADC		;ADDRESS ERROR
	MOVE	T4,T1		;SAVE IT
	HLRZ	T2,T1		;GET LENGTH OF ARG BLOCK
	HRRES	T1		;ISOLATE FUNCTION CODE
	CAML	T1,[SEGCMX]	;LEGAL CUSTOMER FUNCTION?
	CAILE	T1,SEGFMX	;LEGAL FUNCTION CODE?
	JRST	SOPILF		;NOPE
	CAMGE	T2,SEGMLN(T1)	;ARGUMENT LIST LONG ENOUGH?
	JRST	SOPATS		;NO, ARGUMENT LIST TOO SHORT
	MOVE	T1,M		;GET ADDRESS OF ARG LIST
	PUSHJ	P,ARNGE##	;ADDRESS CHECK THE ARG BLOCK ITSELF
	  JRST	SOPADC		;NOT ALL ADDRESSABLE
	  JRST	SOPADC		;CAN'T STORE RESULTS
	HRRE	T1,T4		;GET FCN CODE AGAIN
	PJRST	@SEGJMP(T1)	;AND GO FOR IT

	DEFINE	SOPFNS,<
SOPFUN	(4,SOPINF)		;(0) GET SEGMENT INFO
SOPFUN	(7,SOPGET)		;(1) GET A SEGMENT
SOPFUN	(3,SOPREL)		;(2) RELEASE SEGMENT(S)
SOPFUN	(6,SOPRMP)		;(3) REMAP
SOPFUN	(3,SOPSWP)		;(4) SETUWP
SOPFUN	(6,SOPCOR)		;(5) CORE
SOPFUN	(3,SOPDMP)		;(6) RETURN A LIST OF SEGMENTS IN SOME ADR SPACE
>

	DEFINE	SOPFUN(LENGTH,DISPATCH),<IFIW	DISPATCH>


;DISPATCH TABLE OF SEGOP.
;CUSTOMER FUNCTIONS GO HERE
CSEGJM:
SEGJMP:	SOPFNS
SEGFMX==.-SEGJMP-1
SEGCMX==SEGJMP-CSEGJM

	DEFINE	SOPFUN(LENGTH,DISPATCH),<EXP	LENGTH>

;TABLE OF MINIMUM LEGAL LENGTHS OF ARGUMENT LIST FOR VARIOUS FUNCTIONS

SEGMLN:	SOPFNS			;TABLE OF MINIMUM LENGTHS

;ERROR RETURNS

SOPNSS:	MOVEI	T1,FNFERR	;NO SUCH SEGMENT
	JRST	STOTAC##	;STORE ERROR CODE
SOPNCA:	MOVEI	T1,NECERR	;NOT ENOUGH CORE AVAILABLE
	JRST	STOTAC##	;STORE ERROR CODE
S