Google
 

Trailing-Edge - PDP-10 Archives - bb-x130a-sb - whouuo.mac
There are 4 other files named whouuo.mac in the archive. Click here to see a list.
	TITLE	WHOUUO -- MONITOR DEPENDENT UUO/SPY/GETTABS ETC

	SEARCH	WHOMAC

	$SETUP	(WHOUUO)

.FPMC==340000   
.LPMC==370000   
.MCFV==1000000
.UPMP==370000   
PAGSIZ==1000   

	NDATAC==:(T4)		;ANF10 NETSER NDB INDEX AND INDIRECTION
	SUBTTL	Table of contents

;               TABLE OF CONTENTS FOR WHOUUO
;
;
;                        SECTION                                   PAGE
;    1. Table of contents.........................................   2
;    2. SPY routines
;         2.1   SPYINI - Setup for SPY page.......................   3
;         2.2   VRSKEW -- Check version skew......................   4
;         2.3   FETCHK - UUO feature consistancy check............   5
;         2.4   UUOFET - Get monitor UUO features.................   6
;         2.5   MWORD - Fetch a word from the monitor.............   7
;         2.6   FWORD - Get a word from the monitor or funny space   8
;         2.7   JWORD - Get a word from a jobs core image.........   9
;         2.8   MAPSPY - Map a monitor SPY page...................  10
;         2.9   MAPFUN - Map a funny space/UPMP SPY page..........  11
;         2.10  ZAPFUN - Clear funny pages mapped.................  12
;    3. Swap reading routines
;         3.1   SWPCHK - See if actively swapping.................  13
;         3.2   MAPSWP - Map a page from the swapping space.......  14
;         3.3   GETUPT - Read the UPMP from the swapping space....  15
;         3.4   SWPPAG - Read a page from the swapper.............  16
;    4. GETTABs
;         4.1   Do a set of GETTABs...............................  18
;         4.2   Routine to convert GETTAB answers.................  19
;         4.3   Macros to setup data structures...................  20
;         4.4   Symbol offsets....................................  21
;         4.5   System wide tables................................  22
;    5. UUO simulation
;         5.1   UACCT - Read jobs account string..................  23
;         5.2   UCTLJOB - Find controlling job number.............  24
;         5.3   UDEVCHR - Find device characteristics.............  25
;         5.4   UDEVTYP - Get device type.........................  26
;         5.5   UDNET - Return DECnet data........................  27
;         5.6   UGETLCH - Get line characteristics................  32
;         5.7   UGETLIN - return TTY line number..................  33
;         5.8   GETTABs - MTAB, JTAB, GTAB routines...............  34
;         5.9   UGOBSTR - Return search list information..........  35
;         5.10  UGTNTN - Get node/line from terminal number.......  38
;         5.11  UJOBSTS - Get job status bits.....................  39
;         5.12  UNODE - Return ANF-10 network information.........  40
;         5.13  UPATH - Return a job's path.......................  48
;         5.14  USYSSTR - Return next structure in system.........  51
;         5.15  UTRMNO - Get terminal number......................  52
;         5.16  UTRMOP - Find terminal parameters.................  53
;    6. Job state routines
;         6.1   GETIO - Get input or output state.................  56
;         6.2   ANYCPU - See if running on any CPU................  57
;         6.3   MAKEW - Translate EW state codes..................  58
;    7. Print routines
;         7.1   INFTMP - Print TMPCOR directory...................  59
;         7.2   INFCHN - Print active channel information.........  60
;         7.3   INFORG - Print program origin.....................  61
;         7.4   INFDDB - Print all DDBs for a job.................  62
;         7.5   INFJSL - Print job search list....................  63
;         7.6   INFPTH - Print current path.......................  64
;         7.7   INFLNM - Print path pathological names............  65
;    8. DDB routines
;         8.1   GETDDB - Get first/next DDB in chain..............  66
;         8.2   JC$DDB - Check uses /DDBS:<spec> switch...........  67
;         8.3   LSTDDB - Routine to list DDB info.................  69
;         8.4   DSKDDB - Print disk DDB specific information......  73
;         8.5   DSKPTH - Print PPN and PATH info..................  74
;         8.6   MTADDB - Print magtape DDB specific information...  75
;         8.7   TTYDDB - Print TTY DDB specific information.......  76
;         8.8   NETDDB - Print NET DDB specific information.......  77
;         8.9   TSKDDB - Print TSK DDB specific information.......  78
;         8.10  PTYDDB - Print PTY DDB specific information.......  79
;         8.11  DTADDB - Print DTA DDB specific information.......  80
;    9. LOGIN queue routines
;         9.1   LGQINI -- Get initial queue statistics............  81
;         9.2   CHKLGQ - See if in LOGIN queue....................  82
;   10. Network routines
;        10.1   ANODE - Convert ANF-10 node number/name...........  83
;        10.2   DNODE - Convert DECnet node number/name...........  84
;        10.3   NODINF - Return node information..................  85
;        10.4   NRTINF - Return NRTSER information................  86
;   11. Structure routines
;        11.1   STRINI/STRCHK - Initialize structure UUOs.........  87
;        11.2   STRFSN - Convert name to number...................  88
;        11.3   STRNFS - Convert number to name...................  89
;        11.4   STRMNC - Return mount count.......................  90
;   12. Storage
;        12.1   SPY and version...................................  91
;        12.2   DDB...............................................  92
;        12.3   DECnet............................................  93
;        12.4   LOGIN queue.......................................  94
;        12.5   Segment...........................................  95
;        12.6   Structure.........................................  96
;        12.7   Unit and swapper..................................  97
;        12.8   UUO argument blocks...............................  98
;   13. End.......................................................  99
	SUBTTL	SPY routines -- SPYINI - Setup for SPY page

SPYINI::MOVE	T1,[-SYS.L,,SYS.T]	;POINT TO GETTAB TABLES
	PUSHJ	 P,DOGETS		;DO SYSTEM WIDE GETTABS
	TLNN	F,(FL.SPY)		;CAN WE SPY?
	POPJ	P,			;NO--DONE
	MOVE	T1,[-SYM.L,,SYM.T]	;POINT TO GETTAB TABLES
	PUSHJ	P,DOGETS		;GET THEM
	SETOM	SKEWFL			;INIT VERSION SKEW FLAG
	POPJ	P,
	SUBTTL	SPY routines -- VRSKEW -- Check version skew


VRSKEW::AOSE	SKEWFL			;BEEN HERE BEFORE?
	POPJ	P,			;YES--THEN ALL IS WELL
	HLLZ	T1,DECONC##		;GET DEC AND CUSTOMER MONITOR VERSION
	HLR	T1,CUSONC##		; WE WERE CONFIGURED FOR BY WHOONC
	TDZ	T1,[700000,,700000]	;CLEAR OUT -VWHO STUFF
	HLLZ	T2,DECVER		;GET DEC AND CUSTOMER MONITOR VERSION
	HLR	T2,CUSVER		; FOR THE MONITOR WE'RE LOOKING AT
	TDZ	T2,[700000,,700000]	;CLEAR OUT -VWHO STUFF
	CAMN	T1,T2			;MATCH?
	PJRST	FETCHK			;CHECK UUO FEATURES AND RETURN

VRSK.E:	$STOP	(VRS,<Monitor version skew; WHO must be reconfigured>,E.VRS)
E.VRS:	PUSHJ	P,.TCRLF##		;START WITH A CRLF
	PUSHJ	P,.TTABC##		; AND A TAB
	MOVEI	T1,INITXT##		;POINT TO TEXT GENERATED BY WHOONC
	PJRST	.TSTRG##		;TYPE IT AND RETRUN
	SUBTTL	SPY routines -- FETCHK - UUO feature consistancy check


FETCHK::PUSHJ	P,UUOFET		;GET MONITOR UUO FEATURES
	MOVE	T1,F			;GET FLAGS
	AND	T1,[FL.FEATURES]	;KEEP JUST THE FEATURE BITS
	MOVE	T2,FEATURES##		;GET FEATURES WHO WAS CONFIGURED FOR
	TDZ	T2,T1			;DOES MONITOR HAVE ALL FEATURES?
	JUMPE	T2,.POPJ##		;YES
	SKIPL	SKEWFL			;DONE SKEW CHECKING YET?
	$WARN	(FET,<WHO/monitor feature skew; disabling >,E.FET)
	POPJ	P,			;RETURN

E.FET:	MOVSI	T4,-FETLEN		;-LENGTH OF TABLE
	TRZ	F,FR.COMMA		;CLEAR COMMA NEEDED FLAG

E.FET1:	HLLZ	T1,FETTAB(T4)		;GET A FLAG
	TDNE	T1,F			;IS IT SET?
	JRST	E.FET2			;YES--THEN IT'S OK
	TROE	F,FR.COMMA		;NEED A COMMA?
	PUSHJ	P,.TCOMA##		;YES
	HRRZ	T1,FETTAB(T4)		;GET TEXT ADDRESS
	PUSHJ	P,.TSTRG##		;TYPE MESSAGE

E.FET2:	AOBJN	T4,E.FET1		;LOOP
	POPJ	P,			;AND RETURN


DEFINE	$FET	(FLAG,TEXT),<FL.'FLAG+[ASCIZ |'TEXT|]>
FETTAB:	$FET	(CHARGE,<Charge numbers>)
	$FET	(ANF10,<ANF10>)
	$FET	(DECNET,<DECnet>)
	$FET	(SMP,<SMP>)
IFN FTLGNQ,<$FET(LGNQ,<LOGIN queue>)>
FETLEN==.-FETTAB
	SUBTTL	SPY routines -- UUOFET - Get monitor UUO features


UUOFET::TLZ	F,(FL.FEATURES)		;CLEAR ALL FEATURE BITS

	MOVE	T1,[.GTCNO,,.GTSLF]	;GETTAB TO GET THE BASE OF THE
	PUSHJ	P,.MAPG##		; CHARGE NUMBER TABLE
	  MOVEI	T1,0			;NOT THERE
	SKIPE	T1			;HAVE CHARGE NUMBERS?
	TLO	F,(FL.CHARGE)		;YES

	MOVE	T1,[%CNNDB]		;WANT POINTER TO
	PUSHJ	P,.MAPG##		; TO THE FIRST NDB
	  SETZ	T1,			;ASSUME NO NETWORK SUPPORT
	SKIPE	T1			;HAVE ANF10 NETWORKS?
	TLO	F,(FL.ANF10)		;YES

VERSION GE,702,<
	MOVE	T1,[.GTDNT,,.GTSLF]	;GETTAB TO GET THE BASE OF THE
	PUSHJ	P,.MAPG##		; DECNET TABLE
	  SETZ	T1,			;CAN'T
	SKIPE	T1			;HAVE DECNET LOADED IN THIS MONITOR?
	TLO	F,(FL.DECNET)		;YES
>

	MOVE	T1,[%CNCPU]		;NUMBER OF CPUS
	PUSHJ	P,.MAPG##		;GET IT
	  MOVEI	T1,1			;ASSUME SINGLE PROCESSOR
	CAILE	T1,1			;MORE THAN ONE?
	TLO	F,(FL.SMP)		;YES

IFN FTLGNQ,<
	MOVE	T1,[%LQQUE]		;WANT POINTER TO LOGIN QUEUE
	PUSHJ	P,.MAPG##		; IN THE MONITOR
	  SETZ	T1,			;NOT THERE
	SKIPE	T1			;HAVE LOGIN QUEUE SUPPORT?
	TLO	F,(FL.LGNQ)		;YES
> ;END IFN FTLGNQ

	POPJ	P,			;RETURN
	SUBTTL	SPY routines -- MWORD - Fetch a word from the monitor

IFN FTUUO!FTDDB,<
MWORDR:	PUSHJ	P,MWORD
	TLZ	T1,-1
	POPJ	P,

MWORDL:	PUSHJ	P,MWORD
	LSH	T1,-^D18
	POPJ	P,

MWORDS:	AOS	(P)			;TAKE SKIP RETURN
MWORD::	TLZ	T1,-1			;CLEAR EXTRA STUFF
XWORD:	PUSHJ	P,.MAPE##		;DO AN EXAMINE
	 JRST	MAPSTP##		;MAPPING ERROR (STOPCODE)
	POPJ	P,			;RETURN

BWORD:	PUSH	P,T2			;SAVE T2
	MOVE	T2,T1			;COPY BYTE POINTER
	LSH	T1,-22			;RIGHT JUSTIFY THE INDEX AC
	ANDI	T1,17			;KEEP ONLY THE AC
	HLL	T1,@T1			;GET THE SECTION NUMBER
	HRRI	T1,@T2			;GET THE SECTION LOCAL ADDRESS
	PUSHJ	P,XWORD			;NOW GET C(T1)
	TLZ	T2,(@(17))		;CLEAR OUT INDEX AND INDIRECT BITS
	HRRI	T2,T1			;COMPLETE BYTE POINTER
	LDB	T1,T2			;GET BYTE IN QUESTION
	POP	P,T2			;RESTORE T2
	POPJ	P,			;RETURN

>;END IFN FTUUO!FTDDB
	SUBTTL	SPY routines -- FWORD - Get a word from the monitor or funny space

IFN FTDDB,<
UWORD:	ADD	T1,$UPMP		;FORM UPMP OFFSET
					;FALL INTO FWORD
FWORD:	TLZ	T1,-1			;CLEAR EXTRA STUFF
	CAIL	T1,.FPMC		;SEE IF IN FUNNY SPACE
	 CAIL	T1,.LPMC+PAGSIZ		;..
	  JRST	FWORD2			;NO--JUST REGULAR MWORD
	PUSH	P,T2			;SAVE T2
	LSHC	T1,-^D9			;SPLIT INTO PAGE,,OFFSET
	LSH	T2,-^D27		;FASTER THAN IDIVI T1,1000 TOO!
	SKIPGE	PAGTAB(T1)		;SEE IF PAGE MAPPED YET
	 JRST	FWORD1			;IT IS
	PUSHJ	P,MAPFUN		;NO--GO MAP IT NOW
	  SOSA	-1(P)			;COMPENSATE FOR AOS

FWORD1:	MOVE	T1,@PAGTAB(T1)		;FETCH WORD (T2 IN @PAGTAB)
	POP	P,T2			;RESTORE T2
	JRST	.POPJ1##		;AND RETURN

FWORD2:	AOS	(P)			;FROM HERE ON, IT CAN'T FAIL
	PJRST	MWORD			;GO GET A WORD FROM THE MONITOR
>;END IFN FTDDB
	SUBTTL	SPY routines -- JWORD - Get a word from a jobs core image

JWORD::	HRLI	T1,JPKBLK+2		;GET DESTINATION ADDRESS
	MOVSM	T1,JPKBLK+1		;SAVE READ ADDR,,WRITE ADDR
	HRLZI	T1,(O)			;GET JOB NUMBER
	HRRI	T1,1			;GET WORD COUNT
	MOVEM	T1,JPKBLK+0		;SAVE IT
	MOVEI	T1,JPKBLK		;POINT TO ARG BLOCK
	PUSHJ	P,.MAPJ##		;READ ANOTHER JOB'S CORE IMAGE
	 POPJ	P,			;FAILED
	MOVE	T1,JPKBLK+2		;GET WORD FROM THE JOB
	JRST	.POPJ1##		;SUCCESS
	SUBTTL	SPY routines -- MAPSPY - Map a monitor SPY page

IFN FTUUO!FTDDB,<
MAPSPY:	PUSHJ	P,.SAVT4##		;SAVE T1-T4
	PUSHJ	P,SPYPAG		;TRY TO MAP IT
	 $FATAL	(CMS,<Cant map SPY page; >,E.CMS);NO--DIE
	POPJ	P,			;AND RETURN

SPYPAG:	PUSHJ	P,.SAVE2##		;SAVE P1,P2
	MOVE	P1,T1			;COPY MONITOR PAGE TO MAP
	PUSHJ	P,M$NXPG##		;ALLOCATE A NON-EXISTENT PAGE
SPYP.E:	 $STOP	(SAP,<SPY page allocation failure>)
	MOVE	P2,T1			;COPY ALLOCATED PAGE
	MOVEI	T2,1			;ONE ARG FOR PAGE.
	HRRZ	T3,P2			;GET ALLOCATED PAGE
	HRL	T3,P1			;GET MONITOR PAGE
	MOVE	T1,[.PAGSP,,T2]		;POINT TO ARGS
	PAGE.	T1,			;MAP A SPY PAGE
	 PUSHJ	P,SPYP.E		;ERROR
	MOVE	T1,P2			;GET ALLOCATED PAGE
	PUSHJ	P,M$IPRC##		;TELL GLXMEM PAGE EXISTS NOW
	 PUSHJ	P,SPYP.E		;ERROR
	LSH	P2,^D9			;MAKE AN ADDRESS
	TXO	P2,PG.MAP!PG.ALC!<T2>B17;SET PAGE MAPPED AND T2 FOR INDEXING
	MOVEM	P2,PAGTAB(P1)		;SAVE STATUS
	JRST	.POPJ1##		;AND RETURN
	LSH	T2,^D9			;MAKE AN ADDRESS
	TXO	T2,PG.MAP!<T2>B17	;SET PAGE MAPPED AND T2 FOR INDEXING
	MOVEM	T2,PAGTAB(T1)		;SAVE THE ADDRESS ITS MAPPED AT
	JRST	.POPJ1##		;AND RETURN
>;END IFN FTUUO!FTDDB

E.CMS:	PUSHJ	P,E$PAGE##		;CONVERT ERROR CODE
	 JFCL				;CANT
	PJRST	.TSTRG##		;TYPE AND RETURN

S$DUMP:	PUSHJ	P,.SAVE1##		;SAVE P1
	MOVSI	P1,-1000		;POINTER TO ALL PAGES
DUMP.1:	SKIPN	PAGTAB(P1)		;SEE IF EXISTS
	 JRST	DUMP.2			;NO
	MOVEI	T1,(P1)			;GET MONITOR PAGE
	MOVEI	T3,3			;FIELDWIDTH
	PUSHJ	P,.TDECW##		;TYPE
	MOVEI	T1,[ASCIZ/  allocated /]
	MOVE	T2,PAGTAB(P1)
	TXNE	T2,PG.ALC
	 PUSHJ	P,.TSTRG##
	MOVEI	T1,[ASCIZ/  mapped /]
	MOVE	T2,PAGTAB(P1)
	TXNE	T2,PG.ALC
	 PUSHJ	P,.TSTRG##
	HRRZ	T1,PAGTAB(P1)
	LSH	T1,-^D9
	MOVEI	T3,3
	PUSHJ	P,.TDECJ##
	PUSHJ	P,.TCRLF##
DUMP.2:	AOBJN	P1,DUMP.1
	PJRST	.TCRLF##
	SUBTTL	SPY routines -- MAPFUN - Map a funny space/UPMP SPY page

IFN FTDDB,<
MAPFUN:	PUSHJ	P,.SAVT4##		;SAVE T1-T4
	PUSHJ	P,.SAVE1##		;AND P1
	MOVEI	P1,(T1)			;SAVE FUNNY PAGE CALLER WANTED
	MOVE	T2,PAGTAB(P1)		;GET PAGE TABLE BITS
	TXNN	T2,PG.ALC		;PAGE ALLOCATED?
	 PUSHJ	P,ALCPAG		;NO--ALLOCATE IT NOW
MAPF.2:	HRLI	T1,(O)			;LOAD UP CURRENT JOB
	HRRI	T1,1000			;GRAB A PAGE
	MOVEI	T2,(P1)			;GET TARGET PAGE
	CAIN	P1,.UPMP/PAGSIZ		;UPMP?
	 TXOA	T1,JK.UPM		;YES--SET TO READ IT
	  TXOA	T1,JK.EVA		;NO--TRY FOR FUNNY SPACE
	   MOVEI T2,0			;YES--AND SETUP SOURCE
	LSH	T2,^D27			;SHIFT INTO PAGE
	HRR	T2,PAGTAB(P1)		;GET DESTINATION PAGE
	DMOVEM	T1,JPKBLK		;SAVE ARGS
	MOVEI	T1,JPKBLK		;POINT TO ARG BLOCK
	PUSHJ	P,.MAPJ##		;READ MAP OF FUNNY SPACE
	 JRST	MAPF.3			;CANT--TRY THE SWAPPING SPACE
	MOVX	T1,PG.MAP		;INDICATE PAGE IS MAPPED NOW
	IORM	T1,PAGTAB(P1)		;..
	JRST	.POPJ1##		;AND RETURN

MAPF.3:	MOVE	T1,MAPPTR##		;GET MAPPER DATA BLOCK ADDRESS
	MOVE	T1,.MPECD##(T1)		;GET ERROR CODE
	CAIE	T1,MPJSO%##		;JOB SWAPPED OUT OR IN TRANSIT?
	 JRST	MAPFAT##		;MAPPING ERROR
	TLNE	F,(FL.CRASH)		;BUT ARE WE LOOKING AT A CRASH FILE?
	POPJ	P,			;THEN WE CAN'T READ THE SWAPPING SPACE
	PUSHJ	P,SWPCHK		;SEE IF ACTIVILY SWAPPING
	 JRST	MAPF.2			;YES--I THINK HES IN CORE NOW
	AOS	(P)			;FROM HERE ON, IT CAN'T FAIL
	PJRST	MAPSWP			;NO--KNOWN TO TO SWAPPED OUT
>;END IFN FTDDB
	SUBTTL	SPY routines -- ZAPFUN - Clear funny pages mapped

;ZAPFUN -- CLEAR FUNNY PAGES MAPPED
;CALL ONCE FOR EACH NEW JOB
ZAPFUN::MOVX	T2,PG.MAP		;CLEAR MAPPED BIT
	MOVE	T1,[-<.LPMC-.FPMC>/PAGSIZ,,.FPMC/PAGSIZ];SETUP POINTER
ZAPF.1:	ANDCAM	T2,PAGTAB(T1)		;CLEAR OUT FUNNY PAGES
	AOBJN	T1,ZAPF.1		;LOOP FOR ALL
	ANDCAM	T2,PAGTAB+.UPMP/PAGSIZ	;AND UPMP PAGE
	POPJ	P,
	SUBTTL	Swap reading routines -- SWPCHK - See if actively swapping

SWPCHK:	MOVEI	T1,.GTSTS		;GET JOB STATUS
	PUSHJ	P,JTAB			;FOR CURRENT JOB
	TXNN	T1,JS.NSW		;LOCKED?
	 TXNN	T1,JS.SWP		;OR NOT SWAPPED?
	  POPJ	P,			;YES--RETRY JOBPEK
	MOVEI	T1,.GTADR		;GET CORE ASSIGNED
	PUSHJ	P,JTAB			;FOR CURRENT JOB
	JUMPE	T1,.POPJ1##		;JUMP IF SWAPPED AND QUIESCENT
	MOVEI	T1,0			;SLEEP A TICK
	SLEEP	T1,			;ZZZ
	JRST	SWPCHK			;AND CHECK AGAIN
	SUBTTL	Swap reading routines -- MAPSWP - Map a page from the swapping space

MAPSWP:	CAIN	P1,.UPMP/PAGSIZ		;UPMP?
	 PJRST	GETUPT			;YES--GET IT AND RETURN
	CAIL	P1,.LPMC/PAGSIZ		;A FUNNY PAGE?
	 CAILE	P1,.FPMC/PAGSIZ		;..
	  CAIA				;YEP
	   $STOP (MCR,<MAPSWP can only read UPMP and funny space pages>)
	PUSHJ	P,GETUPT		;GET UPMP IF WE DONT HAVE IT
	MOVEI	T2,<<.MCFV-.FPMC>/PAGSIZ>(P1)	;MAKE INTO VIRTUAL PAGE IN UPMP
	IDIVI	T2,2			;SPLIT INTO INDEX,,HALF
	CAIN	T3,1			;ODD?
	 HRRZ	T1,@PAGTAB+.UPMP/PAGSIZ	;YES--GET RH
	CAIN	T3,0			;EVEN?
	 HLRZ	T1,@PAGTAB+.UPMP/PAGSIZ	;YES--GET LH
	LOAD	T2,T1,UP.UNI		;GET UNIT
	LOAD	T3,T1,UP.PAG		;AND PAGE
	MOVEI	T1,(P1)			;COPY PAGE
	PJRST	SWPPAG			;READ IT AND RETURN

UP.UNI==3B22
UP.PAG==17777B35
	SUBTTL	Swap reading routines -- GETUPT - Read the UPMP from the swapping space

;Call:
;	no arguments
;Returns:
;	UPMP page read from swapper, mapped and allocated thru PAGTAB

GETUPT:	MOVEI	T1,.UPMP/PAGSIZ		;GET UPMP PAGE NUMBER
	MOVE	T2,PAGTAB(T1)		;GET ASSOCIATED BITS
	TXNE	T2,PG.MAP		;SEE IF MAPPED
	 POPJ	P,			;YES--JUST RETURN
	TXNN	T2,PG.ALC		;ALLOCATED?
	 PUSHJ	P,ALCPAG		;YES--GET IT
	MOVEI	T1,.GTSWP		;GET THE SWAP STATUS
	PUSHJ	P,JTAB			;ASK MONITOR
	LOAD	T2,T1,SW.UNI		;LOAD UNIT NUMBER
	LOAD	T3,T1,SW.PAG		;LOAD RELATIVE PAGE NUMBER
	MOVEI	T1,.UPMP/PAGSIZ		;GET PAGE OF UPMP
	PUSHJ	P,SWPPAG		;READ THAT PAGE IN
	MOVE	T2,$UPJOB		;GET JOB NUMBER OFFSET
	CAME	O,@PAGTAB+.UPMP/PAGSIZ	;MATCH?
	 $STOP	(WJU,<Wrong jobs UPMP read>)
	POPJ	P,			;AND RETURN

SW.UNI==7B4
SW.PAG==17777B17
	SUBTTL	Swap reading routines -- SWPPAG - Read a page from the swapper

;Call:
;	T1/ virtual page number to read
;	T2/ index into SWPTAB of page on swapper
;	T3/ relative page offset on swapping space
;Returns
;	page read into mapped address as specified in call

SWPPAG:	PUSHJ	P,.SAVE2##		;SAVE P2
	MOVEI	P1,(T1)			;SAVE ARG
	PUSH	P,T3			;SAVE BLOCK NUMBER
	MOVEI	T1,(T2)			;GET UNIT NUMBER
	CAML	T1,SWPMAX		;IN RANGE?
	 $STOP	(SUR,<Swapping unit out of range>)
	ADD	T1,SWPTAB		;ADD ADDRESS OF SWPTAB
	PUSHJ	P,MWORD			;GET IT
	SKIPN	P2,T1			;GET UDB ADDRESS
	 $STOP	(NUS,<No unit for swapping>)
	ADD	T1,UNINAM##		;GET UNIT NAME
	PUSHJ	P,MWORD			;FROM MONITOR
	MOVE	T2,T1			;COPY INTO T2
	MOVX	T1,UU.PHS!.IODMP	;PHYSICAL ONLY DUMP MODE
	MOVEI	T3,0			;NO BUFFERS
	OPEN	SWP,T1			;OPEN THE UNIT
	 $FATAL	(COS,<Cannot open swapping unit>)
	MOVE	T1,UNISLB		;GET OFFSET OF FIRST SWAPPING BLOCK
	ADD	T1,P2			;PLUS BLOCK ON UNIT
	PUSHJ	P,MWORD			;ASK MONITOR
	CAIN	T1,0			;ZERO?
	 $STOP	(SBZ,<Swapping block zero>)
	POP	P,T3			;RESTORE RELATIVE PAGE
	LSH	T3,2			;CONVERT TO BLOCK
	ADD	T1,T3			;COMBINE WITH OFFSET
	TXO	T1,INSVL.(SWP,SU.SCH)	;INSERT CHANNEL
	SUSET.	T1,			;SHOOT FOR THAT BLOCK
	 $FATAL	(SUF,<SUSET. UUO failure; Not enough privileges>)
	HRRZ	T1,PAGTAB(P1)		;GET DESTINATION PAGE
	SUBI	T1,1			;MAKE IOWD
	HRLI	T1,-PAGSIZ		;SIZE
	MOVEI	T2,0			;END OF LIST
	INPUT	SWP,T1			;READ IT
	RELEAS	SWP,			;FREE CHANNEL
	MOVX	T1,PG.MAP		;INDICATE PAGE MAPPPED
	IORM	T1,PAGTAB(P1)		;SAVE
	POPJ	P,			;AND RETURN
ALCPAG:	PUSH	P,T1			;SAVE PAGE USER WANTS
	PUSHJ	P,M$GPAG##		;GET A PAGE
	 $STOP	(SPF,<Swapper page allocation failed>)
	TXO	T1,PG.ALC!<T2>B17	;SET PAGE EXISTS AND T2 FOR INDEXING
	POP	P,T2			;RESTORE USERS PAGE
	MOVEM	T1,PAGTAB(T2)		;SAVE IN MAP
	POPJ	P,			;AND RETURN
	SUBTTL	GETTABs -- Do a set of GETTABs

;CALL:
;	MOVE	T1,[-LEN,,START]

DOGETS:	PUSHJ	P,.SAVE1##		;SAVE P1
	MOVE	P1,T1			;COPY PTR INTO SAFE PLACE
DOGE.1:	MOVE	T1,$GTARG(P1)		;GET THE GETTAB DESIRED
	PUSHJ	P,GTAB			;DO THE GETTAB
	SKIPE	$GTCVT(P1)		;ROUTINE TO CONVERT RESULT?
	 PUSHJ	P,@$GTCVT(P1)		;YES--CONVERT IT
	MOVEM	T1,@$GTADR(P1)		;STORE THE ANSWER
	ADD	P1,[$GTLEN-1,,$GTLEN-1]	;BUMP TO NEXT SLOT
	AOBJN	P1,DOGE.1		;LOOP FOR ALL
	POPJ	P,			;AND RETURN
	SUBTTL	GETTABs -- Routine to convert GETTAB answers

CRH:	TLZA	T1,-1
CLH:	HLRZS	T1
	POPJ	P,

CLHM1:	HLRZS	T1
CRHM1:	MOVEI	T1,-1(T1)
	POPJ	P,

CSWP:	HLRE	T2,T1			;GET -N
	MOVNM	T2,SWPMAX		;SAVE MAX SWAP UNIT
	JRST	CRH			;AND GET RH ONLY

CAT:	TLNN	F,(FL.SPY)		;CAN WE SPY? (OR MAYBE A CRASH FILE)
	TDZA	T1,T1			;NO--ZAP ADDRESS
	PUSHJ	P,XWORD
	POPJ	P,
	SUBTTL	GETTABs -- Macros to setup data structures

	$GTARG==0			;GETTAB ARGUMENT
	$GTADR==1			;ADDRESS TO STORE VALUE
	$GTCVT==2			;ADDRESS TO CONVERT IF NEEDED
	$GTLEN==3			;LENGTH OF A BLOCK

DEFINE	X(ARG,ADR,CVT<0>),<
	EXP	ARG,ADR,CVT
	$LOW
	ADR::	BLOCK	1
	$HIGH
>
	SUBTTL	GETTABs -- Symbol offsets

	XLIST
	LIT
	LIST


DEFINE TABLES,<
	XLIST

	X %CNVER,LODNUM
	X %CNDVN,DECVER
	X %CNCVN,CUSVER

	X %CNDCH,$LDDCH
	X %VMUPJ,$UPJOB
	X %VMLNM,$UPLNM
	X %VMLST,$UPLST
	X %VMUPM,$UPMP
	LIST
>

SYM.T:	TABLES
SYM.L==.-SYM.T
	SUBTTL	GETTABs -- System wide tables

DEFINE	TABLES,<
	XLIST

	X %IPCDQ,IPCFQT
	X %CNPTY,SYSPTY,CLH
	X %CNPTY,PTYN,CRH
	X %CNPTY,LINMAX,CLHM1
	X %CNSJN,JOBMAX,CRHM1
	X %CNLMX,LOGMAX
	X %CNTIC,TICKS
	X %CNST2,STATE2
	X %LDFFA,OPRPPN
	X %LDQUE,QUEPPN
	X %LDSPP,SPLPRT
	X %CNDEV,FIRDDB,CLH
	X %CNPDB,PDBPTR
	X .GTLOC,CENSTA,CRH
	X %CNBCL,CTYLIN
	X %CNFLN,SYSLIN
	X %LDSLP,SWPTAB,CSWP
	X %LDSLB,UNISLB
	X %CNHXC,HIGHXC
IFN FTUUO,<
	X <.GTTTY*1000000+.GTSLF>,TTYTAB
	X %CNPNP,PTYTAB,CRH
	X %CNDSC,DSCTAB
	X %CNNDB,NETNDB
VERSION GE,702,<
	X <.GTNDA*1000000+.GTIDX>,HGHNOD,CRH
	X %DNNSJ,NRTSJP,CAT
	X %DNNCH,NRTCHP,CAT
	X %DNNDQ,NMXNDQ,CAT
	X %DNKON,KONNAM
	X %DNNRV,RTRNRV,CAT
	X %DNOFS,RTROFS,CAT
	X %DNRMX,RTRMXN,CAT
	X %DNCST,RTNCST,CAT
	X %DNHOP,RTNHOP,CAT
	X %DNLCL,RTNLCL,CAT
	X %DNRCH,RTNRCH,CAT
	X %DNNDT,SCTNDT,CAT
	X %DNSMX,SCTMXN,CAT
>;END VERSION GE,702
>;END IFN FTUUO
IFN FTUUO,<
	X %CNLNP,LINTAB
>;END IFN FTUUO

	LIST
>

SYS.T::	TABLES
SYS.L==:.-SYS.T
	SUBTTL	UUO simulation -- UACCT - Read jobs account string

UACCT::
	HRLI	T2,(T1)			;GET ADDR,,0
	HRRI	T2,1(T1)		;GET ADDR,,ADDR+1
	SETZM	(T1)			;ZERO THE FIRST
	BLT	T2,7(T1)		;ZERO THE BLOCK
IFN FTUUO,<
	TLNE	F,(FL.SPY)
	  JRST	SACCT
>;END IFN FTUUO
	MOVEI	T4,(T1)			;SAVE ADDR TO STORE ACCOUNT
	MOVEI	T2,2			;TWO ARGS
	MOVEI	T3,(O)			;JOB NUMBER
	MOVE	T1,[.ACTRD,,T2]		;READ FUNCTION
	ACCT.	T1,			;READ IT
	 CAIA				;FAILED
	POPJ	P,			;ALL SET
	MOVE	T1,[ASCIZ/?????/]	;GET UNKNOWNS
	MOVEM	T1,(T4)			;STORE
	SETZM	1(T4)			;MAKE ASCIZ
	POPJ	P,

IFN FTUUO,<
SACCT:	PUSHJ	P,.SAVE2##		;SAVE P2
	MOVEI	P1,(T1)			;SAVE ADDR TO STORE
	HRLI	P1,-10			;-LENGTH
	MOVE	T1,PDBPTR		;GET PDBPTR
	ADDI	T1,(O)			;PLUS JOB
	PUSHJ	P,MWORD			;FETCH
	ADD	T1,.PDACS##		;GET ACCOUNT STRING OFFSET
	MOVEI	P2,(T1)			;SAVE OFFSET
ACCT.1:	MOVEI	T1,(P2)			;GET STRING ADDR
	PUSHJ	P,MWORD			;FETCH IT'
	MOVEM	T1,(P1)			;STORE IT
	JUMPE	T1,.POPJ##		;RETURN IF ZERO
	ADDI	P2,1			;BUMP TO NEXT ADDRESS
	AOBJN	P1,ACCT.1		;LOOP FOR ALL
	POPJ	P,			;AND RETURN
>;END IFN FTUUO
	SUBTTL	UUO simulation -- UCTLJOB - Find controlling job number

UCTLJOB::
IFN FTUUO,<
	TLNE	F,(FL.SPY)		;CAN WE SPY?
	  JRST	SCTLJOB			;YES!
>;END IFN FTUUO
	CTLJOB	T1,			;NO--DO UUO
	  POPJ	P,			;FAILED
	JRST	.POPJ1##		;RETURN
IFN FTUUO,<
SCTLJOB:CAMN	T1,[EXP -1]		;MY JOB?
	MOVE	T1,MYJOB##		;YES
	ADD	T1,TTYTAB		;GET TTY DDB
	PUSHJ	P,MWORDR		;FROM MONITOR
	JUMPE	T1,.POPJ##		;ERROR IF NONE
	ADD	T1,DDBLDB##		;GET LDB ADDR
	PUSHJ	P,MWORDR		;FROM MONITOR
	JUMPE	T1,.POPJ##		;ERROR IF NONE
	ADD	T1,$LDDCH		;GET CHARACTERISTICS
	PUSHJ	P,MWORD			;FROM MONITOR
	LDB	T1,[POINT 9,T1,35]	;GET LINE NUMBER
	SUB	T1,SYSPTY		;CONVERT TO LINKED PTY
	JUMPL	T1,SCTLJ1		;IF NEG ITS A REAL TTY
	CAML	T1,PTYN			;IS IT LEGAL? (BETTER BE!)
	  JRST	SCTLJ1			;NO--MUST BE ON REMOTE
	ADD	T1,PTYTAB		;GET PTY DDB ADDR
	PUSHJ	P,MWORD			;FROM MONITOR
	ADD	T1,DEVJOB##		;FIND DEVJOB
	PUSHJ	P,MWORD			;FROM MONITOR
	LDB	T1,[POINT 9,T1,35]	;RETURN JOB NUMBER
	JRST	.POPJ1##		;AND RETURN

SCTLJ1:	MOVNI	T1,1			;RETURN -1 IF NOT CONTROLLED
	JRST	.POPJ1##		;AND RETURN
>;END IFN FTUUO
	SUBTTL	UUO simulation -- UDEVCHR - Find device characteristics

UDEVCHR::
IFN FTUUO,<
	TLNE	F,(FL.SPY)
	  JRST	SDEVCHR
>;END IFN FTUUO
	DVCHR.	T1,
	POPJ	P,
IFN FTUUO,<
SDEVCHR:SUBI	T1,.UXTRM		;REMOVE OFFSET
	ADD	T1,LINTAB		;POINT TO LDB ADDR
	PUSHJ	P,MWORDR		;FETCH FROM MONITOR
	JUMPE	T1,.POPJ##		;ERROR IF NONE
	ADD	T1,LDBDDB##		;POINT TO DDB ADDR
	PUSHJ	P,MWORDR		;FETCH FROM MONITOR
	JUMPE	T1,.POPJ##		;ERROR IF NONE
	ADD	T1,DEVMOD##		;GET DEVMOD WORD
	PJRST	MWORD			;FETCH AND RETURN
>;END IFN FTUUO
	SUBTTL	UUO simulation -- UDEVTYP - Get device type

UDEVTYP::
IFN FTUUO,<
	TLNE	F,(FL.SPY)
	  JRST	SDEVTYP
>;END IF FTUUO
	DEVTYP	T1,
	  POPJ	P,
	JRST	.POPJ1##
IFN FTUUO,<
SDEVTYP:SUBI	T1,.UXTRM		;REMOVE OFFSET
	ADD	T1,LINTAB		;GET LDB ADDR
	PUSHJ	P,MWORDR		;FROM MONITOR
	JUMPE	T1,.POPJ##		;ERROR IF NONE
	ADD	T1,LDBDDB##		;GET DDB ADDR
	PUSHJ	P,MWORDR		;FROM MONITOR
	JUMPE	T1,.POPJ##		;ERROR IF NONE
	ADD	T1,DEVJOB##		;POINT TO JOB NUMBER
	PUSHJ	P,MWORD			;FETCH FROM MONITOR
	LDB	T1,[POINT 9,T1,35]	;LOAD JOB NUMBER
	STORE	T1,T1,TY.JOB		;STORE WHERE DEVTYP STORES
	JRST	.POPJ1##		;AND RETURN
>;END IFN FTUUO
	SUBTTL	UUO simulation -- UDNET - Return DECnet data


UDNET::	TLNN	F,(FL.DECNET)		;HAVE DECNET NETWORK SUPPORT?
	POPJ	P,			;NOPE

IFN FTUUO,<
	TLNE	F,(FL.SPY)		;SPYING?
	JRST	SDNET			;YES
>;END IFN FTUUO

	DNET.	T1,			;DO THE UUO
	  POPJ	P,			;FAILED
	JRST	.POPJ1##		;RETURN

IFN FTUUO,<
SDNET:	PUSHJ	P,.SAVE4##		;SAVE SOME ACS
	MOVE	P1,T1			;COPY ARG BLOCK POINTER
	MOVE	P2,P1			;MAKE A COPY FOR STORAGE
	LDB	T2,[POINTR (.DNFFL(P1),DN.ARG)] ;GET ARG BLOCK LENGTH
	MOVN	T1,T2			;NEGATE IT
	HRL	P2,T1			;MAKE AOBJN POINTER TO ARG BLOCK
	LDB	T1,[POINTR (.DNFFL(P1),DN.FNC)] ;GET FUNCTION CODE
	MOVSI	T3,-LENDNU		;GET -TABLE LENGTH

DNET.1:	LDB	T4,[POINT 9,DNUTAB(T3),8] ;GET A FUNCTION CODE
	CAIE	T1,(T4)			;MATCH?
	AOBJN	T3,DNET.1		;NO--LOOP FOR ALL
	SKIPL	T3			;ERROR IF NOT SIMULATED
	$STOP	(DNS,<DNET. UUO function >,E.NNS)
	LDB	T4,[POINT 9,DNUTAB(T3),17] ;GET MINIMUM ARGUMENT LENGTH
	CAILE	T4,0(T2)		;LARGE ENOUGH?
	$STOP	(IDA,<Illegal DNET. UUO argument block>,)
	HRRZ	T4,DNUTAB(T3)		;GET DISPATCH ADDRESS
	PJRST	(T4)			;GO PROCESS DNET. UUO FUNCTION

DEFINE	$DNU	(FNC,LEN,ADR),<BYTE (9)FNC(9)LEN(18)ADR>
DNUTAB:	$DNU	(.DNLNN,03,DNULNN)	;(01) LIST NODES
	$DNU	(.DNNDI,03,DNUNDI)	;(02) RETURN NODE INFORMATION
	$DNU	(.DNSLS,03,DNUSLS)	;(03) SHOW LINK STATUS
LENDNU==.-DNUTAB			;LENGTH OF TABLE
; DNET. UUO function 1 (.DNLNN) - List nodes
DNULNN:	MOVE	T1,.DNFFL(P1)		;GET FLAGS
	AND	T1,  [DN.FLK!DN.FLR!DN.FLE] ;KEEP JUST THE FLAGS
	TXNE	T1,  <DN.FLK!DN.FLR!DN.FLE> ;MAKE SURE ONE OF THESE IS LIT
	TXNE	T1,^-<DN.FLK!DN.FLR!DN.FLE> ;AND MAKE SURE NOTHING ELSE IS
	  JRST	DNUILF			;ILLEGAL CONBINATION OF FLAGS
	TXNE	T1,DN.FLE		;EXECUTOR?
	MOVE	P3,RNLCL##		;SET FLAG FOR LOCAL
	TXNE	T1,DN.FLR		;ACTIVE?
	MOVE	P3,RNRCH##		;SET FLAG FOR REACHABLE
	TXNE	T1,DN.FLK		;KNOWN?
	MOVSI	P3,-1			;MATCH ON ALL NODES
	MOVEI	T1,0			;INIT COUNT OF RETURNED NODES
	PUSHJ	P,DNUPUT		;STORE ZERO
	  JRST	.POPJ1##		;END OF ARGUMENT BLOCK
	MOVEI	P4,0			;INIT NODE NUMBER

DNULN1:	AOS	T1,P4			;GET NEXT NODE NUMBER
	ADD	T1,RTRNRV		;POINT TO ROUTER VECTOR
	PUSHJ	P,XWORD			;GET IT
	MOVE	T2,T1			;SAVE INCASE NO NODE NAME
	TDNN	P3,T1			;TEST ROUTER FLAGS FOR APPLICABILITY
	JRST	DNULN3			;NO MATCH
	MOVE	T1,P4			;GET NODE NUMBER AGAIN
	ADD	T1,SCTNDT		;POINT TO NODE NAMES
	PUSHJ	P,XWORD			;GET IT
	JUMPN	T1,DNULN2		;OK IF WE HAVE A NAME
	TDNN	T2,RNRCH##		;BUT IS IT REACHABLE?
	JRST	DNULN3			;NOPE
	MOVE	T1,P4			;THEN RETURN THE NODE NUMBER

DNULN2:	PUSHJ	P,DNUPUT		;STORE NAME OR NUMBER
	  JRST	.POPJ1##		;END OF ARGUMENT BLOCK
	AOS	.DNCNT(P1)		;COUNT NODES

DNULN3:	CAMG	P4,RTRMXN		;CHECKED ALL NODES YET?
	JRST	DNULN1			;NO
	JRST	.POPJ1##		;RETURN
; DNET. UUO function 2 (.DNNDI) - Return node information
DNUNDI:	MOVE	T1,.DNFFL(P1)		;GET FLAGS
	AND	T1,[DN.FLS!DN.FLK!DN.FLR!DN.FLE] ;KEEP JUST THE FLAGS
	TXNE	T1,DN.FLS		;STEPPING?
	TXNE	T1,<DN.FLK!DN.FLR!DN.FLE> ;MAKE SURE ONE QUALIFIER
	TXNE	T1,^-<DN.FLS!DN.FLK!DN.FLR!DN.FLE> ;AND MAKE SURE NO JUNK
	  JRST	DNUILF			;ILLEGAL CONBINATION OF FLAGS
	TXNE	T1,DN.FLS		;STEPPING?
	TRO	P3,1			;YES
	TXNE	T1,DN.FLE		;EXECUTOR?
	MOVE	P3,RNLCL##		;SET FLAG FOR LOCAL
	TXNE	T1,DN.FLR		;ACTIVE?
	MOVE	P3,RNRCH##		;SET FLAG FOR REACHABLE
	TXNE	T1,DN.FLK		;KNOWN?
	MOVSI	P3,-1			;MATCH ON ALL NODES
	MOVE	T1,.DNNAM(P1)		;GET NODE NAME
	TRNE	P3,1			;STEPPING?
	JUMPE	T1,DNUND1		;YES, SKIP CONVERSION IF NODE NAME ZERO
	TLNN	T1,-1			;REALLY HAVE A NAME?
	JRST	DNUND0			;NO
	PUSHJ	P,SCTN2A		;CONVERT TO NODE NAME TO NUMBER (ADDR)
	  JRST	DNUNSN			;NO SUCH NODE

DNUND0:	SKIPL	T1
	CAMLE	T1,SCTMXN		;A LEGAL NODE NUMBER?
	  JRST	DNUNSN			;NO
	MOVE	P4,T1			;PRESERVE THE NODE NUMBER
	MOVE	T1,.DNNAM(P1)		;GET NODE NAME BACK
	PUSHJ	P,DNUPUT		;ADVANCE POINTER
	  JRST	DNUADE			;SHOULDN'T HAPPEN
	JRST	DNUND3			;ONWARD

DNUND1:	MOVEI	P4,0			;INIT NODE NUMBER

DNUND2:	AOS	T1,P4			;GET NEXT NODE NUMBER
	CAMLE	T1,RTRMXN		;CHECKED ALL NODES YET?
	JRST	[MOVEI	T1,0		;CLEAR NODE NAME
		 PJRST	DNUPUT]		;STORE IT AND RETURN
	ADD	T1,RTRNRV		;POINT TO ROUTER VECTOR
	PUSHJ	P,XWORD			;GET IT
	TDNN	P3,T1			;TEST ROUTER FLAGS FOR APPLICABILITY
	JRST	DNUND2			;NO MATCH
	MOVE	T1,P4			;GET NODE NUMBER AGAIN
	ADD	T1,SCTNDT		;POINT TO NODE NAMES
	PUSHJ	P,XWORD			;GET IT
	JUMPE	T1,DNUND2		;PRETEND IT'S NOT THERE IF NO NAME
	PUSHJ	P,DNUPUT		;RETURN IN ARG BLOCK
	  JRST	.POPJ1##		;END OF ARGUMENT BLOCK

DNUND3:	MOVE	T4,P4			;GET NODE NUMBER
	ADD	T4,RTRNRV		;OFFSET INTO ROUTER VECTOR
	SETZ	T3,			;CLEAR DESTINATION
	MOVE	T1,RTNRCH		;REACHABILITY
	PUSHJ	P,BWORD			;GET BYTE
	DPB	T1,[POINTR (T3,DN.RCH)]	;STORE
	MOVE	T1,RTNHOP		;NUMBER OF HOPS
	PUSHJ	P,BWORD			;GET IT
	DPB	T1,[POINTR (T3,DN.HOP)]	;STORE
	MOVE	T1,RTNCST		;COST
	PUSHJ	P,BWORD			;GET IT
	DPB	T1,[POINTR (T3,DN.CST)]	;STORE
	MOVE	T1,T3			;GET WORD
	PUSHJ	P,DNUPUT		;PUT IN ARG BLOCK
	  JUMPE	.POPJ1##		;END OF BLOCK

DNUND4:	SETZ	T4,			;CLEAR DESTINATION
	MOVE	T1,P4			;GET NODE NUMBER
	PUSHJ	P,SRHNOD		;FIND NODE DATA BASE
	  JRST	DNUND5			;IT'S NOT THERE
	MOVE	T2,T1			;SAVE ADDRESS
	ADD	T1,NN.DLY##		;OFFSET TO DELAY WORD
	PUSHJ	P,XWORD			;GET DELAY
	DPB	T1,[POINTR (T4,DN.DLY)]	;STORE
	MOVE	T1,T2			;GET ADDRESS AGAIN
	ADD	T1,NN.LKC##		;OFFSET TO NUMBER OF LINKS
	PUSHJ	P,XWORD			;GET COUNT
	DPB	T1,[POINTR (T4,DN.LNK)]	;STORE ACTIVE LINKS
	TXO	T4,DN.VLD		;INDICATE DATA IS VALID

DNUND5:	MOVE	T1,T4			;GET WORD TO STORE
	PUSHJ	P,DNUPUT		;PUT IN ARG BLOCK
	  JRST	.POPJ1##		;END OF BLOCK
	MOVE	T1,P4			;GET NODE NUMBER
	PUSHJ	P,DNUPUT		;PUT IN ARG BLOCK
	  JRST	.POPJ1##		;END OF BLOCK

DNUND6:	SETZM	DCNCKT+0		;CLEAR
	SETZM	DCNCKT+1		; CIRCUIT
	SETZM	DCNCKT+2		;  TEXT
	SETZM	DCNCKT+3		;   BLOCK
	MOVE	T1,P4			;GET NODE NUMBER
	ADD	T1,RTRNRV		;OFFSET INTO ROUTER VECTOR
	MOVE	T4,T1			;SAVE ADDRESS
	MOVE	T1,RTNRCH		;REACHABILITY
	PUSHJ	P,BWORD			;GET BYTE
	MOVE	T2,T1			;SAVE IT
	MOVE	T1,RTNLCL		;LOCAL BIT
	PUSHJ	P,BWORD			;GET BYTE
	ANDCM	T2,T1			;TRUTH TABLE
	JUMPN	T2,DNUND7		;THE LOCAL NODE?
	MOVE	T1,[ASCII |local|]	;YES
	MOVEM	T1,DCNCKT		;SAVE IT
	JRST	DNUND8			;GO RETURN CIRCUIT TEXT

DNUND7:	MOVE	T1,P4			;GET NODE NUMBER
	ADD	T1,RTRNRV		;OFFSET INTO ROUTER VECTOR
	ADD	T1,RTROFS		;NOW GET SECONDARY ROUTING VECTOR
	PUSHJ	P,XWORD			;GET IT
	ADD	T1,RC.LID##		;OFFSET TO THE LINE ID
	PUSHJ	P,XWORD			;GET IT
	PUSHJ	P,NMXC2N		;CONVERT TO CIRCUIT ID

DNUND8:	MOVE	T2,[-4,,DCNCKT]		;AOBJN POINTER TO TEXT
	MOVE	T1,(T2)			;GET A WORD
	PUSHJ	P,DNUPUT		;PUT A WORD
	  JRST	.POPJ1##		;END OF BLOCK
	AOBJN	T2,.-2			;LOOP
	MOVEI	T1,0			;GET A ZERO
	PUSHJ	P,DNUPUT		;TERMINATE THE ARG BLOCK
	  JFCL				;END OF BLOCK
	JRST	.POPJ1##		;FINALLY ALL DONE!
; DNET. UUO function 3 (.DNSLS) - Show link status
DNUSLS:	POPJ	P,
; Store a word in the argument block
DNUPUT:	AOBJP	P2,.POPJ##		;ADVANCE TO NEXT WORD
	MOVEM	T1,(P2)			;STORE A WORD
	JRST	.POPJ1##		;RETURN


; Search for a DECnet node number given a name
SCTN2A:	SKIPN	T3,T1			;COPY NODE NAME
	POPJ	P,			;MUST HAVE ONE
	MOVEI	T2,0			;INIT NODE NUMBER

SCTN21:	AOS	T1,T2			;GET A NODE NUMBER
	ADD	T1,SCTNDT		;OFFSET INTO NAME VECTOR
	PUSHJ	P,XWORD			;GET THE NAME
	CAMN	T1,T3			;A MATCH?
	JRST	SCTN22			;YES
	CAMGE	T2,SCTMXN		;CHECKED ALL NODES?
	JRST	SCTN21			;NO--LOOP
	POPJ	P,			;NO SUCH NODE

SCTN22:	MOVE	T1,T2			;GET THE NODE NUMBER
	JRST	.POPJ1##		;AND RETURN



; Search for a DECnet node name given a number
SRHNOD:	MOVE	T2,T1			;COPY NODE NUMBER
	MOVE	T1,NMXNDQ		;GET NETWORK MANGLER'S QUEUE HEADER
	PUSHJ	P,XWORD			; FROM THE MONITOR

SRHN.1:	JUMPE	T1,.POPJ##		;RETURN IF THERE ISN'T ONE
	MOVE	T3,T1			;SAVE DATA BASE ADDRESS
	ADD	T1,$NNNOD##		;OFFSET TO THE NODE NUMBER WORD
	PUSHJ	P,XWORD			;GET IT
	TLZ	T1,600000		;16K NODE NUMBER HACK
	HLRZS	T1			;PUT IN RH
	CAMN	T2,T1			;THE ONE WE'RE LOOKING FOR?
	JRST	SRHN.2			;YES
	MOVE	T1,T3			;GET DATA BASE ADDRESS
	ADD	T1,NN.NXT##		;OFFSET TO NEXT NODE
	PUSHJ	P,XWORD			;POINT TO IT
	JRST	SRHN.1			;AND LOOP

SRHN.2:	MOVE	T1,T3			;GET ADDRESS OF NODE DATA BASE
	JRST	.POPJ1##		;AND RETURN


; Convert circuit ID
NMXC2N:	PUSHJ	P,.SAVE1##		;SAVE P1
	MOVE	P1,T1			;COPY CIRCUIT ID WORD
	MOVE	T1,[POINT 7,DCNCKT]	;BYTE POINTER
	MOVEM	T1,DCNPTR		;SAVE IT
	MOVEI	T1,<4*5>-1		;BYTE COUNT
	MOVEM	T1,DCNCNT		;SAVE IT
	MOVEI	T1,NMXTYO		;TYPER FOR CIRCUIT STORAGE
	PUSHJ	P,.TYOCH##		;TELL SCAN
	PUSH	P,T1			;SAVE OLD TYPER

;	LOAD	T1,LIDEV,+P1		;GET THE TYPE OF DEVICE
	CAMLE	T1,LD.MAX##		;IN RANGE OF DEVICES WE KNOW?
	  JRST	NMXC21			;NO
	ADD	T1,KONNAM		;OFFSET INTO KONTROLLER TABLE
	PUSHJ	P,XWORD			;GET NAME
	PUSH	P,T1			;SAVE IT
	MOVEI	T1,(P)			;POINT TO NAME
	PUSHJ	P,.TSTRG##		;STORE IT
	POP	P,(P)			;TRIM STACK
	MOVEI	T1,"-"			;SEPERATOR
	PUSHJ	P,.TYOCH##		;STORE IT

;	LOAD	T1,LIKON,+P1		;GET THE KONTROLLER NUMBER
	PUSHJ	P,.TDECW##		;STORE IN DECIMAL
	PUSHJ	P,.TDASH##		;SEPARATOR

;	LOAD	T1,LIUNI,+P1		;GET THE UNIT NUMBER
	PUSHJ	P,.TDECW##		;STORE IN DECIMAL
	PUSHJ	P,.TDASH##		;SEPARATOR

;	LOAD	T1,LIDEV,+P1		;GET THE DEVICE TYPE
	CAME	T1,LD.CIP##		;IS IT A CI?
	JRST NMXC22			;NO, WE ARE DONE
	PUSHJ	P,.TDOT##		;SEPARATOR

;	LOAD	T1,LIDRP,+P1		;GET THE DROP NUMBER (PORT ON THE CI)
	PUSHJ	P,.TDECW##		;STORE IN DECIMAL
	POP	P,T1			;RESTORE OLD CHARACTER TYPER
	JRST	NMXC22			;DONE

NMXC21:	MOVEI	T1,[ASCIZ |???|]	;WE DON'T KNOW THIS KONT
	PUSHJ	P,.TSTRG##		;STORE TEXT

NMXC22:	PJRST	.TYOCH##		;TELL SCAN AND RETURN

NMXTYO:	SOSLE	DCNCNT			;COUNT DOWN
	IDPB	T1,DCNPTR		;STORE CHARACTERS
	POPJ	P,			;RETURN


; DNET. UUO error returns
DNUETB:!
DNUADE:	JSP	T1,DNUERR		;ADDRESS ERROR
DNUWNA:	JSP	T1,DNUERR		;WRONG NUMBER OF ARGUMENTS
DNUIDN:	JSP	T1,DNUERR		;ILLEGAL JOB NUMBER
DNUFNE:	JSP	T1,DNUERR		;ILLEGAL FUNCTION CODE
DNUILF:	JSP	T1,DNUERR		;ILLEGAL FLAG SET
DNUNSN:	JSP	T1,DNUERR		;NO SUCH NODE NAME
DNUNSC:	JSP	T1,DNUERR		;NO SUCH CHANNEL

DNUERR:	SUBI	T1,DNUETB		;GET ERROR CODE
	HRRZS	T1			;NO JUNK
	POPJ	P,			;RETURN

> ;END IFN FTUUO
	SUBTTL	UUO simulation -- UGETLCH - Get line characteristics

UGETLCH::
IFN FTUUO,<
	TLNE	F,(FL.SPY)		;CAN WE SPY?
	  JRST	SGETLCH			;YES!
>;END IFN FTUUO
	GETLCH	T1			;NO--DO UUO
	POPJ	P,			;AND RETURN
IFN FTUUO,<
SGETLCH:ADD	T1,LINTAB		;GET LDB ADDRESS
	PUSHJ	P,MWORD			;FROM MONITOR
	ADD	T1,$LDDCH		;POINT TO CHARACTERISTICS WORD
	PUSHJ	P,MWORD			;GET FROM MONITOR
	MOVSI	T1,(T1)			;POSITION LIKE UUO
	POPJ	P,			;AND RETURN
>;END IFN FTUUO

	SUBTTL	UUO simulation -- UGETLIN - return TTY line number


UGETLIN::
IFN FTUUO,<
	TLNE	F,(FL.SPY)		;CAN WE SPY?
	  JRST	SGETLIN			;YES!
> ;END IFN FTUUO

	GETLIN	T1,			;NO--DO THE UUO
	POPJ	P,			;AND RETURN

IFN FTUUO,<
SGETLIN:MOVE	T1,MYJOB##		;GET MY JOB NUMBER
	ADD	T1,TTYTAB		;INDEX INTO TTYTAB
	PUSHJ	P,MWORDR		;FETCH FROM MONITOR
	ADD	T1,DEVNAM##		;OFFSET TO DDB NAME
	PJRST	MWORD			;GET SIXBIT TTY NAME AND RETURN
> ;END IFN FTUUO
	SUBTTL	UUO simulation -- GETTABs - MTAB, JTAB, GTAB routines

MTAB::	JUMPGE	T1,GTAB			;JUMP IF POSITIVE
	HRL	T1,MYJOB		;ELSE INCLUDE MY JOB
	JRST	GTAB			;AND USE THAT
JTAB::	HRLI	T1,(O)			;INCLUDE JOB NUMBER IN J
GTAB::	PUSHJ	P,.MAPG##		;SIMULATE A GETTAB
	 JRST	MAPSTP##		;MAPPING ERROR
	POPJ	P,			;RETURN
	SUBTTL	UUO simulation -- UGOBSTR - Return search list information


UGOBSTR::
IFN FTUUO,<
	TLNE	F,(FL.SPY)		;CAN WE SPY?
	  JRST	SGOBSTR			;YES!
> ;END IFN FTUUO

	GOBSTR	T1,			;DO THE UUO
	  POPJ	P,			;FAILED
	JRST	.POPJ1##		;RETURN

IFN FTUUO,<
SGOBSTR:PUSHJ	P,.SAVE4##		;SAVE SOME ACS
	PUSHJ	P,STRCHK		;MAKE SURE THE STR DB IS SETUP
	PUSHJ	P,GOBPTR		;SET UP ARG BLOCK AND S/L POINTERS
	  POPJ	P,			;SOMETHING'S WRONG
	MOVE	T1,.DFGNM(P1)		;GET POSSIBLE STR NAME
	JUMPE	T1,GOBS.1		;JUMP IF WANT THE FIRST STR AFTER FENCE
	CAMN	T1,[EXP -1]		;WANT THE FIRST STR IN S/L?
	JRST	GOBS.2			;YES
	PUSHJ	P,STRNFS		;CONVERT STR NAME TO FS NUMBER
	  SKIPA	T1,[DFGIF%]		;NO SUCH STR
	JRST	GOBS.5			;SEARCH FOR A SPECIFIC STR
	POPJ	P,			;RETURN

; Get first STR after fence
GOBS.1:	PUSHJ	P,GOBGET		;GET AN ENTRY
	JUMPN	T1,GOBS.1		;LOOP IF NOT THE FENCE
	PUSHJ	P,GOBGET		;GET NEXT STR
	JUMPN	T1,GOBS.3		;HAVE ONE AFTER THE FENCE?
	SOJA	T1,GOBS.3		;NO--MUST BE AN EMPTY S/L

; Get the next STR
GOBS.2:	PUSHJ	P,GOBGET		;GET NEXT STR

; Get the current STR
GOBS.3:	MOVEM	T1,(P2)			;STORE STR NAME
	AOBJP	P2,GOBS.4		;RETURN IF END OF ARG BLOCK
	SETZM	(P2)			;CLEAR RESERVED WORD
	AOBJP	P2,GOBS.4		;RETURN IF END OF ARG BLOCK
	MOVEM	T2,.DFGST(P1)		;STORE FS BITS

GOBS.4:	MOVE	T1,P1			;RESET THE CALLER'S AC
	JRST	.POPJ1##		;AND RETURN

; Get a specific STR
GOBS.5:	PUSHJ	P,GOBGET		;GET A STR
	CAMN	T1,[EXP -1]		;END OF S/L?
	JRST	GOBS.3			;YES--RETURN THAT
	CAMN	T1,.DFGNM(P1)		;MATCH THE CALLER'S ARG?
	JRST	GOBS.2			;YES--THEN GIVE HIM THE NEXT ONE
	JRST	GOBS.5			;ELSE KEEP LOOKING
; Set up return block and search list pointers
; Call:	PUSHJ	P,GOBPTR
;
GOBPTR:	MOVE	P1,T1			;COPY THE CALLER'S ARG BLOCK PTR
	HLRZ	P2,(P1)			;GET LENGTH
	SKIPN	P2			;CONVERT 0
	MOVEI	P2,3			; TO THREE
	CAIG	P2,5			;MAKE SURE LENGTH
	CAIGE	P2,3			; IS OK
	JRST	GOBP.1			;LOSE
	MOVNS	P2			;NEGATE IT
	HRLI	P2,.DFGNM(P1)		;LOAD FIRST STORAGE ADDRESS
	MOVSS	P2			;MAKE AN AOBJN POINTER
	MOVE	T1,.DFGJN(P1)		;GET THE JOB NUMBER
	CAMLE	T1,JOBMAX		;JOB NUMBER LEGAL?
	JRST	GOBP.2			;NO
	HRLI	T1,.GTPPN		;GETTAB TABLE
	MOVSS	T1			;POSITION ARGS
	PUSHJ	P,GTAB			;GET THAT JOB'S PPN
	CAME	T1,.DFGPP(P1)		;PPNS MATCH?
	JRST	GOBP.2			;NOPE
	SKIPE	.DFGJN(P1)		;WHICH SEARCH LIST?
	SKIPA	T1,$JBSRC		;JOB
	MOVE	T1,$SYSRC		;SYS
	PUSHJ	P,MWORD			;GET THE BYTE POINTER
	MOVE	P3,T1			;PUT IN A SAFE PLACE
	TLZ	P3,(@(17))		;ZAP MONITOR'S INDEXING AND INDIRECTION
	SKIPE	.DFGJN(P1)		;NO INDEXING IF THE SYSTEM SEARCH LIST
	TLO	P3,T1			;INDEX OF OUR T1
	MOVE	T1,.DFGJN(P1)		;GET JOB NUMBER AGAIN
	ADD	T1,PDBPTR		;OFFSET INTO JBTPDB
	PUSHJ	P,MWORDR		;FIND THIS JOB'S PDB
	HRRI	P3,@P3			;POINT IT AT MONITOR ADDRESS SPACE
	TLZ	P3,(@(17))		;NO INDEXING OR INDIRECTION NOW
	JRST	.POPJ1##		;RETURN

GOBP.1:	MOVEI	T1,DFGLN%		;ILL ARG BLOCK
	POPJ	P,			;RETURN

GOBP.2:	MOVEI	T1,DFGPP%		;JOB/PPN MISMATCH
	POPJ	P,			;RETURN

REPEAT 0,<
GOBP.3:	MOVEI	T1,DFGNP%		;NO PRIVS
	POPJ	P,			;RETURN
>
; Get a S/L entry
; Call:	PUSHJ	P,GOBGET
;
; On return, T1 = STR name, T2 = file structure bits
;
GOBGET:	IBP	P3			;POINT TO NEXT BYTE
	MOVEI	T1,@P3			;GET ADDRESS FROM BYTE POINTER
	PUSHJ	P,MWORD			;GET WORD
	HLLZ	T2,P3			;GET LH BYTE POINTER
	HRRI	T2,T1			;POINT TO ADDRESS
	LDB	T1,T2			;GET FILE STRUCTURE NUMBER
	MOVE	T2,T1			;COPY IT
	AND	T1,FS.NMK##		;KEEP ONLY THE FS NUMBER
	CAMG	T1,.FSMAX##		;LEGAL FS NUMBER?
	CAMGE	T1,.FSMIN##		;CAN'T BE TOO SMALL EITHER
	JRST	GOBG.1			;NO
	MOVE	T1,STRTAB(T1)		;GET STR NAME
	AND	T2,FS.BMK##		;KEEP ONLY THE FS BITS
	MOVE	T3,FS.BMK##		;GET MASK
	JFFO	T3,.+1			;COMPUTE BITS TO LSH
	LSH	T2,1(T4)		;LEFT JUSTIFY THEM
	POPJ	P,			;RETURN

GOBG.1:	SETZ	T2,			;FS BITS ARE MEANINGLESS
	CAMN	T1,.FSFNC##		;THE FENCE?
	SETZ	T1,			;YES--GIVE BACK A ZERO
	CAMN	T1,.FSEND##		;END OF S/L?
	MOVNI	T1,1			;YES--GIVE BACK A MINUS ONE
	POPJ	P,			;RETURN
> ;END IFN FTUUO
	SUBTTL	UUO simulation -- UGTNTN - Get node/line from terminal number

UGTNTN::TLNN	F,(FL.ANF10)		;HAVE ANF10 NETWORK SUPPORT?
	POPJ	P,			;NOPE

IFN FTUUO,<
	TLNE	F,(FL.SPY)		;CAN WE SPY?
	  JRST	SGTNTN			;YES!
>;END IFN FTUUO
	GTNTN.	T1,			;NO--DO UUO
	  POPJ	P,			;FAILED
	JRST	.POPJ1##		;NORMAL

IFN FTUUO,<
SGTNTN:	SUBI	T1,.UXTRM		;REMOVE OFFSET
	ADD	T1,LINTAB		;GET LDB ADDR
	PUSHJ	P,MWORD			;FROM MONITOR
	MOVEI	T4,(T1)			;SAVE LDB ADDR
	ADD	T1,$LDDCH		;GET CHARACTERISITICS
	PUSHJ	P,MWORD			;FROM MONITOR
	TDNN	T1,LDRREM##		;SEE IF NETWORK TTY
	 JRST	SGTNT1			;NO--LOCAL TTY
	MOVE	T1,T4			;GET LDB ADDR
	ADD	T1,LDBREM##		; AND LDBREM WORD
	PUSHJ	P,MWORD			;FROM MONITOR
	TSNN	T1,LRLCON##		;CONNECTED?
	 POPJ	P,			;NO--ERROR
	MOVEI	T1,3(T4)		;GET LDB+X ADDR
	ADD	T1,LDBREM##		; AND LDBREM WORD
	PUSHJ	P,MWORD			;FROM MONITOR
	LDB	T2,[POINT 16,T1,35]	;GET NODE NUMBER
	MOVEI	T1,2(T4)		;GET LDB+X ADDR
	ADD	T1,LDBREM##		; AND LDBREM WORD
	PUSHJ	P,MWORD			;FROM MONITOR
	LDB	T1,[POINT 10,T1,35]	;GET LINE NUMBER
	HRLI	T1,(T2)			;INCLUDE NODE NUMBER
	JRST	.POPJ1##		;AND RETURN
SGTNT1:	LDB	T1,[POINT 9,T1,35]	;GET LINE NUMBER
	HRL	T1,CENSTA		;INCLUDE LOCAL NODE NUMBER
	JRST	.POPJ1##		;AND RETURN
>;END IFN FTUUO
	SUBTTL	UUO simulation -- UJOBSTS - Get job status bits

UJOBSTS::
IFN FTUUO,<
	TLNE	F,(FL.SPY)		;CAN WE SPY?
	  JRST	SJOBSTS			;YES!
>;END IFN FTUUO
	JOBSTS	T1,			;NO--DO UUO
	  POPJ	P,			;ERROR
	JRST	.POPJ1##		;NORMAL
IFN FTUUO,<
SJOBSTS:MOVNI	T1,(T1)			;GET POSTIVE JOB NUMBER
	ADD	T1,TTYTAB		;GET DDB ADDR FOR JOB
	PUSHJ	P,MWORD			;FROM MONITOR
	ADD	T1,DEVIOS##		;POINT TO DEVIOS
	PUSHJ	P,MWORD			;GET FROM MONITOR
	TSNE	T1,IO##			;OUTPUT?
	 TXOA	T1,JB.UOA		;YES--FLAG AND SKIP
	  MOVEI	T1,0			;NO--RETURN ZERO
	JRST	.POPJ1##		;AND RETURN
>;END IFN FTUUO
	SUBTTL	UUO simulation -- UNODE - Return ANF-10 network information


UNODE::	TLNN	F,(FL.ANF10)		;HAVE ANF10 NETWORK SUPPORT?
	POPJ	P,			;NOPE

IFN FTUUO,<
	TLNE	F,(FL.SPY)		;SPYING?
	  JRST	SNODE			;YES
>;END IFN FTUUO

	NODE.	T1,			;DO THE UUO
	  POPJ	P,			;FAILED
	JRST	.POPJ1##		;RETURN

IFN FTUUO,<
SNODE:	HLRZ	T2,T1			;GET FUNCTION CODE
	MOVSI	T3,-LENNOD		;GET -LENGTH OF TABLE TO SEARCH

NODE.1:	LDB	T4,[POINT 9,NODTAB(T3),8] ;GET A FUNCTION CODE
	CAIE	T2,(T4)			;MATCH?
	  AOBJN	T3,NODE.1		;NO--LOOP FOR ALL
	JUMPGE	T3,E$$NNS		;ERROR IF NOT SIMULATED
	LDB	T4,[POINT 9,NODTAB(T3),17] ;GET MINIMUM ARGUMENT LENGTH
	CAMLE	T4,0(T1)		;LARGE ENOUGH?
	$STOP	(INA,<Illegal NODE. UUO argument block>,)
	HRRZ	T4,NODTAB(T3)		;GET DISPATCH ADDRESS
	PJRST	(T4)			;GO PROCESS NODE. UUO FUNCTION


	$STOP	(NNS,<NODE. UUO function >,E.NNS)
E.NNS:	HLRZS	T1			;GET FUNCTION CODE
	PUSHJ	P,.TOCTW##		;TYPE IT
	MOVEI	T1,[ASCIZ/ not simulated/]
	PJRST	.TSTRG##		;AND FINISH OFF


DEFINE	$NOD	(FNC,LEN,ADR),<BYTE (9)FNC(9)LEN(18)ADR>
NODTAB:	$NOD	(.NDRNN,02,NOD2)	;(02) RETURN NODE NAME/NUMBER
	$NOD	(.NDNDB,04,NOD13)	;(13) RETURN INFO FROM THE NDB
LENNOD==.-NODTAB			;LENGTH OF TABLE
; NODE. UUO function 2
; Return node name/number
;
NOD2:	MOVE	T1,1(T1)		;GET NODE NAME OR NUMBER
	PUSHJ	P,SRCNDB		;SEARCH FOR THE NDB
	  POPJ	P,			;NO SUCH NODE
	MOVEI	T1,NODNNM		;ASSUME NODE NUMBER
	TLNN	T3,505050		;OCTAL OR SIXBIT
	MOVEI	T1,NODSNM		;WANTS A NAME
	PUSHJ	P,(T1)			;GET NUMBER OR NAME
	JRST	.POPJ1##		;AND RETURN
; NODE. UUO function 13
; Return node information from the NDB
;
NOD13:	PUSHJ	P,.SAVE3##		;SAVE SOME ACS
	MOVN	P1,0(T1)		;GET -LENGTH
	ADDI	P1,3			;ACCOUNT FOR 3 WORD HEADER
	HRLZS	P1			;PUT -LENGTH IN LH
	HRRI	P1,3(T1)		;MAKE AN AOBJN POINTER
	JUMPGE	P1,.POPJ##		;NEED AT LEAST 1 WORD TO STORE RESULTS
	SKIPE	P2,2(T1)		;GET SUBFUNCTION CODE
	CAILE	P2,NDBMAX		;A REASONABLE NUMBER?
	POPJ	P,			;NO
	SKIPN	NDBTAB-1(P2)		;DO WE HANDLE THIS SUBFUNCTION?
	POPJ	P,			;NO
	MOVE	T1,1(T1)		;GET NODE NAME OR NUMBER
	PUSHJ	P,SRCNDB		;FIND ITS NDB
	  POPJ	P,			;NO SUCH NODE
	HLRE	T1,NDBTAB-1(P2)		;GET LH OF DISPATCH
	CAME	T1,[EXP -1]		;SUBROUTINE?
	JRST	NETBYT			;JUST EXTRACT A BYTE FROM THE NDB
	HRRZ	T1,NDBTAB-1(P2)		;GET PROCESSOR ADDRESS
	JRST	(T1)			;GO TO IT

NDBTAB:	Z	NB%NNM##		;(01) NODE NUMBER
	XWD	-1,NETSNM		;(02) STATION NAME
	XWD	-1,NETSID		;(03) SOFTWARE ID
	XWD	-1,NETSDT		;(04) SOFTWARE CREATION DATE
	Z	NB%LMA##		;(05) LMA - LAST MESSAGE ASSIGNED
	Z	NB%LMS##		;(06) LMS - LAST MESSAGE SENT
	Z	NB%LAR##		;(07) LAR - LAST ACK RECEIVED
	Z	NB%LAP##		;(10) LAP - LAST ACK PROCESSED
	Z	NB%LMR##		;(11) LMR - LAST MESSAGE RECEIVED
	Z	NB%LMP##		;(12) LMP - LAST MESSAGE PROCESSED
	Z	NB%LAS##		;(13) LAST MESSAGE SENT
	Z	NB%MOM##		;(14) MAX. OUTSTANDING MESSAGE COUNTER
	XWD	-1,NETTOP		;(15) TOPOLOGY AND COSTS
	XWD	-1,NETCNF		;(16) OBJECT TYPES
	Z	NB%CTJ##		;(17) STATION CONTROL JOB NUMBER
	XWD	-1,NETOPR		;(20) OPR TTY NUMBER
NDBMAX==.-NDBTAB			;LENGTH OF TABLE
; Extract a single byte from an NDB
NETBYT:	MOVE	T1,@NDBTAB-1(P2)	;GET BYTE POINTER
	PUSHJ	P,BWORD			;GET THE BYTE IN QUESTION
	MOVEM	T1,(P1)			;PUT IT IN CALLER'S ARG BLOCK
	JRST	.POPJ1##		;AND RETURN


; Return the station name
NETSNM:	PUSHJ	P,NODSNM		;GET NODE NAME
	MOVEM	T1,(P1)			;SAVE IT AWAY
	JRST	.POPJ1##		;AND RETURN


; Return the software id as an ASCIZ string
NETSID:	MOVE	T1,NB%SID##		;GET BYTE POINTER
	PUSHJ	P,BWORD			;GET ADDRESS OF STRING
	MOVE	P2,T1			;COPY STATION ID ADDRESS
	JRST	NETSTR			;GO RETURN A STRING


; Return the software creation date as an ASCIZ string
NETSDT:	MOVE	T1,NB%SDT##		;GET BYTE POINTER
	PUSHJ	P,BWORD			;GET ADDRESS OF STRING
	MOVE	P2,T1			;COPY STATION DATE ADDRESS


; Common routine to return an ASCIZ string
NETSTR:	MOVE	T1,P2			;GET ADDRESS
	PUSHJ	P,MWORD			;GET CONTENTS
	MOVEM	T1,(P1)			;SAVE IT AWAY
	ADDI	P2,1			;POINT TO NEXT WORD
	TRNE	T1,377			;END OF ASCIZ STRING?
	AOBJN	P1,NETSTR		;NO--LOOP
	JRST	.POPJ1##		;RETURN
; Return the topology and costs
NETTOP:	MOVE	P2,NB%NGH##		;GET BYTE POINTER TO DEVICES
	HRRI	P2,@P2			;POINT IT AT MONITOR ADDRESS SPACE
	TLZ	P2,(@(17))		;NO INDEXING OR INDIRECTION
	MOVE	P3,NB%NGL##		;GET BYTE POINTER TO LAST NEIGHBOR
	HRRI	P3,@P3			;POINT IT AT MONITOR ADDRESS SPACE
	TLZ	P3,(@(17))		;NO INDEXING OR INDIRECTION

NETT.1:	MOVEI	T1,@P2			;GET ADDRESS FROM BYTE POINTER
	PUSHJ	P,MWORD			;GET WORD
	HLLZ	T2,P2			;GET LH BYTE POINTER
	HRRI	T2,T1			;POINT TO ADDRESS
	LDB	T3,T2			;GET A COUNT
	LSHC	T3,-11			;CUZ WE KNOW
	LSH	T3,11			; WE'RE DEALING WITH
	LSHC	T3,11			;  18 BIT BYTES
	IBP	P2			;POINT TO NEXT BYTE
	JUMPE	T3,NETT.2		;IGNORE NULL ENTRIES
	MOVSM	T3,(P1)			;GIVE HIM COST,,NODE

NETT.2:	CAMN	P2,P3			;CHECKED ALL NEIGHORS?
	JRST	NETT.3			;YES--DONE
	JUMPE	T3,NETT.1		;DON'T ADJUST POINTER IF NO STORE
	AOBJN	P1,NETT.1		;LOOP
	JUMPGE	P1,.POPJ##		;ERROR IF ARG BLOCK TOO SHORT

NETT.3:	SETZM	(P1)			;TERMINATE BLOCK
	JRST	.POPJ1##		;AND RETURN
; Return the configuration
; *** Note ***
; This routine returns the NCL object types and device counts
; in reverse order from the way the NODE. UUO does it.  This
; shouldn't matter however, since intelligent programs should
; key off the NCL object type and not depend on the order of
; the entries being returned.  It benefits WHO to do it this
; way so the configuration typeout looks the same as the NODE
; command produces.
NETCNF:	MOVN	P2,OBJ.MX##		;GET -NUMBER OF ANF-10 OBJECTS
	HRLZS	P2			;MAKE AN AOBJN POINTER
	MOVE	P3,NB%DEV##		;GET BYTE POINTER TO DEVICES
	HRRI	P3,@P3			;POINT IT AT MONITOR ADDRESS SPACE
	TLZ	P3,(@(17))		;NO INDEXING OR INDIRECTION

NETC.1:	MOVEI	T1,@P3			;GET ADDRESS FROM BYTE POINTER
	PUSHJ	P,MWORD			;GET WORD
	HLLZ	T2,P3			;GET LH BYTE POINTER
	HRRI	T2,T1			;POINT TO ADDRESS
	LDB	T3,T2			;GET A COUNT
	IBP	P3			;POINT TO NEXT BYTE
	JUMPE	T3,NETC.3		;IGNORE NULL ENTRIES
	HRL	T3,P2			;INCLUDE NCL OBJECT TYPE
	MOVEM	T3,(P1)			;STORE IN CALLER'S ARG BLOCK
	AOBJP	P2,NETC.2		;ALL THROUGH OBJECT TABLE?
	AOBJN	P1,NETC.1		;LOOP
	POPJ	P,			;ARG BLOCK TOO SHORT

NETC.2:	AOSA	P1			;+1

NETC.3:	AOBJN	P2,NETC.1		;ON TO THE NEXT ENTRY
	SETZM	(P1)			;TERMINATE BLOCK
	JRST	.POPJ1##		;AND RETURN


; Return OPR TTY number
NETOPR:	MOVE	T1,NB%OPR##		;GET BYTE POINTER
	PUSHJ	P,BWORD			;GET LDB ADDRESS
	JUMPE	T1,NETO.1		;RETURN IF NO OPR AT THIS STATION
	ADD	T1,$LDDCH		;OFFSET INTO THE LDB
	PUSHJ	P,MWORDR		; WHERE THE LINE NUMBER IS STORED
	TDZA	T1,[777777,,777000]	;KEEP ONLY THE LINE NUMBER

NETO.1:	MOVNI	T1,1			;-1 MEANS NO OPR LINE CONNECTED
	MOVEM	T1,(P1)			;RETURN IT TO THE CALLER
	JRST	.POPJ1##		;AND RETURN
; Return the node number in T1
; Call:	PUSHJ	P,NODNNM
;
NODNNM:	MOVE	T1,NB%NNM##		;GET BYTE POINTER
	PJRST	BWORD			;GET THE NODE NUMBER AND RETURN


; Return the station name in T1
; Call:	PUSHJ	P,NODSNM
;
NODSNM:	MOVE	T1,NB%SNM##		;GET BYTE POINTER
	PUSHJ	P,BWORD			;GET NODE NAME ADDRESS
	JUMPE	T1,.POPJ##		;RETURN IF NO NAME
	PJRST	MWORD			;GET NAME AND RETURN
; Search the NDBs for a given node
; Call:	MOVE	T1, node name or number
;	PUSHJ	P,SRCNDB
;
SRCNDB:	MOVE	T3,T1			;COPY ARGUMENT
	MOVE	T4,NETNDB		;GET FIRST NDB

SRCN.1:	TLNE	T3,505050		;NUMBER OR SIXBIT?
	  JRST	SRCN.2			;SIXBIT

VERSION GE,702,<
	CAMLE	T1,HGHNOD		;WITHIN RANGE?
	 POPJ	P,			;NO--ERROR
	HRLZS	T1			;GET NODE,,0
	HRRI	T1,.GTNDA		;POINT TO NDB GETTAB TABLE
	PUSHJ	P,GTAB			;FETCH
	MOVEI	T4,(T1)			;GET NDB ADDRESS
	JUMPN	T4,.POPJ1##		;RETURN IF NDB EXISTS
	POPJ	P,			;ELSE FAIL
> ;END VERSION GE,702

	PUSHJ	P,NODNNM		;GET NODE NUMBER
	CAIN	T1,(T3)			;NUMBER--MATCH?
	  JRST	.POPJ1##		;YES!
	JRST	SRCN.3			;NO--LOOP

SRCN.2:	PUSHJ	P,NODSNM		;GET NODE NAME
	CAMN	T1,T3			;MATCH USERS?
	 JRST	.POPJ1##		;YES!

SRCN.3:	MOVE	T1,NB%NXT##		;GET BYTE POINTER
	PUSHJ	P,BWORD			;GET ADDRESS OF LINK TO NEXT NDB
	SKIPE	T4,T1			;SET INDEX
	JRST	SRCN.1			;LOOP
	POPJ	P,			;ELSE LOSE

>;END IFN FTUUO
	SUBTTL	UUO simulation -- UPATH - Return a job's path


UPATH::
IFN FTUUO,<
	TLNE	F,(FL.SPY)		;CAN WE SPY?
	  JRST	SPATH			;YES!
> ;END IFN FTUUO

	PATH.	T1,			;DO THE UUO
	  POPJ	P,			;FAILED
	JRST	.POPJ1##		;RETURN

IFN FTUUO,<
SPATH:	PUSHJ	P,.SAVE4##		;SAVE SOME ACS
	PUSHJ	P,STRCHK		;MAKE SURE THE STR DB IS SETUP
	PUSHJ	P,PTHPTR		;SET UP POINTERS
	  POPJ	P,			;SOMETHING'S WRONG
	TDNE	P3,JBPSCN##		;SCANNING TURNED ON?
	SKIPA	T1,[.PTSCY]		;YES
	MOVEI	T1,.PTSCN		;NO
	TSNE	P3,JBPSYS##		;SEARCH SYS AFTER DSK?
	TXO	T1,PT.SYS		;YES
	TSNE	P3,JBPXSY##		;SEARCH NEW BEFORE SYS?
	TXO	T1,PT.NEW		;YES
	TDNE	P3,JBPUFB##		;LIB PPN?
	TXO	T1,PT.LIB		;YES
	MOVEM	T1,(P2)			;SAVE PATH SWITCHES
	AOBJP	P2,PATH.4		;END OF BLOCK?
	PUSHJ	P,SFDPPN		;GET THE DEFAULT PPN
	MOVEM	T1,(P2)			;SAVE IT
	AOBJP	P2,PATH.4		;END OF BLOCK?
	TDZ	P3,[777777,,3]		;NMB ALWAYS RESIDES ON A 4-WORD BOUNDRY
	JUMPE	P3,PATH.5		;NOTHING TO DO IF NO NMB
	PUSH	P,[0]			;MARK END OF PATH

PATH.1:	MOVE	T1,P3			;GET NMB
	ADD	T1,NMBNAM##		; AND NAME
	PUSHJ	P,MWORD			;FROM MONITOR
	PUSH	P,T1			;SAVE THE SFD NAME

PATH.2:	MOVE	T1,P3			;GET NMB
	ADD	T1,NMBPPB##		; AND PPB
	PUSHJ	P,MWORD			;READ WORD
	HLRZ	P3,T1			;SAVE
	TDZN	P3,NMPUPT##		;NAME SHOULD BE OUTPUT?
	JUMPN	P3,PATH.2		;NO, GET NEXT LEVEL IF NOT AT END
	JUMPN	P3,PATH.1		;YES, SAVE NAME AND GET NEXT LEVEL

PATH.3:	POP	P,T1			;GET AN SFD
	MOVEM	T1,(P2)			;STORE IT
	JUMPE	T1,PATH.6		;DONE?
	AOBJN	P2,PATH.3		;LOOP FOR ALL SFD LEVELS

PATH.4:	AOS	P2			;YES

PATH.5:	SETZM	(P2)			;TERMINATE THE LIST

PATH.6:	MOVE	T1,P1			;RELOAD CALLER'S AC
	JRST	.POPJ1##		;AND RETURN
PTHPTR:	MOVE	P1,T1			;COPY THE CALLER'S ARG BLOCK PTR
	HLRZ	P2,P1			;GET LENGTH
	SKIPN	P2			;CONVERT 0
	MOVEI	P2,3			; TO THREE
	CAIG	P2,3			;MAKE SURE LENGTH IS OK
	JRST	PTHP.1			;LOSE
	MOVNS	P2			;NEGATE IT
	HRLI	P2,.PTSWT(P1)		;LOAD FIRST STORAGE ADDRESS
	MOVSS	P2			;MAKE AN AOBJN POINTER
	HLRZ	T1,.PTFCN(P1)		;GET THE JOB NUMBER
	CAMLE	T1,JOBMAX		;JOB NUMBER LEGAL?
	JRST	PTHP.2			;NO
	ADD	T1,$JBSFD		;OFFSET INTO JBTSFD
	PUSHJ	P,MWORD			;GET TABLE ENTRY
	MOVE	P3,T1			;PUT IN A SAFE PLACE
	JRST	.POPJ1##		;AND RETURN

PTHP.1:	MOVEI	T1,PTNSJ%		;NO SUCH JOB
	POPJ	P,			;RETURN

PTHP.2:	MOVEI	T1,PTNAI%		;ILLEGAL NUMBER OF ARGUMENTSS
	POPJ	P,			;RETURN
; Return the target job's default PPN in T1
;
SFDPPN:	MOVE	T2,P3			;GET DEFAULT SFD
	SETCM	T3,CORXTR##		;GET ONES COMPLEMENT
	HRRZS	T3			;KEEP ONLY RH
	TDNN	T2,T3			;IS THERE REALLY AN NMB?
	JRST	SFDPP2			;NO--USE LOGGED-IN PPN IF NO DEFAULT
	LDB	T3,[POINT 2,P3,35]	;GET SCAN AND UFB BITS
	TDZ	T2,CORXTR##		;ZERO EXTRANEOUS BITS
	HRLS	T2			;LH(T1)=L(PPB) IF JBPUFB=1
	TDNN	T3,JBPUFB##		;IS IT A UFB?
	JRST	SFDPP1			;NO
	SETZ	P3,			;SO NO CONFUSION LATER
	MOVE	T1,T2			;GET PPB
	ADD	T1,PPBNAM##		; AND ADDRESS OF PPN
	PJRST	MWORD			;NOW GET THE PPN AND RETURN

SFDPP1:	MOVE	T1,T2			;GET NMB
	ADD	T1,NMBACC##		; AND ACCESS TABLE ADDR
	PUSHJ	P,MWORD			;GET C(T1)
	HLRZ	T4,T1			;L(1ST A.T. IN RING)
	TDNE	T4,DIFNAL##		;IS THERE AN A.T.?
	JRST	SFDPP2			;NO. SYSTEM ERROR?
	MOVE	T1,T4			;GET ACCESS TABLE ADDR
	ADD	T1,ACCPPB##		;GET ADDR OF PPB
	PUSHJ	P,MWORD			;GET C(T1)
	MOVE	T4,T1			;GET L(PPB)
	ADD	T1,PPBNAM##		;GET ADDR OF PPN
	PJRST	MWORD			;GET THE PPN AND RETURN

SFDPP2:	SETZ	P3,			;NO CONFUSTION
	PJRST	JB$PPN##		;GET LOGGED-IN PPN AND RETURN
	SUBTTL	UUO simulation -- USYSSTR - Return next structure in system


USYSSTR::
	PUSHJ	P,STRCHK		;INIT OUR STR DB IF NECESSARY
	CAME	T1,[EXP -1]		;WANT THE
	CAIN	T1,0			; FIRST STR?
	SKIPA	T1,.FSMIN##		;GET INDEX OF FIRST STR
	JRST	SYSS.1			;GO SEARCH
	MOVE	T1,STRTAB(T1)		;GET FIRST STR
	JRST	.POPJ1##		;RETURN

SYSS.1:	PUSHJ	P,.SAVE1##		;SAVE P1
	MOVN	P1,.FSMAX##		;GET -NUMBER OF STRS
	HRLZS	P1			;PUT IN LH
	ADD	P1,.FSMIN##		;OFFSET TO THE FIRST STR
	CAME	T1,STRTAB(P1)		;FOUND THE "PREVIOUS" STR?
	AOBJN	P1,.-1			;KEEP LOOKING
	JUMPGE	P1,.POPJ##		;NO SUCH STR
	AOBJP	P1,SYSS.2		;LAST STR IN SYSTEM?
	MOVE	T1,TABSTR(P1)		;NO--GET THE NEXT STR ADDRESS
	MOVEM	T1,STRADR		;SAVE IT
	SKIPA	T1,STRTAB(P1)		;GET THE NEXT STR NAME

SYSS.2:	MOVEI	T1,0			;RETURN ZERO IF NO MORE STRUCTURES
	JRST	.POPJ1##		;AND RETURN
	SUBTTL	UUO simulation -- UTRMNO - Get terminal number

UTRMNO::
IFN FTUUO,<
	TLNE	F,(FL.SPY)		;CAN WE SPY?
	  JRST	STRMNO			;YES!
>;END IFN FTUUO
	TRMNO.	T1,			;NO--DO UUO
	  POPJ	P,			;ERROR
	JRST	.POPJ1##		;NORMAL
IFN FTUUO,<
STRMNO:	CAMN	T1,[EXP -1]		;MY JOB?
	MOVE	T1,MYJOB##		;YES
	ADD	T1,TTYTAB		;GET ADDR OF TTY DDB
	PUSHJ	P,MWORDR		;FETCH FROM MONITOR
	JUMPE	T1,.POPJ##		;ERROR IF NONE
STRMND:	ADD	T1,DDBLDB##		;GET LDB ADDR
	PUSHJ	P,MWORDR		;FROM MONITOR
	JUMPE	T1,.POPJ##		;ERROR IF NONE
	ADD	T1,$LDDCH		;POINT TO CHARACTERISTICS
	PUSHJ	P,MWORD			;FETCH FROM MONITOR
	LDB	T1,[POINT 9,T1,35]	;GET LINE NUMBER
	ADDI	T1,.UXTRM		;MAKE UDX
	JRST	.POPJ1##		;AND TAKE GOOD RETURN
>
	SUBTTL	UUO simulation -- UTRMOP - Find terminal parameters

UTRMOP::
IFN FTUUO,<
	TLNE	F,(FL.SPY)
	  JRST	STRMOP
>;END IFN FTUUO
XTRMOP:	MOVE	T3,[2,,T1]
	TRMOP.	T3,
	  POPJ P,
	MOVE	T1,T3
	JRST	.POPJ1##
IFN FTUUO,<
STRMOP:	MOVSI	T3,-LENTRM
UTRM.1:	HLRZ	T4,TRMTAB(T3)
	CAIE	T1,(T4)			;MATCH?
	  AOBJN	T3,UTRM.1		;NO--LOOP FOR ALL
;;	JUMPGE	T3,E$$TNS		;ERROR IF NOT SIMULATED
	JUMPGE	T3,XTRMOP		;**TEMP**
	MOVEI	T1,-.UXTRM(T2)		;GET INDEX FROM UDX
	HRRZ	T3,TRMTAB(T3)		;GET DISPATCH
	ADD	T1,LINTAB		;POINT TO LDB ADR
	PUSHJ	P,MWORD			;GET LINTAB ENTRY
	PJRST	(T3)			;AND DISPATCH

	$STOP	(TNS,<TRMOP. function >,E.TNS)
E.TNS:	PUSHJ	P,.TOCTW##		;TYPE THE BAD ONE
	MOVEI	T1,[ASCIZ/ not simulated/]
	PJRST	.TSTRG##		;AND FINISH OFF

TRMTAB:	.TORSP,,URSP			;READ RECEIVE SPEED
	.TOTSP,,UTSP			;READ TRANSMIT SPEED
	.TOTRM,,UTYP			;READ TERMINAL TYPE
	.TODSS,,UDSS			;READ DATASET STATUS
	.TOICT,,UICT			;READ INPUT CHAR COUNT
	.TOOCT,,UOCT			;READ OUTPUT CHAR COUNT
	.TOBCT,,UBCT			;READ BREAK CHAR COUNT
	.TOGMS,,UGMS			;READ MIC STATUS
	.TOSLV,,USLV			;READ SLAVE STATUS
	.TORMT,,URMT			;READ REMOTE STATUS
	.TOSTP,,USTP			;READ ^S STATUS
VERSION GE,702,<
	.TOAPC,,UAPC			;READ ASYNC PORT CHARACTERISTIC
>
LENTRM==.-TRMTAB
URSP:	ADD	T1,LDBISR##		;GET SPEED WORD
	PUSHJ	P,MWORD			;FROM MONITOR
	LDB	T1,[POINT 4,T1,8]	;GET RSP BITS
	JRST	.POPJ1##		;AND SKIP RETURN

UTSP:	ADD	T1,LDBISR##		;GET SPEED WORD
	PUSHJ	P,MWORD			;FROM MONITOR
	LDB	T1,[POINT 4,T1,4]	;GET TSP BITS
	JRST	.POPJ1##		;AND SKIP RETURN

USLV:	ADD	T1,$LDDCH		;GET CHARACTERISTICS WORD
	PUSHJ	P,MWORD			;FROM MONITOR
	TSNN	T1,LDLSLV##		;SLAVED?
	TDZA	T1,T1			;NO
	MOVEI	T1,1			;YES
	JRST	.POPJ1##		;AND SKIP RETURN

URMT:	ADD	T1,$LDDCH		;GET CHARACTERISTICS WORD
	PUSHJ	P,MWORD			;FROM MONITOR
	TDNN	T1,LDRRMT##		;REMOTE?
	TDZA	T1,T1			;NO
	MOVEI	T1,1			;YES
	JRST	.POPJ1##		;AND SKIP RETURN

USTP:	ADD	T1,$LDDCH		;GET CHARACTERISTICS WORD
	PUSHJ	P,MWORD			;FROM MONITOR
	MOVE	T3,LDLSTP##		;GET STOPPED BIT
	IOR	T3,LDLSSO##		;AND SCNSER STOPPED OUTPUT BIT
	TSNN	T1,T3			;^S BY USER OR SCNSER?
	 TDZA	T1,T1			;NO
	  MOVEI	T1,1			;YES
	JRST	.POPJ1##

UTYP:	ADD	T1,LDBTTW##		;GET TERMINAL TYPE WORD
	PUSHJ	P,MWORD			;FROM MONITOR
	LDB	T1,[POINT 7,T1,35]	;LOAD TYPE INDEX
	JUMPE	T1,.POPJ1##		;RETURN ZERO IF NONE
	TRZE	T1,100			;SEE IF CUSTOMER
	 MOVNS	T1			;YES--NEGATE
	HRLI	T1,.GTTNM		;POINT TO TERMINAL TYPES
	MOVSS	T1			;POSITION FOR GETAB
	AOS	(P)			;TAKE SKIP
	PJRST	GTAB			;AND GET IT

UDSS:	MOVE	T4,T1			;SAVE LINTAB BITS
	ADD	T1,$LDDCH		;GET CHARACTERISTICS
	PUSHJ	P,MWORD			;FROM MONITOR
	TDNE	T1,LDRREM##		;REMOTE?
	 JRST	UDSSN			;YES--DO THE NETSER WAY
	TDNN	T4,LDRDSD##		;NO--LOCAL DATA SET?
	 POPJ	P,			;NO--ERROR
	MOVE	T1,T4			;GET LDB ADDR
	ADD	T1,LDBBY2##		; AND DSCTAB INDEX
	PUSHJ	P,MWORD			;FROM MONITOR
	LDB	T1,[POINT 9,T1,17]	;GET THE INDEX
	ADD	T1,DSCTAB		;POINT TO TABLE
	PUSHJ	P,MWORD			;GET TABLE ENTRY
	CAIL	T1,0			;SEE IF CARRIER
	 TDZA 	T1,T1			;NO--CLEAR T1
	  HRLZ	T1,DSCHWC##		;YES--FLAG
	JRST	.POPJ1##
UDSSN:	MOVE	T1,T4			;GET LDB ADDR
	ADD	T1,LDBREM##		; AND LDBREM WORD
	PUSHJ	P,MWORD			;FROM MONITOR
	TSNN	T1,LRLDSR##		;CARRIER ON?
	 TDZA	T1,T1			;NO
	  HRLZ	T1,DSCHWC##		;YES
	JRST	.POPJ1##

UICT:	ADD	T1,LDBICT##		;GET COUNT
	AOS	(P)			;SKIP RETURN
	PJRST	MWORD			;FETCH AND RETURN

UOCT:	ADD	T1,LDBOCT##		;GET COUNT
	AOS	(P)			;SKIP RETURN
	PJRST	MWORD			;FETCH AND RETURN

UBCT:	ADD	T1,LDBBCT##		;GET COUNT
	AOS	(P)			;SKIP RETURN
	PJRST	MWORD			;FETCH AND RETURN

UGMS:	ADD	T1,LDBMIC##		;OFFSET TO MIC STATUS WORD
	AOS	(P)			;SKIP RETURN
	PJRST	MWORD			;FETCH AND RETURN

VERSION LT,702,<
IFN FTIPC,<
UAPC::	ADD	T1,LINTAB		;POINT TO LINTAB
	PUSHJ	P,MWORD			;GET ADDRESS OF LDB
	ADD	T1,LDBTSG##		;OFFSET TO TSG WORD
	PUSHJ	P,MWORD			;FETCH FROM MONITOR
	LDB	T1,[POINT 3,T1,2]	;LOAD APC FIELD
	JRST	.POPJ1##		;AND RETURN
> ;END IFN FTIPC
> ;END VERSION LT,702

VERSION GE,702,<
UAPC:	ADD	T1,LDBPAG##		;OFFSET TO PAGE COUNTER WORD
	PUSHJ	P,MWORD			;FETCH FROM MONITOR
	LDB	T1,[POINT 4,T1,21]	;LOAD APC FIELD
	JRST	.POPJ1##		;AND RETURN
> ;END VERSION GE,702

>;END IFN FTUUO
	SUBTTL	Job state routines -- GETIO - Get input or output state

;CALL:
;	MOVE	T1,[SIXBIT/XXYYZZ/]
;ZZ=GENERIC CODE
;YY=OUTPUT CODE
;XX=INPUT CODE

GETTIO::SKIPA	T2,[TSNN T1,TTYOUW##]	;GET TEST FOR TTY OUTPUT
GETIO::	 MOVE	T2,[TSNN T1,IO##]	;GET TEST FOR OTHER OUTPUT
	PUSHJ	P,.SAVE2##		;SAVE P1,P2
	DMOVE	P1,T1			;COPY ARGS
	PUSHJ	P,JB$DDB##		;GET I/O ACTIVE DDB ADDR
	ADD	T1,DEVIOS##		;OFFSET TO WORD WE WANT
	CAIL	T1,.FPMC		;IN FUNNY SPACE?
	 CAIL	T1,.LPMC		;..?
	  TLNN	F,(FL.SPY)		;NO--CHECK SPY PAGES PRIVS
	   TLNE F,(FL.JACCT!FL.POKE)	;YES--CHECK JOBPEK PRIVS
	    CAIA			;HES OK
	     JRST GETI.1		;NO PRIVS
	PUSHJ	P,FWORD			;READ IT
	  JRST	GETI.1			;CAN'T--USE GENERIC CODE
	XCT	P2			;OUTPUT?
	 LSH	P1,-^D12		;NO--POSITION INPUT
	LSH	P1,-^D12		;YES--POSITION OUTPUT
GETI.1:	LDB	T1,[POINT 12,P1,35]	;GET LAST 2 CHARS
	POPJ	P,			;AND RETURN
	SUBTTL	Job state routines -- ANYCPU - See if running on any CPU

ANYCPU::TLNE	F,(FL.SMP)		;HAVE SMP IN THIS MONITOR?
	SKIPA	T1,M.CPU##		;GET NUMBER OF CPUS
	MOVEI	T1,1			;NOT SMP
	CAIN	T1,1			;SEE IF 1
	 JRST	ANY.1			;YES
	PUSHJ	P,JB$SPS##		;NO--GET PROCESSOR STATUS
	TDNN	T1,SP.CJA##		;ON ANY CPU?
	 AOS	(P)			;NO
	POPJ	P,			;YES

ANY.1:	TLNN	F,(FL.CRASH)		;CRASH FILE?
	 PUSHJ	P,SB$LJR##		;NO--GET LAST JOB RUN
	TLNE	F,(FL.CRASH)		;CRASH FILE?
	 PUSHJ	P,SB$CJR##		;YES--GET CURRENT JOB RUNNING
	CAME	T1,O			;MATCH THIS JOB?
	 AOS	(P)			;NO
	POPJ	P,			;YES
	SUBTTL	Job state routines -- MAKEW - Translate EW state codes

;Call:
;	T2/ EW wait state index
;Returns:
;	P3/ sixbit EW state code

MAKEW::	MOVEI	P3,'EW'			;GET GENERAL STATE
	CAMN	T2,EV.TKW##		;MAGTAPE KONTROLLER WAIT?
	 MOVEI	P3,'EK'			;YES
	CAMN	T2,EV.REW##		;MAGTAPE REWIND?
	 MOVEI	P3,'ER'			;YES
	CAMN	T2,EV.LBL##		;LABEL PROCESSING WAIT?
	 MOVEI	P3,'EL'			;YES
	CAME	T2,EV.FEI##		;FRONT END INPUT WAIT?
	 CAMN	T2,EV.FEO##		;OR FRONT END OUTPUT WAIT?
	  MOVEI	P3,'EF'			;YES
	CAME	T2,EV.NTC##		;NETWORK TERMINAL CONNECT?
	 CAMN	T2,EV.STC##		;NETWORK STATION CONTROL?
	  MOVEI	P3,'EN'			;YES
	CAMN	T2,EV.NET##		;OR GENERAL NETWORK WAIT?
	 MOVEI	P3,'EN'			;YES
	CAMN	T2,EV.D60##		;DN60 WAIT?
	 MOVEI	P3,'E6'			;YES
	CAMN	T2,EV.IPC##		;SYSTEM IPCF WAIT?
	 MOVEI	P3,'EI'			;YES
VERSION GE,702,<
	CAMN	T2,EV.DTE##		;DTE WAIT?
	 MOVEI	P3,'ET'			;YES
	CAMN	T2,EV.KDP##		;KDP WAIT?
	 MOVEI	P3,'EP'			;YES
	CAMN	T2,EV.DMR##		;DMR WAIT?
	 MOVEI	P3,'EM'			;YES
	CAMN	T2,EV.DCN##		;DECNET CONNECT WAIT?
	 MOVEI	P3,'ED'			;YES
>
	POPJ	P,			;AND RETURN
	SUBTTL	Print routines -- INFTMP - Print TMPCOR directory

INFTMP::PUSHJ	P,.SAVE3##		;SAVE P1,P3
	SETZB	P1,P2			;CLEAR COUNT OF FILES, SIZES
	$TYPEL	<     TMPCOR directory:>
	MOVE	T1,.UPFCC##		;GET START OF TMPCOR LIST
	PUSHJ	P,UWORD			;..
	  POPJ	P,			;CAN'T
	HLRZ	P3,T1			;SAVE START
PRTT.L:	JUMPE	P3,PRTT.E		;JUMP IF DONE
	MOVEI	T1,(P3)			;COPY ADDRESS
	PUSHJ	P,FWORD			;GET XWD LINK,,NAME
	  POPJ	P,			;CAN'T
	MOVE	T2,T1			;SAVE A MOMENT
	MOVEI	T1,1(P3)		;GET EXP SIZE
	PUSHJ	P,FWORD			;CANT
	  POPJ	P,			;CAN'T
	PUSH	P,T1			;SAVE SIZE A MOMENT
	PUSHJ	P,.TTABC##		;TAB
	HLRZ	P3,T2			;GET LINK TO NEXT FILE
	HRLZ	T1,T2			;GET NAME
	PUSHJ	P,.TSIXN##		;TYPE
	POP	P,T1			;RESTORE SIZE
	ADDI	P2,(T1)			;INCLUDE FOR TOTAL
	MOVEI	T3,^D5			;FIELDWIDTH
	PUSHJ	P,.TDECJ##		;TYPE
	PUSHJ	P,.TCRLF##		;CRLF
	AOJA	P1,PRTT.L		;LOOP FOR ALL

PRTT.E:	JUMPE	P1,PRTT.B		;EMPTY IF NO FILES
	$TYPE	<     Total of >
	MOVEI	T1,(P2)			;GET COUNT OF WORDS
	MOVEI	T2,[ASCIZ/word/]
	PUSHJ	P,.TPLRS##		;TYPE
	$TYPE	< in >
	MOVEI	T1,(P1)			;GET COUNT OF FILES
	MOVEI	T2,[ASCIZ/file/]
	PUSHJ	P,.TPLRS##
	PJRST	.TCRLF##		;CRLF AND RETURN

PRTT.B:	$TYPEL	<     Directory is empty>
	POPJ	P,			;AND RETURN
	SUBTTL	Print routines -- INFCHN - Print active channel information

INFCHN::MOVE	T1,USRJDA##		;GET OFFSET OF USRJDA
	HRLI	T1,-20			;SETUP FOR 20 CHANNELS
	MOVEI	T2,0			;START WITH CHANNEL 0
	PUSHJ	P,DOCHN			;PROCESS THOSE
	MOVE	T1,.UPCTA##		;GET THE EXTENDED CHANNEL TABLE POINTER
	PUSHJ	P,UWORD			;FROM UPMP
	  POPJ	P,			;CAN'T
	MOVEI	T1,(T1)			;JUST RH
	JUMPE	T1,.POPJ##		;RETURN IF NONE
	MOVN	T2,HIGHXC		;GET -MAX EXTENDED CHANNELS
	HRLI	T1,(T2)			;MAKE -N,,ADDR OF EXTENDED TABLE
	MOVEI	T2,20			;THE START OF CHANNEL NUMBERS
	PJRST	DOCHN			;GET THEM AND RETURN

DOCHN:	PUSHJ	P,.SAVE4##		;SAVE P1-P4
	DMOVE	P1,T1			;SAVE ARGS
DOCH.1:	MOVEI	T1,(P1)			;GET JDA ADDRESS
	PUSHJ	P,FWORD			;FROM MONITOR
	  POPJ	P,			;MUST BE SWAPPED OR SOMETHING
	JUMPE	T1,DOCH.L		;LOOP IF NOTHING
	MOVEI	D,(T1)			;SAVE DDB ADDRESS
	HLLZ	P3,T1			;SAVE THE BITS
	MOVEI	T1,(P2)			;GET THE CHANNEL NUMBER
	MOVEI	T3,4			;FIELDWIDTH
	PUSHJ	P,.TOCTJ##		;TYPE
	MOVEI	T1,2
	PUSHJ	P,.TSPAN##		;SPACE
	MOVE	T1,D			;GET DDB ADDR
	ADD	T1,DEVNAM##		; AND DEVICE NAME
	PUSHJ	P,FWORD			;..
	  POPJ	P,			;??
	MOVEI	T3,^D8			;GET FIELDWIDTH
	PUSHJ	P,.TSIXJ##		;TYPE
	MOVE	T1,D			;POINT TO DDB
	ADD	T1,DEVIOS##		; AND TO DEVIOS WORD
	PUSHJ	P,FWORD			;..
	  POPJ	P,			;??
	MOVEI	T1,(T1)			;JUST RH
	MOVEI	T3,^D6			;GET FIELDWIDTH
	PUSHJ	P,.TOCTJ##		;TYPE
	MOVEI	T1,2
	PUSHJ	P,.TSPAN##
	MOVSI	P4,-CHNBLN		;GET -LENGTH
DOCH.3:	MOVEI	T1,0			;ASSUME BLANK
	HLRZ	T2,CHNBIT(P4)		;GET ADDRESS OF A BIT
	TDNE	P3,(T2)			;SEE IF BIT SET
	 HRLZ	T1,CHNBIT(P4)		;YES--GET CODE
	MOVEI	T3,4			;FIELDWIDTH
	PUSHJ	P,.TSIXJ##		;TYPE
	AOBJN	P4,DOCH.3		;LOOP FOR ALL BITS
	PUSHJ	P,.TCRLF##		;CRLF
	MOVX	T1,IFMDDBS##		;GET /INFORM:DDBS
	TDNN	T1,.FZINF##(I)		;SEE IF GIVEN
	 SKIPL	.FZDBS##(I)		;OR /DDBS
	  CAIA				;YES--LIST DDBS
	   JRST DOCH.L			;NO--ADVANCE TO NEXT CHANNEL
	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVMOD##		; AND DEVMOD WORD
	PUSHJ	P,FWORD			;FROM DDB
	  POPJ	P,			;??
	PUSHJ	P,LSTDDB		;LIST THIS DDB
DOCH.L:	ADDI	P2,1			;ADVANCE TO NEXT CHANNEL
	AOBJN	P1,DOCH.1		;LOOP FOR ALL CHANNELS
	POPJ	P,			;AND RETURN

;Table of bits in USRJDA and extended channel table
;Format is
;	XWD	bit-position,'bit-typeout-name'

CHNBIT:	XWD	IBUFB##, 'OI '
	XWD	OBUFB##, 'OO '
	XWD	INBFB##, 'IB '
	XWD	OUTBFB##,'OB '
	XWD	LOOKB##, 'L  '
	XWD	ENTRB##, 'E  '
	XWD	INPB##,	 'I  '
	XWD	OUTPB##, 'O  '
	XWD	ICLOSB##,'IC '
	XWD	OCLOSB##,'OC '
CHNBLN==.-CHNBIT
	SUBTTL	Print routines -- INFORG - Print program origin

INFORG::$TYPE	<     Origin: >
	PUSHJ	P,.SAVE2##
	$ZERO	SEG.ZB,SEG.ZE		;ZERO OUT STORAGE
;
;Loop to get low segment information from GETTABs and SPY
;
	MOVSI	P1,-LOWLEN		;LOW LENGTH OF LOWTABS
PRTP.1:	MOVE	T1,LOWTAB(P1)		;GET TABLE
	PUSHJ	P,JTAB			;GET FOR CURRENT JOB
	MOVEM	T1,LOWDAT(P1)		;SAVE
	AOBJN	P1,PRTP.1		;LOOP FOR ALL
	MOVEI	T1,.JBVER		;GET ADDRESS OF LOW SEG VERSION
	TLNE	F,(FL.SPY)		;FORGET IT IF WE CANT SPY
	PUSHJ	P,JWORD			;GET IT
	 MOVEI	T1,0			;CANT
	MOVEM	T1,LOWVER		;SAVE VERSION
	MOVEI	T1,.JBCST		;GET ADDR CUSTOMER WORD
	TLNE	F,(FL.SPY)		;SKIP IF WE CANT SPY
	PUSHJ	P,JWORD			;FROM JOB
	 MOVEI	T1,0			;FAILED
	MOVEM	T1,LOWCST		;SAVE CUSTOMER VERSION
;
;Now print low seg information
;
	MOVE	T1,LOWDAT		;GET DEVICE
	PUSHJ	P,.TDEVN##		;TYPE
	MOVE	T1,LOWDAT+1		;GET FILE
	PUSHJ	P,.TSIXN##		;TYPE
	MOVE	T1,[1,,LOWDAT+2]	;PATH STYLE
	PUSHJ	P,.TDIRB##		;TYPE THAT

	SKIPN	LOWVER			;SEE IF LOW SEG VERSION
	 JRST	PRTP.A			;NO
	PUSHJ	P,.TSPAC##		;SPACE OVER
	MOVE	T1,LOWVER		;GET VERSION
	PUSHJ	P,.TVERW##		;TYPE
	SKIPN	LOWCST			;SEE IF LOW SEG CUSTOMER VERSION
	 JRST	PRTP.A			;NO
	MOVEI	T1,"/"			;SEPARATE
	PUSHJ	P,.TCHAR##		;TYPE
	MOVE	T1,LOWCST		;GET CUSTOMER VERSION
	PUSHJ	P,.TVERW##		;TYPE THAT
;
;Now get high segment information from GETTABs and SPY
;
PRTP.A:	PUSHJ	P,JB$SGN##		;GET HIGH SEGMENT INFO
	MOVE	P1,T1			;COPY INFO
	JUMPE	P1,PRTP.E		;NOTHING
	$TYPE	< + >			;INDICATE HIGH SEGMENT
	JUMPL	P1,PRTP.S		;JUMP IF SPYING
	TXNN	P1,SG.SHR		;SHAREABLE?
	 JRST	PRTP.N			;NO
	MOVSI	P1,-HIGLEN		;HIGH LENGTH OF GETTABS
PRTP.3:	PUSHJ	P,JB$SGN		;GET SEGMENT INFO
	MOVSI	T1,(T1)			;GET SEGMENT NUMBER
	HRR	T1,HIGTAB(P1)		;INCLUDE TABLE
	PUSHJ	P,GTAB			;GET THAT
	MOVEM	T1,HIGDAT(P1)		;STORE
	AOBJN	P1,PRTP.3		;LOOP FOR ALL
	PUSHJ	P,JB$SGN##		;GET SEGMENT INFO
	MOVSI	T1,(T1)			;GET SEGMENT NUMBER
	HRRI	T1,.GTUPM		;GET SEGMENTS ORIGIN
	PUSHJ	P,GTAB			;GET IT
	LDB	P2,[POINT 9,T1,8]	;GET PAGE OF START OF HIGH SEG
	LSH	P2,^D9			;MAKE ADDRESS
	MOVEI	T1,.JBHVR(P2)		;POINT TO HIGH SEG VERSION
	TLNE	F,(FL.SPY)		;DONT TRY IF WE CANT SPY
	PUSHJ	P,JWORD			;GET IT
	 MOVE	T1,LOWVER		;DEFAULT TO LOW SEG 
	MOVEM	T1,HIGVER		;SAVE HIGH SEGMENT VERSION
;
;Now print out high segment information if different than low segment
;
	SKIPE	T1,HIGDAT+2		;SEE IF PPN/PATH POINTER
	 TLNE	T1,-1			;SEE IF PATH
	  JRST	PRTP.4			;NOT INTERESTING
	TLNN	F,(FL.SPY)		;CAN WE SPY?
	 JRST	PRTP.4			;NO--THATS ALL WE CAN DO
	MOVEI	P1,(T1)			;SAVE PATH POINTER ADDR
	MOVEI	T2,HIGDAT+2		;SETUP A POINTER TO STORE
PRTP.5:	MOVEI	T1,(P1)			;GET ADDR TO FETCH
	PUSHJ	P,MWORD			;GET IT
	MOVEM	T1,(T2)			;STORE IT
	JUMPE	T1,PRTP.4		;JUMP IF THE END
	ADDI	T2,1			;ADVANCE STORAGE
	AOJA	P1,PRTP.5		;LOOP FOR PATH

PRTP.4:	MOVSI	P1,-LOWLEN		;LENGTH OF TABLES
PRTP.6:	MOVE	T1,LOWDAT(P1)		;GET LOW SEG
	CAME	T1,HIGDAT(P1)		;SAME AS HIGH SEG?
	 JRST	PRTP.H			;NO--PRINT IT
	JUMPE	T1,PRTP.V		;RETURN IF THE SAME AND BOTH ZERO
	AOBJN	P1,PRTP.6		;LOOP FOR ALL
	JRST	PRTP.V			;AND RETURN

PRTP.H:	MOVE	T1,HIGDAT		;GET DEVICE
	PUSHJ	P,.TDEVN##		;TYPE
	SKIPN	T1,HIGDAT+1		;SEE IF FILE
	 JRST	[MOVEI	T1,.JBHNM(P2)	;NO--GET NAME
		 PUSHJ	P,JWORD		;FETCH
		  MOVEI	T1,0		;FAILED
		 JRST	.+1]		;AND CONTINUE
	PUSHJ	P,.TSIXN##		;TYPE
	MOVE	T1,[1,,HIGDAT+2]	;PATH STYLE
	PUSHJ	P,.TDIRB##		;TYPE THAT
	JRST	PRTP.V			;AND FINISH OFF

PRTP.N:	$TYPE	<(not shareable)>	;TEXT
	JRST	PRTP.E			;AND EXIT

PRTP.S:	$TYPE	<SPY(>			;INDICATE SPY
	PUSHJ	P,JB$SGN##		;GET SEGMENT INFO
	ANDI	T1,777000		;INTO LAST PAGE
	PUSHJ	P,.TCORW##		;TYPE AS CORE
	PUSHJ	P,.TRPAR##		;CLOSE PARA
	JRST	PRTP.E			;AND FINISH OFF

PRTP.V:	PUSHJ	P,.TSPAC##		;SPACE OVER
	SKIPE	T1,HIGVER		;GET HIGH SEG VERSION
	 CAMN	T1,LOWVER		;SEE IF DIFFERENT
	  CAIA				;NONE OR THE SAME
	   PUSHJ P,.TVERW##		;DIFFERENT--PRINT IT
	SKIPE	HIGDAT+1		;SEE IF SUPERSEDED
	 JRST	PRTP.E			;NO
	$TYPE	< (superseded)>		;YES

PRTP.E:	PUSHJ	P,.TCRLF##		;END LINE
	TRZ	F,FR.COMMA		;CLEAR CRLF NEEDED FLAG
	PUSHJ	P,ORGDDT		;HANDLE DDT STUFF
	PUSHJ	P,ORGPFH		;AND PFH STUFF
	TRZE	F,FR.COMMA		;CRLF NEEDED?
	 PUSHJ	P,.TCRLF##		;YES
	POPJ	P,			;AND RETURN

LOWTAB:	.GTRDV				;DEVICE
	.GTRFN				;NAME
	.GTRDI				;PPN
	.GTRS0				;SFDS
	.GTRS1
	.GTRS2
	.GTRS3
	.GTRS4
LOWLEN==.-LOWTAB

HIGTAB:	.GTDEV				;DEVICE
	.GTPRG				;NAME
	.GTPPN				;PPN
HIGLEN==.-HIGTAB

TRANGE:	PUSH	P,T1			;SAVE T1
	HRRZ	T1,T1			;GET LOW
	PUSHJ	P,.TOCTW##		;TYPE
	PUSHJ	P,.TDASH##		;DASH
	POP	P,T1			;RESTORE T1
	HLRZ	T1,T1			;GET HIGH
	PJRST	.TOCTW##		;TYPE AND RETURN

ORGDDT:	PUSHJ	P,JB$DDT##		;GET DDT ORIGIN
	JUMPE	T1,.POPJ##		;NO--RETURN
	PUSH	P,T1			;SAVE ADDRESS
	TRO	F,FR.COMMA		;FLAG NEED CRLF
	$TYPE	<     DDT: >
	POP	P,T1			;RESTORE ADDRESS
	PUSHJ	P,TRANGE		;TYPE OUT RANGE
	PUSHJ	P,JB$BPT##		;GET UNSOLICTED BREAKPOINT ADDRESS
	JUMPE	T1,.POPJ##		;RETURN IF NONE
	PUSH	P,T1			;SAVE IT
	$TYPE	<   BPT: >
	POP	P,T1			;GET BPT ADDR
	PJRST	.TOCTW##		;TYPE IT AND RETURN

ORGPFH:	PUSHJ	P,JB$PFH##		;GET PFH ORIGIN
	JUMPE	T1,.POPJ##		;RETURN IF NONE
	PUSHJ	P,.SAVE1##		;SAVE P1
	MOVE	P1,T1			;COPY TO SAFE PLACE
	TROE	F,FR.COMMA		;WAS THERE DDT AND BPT TYPEOUT?
	PUSHJ	P,.TCRLF##		;YES--NEED A CRLF
	$TYPE	<     PFH: >
	MOVE	T1,P1			;GET PFH RANGE
	PUSHJ	P,TRANGE
	MOVEI	T1,.PFHVR(P1)		;GET VERSION
	PUSHJ	P,JWORD			;GET IT
	 POPJ	P,			;CANT
	JUMPE	T1,.POPJ##		;NONE
	TLNE	T1,700000		;LOOK LIKE OPCODE?
	 POPJ	P,			;YES--FORGET IT TOO
	PUSH	P,T1			;NO--SAVE IT
	$TYPE	<  >			;SPACE OVER
	POP	P,T1			;RESTORE VERSION
	PUSHJ	P,.TVERW##		;TYPE THE VERSION
	MOVEI	T1,.PFHCR(P1)		;GET RUNTIME
	PUSHJ	P,JWORD			;FETCH
	 POPJ	P,			;CANT
	TLNE	T1,700000		;LOOK LIKE AN OPCODE?
	 POPJ	P,			;YES--FORGET IT
	IDIVI	T1,^D100		;NO--MAKE MILLISECONDS
	PUSH	P,T1			;SAVE IT
	$TYPE	<  PFH runtime:>
	MOVE	T1,(P)			;GET IT
	PUSHJ	P,.TTIMH##		;TYPE
	$TYPE	< (>
	PUSHJ	P,JB$TIM##		;GET RUNTIME (MILLISECONDS)
	PUSH	P,T1			;SAVE A MOMENT
	MOVEI	T1,.PFHOR(P1)		;GET ORIGINAL RUNTIME WHEN PFH
	PUSHJ	P,JWORD			;FIRST CALLED
	 POPJ	P,			;CANT
	IDIVI	T1,^D100		;MAKE MILLISECONDS
	POP	P,T2			;RESTORE JOBS RUNTIME
	SUB	T2,T1			;COMPUTE RUNTIME SINCE PFH
	POP	P,T1			;RESTORE RUNTIME IN PFH
	IMULI	T1,^D100
	PUSHJ	P,TNN##			;TYPE AS PERCENT
	$TYPE	<% of CPU runtime)>
	POPJ	P,			;AND RETURN
	SUBTTL	Print routines -- INFDDB - Print all DDBs for a job

;Call:
;	J=job number


INFDDB::MOVEI	D,0			;START WITH FIRST DDB

PRTD.1:	PUSHJ	P,GETDDB		;GET A DDB
	 POPJ	P,			;ALL DONE
	MOVX	T2,IFMCHANNEL##		;GET /INFORM:CHANNEL
	TDNE	T2,.FZINF##(I)		;SEE IF GIVEN
	 TDNN	T1,ASSPRG##		;YES--SEE IF OPEN ON CHANNEL
	  CAIA				;NO
	   JRST	PRTD.1			;YES--SKIP THIS ONE
	PUSHJ	P,LSTDDB		;LIST IT
	JRST	PRTD.1			;AND RETURN
	SUBTTL	Print routines -- INFJSL - Print job search list

INFJSL::$TYPE	<     Job search list:  >
	TRZ	F,FR.COMMA		;CLEAR COMMA FLAG
	PUSHJ	P,.SAVE1##		;SAVE P1
	MOVEM	O,GOBBLK+.DFGJN		;SAVE JOB NUMBER
	PUSHJ	P,JB$PPN##		;GET CORRESPONDING PPN
	MOVEM	T1,GOBBLK+.DFGPP	;SAVE THAT
	SETOM	GOBBLK+.DFGNM		;START WITH THE FIRST STR
PTHJ.1:	MOVE	T1,[5,,GOBBLK]		;POINT TO ARGS
	PUSHJ	P,UGOBSTR		;READ IT
	 JRST	PTHJ.E			;OH WELL
	MOVE	P1,GOBBLK+.DFGNM	;GET THIS STR NAME
	CAMN	P1,[-1]			;SEE IF THE END
	 JRST	PTHJ.E			;YES
	MOVEI	T1,[ASCIZ/, /]		;GET SEPARATOR
	TROE	F,FR.COMMA		;SEE IF FIRST TIME
	 PUSHJ	P,.TSTRG##		;NO--TYPE COMMA SPACE
	JUMPN	P1,PTHJ.2		;JUMP IF NOT THE FENCE
	MOVE	T1,[SIXBIT/FENCE/]	;THE FENCE
	PUSHJ	P,.TSIXN##		;TYPE IT
	JRST	PTHJ.1			;AND LOOP
PTHJ.2:	MOVE	T1,P1			;COPY STR NAME
	PUSHJ	P,.TDEVN##		;TYPE
	MOVE	P1,GOBBLK+.DFGST	;GET STATUS BITS
	MOVEI	T1,[ASCIZ"/NOCREATE"]	;GET /NOCREATE
	TXNE	P1,DF.SNC		;IS IT?
	 PUSHJ	P,.TSTRG##		;YES--TYPE
	MOVEI	T1,[ASCIZ"/NOWRITE"]	;GET /NOWRITE
	TXNE	P1,DF.SWL		;IS IT?
	 PUSHJ	P,.TSTRG##		;YES--TYPE
	JRST	PTHJ.1			;AND LOOP

PTHJ.E:	PJRST	.TCRLF##		;CRLF AND RETURN
	SUBTTL	Print routines -- INFPTH - Print current path

INFPTH::HRLZI	T1,(O)			;GET JOB NUMBER
	HRRI	T1,.PTFRD		;READ DEFAULT PATH
	MOVEM	T1,PTHBLK+.PTFCN	;STORE FUNCTION
	MOVE	T1,[.PTMAX,,PTHBLK]	;POINT TO PATH. BLOCK
	PUSHJ	P,UPATH			;READ JOBS PATH
	 POPJ	P,			;FAILED
	$TYPE	<     Path:  >		;GET TEXT
	MOVE	T1,[1,,PTHBLK+.PTPPN]	;POINT TO START OF PATH
	PUSHJ	P,.TDIRB##		;TYPE IT
	PUSHJ	P,.SAVE1##		;SAVE P1
	MOVE	P1,PTHBLK+.PTSWT	;GET SWITCHES AND FLAGS
	MOVEI	T1,[ASCIZ//]		;SETUP NULL
	LOAD	T2,P1,PT.SCN		;GET SCAN FLAGS
	CAIN	T2,.PTSCY		;IS IT?
	 MOVEI	T1,[ASCIZ"/SCAN"]	;YES--LOAD IT
	CAIN	T2,.PTSCN		;IS IT /NOSCAN
	 MOVEI	T1,[ASCIZ"/NOSCAN"]	;YES--LOAD IT
	PUSHJ	P,.TSTRG##		;TYPE IT
	MOVEI	T1,[ASCIZ"/NEW"]	;GET /NEW
	TXNE	P1,PT.NEW		;IS IT?
	 PUSHJ	P,.TSTRG##		;YES--TYPE
	MOVEI	T1,[ASCIZ"/SYS"]	;GET /SYS
	TXNE	P1,PT.SYS		;IS IT?
	 PUSHJ	P,.TSTRG##		;YES--TYPE
PTHP.E:	PJRST	.TCRLF##		;CRLF AND RETURN
	SUBTTL	Print routines -- INFLNM - Print path pathological names

INFLNM::MOVE	T1,$UPLNM		;GET POINTER TO LOGICAL NAMES
	PUSHJ	P,UWORD			;FROM UPMP
	  POPJ	P,			;CAN'T
	JUMPE	T1,.POPJ##		;RETURN IF NO NAMES
	PUSHJ	P,.SAVE2##		;SAVE P1&P2
	MOVEI	P1,(T1)			;SAVE POINTER TO TABLE
	PUSHJ	P,FWORD			;FETCH FIRST WORD IN TABLE
	  SETZ	T1,			;ASSUME NONE
	JUMPE	T1,.POPJ##		;DOESNT HAVE ANY NAMES
	$TYPEL	<     Logical name definitions:>
PRTLOP:	MOVEI	T1,(P1)			;GET ADDRESS OF NAME SPEC
	PUSHJ	P,FWORD
	  SETZ	T1,			;ASSUME END OF LNM LIST
	JUMPE	T1,.POPJ##		;RETURN WHEN DONE
	MOVE	P2,T1			;SAVE POINTER AND FLAGS
	MOVEI	T1,6			;SOME SPACES
	PUSHJ	P,.TSPAN##		;TYPE
	PUSHJ	P,.TSTRG##		;TYPE FILLER
	MOVEI	T1,(P2)			;GET PATHOLOGICAL NAME
	PUSHJ	P,FWORD
	  POPJ	P,			;SHOULDN'T HAPPEN BUT ...
	CAMN	T1,[-1]			;OLD STYLE LIB?
	 MOVE	T1,[SIXBIT/(LIB)/]	;YES--INDICATE
	PUSHJ	P,.TDEVN##		;TYPE
	MOVEI	T1,[ASCIZ"/SEARCH"]	;ASSUME LIBRARY SEARCH
	TSNE	P2,LN.LIB##		;IS IT?
	 PUSHJ	P,.TSTRG##		;YES--TYPE
VERSION GE,702,<
	MOVEI	T1,[ASCIZ"/COMMAND"]	;ASSUME ITS A COMMAND
	TSNE	P2,LNPCMD##		;IS IT?
	 PUSHJ	P,.TSTRG##		;YES--TYPE
	MOVEI	T1,[ASCIZ"/OVERRIDE"]	;ASSUME OVERRIDE FILE SPECS
	TSNE	P2,LNPOVR##		;IS IT?
	 PUSHJ	P,.TSTRG##		;YES--TYPE
>;GE 702
	$TYPE	< = >			;EQUALS
	AOSA	P2			;POINT TO FIRST DEVICE, SKIP 
PRTLPS:	 PUSHJ	P,.TCOMA##		;SEPARATE
	MOVEI	T1,(P2)			;GET DEVICE COMPONENT
	PUSHJ	P,FWORD
	  POPJ	P,
	PUSHJ	P,.TDEVN##		;TYPE
	ADDI	P2,1			;ADVANCE PAST DEV
VERSION GE,702,<
	MOVEI	T1,(P2)			;COPY ADDRESS
	PUSHJ	P,FWORD			;GET FILENAME
	  POPJ	P,
	JUMPE	T1,INFL.2		;SKIP IF NONE
	PUSHJ	P,.TSIXN##		;OUTPUT FILE
INFL.2:	ADDI	P2,1			;ADVANCE PAST FILE TO EXT
	MOVEI	T1,(P2)			;COPY ADDRESS
	PUSHJ	P,FWORD			;GET EXTENSION
	  POPJ	P,
	JUMPE	T1,INFL.3		;SKIP IF NONE
	PUSH	P,T1			;SAVE EXT
	PUSHJ	P,.TDOT##		;TYPE DOT
	POP	P,T1			;RESTORE EXT
	PUSHJ	P,.TSIXN##		;TYPE IT
INFL.3:	ADDI	P2,1			;ADVANCE PAST EXT TO PPN
>;GE 702
	MOVEI	T1,(P2)			;GET PPN COMPONENT
	PUSHJ	P,FWORD
	  POPJ	P,
	JUMPE	T1,PRELPN		;DONE IF ZERO
	PUSH	P,T1			;SAVE PPN
	PUSHJ	P,.TLBRK##		;TYPE "["
	POP	P,T1			;RESTORE PPN
	PUSHJ	P,.TXWDW##		;TYPE P,PN
	ADDI	P2,1			;ADVANCE PAST PPN TO SFD
PRTSFD:	MOVEI	T1,(P2)			;COPY ADDRESS
	PUSHJ	P,FWORD			;GET SFD COMPONENT
	  POPJ	P,
	JUMPE	T1,PRELPS		;DONE WITH SFDS
	PUSH	P,T1
	PUSHJ	P,.TCOMA##
	POP	P,T1
	PUSHJ	P,.TSIXN##		;TYPE
	AOJA	P2,PRTSFD		;LOOP FOR ALL
PRELPS:	PUSHJ	P,.TRBRK##		;TYPE "]"
PRELPN:	ADDI	P2,1			;ADVANCE TO NEXT WORD
	MOVEI	T1,(P2)			;COPY
	PUSHJ	P,FWORD
	  POPJ	P,
	JUMPN	T1,PRTLPS		;LOOP IF MORE
	PUSHJ	P,.TCRLF##		;CRLF
	AOJA	P1,PRTLOP		;LOOP TO NEXT NAME
	SUBTTL	DDB routines -- GETDDB - Get first/next DDB in chain

;CALL:
;	MOVE	D,LASDDB		;0 TO START AT BEGINNING
;	PUSHJ	P,GETDDB
;	  <ERROR>			;NO MORE DDBS
;	<NORMAL>			;T1=DEVMOD, D=DDB ADDR

GETDDB:	JUMPN	D,GETD.1		;JUMP IF DDB LIST SETUP
	MOVE	D,FIRDDB		;NO--GET FIRST DDB
	MOVEI	T1,^D2000		;MAX DDBS/SYSTEM
	MOVEM	T1,DDBCNT		;SAVE COUNTER
	JRST	GETD.2			;AND PROCEED

GETD.1:	SOSG	DDBCNT			;SEE IF LOOPING
	 JRST	E$$DLJ			;YES--CUT OUT NOW
	MOVE	T1,D			;POINT TO DDB
	ADD	T1,DEVSER##		; AND DEVSER WORD
	PUSHJ	P,FWORD
	  POPJ	P,			;CAN'T READ THEM IF SWAPPED
	TLNE	T1,-1			;SEE IF THE END
	 JRST	[HLRZ	D,T1		;NO--RETURN NEXT ADDR
		 JRST	GETD.2]		; AND SCAN FROM THERE
	CAIL	D,.FPMC			;YES--ALREADY IN FUNNY SPACE?
	 POPJ	P,			;YES--END OF LIST
	MOVE	T1,$UPLST		;GET POINTER TO SWAPPABLE DDBS
	PUSHJ	P,UWORD			;FROM UPMP
	  POPJ	P,			;CAN'T
	HLRZ	D,T1			;GET LH
	JUMPE	D,.POPJ##		;RETURN IF NO DDBS
GETD.2:	MOVE	T1,D			;POINT TO DDB
	ADD	T1,DEVMOD##		; AND DEVMOD WORD
	PUSHJ	P,FWORD			;GET FROM MONITOR
	  POPJ	P,
	TDNN	T1,ASSCON##		;ASSIGNED BY CONSOLE COMMAND?
	TDNE	T1,ASSPRG##		;ASSIGNED BY PROGRAM INIT?
	SKIPA				;YES TO EITHER
	JRST	GETD.1			;NO--LOOP FOR NEXT DDB
	MOVE	T4,T1			;SAVE DEVMOD
	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVJOB##		; AND DEVJOB WORD
	PUSHJ	P,FWORD
	  POPJ	P,
	LDB	T1,[POINT 9,T1,35]	;GET JOB NUMBER
	CAIE	T1,(O)			;MATCH?
	  JRST	GETD.1			;NO--LOOP FOR NEXT
	MOVE	T1,T4			;RETURN DEVMOD
	JRST	.POPJ1##		;TAKE GOOD RETURN

	$WARN	(DLJ,<DDB loop for job >,E.CRD,.POPJ##)
E.CRD:	MOVEI	T1,(O)			;GET JOB NUMBER
	PJRST	.TDECW##		;TYPE AND RETURN
	SUBTTL	DDB routines -- JC$DDB - Check uses /DDBS:<spec> switch


JC$DDB::PUSHJ	P,.SAVE1##		;SAVE P1
	MOVE	P1,.FZDDB##+.FXDEV(I)	;GET DEVICE
	JUMPE	P1,.POPJ1##		;RETURN IF NONE
	MOVEI	D,0			;START WITH FIRST

CHKD.1:	PUSHJ	P,GETDDB		;GET FIRST/NEXT DDB
	  POPJ	P,			;NO MORE
	TSNN	T1,DVDSK##		;SEE IF A DISK
	  JRST	CHKD.2			;NO
	MOVE	T1,D			;GET DDB ADDR
	ADD	T1,DEVNAM##		; AND DEVICE NAME
	PUSHJ	P,FWORD			;GET IT
	  POPJ	P,			;SWAPPED
	CAME	T1,P1			;SEE IF USER MATCHES DEVNAM
	 CAMN	P1,[SIXBIT/DSK/]	;SEE IF DSK:
	  JRST	CHKD.6			;YES
	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVUNI##		;OFFSET TO UNIT POINTER
	PUSHJ	P,FWORD			;..
	  POPJ	P,
	HLRZS	T1			;GET FIRST UDB
	JUMPE	T1,CHKD.1		;NONE--GET NEXT
	ADD	T1,UNISTR##		;GET UNIT DATA BLOCK
	PUSHJ	P,FWORD
	  POPJ	P,
	ADD	T1,STRNAM##		;GET STR NAME
	PUSHJ	P,FWORD			;..
	  POPJ	P,
	CAME	T1,P1			;SEE IF MATCHES USER
	  JRST	CHKD.1			;NO
CHKD.6:	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVFIL##		; AND FILE NAME
	PUSHJ	P,FWORD
	  POPJ	P,
	XOR	T1,.FZDDB##+.FXNAM(I)	;CLEAR
	TDNE	T1,.FZDDB##+.FXNMM(I)	;TEST WILDS
	  JRST	CHKD.1			;FAILED
	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVEXT##		; AND EXTENSION
	PUSHJ	P,FWORD
	  POPJ	P,
	TRZ	T1,-1			;CLEAR RH
	XOR	T1,.FZDDB##+.FXEXT(I)	;COMPARE TO MATCH
	TLNE	T1,(T1)			;TEST AGAINST MATCH
	  JRST	CHKD.1			;FAILED
	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVPPN##		; AND PPN WORD
	PUSHJ	P,FWORD
	  POPJ	P,
	XOR	T1,.FZDDB##+.FXDIR(I)	;CLEAR
	TDNE	T1,.FZDDB##+.FXDIM(I)	;TEST WILDS
	  JRST	CHKD.1			;FAILED
	JRST	.POPJ1##		;MATCH!

CHKD.2:	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVFIL##		; AND FILE NAME
	PUSHJ	P,FWORD
	  POPJ	P,
	TLNN	T1,-1			;SEE IF LH=0
	  HRLI	T1,'DET'		;YES--MUST BE DETACHED
	CAMN	T1,.FZDDB##+.FXDEV(I)	;SEE IF MATCHS
	  JRST	.POPJ1##		;WIN!!
	TRNE	P1,-1			;GENERIC? (3 CHARS)
	  JRST	CHKD.1			;NO
	TRZ	T1,-1			;YES--GET JUST THAT
	CAMN	T1,P1			;SEE IF MATCHES
	  JRST	.POPJ1##		;WIN!!
	JRST	CHKD.1			;NO

	SUBTTL	DDB routines -- LSTDDB - Routine to list DDB info

;Call:
;	T1=DEVMOD(D)
;	D=DDB address

LSTDDB:	MOVEM	T1,DDBMOD		;SAVE DEVMOD
	MOVE	T1,D			;POINT TO DDB
	ADD	T1,DEVIOS##		; AND TO DEVIOS WORD
	PUSHJ	P,FWORD			;FROM DDB
	  POPJ	P,
	MOVEM	T1,DDBIOS		;STORE FOR LATER
	MOVE	T1,D			;POINT TO DDB
	ADD	T1,DEVSPL##		; AND DEVSPL WORD
	PUSHJ	P,FWORD			;FROM DDB
	  POPJ	P,
	MOVEM	T1,DDBSPL		;SAVE
	TRZ	F,FR.DSKDDB!FR.MTADDB!FR.NETDDB!FR.TTYDDB	;FLAG NOT A DSK DDB
	SETZM	DDBACC			;AND NO ACCESS TABLE POINTER
	SKIPG	T3,.FZDBS##(I)		;SEE IF /DDBS
	 MOVEI	T3,%NORMAL##		;NO--USE NORMAL
	CAIN	T3,PD.DDB##		;PRESENT DEFAULT?
	 MOVE	T3,.FZFMT##(I)		;YES--DEFAULT FROM /FAST/SLOW
	TLNE	T3,-1			;FORMAT SPECIFIER?
	 MOVEI	T3,%NORMAL##		;YES--BETTER USE NORMAL
	MOVE	T1,DDBDAT##(T3)		;GET FORMAT DESCRIPTOR
	PUSHJ	P,PRTFMT##		;TYPE
	MOVX	T2,IFMMTA##		;GET /INFORM:MTA
	TRNE	F,FR.MTADDB		;MTA?
	 TDNN	T2,.FZINF##(I)		;SEE IF GIVEN
	  CAIA				;NO
	   PUSHJ P,INFMTA		;YES--DUMP IT
	MOVX	T2,IFMSIZE##		;GET /INFORM:SIZE
	SKIPE	T1,DDBACC		;SEE IF ACCESS TABLE
	 TDNN	T2,.FZINF##(I)		;SEE IF GIVEN
	  POPJ	P,			;NO
	PJRST	INFSIZ			;YES--DUMP IT
INFSIZ:	PUSHJ	P,.SAVE1##		;SAVE P1
	MOVEI	P1,(T1)			;SAVE POINTER
	MOVEI	T1,5			;SPACE OVER
	PUSHJ	P,.TSPAN##		;TYPE
	$TYPE	<Size written: >
	MOVE	T1,P1			;GET ACCESS TABLE ADDRESS
	ADD	T1,ACCWRT##		;GET WRITTEN SIZE
	PUSHJ	P,MWORD			;..
	PUSHJ	P,.TDECW##		;TYPE
	$TYPE	< allocated: >
	MOVE	T1,P1			;GET ACCESS TABLE ADDR
	ADD	T1,ACCALC##		;GET ALLOCATED SIZE
	PUSHJ	P,MWORD			;..
	PUSHJ	P,.TDECW##		;TYPE
	$TYPE	< Created: >
	MOVE	T1,P1			;GET ACCESS TABLE ADDR
	ADD	T1,ACCADT##		;GET HIGH DATE
	PUSHJ	P,MWORD			;..
	HLRZS	T1			;POSITION LIKE .RBEXT
	LOAD	T2,T1,RB.CRX		;GET HIGH PART
	LSH	T2,WID(RB.CRD)		;POSITION
	MOVE	T1,P1			;GET ACCESS TABLE ADDR
	ADD	T1,ACCPRV##		;GET PRIVILIEGE WORD (.RBPRV)
	PUSHJ	P,MWORD			;..
	PUSH	P,T1			;SAVE NEW BITS
	LOAD	T1,T1,RB.CRD		;GET LOW DATE
	XOR	T1,T2			;INCLUDE HIGH DATE
	PUSHJ	P,.TDATE##		;TYPE
	PUSHJ	P,.TSPAC##		;SPACE
	POP	P,T1			;RESTORE BITS
	LOAD	T1,T1,RB.CRT		;GET CREATION TIME
	PUSHJ	P,.TTME##		;TYPE
	PJRST	.TCRLF##		;CRLF AND RETURN
INFMTA:	PUSHJ	P,.SAVE1##		;SAVE P1
	MOVE	T1,D			;GET DDB BASE ADDRESS
	ADD	T1,TDVUDB##		;POINT TO UDB
	PUSHJ	P,FWORD			;FROM DDB
	  POPJ	P,
	HLRZ	P1,T1			;SAVE UDB ADDRESS
	MOVEI	T1,5			;SPACE OVER
	PUSHJ	P,.TSPAN##		;..
	$TYPE	<Density:>
	MOVE	T1,D			;GET DDB BASE ADDRESS
	ADD	T1,TDVSTS##		;POINT TO STATUS BITS
	PUSHJ	P,FWORD			;..
	  POPJ	P,
	LDB	T1,[POINT 4,T1,35]	;GET DENSITY
	MOVE	T1,DENTAB(T1)		;GET TEXT
	PUSHJ	P,.TSTRG##		;TYPE
	$TYPE	<  Track:>
	MOVE	T1,P1			;POINT TO TUB
	ADD	T1,TUBCNF##		; AND TUBCNF
	PUSHJ	P,FWORD			;..
	  POPJ	P,
	LDB	T1,[POINT 1,T1,18]	;GET TRACK
	MOVE	T1,[DEC 9,7](T1)	;GET VALUE
	PUSHJ	P,.TDECW##		;TYPE
	$TYPE	<  Mode:>
	MOVE	T1,D			;GET DDB BASE ADDRESS
	ADD	T1,TDVSTS##		;POINT TO STATUS BUTS
	PUSHJ	P,FWORD			;..
	  POPJ	P,
	LDB	T1,[POINT 3,T1,10]	;GET MODE
	MOVE	T1,MODTAB(T1)		;GET NAME
	PUSHJ	P,.TSTRG##		;TYPE
	$TYPE	<  Labels:>
	PUSHJ	P,SB$MDA##		;SEE IF MDA
	JUMPE	T1,[MOVNI T1,1		;JUMP IF NO MDA
		    JRST  INFM.1]	;SO USE -1 INDEX
	MOVE	T1,P1			;POINT TO TUB
	ADD	T1,TUBLBL##		; AND LABEL TYPE
	PUSHJ	P,FWORD			;..
	  POPJ	P,
	LDB	T1,[POINT 4,T1,35]	;GET LABEL TYPE
INFM.1:	MOVE	T1,LABTAB(T1)		;GET NAME
	PUSHJ	P,.TSTRG##
	PJRST	.TCRLF##
	MOVE	T1,D			;POINT TO DDB
	ADD	T1,DEVNAM##		;OFFSET TO NAME
	PUSHJ	P,MWORD			;GET IT
	LSH	T1,-^D24		;POSITION
	CAIE	T1,(SIXBIT/ 'L/)	;LABEL DDB?
	PJRST	.TCRLF##		;NO--ALL DONE
	$TYPE	<  Job:>		;PREPARE TO TYPE REAL DDB JOB NUMBER
	MOVE	T1,D			;POINT TO DDB
	ADD	T1,TDVUDB##		;OFFSET TO UDB POINTER
	PUSHJ	P,MWORD			;GET IT
	HLRZS	T1			;KEEP ONLY UDB ADDRESS
	ADD	T1,TUBDDB##		;OFFSET TO DDB POINTER
	PUSHJ	P,MWORD			;GET IT
	HRRZS	T1			;KEEP ONLY DDB ADDRESS
	ADD	T1,DEVJOB##		;FIND DEVJOB
	PUSHJ	P,MWORD			;FROM MONITOR
	LDB	T1,[POINT 9,T1,35]	;GET JOB NUMBER
	PUSHJ	P,.TDECW##		;TYPE IT
	PJRST	.TCRLF##		;FINISH LINE AND RETURN

DENTAB:	[ASCIZ/default/]
	[ASCIZ/200/]
	[ASCIZ/556/]
	[ASCIZ/800/]
	[ASCIZ/1600/]
	[ASCIZ/6250/]

MODTAB:	[ASCIZ/none/]
	[ASCIZ/DEC core dump/]
	[ASCIZ/Industry core dump/]
	[ASCIZ/SIXBIT/]
	[ASCIZ/ASCII/]
	[ASCIZ/DEC core dump/]

	[ASCIZ/No MDA/]
LABTAB:	[ASCIZ/Bypass/]
	[ASCIZ/ANSI/]
	[ASCIZ/ANSI(user)/]
	[ASCIZ/IBM/]
	[ASCIZ/IBM(user)/]
	[ASCIZ/leading tape mark/]
	[ASCIZ/nonstandard/]
	[ASCIZ/none/]
	[ASCIZ/COBOL ASCII/]
	[ASCIZ/COBOL SIXBIT/]
	[ASCIZ/user EOT/]
DG$ACT::PUSHJ	P,JB$DDB##		;GET I/O ACTIVE DDB
	CAIN	T1,(D)			;THIS ONE?
	 SKIPA	T1,["*"]		;YES--FLAG
	  MOVEI	T1," "			;NO--SPACE
	POPJ	P,

DG$SPL::MOVEI	T1," "			;LOAD SPACE
	SKIPGE	DDBSPL			;SEE IF SPOOLED
	  MOVEI	T1,"'"			;YES--FLAG
	POPJ	P,

DG$DEV::MOVE	T1,D			;GET DDB ADDR
	ADD	T1,DEVNAM##		; AND DEVICE NAME
	PUSHJ	P,FWORD			;PEEK
	  MOVE	T1,['??????']		;WE DON'T KNOW WHAT IT IS
	TLNN	T1,-1			;SEE IF LH=0
	  HRLI	T1,'DET'		;YES--MUST BE DETACHED
	POPJ	P,

DG$MOD::HRRZ	T1,DDBIOS		;GET DDB I/O STATUS
	POPJ	P,

DG$ADR::MOVEI	T1,(D)			;GET DDB ADDRESS
	POPJ	P,

DG$AIF::MOVE	T2,DDBMOD		;GET DEVMOD
	TDNE	T2,ASSCON##		;ASSIGNED?
   	 MOVEI	T1,[ASCIZ/A/]		;GET ASSIGNED
	TDNE	T2,ASSPRG##		;INITED?
	 MOVEI	T1,[ASCIZ/I/]		;YES
	PUSH	P,T3			;SAVE T3
	MOVE	T3,ASSCON##		;GET ASSIGNED BY CONSOLE COMMAND
	IOR	T3,ASSPRG##		;AND ASSIGNED BY PROGRAM INIT
	TDC	T2,T3			;SEE IF EITHER ON
	 TDCN	T2,T3			;SEE IF BOTH
	  MOVEI	T1,[ASCIZ/A+I/]		;YES
	POP	P,T3			;RESTORE T3
	POPJ	P,

DG$LOG::MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVLOG##		; AND LOGICAL NAME
	PUSHJ	P,FWORD			;PEEK
	  MOVE	T1,['??????']		;TOO BAD
	POPJ	P,

TSDDB::	PUSHJ	P,.SAVE1##
	MOVE	P1,DDBMOD
	MOVE	T1,DVDSK##		;GET DSK
	IOR	T1,DVMTA##		; AND MTA BITS
	TSC	P1,T1			;SEE IF NUL:
	TSCN	P1,T1			;...
	 POPJ	P,			;YES
	MOVE	T1,D			;POINT TO DDB
	ADD	T1,DEVCHR##		; AND DEVCHR WORD
	PUSHJ	P,FWORD			;GET IT
	  POPJ	P,			;DDB IS SWAPPED
	TDNE	T1,DVCNET##		;NETWORK DEVICE?
	 TRO	F,FR.NETDDB		;YES--FLAG
	TSNN	P1,DVDSK##		;SEE IF DISK
	 SKIPGE	DDBSPL			;OR SPOOLED
	  PUSHJ P,DSKDDB		;YES--PRINT DSK STUFF
	TSNE	P1,DVMTA##		;MTA?
	  PUSHJ	P,MTADDB		;YES--PRINT MTA STUFF
	TSNE	P1,DVTTY##		;TTY?
	  PUSHJ	P,TTYDDB		;YES--PRINT TTY STUFF
	TSNE	P1,DVDTA##		;DTA?
	  PUSHJ	P,DTADDB		;YES--PRINT DTA STUFF
	MOVE	T1,D			;GET DDB ADDR
	ADD	T1,DEVNAM##		; AND DEVICE NAME
	PUSHJ	P,FWORD
	  POPJ	P,
	HLRZS	T1
	CAIN	T1,'TSK'
	 PJRST	TSKDDB			;YES--PRINT TSK STUFF
	CAIN	T1,'PTY'
	 PJRST	PTYDDB			;YES--PRINT PTY STUFF
	TRNE	F,FR.NETDDB		;SEE IF NET DDB (NOT TSK)
	 PUSHJ	P,NETDDB		;YES--TYPE IT
	POPJ	P,			;AND RETURN

DG$IO::	MOVE	T2,DDBIOS		;GET DEVIOS
	MOVEI	T1,"R"			;ASSUME READ
	TSNE	T2,IO##			;WRITE?GET THE PUN?
	 MOVEI	T1,"W"			;WRITE(WRONG?)
	POPJ	P,

DG$SIO::MOVE	T2,DDBIOS		;GET DEVIOS
	TRNE	F,FR.DSKDDB		;A DISK DDB?
	 TSNN	T2,IOSUPR##		;SUPER IO?
	  SKIPA	T1,[" "]		;NO
	   MOVEI T1,"S"			;YES
	POPJ	P,
	SUBTTL	DDB routines -- DSKDDB - Print disk DDB specific information

;Call:
;	D=DDB address

DSKDDB:	TRO	F,FR.DSKDDB		;FLAG A DISK DDB
	PUSHJ	P,.SAVE1##
	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVACC##		;OFFSET TO ACCESS TABLE POINTER
	PUSHJ	P,FWORD			;GET IT
	  POPJ	P,
	MOVEI	T1,(T1)			;KEEP JUST ACC ADDR
	MOVEM	T1,DDBACC		;SAVE
	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVUNI##		;GET UNIT POINTER
	PUSHJ	P,FWORD			;..
	  POPJ	P,
	HLRZS	T1			;GET FIRST UDB
	JUMPE	T1,PRTD.4		;NONE--DONT TRY
	ADD	T1,UNILOG##		;GET UNIT DATA BLOCK ADDRESS
	PUSHJ	P,FWORD
	  POPJ	P,
	JRST	PRTD.3			;TYPE
PRTD.4:	MOVE	T1,D			;GET DDB ADDR
	ADD	T1,DEVNAM##		; AND DEVICE NAME
	PUSHJ	P,FWORD			;..
	  POPJ	P,
PRTD.3:	PUSHJ	P,.TDEVN##		;TYPE
	MOVE	T1,DDBIOS		;GET DEVIOS
	TSNE	T1,IOSUPR##		;SUPER I/O?
	  POPJ	P,			;YES
	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVFIL##		; AND FILE NAME
	PUSHJ	P,FWORD			;..
	  POPJ	P,
	JUMPE	T1,.POPJ##		;JUMP IF NONE
	PUSH	P,T1			;SAVE
	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVEXT##		; AND EXTENSION
	PUSHJ	P,FWORD			;GET IT
	  POPJ	P,
	HLRZS	T1
	CAIE	T1,'UFD'		;SEE IF UFD
	  JRST	PRTM.1			;NO
	POP	P,T1			;GET FILENAME
	PUSHJ	P,.TPPNW##		;TYPE AS PPN
	MOVEI	T1,[ASCIZ/.UFD/]	;ITS A UFD
	PJRST	.TSTRG##		;TYPE AND RETURN
PRTM.1:	POP	P,T1			;GET FILENAME BACK
	PUSHJ	P,.TSIXN##		;TYPE
	PUSHJ	P,.TDOT##
	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVEXT##		; AND EXTENSION
	PUSHJ	P,FWORD			;..
	  POPJ	P,
	TRZ	T1,-1			;ONLY LH
	PUSHJ	P,.TSIXN##		;TYPE
	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVPPN##		; AND PPN WORD
	PUSHJ	P,FWORD			;..
	  POPJ	P,
	CAIE	T1,0			;FORGET IF BLANK
	 PUSHJ	P,DSKPTH		;YES--PRINT PATH INFO
	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVSPN##		;OFFSET TO SPOOLED FILE NAME
	PUSHJ	P,FWORD
	  POPJ	P,
	JUMPN	T1,[PUSH  P,T1		;SAVE T1
		    PUSHJ P,.TSPAC##	;SPACE OVER
		    POP   P,T1		;RESTORE T1
		    PUSHJ P,.TSIXP##	;TYPE IT
		    JRST  .+1]		;AND CONTINUE
	POPJ	P,			;RETURN

DG$BLK::MOVEI	T1,0
	TRNN	F,FR.DSKDDB		;DSK DDB?
	 POPJ	P,			;NO
	MOVE	T1,DEVREL##		;GET RELATIVE BLOCK
	MOVE	T2,DDBIOS		;GET DEVIOS
	TSNE	T2,IOSUPR##		;SUPER I/O?
	 MOVE	T1,DEVBLK##		;YES--GET BLOCK ON UNIT
	ADDI	T1,(D)			;OFFSET INTO THE DDB
	PUSHJ	P,FWORD			;GET FROM MONITOR
	  MOVNI	T1,1			;SET TO -1 SINCE JOB MUST BE SWAPPED
	POPJ	P,

DP$ACC::TRNE	F,FR.MTADDB		;MTA?
	 JRST	DP$ACM			;YES
	TRNN	F,FR.DSKDDB		;DSK DDB?
	 POPJ	P,			;NO
	SKIPN	T1,DDBACC		;GET ACCESS TABLE IF ANY
	 POPJ	P,			;NONE
	ADD	T1,ACCCNT##		;GET READ COUNT
	PUSHJ	P,MWORD			;..
	AND	T1,ACMCNT##		;KEEP ONLY THE READ COUNT
	PUSH	P,T1			;SAVE DATA
	MOVE	T1,ACPCNT##		;GET RIGHT MOST BIT
	JFFO	T1,.+1			;COMPUTE LEADING ZEROS
	POP	P,T1			;GET DATA BACK AGAIN
	ROT	T1,1(T2)		;RIGHT JUSTIFY IT
	CAIN	T1,1			;TURN ONE
	 MOVEI	T1,0			;INTO ZERO
	CAIE	T1,0			;ANYTHING?
	 PUSHJ	P,.TDECW##		;YES--TYPE
	MOVE	T1,DDBACC		;GET ACCESS TABLE POINTER
	ADD	T1,ACCSTS##		;GET ACCESS TABLE STATUS WORD
	PUSHJ	P,MWORD			;GET IT
	LDB	T2,[POINT 3,T1,32]	;GET STATUS
	MOVE	T2,["R"		
		    "U"
	    	    "S"
		    "?"
	  	    "C"](T2)		;GET CODE
	TDNE	T1,ACPSMU##		;MULTIUSER UPDATE?
	 MOVEI	T2,"M"			;YES
	MOVEI	T1,(T2)
	PJRST	.TCHAR##		;TYPE CHAR AND RETURN

DG$AC1::MOVEI	T1," "
	TRNE	F,FR.MTADDB		;MTA?
	 JRST	DGAC1			;YES--SLASH
	TRNN	F,FR.DSKDDB		;DSK DDB?
	  POPJ	P,			;NO
	SKIPG	T2,DDBACC		;ACCESS TABLE?
	 POPJ	P,			;NO
	MOVE	T1,T2			;GET ACCESS TABLE ADDR
	ADD	T1,ACCDEL##		;GET DELETE BIT
	PUSHJ	P,MWORD
	TDNN	T1,ACPDEL##		;DELETE?
DGAC1:	 SKIPA	T1,["/"]		;NO--ADD SLASH
	  MOVEI	T1,"!"			;YES--FLAG
	POPJ	P,			;RETURN

DP$ACM:	MOVE	T2,TBSTS		;GET TUBSTS
	TDNN	T2,TUSWTL##		;WRITE LOCKED?
	 SKIPA	T1,[SIXBIT/WE/]		;WRITE
	  MOVSI	T1,'WL '		;NO
	PJRST	.TSIXN##		;TYPE AND RETURN
	SUBTTL	DDB routines -- DSKPTH - Print PPN and PATH info

DSKPTH:	PUSH	P,T1			;SAVE PPN
	PUSHJ	P,.TLBRK##		;OPEN "["
	POP	P,T1			;GET PPN
	PUSHJ	P,.TXWDW##		;TYPE P,PN
	MOVEI	T1,[ASCIZ/,]/]		;CLOSE OFF WITH TRAILING COMMA
	SKIPN	DDBACC			;ACCESS TABLE?
	 PJRST	.TSTRG##		;NO--TERMINATE
;ROUTINE TO TYPE A PATH WITH SFD'S IF NEEDED

	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVSFD##		;GET PATH POINTER
	PUSHJ	P,FWORD		;FROM MONITOR
	  POPJ	P,
	TLZ	T1,-1		;CLEAR LH
	PJUMPE	T1,.TRBRK##	;CLOSE "]" IF NONE
	PUSHJ	P,.SAVE1##	;SAVE P1
	MOVEI	P1,(T1)		;SAVE PATH POINTER
	PUSH	P,[0]		;MARK END OF PATH
PRTPT1:	MOVE	T1,P1		;GET NMB
	ADD	T1,NMBNAM##	; AND SFD NAME
	PUSHJ	P,MWORD		;FROM MONITOR
	PUSH	P,T1		;SAVE THE SFD NAME
PRTPT2:	MOVE	T1,P1		;GET NMB
	ADD	T1,NMBPPB##	; AND PPB
	PUSHJ	P,MWORD		;READ WORD
	HLRZ	P1,T1		;SAVE
	TDZN	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,T1		;RESTORE SFD NAME
	PJUMPE	T1,.TRBRK##	;IF END, CLOSE "]"
	PUSH	P,T1		;SAVE SFD
	PUSHJ	P,.TCOMA##	;TYPE ","
	POP	P,T1		;RESTORE SFD NAME
	PUSHJ	P,.TSIXN##	;TYPE IT
	JRST	PRTPT3		;LOOP OVER WHOLE PATH
	SUBTTL	DDB routines -- MTADDB - Print magtape DDB specific information

;Call:
;	D=DDB address


MTADDB:	TRO	F,FR.MTADDB		;FLAG A MTA
	PUSHJ	P,.SAVE2##		;SAVE P2
	MOVE	T1,D			;GET DDB BASE ADDRESS
	ADD	T1,TDVUDB##		;POINT TO UDB
	PUSHJ	P,FWORD			;FROM DDB
	  POPJ	P,
	HLRZ	P1,T1			;SAVE UDB
	$TYPE	<reelid >
	MOVE	T1,P1			;POINT TO TUB
	ADD	T1,TUBRID##		; AND REELID
	PUSHJ	P,FWORD			;GET IT
	  POPJ	P,
	CAIN	T1,0
	 MOVE	T1,[SIXBIT/(NONE)/]	;MAKE NONE IF BLANK
	PUSHJ	P,.TSIXN##
	$TYPE	< file >
	MOVE	T1,P1			;POINT TO TUB
	ADD	T1,TUBFIL##		; AND FILE NUMBER
	PUSHJ	P,FWORD			;FROM UDB
	  POPJ	P,
	PUSHJ	P,.TDECW##		;TYPE
	$TYPE	< record >
	MOVE	T1,P1			;POINT TO TUB
	ADD	T1,TUBREC##		; AND RECORD COUNT
	PUSHJ	P,FWORD			;FROM UDB
	  POPJ	P,
	JUMPGE	T1,MTAD.1		;JUMP IF POSITIVE
	$TYPE	<???>			;THIS IS WHAT COMCON DOES!!
	JRST	MTAD.2			;AND CONTINUE
MTAD.1:	PUSHJ	P,.TDECW##		;TYPE
MTAD.2:	MOVE	T1,P1			;POINT TO TUB
	ADD	T1,TUBSTS##		; AND STATUS WORD
	PUSHJ	P,FWORD			;GET IT
	  POPJ	P,
	MOVEM	T1,TBSTS		;SAVE IT
	MOVE	P2,T1			;SAVE IT
	MOVSI	T1,-STSLEN		;LENGTH OF BITS
MTAD.3:	HLRZ	T2,STSTAB(T1)		;GET ADDRESS OF BIT
	MOVE	T2,(T2)			;NOW GET THE BIT
	TLNN	P2,(T2)			;ON?
	 JRST	MTAD.4			;NO
	PUSH	P,T1			;SAVE T1
	HRRZ	T1,STSTAB(T1)		;GET CODE
	PUSHJ	P,.TSTRG##		;TYPE
	POP	P,T1			;RESTORE T1
MTAD.4:	AOBJN	T1,MTAD.3		;LOOP FOR ALL
	POPJ	P,			;AND RETURN

;table of LH bit in TUBSTS/TUBCNF and ASCIZ string to type

STSTAB:	XWD	TKSOFL##,[ASCIZ/ OFL/]
	XWD	TKSSEL##,[ASCIZ/ SEL/]
	XWD	TKSSTD##,[ASCIZ/ STD/]
	XWD	TUSNS## ,[ASCIZ/ UNS/]
	XWD	TUSBOT##,[ASCIZ/ BOT/]
	XWD	TUSREW##,[ASCIZ/ REW/]
STSLEN==.-STSTAB
	SUBTTL	DDB routines -- TTYDDB - Print TTY DDB specific information

TTYDDB:	TRO	F,FR.TTYDDB		;FLAG TTY DDB
	MOVEI	T1,(D)			;GET DDB
	PUSHJ	P,STRMND		;GET UDX FROM DDB
	 POPJ	P,			;NONE?
	TLNN	F,(FL.DECNET)		;HAVE DECNET?
	JRST	TTYD.2			;NO
	MOVE	T4,T1			;SAVE UDX INCASE LINE NOT DECNET
	MOVEI	T2,-.UXTRM(T1)		;COPY IT
	MOVEI	T1,DCNNRT		;POINT TO SCRATCH NRTINF BLOCK
	PUSHJ	P,NRTINF		;GET NRTSER INFO
	  SKIPA				;CAN'T--TRY FOR ANF10
	SKIPN	DCNNRT+.NRTFL		;IS THIS A NRTSER LINE?
	JRST	TTYD.1			;NO
	$TYPE	<node >
	SKIPN	T1,DCNNRT+.NRTNM	;GET NODE NAME
	MOVE	T1,[SIXBIT/??????/]	;STRANGE ...
	PUSHJ	P,.TSIXN##		;TYPE IT
	PUSHJ	P,.TLPAR##		;TYPE "("
	MOVE	T1,DCNNRT+.NRTNN	;GET NODE NUMBER
	PUSHJ	P,.TDECW##		;TYPE IT
	PUSHJ	P,.TDOT##		;DECNET NODES ARE DECIMAL
	PUSHJ	P,.TRPAR##		;TYPE ")"
	$TYPE	< DECnet channel >
	MOVE	T1,DCNNRT+.NRTCH	;GET CHANNEL NUMBER
	PJRST	.TOCTW##		;TYPE AND RETURN

TTYD.1:	MOVE	T1,T4			;GET UDX BACK
TTYD.2:	TLNN	F,(FL.ANF10)		;HAVE NETWORK SOFTWARE?
	 POPJ	P,			;NO--JUST RETURN
	PUSHJ	P,UGTNTN		;MAKE NODE,,LINE
	 JRST	TTYDNC			;NOT CONNECTED
	PUSHJ	P,.SAVE1##		;SAVE P1
	MOVE	P1,T1			;SAVE IT
	$TYPE	<node >
	HLRZ	T1,P1			;GET NODE NUMBER
	PUSHJ	P,ANODE			;MAKE NODE NAME
	 MOVE	T1,[SIXBIT/??????/]	;(SHOULD NEVER HAPPEN)?
	PUSHJ	P,.TSIXN##		;TYPE
	HLRZ	T1,P1			;GET NODE NUMBER
	PUSHJ	P,.TOCTP##		;TYPE IN ( )
	$TYPE	< line >
	MOVEI	T1,(P1)			;GET LINE
	PJRST	.TOCTW##		;TYPE AND RETURN

TTYDNC:	MOVEI	T1,[ASCIZ/not connected/]
	PJRST	.TSTRG##
	SUBTTL	DDB routines -- NETDDB - Print NET DDB specific information

NETDDB:	$TYPE	<node >
	MOVE	T1,D			;GET DDB ADDR
	ADD	T1,DEVNET##		; AND DEVNET WORD
	PUSHJ	P,MWORDR		;RH ONLY
	PUSH	P,T1			;SAVE A MOMENT
	PUSHJ	P,ANODE			;MAKE NODE NAME
	 MOVE	T1,[SIXBIT/??????/]	;HUH?
	PUSHJ	P,.TSIXN##		;TYPE
	POP	P,T1			;RESTORE NUMBER
	PUSHJ	P,.TOCTP##		;TYPE IN ( )
	$TYPE	< unit >
	MOVE	T1,D			;POINT TO DDB
	ADD	T1,DEVJOB##		; AND DEVJOB WORD
	PUSHJ	P,MWORD			;FROM MONITOR
	LDB	T1,[POINT 9,T1,26]	;GET UNIT
	PJRST	.TOCTW##		;TYPE AND RETURN

DP$SLA::TRNE	F,FR.TTYDDB		;TTY DDB?
	 JRST	TTYSLA			;YES
	TRNN	F,FR.NETDDB		;NETWORK DDB?
	 POPJ	P,			;NO--RETURN
	$TYPE	<SLA:>
	HRRZ	T1,NT%SLA##		;GET RH OF BYTE POINTER
	ADDI	T1,(D)			;GET NETXLA
	PUSHJ	P,MWORD			;..
	MOVE	T2,NT%SLA##		;GET BYTE POINTER
	AND	T2,[7777B11]		;KEEP BYTE SIZE AND POSITION
	HRR	T2,T1			;POINT TO TARGET
	LDB	T1,T2			;LOAD SLA
	PJRST	.TOCTW##		;TYPE AND RETURN

TTYSLA:	PUSHJ	P,TTYLA			;GET LA
	 POPJ	P,			;NONE
	PUSH	P,T1			;SAVE
	$TYPE	<SLA:>
	POP	P,T1			;RESTORE LA
	LDB	T1,[POINT 13,T1,12]	;GET SLA
	PJRST	.TOCTW##		;TYPE AND RETURN

TTYLA:	MOVE	T1,D			;POINT TO DDB
	ADD	T1,DDBLDB##		; AND THE LDB ADDRESS
	PUSHJ	P,MWORDR		;..
	JUMPE	T1,.POPJ##		;ERROR IF NONE
	MOVEI	T4,(T1)			;SAVE
	ADD	T1,$LDDCH		;GET CHARACTERISTICS
	PUSHJ	P,MWORD			;FROM MONITOR
	TDNN	T1,LDRREM##		;REMOTE TTY?
	 POPJ	P,			;NO--RETURN
	MOVEI	T1,2(T4)		;GET LDB+X ADDR
	ADD	T1,LDBREM##		; AND LDBREM WORD
	PUSHJ	P,MWORD			;GET IT
	JRST	.POPJ1##		;RETURN

DP$DLA::TRNE	F,FR.TTYDDB		;TTY DDBS?
	 JRST	TTYDLA			;YES
	TRNN	F,FR.NETDDB		;NETWORK DDB?
	 POPJ	P,			;NO--RETURN
	$TYPE	<DLA:>
	HRRZ	T1,NT%DLA##		;GET RH OF BYTE POINTER
	ADDI	T1,(D)			;GET NETXLA
	PUSHJ	P,MWORD			;..
	MOVE	T2,NT%DLA##		;GET BYTE POINTER
	AND	T2,[7777B11]		;KEEP BYTE SIZE AND POSITION
	HRR	T2,T1			;POINT TO TARGET
	LDB	T1,T2			;LOAD DLA
	PJRST	.TOCTW##		;TYPE AND RETURN

TTYDLA:	PUSHJ	P,TTYLA			;GET LA
	 POPJ	P,			;NONE
	PUSH	P,T1			;SAVE
	$TYPE	<DLA:>
	POP	P,T1			;RESTORE LA
	LDB	T1,[POINT 13,T1,25]	;GET DLA
	PJRST	.TOCTW##		;TYPE AND RETURN
	SUBTTL	DDB routines -- TSKDDB - Print TSK DDB specific information

TSKDDB:	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVNPD##		; AND NPD WORD
	PUSHJ	P,FWORD			;FROM MONITOR
	  POPJ	P,
	PUSH	P,T1			;SAVE A MOMENT
	TLNN	T1,-1			;SEE IF INPUT
	 JRST	TSKD.1			;NO
	$TYPE	<I: >
	HLRZ	T1,(P)			;GET NPD ADDRESS
	PUSHJ	P,TSKNPD		;LIST THAT
	PUSHJ	P,.TSPAC##		;SPACE
TSKD.1:	HRRZ	T1,(P)			;GET OUTPUT
	JUMPE	T1,TSKD.2		;NONE
	$TYPE	<P: >
	HRRZ	T1,(P)			;GET ADDR BCAK
	PUSHJ	P,TSKNPD		;LIST THAT
TSKD.2:	PJRST	.PT1J##			;POP T1 AND RETURN


TSKNPD:	PUSHJ	P,.SAVE3##		;SAVE SOME ACES
	MOVEI	P1,(T1)			;SAVE NPD ADDRESS
	MOVE	T1,P1			;GET NPD ADDR
	ADD	T1,NPDNOD##		; AND NODE WORD
	PUSHJ	P,MWORD
	CAME	T1,[-1]			;SEE IF ANY
	 PUSHJ	P,ANODE			;CONVER TO NODE NAME
	  MOVSI	T1,'*  '		;DEFAULT TO ALL
	PUSHJ	P,.TSIXN##		;TYPE
	PUSHJ	P,.TCOLN##		;TYPE :
	PUSHJ	P,.TCOLN##		; ::
	TLNN	F,(FL.PEEK)		;PEEK?
	 POPJ	P,			;NO--NO NPD STRING
	MOVE	T1,P1			;GET NPD ADDR
	ADD	T1,NPDNLN##		; AND LENGTH WORD
	PUSHJ	P,MWORD
	MOVEI	P2,(T1)			;SAVE LENGTH
	JUMPE	P2,.POPJ##
	ADD	P1,NPDNAM##		;POINT TO START
TSKN.1:	MOVEI	T1,(P1)			;COPY ADDRESS
	PUSHJ	P,MWORD			;GET 5 CHARS
	MOVE	T3,T1			;SAVE WORD
	MOVE	T2,[POINT 7,T3]		;POINT TO TO
REPEAT 5,<
	ILDB	T1,T2			;GET CHAR
	PUSHJ	P,TCHAR
	SOJLE	P2,.POPJ##		;RETURN IF DONE
>
	AOJA	P1,TSKN.1		;LOOP FOR NEXT WORD

TCHAR:	CAIN	T1,0			;TURN NULL
	 MOVEI	T1,"\"			;INTO BACKSLASH
	CAIL	T1," "			;SEE IF CONTROL-CHAR
	 PJRST	.TCHAR##		;NO--SEND IT
	PUSH	P,T1			;SAVE IT
	MOVEI	T1,"^"			;FLAG
	PUSHJ	P,.TCHAR##		;..
	POP	P,T1			;RESTORE IT
	ADDI	T1,"A"-1		;INTO PRINTABLE
	PJRST	.TCHAR##		;TYPE AND RETURN
	SUBTTL	DDB routines -- PTYDDB - Print PTY DDB specific information

PTYDDB:	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVJOB##		; AND DEVJOB WORD
	PUSHJ	P,FWORD			;FROM MONITOR
	  POPJ	P,
	LDB	T1,[POINT 9,T1,26]	;GET UNIT NUMBER
	ADD	T1,SYSPTY		;FORM TERMINAL NUMBER
	ADD	T1,LINTAB		;POINT TO LINTAB+TTYN
	PUSHJ	P,FWORD			;GET LDB ADDRESS
	  POPJ	P,
	ADD	T1,LDBDDB##		;GET DDB ADDRESS
	PUSHJ	P,FWORD			;..
	  POPJ	P,
	ADD	T1,DEVJOB##		;GET DEVJOB
	PUSHJ	P,FWORD
	  POPJ	P,
	LDB	T1,[POINT 9,T1,35]	;GET JOB NUMBER
	JUMPE	T1,.POPJ##		;RETURN IF NO JOB
	PUSH	P,O			;SAVE J
	MOVE	O,T1			;COPY JOB
	PUSHJ	P,JOBSET##		;SETUP FOR THAT JOB
	 JRST	PTYD.1			;WHAT, NO JOB?
	$TYPE	<job >
	MOVE	T1,O
	PUSHJ	P,.TDECW##
	$TYPE	< running >
	PUSHJ	P,JB$PRG##
	PUSHJ	P,.TSIXN##
	PUSHJ	P,JB$BSN##
	JUMPL	T1,PTYD.1		;SKIP IF NO BATCH STREAM
	$TYPE	< in stream >
	PUSHJ	P,JB$BSN##
	PUSHJ	P,.TDECW##
PTYD.1:	POP	P,O
	PJRST	JOBSET##
	SUBTTL	DDB routines -- DTADDB - Print DTA DDB specific information

DTADDB:	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVFIL##		; AND FILE NAME
	PUSHJ	P,MWORD			;FETCH
	JUMPE	T1,DTAD.1		;SKIP FILE.EXT IF NO FILE NAME
	PUSHJ	P,.TSIXN##		;TYPE
	PUSHJ	P,.TDOT##		;TYPE "."
	MOVE	T1,D			;GET DDB ADDRESS
	ADD	T1,DEVEXT##		; AND EXTENSION
	PUSHJ	P,MWORD			;FETCH
	TRZ	T1,-1			;JUST LH
	PUSHJ	P,.TSIXN##		;TYPE

DTAD.1:	MOVEI	T1,[ASCIZ/   In:/]
	PUSHJ	P,.TSTRG##
	MOVE	T1,D			;GET DDB ADDR
	ADD	T1,IBLK##		; AND NEXT BLOCK TO INPUT
	PUSHJ	P,MWORDR		;GET RH
	PUSHJ	P,.TDECW##		;TYPE
	MOVEI	T1,[ASCIZ/ Out:/]
	PUSHJ	P,.TSTRG##
	MOVE	T1,D			;GET DDB ADDR
	ADD	T1,OBLK##		; AND NEXT BLOCK TO OUTPUT
	PUSHJ	P,MWORDR
	PUSHJ	P,.TDECW##
	POPJ	P,			;ALL FOR NOW DPM
	SUBTTL	LOGIN queue routines -- LGQINI -- Get initial queue statistics


IFN FTLGNQ,<
LGQINI::TLNE	F,(FL.LGNQ)		;HAVE LOGIN QUEUE SUPPORT?
	POPJ	P,			;NO
	MOVX	T1,%LQCNT		;GET COUNT OF JOBS IN LOGINQ
	PUSHJ	P,GTAB
	MOVEM	T1,LGQCNT		;SAVE
	MOVX	T1,%LQPTL		;GET ONES WITH PERMISSION
	PUSHJ	P,GTAB
	MOVEM	T1,LGQPTL		;SAVE
	POPJ	P,			;AND RETURN
> ;END IFN FTLGNQ
	SUBTTL	LOGIN queue routines -- CHKLGQ - See if in LOGIN queue

IFN FTLGNQ,<
CHKLGQ::MOVEI	T1,0			;INDICATE NOT IN Q
	TLNE	F,(FL.LGNQ)		;HAVE LOGIN QUEUE SUPPORT?
	TLNN	F,(FL.SPY)		;YES--CAN WE SPY?  **TEMP**
	 POPJ	P,			;NO--NO LOGINQ STUFF **TEMP**
	PUSHJ	P,.SAVE2##
	MOVE	P1,LGQCNT		;GET ENTRIES IN Q
	SOJL	P1,.POPJ##		;RETURN IF EMPTY
	MOVEI	T1,(O)			;GET LINE NUMBER
	ADD	T1,LINTAB		;ADD LINTAB ADDR
	PUSHJ	P,MWORD			;READ
	MOVEI	P2,(T1)			;RETURN LDB ADDR
CHKL.1:	MOVSI	T1,(P1)			;GET OFFSET
	ADD	T1,[%LQQUE]		;INCLUDE GETTAB
	PUSHJ	P,GTAB			;GET VALUE
;	LOAD	T2,T1,LQ.LDB		;GET LDB ADDR
	HRRZ	T2,T1			;GET LDB ADDRESS
	CAIN	T2,(P2)			;MATCH?
	 JRST	CHKL.2			;YES!
	SOJGE	P1,CHKL.1		;NO--LOOP FOR ALL
	MOVEI	T1,0			;INDICATE NOT IN LOGIN QUEUE
	POPJ	P,			;AND RETURN

CHKL.2:	SUB	P1,LGQPTL		;MINUS THOSE WITH PERMISSION
	ADDI	P1,1			;CORRECT FOR 0-1
	JUMPLE	P1,CHKL.3		;WE CAN LOGIN
	TDNE	T1,LQ.PLI##		;SEE IF PERMISSION
	 JRST	CHKL.3			;YES
	MOVEI	T1,(P1)			;GET POSITION IN QUEUE
	POPJ	P,			;AND RETURN

CHKL.3:	MOVNI	T1,1			;FLAG PERMISSION GIVEN
	POPJ	P,			;AND RETURN
> ;END IFN FTLGNQ
	SUBTTL	Network routines -- ANODE - Convert ANF-10 node number/name

; Convert an ANF-10 node number/name
; Call:	MOVE	T1, argument
;	PUSHJ	P,ANODE
;
ANODE::	MOVEM	T1,NODBLK+1		;SAVE NODE NUMBER
	MOVEI	T1,2			;2 WORDS LONG
	MOVEM	T1,NODBLK+0		;SAVE COUNT
	MOVE	T1,[.NDRNN,,NODBLK]	;POINT TO BLOCK
	PJRST	UNODE			;AND SIMULATE A NODE UUO
	SUBTTL	Network routines -- DNODE - Convert DECnet node number/name


; Convert a DECnet-10 node number/name
; Call:	MOVE	T1, argument
;	PUSHJ	P,DNODE
;
DNODE::	TLNE	T1,-1			;A NUMBER?
	PJRST	SCTN2A			;NO--A NAME
	ADD	T1,SCTNDT		;POINT TO NODE NAMES
	PUSHJ	P,XWORD			;GET IT
	JUMPE	T1,.POPJ##		;OK IF WE HAVE A NAME
	JRST	.POPJ1##		;RETURN
	SUBTTL	Network routines -- NODINF - Return node information


; Return node information
; Call:	MOVE	T1, node number or name
;	PUSHJ	P,NODINF
;	  <NON-SKIP>			;NO SUCH NODE
;	<SKIP>				;ON-LINE
;
; On sucessful return, the following data is returned:
;	T1:= sixbit node name
;	T2:= node number
;	T3:= flags,,network type code
;
NODINF::PUSHJ	P,.SAVE1##		;SAVE P1
	MOVE	P1,T1			;COPY ARGUMENT
	TLNE	F,(FL.NETWORKS)		;HAVE NETWORK SUPPORT?
	JRST	NODI.1			;YES
	MOVE	T1,['CENTRA']		;CENTRAL STATION
	MOVEI	T2,0			;STATION 0
	MOVEI	T3,.NTNON		;NO NETWORK SUPPORT
	JRST	.POPJ1##		;RETURN

NODI.1:	PUSHJ	P,SRCNDB		;SEARCH THE ANF10 DATA BASE
	  JRST	NODI.2			;NOT THERE
	PUSHJ	P,NODSNM		;GET THE NAME
	PUSH	P,T1			;SAVE IT
	PUSHJ	P,NODNNM		;GET NODE NUMBER
	MOVE	T2,T1			;COPY NUMBER
	POP	P,T1			;GET NAME BACK
	MOVE	T3,[NT.ONL+NT.KNO+.NTANF] ;NODE IS ANF10, ONLINE, AND KNOWN
	JRST	.POPJ1##		;AND RETURN

NODI.2:	MOVE	T1,P1			;GET ARGUMENT
	PUSHJ	P,DNODE			;CONVERT
	  POPJ	P,			;NO SUCH NODE
	MOVE	T2,P1			;GET ARGUMENT BACK
	TLNE	T2,-1			;WAS IT A NAME?
	EXCH	T1,T2			;YES, RETURN DATA IN THE RIGHT ACS
	PUSH	P,T1			;SAVE NAME
	PUSH	P,T2			;SAVE NUMBER
	MOVE	T1,T2			;GET NUMBER
	ADD	T1,RTRNRV		;OFFSET INTO THE ROUTER VECTOR
	PUSHJ	P,XWORD			;GET THE ENTRY
	MOVE	T3,[NT.KNO+.NTDCN]	;NODE IS DECNET AND KNOWN
	TDNE	T1,RNRCH##		;IS IT ONLINE?
	TXO	T3,NT.ONL		;YES
	POP	P,T2			;RESTORE NUMBER
	POP	P,T1			;RESTORE NAME
	JRST	.POPJ1##		;AND RETURN
	SUBTTL	Network routines -- NRTINF - Return NRTSER information


; Return DECnet node name, node number and channel for a NRTSER line
; Call:	MOVE	T1, address
;	MOVE	T2, line
;	PUSHJ	P,NRTINF
;
NRTINF::SETZM	.NRTFL(T1)		;CLEAR NODE NAME
	SETZM	.NRTNM(T1)		;CLEAR NODE NAME
	SETZM	.NRTNN(T1)		;CLEAR NODE NUMBER
	SETZM	.NRTCH(T1)		;CLEAR CHANNEL NUMBER
	TLNE	F,(FL.SPY)		;CAN WE SPY?
	TLNN	F,(FL.DECNET)		;AND DO WE HAVE DECNET?
	POPJ	P,			;NO
	PUSHJ	P,.SAVE1##		;SAVE P1
	MOVE	P1,T1			;COPY ADDRESS OF STORAGE
	MOVE	T1,T2			;GET LINE NUMBER
	ADD	T1,LINTAB		;GET LINTAB OFFSET
	PUSHJ	P,MWORD			;GET ADDRESS OF LDB
	MOVE	T2,T1			;SAVE LDB ADDRESS
	ADD	T1,LDBTTW##		;OFFSET TO TERMINAL TYPE WORD
	PUSHJ	P,MWORD			;GET IT
	TSNN	T1,LDLNRT##		;A NRTSER LINE?
	POPJ	P,			;NO
	SETOM	.NRTFL(P1)		;SET NRT FLAG
	MOVE	T1,T2			;GET LDB ADDRESS
	ADD	T1,LDBNRT##		;OFFSET TO NRTSER WORD
	PUSHJ	P,MWORD			;GET NRB ADDRESS
	ADD	T1,NR.CHN##		;OFFSET TO DECNET CHANNEL WORD
	PUSHJ	P,XWORD			;GET IT
	LDB	T1,[POINT 12,T1,17]	;NOW GET CHANNEL NUMBER
	MOVEM	T1,.NRTCH(P1)		;SAVE IT
	SOS	T2,T1			;SAVE IT (ZERO ISN'T USED)
	MOVE	T1,NRTSJP		;GET NRTSER'S SJB ADDRESS
	ADD	T1,$SJCHT##		;OFFSET TO CHANNEL TABLE ADDRESS
	PUSHJ	P,XWORD			;GET TABLE
	ADD	T1,T2			;INDEX BY CHANNEL NUMBER
	PUSHJ	P,XWORD			;NOW GET ADDRESS OF SLB
	ADD	T1,$SLDNA##		;OFFSET TO DESTINATION NODE ADDRESS
	PUSHJ	P,XWORD			;GET WORD CONTAINING NODE NUMBER
	HLRZS	T1			;PUT IN RH
	MOVEM	T1,.NRTNN(P1)		;SAVE NODE NUMBER
	ADD	T1,SCTNDT		;POINT TO NODE NAMES
	PUSHJ	P,XWORD			;GET IT
	MOVEM	T1,.NRTNM(P1)		;SAVE NODE NAME
	JRST	.POPJ1##		;RETURN
	SUBTTL	Structure routines -- STRINI/STRCHK - Initialize structure UUOs


STRINI:	SETZM	STRFLG			;FORCE STR DB INITIALIZATION
STRCHK:	SKIPE	STRFLG			;NEED TO INITIALIZE?
	POPJ	P,			;NOPE
	PUSHJ	P,.SAVE3##		;SAVE SOME ACS
	PUSH	P,T1			;SAVE FROM DESTRUCTION
	SETZM	STR.ZB			;CLEAR
	MOVE	T1,[STR.ZB,,STR.ZB+1]	; OUR STR
	BLT	T1,STR.ZE		;  DATA BASE
IFN FTUUO,<
	TLNE	F,(FL.SPY)		;SPYING?
	JRST	STRI.3			;YES--DO IT THE QUICK WAY
> ;END OF IFN FTUUO
	MOVNI	T1,1			;INIT UUO ARGUMENT

STRI.1:	SYSSTR	T1,			;GET NEXT STR IN SYSTEM
	  SETZ	T1,			;ASSUME NO MORE STRS
	JUMPE	T1,STRI.2		;DONE?
	CAMGE	P1,.FSMAX##		;HAVE ALL STRS YET?
	AOJA	P1,STRI.1		;NO--LOOP

STRI.2:	POP	P,T1			;RESTORE T1
	AOS	STRFLG			;REMEMBER WE'RE INITIALIZED
	POPJ	P,			;AND RETURN

IFN FTUUO,<
STRI.3:
; Crock to get around the lack of a GETTAB to return the
; SYS and job S/L byte pointers.
	MOVE	T1,[.GTEDN,,.GTSLF]	;ARGS TO GET THE BASE
	PUSHJ	P,GTAB			; ADDRESS OF SDVTBL
	TLZ	T1,777			;NO JUNK
	LSHC	T1,-32			;GET LENGTH*2
	LSH	T2,-12			;RIGHT JUSTIFY THE TABLE ADDRESS
	ADDI	T1,15(T2)		;POINT TO SYSSRC
	MOVEM	T1,$SYSRC		;SAVE IT
	ADDI	T1,1			;POINT TO JOBSRC
	MOVEM	T1,$JBSRC		;SAVE IT
	MOVE	T1,[.GTRCT,,.GTSLF]	;ARGS TO GET THE BASE
	PUSHJ	P,GTAB			; ADDRESS OF JBTRCT
	SUB	T1,JOBMAX		;  WHICH JUST HAPPENS
	MOVEI	T1,-1(T1)		;   HAPPENS TO
	MOVEM	T1,$JBSFD		;    FOLLOW JBTSFD

	MOVE	T1,[%LDSTR]		;THE ONE AND ONLY STR GETTAB
	PUSHJ	P,GTAB			;GET IT
	HLRZM	T1,STRFIR		;SAVE FIRST STR ADDRESS
	HRRZM	T1,STRNXT		;SAVE OFFSET TO ADDRESS OF NEXT STR
	MOVE	T1,STRFIR		;GET ADDR OF FIRST STR

STRI.4:	MOVE	P1,T1			;SAVE STR ADDRESS
	ADD	T1,STRNAM##		;OFFSET TO NAME
	PUSHJ	P,MWORD			;GET IT
	MOVE	P2,T1			;SAVE STR NAME
	MOVE	T1,P1			;GET STR ADDRESS BACK
	ADD	T1,STRNXT		;OFFSET TO THE NEXT ONE
	PUSHJ	P,MWORD			;GET IT
	HRRZ	P3,T1			;GET THIS FS NUMBER
	MOVEM	P1,TABSTR(P3)		;SAVE STR ADDRESS
	MOVEM	P2,STRTAB(P3)		;SAVE STR NAME
	HLRZS	T1			;GET NEXT STR ADDRESS
	JUMPN	T1,STRI.4		;LOOP
	JRST	STRI.2			;ALMOST DONE

> ;END IFN FTUUO
	SUBTTL	Structure routines -- STRFSN - Convert name to number


; Convert a file structure number to a name
; Call:	MOVE	T1, fs-number
;	PUSHJ	P,STRFSN
;	  ERROR				;NO SUCH STR
;	SKIP				;T1 = SIXBIT NAME
;
STRFSN::PUSHJ	P,STRCHK		;MAKE SURE STR DB IS SET UP
	CAMLE	T1,.FSMAX##		;RANGE CHECK IT
	POPJ	P,			;LOSER
	MOVE	T1,STRTAB(T1)		;GET STR NAME
	JRST	.POPJ1			;AND RETURN
	SUBTTL	Structure routines -- STRNFS - Convert number to name


; Convert a STR name to a file structure number
; Call:	MOVE	T1, sixbit-STR-name
;	PUSHJ	P,STRNFS
;	  ERROR				;NO SUCH STR
;	SKIP				;T1 = FILE STRUCTURE NUMBER
;
STRNFS::PUSHJ	P,STRCHK		;MAKE SURE STR DB IS SET UP
	MOVN	T2,.FSMAX##		;GET -NUMBER OF STRS
	HRLZS	T2			;PUT IN LH
	CAME	T1,STRTAB(T2)		;A MATCH?
	AOBJN	T2,.-1			;KEEP LOOKING
	JUMPGE	T2,.POPJ##		;RETURN IF POINTER RAN OUT
	HRRZ	T1,T2			;GET FS NUMBER
	ADD	T1,.FSMIN##		;MAKE IT AGREE WITH THE MONITOR
	JRST	.POPJ1##		;RETURN
	SUBTTL	Structure routines -- STRMNC - Return mount count


; Routine to return the mount count for any structure.
; Call:	MOVE	T1, structure-name
;	PUSHJ	P,STRMNC
;
; On return, the following ACs are set up:
;	T1/	 flags,,count
;	T2/	act-S/L,,pas-S/L
;
STRMNC::PUSHJ	P,.SAVE3##		;SAVE SOME ACS
	MOVE	P1,T1			;SAVE STR NAME
	SETZB	P2,P3			;CLEAR PASSIVE,,ACTIVE S/L COUNTERS
	PUSHJ	P,STRCHK		;MAKE SURE THE STR DB IS SETUP
	PUSH	P,O			;SAVE OBJECT
	SETZB	O,GOBBLK+.DFGJN		;START WITH JOB 0 FOR SSL
	SETZM	GOBBLK+.DFGPP		;INIT PPN WORD TOO
	SETOM	GOBBLK+.DFGNM		;FOR THE FIRST STR
	JRST	STRM.2			;ENTER LOOP

STRM.1:	MOVEI	T1,.GTSTS		;JOB STATUS WORD TABLE
	HRL	T1,O			;INCLUDE JOB NUMBER
	PUSHJ	P,GTAB			;GET STATUS
	TXNN	T1,JS.JNA		;JOB ASSIGNED?
	JRST	STRM.5			;LOOK NO FURTHER
	MOVEM	O,GOBBLK+.DFGJN		;SAVE JOB NUMBER
	MOVEI	T1,.GTPPN		;PPN WORD TABLE
	HRL	T1,O			;INCLUDE JOB NUBER
	PUSHJ	P,GTAB			;GET PPN
	MOVEM	T1,GOBBLK+.DFGPP	;SAVE IT
	SETOM	GOBBLK+.DFGNM		;FOR THE FIRST STR

STRM.2:	MOVE	T1,[5,,GOBBLK]		;SET UP CALL
	PUSHJ	P,UGOBSTR		;READ S/L
	  JRST	STRM.4			;JOB MUST HAVE LOGGED OUT
	SKIPE	T1,GOBBLK+.DFGNM	;GET RETURNED STR NAME
	JRST	STRM.3			;ONWARD
	MOVSS	P2			;MAKE P2 ACTIVE,,PASSIVE
	TRO	P3,777777		;FLAG DOING THE PASSIVE S/L NOW

STRM.3:	CAMN	T1,[EXP -1]		;END OF S/L?
	JRST	STRM.4			;YES
	CAME	T1,P1			;STR MATCH?
	JRST	STRM.2			;TRY ANOTHER STR
	AOS	P2			;COUNT IT
	SKIPN	O			;JOB ZERO (SYSTEM SEARCH LIST)?
	TXO	P3,MC.SYS		;YES

STRM.4:	TRZE	P3,777777		;PROCESSING THE ACTIVE S/L?
	MOVSS	P2			;NO--RESET PASSIVE,,ACTIVE

STRM.5:	CAMGE	O,JOBMAX		;CHECKED ALL JOBS?
	AOJA	O,STRM.1		;NO--LOOP

IFN FTUUO,<
	MOVEI	T4,0			;INIT INDEX INTO SWPTAB

STRM.6:	MOVE	T1,T4			;GET SWAPPING UNIT NUMBER
	ADD	T1,SWPTAB		;INDEX INTO SWPTAB
	PUSHJ	P,MWORD			;GET UDB ADDRESS
	JUMPE	T1,STRM.7		;EMPTY
	ADD	T1,UNISTR##		;GET STR POINTER
	PUSHJ	P,MWORD			;GET STR ADDRESS
	ADD	T1,STRNAM##		;OFFSET TO STR NAME
	PUSHJ	P,MWORD			;GET THE NAME
	CAMN	T1,P1			;TARGET STRUCTURE?
	JRST	STRM.8			;YES!

STRM.7:	CAMGE	T4,SWPMAX		;CHECKED ALL SWAPPING UNITS?
	AOJA	T4,STRM.6		;NO
	TXZA	P3,MC.ASL		;NOT IN ASL

STRM.8:	TXO	P3,MC.ASL		;FLAG UNIT IN THE SWAPPING LIST
> ;END IFN FTUUO

STRM.9:	HLRZ	T1,P2			;GET COUNT IN PASSIVE S/L
	ADDI	T1,(P2)			;PLUS ACTIVE S/L COUNT
	TXNE	P3,MC.SYS		;IN THE SYSTEM SEARCH LIST
	SOS	P2			;YES--ADJUST ACTIVE COUNT
	MOVE	T2,P2			;GET SEPARATE COUNTS TOO
	IOR	T1,P3			;INCLUDE SSL, ASL, SDL BITS
	POP	P,O			;RESTORE OBJECT
	POPJ	P,			;RETURN
	SUBTTL	Miscellaneous routines -- SIXOCT - Sixbit to octal conversion


; Convert sixbit to octal
; Call:	MOVE	T1, sixbit word
;	PUSHJ	P,SIXOCT
;	  <NON-SKIP>			;WORD CONTAINS NON-NUMBERIC CHARACTERS
;	<SKIP>				;T1:= OCTAL NUMBER
;
SIXOCT::TDNN	T1,[505050,,505050]	;ONLY OCTAL CHARCTERS?
	POPJ	P,			;NO
	MOVEI	T4,6			;THREE DIGITS

SIXOC1:	LSHC	T1,-6			;SHIFT DIGIT INTO T2
	LSH	T2,-36			;RIGHT JUSTIFY IT
	SUBI	T2,'0'			;CONVERT
	LSHC	T2,-3			;SHIFT CHARACTER INTO T3
	SOJG	T4,SIXOC1		;LOOP
	HRRZ	T1,T3			;GET RESULT
	JRST	.POPJ1##		;RETURN
	SUBTTL	Miscellaneous routines -- OCTSIX - Octal to sixbit conversion


; Convert octal to sixbit
; Call:	MOVE	T1, octal word
;	PUSHJ	P,OCTSIX
;	  <NON-SKIP>			;T1 GREATER THAN 18 BITS
;	<SKIP>				;T1:= SIXBIT WORD
;
OCTSIX::TLNE	T1,777777		;TOO BIG?
	POPJ	P,			;YES
	MOVEI	T4,6			;NUMBER OF DIGITS

OCTSI1:	LSHC	T1,-3			;SHIFT DIGIT INTO T2
	LSH	T2,-41			;RIGHT JUSTIFY IT
	ADDI	T2,'0'			;MAKE SIXBIT
	LSHC	T2,-6			;SHIFT CHARACTER INTO T3
	SOJG	T4,OCTSI1		;LOOP
	MOVE	T1,T3			;GET RESULT
	JRST	.POPJ1##		;RETURN
	SUBTTL	Storage -- SPY and version


	$LOW

MONVER:: BLOCK	1	;MONITOR VERSION
SKEWFL:  BLOCK	1	;WHO/MONITOR VERSION SKEW FLAG

IFN FTUUO!FTDDB,<

PG.MAP==1B0		;PAGE IS MAPPED AND VALID
PG.ALC==1B1		;PAGE HAS BEEN CREATED

PAGTAB:  BLOCK	1000	;TABLE OF MAPPED PAGES

>;END IFN FTUUO!FTDDB
	SUBTTL	Storage -- DDB


; DDB data base
IFN FTDDB,<
DDBCNT:  BLOCK	1	;COUNT OF DDBS
DDBIOS:  BLOCK	1	;DEVIOS
DDBSPL:  BLOCK	1	;DEVSPL
DDBMOD:  BLOCK	1	;DEVMOD
DDBACC:  BLOCK	1	;DEVACC
TBSTS:   BLOCK	1	;TUBSTS
>;END IFN FTDDB
	SUBTTL	Storage -- DECnet


; DECnet data base
DCNPTR:  BLOCK	1	;BYTE POINTER TO DECNET ROUTER CIRCUIT TEXT BLOCK
DCNCNT:  BLOCK	1	;BYTE COUNT TO ROUTER CIRCUIT TEXT BLOCK
DCNCKT:  BLOCK	4	;DECNET ROUTER CIRCUIT TEXT BLOCK
DCNNRT:	BLOCK	.NRTLN	;SCRATCH NRTINF BLOCK
	SUBTTL	Storage -- LOGIN queue


; LOGIN queue data base
IFN FTLGNQ,<
LGQCNT:: BLOCK	1	;NUMBER OF ENTRIES IN THE QUEUE
LGQPTL:: BLOCK	1	;NUMBER OF LINES WITH PERMISSION TO LOGIN
> ;END IFN FTLGNQ
	SUBTTL	Storage -- Segment


; Segment data base
SEG.ZB:!		;FIRST WORD TO CLEAR

LOWDAT:  BLOCK	10	;LOW SEG FILESPEC
LOWVER:  BLOCK	1	;LOW SEG VERSION
LOWCST:  BLOCK	1	;LOW SEG CUSTOMER WORD
HIGDAT:  BLOCK	10	;HIGH SEG FILESPEC
HIGVER:  BLOCK	1	;HIGH SEG VERSION

SEG.ZE:!		;LAST WORD TO CLEAR
	SUBTTL	Storage -- Structure


; Structure data base
STR.ZB:!		;FIRST WORD TO CLEAR

STRFLG:  BLOCK	1	;NON-ZERO IF OUR STR DB NEEDS INITIALIZING
STRTAB:  BLOCK	^D36+1	;SIXBIT NAMES OF STRS
STRADR:  BLOCK	1	;ADDRESS OF LAST STR RETURNED BY USYSSTR

IFN FTUUO,<
STRFIR:  BLOCK	1	;ADDRESS OF FIRST STR IN MONITOR
STRNXT:  BLOCK	1	;OFFSET TO NEXT STR
TABSTR:  BLOCK	^D36+1	;ADDRESSES OF STRS IN THE MONITOR

$SYSRC:  BLOCK	1	;BYTE POINTER TO SYSTEM S/L
$JBSRC:  BLOCK	1	;BYTE POINTER TO JOB S/L
$JBSFD:  BLOCK	1	;ADDRESS OF JBTSFD

> ;END IFN FTUUO

STR.ZE:!		;LAST WORD TO CLEAR
	SUBTTL	Storage -- Unit and swapper


; Unit and swapper data base
UNI.ZB:!		;FIRST WORD TO CLEAR

SWPMAX:  BLOCK	1	;MAX SWAP UNIT NUMBER

UNI.ZE:!		;LAST WORD TO CLEAR
	SUBTTL	Storage -- UUO argument blocks


GOBBLK:  BLOCK	5	;GOBSTR UUO
JPKBLK:  BLOCK	3	;JOBPEK UUO
NODBLK:  BLOCK	2	;NODE. UUO
PTHBLK:  BLOCK	.PTMAX	;PATH. UUO
DNUBLK:  BLOCK	.DNSLN	;DNET. UUO
	SUBTTL	End


	END