Google
 

Trailing-Edge - PDP-10 Archives - BB-T573C-DD_1986 - 10,7/whojob.mac
There are 4 other files named whojob.mac in the archive. Click here to see a list.
	TITLE	JOBSCN - JOB mode scan defaulting for WHO

	SEARCH	WHOMAC

	$SETUP	(JOBSCN)

Comment |

This module provides the JOB mode specific scan defaulting code. Its
only entry point is JOBSCN.

|
;               TABLE OF CONTENTS FOR JOBSCN
;
;
;                        SECTION                                   PAGE
;    1. JOBSCN - Apply job mode specific scan input defaults......   3
;    2. Storage...................................................   7
	SUBTTL	JOBSCN - Apply job mode specific scan input defaults

;This routine applies the following defaults to the command line
;
;	.WHO .			.WHO/JOB:<SELF>
;	.WHO nnn		.WHO/JOB:nnn
;	.WHO #nnn		.WHO/TTY:nnn
;	.WHO [P,PN]		.WHO/PPN:[P,PN]
;	.WHO NAME		.WHO/NAME:NAME
;	.WHO DEV:		.WHO/DEVICE:DEV
;	.WHO/DEVICE:DEV		.WHO/MOUNT:DEV (If "DEV" is a disk)

JOBSCN::
;
;Here to fix up name and extension (can be job, TTY, or name)
;
	SKIPE	T1,.FXEXT(I)		;SEE IF EXTENSION GIVEN
	  JRST	[CAIN	T1,-1		;YES--INSURE JUST EXTENSION
		  SKIPE	.FXNAM(I)	;AND NO NAME
		   JRST	E$$EIC		;BECAUSE THATS BAD
		 PUSHJ	P,CHKDOT##	;SEE IF DOT OK (NOT CRASH FILE)
		 MOVE	T1,MYJOB##	;GET USERS JOB
		 CHKSWT	(JOB)		;SEE IF GIVEN
		 JRST	.+1]		;AND CONTINUE
	SKIPN	T1,.FXNAM(I)		;SEE IF NAME
	  JRST	JOBS.2			;NO
	SKIPE	.FXEXT(I)		;YES--INSURE NO EXTENSION
	 $FATAL (EIC,<Extension illegal in this context>)	;NO--DIE
	TXNE	T1,77B5			;FIRST CHAR BLANK?
	  JRST	JOBS.3			;NO
;
;Here when name is an octal TTY number
;
	MOVSS	T1			;YES--GET OCTAL NUMBER
	PUSHJ	P,TTYNNN##		;MAKE NNN
	HRLI	T1,'TTY'		;MAKE TTYNNN
	CHKSWT	(TTY)
	JRST	JOBS.2			;CHECK ON
;
;Here to see if name is numeric (job) or alphanumeric (name)
;
JOBS.3:	MOVE	T2,[POINT 6,T1]		;GET POINTER
	MOVEI	T3,0			;CLEAR ANSWER
JOBS.4:	ILDB	T4,T2			;GET A CHAR
	JUMPE	T4,JOBS.5		;END IF BLANK
	CAIL	T4,'0'			;RANGE CHECK
	 CAILE	T4,'9'			;..
	  JRST	JOBS.N			;MUST BE NAME
	IMULI	T3,^D10			;SHIFT OVER
	ADDI	T3,-'0'(T4)		;ADD IN DIGIT
	JRST	JOBS.4			;AND LOOP
;
;Here when name is in fact a name
;
JOBS.N:	CHKSWT	(NAME)
	SETZM	.FZNAM##+1(I)		;INDICATE ONLY 6 CHARS
	JRST	JOBS.2			;AND CONTINUE
;
;Here when name was numeric - must be a job number
;
JOBS.5:	MOVE	T1,T3			;COPY INTO T1
	CHKSWT	(JOB)
;
;Here to fix up PPN specification 
;
JOBS.2:	MOVX	T1,FX.DIR		;GET DIRECTORY BIT
	TDNN	T1,.FXMOD(I)		;SEE IF GIVEN
	  JRST	JOBS.6			;NO
	MOVE	T1,.FXDIR(I)		;GET PPN
	TLNN	T1,-1			;SEE IF PROJ
	  HRROS	.FXDIM(I)		;NO--CLEAR WILDCARDS
	TLNN	T1,-1			;CHECK AGAIN
	  HLL	T1,.MYPPN##		;NO--USE MINE
	TRNN	T1,-1			;SEE IF PROG
	  HLLOS	.FXDIM(I)		;NO--CLEAR WILDCARDS
	TRNN	T1,-1			;CHECK AGAIN
	  HRR	T1,.MYPPN##		;NO--USE MINE
	CHKSWT	(PPN)
	MOVE	T1,.FXDIM(I)		;GET MASK
	MOVEM	T1,.FZPPM##(I)		;STORE MASK
;
;If device is given, store as /DEVICE:NNN

JOBS.6:	MOVX	T1,FX.NDV		;GET NULL DEVICE BIT
	TDNE	T1,.FXMOD(I)		;SEE IF DEVICE GIVEN
	 JRST	JOBS.7			;NO
	MOVE	T1,.FXDEV(I)		;YES--GET DEVICE
	CHKSWT	(DEVICE)
;If /DEVICE:NNN is a disk, change to /MOUNT:NNN

JOBS.7:	MOVE	T1,.FZDEV##(I)		;GET DEVICE
	CAMN	T1,[-1]			;SEE IF GIVEN
	  JRST	JOBS.9			;NO
	DVNAM.	T1,			;GET REAL NAME
	 MOVE	T1,.FZDEV##(I)		;CANT
	MOVEM	T1,.FZDEV##(I)		;STORE REAL DEVICE
	DEVTYP	T1,			;GET DEVICE TYPE
	  MOVEI	T1,0			;FAILED
	JUMPE	T1,JOBS.9		;NO SUCH DEVICE
	LOAD	T1,T1,TY.DEV		;GET DEVICE TYPE
	CAIE	T1,.TYDSK		;SEE IF DISK
	  JRST	JOBS.9			;NO
	SETO	T1,			;LOAD -1
	EXCH	T1,.FZDEV##(I)		;GET DEVICE, CLEAR STORAGE
	CHKSWT	(MOUNT)

;Make mask out of /NAME:NAME switch

JOBS.9:	MOVE	T3,.FZNAM##(I)		;GET NAME
	CAMN	T3,[SIXBIT/*/]		;FULL WILD?
	  MOVEI	T3,0			;YES--INDICATE THAT
	PUSHJ	P,.MKMSK##		;MAKE MASK
	MOVEM	T1,.FZNMM##(I)		;STORE
	MOVE	T3,.FZNAM##+1(I)		;..
	PUSHJ	P,.MKMSK##		;..
	MOVEM	T1,.FZNMM##+1(I)		;..
;
;Convert /LOCAL to /NOREMOTE and visa versa
;
	SKIPL	T1,.FZLCL##(I)		;LT /LCAL
	  JRST	[TRC T1,1		;FLIP THE BIT
		 MOVEM T1,.FZRMT##(I)	;AND STORE /REMOTE
		 JRST .+1]		;CONTINUE

;Default /TTY if /[NO]REMOTE or /[NO]DIALUP

	MOVE	T1,.FZTTY##(I)		;GET /TTY
	MOVSI	T2,'TTY'		;GET DEFAULT FOR ALL TTYS
	SKIPL	.FZRMT##(I)		;SEE IF /[NO]REMOTE
	 CAME	T1,[-1]			;SEE IF /TTY GIVEN
	  SKIPA				;..
	   MOVEM T2,.FZTTY##(I)		;SET FOR TTY'S ONLY
	SKIPL	.FZAPC##(I)		;SEE IF ANY APC SWITCH
	 CAME	T1,[-1]			;SEE IF /TTY GIVEN
	  SKIPA				;..
	   MOVEM T2,.FZTTY##(I)		;SET FOR TTY'S ONLY
;Fix up /TTY spec, and make mask

	PUSHJ	P,FIXTTY##		;CLEAN IT UP
	PUSHJ	P,FIXNOD##		;AND NODE SPEC IF ANY

;Range check job number

	SKIPL	T1,.FZJOB##(I)		;SEE IF JOB NUMBER
	 PUSHJ	P,CHKJOB##		;YES-RANGE CHECK IT

;Default /LOCATE:0 to central site

	SKIPN	T1,.FZLOC##(I)		;GET /LOCATION
	  MOVE	T1,CENSTA##		;0--GET CENTRAL SITE
	MOVEM	T1,.FZLOC##(I)		;STORE

;Convert some common /SEGMENT: codes

	MOVE	T1,.FZHSN##(I)		;GET /SEGMENT
	CAMN	T1,[SIXBIT/OLD/]	;/SEGMENT:OLD?
	  MOVE	T1,[SIXBIT/(OLD)/]	;YES
	CAMN	T1,[SIXBIT/PRIV/]	;/SEGMENT:PRIV?
	  MOVE	T1,[SIXBIT/(PRIV)/]	;YES
	MOVEM	T1,.FZHSN##(I)		;STORE
;
;Here to apply job number if /SWAP:(FORCE,FIT,IN,OUT)
;
	SKIPLE	.FZSWP##(I)		;SEE IF /SWAP
	 SKIPG	.FZJOB##(I)		;SEE IF A JOB
	  CAIA
	   $FATAL (JSS,<Job cannot be specified with /SWAP>)
;
;Here to turn /DDBS or /ORIGIN into new format /INFORMATION:(DDBS,ORIGIN)
;
	MOVX	T1,IFMDDBS##		;SETUP FOR DDBS
	SKIPL	T2,.FZDBS##(I)		;/DDBS GIVEN?
	 JRST	[IORM	T1,.FZINM##(I)	;YES--SET IT
		 CAIE	T2,0
		 IORM	T1,.FZINF##(I)
		 CAIN	T2,0
		 ANDCAM	T1,.FZINF##(I)
		 JRST	.+1]
	MOVX	T1,IFMORIGIN##		;SETUP FOR ORIGIN
	SKIPL	T2,.FZORI##(I)		;IS IT?
	 JRST	[IORM	T1,.FZINM##(I)	;YES--SET IT
		 CAIE	T2,0
		 IORM	T1,.FZINF##(I)
		 CAIN	T2,0
		 ANDCAM	T1,.FZINF##(I)
		 JRST	.+1]
;
;Here to fix up /ACTIVE into /STATE:ACTIVE
;
	MOVSI	T1,STATACTIVE##		;GET /STATE:ACTIVE
	SKIPL	.FZACT##(I)		;/[no]ACTIVE?
	 IORM	T1,.FZSTA##(I)		;YES--SET IN LH
	MOVEI	T1,STATACTIVE##		;GET /STATE:ACTIVE
	SKIPLE	T1,.FZACT##(I)		;/ACTIVE?
	 IORM	T1,.FZSTA##(I)		;YES--SET IN RH

IFN FTIPC,<
;
;Here to change /WHEEL into /PIVOT [1,2]
;
	SKIPL	T1,.FZWHL##(I)			;/WHEEL?
	 JRST	[CHKSWT	(PVT,PIVOT)	;YES--SET /PIVOT
		 MOVE	T1,OPRPPN##	;PPN IS [1,2]
		 CHKSWT	(PPN)
		 SETOM	.FZPPM(I)	;AND NOT WILD
		 JRST	.+1]		;CONTINUE
>
;
;Here to fix up /ACCOUNT string
;
	SETCM	T1,.FZACC##(I)		;SEE IF ACCOUNT GIVEN
	JUMPN	T1,[MOVEI T1,.FZACC##(I)	;POINT TO STRING
	    	    MOVEI T2,.FZATM##(I)	;AND MASK STORAGE
		    MOVEI T3,^D39		;LENGTH
		    PUSHJ P,MSKUC##		;GO MAKE MASK
		    JRST .+1]			
;
;All done with this spec
;
	POPJ	P,			;RETURN
	SUBTTL	Storage

	$LOW

	PRGEND
	TITLE	JOBGET - Get job information

	SEARCH	WHOMAC
	$SETUP	(JOBGET)

IFN	FTIPC,<SEARCH	TSGSYM>
;               TABLE OF CONTENTS FOR JOBGET
;
;
;                        SECTION                                   PAGE
;    1. Main JOB routines
;         1.1   JOBNXT - Get the next job.........................   3
;         1.2   JOBSET - Setup for a new job......................   4
;         1.3   JOBINC - Handle incremental statistics............   5
;         1.4   JOBSRT - Handle job sorting.......................   7
;    2. JOB tables
;         2.1   Define simple GETTABs required....................   8
;         2.2   Define all job subfields..........................   9
;         2.3   Routines to fetch all subfields...................  10
;    3. Subroutines
;         3.1   SEGSIZ - Compute jobs size........................  15
;         3.2   TK2MS - Convert ticks to milliseconds.............  16
;    4. DATA STORAGE..............................................  17
	SUBTTL	Main JOB routines -- JOBNXT - Get the next job

JOBNXT::JUMPL	O,JOBN.1		;JUMP IF THE FIRST TIME
	SKIPL	S.SORT##		;SEE IF /SORT
	 JRST	SRTNXT			;YES--GET NEXT JOB
	ADDI	O,1			;NO--BUMP TO NEXT
	CAMLE	O,MAXJOB		;SEE IF PAST END
	 POPJ	P,			;YES--RETURN
	JRST	JOBN.2			;NO--SETUP FOR THIS JOB

JOBN.1:	MOVX	T1,%NSHJB		;GET HIGHEST JOB IN USE
	PUSHJ	P,GTAB##		;FROM MONITOR
	MOVEM	T1,MAXJOB		;SAVE
	MOVEI	T1,^D10			;SET A HASH TABLE LENGTH
	MOVEI	T2,^D2			;AND SIZE OF ENTRY
	PUSHJ	P,.HASHI##		;INIT IT
	MOVEI	O,1			;START WITH JOB 1
	SKIPL	T1,S.SORT##		;GET /SORT
	 JRST	JOBSRT			;GO PROCESS IF GIVEN

JOBN.2:	PUSHJ	P,JOBSET		;SETUP FOR THIS JOB
	 JRST	JOBNXT			;NOT ASSIGNED
	JRST	.POPJ1##		;AND RETURN
	SUBTTL	Main JOB routines -- JOBSET - Setup for a new job

JOBSET::SKIPE	JP,JOBCOR		;SEE IF CORE ALLOCATED YET
	 JRST	JOBS.C			;YES
	MOVEI	T1,.JBLEN		;NO--GET SIZE
	PUSHJ	P,M$ALLOC##		;GET CORE
	MOVEM	T1,JOBCOR		;SAVE STARTING ADDRESS
	MOVEI	JP,(T1)			;AND INTO JP
JOBS.C:	HRLI	T1,(JP)			;GET STARTING ADDRESS
	HRRI	T1,1(JP)		;ENDING ADDRESS
	SETOM	(JP)			;SET FIRST WORD TO -1
	BLT	T1,.JBLEN-1(JP)		;AND SET THEM ALL TO -1
	PUSHJ	P,JG$STS		;GET JOB STATUS
	TXNN	T1,JS.JNA		;JOB NUMBER ASSIGNED?
	 POPJ	P,			;NO--RETURN
	PUSHJ	P,ZAPFUN##		;YES--CLEAR MAPPED PER PROCESS AREA
	SKPYES	S.INCREMENTAL##		;SEE IF /INCREMENTAL
	 JRST	.POPJ1##		;NO--RETURN NOW
	MOVSI	T1,-INCLEN+1		;GET LENGTH
	MOVEI	T2,-1(O)		;GET JOB INDEX
	IMULI	T2,INCLEN		;POINT TO BLOCK
	ADD	T2,INCINC		;ADD START OF TABLE
	ADDI	T2,1			;SKIP JLT INDEX
JOBS.1:	MOVEI	T3,@INCOFF(T1)		;GET OFFSET THIS FIELD
	MOVE	T4,(T2)			;GET COMPUTED INCREMENTAL VALUE
	SETZM	-1(T3)			;INDICATE WE GOT IT
	MOVEM	T4,(T3)			;STORE IT
	ADDI	T2,1			;ADVANCE TO NEXT
	AOBJN	T1,JOBS.1		;LOOP FOR ALL
	JRST	.POPJ1##		;AND RETURN
	SUBTTL	Main JOB routines -- JOBINC - Handle incremental statistics

JOBINC::PUSH	P,S.INCREMENTAL##	;SAVE /INCREMENTAL
	PUSH	P,S.SORT		;SAVE /SORT
	SETZM	S.INCREMENTAL##		;FAKE IT OFF FOR JOBSET
	SETOM	S.SORT			;..
	MOVNI	O,1			;FLAG FIRST TIME FOR JOBSET
	SKIPE	INCINC			;SEE IF CORE
	 JRST	JOBI.L			;YES
	PUSHJ	P,XB$JMX##		;GET JOBMAX
	IMULI	T1,INCLEN		;TIMES SIZE OF EACH
	PUSH	P,T1			;SAVE A MOMENT
	PUSHJ	P,C$ALLOC##		;ALLOCATE CORE
	MOVEM	T1,INCOLD		;SAVE ADDRESS
	POP	P,T1			;GET CORE BACK
	PUSHJ	P,C$ALLOC##		;ALLOCATE SOME MORE
	MOVEM	T1,INCINC		;SAVE
JOBI.L:	PUSHJ	P,JOBNXT		;GET A JOB
	 JRST	JOBI.E			;ALL DONE
	PUSHJ	P,JOBINJ		;HANDLE INCREMENTAL STUFF
	JRST	JOBI.L			;LOOP FOR ALL
JOBI.E:	POP	P,S.SORT		;RESTORE /SORT
	POP	P,S.INCREMENTAL##		;RESTORE /INCREMENTAL
	POPJ	P,			;YES--RETURN

JOBINJ:	PUSHJ	P,.SAVE3##		;SAVE P1-P3
	MOVEI	T1,-1(O)		;GET JOB NUMBER
	IMULI	T1,INCLEN		;TIME LENGHTH OF TABLE
	MOVSI	P1,-INCLEN+1		;GET AOBJN POINTER
	MOVE	P2,INCOLD		;GET ADDRESS OF TABLE
	ADDI	P2,1(T1)		;..
	MOVE	P3,INCINC		;GET ADDRESS OF TABLE
	ADDI	P3,1(T1)		;..
	PUSHJ	P,JB$JLT		;GET LOGGED IN TIME
	 CAME	T1,-1(P2)		;OR DIFFERENT JOB
	  JRST	JBI.N			;SETUP FOR NEW JOB
JBI.L:	PUSHJ	P,@INCGET(P1)		;GET CURRENT VALUE
	MOVE	T2,T1			;SAVE
	EXCH	T1,(P2)			;STORE OLD,,GET PREVIOUS OLD
	SUB	T2,T1			;COMPUTE CURRENT-OLD
	JUMPGE	T2,JBI.6		;JUMP IF POSITIVE
	MOVE	T3,INCGET(P1)		;GET DISPATCH
	CAIE	T3,JB$ITR		;INCREMENTAL RESET TIME?
	 JRST	JBI.6			;NO--OK FOR NEGATIVE
	PUSHJ	P,XB$UDT##		;GET NOW
	PUSH	P,T1			;SAVE IT
	PUSHJ	P,JB$STM		;GET RESET TIME
	POP	P,T2			;RESTORE NOW
	SUB	T2,T1			;MINUS RESET
JBI.6:	MOVEM	T2,(P3)			;STORE
	ADDI	P3,1			;ADVANCE TO NEXT BLOCK
	ADDI	P2,1			;ADVANCE TO NEXT BLOCK
	AOBJN	P1,JBI.L		;LOOP FOR ALL OFFSETS
	POPJ	P,			;AND RETURN

JBI.N:	MOVEM	T1,-1(P2)		;STORE JLT
JBI.5:	PUSHJ	P,@INCGET(P1)		;GET CURRENT VALUE
	MOVEM	T1,(P2)			;STORE AS OLD
	SETZM	(P3)			;CLEAR INCREMENTAL FIRST PASS
	ADDI	P3,1			;ADVANCE TO NEXT BLOCK
	ADDI	P2,1			;ADVANCE TO NEXT BLOCK
	AOBJN	P1,JBI.5		;LOOP FOR ALL OFFSETS
	POPJ	P,			;AND RETURN
DEFINE	INCS,<
X	BTL
X	IMR
X	IMS
X	UUC
X	TIM
X	KCM
X	VKM
X	DBR
X	DBW
X	IJL
X	ITR
>

DEFINE X(Z),<EXP JB$'Z>

INCGET:	INCS
INCLEN==.-INCGET+1

DEFINE X(Z),<.JB'Z(JP)>

INCOFF:	INCS
	SUBTTL	Main JOB routines -- JOBSRT - Handle job sorting

JOBSRT:	PUSHJ	P,.SAVE1##		;SAVE P1
	MOVEI	P1,(T1)			;SAVE SORT INDEX
	MOVE	T1,MAXJOB		;GET MAX JOBS
	IMULI	T1,2			;2 WORD TABLE
	MOVN	T2,T1			;NEGATE INTO T2
	HRLZM	T2,SRTTAB		;SAVE -N,,0
	PUSHJ	P,I$ALLOC##		;ALLOCATE CORE
	HRRM	T1,SRTTAB		;SAVE START
SRTJ.1:	PUSHJ	P,JOBSET		;SETUP FOR THIS JOB
	 JRST	SRTJ.2			;NOT ASSIGNED
	PUSHJ	P,@SUMLOD##(P1)		;GET SORT KEY
	MOVEI	T2,-1(O)		;GET JOB
	IMULI	T2,2			;DOUBLE
	ADD	T2,SRTTAB		;PLUS START OF TABLE
	MOVEM	T1,(T2)			;SAVE SORT KEY FIELD
	MOVEM	O,1(T2)			;SAVE JOB NUMBER
SRTJ.2:	ADDI	O,1			;BUMP TO NEXT JOB
	CAMG	O,MAXJOB		;ALL DONE?
	 JRST	SRTJ.1			;NO--ADVANCE TO NEXT
	MOVE	T1,SRTTAB		;GET AOBJN WORD
	MOVE	T2,[400000,,2]		;UNSIGNED AND STRAIGHT SORT
	SKIPLE	S.SORT##+1		;SEE IF DESCENDING
	 TLO	T2,200000		;YES-SET FLAG
	PUSHJ	P,.SORT2##		;SORT THE LIST
	MOVE	T1,SRTTAB		;GET AOBJN
	MOVEM	T1,SRTPTR		;SAVE
	SETZM	SRTCNT			;NO JOBS YET
	JRST	JOBNXT			;AND BACK TO THE TOP


SRTNXT:	SKIPL	T1,SRTPTR		;GET POINTER
	 POPJ	P,			;ALL DONE
	SKIPN	O,1(T1)			;GET JOB NUMBER
	 JRST	SRTN.1			;NONE
	PUSHJ	P,JOBSET		;SETUP FOR THIS JOB
	 JRST	SRTN.1			;NOT ASSIGNED NOW?
	AOS	T1,SRTCNT		;COUNT THE JOBS
	CAMLE	T1,S.SORT##+2		;IN RANGE?
	 POPJ	P,			;NO--STOP NOW
	MOVE	T1,[2,,2]		;ADVANCE POINTER
	ADDM	T1,SRTPTR		;TO NEXT PAIR
	JRST	.POPJ1##		;AND USE THAT J

SRTN.1:	MOVE	T1,[2,,2]		;ADVANCE POINTER
	ADDM	T1,SRTPTR		;TO NEXT PAIR
	JRST	SRTNXT			;AND GET NEXT
	SUBTTL	JOB tables -- Define simple GETTABs required

DEFINE JGET(LST),<
    XLIST
    IRP LST,<
	JG%'LST==.JBLEN		;;Define flag word
	.JG'LST==.JBLEN+1		;;And data word
	.JBLEN==.JBLEN+2
	JG$'LST:AOSN	T1,JG%'LST(JP)	;;We already have this GETTAB?
		  JRST	JG1'LST	;;No--Get it now
		 MOVE	T1,.JG'LST(JP)	;;Yes--Return its value
		 POPJ	P,		;;And return
	JG1'LST:MOVEI	T1,.GT'LST	;;Get the desired GETTAB table
		 PUSHJ	P,JTAB##	;;Fetch for the current job
		 MOVEM	T1,.JG'LST(JP)	;;Store for later
		 POPJ	P,		;;And return
    >;END IRP
    LIST
>;END DEFINE

	.JBLEN==0

JGET	<PRV,STS,ST2,SWP,SGN,ADR,PPN,PRG,TIM,KCT,RCT,WCT,NM1,NM2,IPP>
JGET	<UUC,VKS,JLT,VRT,PC,DDB,IPA,LOC,SPL,RTD,TTY,LIM,JTC,PDB,SPS,IPQ>
JGET	<OBI,DFL,CAP,CVL,MVL,WCH,LBS,STM,PTR>

IFN FTIPC,<JGET<PRF,LPN,CID,BDG>>
IFN FTMDC,<JGET<MDC>>
	SUBTTL	JOB tables -- Define all job subfields

;This macro fetches a sub-field about the job. If the field has been
;gotten before, it simply returns the known field. If the field has
;not been gotten before, it it derived/computed, stored for later
;use, and returned.
;
;In all cases, the field will be returned in T1, and set in table
;.JBxxx (flag JB%xxx indicates if the field has been gotten)

DEFINE	JB$(X,N<1>),<
   XLIST
	JB%'X==.JBLEN			;;FLAG WORD
	.JB'X==.JBLEN+1			;;DATA WORD
	.JBLEN==.JBLEN+2
IFG N-1,.JBLEN==.JBLEN+N
	JB$'X::	AOSN	JB%'X(JP)	;;DO WE HAVE THE INFO?
		 JRST	JB1'X		;;NO--GO GET IT
		MOVE	T1,.JB'X(JP)	;;YES--JUST GET IT NOW
		POPJ	P,		;;AND RETURN
	JB1'X:				;;(HERE TO GET INFO)
   DEFINE END$,<
	XLIST
	MOVEM	T1,.JB'X(JP)		;STORE
	POPJ	P,			;AND RETURN
	LIST
   >
   LIST
>;END DEFINE

;This macro is a trivial case of JB$(xxx). The information is simply
;from a GETTAB table, and a dispatch to fetch that GETTAB table entry
;is made, if needed. 
;
;Again, in all cases, the field will be returned in T1, and set in table
;.JBxxx (flag JB%xxx indicates if the field has been gotten)

DEFINE	JB$$(X),<
	JB$'X==:JG$'X
	.JB'X==.JG'X
	JB%'X==JG%'X
>

;This macro fetches a sub-field about the job. If the field has been
;gotten before, it simply returns the known field. If the field has
;not been gotten before, it it derived/computed, stored for later
;use, and returned.
;
;In all cases, the field will be returned in T1, and set in table
;.JXxxx (flag JX%xxx indicates if the field has been gotten)

DEFINE	JX$(X),<
   XLIST
	JX%'X==.JBLEN			;;FLAG WORD
	.JX'X==.JBLEN+1			;;DATA WORD
	.JBLEN==.JBLEN+2
	JX$'X::	AOSN	JX%'X(JP)	;;DO WE HAVE THE INFO?
		 JRST	JX1'X		;;NO--GO GET IT
		MOVE	T1,.JX'X(JP)	;;YES--JUST GET IT NOW
		POPJ	P,		;;AND RETURN
	JX1'X:				;;(HERE TO GET INFO)
   DEFINE END$,<
	MOVEM	T1,.JX'X(JP)		;STORE
	POPJ	P,			;AND RETURN
   >
   LIST
>;END DEFINE
	SUBTTL	JOB tables -- Routines to fetch all subfields

JB$(JOB)	;JOB NUMBER
	MOVE	T1,O			;GET JOB NUMBER
	END$

JB$(BJB)	;BATCH JOB BIT
	PUSHJ	P,JG$LIM		;GET BATCH/TIME INFO
	LOAD	T1,T1,JB.LBT		;GET BATCH BIT
	END$

JB$(BBB)	;BACKGROUND BATCH BIT
	MOVE	T1,STATE2##		;GET SECOND STATES WORD
	TXNN	T1,ST%SHC		;HAVE CLASSES (FTNSCH?)
	 JRST	BBB.1			;NO--NEVER BBATCH THEN
	PUSHJ	P,JB$CLS		;GET SCHEDULAR CLASS
	PUSH	P,T1			;SAVE IT
	PUSHJ	P,XB$BBQ##		;GET BACKGROUND BATCH
	POP	P,T2			;RESTORE CLASS
	CAME	T1,T2			;MATCH?
BBB.1:	 TDZA	T1,T1			;NO--LOAD 0
	  MOVEI	T1,1			;YES--LOAD 1
	END$

JB$(FSB)	;FROM SYS BIT
	PUSHJ	P,JG$LIM		;GET BATCH/TIME INFO
	LOAD	T1,T1,JB.LSY		;GET SYS BIT
	END$

JB$(BTL)	;BATCH TIME LIMIT (MILLISECONDS)
	PUSHJ	P,JG$LIM		;GET BATCH/TIME INFO
	LOAD	T1,T1,JB.LTM		;GET TIME LIMIT
	PUSHJ	P,TK2MS			;TICKS TO MILLISECONDS
	END$

JB$(BCL)	;BATCH CORE LIMIT
	PUSHJ	P,JG$DDB		;GET INFO
	LOAD	T1,T1,JD.LCR		;GET CORE LIMIT
	END$

JB$(CJN)	;CONTROLLING JOB NUMBER
	MOVEI	T1,(O)			;COPY JOB NUMBER
	PUSHJ	P,UCTLJOB##		;FIND CONTROLLING JOB
	 MOVEI	T1,0			;FAILED
	CAIGE	T1,0			;SEE IF SELF
	 MOVEI	T1,0			;YES--INDICATE NONE
	END$

JB$(CPN)	;CONTROLLING PROGRAM NAME
	PUSHJ	P,JB$CJN		;GET CONTROLLING JOB NUMBER
	JUMPE	T1,CPN.1		;NONE
	MOVSI	T1,(T1)			;POSITION JOB FOR GETTAB
	HRRI	T1,.GTPRG		;INCLUDE PROGRAM 
	PUSHJ	P,GTAB##		;FIND ITS NAME
CPN.1:	END$

JB$$(LOC)	;JOBS LOCATION

JB$$(SPL)	;JOBS SPOOL WORD

JB$$(SPS)	;SECOND PROCESSOR STATUS

JB$$(SGN)	;HIGH SEGMENT NUMBER

IFN FTIPC,<
JB$$(CID)	;CHARGE ID

JB$$(BDG)	;DEC BADGE NUMBER
>;END IFN FTIPC

JB$(CNO)	;CHARGE NUMBER
	MOVEI	T1,.GTCNO		;GETTAB TABLE
	TLNN	F,(FL.CHARGE)		;HAVE CHARGE NUMBER SUPPORT?
	TDZA	T1,T1			;NO--RETURN ZERO
	PUSHJ	P,JTAB##		;GET CHARGE NUMBER
	END$

JB$(HPQ)	;JOBS HPQ VALUE
	PUSHJ	P,JG$RTD		;GET REAL TIME WORD
	LOAD	T1,T1,JS.HPQ		;GET HPQ VALUE
	END$

JB$(DPR)	;JOBS DISK PRIORITY
	PUSHJ	P,JG$SPL		;GET SPOOL INFO WORD
	LOAD	T1,T1,JS.PRI		;GET DISK PRIORITY VALUE
	TRZE	T1,4			;CLEAR "SIGN" BIT
	 MOVNS	T1			;SET--NEGATE
	END$

JB$(CLS)	;JOBS SCHEDULAR CLASS
	PUSHJ	P,JG$JTC		;GET SCHEDULAR INFO
	LOAD	T1,T1,JS.CLS		;GET JOBS CLASS
	END$

IFN FTIPC,<
JB$(SLT)	;JOBS DISTRIBUTION SLOT
	PUSHJ	P,JG$PRF		;GET LOCAL PROFILE WORD
	LOAD	T1,T1,PF%LOC		;GET SLOT
	END$

JB$(CAT)	;JOBS LOGIN CATEGORY
	PUSHJ	P,JG$PRF		;GET LOCAL PROFILE WORD
	LOAD	T1,T1,PF%CAT		;GET CATEGORY
	END$
>

IFN FTMDC,<
JB$(STP)	;SETP BIT
	PUSHJ	P,JG$MDC		;GET MDC STATUS WORD
	LOAD	T1,T1,MS.STP		;LOAD THE BIT
	END$
>;END IFN FTMDC

JB$(IMR)	;IPCF MESSAGES RECEIVED
	PUSHJ	P,JG$IPA		;GET IPCF STATISTICS
	LOAD	T1,T1,IP.CQC		;GET COUNT OF RECEIVES
	END$

JB$(IMS)	;IPCF MESSAGES SENT
	PUSHJ	P,JG$IPA		;GET IPCF STATISTICS
	LOAD	T1,T1,IP.CQD		;GET COUNT OF SENDS
	END$

JB$(IOR)	;IPCF OUTSTANDING RECEIVES
	PUSHJ	P,JG$IPP		;GET IPCF COUNTS
	LOAD	T1,T1,IP.CQO		;GET OUTSTANDING RECEIVES
	END$

JB$(IOS)	;IPCF OUTSTANDING SENDS
	PUSHJ	P,JG$IPP		;GET IPCF COUNTS
	LOAD	T1,T1,IP.CQP		;GET OUTSTANDING SENDS
	END$

JB$(IQR)	;IPCF QUOTAS (RECEIVE)
	PUSHJ	P,JG$IPQ		;GET IPCF QUOTAS
	TXNN	T1,IP.CQQ		;QUOTA SET?
	 HRR	T1,IPCFQT##		;NO--USE DEFAULT
	LOAD	T1,T1,IP.CQR		;GET RECIEVE QUOTA
	END$

JB$(IQS)	;IPCF QUOTAS (SEND)
	PUSHJ	P,JG$IPQ		;GET IPCF QUOTAS
	TXNN	T1,IP.CQQ		;QUOTA SET?
	 HRR	T1,IPCFQT##		;NO--USE DEFAULT
	LOAD	T1,T1,IP.CQS		;GET SEND QUOTA
	END$

JB$(IPP)	;IPCF PRIVILEGED PROCESS
	PUSHJ	P,JG$PRV		;GET PRIVS
	LOAD	T1,T1,JP.IPC		;THE IPCF PRIV BIT
	END$

JB$(IDP)	;IPCF DISABLED PROCESS
	PUSHJ	P,JG$IPQ		;GET IPCF STUFF
	LOAD	T1,T1,IP.CQX		;GET DISABLED BIT
	END$

JB$(DDB)	;JOBS I/O ACTIVE DDB
	PUSHJ	P,JG$DDB		;GET WORD
	LOAD	T1,T1,JD.DDB		;EXTRACT DDB ADDRESS
	END$

JB$$(PC)	;JOBS PROGRAM COUNTER

JB$$(STS)	;JOBS STATUS WORD

JB$$(PRV)	;JOBS PRIVILEGE WORD

JB$$(CAP)	;JOBS CAPABILITY WORD

JB$$(ST2)	;JOBS SECOND STATUS WORD

JB$$(PPN)	;JOBS PROJECT-PROGRAMMER NUMBER

JB$$(WCH)	;JOBS WATCH WORD

IFN FTIPC,<
JB$(LPN)	;JOBS LOGGED IN PROJECT-PROGRAMMER NUMMBER
	PUSHJ	P,JG$LPN		;GET LOGGED IN PPN
	CAIN	T1,0			;ZERO?
	 PUSHJ	P,JG$PPN		;YES--SETTLE FOR PPN
	END$
>

JB$$(PRG)	;JOBS PROGRAM NAME

JB$$(UUC)	;UUO COUNTS


JB$(TIM)	;JOBS RUNTIME (MILLISECONDS)
	PUSHJ	P,JG$TIM		;GET RUNTIMES IN TICKS
	PUSHJ	P,TK2MS			;CONVERT TO MILLISECONDS
	END$

JB$(KCM)	;KILO-CORE-MILLISECONDS
	PUSHJ	P,JG$KCT		;GET KILO-CORE TICKS
	PUSHJ	P,TK2MS			;CONVERT TO MILLISECONDS
	END$

JB$(VKM)	;VIRTUAL-KILO-CORE-MILLISECONDS
	PUSHJ	P,JG$VKS		;GET VIRTUAL-KILO-CORE-TICKS
	PUSHJ	P,TK2MS			;CONVERT TO MILLISECONDS
	END$

JB$(DBR)	;DISK BLOCKS READ
	PUSHJ	P,JG$RCT		;GET DISK BLOCKS READ
	LOAD	T1,T1,RC.TTL		;GET TOTAL READS
	END$

JB$(DBW)	;DISK BLOCKS WRITTEN
	PUSHJ	P,JG$WCT		;GET DISK BLOCKS WRITTEN
	LOAD	T1,T1,RC.TTL		;GET TOTAL WRITES
	END$

JB$$(JLT)	;JOB LOGGED IN TIME (NBS)

JB$(IJL)	;INCREMENTAL JOB LOGGED IN TIME (NBS)
	PUSHJ	P,JG$JLT		;GET LOGGED IN TIME
	PUSH	P,T1			;SAVE
	PUSHJ	P,XB$UDT##		;GET NOW
	POP	P,T2			;RESTORE JLT
	SUB	T1,T2			;COPUTE INCREMENTAL TIME
	CAIGE	T1,0			;.GE. 0?
	 MOVEI	T1,0			;NO--DONT LET IT BE NEGATIVE
	END$

JB$$(STM)	;TIME OF LAST RESET (NBS)

JB$(ITR)	;INCREMENTAL TIME OF RESET (NBS)
	PUSHJ	P,JG$STM		;GET TIME OF RESET
	PUSH	P,T1			;SAVE IT
	PUSHJ	P,XB$UDT##		;GET NOW
	POP	P,T2			;RESTORE TIME OF RESET
	SUB	T1,T2			;COMPUTE INCREMENTAL TIME
	CAIGE	T1,0			;.GE. 0?
	 MOVEI	T1,0			;NO--DONT LET IT BE NEGATIVE
	END$

JB$$(PTR)	;PROGRAM TO RUN

JB$(HSN)	;HIGH SEGMENT NAME
	PUSHJ	P,JG$SGN		;GET HIGH SEGMENT NUMBER
	JUMPE	T1,HSN.9		;JUMP IF NONE
	JUMPL	T1,HSN.1		;JUMP IF SPYING
	MOVSI	T1,(T1)			;POSITION SEGMENT NUMBER
	HRRI	T1,.GTPRG		;INCLUDE GETTAB TABLE
	PUSHJ	P,GTAB##
	JUMPN	T1,HSN.9		;JUMP IF IT EXISTS
	MOVX	T1,SG.SHR		;SEE IF SHARABLE
	TDNE	T1,.JGSGN(JP)		;TEST
	 SKIPA	T1,[SIXBIT/(OLD)/]	;YES--MUST BE OLD SEGMENT
	  MOVE	T1,[SIXBIT/(PRIV)/]	;NO--MUST BE PRIVATE SEGMENT
	JRST	HSN.9			;AND STORE
HSN.1:	MOVSI	T1,'SPY'		;FLAG SPY SEGMENT
HSN.9:	END$

JB$(CVL)	;CURRENT VIRTUAL LIMIT
	PUSHJ	P,JG$CVL		;GET CURRENT LIMITS
	HLRZS	T1			;GET LH
	END$

JB$(CPL)	;CURRENT PHYSICAL LIMIT
	PUSHJ	P,JG$CVL		;GET CURRENT LIMITS
	HRRZS	T1			;GET RH
	TRZ	T1,400000		;CLEAR LIMIT BIT
	END$

JB$(MVL)	;MAXIMUM VIRTUAL LIMIT
	PUSHJ	P,JG$MVL		;GET MAXIMUM LIMITS
	HLRZS	T1			;GET LH
	END$

JB$(MPL)	;MAXIMUM PHYSICAL LIMIT
	PUSHJ	P,JG$MVL		;GET MAXIMUM LIMITS
	HRRZS	T1			;GET RH
	END$

JB$(PPL)	;PAGES PHYSICAL LOW SEGMENT SIZE
	MOVEI	T1,(O)			;GET JOB NUMBER
	PUSHJ	P,SEGSIZ		;COMPUTE LOW SEG SIZE
	END$

JB$(PPH)	;PAGES PHYSICAL HIGH SEGMENT SIZE
	PUSHJ	P,JG$SGN		;GET REAL SEGMENT NUMBER
	JUMPLE	T1,PPH.1		;JUMP IF NONE
	PUSHJ	P,SEGSIZ		;COMPUTE SEGMENT SIZE
	JRST	PPH.2			;AND RETURN
PPH.1:	MOVEI	T1,0			;INDICATE NULL
PPH.2:	END$

JB$(PVL)	;PAGES VIRTUAL LOW SEGMENT SIZE
	PUSHJ	P,JG$VRT		;GET VIRTUAL STUFF
	LOAD	T1,T1,JS.LOW		;GET LOW SEG SIZE
	END$

JB$(PVH)	;PAGES VIRTUAL HIGH SEGMENT SIZE
	PUSHJ	P,JG$VRT		;GET VIRTUAL STUFF
	LOAD	T1,T1,JS.HGH		;GET HIGH SEG SIZE
	END$

JB$(PFS)	;PAGES FUNNY SPACE
	PUSHJ	P,JG$PDB		;GET FUNNY,,PDB ADDR
	LOAD	T1,T1,JS.FUN		;GET PAGES OF FUNNY SPACE
	END$

JB$(OVP)	;OVERHEAD PAGES
	MOVEI	T1,.GTIMI		;NOW GET IMAGE IN
	PUSHJ	P,JTAB##		; FOR THE JOB
	LOAD	T1,T1,JS.SMP		;GET NUMBER OF SECTION MAPS
	PUSH	P,T1			;SAVE
	PUSHJ	P,JB$PFS		;GET PAGES OF FUNNY SPACE
	POP	P,T2			;GET NUMBER OF SECTION MAPS BACK
	ADDI	T1,(T2)			;ADD FUNNY PAGES
	END$

JB$(PGR)	;PAGING RATE
	PUSHJ	P,JG$VRT		;GET VIRTUAL STUFF
	LOAD	T3,T1,JS.PGR		;GET PAGING RATE
	JUMPE	T3,PGR.1		;LEAVE ZERO ALONE
	MOVEI	T1,^D100000		;GET TIME UNITS
	IDIVI	T1,(T3)			;COMPUTE PAGING RATE
	IMULI	T2,^D100
	IDIVI	T2,(T3)			;THIS IS WHAT COMCON DOES!
	IMULI	T1,^D100		;COMPUTE RATE*100
	ADDI	T1,(T2)			;ADD FRACTION
	JRST	PGR.2			;AND STORE
PGR.1:	MOVEI	T1,0			;CLEAR
PGR.2:	END$

JB$(NM1)	;USER NAME (FIRST HALF)
	PUSHJ	P,JB$NAM		;GET NAME
	MOVE	T1,(T1)			;GET FIRST PART
	END$

;JB$(NM2)	;USER NAME (SECOND HALF)
;	PUSHJ	P,JB$NAM		;GET NAME
;	MOVE	T1,1(T1)		;GET SECOND PART
;	END$

JB$(AC1)	;ACCOUNT STRING (FIRST WORD)
	PUSHJ	P,JB$ACC		;GET ACCOUNT STRING
	MOVE	T1,(T1)			;GET FIRST WORD
	END$

JB$(APC)	;ASYNC PORT CHARACTERISTICS
	PUSHJ	P,JB$TLN		;GET TERMINAL NUMBER
	JUMPL	T1,APC.1		;DETACHED
	MOVEI	T2,.UXTRM(T1)		;GET UDX
	MOVEI	T1,.TOAPC		;FUNCTION CODE
	PUSHJ	P,UTRMOP##		;READ IT
APC.1:	  MOVEI	T1,.TOUNK		;FAILED
APC.E:	END$


JB$(RMT)	;REMOTE TERMINAL BIT
	PUSHJ	P,JX$GLC		;GET LINE CHARACTERISTICS
	LOAD	T1,T1,GL.REM		;GET REMOTE BIT
	END$

JB$(TLN)	;TERMINAL LINE NUMBER
	MOVEI	T1,(O)			;COPY JOB NUMBER
	PUSHJ	P,UTRMNO##		;CONVERT TO LINE NUMBER
	 SKIPA	T1,[-1]			;DETACHED--FLAG -1
	  SUBI	T1,.UXTRM		;REMOVE UDX OFFSET
	END$

JB$(NLN)	;NETWORD LINE NUMBER
	PUSHJ	P,JB$NRT		;GET NRTSER STUFF
	SKIPE	.NRTFL(T1)		;A NRTSER LINE?
	JRST	NLN.1			;YES
	PUSHJ	P,JX$NNL		;GET NODE AND LINE
	CAIGE	T1,0			;SEE IF DETACHED
	 TDZA	T1,T1			;YES--LOAD ZERO
	  LOAD	T1,T1,GX.LIN		;NO--GET LINE NUMBER
	JRST	NLN.E			;DONE
NLN.1:	MOVE	T1,.NRTCH(T1)		;GET DECNET CHANNEL NUMBER
NLN.E:	END$

JB$(NNU)	;NETWORK NODE NUMBER
	PUSHJ	P,JB$NRT		;GET NRTSER STUFF
	SKIPE	.NRTFL(T1)		;A NRTSER LINE?
	JRST	NNU.1			;YES
	PUSHJ	P,JX$NNL		;GET NODE AND LINE
	CAIGE	T1,0			;SEE IF DETACHED
	 TDZA	T1,T1			;YES--LOAD ZERO
	  LOAD	T1,T1,GX.NOD		;NO--GET NODE NUMBER
	JRST	NNU.E			;DONE
NNU.1:	MOVE	T1,.NRTNN(T1)		;GET DECNET NODE NUMBER
NNU.E:	END$

JB$(NNM)	;NETWORK NODE NAME
	PUSHJ	P,JB$NRT		;GET NRTSER STUFF
	SKIPE	.NRTFL(T1)		;A NRTSER LINE?
	JRST	NNM.2			;YES
	PUSHJ	P,JB$TLN		;GET LINE NUMBER
	JUMPL	T1,NNM.1		;DETACHED?
	MOVE	T2,T1			;SAVE IT
	PUSHJ	P,JB$NNU		;GET NODE NUMBER
	CAIE	T1,0			;SEE IF KNOWN
	 PUSHJ	P,ANODE##		;YES--CONVERT TO NAME
NNM.1:	  MOVEI	T1,0			;FAILED?
	JRST	NNM.E			;DONE
NNM.2:	MOVE	T1,.NRTNM(T1)		;GET DECNET NODE NAME
NNM.E:	END$

JB$(NRT,.NRTLN+1)	;NRTSER NODE NAME, NUMBER, AND CHANNEL
	PUSHJ	P,JB$TLN		;GET LINE NUMBER
	SKIPGE	T2,T1			;COPY LINE NUMBER
	JRST	NRT.1			;DETACHED
	MOVEI	T1,.JBNRT+1(JP)		;POINT TO STORAGE
	PUSHJ	P,NRTINF##		;GET NRTSER STUFF
NRT.1:	  SETZM	.JBNRT+.NRTFL+1(JP)	;NOT A NRTSER LINE
	MOVEI	T1,.JBNRT+1(JP)		;POINT TO STORAGE
	END$


JB$(TTY)	;TERMINAL NAME
	PUSHJ	P,JB$TLN		;GET TERMINAL LINE NUMBER
	PUSHJ	P,TTYNAM##		;GET SIXBIT TERMINAL NAME
	END$

JB$(PPG)	;PROGRAMMER NUMBER
	PUSHJ	P,JB$PPN		;GET PPN
	TLZ	T1,-1			;MASK TO PROGRAMMER
	END$

JB$(PPJ)	;PROJECT NUMBER
	PUSHJ	P,JB$PPN		;GET PPN
	HLRZ	T1,T1			;EXTRACT PROJECT
	END$

IFN FTIPC,<
JB$(LPG)	;LOGGED IN PROGRAMMER NUMBER
	PUSHJ	P,JB$LPN		;GET LPN
	TLZ	T1,-1			;MASK TO PROGRAMMER
	END$

JB$(LPJ)	;LOGGED IN PROJECT NUMBER
	PUSHJ	P,JB$LPN		;GET LPN
	HLRZ	T1,T1			;EXTRACT PROJECT
	END$
>;END IFN FTIPC

JB$(ACC,10)	;ACCOUNT STRING
	MOVEI	T1,.JBACC+1(JP)		;GET ADDRESS OF ACCOUNT STRING
	PUSHJ	P,UACCT##		;READ THE ACCOUNT STRING
	MOVEI	T1,.JBACC+1(JP)		;POINT TO NAME
	END$

JB$(WTO)	;WTO PRIVS
	PUSHJ	P,JG$OBI		;GET OPERATOR/BATCH INFO
	LOAD	T1,T1,OB.WTO		;LOAD WTO PRIVS
	END$

JB$(GOP)	;GALAXY OPR PRIVS
	PUSHJ	P,JG$OBI		;GET OPERATOR/BATCH INFO
	LOAD	T1,T1,OB.OPR		;LOAD OPR PRIVS
	END$

JB$(BSN)	;BATCH STREAM NUMBER
	PUSHJ	P,JG$OBI		;GET OPERATOR/BATCH INFO
	TXNN	T1,OB.BSS		;SET?
	 SKIPA	T1,[-1]			;NO--LOAD -1
	  LOAD	T1,T1,OB.BSN		;YES--GET STREAM
	END$

JB$(DNB)	;DEFAULT NUMBER OF BUFFERS
	PUSHJ	P,JG$DFL		;GET DEFAULTS
	LOAD	T1,T1,JD.BUF		;GET NUMBER OF BUFFERS
	END$

JB$(DBB)	;DEFAULT BIGBUF
	PUSHJ	P,JG$LBS		;GET BIGBUF WORD
	LOAD	T2,T1,LB.PGM		;GET SET BY PROGRAM
	SKIPN	T2			;OK IF NON-ZERO
	LOAD	T2,T1,LB.CMD		;ELSE GET SET BY COMMAND
	MOVE	T1,T2			;INTO T1
	LSH	T1,-7			;INTO BLOCKS
	END$

JB$(DPS)	;DEFAULT PROTECTION SET
	PUSHJ	P,JG$DFL		;GET DEFAULTS
	LOAD	T1,T1,JD.SDP		;GET PROTRECTION SET BIT
	END$

JB$(DPV)	;DEFAULT PROTECTION VALUE
	PUSHJ	P,JG$DFL		;GET DEFAULTS
	LOAD	T1,T1,JD.PRT		;GET PROTECTION VALUE
	END$

JB$(DAD)	;DEFAULT DONT ASK ABOUT DETACHED JOBS
	PUSHJ	P,JG$DFL		;GET DEFAULTS
	LOAD	T1,T1,JD.DAD		;GET DONT ASK BIT
	END$

JB$(DDT)	;ORIGIN OF DDT
	PUSHJ	P,JOBDDT##		;GET DDT ADDRESS
	END$

JB$(BPT)	;UNSOLICITED BREAKPOINT ADDRESS
	PUSHJ	P,JOBBPT##		;GET BPT ADDRESS
	END$

JB$(PFH)	;ORIGIN OF PFH
	PUSHJ	P,JOBPFH##		;GET PFH ADDRESS
	END$
;BLANK NAMES DEFAULTS TO "HELP", AND LEADING SPACES ARE REMOVED
;IF /FLOAT IS SPECIFIED, MULTIPLE SPACES ARE CONVERTED INTO A
;SINGLE DASH


JB$(NAM,2)
	PUSHJ	P,.SAVE2##		;SAVE P1-P2
	PUSHJ	P,JG$NM1		;GET FIRST HALF
	MOVE	P1,T1			;SAVE FIRST HALF
	PUSHJ	P,JG$NM2		;GET SECOND HALF
	SKIPN	P2,T1			;SAVE SECOND HALF
	 JUMPE	P1,GETN.1		;USE "HELP" IF BOTH BLANK
GETN.2:	TLNE	P1,770000		;FIRST CHAR BLANK?
	 JRST	GETN.3			;NO--ALL SET
	LSHC	P1,6			;YES--STRIP OFF
	JRST	GETN.2			;AND LOOP
GETN.3:	MOVE	T1,S.DFORMAT##		;GET /FORMAT
	CAIE	T1,FORFLOAT##		;SEE IF /FORMAT:FLOAT
	 JRST	GETN.4			;NO--GO STORE
	MOVE	T1,[POINT 6,.JBNAM+1(JP)]	;SETUP POINTER TO STORAGE
	SETZB	T3,.JBNAM+1(JP)		;CLEAR SPACE COUNTER,NAME
	SETZM	.JBNAM+2(JP)		;CLEAR SECOND HALF
GETN.6:	JUMPE	P1,GETN.E		;RETURN IF DONE
	LDB	T2,[POINT 6,P1,5]	;GET A CHAR
	CAIN	T2,' '			;SPACE?
	 AOJA	T3,GETN.7		;YES--COUNT AND LOOP
	JUMPE	T3,GETN.8		;NO--JUMP IF NONE BEFORE
	MOVEI	T3,'-'			;SOME BEFORE
	IDPB	T3,T1			;SO STORE A DASH
	MOVEI	T3,0			;AND CLEAR COUNTER
GETN.8:	IDPB	T2,T1			;STORE THE CHAR
GETN.7:	LSHC	P1,6			;GET NEXT CHAR
	JRST	GETN.6			;AND LOOP

GETN.1:	PUSHJ	P,JG$STS		;GET JOB STATUS
	TXNN	T1,JS.LOG		;LOGGED IN?
	 SKIPA	P1,[SIXBIT/HELP/]	;NO--HELP
	  MOVE	P1,[SIXBIT/GUEST/]	;YES--GUEST
	MOVEI	P2,0			;CLEAR SECOND HALF
GETN.4:	DMOVEM	P1,.JBNAM+1(JP)		;STORE NAME
GETN.E:	MOVEI	T1,.JBNAM+1(JP)		;POINT TO NAME
	END$
JB$(WSC)	;SIXBIT JOB STATE CODE
	PUSHJ	P,.SAVE3##
	PUSHJ	P,JB$STS		;GET JOB STATUS
	MOVE	P1,T1			;INTO P1
	PUSHJ	P,JB$ST2		;GET SECOND JOB STATUS
	MOVE	P2,T1			;INTO P2
	TXNN	P1,JS.RUN		;RUNNING?
	 JRST	ANL.CC			;NO--CHECK ^C BITS
	MOVEI	P3,'RU'			;ASSUME IN RUN UUO OR COMMAND
	TXNE	P1,JS.RUU		;ARE WE?
	 JRST	GETS.3			;YES
	MOVEI	P3,'GU'			;ASSUME IN GETSEG OR MERGE
	TXNE	P2,J2.IGS		;ARE WE?
	 JRST	GETS.3			;YES
	LOAD	T1,P1,JS.COD		;GET WAIT STATE CODE
	IDIVI	T1,3			;POSITION TO WORD
	PUSH	P,T2			;SAVE INDEX
	MOVSI	T1,(T1)			;POSITION OVER
	HRRI	T1,.GTWSN		;GETTAB FOR WAIT STATE CODES
	PUSHJ	P,GTAB##		;GET IT
	POP	P,T2			;RESTORE INDEX
	LDB	P3,[POINT 12,T1,11	;GET SIXBIT NAME
		    POINT 12,T1,23
		    POINT 12,T1,35](T2)
	CAIN	P3,'EW'			;EVENT WAIT?
	 JRST	ANL.EW			;YES
	CAIN	P3,'SL'			;SLEEP?
	 JRST	ANL.SL			;YES
	CAIN	P3,'RN'			;RUNNING?
	 JRST	ANL.RN			;YES
	CAIN	P3,'IO'			;IO WAIT?
	 JRST	ANL.IO			;YES
	CAIN	P3,'DI'			;DISK I/O WAIT?
	 JRST	ANL.DI			;YES
	CAIN	P3,'TI'			;TTY I/O WAIT?
	 JRST	ANL.TI			;YES
GETS.3:	LSH	P3,^D6*4		;LEFT JUSTIFY
	TXNE	P1,JS.SWP		;SWAPED?
	 PUSHJ	P,ANL.SW		;YES--CHECK
	TXNE	P1,JS.NSW		;NEVER SWAP (IE LOCKED)?
	 HRRI	P3,'LK '		;YES--FLAG
	PUSHJ	P,ANYCPU##		;SEE IF ON ANY CPU
	 TLO	P3,'  *'		;YES--FLAG RUNNING
	MOVE	T1,P3			;COPY INTO T1
	END$


ANL.SL:	TXNN	P2,J2.HIB		;IN A HIBER?
	 JRST	GETS.3			;NO--MUST BE SLEEP
	MOVEI	P3,'HB'			;YES--MAKE HIBER
	TXNE	P1,JS.CLK		;CLOCK REQUEST IN?
	 MOVEI	P3,'HS'			;YES--HIBER WITH SLEEP TIME
	JRST	GETS.3

ANL.TI:	TLNN	F,(FL.SPY)		;CAN WE SPY?
	 JRST	ANLTI1			;NO--JOBSTS FOR TO CHECK
	MOVE	T1,[SIXBIT/TITOTW/]	;CODES TO USE
	PUSHJ	P,GETTIO##		;CHOOSE THE RIGHT ONE
	MOVE	P3,T1			;INTO P3
	JRST	ANL.TO			;AND CHECK FOR ^S
ANLTI1:	MOVNI	T1,(O)			;GET JOB NUMBER
	PUSHJ	P,UJOBSTS##		;DO JOBSTS UUO
	 MOVEI	T1,0			;CLEAR RESULT
	MOVE	T2,T1			;SAVE RESULT
	MOVEI	P3,'TI'			;ASSME 'TI'
	TXNE	T2,JB.UTO		;OUTPUT AVAILABLE?
	 MOVEI	P3,'TO'			;YES--MAKE'TO'
ANL.TO:	CAIE	P3,'TO'			;TO?
	 JRST	GETS.3			;NO--RETURN
	PUSHJ	P,JB$TLN		;YES--GET LINE NUMBER
	JUMPL	T1,GETS.3		;DETACHED
	MOVEI	T2,.UXTRM(T1)		;FORM UDX
	MOVEI	T1,.TOSTP		;^S READ TRMOP
	PUSHJ	P,UTRMOP##		;READ IT
	 MOVEI	T1,0			;FAILED
	JUMPE	T1,GETS.3		;NOT ^S
	MOVEI	P3,'^S'			;^S ed
	JRST	GETS.3			;AND STORE

ANL.IO:	SKIPA	T1,[SIXBIT/WIWOIO/]	;CODES TO USE FOR IO
ANL.DI:	 MOVE	T1,[SIXBIT/DIDODW/]	;CODES FOR DI
	PUSHJ	P,GETIO##		;CHOOSE THE RIGHT ONE
	MOVE	P3,T1			;INTO P3
	JRST	GETS.3


ANL.CC:	MOVEI	P3,'^C'			;ASSUME ^C STATE
	TXNE	P1,JS.JDC		;DCORE WAIT?
	 MOVEI	P3,'^D'			;YES--FLAG
	TXNE	P1,JS.CMW		;COMMAND WAIT?
	 MOVEI	P3,'^W'			;YES--FLAG
	TXNE	P1,JS.OPR		;OPERATER INTERVENTION?
	 MOVEI	P3,'OW'			;YES--FLAG
	JRST	GETS.3

ANL.EW:	LOAD	T2,P2,J2.EWC		;GET EVENT WAIT CODE
	PUSHJ	P,MAKEW##		;TRANSLATE EW STATE CODE
	TXNE	P2,J2.EWS		;EVENT WAIT STATISFIED?
	 MOVEI	P3,'ES'			;YES
	JRST	GETS.3
ANL.RN:	;MOVX	T1,JB.RUN		;GET RUNNNING BIT
;	IORM	T1,.JBBAT(JP)		;SET
	PUSHJ	P,JB$HPQ		;GET HPQ SETTING
	JUMPN	T1,ANL.HP		;JUMP IF SET
	PUSHJ	P,JG$JTC		;GET SCHEDULE CLASS INFO
	TXNE	T1,JS.PQ2		;IN PQ2?
	 SKIPA	P3,[SIXBIT/     2/]	;YES-- 2
	  MOVEI	P3,'  1'		;NO-- 1
	PUSHJ	P,JB$BBB		;GET BACKGROUND BATCH
	CAIE	T1,0			;CHECK
	 TROA	P3,' B '		;YES-MAKE Bx
	  TRO	P3,' R '		;NO--MAKE Rx
	JRST	GETS.3

ANL.HP:	MOVEI	P3,'H0'(T1)		;FORM HPQ NAME
	JRST	GETS.3

ANL.SW:	PUSHJ	P,JG$SWP		;GET SWAP STATUS
	CAILE	T1,0			;FRAGMENTED?
	 HRRI	P3,'SW '		;NO
	CAIG	T1,0			;FRAGMENTED?
	 HRRI	P3,'SF '		;YES
	PUSHJ	P,JG$ADR		;GET .GTADR
	CAIE	T1,0			;ANY CORE?
	 TRO	P3,'  *'		;YES--FLAG SWAPPING
	POPJ	P,			;AND RETURN
JB$(STA)	;JOB STAT BITS
	PUSHJ	P,JB$WSC		;GET WAIT STATE CODE
	PUSH	P,T1			;SAVE A MOMENT
	LDB	T1,[POINT 12,T1,11]	;GET FIRST 2 CHARS
	PUSHJ	P,STAIDX		;GET INDEX
	 TDZA	T1,T1			;NOT FOUND--CLEAR
	MOVE	T1,STABIT(T1)		;GET THE BITS
	EXCH	T1,(P)			;SAVE T1,,GET OLD
	LDB	T1,[POINT 12,T1,29]	;GET SECOND 2 CHARS
	JUMPE	T1,STA.1		;JUMP IF NONE
	PUSHJ	P,STAIDX		;GET INDEX
	 TDZA	T1,T1			;NOT FOUND--CLEAR
	MOVE	T1,STABIT(T1)		;GET THE BITS
	IORM	T1,(P)			;INCLUDE EXTRA BITS
STA.1:	POP	P,T1			;RESTORE T1
	END$

STAIDX::MOVSI	T2,-LN$STA		;GET LENGTH OF TABLE
STAS.1:	CAME	T1,STATAB(T2)		;MATCH?
	 AOBJN	T2,STAS.1		;NO-LOOP FOR ALL
	JUMPGE	T2,.POPJ##		;ERROR IF NOT FOUND
	MOVE	T1,T2			;RETURN INDEX IN T1
	JRST	.POPJ1##		;AND SKIP

DEFINE BITS,<
	XLIST
	X	AU,<ACTIVE,RWAITS>	,<Alter UFD wait>
	X	B1,<RUN,ACTIVE,QUEUES>	,<Background batch running in PQ1>
	X	B2,<RUN,ACTIVE,QUEUES>	,<Background batch running in PQ2>
	X	CA,<ACTIVE,RWAITS>	,<Core allocation wait>
	X	CB,<ACTIVE,RWAITS>	,<Core block wait>
	X	D1,<ACTIVE,RWAITS>	,<DECtape controller 1 wait>
	X	D2,<ACTIVE,RWAITS>	,<DECtape controller 2 wait>
	X	D3,<ACTIVE,RWAITS>	,<DECtape controller 3 wait>
	X	D4,<ACTIVE,RWAITS>	,<DECtape controller 4 wait>
	X	D5,<ACTIVE,RWAITS>	,<DECtape controller 5 wait>
	X	D6,<ACTIVE,RWAITS>	,<DECtape controller 6 wait>
	X	D7,<ACTIVE,RWAITS>	,<DECtape controller 7 wait>
	X	D8,<ACTIVE,RWAITS>	,<DECtape controller 8 wait>
	X	DA,<ACTIVE,RWAITS>	,<Disk allocation wait>
	X	DC,<ACTIVE,RWAITS>	,<DECtape/magtape data control wait>
	X	DI,<IOWAIT,ACTIVE,CODES>,<Disk input wait>
	X	DO,<IOWAIT,ACTIVE,CODES>,<Disk output wait>
	X	DS,<ACTIVE,QUEUES>	,<Disk I/O satisfied>
	X	DW,<IOWAIT,ACTIVE,CODES>,<Disk I/O wait>
	X	E6,<EVENTWAIT,CODES>	,<DN60 event wait>
	X	ED,<EVENTWAIT,CODES>	,<DECnet event wait>
	X	EF,<EVENTWAIT,CODES>	,<Front end event wait>
	X	EI,<EVENTWAIT,CODES>	,<IPCF wait>
	X	EK,<EVENTWAIT,CODES>	,<Tape kontroller wait>
	X	EL,<EVENTWAIT,CODES>	,<Tape labeler event wait>
	X	EM,<EVENTWAIT,CODES>	,<DMR event wait>
	X	EN,<EVENTWAIT,CODES>	,<Network event wait>
	X	EP,<EVENTWAIT,CODES>	,<KDP event wait>
	X	EQ,<RWAITS>		,<ENQ/DEQ resource wait>
	X	ER,<EVENTWAIT,CODES>	,<Magtape rewind wait>
	X	ES,<EVENTWAIT,CODES>	,<Event wait satisfied>
	X	ET,<EVENTWAIT,CODES>	,<DTE event wait>
	X	EV,<RWAITS>		,<Exec virtual memory wait>
	X	EW,<EVENTWAIT,CODES>	,<Event wait>
	X	GU,<ACTIVE>		,<GETSEG UUO in progress>
	X	HB,<SLEEP>		,<Hibernating for condition>
	X	HS,<SLEEP>		,<Hibernate with sleep time>
	X	H1,<RUN,ACTIVE,QUEUES>	,<Running in HPQ 1>
	X	H2,<RUN,ACTIVE,QUEUES>	,<Running in HPQ 2>
	X	H3,<RUN,ACTIVE,QUEUES>	,<Running in HPQ 3>
	X	IO,<IOWAIT,ACTIVE>	,<I/O wait>
	X	JD,<CODES>		,<DAEMON wait>
	X	LK,<LOCK>		,<Locked in core>
	X	MC,<ACTIVE,RWAITS>	,<Monitor disk cache wait>
	X	MM,<ACTIVE,RWAITS>	,<Memory management wait>
	X	NA,<SLEEP,ACTIVE,CODES> ,<Napping (short sleep)>
	X	NU,<>			,<Null>
	X	OW,<>			,<Operator wait>
	X	PI,<ACTIVE>		,<Paging I/O wait>
	X	PS,<ACTIVE,QUEUES>	,<Paging I/O wait satisfied>
	X	R1,<RUN,ACTIVE,QUEUES>	,<Running in PQ1>
	X	R2,<RUN,ACTIVE,QUEUES>	,<Running in PQ2>
	X	RN,<RUN,ACTIVE,QUEUES>	,<Running>
	X	RU,<ACTIVE>		,<RUN UUO in progress>
	X	SF,<SWAP>		,<Swapped out and fragmented>
	X	SL,<SLEEP,CODES>	,<Sleeping>
	X	SW,<SWAP>		,<Swapped out>
	X	TI,<IOWAIT,CODES>	,<Terminal input wait>
	X	TO,<IOWAIT,ACTIVE,CODES>,<Terminal output wait>
	X	TS,<ACTIVE,QUEUES>	,<Terminal I/O wait satisfied>
	X	TW,<IOWAIT,ACTIVE,CODES>,<Terminal I/O wait>
	X	WI,<IOWAIT,ACTIVE,CODES>,<Waiting for input>
	X	WO,<IOWAIT,ACTIVE,CODES>,<Waiting for output>
	X	WS,<ACTIVE,QUEUES>	,<I/O wait satisfied>
	X	^C,<STOP>		,<Stopped>
	X	^D,<STOP>		,<DAEMON DCORE wait>
	X	^S,<IOWAIT>		,<Output stopped with ^S>
	X	^W,<STOP>		,<Command wait>
	LIST
>

DEFINE X(STATE,BIT,TEXT),< EXP ''STATE''>

STATAB::BITS
LN$STA==:.-STATAB

DEFINE X(STATE,BIT,TEXT),<EXP [ASCIZ |TEXT|]>

STATXT::BITS

DEFINE X(STATE,BIT,TEXT),<
	..Z==0
	IRP	BIT,<
		..Z==..Z!STAT'BIT##
	>
	EXP	..Z
>

STABIT:	BITS
JX$(GLC)	;GET LINE CHARACTERISTICS
	PUSHJ	P,JB$TLN		;GET TERMINAL NUMBER
	JUMPL	T1,GLC.1		;RETURN ZERO IF DETACHED
	PUSHJ	P,UGETLCH##		;DO GETLCH
	JRST	GLC.E			;DONE
GLC.1:	MOVEI	T1,0			;NOTHING
GLC.E:	END$

JX$(NNL)	;GET NETWORK NODE AND LINE
	PUSHJ	P,JB$TLN		;GET TERMINAL NUMBER
	JUMPL	T1,NNL.E		;SKIP IF DETACHED
	ADDI	T1,.UXTRM		;INTO UDX
	PUSHJ	P,UGTNTN##		;DO GTNTN.
	 MOVEI	T1,0			;FAILED
NNL.E:	END$
	SUBTTL	Subroutines -- SEGSIZ - Compute jobs size

SEGSIZ:	PUSHJ	P,.SAVE1##		;SAVE P1
	MOVEI	P1,(T1)			;COPY JOB/SEGMENT NUMBER
	CAMLE	P1,JOBMAX##		;LOW SEGMENT?
	  JRST	SEGSZ0			;NO--GET HIGH SEG SIZE
	PUSHJ	P,JG$SGN		;GET SEGMENT STATUS
	SKIPE	T1			;SKIP IF NO HIGH SEGMENT AT ALL
	TXNE	T1,JS.SPY!JS.SHR	;SPY OR SHARABLE?
	 JRST	SEGSZ0			;YES--SIMPLE CASE
	HRLI	T1,.GTSWP		;NO--POINT OT SEGMENT'S SWAP WORD
	MOVSS	T1			;SWAP
	PUSHJ	P,GTAB##		;GET IT
	HLRZS	T1			;FLIP
	MOVNS	T1			;GET HIGH SEG SIZE
	PUSH	P,T1			;SAVE
	MOVEI	T1,.GTIMI		;NOW GET IMAGE IN
	PUSHJ	P,JTAB##		; FOR THE JOB
	TLZ	T1,777770		;CLEAR JUNK
	POP	P,T2			;GET NON-SHARABLE HIGH SEG SIZE BACK
	ADD	T1,T2			;INCLUDE
	JRST	SEGSZ2			;ADD UPMP AND RETURN

SEGSZ0:	MOVEI	T1,.GTIMI		;GET SEGMENT SIZE
	HRLI	T1,(P1)			;INCLUDE JOB/SEGMENT
	PUSHJ	P,GTAB##		;GET IT
	TLZ	T1,777770		;CLEAR JUNK
	JUMPN	T1,SEGSZ1		;GO IF NON-ZERO
	MOVEI	T1,.GTSWP
	HRLI	T1,(P1)
	PUSHJ	P,GTAB##		;READ JBTSWP FOR SEGMENT
	HLRZS	T1
	JUMPE	T1,.POPJ##		;RETURN IF NO CORE
SEGSZ1:;	CAMG	P1,JOBMAX##		;IS THIS A LOW SEGMENT
SEGSZ2:;	  ADDI	T1,1			;YES--ACCOUNT FOR UPMP
	POPJ	P,			;AND RETURN
	SUBTTL	Subroutines -- TK2MS - Convert ticks to milliseconds

TK2MS::	IMULI	T1,^D1000
	IDIV	T1,TICKS##
	POPJ	P,
	SUBTTL	DATA STORAGE

	$LOW

JOBCOR::BLOCK	1
MAXJOB:	BLOCK	1
SRTTAB:	BLOCK	1
SRTPTR:	BLOCK	1
SRTCNT:	BLOCK	1
INCOLD:	BLOCK	1
INCINC:	BLOCK	1

	END