Google
 

Trailing-Edge - PDP-10 Archives - bb-h240e-bm_decnet-20_v4_0_dist - tools/dcnspy.mac
There are 11 other files named dcnspy.mac in the archive. Click here to see a list.
; UPD ID= 145, SNARK:<6.1.UTILITIES>DCNSPY.MAC.39,  19-Jun-85 17:35:02 by NICHOLS
;Fix typeout of DECnet state from CTERM's CDB in CHSTS
; UPD ID= 131, SNARK:<6.1.UTILITIES>DCNSPY.MAC.38,   5-Jun-85 13:24:21 by PALMIERI
;Update BEGSTR LT
; UPD ID= 103, SNARK:<6.1.UTILITIES>DCNSPY.MAC.37,  22-Mar-85 15:45:59 by PALMIERI
;Remove FTPARANOID in EL and MB ENTRY. macros
; UPD ID= 102, SNARK:<6.1.UTILITIES>DCNSPY.MAC.36,  21-Mar-85 16:14:54 by PALMIERI
;Update LAT BEGSTRs,  fix TYPPRT to understand new port database
; UPD ID= 86, SNARK:<6.1.UTILITIES>DCNSPY.MAC.34,  22-Feb-85 16:09:05 by MCCOLLUM
;ADD DEFINITIONS TO HN BEGSTR
; More work on PSB and PTB displays. Add INDEX command
; UPD ID= 81, SNARK:<6.1.UTILITIES>DCNSPY.MAC.32,  18-Feb-85 21:51:17 by MCCOLLUM
; Add PSB and PTB displays
; UPD ID= 80, SNARK:<6.1.UTILITIES>DCNSPY.MAC.31,  18-Feb-85 16:04:54 by MCCOLLUM
;Fix up some TDB bugs. Reset LINGOL when toggling SCNCOM.
; UPD ID= 77, SNARK:<6.1.UTILITIES>DCNSPY.MAC.30,  13-Feb-85 14:28:44 by MCCOLLUM
;Add TDB and SLT commands and displays
; UPD ID= 75, SNARK:<6.1.UTILITIES>DCNSPY.MAC.29,   8-Feb-85 15:10:52 by NICHOLS
;Add help for HN and CBL displays
; UPD ID= 74, SNARK:<6.1.UTILITIES>DCNSPY.MAC.28,   8-Feb-85 15:00:16 by NICHOLS
;Add LAT displays HN and CBL
; UPD ID= 66, SNARK:<6.1.UTILITIES>DCNSPY.MAC.27,  12-Jan-85 00:07:43 by NICHOLS
;Break up DCNSPY with PRGENDs so that each subprogram can search a
;different universal file, so we can build tables with conflicting symbol
;names.  Fix the symbol name conflict over LS.ON and LS.OFF between Line
;State and LAT State.
; UPD ID= 59, SNARK:<6.1.UTILITIES>DCNSPY.MAC.26,  17-Dec-84 14:47:06 by PALMIERI
;Have GTCHTR use XPEEKX instead of the NODE% JSYS; update PT begstr
; UPD ID= 43, SNARK:<6.1.UTILITIES>DCNSPY.MAC.25,  13-Nov-84 14:29:16 by PALMIERI
;Add DNADLL line table display
;Make common state table output routine
;Fix memory display for ASGRES stuff
; UPD ID= 32, SLICE:<6.1.UTILITIES>DCNSPY.MAC.25,  26-Sep-84 14:56:28 by NICHOLS
;Fix up names of SLDOB and SLSOB
; UPD ID= 23, SNARK:<6.1.UTILITIES>DCNSPY.MAC.23,   2-Aug-84 16:04:21 by PALMIERI
;Change CTERM state code display to agree with CTHSRV
; UPD ID= 20, SNARK:<6.1.UTILITIES>DCNSPY.MAC.22,  18-Jul-84 12:28:42 by MCINTEE
;More of previous
; UPD ID= 19, SNARK:<6.1.UTILITIES>DCNSPY.MAC.21,  18-Jul-84 12:24:28 by MCINTEE
;CHOUT no longer exists
; UPD ID= 16, SNARK:<6.1.UTILITIES>DCNSPY.MAC.20,   3-Jul-84 12:28:16 by MCINTEE
;Fix CDB
; UPD ID= 15, SNARK:<6.1.UTILITIES>DCNSPY.MAC.18,   3-Jul-84 11:51:19 by GLINDELL
;Fix PB,SL,EL
; UPD ID= 14, SNARK:<6.1.UTILITIES>DCNSPY.MAC.17,  27-Jun-84 17:33:21 by PALMIERI
;Add ESCDA and ESCWS.
;Add display of data link block to circuit block display
;Update display for circuit block
; UPD ID= 12, SNARK:<6.1.UTILITIES>DCNSPY.MAC.15,   8-Jun-84 14:19:33 by GLINDELL
;Add ELCIM
; UPD ID= 11, SNARK:<6.1.UTILITIES>DCNSPY.MAC.14,  31-May-84 15:27:07 by PALMIERI
;Remove AJLRM from adjacency block
; UPD ID= 10, SNARK:<6.1.UTILITIES>DCNSPY.MAC.13,  25-May-84 16:27:44 by PALMIERI
;Add adjacency state "off-line"
; UPD ID= 9, SNARK:<6.1.UTILITIES>DCNSPY.MAC.12,  15-May-84 12:22:20 by PALMIERI
;Add new circuit block state - FAILED
; UPD ID= 8, SNARK:<6.1.UTILITIES>DCNSPY.MAC.11,  25-Apr-84 16:00:48 by PALMIERI
;Update Adjacency block
;WORK:<PALMIERI.NI>DCNSPY.MAC.3 24-Apr-84 14:09:21, Edit by PALMIERI
;More CI stuff that only Gunnar understands
;SNARK:<6.1.UTILITIES>DCNSPY.MAC.9 17-Apr-84 11:32:13, Edit by GLINDELL
;Remove CBBMAC and PBBMAC since they are no longer in D36PAR
;WORK:<GLINDELL.MONITOR>DCNSPY.MAC.5  9-Apr-84 11:37:30, Edit by GLINDELL
;Add new DECnet/CI port connection states.
;WORK:<GLINDELL.MONITOR>DCNSPY.MAC.23  4-Apr-84 14:36:59, Edit by GLINDELL
;Add CI command to display DECnet/CI tables.
;Include drop # for CI in CIRCUIT command and typeout of circuit ID
;SNARK:<6.1.UTILITIES>DCNSPY.MAC.5  2-Apr-84 21:41:52, Edit by NICHOLS
;Change name of CI device from CIP to CI
;WORK:<PALMIERI.NI>DCNSPY.MAC.73 26-Mar-84 13:16:19, Edit by PALMIERI
;Add Data Link Block typeout
;Add previous/next capability to circuits/adjacencies
;Add DPY A command to display adjacencies associated with circuits
;Add MRQ to type out memory request table
;Make AJB invokable and neaten up its display
;SNARK:<6.1.UTILITIES>DCNSPY.MAC.4 19-Jan-84 14:39:25, Edit by NICHOLS
;Add AJB display
;WORK:<NICHOLS>DCNSPY.MAC.2 13-Jan-84 13:48:29, Edit by NICHOLS
;Add MB display
; UPD ID= 265, SNARK:<6.1.MONITOR>DCNSPY.MAC.8,   2-Dec-83 22:38:53 by NICHOLS
;Add PORT command to type out SJB's port table block for a channel.
;Add E command to exit from DPY mode.
	UNIVERSAL DCNSPY - Spy on DECnet-36

	SEARCH MONSYM,MACSYM
	SEARCH SCNMAC,DPYDEF
	SEARCH D36PAR,SCPAR,CTERMD

	.REQUIRE SYS:MACREL
	.REQUEST REL:SCAN
	.REQUEST REL:HELPER
	.REQUEST REL:DPY	;GET THE DPY PACKAGE

	.TEXT	"/LOCALS/SYMSEG:HIGH"

;DEFINE NODE,<CAIA>		;disables NODE JSYS, for debug

DEFINE RETSKP,<JRST CPOPJ1>	;OVERRIDE UNIVERSAL'S DEFN

	XALL

	PRGID='DCNSPY'		;NAME OF THIS PROGRAM
	PRGABR='SPY'		;3 CHR ABBREVIATION USED FOR PROG.

	SPYWHO==0
	SPYVER==3		;MAJOR VERSION
	SPYMIN==0		;MINOR VERSION
	SPYEDT==4		;EDIT NUMBER
	SUBTTL Help for Hackers

COMMENT |
               ADDING A NEW TABLE AND COMMANDS TO DCNSPY


DEFINING THE TABLE MACRO

   The BEGSTR MACRO which defines your table must be copied into DCNSPY
and  changed  to  the right format. It ends up as a macro named XXXMAC,
where XXX is the table name. The BEGSTR entries must  be  changed;  for
example the BEGSTR entry

	WORD NXT		;NEXT JOB BLOCK IN SYSTEM

would become

	ENTRY. SJ,NXT,,.TXWDW,0,<NEXT JOB BLOCK IN SYSTEM>

o SJ is the name of the BEGSTR.

o NXT the name of the data item.

o The  omitted  third item is in case this table is an offset within an
  outer table. See SLBMAC and ELBMAC.

o .TXWDW is the name of the  routine  to  output  the  value.  Standard
  routines are:

    .TXWDW	XWD octal
    .TDECD	Decimal, followed by "."
    .TOCTW	Octal word
    .TSTCF	CTERM state
    .TCHRS	ASCII word (not a pointer), up to 5 characters
    .TCHR8	8-bit ASCII word (not a pointer), up to 4 characters

  You  can  write others if you want. They are called with the value in
  T1.

o The  0  gives  the  number  of  CRLF's to output after this item when
  DCNSPY is displaying in NOCOMMENT mode. If it's 0 DCNSPY will  output
  4 items per line; set it non-zero to double space or to force an item
  to  be  at  the  beginning  of a line.

o The  comment  is  the  text  which is output in COMMENT mode. This is
  usually just the comment from the BEGSTR macro.

There are SED and EMACS macros to help in changing a BEGSTR macro into one of
these things.


After defining the macro, add the entry

	DOBLK XXX

after the other DOBLK's, where XXX is the XXX in XXXMAC.


SWITCHES:

In  SWTCHS,  Define  a  new  action  command,  and  perhaps  some setup
commands, to implement your new command. Also add some documentation to
the help text at HLPSTR.

Generally an action command just looks like:

	SP	*SJB,0,SPYSJB

o The  asterisk  is a SCAN artifact which I won't explain here. Include
  it on the action commands.

o SJB is the command name

o SPYSJB  is  the  routine which handles the command (described further
  below).

A setup command might look like:

	SP	JOB,SCNJOB,.SWDEC,JOB,FS.NFS!FS.NCM!FS.VRQ

o JOB is the command

o SCNJOB is a variable which gets set to 1 if

o JOB is typed, 0 if NOJOB is typed (-1 if not invoked),

o .SWDEC is the routine which reads the argument (decimal in this case)

o JOB  is  the  list of defaults and ranges to use (defined by the DM's
  just above SWTCHS),

o Then some optional flags:

	NFS	Not a file switch
	NCM	Not a command
	VRQ	Value required (no default)
	LRG	Argument can be larger than 18 bits

ROUTINES:

SPYXXX  is given in the command entry in SWTCHS. It's the routine which
SCAN dispatches to when that command is typed. It is simply:

SPYXXX:	MOVEI T1,TYPXXX		;TYPE OUT THE XXX TABLE
	CALLRET SPYGO

where that's the same old XXX - some name representing your table.

TYPXXX  needs  to  read  in  the  table, output up the header, and call
TYPBLK to output the body of the  table  using  the  XXXMAC  macro.  It
should  first  call  SETXXX  to read the table. Then output the header.
Useful header routines are:

	TYPJOB	Type the job number or special name
	TYPCHL	Output the channel number and skip a line
	TYPTTN	Output the tty number
	TYPTAD	Output the address of the table being output

You can also add your own routines. Finish up with the following:

	MOVE T1,XXXPTR
	CALL TYPBLK
	RETSKP

XXXPTR  is set up along with XXXMAC. TYPBLK outputs the table according
to XXXMAC. The skip  return  indicates  success.  There  are  no  error
returns  now;  the  skip  return  is  just  there  to  waste  time  and
instructions.

(Note:  if  an error occurs while DPYing the table - mainly a NODE JSYS
error - DCNSPY will continue to loop,  continuing  to  get  the  error,
until  the  user types ESC to get back to command level. This is so the
user can see a table which the monitor is setting it up - DCNSPY  would
get  errors  until  the  table were created, and then it would start to
display the table.)

SETXXX:  calls  the  NODE JSYS to read the table. If NODE doesn't know
how to read your table you will have to educate it. It's  the  routine
NDRDB  in  JNTMAN.MAC.  To  call  NODE,  set  up  the  table  name  in
NODARG+.NDBST   and  the  arguments,  if  any,  in  NODARG+.NDBSJ  and
NODARG+.NDBSC. Then do:

	MOVEI T2,NODARG
	NODE
	 ERJMP NODERR		;FAILED - FATAL ERROR

If  NODE  succeeds  the  table is now at NODBLK and the address of the
table is at NODADR.

That's all there is to it.
|
	SUBTTL External Definitions

	EXTERN .JB41		;LUUO TRAP ADDRESS (FOR DPY)
	EXTERN DPYUUO		;DPY'S ENTRY POINT

	EXTERN .ISCAN		;INITIALIZE THE WHOLE SCAN ROUTINE
	EXTERN .OSCAN		;READ SWITCH.INI
	EXTERN .PSCAN		;PARTIAL SCAN INITIALIZER
	EXTERN .VSCAN		;VERB SCANNER

	EXTERN .TSPAC		;TYPE A SPACE
	EXTERN .TTABC		;TYPE A TAB CHARACTER
	EXTERN .TCOMA		;TYPE OUT A COMMA
	EXTERN .TCRLF		;TYPE A CRLF
	EXTERN .TSTRG		;TYPE A STRING FROM T1
	EXTERN .TOCTW		;TYPE NUMBER IN T1 IN OCTAL
	EXTERN .TDECW		;TYPE NUMBER IN T1 IN DECIMAL
	EXTERN .TSIXN		;TYPE VALUE IN T1 IN SIXBIT
	EXTERN .TCOLN		;TYPE A COLON
	EXTERN .TRBRK		;TYPE A RIGHT BRACKET
	EXTERN .TPPNW		;TYPE T1 AS A PPN
	EXTERN .TXWDW		;TYPE T1 AS HALF-WORDS
	EXTERN .TCHAR		;TYPE CHARACTER IN T1
	EXTERN .TTIME		;TYPE T1 AS A MILLISECOND TIME
	EXTERN .TTIMN		;TYPE OUT THE CURRENT TIME

	EXTERN .OCTNW		;READ THE CONTROLLER, AND OTHER, NUMBERS
	EXTERN .DECNW		;READ IN A DECIMAL NUMBER
	EXTERN .SWDEC		;READ IN A DECIMAL SWITCH ARG
	EXTERN .SWOCT		;READ IN AN OCTAL SWITCH ARG
	EXTERN .SIXSW		;READ IN A SWITCH NAME IN SIXBIT
	EXTERN .TICHR		;Read a single character
	SUBTTL Build the SCAN switch tables

; See SCNMAC.MAC for definition of macros used here.

;Define the defaults for switches:
;	First arg is 3-chr abbreviation used for this switch.
;	Second arg is maximum allowed value.
;	Third arg is absent default (AD.xxx)
;		(not used by SCAN, for application use only).
;	Fourth arg is present default (PD.xxx)
;		(used by SCAN unless FS.VRQ specified)

DEFINE DM(name,max,abs,pres),<
	MX.'name==max
	AD.'name==abs
	PD.'name==pres
>
	RADIX	10

;	Name	Max	Absent	Present
;	xxx	MX.xxx	AD.xxx	PD.xxx
;	----	------	------	-------

DM	DPY,	1,	1,	1	;/DPY
DM	COM,	1,	0,	1	;/COM
DM	JOB,	1024,	0,	0	;/JOB, /TTY
DM	CHN,	1024,	1,	1	;/CHANNEL
DM	DLY,	1024,	2,	2	;/DELAY (SECONDS)
DM	PAG,	512,	10,	15	;/PAGE
DM	SJP,	0,	0,	0	;/TABLE
DM	TLN,	128,	0,	0	;/LENGTH
DM	IDX,	128,	0,	0	;/INDEX

	RADIX	8

;Remember to update HELP string at HLPSTR

DEFINE	SWTCHS,<
	XLIST

;SET-UP SWITCHES - SET ARGUMENTS FOR ACTION SWITCHES

SP	*JOB,SCNJOB,.SWDEC,JOB,FS.NFS!FS.NCM!FS.VRQ
SP	*CHANNEL,SCNCHN,.SWDEC,CHN,FS.NFS!FS.NCM!FS.VRQ
SP	ADDRESS,SCNTAD,.SWOCT,SJP,FS.NFS!FS.NCM!FS.VRQ!FS.LRG
SP	*LENGTH,SCNTLN,.SWDEC,TLN,FS.NFS!FS.NCM!FS.VRQ
SP	TTY,SCNTTY,.SWOCT,JOB,FS.NFS!FS.NCM!FS.VRQ
SP	NRT,,.SWNRT,,FS.NCM!FS.NFS		;(SETS UP SCNJOB)
SP	CTERM,,.SWCTM,,FS.NCM!FS.NFS		;(SETS UP SCNJOB)
SP	CIRCUIT,,.SWCKT,,FS.NFS!FS.NCM!FS.VRQ
SP	*INDEX,SCNIDX,.SWDEC,IDX,FS.NFS!FS.NCM!FS.VRQ

;ACTION SWITCHES - CAUSE A TABLE TO BE DISPLAYED

SP	*SJB,0,SPYSJB
SP	*SLB,0,SPYSLB
SP	*ELB,0,SPYELB
SP	*RCB,0,SPYRCB
SP	*AJB,0,SPYAJ
SP	*MEM,0,SPYMEM
SP	*MRT,0,SPYMRT
SP	*CDB,0,SPYCDB
SP	*SPY,0,SPYSPY
SP	*PORT,0,SPYPRT
SP	*MB,0,SPYMB
SP	*CI,0,SPYCI
SP	*HN,0,SPYHN
SP	CBL,0,SPYCBL
SP	*SLT,0,SPYSLT
SP	*TDB,0,SPYTDB
SP	*PSB,0,SPYPSB
SP	*PTB,0,SPYPTB
SP	DAYTIME,0,SPYTIM

;COSMETIC SWITCHES - AFFECT THE NATURE OF THE DISPLAY

SP	*EXIT,,SPYXIT,,FS.NCM!FS.NFS
SN	DPY,SCNDPY,FS.NCM!FS.NFS
SP	PAGE,SCNPAG,.SWDEC,PAG,FS.NFS!FS.NCM!FS.VRQ
SN	COMMENT,SCNCOM,FS.NCM!FS.NFS
SP	DELAY,SCNDLY,.SWDEC,DLY,FS.NFS!FS.NCM!FS.VRQ
	LIST
>
;Now build the tables.

	DOSCAN (SWT)
	SUBTTL HLPSTR -- The HELP string

HLPSTR:	ASCIZ ~
DCNSPY uses verb-mode SCAN.  The commands are:

Set-up commands:

  JOB n		Job number to spy on (for SJB, SLB, ELB)
  NRT		Look at NRT's DECnet data (instead of JOB)
  CTERM		Look at CTERM's DECnet data (instead of JOB)
  CHANNEL n	DECnet channel number for that job. Default is 1.
		Channel also controls LAT CBL Circuit number.
  INDEX n	NI PSB or PTB index number. Default is 0.
  CIRCUIT c	Set circuit-id for examining DECnet circuit blocks.
          	(Circuit-ids are of the form DEV-CNT-UNT, (DTE-0-1,CI-0-0.1))
  TTY n		TTY number to spy on (for CTERM's CDB)
  ADDRESS n	Look at the table starting at n, also used for MB msg blk.
  LENGTH l	Set length of the table at ADDRESS n to be l

Action commands:

  AJ		Type out the adjacency Block at the given Address
  CBL		Type out the Circuit Block (LAT) for given Channel = Circuit
  CDB		Type out the CTERM DATA BLOCK for the given TTY
  CI		Type out the CB and PB for DECnet/CI
  DAYTIME	Type out the current time
  ELB		Type out the ELB for the given Job, Channel
  HN		Type out LAT's Host Node Data Block for this system
  MB		Type out the Message Block at the given Address
  MEM		Type out DECnet free pool usage
  MR		Type out the memory request table
  PORT		Type out the Port Table for given Job, Channel
  RCB		Type out Router's RCB for given Circuit-id
  SJB		Type out the SJB for the given Job
  SLB		Type out the SLB for the given Job, Channel
  SLT		Type out the Slot Block for the given TTY
  SPY		Type out the table at the given Address and Length
  TDB		Type out the Terminal Data Block for the given TTY
  PSB		Type out the port storage block for the given index
  PTB		Type out the portal table block for the given index

Cosmetic commands:

  [NO]COMMENT	Type out comments for each field displayed
  [NO]DPY	Use DPY mode
  PAGE		Length by which DPY mode + and - commands shift page
  DELAY		Seconds to sleep in DPY mode

In DPY mode, the Immediate commands are:

  escape	Escape to command mode
  ^Z		Exit to monitor. Type CONTINUE to continue
  ^C		Exit to monitor. Type CONTINUE to continue
  E		Exit to monitor. Type CONTINUE to continue
  C		Toggle the comment/nocomment display mode
  N		Go to Next channel, LAT Circuit, PSB or PTB
  P		Go to Previous channel LAT Circuit, PSB or PTB
  R		Refresh the screen now
  space		Recalculate the screen now
  <CR>		Recalculate the screen now
  +		Move window forward by PAGE lines
  -		Move window backward by PAGE lines

~;END OF ASCIZ STRING
	SUBTTL Accumulator Assignments

	T1=1
	T2=2
	T3=3
	T4=4

	P1=5
	P2=6

	NUM=7			;NUMBER TO PRINT FOR "OUTNUM"
	N=7			;SCAN CALLS IT THIS
	BAS=10			;BASE FOR "OUTNUM" TO PRINT NUMBER IN
	C=10			;AGAIN FOR SCAN
	WDT=11			;WIDTH OF FIELD FOR OUTNUM. ZERO = ANY,
				;  MINUS MEANS LEFT JUSTIFY.
	FIL=12			;CHAR TO USE FOR FILLER.

	DX=13			;ADDRESS OF SCTL JOB BLOCK IN SPY PAGE

	CX=16			;SUPER-TEMP FOR MACROS
	.SAC==CX		;SOME MACROS USE THIS NAME

	P=17

	%CIRMX==6		;Maximum number of circuit addresses we cache
	TYOBSZ==400		;TTY'S OUTPUT BUFFER SIZE

	SUBTTL MACROS

DEFINE ERR(TEXT),<
	JRST	[MOVEI	T1,[ASCIZ |TEXT
|]
		 JRST	ERRSTR]
>


DEFINE MSG(TEXT),<
	JRST	[MOVEI	T1,[ASCIZ |TEXT
|]
		 JRST	.TSTRG]
>
	SUBTTL Expand the Block Description Macros

;The tables set on this page are used by the TYPBLK routine

;Define the offsets into the first-level tables, these offsets
;correspond to the ordering of the ENTRY. calls in the DOBLK macro.

	DO.NAM==0
	DO.PTR==1
	DO.RTN==2
	DO.TXT==3
	DO.STX==4

DEFINE DOBLK1(aa),<
DEFINE ENTRY.(n1,n2,offset,routine,count,ltxt),<EXP <SIXBIT /n1'n2/>>
	Z [aa'MAC](P2)
DEFINE ENTRY.(n1,n2,offset,routine,count,ltxt),<POINTR(n1'.'n2'offset,n1'n2)>
	Z [aa'MAC](P2)
DEFINE ENTRY.(n1,n2,offset,routine,count,ltxt),<EXP routine>
	Z @[aa'MAC](P2)
DEFINE ENTRY.(n1,n2,offset,routine,count,ltxt),<LTXMAC(<ltxt>)>
	Z [aa'MAC](P2)
DEFINE ENTRY.(n1,n2,offset,routine,count,ltxt),<STXMAC(count)>
	Z [aa'MAC](P2)
DEFINE ENTRY.(n1,n2,offset,routine,count,ltxt),<aa'LEN==aa'LEN+1>
	aa'LEN==0
	aa'MAC
>;END OF DEFINE DOBLK1

DEFINE STXMAC(count),<
	EXP count
>

DEFINE LTXMAC(ltxt),<
	[ASCIZ ~ltxt
~]>

DEFINE DOBLK(aa),<
aa'TBL::DOBLK1(aa)
aa'PTR::XWD -aa'LEN,aa'TBL
>
	SUBTTL Storage Definitions

;Data areas to support the NODE JSYS .NDRDB function.
;Note: NODBLK must be longer than the longest block read.

NODARG:	BLOCK	4		;ARGUMENT BLOCK FOR NODE JSYS

NODADR::BLOCK	1		;ADDRESS OF THE TABLE BEING READ
NODBLK::BLOCK	^D128		;(THAT OUGHT TO HOLD THE LITTLE SOB'S)
NODBLE=.-1

NODCHL:	BLOCK	^D32		;CHANNEL TABLE FOR JOB

PEKSTG:	ASCII	/?XPEEK JSYS failed - / ;(21 characters)
NODSTG:	ASCII	/?NODE JSYS failed - / ;(THIS IS 20 CHARACTERS LONG)
NODERM:	BLOCK	20		;PLACE TO HOLD MONITOR'S ERROR MESSAGE

XPKBLK:	BLOCK	.XPLEN		;XPEEK argument block

TTYJFN:	BLOCK	1		;TTY JFN, FOR OUTPUT
SPMSAV:	BLOCK	1		;RFMOD IN EFFECT WHILE DCNSPY IS RUNNING
FMDSAV:	BLOCK	1		;SAVED RFMOD WORD, TO BE RESTORED ON EXIT
INIFLG:	BLOCK	1		;-1 IF INI$ DONE, ELSE ZERO

	SUBTTL General Storage

	LN$PDL==100
PDL:	BLOCK	LN$PDL+1

TTYOBF:	BLOCK	1		;COUNT OF CHARACTERS LEFT IN OUTPUT BUFFER
TTYBPT:	BLOCK	1		;POINTER TO NEXT PLACE TO STORE A CHARACTER
OBF1:	BLOCK	TYOBSZ		;TTY OUTPUT BUFFER
	BLOCK	1		;EXTRA WORD TO MAKE SURE BUFFER ENDS WITH NULL

CCLF1:	BLOCK 1			;NON-ZERO IF CCL STARTED

SPYFCN:	EXP 0			;PUT FUNCTION ADDRESS HERE FOR SPYGO
TYPDPY:	EXP 0			;NON-ZERO TO TYPE IN DPY MODE
COLPOS:	BLOCK 1			;COLUMN POSITION WHILE DPY-ING
BIGOUT:	BLOCK 1			;NON-ZERO TO USE TTY OUTPUT BUFFERS

LINGOL:	EXP 0			;USED BY SPYINT'S + AND - COMMANDS
LINCNT:	EXP 0			; DITTO

NREPMX:	EXP 0
NREQTA:	EXP 0
NREPFR:	EXP 0
XREPMX:	EXP 0
XREQTA:	EXP 0
XREPFR:	EXP 0

CKTID: EXP 0			;PLACE TO STORE CIRCUIT ID
LOPCKT:	EXP 0			; Current circuit block
CHBADR:	EXP 0			; Address of CH blocks
CHBSIZ:	EXP 0			; Length of CH blocks
CHBLKN:	EXP 0			; Number of CH blocks

CIRBUF:	BLOCK RC.LID+1
CIRBLK:	BLOCK %CIRMX		; Table of circuit blocks
CIRIDB: BLOCK %CIRMX		; Table of line IDs
CIRDLA:	BLOCK %CIRMX		; Table of data link block addresses
CIRAJQ:	BLOCK %CIRMX		; Table of adjacency queues
CIRIDX:	BLOCK 1			; Index into above tables

CBADR:	BLOCK 1			;Keeps address of CBBLK (DECnet/CI)
LAHNDB::BLOCK 1                 ;Keeps address of HN block (LAT Host Node)

CHNBAS::BLOCK 1			;ADDRESS OF FIRST PORT STORAGE BLOCK
PORBAS::BLOCK 1			;ADDRESS OF FIRST PORTAL TABLE BLOCK

TTACTL::BLOCK	1		;Holds value of monitor symbol TTACTL

	;SCAN storage

BEGSCN:!			;START OF REGION TO BE SET TO -1
SCNCHN::BLOCK 1			;ZERO-RELATIVE CHANNEL NUMBER WE'RE TO SPY ON
SCNJOB:	BLOCK 1			;JOB NUMBER WE'RE TO SPY ON
SCNDPY:	BLOCK 1			;NON-ZERO TO GO INTO DPY MODE
SCNPAG:	BLOCK 1			;SIZE OF A PAGE, FOR "+" SCROLLING
SCNDLY:	BLOCK 1			;DEFAULT DPY TIMER
SCNCOM:	BLOCK 1			;TYPE OUT COMMENTS IF NON-ZERO
SCNTAD::BLOCK 1			;ADDRESS OF MONITOR TABLE TO LOOK AT
MAPADR: BLOCK 1			;Temporary location for SCNTAD
SCNTLN:	BLOCK 1			;LENGTH OF MONITOR TABLE TO LOOK AT
SCNTTY::BLOCK 1			;TTY NUMBER TO LOOK AT
ENDSCN==.-1			;END OF REGION TO BE SET TO -1

SCNIDX::BLOCK 1			;INDEX FOR PSB,PTB
LENGTH::BLOCK 1			;INTERMEDIATE TABLE LENGTH VALUE
	SUBTTL Necessary BEGSTRs

;This is the CH BEGSTR from D36COM with its name changed to avoid conflicts

BEGSTR XH			;Core handler structure
	WORD BOT		;Pointer to free pool start
	WORD PTR		;pointer to first free block
	WORD AVL		;Number of available blocks
	HWORD LWM		;;; Low water mark
	HWORD REQ		;;; Size requested
;The following 3 fields are expected to be in the last word, see CHBLKS
	FIELD CON,1		;Set if this block type subject to congestion
	FIELD NUM,17		;Total blocks, alloc & unalloc.
	HWORD SIZ		;Size of blocks.
ENDSTR


BEGSTR RE
	WORD BAS		;Starting address of free space
	WORD END		;Address of last word of free space
	WORD TOT		;Total size of free space in blocks
	WORD PR1		;If remaining space less than this,
				; allocate only priority 1
	WORD GRO		;If remaining space less than this, grow free
				;space (larger than REPR1)
	WORD BTB		;Address of start of bit table
	WORD BTL		;Length of bit table (words)
	WORD TFR		;Total remaining unallocated blocks
	WORD FFB		;Number of block just past end of free space
	WORD PMX		;Number of pools
	WORD QTA		;Addr of block containing quota for each pool
	WORD PFR		;Address of block containing count of
ENDSTR				; unallocated blocks per pool
	SUBTTL Line table BEGSTR
BEGSTR LT
	WORD LID		; Line ID
	FIELD FLG,2		; Flags
	  BIT DVE		; Driver believes device is present
	  BIT CAD		; Channel address is DECnet (Ethernet only)
	FIELD STA,2		; State of line
	FIELD CON,2		; Controller (normal/loopback)
	FIELD PRO,6		; Protocol type
	FIELD CTY,6		; Circuit type
	FIELD DBF,6		; Default number of buffers
	FIELD BSZ,12		; Maximum receive buffer size on this line
	HWORD BNO		; Number of buffers to post
	HWORD NBP		; Number of buffers posted
ENDSTR
	SUBTTL TDB BEGSTR

BEGSTR T
	FIELD FLG,30,29		;FLAGS
	 BIT T%SAL		;SENDALL BEING DONE TO THIS LINE
	 BIT T%SHT		;THIS IS A SHORT BLOCK
	 BIT T%MES		;THIS IS A SYSTEM MESSAGE BLOCK
	 BIT T%OTP		;OUTPUT IS ENROUTE TO THE LINE
	 BIT T%FWK		;FORCED WAKEUP
	 BIT T%SFG		;STOPPED ON END-OF-PAGE
	 BIT T%RFG		;REPEAT LAST CHARACTER (BKJFN)
	 BIT T%WFG		;BLOCKED ON INPUT
	 BIT T%PRM		;DON'T DEALLOCATE DYNAMIC DATA
	 BIT T%BAC		;PERMANENT AND BECOMING ACTIVE
	 BIT T%NXO		;PAUSE ON END-OF-PAGE MODE
	 BIT T%BKO		;FORK BLOCKED FOR OUTPUT EVENT ON THIS LINE
	 BIT T%NUS		;NET USER STATE
	 BIT T%DD1		;DEVICE DEPENDENT BIT
	 BIT T%NPM		;MCB NVT OLD PAGE MODE
	 BIT T%RXF		;HAVE RECEIVED XOFF ON LINE
	 BIT T%FLO		;FLUSHING OUTPUT AT TTSND
	 BIT T%HPO		;HIGH PRIORITY OUTPUT QUEUED
	 BIT T%DAL		;DEALLOCATE OF BLOCK REQUESTED
;	 BIT T%DBA		;CTS Terminal Data Base is Active
	 BIT T%XFF		;FORCE XOFF/XON STATUS TO FRONT-END
	 BIT T%SEC		;SERVER SHOULD ECHO
	 BIT T%WKC		;WAKE-UP SET HAS CHANGED
	 BIT T%SPG		;PAGE STOP IS TURNED ON IN THE SERVER
	FIELD TLCK,6,35		;(30-35) COUNT OF LOCKS ON THIS BLOCK

	FIELD YLMD,2,4		;TERMINAL DATA MODE FOR LAST INPUT CHAR
	FIELD TOCN,3,7		;COUNT OF EXTRA BUFFERS
	FIELD TOMX,1,8		;EXTRA BUFFERS IN USE
	FIELD TTYP,9,17		;TERMINAL TYPE
	HWORD INTL

	HWORD LTYP		;LINE TYPE (SAME AS TTSTY)
	FIELD SALT,6,23		;SENDALL TIMEOUT COUNT
	FIELD SALC,12,35	;SENDALL CHARACTER COUNT

	WORD TSAL2		;SENDALL BYTE POINTER

	WORD TDEV		;DEVICE DEPENDET WORD

	FIELD OWRN,8,7		;COUNT IN OUPUT BUFFER FOR WAKEUP
	FIELD TNIN,4,11		;NO. INPUT BUFFERS
	FIELD TNOU,4,15		;NUMBER OUTPUT BUFFERS
	FIELD IMAX,10,25	;MAX BYTES IN INPUT BUFFER
	FIELD OMAX,10,35	;MAX BYTES IN OUTPUT BUFFER

	WORD TOCT		;NUMBER CHARACTERS IN OUTPUT BUFFER
	WORD TOOUT		;POINTER FOR REMOVING CHAR FROM OUTPUT BUFFER
	WORD TOIN		;POINTER FOR ENTERING CHAR INTO OUTPUT BUFFER

	FIELD TUPC,9,8		;UNPAUSE ON PAGE CHARACTER
	FIELD YLCH,9,17		;LAST CHAR REMOVED FROM INPUT BUFFER
	FIELD PWID,9,26		;PAGE WIDTH
	FIELD TPPC,9,35		;PAUSE/UNPAUSE ON PAGE CHARACTER

	WORD TICT		;NUMBER CHARACTERS IN INPUT BUFFER
	WORD TIOUT		;POINTER FOR REMOVING CHAR FROM INPUT BUFFER
	WORD TIIN		;POINTER FOR ENTERING CHAR INTO INPUT BUFFER
	WORD MOD1		;CONTROL CHARACTER OUTPUT CONTROL WORDS
	WORD MOD2		;(2 BITS PER CHARACTER)
	WORD TDPSI		;BIT FOR TERMINAL CODE SET IF DEFERRED INTERRUPT
	WORD TPSI		;BIT FOR TERMINAL CODE SET IF INTERRUPT
	WORD TLNK		;LINES LINKED TO (9 BITS PER LINE)

	HWORD PGPS		;CURRENT LINE POSITION WITHIN PAGE
	HWORD LNPS		;CURRENT CHARACTER POSITION WITHIN LINE

	FIELDM OFLG,TT%OSP	;CTRL/O WAS TYPED
	FIELD PLEN,8,17		;PAGE LENGTH
	FIELDM TDUM,TT%DUM	;DUPLEX MODE
	NXTWRD

	HWORD CJOB		;CONTROLLING JOB NUMBER
	HWORD WFRK		;NUMBER OF FORK IN INPUT WAIT ON THIS LINE

	HWORD TPFK		;FORK WHICH IS TOP FORK OF A SCTTY TREE
	HWORD TPSFK		;PSI FORK FOR NON CONTROL TTY PSI'S

	WORD CHR1		;WAKE UP CHARACTER MASK (ASCII CODES 0-31.)
	WORD CHR2		;WAKE UP CHARACTER MASK (ASCII CODES 32.-63.)
	WORD CHR3		;WAKE UP CHARACTER MASK (ASCII CODES 64.-95.)
	WORD CHR4		;WAKE UP CHARACTER MASK (ASCII CODES 96.-127.)

	FIELD TIPSI,6,11	;INPUT PSI LEVEL
	FIELD TOPSI,6,17	;OUPUT PSI LEVEL
	HWORD TFCNT		;BYTE COUNT FOR WAKE-UP (0=DISABLED FOR WAKE UP)
	WORD TLINE		;LINE COUNTER

	FIELD TUEC,7,6		;NET USER ESCAPE CHAR
	FIELD TULL,29,35	;NET USER LOGICAL LINK - WHEN TTLMAX NOT IN USE
	NXTWRD

	FIELD TFLA,1,0		;FIRST CHARACTER SEEN FLAG
	FIELD TETP,3,4		;TYPE 
	FIELD TCH1,7,11		;FIRST CHARACTER
	FIELD TCH2,7,18		;SECOND CHARACTER
	NXTWRD

	WORD TSVPD		;SAVED LINE SPEED

ENDSTR

	
	SUBTTL Start Here

DCNSPY::TDZA T1,T1
	MOVEI T1,1
	MOVEM T1,CCLF1		;SET CCL FLAG FOR SCAN

	MOVEI T1,NODADR		;INITIALIZE THE NODE JSYS BLOCK:
	MOVEM T1,NODARG+.NDRBD	; SET UP DESTINATION

	OUTSTR [ASCIZ /Type HELP for HELP

/]
	MOVE	T1,[PUSHJ P,DPYUUO] ;GET CALLING INSTRUCTION
	MOVEM	T1,.JB41	;AND SET UP LUUO DISATCH

RESTART:RESET
	MOVE P,[IOWD LN$PDL,PDL] ;STACK

	SETOM	BEGSCN		;SET SCAN SWITCHES TO -1
	MOVE	T1,[BEGSCN,,BEGSCN+1]
	BLT	T1,ENDSCN
	CALL	TTYINI		;GET READY FOR TTY OUTPUT
	SETZM	SCNCOM		;SET FOR NO COMMENTS

;Fall through to next page
	SUBTTL	Call .ISCAN

;From previous page

;The comment from SCN7B.MAC about call to .ISCAN
;.ISCAN--SUBROUTINE TO INITIALIZE COMMAND SCANNER
;CALL	AC1=XWD LENGTH,BLOCK
;	BLOCK+0=0 OR IOWD PTR TO A LIST OF LEGAL MONITOR COMMANDS
;		IF 0, NO RESCAN IS DONE
;	BLOCK+1=RH 0 OR SIXBIT CCL NAME
;		  IF 0, NO CCL MODE
;		LH 0 OR ADDRESS OF STARTING OFFSET
;	BLOCK+2=RH 0 OR ADDRESS OF CHARACTER TYPEOUT ROUTINE
;		  IF 0, OUTCHR WILL BE DONE FROM T1
;		LH 0 OR ADDRESS OF CHARACTER INPUT ROUTINE
;			MUST SAVE ALL ACS, CHAR IN P4
;	BLOCK+3=0 OR POINTER (XWD LEN,BLOCK) TO INDIRECT FILE BLOCK
;		  A.DEV NE 0 TO USE BLOCK
;	BLOCK+4=RH 0 OR ADDRESS OF MONRET ROUTINE
;		LH 0 OR ADDRESS OF PROMPT ROUTINE
;			CALLED WITH CHAR IN RH(T1), LH(T1) HAS
;			    0 FOR FIRST LINE, -1 FOR CONTINUATION LINES
;	BLOCK+5=LH FLAGS
;		RH (FUTURE)
;VALUE	AC1=INDEX IN TABLE OF COMMANDS IF FOUND(0,1,...), ELSE -1

	MOVE T1,[3,,[ 0
		      CCLF1,,PRGABR
		      0,,SCNOUC]]
	CALL .ISCAN

;Fall through to next page
	SUBTTL	Call .OSCAN

;.OSCAN -- SUBROUTINE TO SCAN OPTIONS FILE (DSK:SWITCH.INI[,])
;	RETURNS CPOPJ AFTER UPDATING GLOBAL SWITCHES FROM FILE
;	THIS ROUTINE SHOULD BE CALLED AFTER TSCAN OR PSCAN
;		BUT BEFORE DEFAULTING.
;	CALL THIS ONLY AT END OF LINE.
;	IT SHOULD BE CALLED BETWEEN ISCAN AND VSCAN FOR VERBS.
;ARGS:	AC1=XWD LENGTH,BLOCK
;	BLOCK+0=IOWD POINTER TO LIST OF SWITCH NAMES (IOWD XXXXXL,XXXXXN)
;	BLOCK+1=LH ADDRESS OF DEFAULT SWITCH TABLE (XXXXXD)
;		RH ADDRESS OF PROCESSOR SWITCH TABLE (XXXXXM)
;	BLOCK+2=LH ADDRESS OF (FUTURE)
;		RH ADDRESS OF SWITCH POINTERS FOR STORING (XXXXXP)
;	BLOCK+3=LH TYPE OF HELP (0=NONE, 1=STRING, 2=SUBROUTINE)
;		  IF GT 77, NAME OF PROGRAM IN WHOLE WORD
;		  IF -1 IN WORD, USE JOB TABLE
;		RH LOCATION OF HELP
;	BLOCK+4=NAME OF OPTIONS TO SELECT IN FILE (0 IF NAME OF PROGRAM)
;			OR LENGTH,,LIST OF OPTION NAMES
;IF CALL FROM VSCAN, C(T3)= SAME AS BLOCK+4 ABOVE

	MOVE	T1, [4,,[IOWD SWTL,SWTN ;SHORT LIST OF SWITCHES
			 SWTD,,SWTM
			 0,,SWTP
			 1,,HLPSTR]]	;HELP STRING

	CALL	.OSCAN		;OPTION (SWITCH.INI) SCANNER

;Now fill in from internal defaults set up with DM macro

DEFINE DFT,(name),<
	MOVX	T1,AD.'name
	SKIPGE	SCN'name
	  MOVEM	T1,SCN'name
>

	DFT DPY			;/DPY mode
	DFT PAG			;/PAGE length
	DFT DLY			;/DELAY seconds
	DFT COM			;/COMMENTS
	DFT CHN			;/CHANNEL number

;Fall through to next page
	SUBTTL Find out what user wants to see

;.VSCAN --SUBROUTINE FOR VERB ARGS FORM OF COMMAND SCANNER
;	RETURNS CPOPJ IF EOF DURING COMMAND OR CCL AT TOP LEVEL
;ARGS	AC1=XWD LENGTH,BLOCK
;	BLOCK+0=IOWD POINTER TO LIST OF SWITCH NAMES
;			(IOWD XXXXXL,XXXXXN)
;	BLOCK+1=LH ADDRESS OF DEFAULT SWITCH TABLE (XXXXXD)
;		RH ADDRESS OF PROCESSOR SWITCH TABLE (XXXXXM)
;	BLOCK+2=LH ADDRESS OF (FUTURE)
;		RH ADDRESS OF SWITCH POINTERS FOR STORING (XXXXXP)
;	BLOCK+3=LH TYPE OF HELP (0=NONE, 1=STRING, 2=SUBROUTINE)
;		  IF GT 77, NAME OF PROGRAM IN WHOLE WORD
;		  IF -1 IN WORD, USE JOB TABLE
;		RH LOCATION OF HELP
;	BLOCK+4=LH LENGTH OF FXXX AND PXXX AREAS
;		RH START OF FXXX (PER FILE SWITCHES)
;	BLOCK+5=LH (FUTURE)
;		RH START OF PXXX (STICKY FORM OF FXXX)
;	BLOCK+6=NAME OF OPTION LINES (0 IF THIS PROGRAM'S NAME)


;From previous page

	MOVE	T1, [4,,[IOWD SWTL,SWTN ;SHORT LIST OF SWITCHES
			 SWTD,,SWTM
			 0,,SWTP
			 1,,HLPSTR]]	;HELP STRING

	CALL	.VSCAN		;VERB SCANNER
	JRST	RESTART
	SUBTTL Action Commands

SPYSJB:	MOVEI T1,TYPSJB		;TYPE OUT THE SJB
	CALLRET SPYGO

SPYSLB:	MOVEI T1,TYPSLB		;TYPE OUT THE SLB
	CALLRET SPYGO

SPYELB:	MOVEI T1,TYPELB		;TYPE OUT THE ELB
	CALLRET SPYGO

SPYCDB:	MOVEI T1,TYPCDB		;TYPE OUT THE CTERM DATA BLOCK
	CALLRET SPYGO

SPYRCB:	MOVEI T1,TYPRCB		;TYPE OUT ROUTER CIRCUIT BLOCK
	CALLRET SPYGO

SPYTIM:	MOVEI T1,TYPTIM		;TYPE OUT TIME (FOR DPY DEBUG)
	CALLRET SPYGO

SPYSPY:	MOVEI T1,TYPSPY		;TYPE OUT SOME ARBITRARY TABLE
	CALLRET SPYGO

SPYMB:	MOVEI T1,TYPMB		;TYPE OUT A MESSAGE BLOCK
	CALLRET SPYGO

SPYAJ:	MOVEI T1,TYPAJ		;TYPE OUT AN ADJACENCY BLOCK
	CALLRET SPYGO

SPYMEM:	MOVEI T1,TYPMEM		;Show DECnet memory utilization
	CALLRET SPYGO

SPYMRT:	MOVEI T1,TYPMRT		;Type out the memory request table
	CALLRET SPYGO

SPYPRT:	MOVEI T1,TYPPRT		;TYPE OUT THE PORT
	CALLRET SPYGO

SPYCI:	MOVEI T1,TYPCI		;Type out CI blocks
	CALLRET SPYGO

SPYHN:	CALL HNSUBR             ;Get HN block address
	  RET
	MOVEI T1,TYPHN          ;Type out HN (LAT Host Node) Blocks
	CALLRET SPYGO

SPYCBL:	CALL HNSUBR             ;Get HN block address
	  RET
	MOVEI T1,TYPCBL##       ;Type out CBL (LAT Host Circuit) Block
	CALLRET SPYGO

SPYSLT:	CALL TDSUBR             ;Get TTACTL address
	  RET
	MOVEI T1,TYPSLT##       ;Type out SLOT (LAT Slot) Block
	CALLRET SPYGO

HNSUBR:	SKIPE LAHNDB            ;Already got the value?
	RETSKP                  ;Yes, its not going to change
	MOVX T1,.SNPSY          ;Get symbol
	MOVE T2,[RADIX50,LAHNDB] ; LAHNDB is global pointer to Host Node list
	SETZ T3,                 ;  in any module
;	MOVE T3,[RADIX50,LATSRV] ;  in module LATSRV
	SNOOP%			;Address comes back in T2
	 ERR ?Can't find symbol LAHNDB
	MOVX T1,1               ;Get pointer to HN block
	XMOVEI T3,LAHNDB        ; to LAHNDB
	CALL XPEEKX		;  by way of XPEEK
	 ERR ?Can't XPEEK LAHNDB pointer
	RETSKP
SPYPSB:	CALL PSSUBR		;GET CHNBAS VALUE
	 RET			;FAILED
	MOVEI T1,TYPPSB##	;DISPLAY PSB (PORT STORAGE BLOCK)
	CALL SPYGO
	SETZM SCNIDX		;REINIT SCNIDX
	RET

PSSUBR:	SKIPE CHNBAS		;ALREADY HAVE VALUE?
	RETSKP			;ALL SET THEN
	MOVX T1,.SNPSY          ;Get symbol
	MOVE T2,[RADIX50,CHNBAS] ;CHNBAS IS POINTER TO FIRST PSB
	SETZ T3,                 ;  in any module
	SNOOP%			;Address comes back in T2
	 ERR ?Can't find symbol CHNBAS
	MOVX T1,1               ;GET ADDRESS OF FIRST BLOCK
	XMOVEI T3,CHNBAS        ; to CHNBAS
	CALL XPEEKX		;  by way of XPEEK
	 ERR ?Can't XPEEK CHNBAS
	RETSKP

SPYPTB:	CALL PTSUBR		;GET PORBAS VALUE
	 RET			;FAILED
	MOVEI T1,TYPPTB##	;DISPLAY PTB (PORTAL TABLE BLOCK)
	CALL SPYGO
	SETZM SCNIDX		;REINIT SCNIDX
	RET

PTSUBR:	SKIPE PORBAS		;ALREADY HAVE VALUE?
	RETSKP			;ALL SET THEN
	MOVX T1,.SNPSY          ;Get symbol
	MOVE T2,[RADIX50,PORBAS] ;PORBAS IS POINTER TO FIRST PTB
	SETZ T3,                 ;  in any module
	SNOOP%			;Address comes back in T2
	 ERR ?Can't find symbol PORBAS
	MOVX T1,1               ;GET ADDRESS OF FIRST BLOCK
	XMOVEI T3,PORBAS        ; to PORBAS
	CALL XPEEKX		;  by way of XPEEK
	 ERR ?Can't XPEEK PORBAS
	RETSKP

SPYTDB:	CALL TDSUBR             ;Get TTACTL value
	  RET
	MOVEI T1,TYPTDB		;Type out TDB (Terminal data block)
	CALLRET SPYGO

TDSUBR:	SKIPE TTACTL            ;Already got the value?
	RETSKP                  ;Yes, its not going to change
	MOVX T1,.SNPSY          ;Get symbol
	MOVE T2,[RADIX50,TTACTL] ; LAHNDB is global pointer to Host Node list
	SETZ T3,		;  in any module
	MOVE T3,[RADIX50,STG]	;  in module STG
	SNOOP%			;Address comes back in T2
	 ERR ?Can't find symbol TTACTL
	MOVEM T2,TTACTL		;SAVE THE VALUE OF TTACTL
	RETSKP
	SUBTTL SPYGO - Called by Action Commands

;Call:
;	CALL SPYGO
;	Only Return

SPYGO:	MOVEM	T1,SPYFCN	;SAVE THE ADDRESS OF THE OUTPUT ROUTINE
	MOVEI	T1,.PRIOU	;TURN OFF ECHO
	MOVE	T2,SPMSAV
	TRZ	T2,4000
	SFMOD			;SET THOSE SETTINGS
	SKIPLE	SCNDPY		;IN DPY MODE?
	JRST	SPYDPY		;YES, GO LOOP FOR A WHILE

;Here for non-DPY mode

	SETZM	TYPDPY		;TELL SCNOUC NOT TO USE DPY MODE
	CALL	@SPYFCN		;TYPE OUT THE DATA ONCE
	  JFCL			;IGNORE ERROR RETURN
	RET			;RETURN TO VSCAN

;Here to loop for DPY mode

SPYDPY:	SETZM	LINGOL		;START AT TOP OF LOGICAL SCREEN
	SETOM	TYPDPY		;TELL SCNOUC TO USE DPY MODE
	SETOM	BIGOUT		;USE BUFFERS INSTEAD OF OUTCHRS

	CALL	SPYRFH		;DO THE DPY DISPLAY LOOP

	SKIPE	TYPDPY		;STILL IN DPY MODE?
	  TTY$	$TTCLR		;YES, HOME UP AND CLEAR SCREEN
	CALL	TTYFRC		;FORCE OUT LAST OF PIM MODE DATA
	SETZM	TYPDPY		;REFRAIN FROM DPY DISPLAYS NOW
	SETZM	BIGOUT		;NOW USE OUTCHRS INSTEAD OF BUFFERS

	MOVEI	T1,.PRIOU	;TURN ECHO BACK ON
	MOVE	T2,SPMSAV
	SFMOD
	RET			;RETURN TO VSCAN
	SUBTTL	DPY Driver

SPYRFH:	INI$			;INITIALIZE AND BLANK THE SCREEN
	SETOM	INIFLG		;SAY THE INITIALIZE WAS DONE
	SET$	[XWD $SECHR,TTYOUC] ;USE OUR CHARACTER OUTPUT ROUTINE

SPYDPL:	MOVEI	T1,.PRIIN	;SEE IF THE USER TYPED SOMETHING
	SIBE
	 JRST	SPYINT		;THERE'S SOMETHING THERE - GO READ IT

SPYDP1:	SETZM	LINCNT		;TELL SCNOUC WE'RE STARTING ANEW
	SETZM	COLPOS		;SET POSITION TO COLUMN 1
	CALL	@SPYFCN		;CAUSE SOME TTY OUTPUT
	  RET			;RETURN NOW IF ERROR ENCOUNTERED
	DPY$			;SUCCESS, UPDATE THE SCREEN
	CALL	TTYFRC		;FORCE OUT REMAINDER OF BUFFER

	MOVE	T1,SCNDLY	;PICK UP USER'S IDEA OF A GOOD WAIT TIME
	IMULI	T1,^D1000	;MAKE SECONDS INTO MILLISECONDS
	DISMS			;SLEEP FOR SCNDLY MILLISECONDS
	JRST	SPYDPL		;TIME TO GO CHECK THINGS AGAIN

;HERE WHEN THE USER TYPED A CHARACTER, TO SEE WHAT HE WANTS

SPYINT:	PBIN			;READ THE USER'S CHARACTER INTO T1
	CAIL	T1,"A"+40	;LOWER CASE?
	CAILE	T1,"Z"+40	;...
	CAIA			;NO
	SUBI	T1,40		;YES - MAKE UPPER CASE
	CAIN	T1,33		; ESCAPE?
	  RET			;YES - GET OUT OF THE LOOP
	CAIN	T1,"A"		; User request we display adjacencies?
	 JRST	[MOVE T1,SPYFCN	; Get previous request
		 CAIE T1,TYPRCB	; Were we showing circuits?
		  SKIPA T1,[TYPRCB]; No, toggle to circuits
		 MOVEI T1,TYPAJ	; Yes, then toggle to adjacencies
		 MOVEM T1,SPYFCN
		 JRST SPYRFH]	;  and make the new display
	CAIN	T1,"R"		;REFRESH?
	  JRST	SPYRFH		;YES
	CAIN	T1,"C"		;TOGGLE COMMENT/NOCOMMENT SWITCH
	  JRST	[SKIPLE T1,SCNCOM ;YES - DO IT
		 TDZA   T1,T1
		 MOVEI  T1,1
		 MOVEM  T1,SCNCOM
		 SETZM LINGOL
		 JRST   SPYDPL]	;AND PROCEED
	CAIE	T1,15		;<CR> OR
	 CAIN	T1," "		; SPACE?
	  JRST	SPYDPL		;YES, RECALC SCREEN
	CAIE	T1,"C"-100	;CONTROL-C,
	 CAIN	T1,"Z"-100	; OR CONTROL Z?
	  JRST	SPYXIT		;YES - GO HOME TO MONITOR
	CAIN	T1,"E"		; OR "E"
	  JRST	SPYXIT		;YES - GO HOME TO MONITOR
	CAIE	T1,"="		;LOWER CASE VERSION OF "+"
	 CAIN	T1,"+"		;GO TO NEXT PART OF SCREEN?
	  JRST	[MOVE T2,SCNPAG	;YES
		 ADDM  T2,LINGOL
		 JRST  SPYRFH]
	CAIN	T1,"N"		;GO TO NEXT CHANNEL?
	  JRST	[AOS SCNCHN	;Increment channel pointer
		 AOS SCNIDX	; and the index counter
		 SETZM CKTID	; and clear circuit the user requested
		 JRST  SPYRFH]
	CAIN	T1,"P"		;GO TO PREV CHANNEL?
	  JRST	[SOSG SCNCHN	;YES
		 AOS  SCNCHN	;DON'T LET CHN GO BELOW 1
		 SOSGE SCNIDX	;Decrement index counter
		 AOS SCNIDX	; don't let it go below zero
		 SETZM CKTID	; and clear requested circuit
		 JRST  SPYRFH]
	CAIN	T1,"-"		;GO TO PREVIOUS PAGE?
	  JRST	[MOVN T2,SCNPAG	;YES
		 ADDB  T2,LINGOL
		 JUMPGE T2,SPYRFH
		 SETZM LINGOL	;DON'T LET GOAL GO NEGATIVE
		 JRST  SPYRFH]
	JRST	SPYDP1		;UNKNOWN COMMAND - JUST LOOP

;HERE ON CONTROL-C OR CONTROL-Z, TO EXIT

SPYXIT:	SKIPE	INIFLG		;WAS AN INITIALIZE DONE?
	TTY$	$TTCLR		;YES - HOME UP AND CLEAR SCREEN
	CALL	TTYFRC		;FORCE OUT REST OF TTY BUFFER
	MOVEI	T1,.PRIIN	;GET THE ORIGINAL RFMOD WORD
	MOVE	T2,FMDSAV
	SFMOD			;RESTORE THE ORIGINAL SETTINGS
	STPAR
	HALTF			;GO HOME
	JRST	SPYRFH		;REFRESH SCREEN ON CONTINUE
	SUBTTL	TYPTIM - Type out current time

;For debugging the DPY driver
;
;Call:
;	CALL TYPTIM		;NO ARGS IN ACS
;	  Error Return to stop DPY loop
;	Normal Return

TYPTIM:	CALL .TTIMN		;TYPE OUT CURRENT TIME
	CALL .TCRLF		;CARRIAGE RETURN
	RETSKP			;SUCCESS RETURN
	SUBTTL	TYPSJB - Type out contents of an SJB

;Call:
;	CALL TYPSJB		;NO ARGS IN ACS
;	  Error Return to stop DPY loop
;	Normal Return

TYPSJB:	CALL SETSJB		;SET UP POINTERS TO DECNET BLOCKS
	 RETSKP			;LEAVE IF NO SJB (ERROR ALREADY GIVEN)
	CALL .TCRLF		;SKIP A LINE BETWEEN CHANNELS AND BANNER
	MOVEI T1,[ASCIZ /SJB for /]
	CALL .TSTRG
	CALL TYPJOB		;TYPE THE JOB NUMBER OR SPECIAL
	CALL TYPTAD		;AND THE ADDRESS OF THE TABLE
	MOVE T1,SJBPTR##        ;GET AOBJN POINTER TO SJBTBL
	CALL TYPBLK		;TYPE OUT THE SJB
	RETSKP			;SUCCESS RETURN
	SUBTTL	TYPPRT - Type out contents of an PRT

;Call:
;	CALL TYPPRT		;NO ARGS IN ACS
;	  Error Return to stop DPY loop
;	Normal Return

TYPPRT:	CALL SETSJB		;Set up pointers to DECnet blocks
	  RETSKP		;Leave if no SJB (error already given)

	LOAD T1,SJMXP,+NODBLK	;Get count of channels alloc'd to port table
	SKIPL SCNCHN		;Channel number not negative?
	 CAMGE T1,SCNCHN	;Channel number fit in allocated port slots?
	  JRST ILLCHN		;No, boo
	LOAD T2,SJPRT,+NODBLK	;Add in address of port indirect table
	JUMPE T2,ILLPRT		;Jump if no port indirect table exists
	LOAD T1,SJMXP,+NODBLK	;Get length of port indirect table
	CALL SUBSPY		;Read the indirect table into NODBLK
	 RETSKP

	MOVX T1,PT.LEN		;Get length of port block for arg to XPEEKX
	MOVE T2,SCNCHN		;Channel number = port block number
	MOVE T2,NODBLK(T2)	;Get address of port block
	JUMPE T2,CHNNIU
	MOVEM T2,NODADR		;TELL TYPTAD WHERE THE BLOCK IS
	CALL SUBSPY
	  RETSKP		;It's no use if no block

	CALL .TCRLF		;Skip a line between channels and banner
	MOVEI T1,[ASCIZ /Port Table for /]
	CALL .TSTRG
	CALL TYPJOB		;TYPE THE JOB NUMBER OR SPECIAL
	CALL TYPCHL		;FOLLOWED BY THE CHANNEL NUMBER
	CALL TYPTAD		;AND THE ADDRESS OF THE TABLE

	MOVE T1,PRTPTR##        ;GET AOBJN POINTER TO PRTTBL
	CALL TYPBLK		;TYPE OUT THE PORT BLOCK
	RETSKP			;SUCCESS RETURN


ILLPRT:	MOVEI T1,[ASCIZ /?No port table for that SJB
/]
	CALLRET .TSTRG
CHNNIU:	MOVEI T1,[ASCIZ /%Channel is not in use
/]
	CALL .TSTRG
	RETSKP
	SUBTTL TYPSLB - Type out an SLB

;Call:
;	CALL TYPSLB		;NO ARGS IN ACS
;	  Error Return to stop DPY loop
;	Normal Return

TYPSLB:	CALL SETSLB		;SET UP POINTER TO SLB
	  RETSKP		;NO CHANNEL, NO TYPEOUT
	MOVEI T1,[ASCIZ /SLB for /]
	CALL .TSTRG
	CALL TYPJOB		;OUTPUT THE JOB NUMBER OR SPECIAL
	CALL TYPCHL		;FOLLOWED BY THE CHANNEL NUMBER
	CALL TYPTAD		;AND THE ADDRESS OF THE TABLE
	MOVE T1,SLBPTR##        ;GET AOBJN POINTER TO SLBTBL
	CALL TYPBLK		;TYPE OUT THE SLB
	RETSKP			;SUCCESS RETURN
	SUBTTL TYPELB - Type out the ELB

;Call:
;	CALL TYPELB		;NO ARGS IN ACS
;	  Error Return to stop DPY loop
;	Normal Return

TYPELB:	CALL SETELB		;GET PTR TO ELB
	 RETSKP			;IT'S NO USE IF NO BLOCK
	MOVEI T1,[ASCIZ /ELB for /]
	CALL .TSTRG
	CALL TYPJOB		;OUTPUT THE JOB NUMBER OR SPECIAL
	CALL TYPCHL		;FOLLOWED BY THE CHANNEL NUMBER
	CALL TYPTAD		;AND THE ADDRESS OF THE TABLE
	MOVE T1,ELBPTR##        ;GET AOBJN POINTER TO ELBTBL
	CALL TYPBLK		;TYPE OUT THE ELB
	RETSKP			;SUCCESS RETURN
	SUBTTL TYPCDB - Type out the CTERM Data Block

;Call:
;	CALL TYPCDB		;NO ARGS IN ACS
;	  Error Return to stop DPY loop
;	Normal Return

TYPCDB:	CALL SETCDB		;GET POINTER TO THE CDB
	 RETSKP			;IT'S NO USE IF NO BLOCK
	MOVEI T1,[ASCIZ /CDB for /]
	CALL .TSTRG
	CALL TYPTTN		;OUTPUT THE TTY NUMBER
	CALL TYPTAD		;AND THE ADDRESS OF THE TABLE
	MOVE T1,CDBPTR##        ;GET AOBJN POINTER TO CDBTBL
	CALL TYPBLK		;TYPE OUT THE CDB
	RETSKP			;SUCCESS RETURN
	SUBTTL TYPRCB - Type out the Router Circuit Block

;Call:
;	CALL TYPRCB		;NO ARGS IN ACS
;	  Error Return to stop DPY loop
;	Normal Return

TYPRCB:	STKVAR <DLB,LTP>
	CALL SETRCB		;GET PTR TO RCB
	 RETSKP			;IT'S NO USE IF NO BLOCK
	MOVEI T1,[ASCIZ /Router circuit block /]
	CALL .TSTRG
	MOVEI T1,NODBLK
	LOAD T2,RCDLB,(T1)
	MOVEM T2,DLB
	LOAD T1,RCLID,(T1)	; Get the circuit ID
	CALL .TCKT		;TYPE THE CIRCUIT
	CALL TYPTAD		;AND THE ADDRESS OF THE TABLE
	MOVE T1,RCBPTR##        ;GET AOBJN POINTER TO RCBTBL
	CALL TYPBLK		;TYPE OUT THE RCB
	CALL .TCRLF		; End the previous display
	MOVEI T1,[ASCIZ /DNADLL data link block:/]
	CALL .TSTRG

;Get the data link block associated with the currently selected circuit

	MOVE T2,DLB		; Get the address of the data link block
	MOVEM T2,NODADR		; So TYPADR can display the address
	MOVEI T1,DL.LEN		; Length of DLB
	MOVEI T3,NODBLK		; Save the data here
	CALL XPEEKX
	 MSG < getting Data Link Block>
	MOVEI T1,NODBLK
	LOAD T2,DLLTP,(T1)
	MOVEM T2,LTP
	MOVE T1,DLB
	CALL TYPADR		; Display the address of the data link block
	MOVE T1,DLBPTR##        ; and now the data link block pointer
	CALL TYPBLK		;Type it as well

	CALL .TCRLF		; End the previous display
	MOVEI T1,[ASCIZ /DNADLL line table:/]
	CALL .TSTRG
	MOVE T2,LTP		; Get the address of the line table
	MOVEM T2,NODADR		; So TYPADR can display the address
	MOVEI T1,LT.LEN		; Length of line table
	MOVEI T3,NODBLK		; Save the data here
	CALL XPEEKX
	 MSG < getting Line Table>
	MOVEI T1,NODBLK
	CALL TYPADR		; Display the address of the data link block
	MOVE T1,LTBPTR##        ; and now the data link block pointer
	CALL TYPBLK		;Type it as well
	RETSKP			;SUCCESS RETURN
	SUBTTL TYPSPY - Type out an arbitrary table

;Call:
;	CALL TYPSPY		;NO ARGS IN ACS
;	  Error Return to stop DPY loop
;	Normal Return

TYPSPY:	MOVE T1,SCNTLN		;GET USER-DECLARED LENGTH
	MOVEM T1,LENGTH		;SAVE AS LENGTH OF TABLE TO READ
	CALL SETSPY		;GET POINTER TO THE TABLE
	 RETSKP			;IT'S NO USE IF NO BLOCK
	MOVEI T1,[ASCIZ /Generic/]
	CALL .TSTRG
	CALL TYPTAD		;AND THE ADDRESS OF THE TABLE
	MOVE T1,LENGTH		;GET THE TABLE LENGTH
	CALL TYPTAB		;TYPE OUT THE TABLE
	RETSKP			;SUCCESS RETURN
	SUBTTL TYPAJ - Type out an adjacency block

;Call:
;	CALL TYPAJ		;NO ARGS IN ACS
;	  Error Return to stop DPY loop
;	Normal Return

TYPAJ:	SAVEAC <P1>	
	SKIPN T1,LOPCKT		; Get current circuit
	 ERR ?No circuit block selected
	SETZ P1,		; Default is not to loop
	CALL FNDCHB		; Find the cache entry offset
	 JRST NODERR		;  **** FIX THIS ****
	JUMPN T2,TYPAJ2
TYPAJ1:	AOS P1			; Say this is first adjacency
	MOVEI T1,RC.AJQ+1	; Read enough to get the queue pointer
	MOVE T2,LOPCKT
	MOVEI T3,NODBLK		; Save data at NODBLK
	CALL XPEEKX		; Get partial circuit block
	 MSG <Getting circuit block at TYPAJ1>
	MOVEI T2,NODBLK
	SKIPN T2,RC.AJQ(T2)	; Pointer to adjacency block queue
	 ERR ?No adjacenies are online
TYPAJ2:	MOVEI T1,AJ.LEN		; Length of adjacency block
	MOVEM T2,NODADR		; Save block address for type out routine
	MOVEI T3,NODBLK		; Store the data here
	CALL XPEEKX
	 MSG <Getting adjacency block at TYPAJ2>
	JUMPE P1,TYPAJ4		; If zero, we have the data we want
	MOVEI T4,NODBLK
	MOVE T2,AJ.NXT(T4)	; Get next block pointer
	CAMN P1,SCNCHN		; The one we want?
	 JRST TYPAJ4		; Yes, display it
	SKIPE T2		; Continue as long as we have a pointer
	AOJA P1,TYPAJ2		; Get the next adjacency
	MOVEI T1,1		; 
	MOVEM T1,SCNCHN		; Reset SCNCHN to start
	SETZ P1,		; Reset loop counter
	JRST TYPAJ1		;  and try again
TYPAJ4:	MOVEI T1,[ASCIZ /Adjacency Block/]
	CALL .TSTRG
	CALL TYPTAD		;AND THE ADDRESS OF THE TABLE
	MOVE T1,AJBPTR##        ;GET AOBJN POINTER TO AJBTBL
	CALL TYPBLK		;TYPE OUT THE AJACENCY BLOCK
	RETSKP			;SUCCESS RETURN
	SUBTTL FNDCHB - Find cache block

;Find the adjacency queue for the currently selected circuit

;Call T1 = Circuit block address

FNDCHB:	SAVEAC <P1>
	MOVNI P1,%CIRMX		; Set up an AOBJN pointer for circuit max
	HRLZ P1,P1
FNDCH1:	CAMN T1,CIRBLK(P1)	; Is this the circuit block we want?
	 JRST FNDCH2		; Yes, return the info requested
	AOBJN P1,FNDCH1		; No, try the next
	SETZ T1,		; Failed to match
	SETZ T2, 		; Indicate failure
	RET
FNDCH2:	HRRZ T1,P1		; Get the offset
	MOVE T2,CIRAJQ(P1)	;  and the adjacency address if any
	RETSKP
	SUBTTL TYPMEM - Type out DECnet memory utilization


TYPMEM:	SAVEAC <P1,P2>
	SKIPE CHBLKN		; Do we know how many blocks?
	 JRST TYPME1		; Yes, don't have to look again
	MOVE T1,[.SNPSY]	;Snoop for a symbol value
	MOVE T2,[RADIX50,CHBLKQ] ;In particular CHBLKQ in D36COM
	MOVE T3,[RADIX50,D36COM]
	SNOOP%			;Return address in T2
	 RET
	MOVEI T1,1		;Now read our requested memory data
	MOVEI T3,T4		;Load the 1 word into T4
	CALL XPEEKX		;Peek for number of CH blocks
	 MSG <Getting number of CH blocks>
	MOVEM T4,CHBLKN
TYPME1:	SKIPE T2,CHBADR		; Do we have an address for the blocks?
	 JRST TYPME2		; Yes, then just read the data
	MOVE T1,[.SNPSY]	; Snoop for a symbol value
	MOVE T2,[RADIX50,CHBLKS] ;In particular CHBLKS in D36COM
	MOVE T3,[RADIX50,D36COM]
	SNOOP%			; Return address in T2
	 RET
	MOVEM T2,CHBADR		; Save address for next time
	MOVEM T2,NODADR		; To fool TYPTAD
TYPME2:	SKIPE T2,CHBSIZ		; Do we have a length for the blocks?
	 JRST TYPME3		; Yes, then just read the data
	MOVE T1,[.SNPSY]	; Snoop for a symbol value
	MOVE T2,[RADIX50,CH.LEN] ;In particular CH.LEN in D36COM
	MOVE T3,[RADIX50,D36COM]
	SNOOP%			;Return address in T2
	 RET
	MOVEM T2,CHBSIZ		; Save length for next time
TYPME3:	MOVE T1,CHBLKN		; Get number of blocks
	IMUL T1,CHBSIZ		; Multiply by length to get number of words
	MOVE T2,CHBADR		; Address of start of block
	MOVEI T3,NODBLK		; Place to store data
	CALL XPEEKX		; Get the data
	 MSG <Getting data from CH blocks>
	MOVEI T1,[ASCIZ /CH block utilization/] ; Display name
	CALL .TSTRG
	CALL .TCRLF
	CALL .TCRLF

	MOVN P1,CHBLKN		; Set up an AOBJN pointer for number
	HRLZ P1,P1		;  of blocks
	CAIG P1,2		; Do we have more than 2 blocks?
	 ADDI P1,5		; No, assume just 2
TYPME4:	MOVE T1,XBLCB(P1)	; Name of block
	CALL .TSTRG
	CALL .TTABC
	CALL .TTABC
	CALL .TSPAC
	CALL .TSPAC
	CALL .TSPAC
	CALL .TSPAC
	MOVE T1,CHBPTR##        ; Get aobjn pointer to CH block table
	CALL TYPBLK		; Type out the CH block
	CALL .TCRLF		; End the previous display
	MOVE T1,[NODBLK+XH.LEN,,NODBLK]
	BLT T1,NODBLE
	AOBJN P1,TYPME4		; 
	CALL TYPREB
	 TRN
	RETSKP

XBLCB:	[ASCIZ /SBLCB:/]
	[ASCIZ /ABLCB:/]
	[ASCIZ /BBLCB:/]
	[ASCIZ /LBLCB:/]
	[ASCIZ /VBLCB:/]
	[ASCIZ /MBLCB:/]
	[ASCIZ /UBLCB:/]

DEFINE X(Name,description),<
	[ASCIZ /NAME/]
>
FRETAB:
X <.REBAS>,<Starting address of free space>
X <.REEND>,<Address of last word of free space>
X <.RETOT>,<Total size of free space in blocks>
X <.REPR1>,<If remaining space less than this, allocate only priority 1>
X <.REGRO>,<If remaining space less than this, grow free space>
X <.REBTB>,<Address of start of bit table>
X <.REBTL>,<Length of bit table (words)>
X <.RETFR>,<Total remaining unallocated blocks>
X <.REFFB>,<Number of block just past end of free space>
X <.REPMX>,<Number of pools>
X <.REQTA>,<Address of block containing quota for each pool>
X <.REPFR>,<Address of block containing count of unallocated blocks per pool>
	SUBTTL TYPREB - Type the system free pool tables

TYPREB:	SAVEAC <P1>
	MOVE T1,[.SNPSY]
	MOVE T2,[RADIX50,SBLCB] ;In particular SBLCB in D36COM
	MOVE T3,[RADIX50,D36COM]
	SNOOP%			; Return address in T2
	 TRNA
	RETSKP			; Return if using old memory manager
	MOVE T1,[.SNPSY]	; Snoop for a symbol value
	MOVE T2,[RADIX50,RES0TB] ;In particular RES0TB in STG
	MOVE T3,[RADIX50,STG]
	SNOOP%			; Return address in T2
	 RET
;	MOVEM T2,RES0TB
	MOVEI T1,RE.LEN		; Get length of block
	MOVEI T3,NODBLK		; Place to store data
	CALL XPEEKX		; Get the data
	 MSG <Getting non-extended free space block>
	MOVE T1,[.SNPSY]	; Snoop for a symbol value
	MOVE T2,[RADIX50,RESNTB] ;In particular RESNTB in STG
	MOVE T3,[RADIX50,STG]
	SNOOP%			; Return address in T2
	 RET
;	MOVEM T2,RESNTB
	MOVEI P1,NODBLK
	ADDI P1,RE.LEN		; Don't overwrite previous data
	MOVE T3,P1
	MOVEI T1,RE.LEN		; Get length of block
	CALL XPEEKX		; Get the data
	 MSG <Getting extended free space block>
	ADDI P1,RE.LEN
	SKIPN NREQTA
	 CALL LDQTA
	MOVE T1,NREPMX		; Get length of block
	MOVE T2,NREQTA		; Non-extended quota
	MOVE T3,P1		; Place to store data
	CALL XPEEKX		; Get the data
	 RET
	ADD P1,NREPMX
	MOVE T1,NREPMX
	MOVE T2,NREPFR		; Non-extended remaining
	MOVE T3,P1
	CALL XPEEKX
	 RET
	ADD P1,NREPMX
	MOVE T1,XREPMX		; Get length of block
	MOVE T2,XREQTA		; Extended quota
	MOVE T3,P1		; Place to store data
	CALL XPEEKX		; Get the data
	 RET
	ADD P1,XREPMX
	MOVE T1,XREPMX
	MOVE T2,XREPFR		; Extended remaining
	MOVE T3,P1
	CALL XPEEKX
	 RET
	CALL TYPFRE
	RETSKP
	SUBTTL TYPFRE - Type out free space utilization

TYPFRE:	SAVEAC <P1,P2>
	MOVEI T1,[ASCIZ / Pool  Non-extended  Extended		Assigned  	   Used/]
	CALL .TSTRG
	CALL .TCRLF
	CALL .TCRLF
	HRRZ P1,REBPTR##        ;Pointer to REB table
	HLLZ P2,REBPTR          ;AOBJN length of table
TYPFR1:	MOVE T1,@DO.NAM(P1)	; Entry name
	CALL .TSIXN
	CALL .TCOLN		;TYPE A COLON
	CALL .TSPAC		;TYPE OUT A SPACE
	MOVE T1,NODBLK(P2)	;GET THE VALUE
	CALL @DO.RTN(P1)
	CALL TYPTBB		;TAB OVER
	HRRZ T1,P2
	ADDI T1,RE.LEN
	MOVE T1,NODBLK(T1)
	CALL @DO.RTN(P1)
	MOVE T1,P2
	CALL TYPQTA
	CALL .TCRLF		;MOVE TO THE NEXT LINE
	AOBJN P2,TYPFR1		;LOOP THOUGH ALL THE ITEMS
	CALL TYPTBB		;TAB OVER
	MOVE T1,P2
	CALL TYPQTA
	 TRN
	RET			;ALL DONE
	SUBTTL Load free core quota tables


LDQTA:	MOVEI T1,NODBLK
	LOAD T2,REQTA,(T1)
	MOVEM T2,NREQTA		; Save pointer to quota table

	LOAD T2,REPMX,(T1)	; Get number of pools
	MOVEM T2,NREPMX

	LOAD T2,REPFR,(T1)
	MOVEM T2,NREPFR		;  and pointer to quota remaining

	ADDI T1,RE.LEN
	LOAD T2,REQTA,(T1)
	MOVEM T2,XREQTA		; Save pointer to quota table

	LOAD T2,REPMX,(T1)	; Get number of pools
	MOVEM T2,XREPMX

	LOAD T2,REPFR,(T1)
	MOVEM T2,XREPFR		;  and pointer to quota remaining
	RET
	SUBTTL TYPQTA - Type out free space quotas (assigned and remaining)

;Call:
;	T1/ Offset into display

TYPQTA:	SAVEAC <P1,P2>
	STKVAR <TEMP>
	SETZ P2,		; Initialize to start of NODBLK
	HRRZ T1,T1		; Right half only
	CAMN T1,NREPMX		; Have we completed one block's worth?
	 RET			; Then leave a blank line
	CAMG T1,NREPMX		; Have we reached the next block?
	IFSKP.
	  SUBI T1,1		; Account for the blank line
	  MOVE P2,NREPMX	; Compute offset into next group
	  LSH P2,1		;  which is 2 blocks away
	ENDIF.
	IDIV T1,NREPMX		; Get offset mod NREPMX
	CAMLE T2,NREPMX		; If too big leave
	 RET
	MOVE P1,T2		; Preserve offset
	CALL TYPTBB		; Type a tab
	CAIE P1,0		; If zeroth element
	IFSKP.	 
	  CAIE P2,0		; If beginning of display then
	  IFSKP.
	    MOVEI T1,[ASCIZ /   -- Non-extended -- /] ; use this message
	  ELSE.
	    MOVEI T1,[ASCIZ /     -- Extended -- /]
	  ENDIF.
	  CALL .TSTRG
	ELSE.
	  MOVE T1,QTATAB(P1)	; Display item name
	  CALL .TSTRG
	  CALL .TCOLN		;TYPE A COLON
	  CALL .TSPAC		;TYPE OUT A SPACE
	  ADDI P2,<2*RE.LEN>	; Offset to the quota tables
	  ADD P2,P1		;  and into the entry in the quota table
	  MOVE T1,NODBLK(P2)	; Get datum
	  MOVEM T1,TEMP
	  CALL .TDECD
	  CALL TYPTBB		;TAB OVER
	  ADD P2,NREPMX		; Offset to remaining
	  MOVE T2,NODBLK(P2)	; Get datum
	  MOVE T1,TEMP		; Get quota
	  SUB T1,T2		; Compute used
	  CALL .TDECD
	ENDIF.
	RET

DEFINE X(NAME),<
	EXP 0
	[ASCIZ /Genrl /]
	[ASCIZ /Termnl/]
	[ASCIZ /DECnet/]
	[ASCIZ /Timer /]
	[ASCIZ /Units /]
>
QTATAB:	X
	SUBTTL TYPMRT - Type out the memory request table

;Call:
;	CALL TYPMRT		;No arguments in ACs
;	  Error Return to stop DPY loop
;	Normal Return

TYPMRT:	MOVE T1,[.SNPSY]	;Snoop for a symbol value
	MOVE T2,[RADIX50,MRQTAB] ;In particular MRQTAB in D36COM
	MOVE T3,[RADIX50,D36COM]
	SNOOP%			;Return address in T2
	 RET
	MOVEI T1,1		;Now read our requested memory data
	MOVEI T3,T4		;Load the 1 word into T4
	PUSHJ P, XPEEKX		;Peek...
	 RET
	MOVEM T4,SCNTAD		;Address user requested
	MOVEM T4,MAPADR		;Keep a safe copy
	MOVEM T4,NODADR		;To fool TYPTAD
	MOVEI T1,[ASCIZ /Memory request table/]
	CALL .TSTRG
	CALL TYPTAD		;And the address of the table
	MOVEI T1,[ASCIZ /# Words   High   Current/]
	CALL .TSTRG
	CALL .TCRLF
	CALL .TCRLF
	MOVEI P1,<^D2048/^D128>	;Number of times we have to read memeory
	MOVEI T1,^D128		;Length of table
	MOVEM T1,LENGTH		;Save as length of table to read
TYPMR1:	CALL SETSPY		;Get pointer to the table
	 RETSKP			;It's no use if no block
	MOVE T1,LENGTH		;Get the table length
	CALL TYPMTB		;Type out the table
	MOVEI T1,^D128		;Step to next chunk of table
	ADDM T1,SCNTAD
	SOJG P1,TYPMR1		;Continue until done
	MOVE T1,MAPADR		;Restore address originally requested
	MOVEM T1,SCNTAD
	RETSKP			;Success return
	SUBTTL XPEEKX - Common routine to peek into the monitor

;Call with
;	T1 = Number of words to read
;	T2 = Address to read from
;	T3 = Place to store what is read

XPEEKX::SAVEAC <P1>
	MOVEI P1,XPKBLK		;Argument block for JSYS
	MOVEM T1,.XPCN1(P1)	;Count of words to read
	SETZM .XPCN2(P1)
	MOVEM T2,.XPMAD(P1)	;Memory addrees to begin reading
	MOVEM T3,.XPUAD(P1)	;Where in user space to store results
	MOVEI T1,.XPLEN
	MOVEM T1,.XPABL(P1)	;Length of argument block
	MOVEI T1,.XPPEK		;Function
	MOVEM T1,.XPFNC(P1)
	MOVEI T1,XPKBLK
	XPEEK%
	 ERJMP PEKERR
	RETSKP
	SUBTTL TYPMB - Type out a Message Block

;Call:
;	CALL TYPMB		;NO ARGS IN ACS
;	  Error Return to stop DPY loop
;	Normal Return

TYPMB:	MOVX T1,MB.LEN		;LENGTH OF A MESSAGE BLOCK
	MOVEM T1,LENGTH		;STORE AS LENGTH OF TABLE TO READ
	CALL SETSPY		;GET POINTER TO THE TABLE
	 RETSKP			;IT'S NO USE IF NO BLOCK
	MOVEI T1,[ASCIZ /Message Block /]
	CALL .TSTRG
	CALL TYPTAD		;AND THE ADDRESS OF THE TABLE
	MOVE T1,MBBPTR##        ;GET AOBJN POINTER TO MBBTBL
	CALL TYPBLK		;TYPE OUT THE MB
	RETSKP			;SUCCESS RETURN
	SUBTTL TYPCI - Type out CI DECnet tables

;Call:
;	CALL TYPCI
;	  Error return to stop DPY loop
;	Normal return

TYPCI:	MOVE T1,[.SNPSY]	;Get symbol
	MOVE T2,[RADIX50,CBBLK]	; CBBLK
	MOVE T3,[RADIX50,CIDLL]	;  in module CIDLL
	SNOOP%			;Address comes back in T2
	 ERR ?Can't find symbol CBBLK
	MOVX T1,CB.LEN		;Read all of CB
	MOVEM T2,CBADR		; from T2 (and save value)
	XMOVEI T3,NODBLK	; to NODBLK
	CALL XPEEKX		;  by way of XPEEK
	 ERR ?Can't XPEEK CBBLK
	MOVEI T1,[ASCIZ ?DECnet/CI controller block (CBBLK) at address ?]
	CALL .TSTRG		;Type out text
	MOVE T1,CBADR		;Get address of CBBLK
	CALL .TXWDW		; and type in halfword format
	CALL .TCRLF		;  and end with a free CRLF
	CALL .TCRLF		;   and a final one
;Now type CB table on screen
	MOVE T1,CBBPTR##        ;Get AOBJN pointer to CB table
	CALL TYPBLK		; and write CB to screen
;Type out the name of the circuit the user specified
	MOVEI T1,[ASCIZ /Circuit /]
	CALL .TSTRG		;Type out header
	MOVE T1,CKTID		; and get circuit ID
	CALL .TCKT		;  to type out the circuit name
;If the user specified a circuit ID, write the PB corresponding to the circuit
; below the CB.
	MOVE T1,CKTID		;Get the circuit ID
	LOAD T2,LIDEV,+T1	;Get device type
	CAXN T2,LD.CIP		;Is it CI?
	IFSKP.			; -no
	  MOVEI T1,[ASCIZ / - is not a CI circuit/]
	  CALL .TSTRG		;  and type error message
	  RETSKP		;  and return
	ENDIF.
	LOAD T2,LIDRP,+T1	;Get drop number
	ADDI T2,CB.PRT##        ;Add offset to port tables
	SKIPE T2,NODBLK(T2)	; and retrieve port block pointer from CB block
	IFSKP.			;  -no such port
	  MOVEI T1,[ASCIZ / - no such port opened/]
	  CALL .TSTRG		;    and type error message
	  RETSKP		;     and return
	ENDIF.
	MOVX T1,PB.LEN		;Read all of PB
				; from T2
	XMOVEI T3,NODBLK+CB.LEN	; to just after CB block in NODBLK
	CALL XPEEKX		;  by way of XPEEK
	IFNSK.			;Fail from XPEEK
	  MOVEI T1,[ASCIZ / - failed to read port block from monitor/]
	  CALL .TSTRG		; and type error message
	  RETSKP		; and return
	ENDIF.
	CALL .TCRLF		;Give a CRLF before typing table
	CALL .TCRLF		; and another one
	MOVE T1,PBBPTR##        ;Get AOBJN pointer to PB table
	CALL TYPBLK		; and write PB to screen
	RETSKP			;Return success to allow a new pass
	SUBTTL TYPHN - Type out LAT's HN Table

;Call:
;	CALL TYPHN
;	  Error return to stop DPY loop
;	Normal return

TYPHN:	MOVX T1,HN.LEN##        ;Read all of the HN block,
	MOVE T2,LAHNDB		; pointer from T2
	XMOVEI T3,NODBLK	; to NODBLK
	CALL XPEEKX		;  by way of XPEEK
	 ERR ?Can't XPEEK HN block
	MOVEI T1,[ASCIZ "LAT's HN block, at address "]
	CALL .TSTRG		;Type out text
	MOVE T1,LAHNDB		;Get address of HN block
	CALL .TXWDW		; and type in halfword format

	CALL .TCRLF		;Give a CRLF before typing table
	CALL .TCRLF		; and another one
	MOVE T1,HNBPTR##        ;Get AOBJN pointer to HN table
	CALL TYPBLK		; and write HN to screen
	RETSKP			;Return success to allow a new pass
	SUBTTL TYPTDB - Read the TDB

;CALL:
;	CALL TYPTDB
;	  Error return to stop DPY display
;	Normal Return

TYPTDB::SAVEAC <P1>		;SAVE P1
	CALL GETTDB		;READ IN THE TDB
	 RET			;FAILED
	MOVEI T1,[ASCIZ/TDB for line /]
	CALL .TSTRG		;HEADER TEXT
	MOVE T1,SCNTTY		;GET THE LINE NUMBER
	CALL .TOCTW		;DISPLAY IT
	MOVEI T1,[ASCIZ/ at address /]
	CALL .TSTRG		;HEADER TEXT
	MOVE T1,NODADR		;GET ADDRESS OF TDB
	CALL .TXWDW		;SHOW IT
	CALL .TCRLF		;<CRLF>
	CALL .TCRLF		;<CRLF>
	MOVE T1,TDBPTR##	;GET AOBJN POINTER TO TDB TABLE
	CALL TYPBLK		; AND WRITE TDB ONTO SCREEN
	RETSKP			;DONE
	SUBTTL GETTDB - Read in a TDB

; GETTDB - Read in a TDB
; CALL:
;	+1 Failed to read TDB
;	+2 Norml return, TDB IN NODBLK

GETTDB::SKIPG T2,SCNTTY		;GET THE TTY NUMBER THE USER GAVE
	 ERR ?TTY number must be specified
	MOVEI T1,1		;NUMBER OF WORDS TO READ
	ADD T2,TTACTL		;GET MONITOR ADDRESS OF TDB FOR THIS LINE
	MOVEI T3,NODADR		;PUT IT IN NODADR
	CALL XPEEKX		;DO THE XPEEK
	 ERR ?Failed to read TTACTL entry
	SKIPG T2,NODADR		;GET ADDRESS OF TDB
	 ERR ?No TTACTL entry for specified TTY
	MOVEI T1,T.LEN		;GET LENGTH OF TDB
	MOVEI T3,NODBLK		;USE NODBLK FOR TDB
	CALL XPEEKX		;DO THE XPEEK
	 ERR ?Failed to read TDB
	RETSKP
	SUBTTL SETSJB - Read the SJB

;Call:
;	CALL SETSJB
;	Returns +1 on error, +2 on success

SETSJB:	MOVE T1,SCNJOB		;GET THE JOB NUMBER THE USER GAVE
	CAMN T1,[-1]		;DID HE GIVE ONE (OR A SPECIAL)?
	  ERR ?Job number must be specified
	MOVEM T1,NODARG+.NDRBJ	;YES - SAVE IT FOR NODE
	MOVEI T1,.NDBSJ		;SET TO READ THE SJB
	MOVEM T1,NODARG+.NDRBT
	MOVEI T1,.NDRDB		;READ IT
	MOVEI T2,NODARG
	NODE
	 ERJMP NODERR		;FAILED - FATAL ERROR
				;SUCCESS - SJB IS IN NODBLK
	CALL GETCHT		;READ CHANNEL TABLE INTO NODCHL
	CALL ENMCHN		;ENUMERATE OPEN CHANNELS FOR USER
	RETSKP			;RETURN SUCCESS

;SUBROUTINE TO GET THE CHANNEL TABLE INTO NODCHL
;COPIES THE TABLE FROM THE SJB IF THAT'S WHERE IT IS
;OTHERWISE, READS THE TABLE FROM THE MONITOR

;ASSUMES THE SJB HAS BEEN READ INTO NODBLK

;RETURNS
;	T1/ LENGTH OF THE CHANNEL TABLE

GETCHT:	LOAD T1,SJCHT,+NODBLK	;GET POINTER TO CHANNEL TABLE
	SUB T1,NODADR		;MAKE IT RELATIVE TO THE START OF THE SJB
	CAILE T1,SJ.LEN		;IS THE TABLE PART OF THE SJB?
	JRST GTCHTR		;NO - GO ASK YOUR MONITOR
	ADDI T1,NODBLK		;YES - POINT TO THE START OF THE TABLE
	LOAD T2,SJCHC,+NODBLK	;GET ITS LENGTH
	MOVNS T2
	HRL T1,T2		;MAKE AN AOBJN POINTER
	MOVEI T2,NODCHL		;GET THE PLACE TO STORE THE TABLE

GTCHT1:	MOVE T3,(T1)		;GET A TABLE ENTRY
	MOVEM T3,(T2)		;SAVE IT
	AOJ T2,
	AOBJN T1,GTCHT1		;LOOP THROUGH ALL THE ENTRIES

GTCHTE:	LOAD T1,SJCHC,+NODBLK	;RETURN THE LENGTH TO THE CALLER
	RET			;DONE

;READ THE CHANNEL TABLE FROM THE MONITOR

GTCHTR:	LOAD T2,SJCHT,+NODBLK	;GET THE ADDRESS OF THE CHANNEL TABLE
	LOAD T1,SJCHC,+NODBLK	;AND ITS LENGTH
	MOVEI T3,NODCHL		;READ IT INTO THE CHANNEL AREA
	CALL XPEEKX
	 MSG < getting channel table>
	MOVEI T1,NODADR		;RESTORE THE NODE BLOCK ADDRESS
	MOVEM T1,NODARG+.NDRBD
	JRST GTCHTE		;FINISH OFF AND RETURN
	SUBTTL	SETSLB - Read the SLB

;Call:
;	CALL SETSLB
;	Returns +1 on error, +2 on success

SETSLB:	SKIPG T1,SCNCHN		;DID USER SPECIFY LEGAL CHANNEL NUMBER?
	 JRST ILLCHN		;NO, BOO
	MOVEM T1,NODARG+.NDRBC	;YES - SAVE IT FOR NODE

	MOVEI T1,.NDBSL		;SET TO READ THE SLB
	MOVEM T1,NODARG+.NDRBT
	MOVE T1,SCNJOB		;FOR THE TARGET JOB NUMBER
	MOVEM T1,NODARG+.NDRBJ
	MOVEI T1,.NDRDB		;READ IT
	MOVEI T2,NODARG
	NODE
	 ERJMP NODERR		;FAILED - FATAL ERROR
	RETSKP			;SUCCESS - SLB IS IN NODBLK
	SUBTTL	SETELB - Read the ELB

;Call:
;	CALL SETELB
;	Returns +1 on error, +2 on success

SETELB:	SKIPG T1,SCNCHN		;DID USER SPECIFY LEGAL CHANNEL NUMBER?
	 JRST ILLCHN		;NO, BOO
	MOVEM T1,NODARG+.NDRBC	;YES - SAVE IT

	MOVEI T1,.NDBEL		;SET TO READ THE ELB
	MOVEM T1,NODARG+.NDRBT
	MOVE T1,SCNJOB		;FOR THE TARGET JOB NUMBER
	MOVEM T1,NODARG+.NDRBJ
	MOVEI T1,.NDRDB		;READ IT
	MOVEI T2,NODARG
	NODE
	 ERJMP NODERR		;FAILED - FATAL ERROR
	RETSKP			;SUCCESS - ELB IS IN NODBLK
	SUBTTL	SETCDB - Read the CTERM DATA BLOCK

;Call:
;	CALL SETCDB
;	Returns +1 on error, +2 on success

SETCDB:	SKIPG T1,SCNTTY		;DID THE USER GIVE A TTY NUMBER
	 JRST ILLTTY		;NO, BOO
	MOVEM T1,NODARG+.NDRBJ	;YES - SAVE IT

	MOVEI T1,.NDBCT		;SET TO READ THE CDB
	MOVEM T1,NODARG+.NDRBT
	MOVEI T1,.NDRDB		;READ IT
	MOVEI T2,NODARG
	NODE
	 ERJMP NODERR		;FAILED - FATAL ERROR
	RETSKP			;SUCCESS - CDB IS IN NODBLK
	SUBTTL	SETRCB - Read the RCB

;Call:
;	CALL SETRCB
;	Returns +1 on error, +2 on success

SETRCB: SAVEAC <P1>
	SKIPE CIRBLK		; Circuit cache set up yet?
	IFSKP.
	  CALL CIRCHE		; No, set it up
	  MSG <No circuit blocks>	  
	ENDIF.
	SKIPE T1,CKTID		; User request a block?
	 JRST SETURQ		; Yes, try to satisfy his request
	MOVE P1,SCNCHN		; Get the relative circuit number
	SOS P1			; Block starts at zero, SCNCHN starts at 1
	CAILE P1,%CIRMX		; Requesting block outside range?
SETRC1:	 JRST [MOVEI P1,1	; Reset to beginning
	       MOVEM P1,SCNCHN
	       SETZ P1,
	       JRST .+1]
	MOVE T2,CIRBLK(P1)	; Get the monitor circuit block address
	JUMPE T2,SETRC1		; If we didn't get one reset to beginning
	JRST SETRDD		; Got one, display it

SETURQ:	MOVNI P1,%CIRMX		; Make pointer to loop though circuit types
	HRLZ P1,P1
SETUR1:	CAME T1,CIRIDB(P1)	; Circuit user asked for?
	 AOBJN P1,SETUR1	; No, try next
	MOVE T2,CIRBLK(P1)	; Get the address
	ADDI P1,1		; Channels start at 1
	HRRZM P1,SCNCHN		; Remember the relative circuit number
	JUMPE T2,NODERR		; **** FIX THIS *****

;T2 points to data in monitor
;P1 is index into circuit block cache

SETRDD:	MOVEM P1,CIRIDX		; Index into circuit block table
	MOVEM T2,LOPCKT		; Save circuit we got for others
	MOVEM T2,NODADR		; For TYPTAD
	MOVEI T1,RC.LEN		; Now read in the data
	MOVEI T3,NODBLK		; Into NODBLK
	CALL XPEEKX
	 JRST NODERR	 	;
	RETSKP			; Got it done
CIRCHE:	SAVEAC <P1>
	MOVNI P1,%CIRMX		; AOBJN pointer for max circuits
	HRLZ P1,P1
	MOVE T1,[.SNPSY]	; Snoop for a symbol value
	MOVE T2,[RADIX50,RTRCBQ] ; SNOOP to get the first circuit block
	MOVE T3,[RADIX50,ROUTER] ; in Router
	SNOOP%
	 ERJMP NODERR		; *** Fix This ******
;T2 now contains the address of the pointer to the first circuit block
	MOVEI T1,1		; Read one word of circuit block address
	MOVEI T3,T2		; Load the word into AC T2
	CALL XPEEKX		; Get the address of a circuit block
	 MSG <Peek for first circuit block failed>
	SKIPN T2		; Any circuits yet?
	 RET			; Return fail
;We now have the address of the circuit block in T2

CIRCH1:	MOVEM T2,CIRBLK(P1)	; Save address
	MOVEI T1,RC.LID		; See which is larger so we read enough in
	CAIG T1,RC.DLB		; Which comes first the line ID
	 MOVEI T1,RC.DLB	;  or the DLB address?
	CAIG T1,RC.AJQ
	 MOVEI T1,RC.AJQ	; AJQ is the largest
	ADDI T1,1		; Read circuit block
	MOVEI T3,NODBLK		; Save data in NODBLK
	CALL XPEEKX		; Read as much of the block as we need
	 MSG <Getting circuit block at CIRCH1>
	MOVEI T2,NODBLK		; Point to circuit block data
	MOVE T1,RC.LID(T2)	; Get the ID
	MOVEM T1,CIRIDB(P1)
	MOVE T3,RC.AJQ(T2)	; Get the queue of adjacencies
	LOAD T1,LIDEV,+T1	; Get the device type
	CAIN T1,LD.NI		; Is this an Ethernet circuit?
	 SETZ T3,		; Yes, then don't save an adjacency address
	MOVEM T3,CIRAJQ(P1)
	MOVE T1,RC.DLB(T2)	; Get DLB address
	MOVEM T1,CIRDLA(P1)
	SKIPE T2,RC.NXT(T2)	; Is there a next?
	 AOBJN P1,CIRCH1	;
	RETSKP
	SUBTTL	SETSPY - Read the table at SCNTAD, length LENGTH

;Call:
;	CALL SETSPY
;	Returns +1 on error, +2 on success

SETSPY::SKIPG T2,SCNTAD		;DID THE USER GIVE A TABLE ADDRESS?
	 JRST ILLTAB		;NO, BOO
	SKIPG T1,LENGTH		;DID THE USER GIVE A TABLE LENGTH?
	 JRST ILLTLN		;NO, BOO


;CALL SUBSPY WITH	T1/ LENGTH OF TABLE
;			T2/ ADDRESS OF TABLE

SUBSPY:	MOVEI T3,NODBLK		;Where to put data
	CALL XPEEKX		;(T1,T2,T3)GET PORT BLK INTO NODBLK AREA
	 MSG <Getting table data for SUBSPY>	 
	RETSKP
	SUBTTL Error Message Routines

;HERE IF NODE JSYS FAILED

NODERR:	SETZM NODERM		;ASSUME THERE WON'T BE A MESSAGE
	HRROI T1,NODERM		;READ THE MONITOR'S ERROR MESSAGE
	MOVE T2,[.FHSLF,,-1]
	MOVSI T3,-^D80
	ERSTR
	 JFCL			;ERROR (PROBABLY AN OLD ERRMES.BIN)
	 JFCL			;NOT ENOUGH ROOM
	MOVEI T1,NODSTG		;OUTPUT THE ERROR MESSAGE
	CALLRET .TSTRG		;AND RETURN TO LET THE CALLER PROCEED

PEKERR:	SETZM NODERM		;ASSUME THERE WON'T BE A MESSAGE
	HRROI T1,NODERM		;READ THE MONITOR'S ERROR MESSAGE
	MOVE T2,[.FHSLF,,-1]
	MOVSI T3,-^D80
	ERSTR
	 JFCL			;ERROR (PROBABLY AN OLD ERRMES.BIN)
	 JFCL			;NOT ENOUGH ROOM
	MOVEI T1,PEKSTG		;OUTPUT THE ERROR MESSAGE
	CALLRET .TSTRG		;AND RETURN TO LET THE CALLER PROCEED

ILLCHN:	MOVEI T1,[ASCIZ /?Channel /]
	CALL ERRSTR
	MOVE T1,SCNCHN		;GET CHANNEL USER REQUESTED
	CALL .TDECD		;TYPE IN DECIMAL
	MOVEI T1,[ASCIZ / is illegal
/]
	CALLRET .TSTRG

ILLTTY:	MOVEI T1,[ASCIZ /?No TTY number was given
/]
	CALLRET .TSTRG

ILLTAB:	MOVEI T1,[ASCIZ /?No table address was given
/]
	CALLRET .TSTRG

ILLTLN:	MOVEI T1,[ASCIZ /?No table length was given
/]
	CALLRET .TSTRG

NORCB:	ERR ?No circuit-id found to match /CIRCUIT switch

	SUBTTL ERRSTR - Type out an error string

;	T1/ Address of error string (ASCIZ)

ERRSTR::PUSH P,T1		;SAVE ERROR MESSAGE ADDRESS
	MOVEI T1,.PRIIN
	CFIBF			;IGNORE REST OF ERRONEOUS TYPIN
	SKIPE TYPDPY		;IN DPY MODE?
	  TTY$ $TTCLR		;HOME UP AND CLEAR SCREEN
	SETZM TYPDPY		;LEAVE DPY MODE
	POP P,T1		;GET ERROR MESSAGE ADDRESS BACK
	CALLRET .TSTRG		;TELL SCAN TO TYPE IT OUT NOW

RSKP:
CPOPJ1:	AOS (P)			;SUCCESS RETURN
CPOPJ:	RET
	SUBTTL	UTILITY OUTPUT SUBROUTINES

;SUBROUTINE TO TYPE THE JOB NUMBER OR SPECIAL NAME

TYPJOB:	SKIPGE T1,SCNJOB	;IS IT SPECIAL?
	JRST TYPJSP		;YES - HANDLE SEPARATELY
	MOVEI T1,[ASCIZ /Job /] ;NO - OUTPUT THE JOB NUMBER
	CALL .TSTRG
	MOVE T1,SCNJOB		;TYPE THE JOB NUMBER THE USER GAVE
	CALLRET .TDECD		;AND RETURN

TYPJSP:	CAMN T1,[ASCIZ /NRT/]	;OUTPUT FOR NRT?
	MOVEI T1,SCNJOB		;YES - SET UP ADDRESS OF STRING
	CAMN T1,[ASCIZ /CTM/]	;OUTPUT FOR CTERM?
	MOVEI T1,[ASCIZ /CTERM/] ;YES - SET UP ADDRESS OF LONGER STRING
	CALLRET .TSTRG		;OUTPUT THE STRING AND RETURN

;SUBROUTINE TO OUTPUT THE CHANNEL NUMBER AND SKIP A LINE
;CALL AFTER TYPJOB FOR THOSE THINGS THAT DEPEND ON THE CHANNEL

TYPCHL:	MOVEI T1,[ASCIZ /, channel /]
	CALL .TSTRG
	MOVE T1,SCNCHN
	CALLRET .TDECD		;TYPE IN DECIMAL, WITH DECIMAL POINT; RETURN

;SUBROUTINE TO OUTPUT THE TTY NUMBER

TYPTTN:	MOVE T1,SCNTTY		;OUTPUT THE TTY NUMBER
	CALLRET .TTTY		;AND RETURN

;SUBROUTINE TO OUTPUT THE ADDRESS OF THE TABLE BEING OUTPUT

TYPTAD::MOVEI T1,[ASCIZ / - Table address: /]
	CALL .TSTRG
	MOVE T1,NODADR
	CALL .TXWDW		; TYPE AS TWO HALF-WORDS
	CALL .TTABC
	MOVEI T1,[ASCIZ /  Uptime: /]
	CALL .TSTRG
	TIME%			; Get the uptime in milliseconds
	CALL .TTIME
	CALL .TCRLF		; SKIP A LINE
	CALLRET .TCRLF		; AND RETURN


TYPADR:	MOVEI T1,[ASCIZ / - Table address: /]
	CALL .TSTRG
	MOVE T1,NODADR
	CALL .TXWDW		; TYPE AS TWO HALF-WORDS
	CALL .TCRLF
	CALLRET .TCRLF		; AND RETURN
	SUBTTL ENMCHN - Type out which channels are in use

;Call:
;	T1/ Number of channel slots in use
;	CALL ENMCHN
;	  Error Return
;	Normal Return, no value

ENMCHN:	SAVEAC <P1,P2>
	MOVEI P1,NODCHL		;GET ADDRESS OF CHANNEL TABLE
	MOVE P2,T1		;Keep number of channels for a sec
	MOVNS T1		;NEGATE THE SLOT COUNT
	HRL P1,T1		;MAKE AN AOBJN POINTER

	CALL TYPJOB		;OUTPUT THE JOB NUMBER OR SPECIAL
	MOVEI T1,[ASCIZ / has the following channels open: /]
	CALL .TSTRG
	CAILE P2,^D10		;If more than ten put them on a separate line
	 CALL .TCRLF
	SETZ P2,		;FIRST CHANNEL NUMBER IS 1
ENMBL2:	AOS T1,P2		;INCREMENT USER'S CHANNEL NUMBER
	SKIPN (P1)		;IS THIS SLOT IN USE?
	JRST ENMBL3		;NO
	CALL .TDECW		;YES, TYPE OUT ITS NUMBER FROM T1
	CALL .TSPAC		;SEPARATE WITH A SPACE
ENMBL3:	AOBJN P1,ENMBL2		;TRY THE NEXT
	CALLRET .TCRLF		;THAT'S ALL
	SUBTTL TYPBLK - Type out a data block

;Call:	T1/ AOBJN Pointer to the DOBLK table for this block type
;	(The block to be typed is at NODBLK)
;	CALL TYPBLK
;	Always returns +1

TABCOM==^D24	;COLUMN POSITION AT WHICH TO START THE COMMENT
TABSPY==^D40	;SECOND COLUMN FOR GENERIC TABLE
TABINT==^D20	;LENGTH OF A TAB, FOR NO-COMMENT CASE
TABNUM==3	;NUMBER OF COLUMNS ON THE SCREEN - 1

TYPBLK::SAVEAC <P1,P2>
	HRRZ P1,T1		;POINTER TO DESCRIPTOR TABLES TABLE
	HLLZ P2,T1		;AOBJN POINTER TO INDEX THRU TABLES

;Note that the DOBLK macro (above) depends on P2 being set up here

TYPBL1:	MOVE T1,@DO.NAM(P1)	;GET THE SIXBIT NAME OF ENTRY
	CALL .TSIXN		;TYPE IT OUT
	CALL .TCOLN		;TYPE A COLON
	CALL .TSPAC		;TYPE OUT A SPACE
	MOVE T2,@DO.PTR(P1)	;PASS THE BYTE POINTER IN T2
	HRRI T2,@T2		;RESOLVE INDIRECTION AND EXTRA INDEXING
	TLZ T2,37		;WE RESOLVED IT, LEAVE BYTE PTRS P & S FIELDS
	ADDI T2,NODBLK		;MAKE IT RELATIVE TO THE NODE BLOCK
	LDB T1,T2		;GET THE VALUE TO OUTPUT IN T1

;Call the typeout routine with
;	T1/ Value in Location. Most typeout routines will type this
;	T2/ Byte Ptr to Location; indexing and indirection resolved

	CALL @DO.RTN(P1)	;CALL TYPEOUT ROUTINE
	SKIPG SCNCOM		;DOES THE USER WANT THE COMMENTS?
	JRST TYPBLS		;NO - JUST TAB OVER
	MOVEI T2,TABCOM		;FIND HOW MANY SPACES ARE NEEDED
	SUB T2,COLPOS		; TO GET TO THE TAB COLUMN
	JUMPLE T2,TYPBL2	;IF ALREADY THERE, DONE
	CALL .TSPAC		;ELSE SPACE OVER
	SOJG T2,.-1		;TO THE DESIRED COLUMN
TYPBL2:	MOVE T1,@DO.TXT(P1)	;THEN GET PTR TO THE TEXT STRING (COMMENT)
	CALL .TSTRG		;TYPE IT OUT; CRLF IS INCLUDED IN TEXT

TYPBL3:	AOBJN P2,TYPBL1		;DO THE REST
	RET			;ALL DONE

;MOVE TO THE NEXT TAB. TAB STOPS ARE AT 1, 21, 41, AND 61

;(use tabs .ttabc)

TYPBLS:	SKIPE T2,@DO.STX(P1)	;DOES THE USER WANT ANYTHING SPECIAL?
	JRST TYPBSF		;YES - DO WHAT HE SAYS
	CALL TYPTBB		;NO - TAB OVER OR MOVE TO NEXT LINE
	JRST TYPBL3		;BACK TO THE FLOW

;HERE IF THE MACRO SAYS TO DO SOMETHING (FORCE ONE OR MORE CRLF'S)

TYPBSF:	CALL .TCRLF		;MOVE TO A NEW LINE
	SOJG T2,.-1		;AS MANY TIMES AS THE MACRO WANTS
	JRST TYPBL3		;THEN BACK TO THE FLOW

;SUBROUTINE TO MOVE TO THE NEXT TAB SETTING OR TO THE NEXT LINE

TYPTBB:	MOVE T2,COLPOS		;GET THE COLUMN POSITION
	CAIL T2,TABINT*TABNUM	;PAST THE LAST TAB?
	JRST TYPBB1		;YES - MOVE TO THE NEXT LINE
	SUBI T2,TABINT		;NO - FIND HOW MANY SPACES
	JUMPGE T2,.-1		; ARE NEEDED TO GET TO THE NEXT STOP
	MOVNS T2
	CALL .TSPAC		;OUTPUT THAT MANY SPACES
	SOJG T2,.-1
	RET			;BACK TO THE FLOW

TYPBB1:	CALL .TCRLF		;BEYOND THE LAST TAB - MOVE TO A NEW LINE
	RET			;BACK TO THE FLOW
	SUBTTL TYPTAB - Type out an arbitrary table as octal words

;Also types out the data as decimal, ASCII, and 8-bit ASCII.
;That ought to hold 'em.
;Call:	T1/ Length of the table
;	(The block to be typed is at NODBLK)
;	CALL TYPTAB
;	Always returns +1

TYPTAB:	SAVEAC <P1>
	MOVNS T1		;GET AN AOBJN POINTER TO THE TABLE
	HRLZ P1,T1
TYPTB1:	MOVEI T1,"+"
	CALL .TCHAR
	HRRZ T1,P1		;OUTPUT THE LOCATON OF THE ENTRY
	CALL .TOCTW		;TYPE IT OUT
	CALL .TCOLN		;TYPE A COLON
	CALL .TSPAC		;TYPE OUT A SPACE
	HRRZ T1,P1
        CAIGE T1,100		;IS LOCATION ONE OR TWO DIGITS?
	CALL .TSPAC		;YES - TYPE OUT ANOTHER SPACE
	HRRZ T1,P1
	CAIGE T1,10		;IS LOCATION ONE DIGIT?
	CALL .TSPAC		;YES - TYPE OUT ANOTHER SPACE
	MOVE T1,NODBLK(P1)	;GET THE VALUE
	CALL .TXWDW		;OUTPUT IT IN OCTAL
	CALL TYPTBB		;TAB OVER
	MOVE T1,NODBLK(P1)	;GET THE VALUE
	CALL .TDECD		;OUTPUT IT IN DECIMAL
	CALL TYPTBB		;TAB OVER
	MOVE T1,NODBLK(P1)	;GET THE VALUE
	CALL .TCHR8		;OUTPUT IT IN 8-BIT ASCII
	CALL TYPTBB		;TAB OVER
	MOVE T1,NODBLK(P1)	;GET THE VALUE
	TLNE T1,-1		;IS THERE ANYTHING IN THE LEFT HALF?
	CALL .TCHRS		;YES - OUTPUT IT IN ASCII
	CALL .TCRLF		;MOVE TO THE NEXT LINE
	AOBJN P1,TYPTB1		;LOOP THOUGH ALL THE ITEMS
	RET			;ALL DONE
	SUBTTL TYPMTB - Type out a memeory request table as decimal half words

;Call:	T1/ Length of the table
;	(The block to be typed is at NODBLK)
;	CALL TYPMTB
;	Always returns +1

TYPMTB:	SAVEAC <P1,P2>
	MOVNS T1		;Get an AOBJN pointer to the table
	HRLZ P1,T1
TYPMT1:	SKIPN NODBLK(P1)	;Any data?
	 JRST TYPMT2		; No, check next location
	MOVE P2,SCNTAD		; Start address
	SUB P2,MAPADR		;  Minus current
	ADDI P2,(P1)		;   Plus offset into current block
	CAIG P2,^D9		;Less than 2 digits
	CALL .TSPAC
        CAIG P2,^D99		;Is memory addr less than 3 digits
	CALL .TSPAC		;Yes - type out another space
	CAIG P2,^D999		;Less than 4 digits
	CALL .TSPAC		;
	MOVE T1,P2
	CALL .TDECD		; Type that!
	HLRZ P2,NODBLK(P1)	; Get the high water mark
	CALL TYPTBL
	HRRZ P2,NODBLK(P1)	;  and now the current
	CALL TYPTBL
	CALL .TCRLF		;Move to the next line
TYPMT2:	AOBJN P1,TYPMT1		;Loop though all the items
	RET			;All done

TYPTBL:	CALL .TTABC		; Tab
	CALL .TSPAC
	CALL .TSPAC
	CALL .TSPAC
	CAIG P2,^D9		; Less than 2 digits?
	CALL .TSPAC		; Yes, then pad with a space
	MOVE T1,P2
	CALL .TDECD
	RET
;Call:	T1/ value
;	CALL .TBOOL
;	Normal Return

.TBOOL::TRNN T1,1		    ;TRUE?
	 SKIPA T1,[[ASCIZ /false/]] ;NO
	  MOVEI T1,[ASCIZ /true/]   ;YES
	CALLRET .TSTRG

;Call:	T1/ TTY number
;	CALL .TTTY
;	Normal Return

.TTTY::	PUSH P,T1		;SAVE THE TTY NUMBER
	MOVEI T1,[ASCIZ /TTY/]	;OUTPUT THE FACT THAT IT'S A TTY
	CALL .TSTRG
	POP P,T1		;GET THE TTY NUMBER BACK
	CALLRET .TOCTW		;OUTPUT IT AND RETURN

;Subroutine to output the character(s) left justified in T1
; or the single character, right justified
;Control characters are converted to up-arrow format
;If the string is 0, outputs nothing

;Call:	T1/ String (Note: NOT a pointer)
;	CALL .TCHRS
;	Normal Return

.TCHRS::SKIPN T2,T1		;PUT ENTIRE STRING IN SAFE PLACE - ANYTHING?
	RET			;NO - TYPE NOTHING
	TDNN T2,[-1,,777600]	;YES - IS THERE ONLY ONE CHARACTER?
	JRST .TCHAR		;YES - OUTPUT IT AND RETURN
	TLNN T2,-1		;NO - IS THERE ANYTHING IN THE LEFT HALF?
	RET			;NO - TYPE NOTHING
TCHR1A:	SETZ T1,		;CLEAR THE TARGET
	ROTC T1,7		;GET A CHARACTER
	CAIGE T1," "		;IS IT A CONTROL CHARACTER?
	CALL TCHRC		;YES - START IT WITH AN ARROW
	CALL .TCHAR		;OUTPUT THE CHARACTER
	JUMPN T2,TCHR1A		;LOOP IF THERE'S MORE TO DO
	RET			;ELSE DONE

TCHRC::	PUSH P,T1		;SAVE THE CHARACTER
	MOVEI T1,"^"		;START IT WITH AN UP-ARROW
	CALL .TCHAR
	POP P,T1		;GET THE CHARACTER BACK
	ADDI T1,"@"		;CONVERT IT TO PRINTING ASCII
	RET			;AND RETURN TO OUTPUT IT

;Subroutine to output a word in 8-bit ASCII
;Control characters are converted to up-arrow format
;If the string is 0, outputs nothing

;Call:	T1/ String (Note: NOT a pointer)
;	CALL .TCHR8
;	Normal Return

.TCHR8::SKIPN T2,T1		;PUT ENTIRE STRING IN SAFE PLACE - ANYTHING?
	RET			;NO - TYPE NOTHING
TCHR81:	SETZ T1,		;CLEAR THE TARGET
	ROTC T1,10		;GET A CHARACTER
	CAIGE T1," "		;IS IT A CONTROL CHARACTER?
	CALL TCHRC		;YES - START IT WITH AN ARROW
	CALL .TCHAR		;OUTPUT THE CHARACTER
	JUMPN T2,TCHR81		;LOOP IF THERE'S MORE TO DO
	RET			;ELSE DONE

;Call:	T1/ value
;	CALL .TDECD
;	Normal Return

.TDECD::CALL .TDECW		;TYPE T1 IN DECIMAL
	MOVEI T1,"."		;LOAD UP A DECIMAL POINT
	CALLRET .TCHAR		;FOLLOWED BY A DECIMAL POINT


;Call:	T1/ Circuit ID
;	CALL .TCKT
;	Normal Return

.TCKT::	SAVEAC <P1>
	MOVE P1,T1		;PRESERVE CIRCUIT-ID
	LOAD T1,LIDEV,+P1	;GET THE DEVICE TYPE RIGHT JUSTIFIED
	CAIL T1,0		;IS THE DEVICE TYPE WITHIN RANGE?
	CAILE T1,DEVTLN
	JRST [MOVE T1,P1	;NO - JUST OUTPUT IT IN OCTAL
	      JRST .TOCTW]
	MOVE T1,DEVTAB(T1)	;GET THE NAME OF THE DEVICE
	CALL .TSIXN		;TYPE IT OUT
	MOVEI T1,"-"		;TYPE THE "-"
	CALL .TCHAR
	LOAD T1,LIKON,+P1	;NOW GET THE CONTROLLER (CPU) NUMBER
	CALL .TOCTW		;TYPE IT OUT
	MOVEI T1,"-"		;TYPE THE "-"
	CALL .TCHAR
	LOAD T1,LIUNI,+P1	;AND LAST DO THE UNIT NUMBER
	CALL .TOCTW		;TYPE IT AND RETURN
	LOAD T1,LIDEV,+P1	;GET DEVICE TYPE
	CAXE T1,LD.CIP		;IS THIS A CI DEVICE?
	RET			;NO
	MOVEI T1,"."		;YES, TYPE
	CALL .TCHAR		; A DOT
	LOAD T1,LIDRP,+P1	;LOAD THE DROP NUMBER (PORT ON THE CI)
	CALLRET .TDECW##	;TYPE IT IN DECIMAL AND RETURN TO CALLER
	SUBTTL .SWxxx - Local Switch Value Processors

;Call:	CALL .SWLIN
;	Normal return
;Returns nothing

;The following is the definition of the Line-ID that router maps into
;a line block address.  This is used by Network Management to set lines
;into loopback, etc.

.SWCKT:	SAVEAC <P1,P2>
	SETZ P2,		;CLEAR TARGET
	CALL .SIXSW		;GET THE DEVICE NAME
	MOVSI T3,-DEVTLN	;SET UP FOR DEVICE NAME SEARCH
SWCKT1:	CAMN N,DEVTAB(T3)	;IS THIS THE RIGHT DEVICE?
	JRST SWCKT2		;YES, GO DO THE REST
	AOBJN T3,SWCKT1		;NO, CHECK THE NEXT ONE
SWCKTE:	SETZB T1,CKTID		;RETURN AN ILLEGAL CIRCUIT-ID
	POPJ P,			; TO CALLER

SWCKT2:	STOR T3,LIDEV,+P2	;PUT THE DEVICE TYPE IN THE RIGHT FIELD
	CAIE C,"-"		;WAS IT A LEGAL SEPARATOR?
	JRST SWCKTE		;NO - GIVE THE ERROR RETURN
	CALL .OCTNW		;GET THE CONTROLLER (CPU) NUMBER
	STOR N,LIKON,+P2	;STORE IT
	CAIE C,"-"		;WAS IT THE SEPARATOR?
	JRST SWCKTE		;NO - GIVE THE ERROR RETURN
	CALL RDOCT		;GET THE UNIT NUMBER
	STOR N,LIUNI,+P2	;STORE IT
	LOAD T1,LIDEV,+P2	;Get device type again
	CAXE T1,LD.CIP		;Is it CI?
	IFSKP.			; -yes, pick up a drop #
	  CAIE C,"."		;  Was "." there?
	  JRST SWCKTE		;  -no, give error return
	  CALL .DECNW		;  Get the drop #
	  STOR N,LIDRP,+P2	;  and store it
	ENDIF.
	MOVE T1,P2		;ALSO RETURN IN T1
	MOVEM T1,CKTID		;SAVE THE CIRCUIT-ID
	SKIPN CIRBLK		; Circuit cache set up yet?
	 CALL CIRCHE		; Set up circuit data base
	  TRN
	POPJ P,			; AND RETURN

DEVTAB:	SIXBIT /TST/		;TEST BED DRIVER (IPCF OR KDP)
	SIXBIT /DTE/		;DTE
	SIXBIT /KDP/		;KDP
	SIXBIT /DDP/		;DDP
	SIXBIT /CI/		;CI
	SIXBIT /NI/		;NI
	SIXBIT /DMR/		;DMR
DEVTLN==.-DEVTAB

;RDOCT - read an octal # without accepting a decimal point. (Couldnt use
; .OCTNW in .SWCKT since it read the drop dot as part of the previous number)
;
;Return value in N, next character in C
RDOCT:	SETZ N,			;No value yet
	DO.			;LOOP
	  CALL .TICHR		;  Read next character into C
	  CAIL C,"0"		;  Between 0
	  CAILE C,"7"		;   and 7?
	  EXIT.			;    -no, get out of loop
	  SUBI C,"0"		;  Make it a value
	  LSH N,3		;  N := N * 8 + C
	  ADD N,C		;  ...
	  LOOP.			;  Loop back
	ENDDO.			;End of loop
	RET			;Return with C and N

;Call:	CALL .SWCTM     CALL .SWNRT
;	Normal return   Normal return
;Returns with no value anywhere

.SWCTM:	SKIPA T1,[ASCII /CTM/]	;FUDGE SCNJOB TO LOOK AT CTERM'S BLOCKS
.SWNRT:	MOVE T1,[ASCII /NRT/]	;FUDGE SCNJOB TO LOOK AT NRT'S BLOCKS
	MOVEM T1,SCNJOB
	RET			;DONE - RETURN NO VALUE TO THE CALLER
;Routine to allocate output spec area

SCNAOT:	OUTSTR	[ASCIZ /?SCAN called for output space?
/]
	RET			;RETURN

;Routine to allocate input spec area

SCNAIN:	OUTSTR	[ASCIZ /?SCAN called for input spec space?
/]
	RET			;RETURN
	SUBTTL	Terminal Handling Routines

;TTYINI - Init the TTY

TTYINI:	MOVE	T1,[GJ%SHT]	;OPEN UP THE TERMINAL FOR OUTPUT
	HRROI	T2,[ASCIZ /TTY:/] ;SO OUTPUT WON'T BE TRANSLATED
	GTJFN
	  HALTF
	HRRZ	T1,T1
	MOVEM	T1,TTYJFN
	MOVE	T2,[10B5+OF%RD+OF%WR]
	OPENF
	  HALTF
	MOVEI	T1,.PRIIN	;READ MODE WORD
	RFMOD
	MOVEM	T2,FMDSAV	;SAVE IT FOR EXIT
	TDZ	T2,[037777,,0020] ;ZERO PAGE LENGTH, WIDTH
	TDO	T2,[200000,,1300] ;TURN ON FORMF, NO-TRANS-OUTPUT BITS
	MOVEM	T2,SPMSAV	;SAVE OUR SETTINGS
	SFMOD			;SET THOSE SETTINGS
	STPAR

	MOVEI	T1,TYOBSZ*4	;SAY THERE'S NOTHING IN THE BUFFER
	MOVEM	T1,TTYOBF
	MOVE	T1,[POINT 8,OBF1]
	MOVEM	T1,TTYBPT
	POPJ	P,		;ALL DONE

;TTYOUC - Output a character to TTY

TTYOUC:	EXCH	T1,(P)		;GET THE CHAR, SAVE T1
	JUMPL	T1,TTYOU2	;JUMP IF SIGNAL FOR LAST - IGNORE IT & RETURN
TTYOU1:	SOSG	TTYOBF		;COUNT OUT THE NEXT CHARACTER
	JRST	[PUSH  P,T1
		 PUSHJ P,TTYFRC	;IF NO ROOM, FORCE OUT CURRENT BUFFER
		 POP   P,T1
		 JRST  TTYOU1]	;  AND TRY AGAIN
	IDPB	T1,TTYBPT	;STORE THE CHARACTER
TTYOU2:	POP	P,T1		;RESTORE DPY'S AC
	POPJ	P,		;  AND RETURN

;TTYFRC - Force out the current TTY buffer

TTYFRC:	PUSH P,T2		;SAVE THE FRAGGED ACS (T1 ALREADY SAVED)
	PUSH P,T3
	SETZ T1,		;MAKE SURE THE BUFFER ENDS WITH A NULL
	IDPB T1,TTYBPT
	MOVE T1,TTYJFN		;OUTPUT THE BUFFER TO THE TERMINAL
	MOVE T2,[POINT 8,OBF1]
	SETZ T3,
	SOUT			;OUTPUT IT
	 ERJMP TTFERR		;ON FAILURE TYPE AN ERROR
	POP P,T3		;RESTORE THOSE SAVED ACS
	POP P,T2
	MOVEI T1,TYOBSZ*4	;SAY THERE'S NOTHING IN THE BUFFER
	MOVEM T1,TTYOBF
	MOVE T1,[POINT 8,OBF1]
	MOVEM T1,TTYBPT
	RET			;DONE

TTFERR:	ERR ? TTY output I/O error.
	HALTF
;TTY output routine called from SCAN's .TCHAR

SCNOUC:	SKIPN	BIGOUT		;USE BIG BUFFER OUTPUT?
	JRST	[PBOUT		;NO, PUSH SCAN'S MSGS OUT NOW
		 RET]
	SKIPN	TYPDPY		;USER WANT DPY MODE?
	JRST	SCNOU1		;NO, OUTPUT STRAIGHT TO TTY

;Here to output a character to DPY package

	PUSH	P,T2		;CALLERS EXPECT ALL ACS TO BE SAVED
	MOVE	T2,LINCNT	;GET CURRENT LINE COUNT
	CAML	T2,LINGOL	;UP TO BEGINNING OF LOGICAL SCREEN YET?
	  CHR$	T1		;YES, TELL DPY
	POP	P,T2		;RESTORE CALLER'S T2
	CAIN	T1,12		;A LINE FEED?
	  AOS	LINCNT		;YES, ONE MORE LINE FEED OVER DAM

	CAIN	T1,11		;WAS IT A TAB?
	PUSHJ	P,SCNOU3	;YES - COUNT IT
	AOS	COLPOS		;BUMP THE CHARACTER POSITION
	CAIN	T1,12		;GOT A LF?
	SETZM	COLPOS		;YES - SET BACK TO COLUMN 1
	RET			;RETURN TO SCAN

SCNOU3:	MOVEI	T1,7		;GOT A TAB - COUNT IT IN THE COLUMN POSITION
	ORM	T1,COLPOS
	RET

SCNOU1:	SOSG	TTYOBF		;COUNT OUT NEXT CHARACTER
	JRST	[PUSH  P,T1
		 PUSHJ P,TTYFRC	;IF NO ROOM, FORCE OUT CURRENT BUFFER
		 POP   P,T1
		 JRST  SCNOU1]	;  AND TRY AGAIN
	IDPB	T1,TTYBPT	;STORE CHARACTER
	POPJ	P,		;  AND RETURN
	SUBTTL	End of Subprogram

	PRGEND	DCNSPY
	TITLE SPYDCN -- One of several Block Description Subprograms

;This and following modules are separate programs so that they can build
;tables based on different universals which contain conflicting symbols.

;All SPYxxx modules search these:
	SEARCH MACSYM
	SEARCH DCNSPY

;The following universals are searched for symbols in the xxxMAC tables:
	SEARCH D36PAR,SCPAR,CTERMD

;And now glue the various subprograms together:

	EXTERN .TTTY, .TBOOL, .TDECD, .TDECW, .TSIXN, .TOCTW, .TXWDW, ERRSTR
	EXTERN .TSPAC, .TTABC
	SUBTTL Block Description Tables -- SJB

;Session Control Job Block

DEFINE SJBMAC,<
ENTRY. SJ,NXT,,.TXWDW,0,<NEXT JOB BLOCK IN SYSTEM>
ENTRY. SJ,CHT,,.TXWDW,0,<PTR TO SLB TABLE (INDEXED BY CHANNEL)>
ENTRY. SJ,CHC,,.TDECD,0,<COUNT OF SPACES ALLOCATED IN SLB TABLE>
ENTRY. SJ,PSJ,,.TXWDW,0,<POINTER TO SYSTEM'S POINTER TO THE SJB>
ENTRY. SJ,BLK,,.TBOOL,0,<USER IS PRVJ PRIVILEGED>
ENTRY. SJ,RST,,.TBOOL,0,<RESET IN PROGRESS>
ENTRY. SJ,FRK,,.TDECD,0,<JOB NUMBER>
ENTRY. SJ,CTA,,.TDECD,0,<NUMBER OF CI TIMERS ACTIVE FOR JOB>
ENTRY. SJ,TXQ,,.TQUE ,0,<TRANSACTION QUEUE OF NSPSER CALLS>
ENTRY. SJ,PSQ,,.TQUE ,0,<QUEUE OF SLBs WITH PSIs OUTSTANDING>
ENTRY. SJ,GOL,,.TDECD,0,<INPUT DATA REQUEST GOAL>
ENTRY. SJ,INQ,,.TDECD,0,<JOB INPUT QUOTA>
ENTRY. SJ,OTQ,,.TDECD,0,<JOB OUTPUT QUOTA>
ENTRY. SJ,INU,,.TDECD,0,<BUFFERS USED TOWARD INPUT JOB QUOTA>
ENTRY. SJ,OTU,,.TDECD,0,<BUFFERS USED TOWARD OUTPUT JOB QUOTA>
ENTRY. SJ,SAB,,.TXWDW,0,<SA BLOCK POINTER>
ENTRY. SJ,PRT,,.TXWDW,0,<POINTER TO PORT TABLE>
ENTRY. SJ,MXP,,.TDECD,0,<MAXIMUM NUNBER OF PORTS>
>;END OF SJBMAC
DEFINE PRTMAC,<
ENTRY. PT,CON,,.TDECD,0,<USER'S PSI CHANNEL FOR INCOMING CI OR CC>
ENTRY. PT,INT,,.TDECD,0,<USER'S PSI CHANNEL FOR INTERRUPT MESSAGES>
ENTRY. PT,DAT,,.TDECD,0,<USER'S PSI CHANNEL FOR DATA/DISCONNECT>
ENTRY. PT,TYP,,.TPTYP,0,<OPEN TYPE:  0=PASSIVE  1=ACTIVE>
ENTRY. PT,EMI,,.TBOOL,0,<EOM HAS ARRIVED>
ENTRY. PT,PSI,,.TBOOL,0,<USER HAS BEEN "PSI"ED FOR DATA AVAILABLE>
ENTRY. PT,LWC,,.TBOOL,0,<LINK WAS CONNECTED INDICATOR>
ENTRY. PT,BLK,,.TBOOL,0,<"WE BLOCKED" DURING THE CALL TO SCTNSF>
ENTRY. PT,WAK,,.TBOOL,0,<WAKE THE NEXT PROCESS THAT TRIES TO BLOCK>
ENTRY. PT,NRR,,.TBOOL,0,<NULL RECORD RECEIVED.>
ENTRY. PT,JFN,,.TOCTW,0,<JFN ASSOCIATED WITH CHANNEL>
ENTRY. PT,FRK,,.TDECD,0,<FORK NUMBER>
ENTRY. PT,STS,,.TDECD,0,<LINK STATUS>
ENTRY. PT,DEV,,.TXWDW,0,<STORAGE FOR DEV DURING A BLOCK>
>;END OF PRTMAC
DEFINE SLBMAC,<
ENTRY. SL,ASQ,,.TXWDW,0,<NEXT SLB ON ALL SLBs QUEUE>
ENTRY. SL,NXP,,.TXWDW,0,<POINTER TO NEXT SL WITH ACTIVE PSI>
ENTRY. SL,JFQ,,.TXWDW,0,<POINTER TO NEXT SL REQUESTING JIFFY SERVICE>
ENTRY. SL,SLB,,.TXWDW,0,<POINTER TO OURSELVES>
ENTRY. SL,SJB,,.TXWDW,0,<POINTER TO JOB BLOCK>
ENTRY. SL,CHN,,.TDECD,0,<CHANNEL NUMBER>
ENTRY. SL,SOB,,.TDECD,0,<SOURCE OBJECT TYPE>
ENTRY. SL,DOB,,.TDECD,0,<DESTINATION OBJECT TYPE>
ENTRY. SL,CCB,,.TBOOL,0,<CHECK CONNECT BLOCK>
ENTRY. SL,KCB,,.TBOOL,0,<KEEP CONNECT BLOCK FOR LIFE OF LINK>
ENTRY. SL,PSI,,.TBOOL,0,<PSI PENDING FLAG>
ENTRY. SL,PH2,,.TBOOL,0,<PHASE II HAS NO RESEND CAPABILITY>
ENTRY. SL,ABO,,.TBOOL,0,<CLOSE PORT AFTER ABORT & RELEASE>
ENTRY. SL,FSL,,.TBOOL,0,<FREE SLB WHEN DONE WITH ALL PROCESSING>
ENTRY. SL,BSY,,.TBOOL,0,<SLB IS BUSY (CANNOT BE FREED)>
ENTRY. SL,LBC,,.TBOOL,0,<LINK IS BEING CLOSED BY NSP>
ENTRY. SL,JFR,,.TBOOL,0,<JIFFY SERVICE REQUESTED FLAG>
ENTRY. SL,EOM,,.TBOOL,0,< LAST SEGMENT OUTPUT WAS END OF MESSAGE>
ENTRY. SL,STA,,.TSTAS,0,<SESSION CONTROL STATE>
ENTRY. SL,XFL,,.TOCTW,0,<TRANSMIT FLOW CONTROL OPTION>
ENTRY. SL,RFL,,.TOCTW,0,<RECEIVE FLOW CONTROL OPTION>
ENTRY. SL,GOL,,.TDECD,0,<RECEIVE DATA REQUEST GOAL>
ENTRY. SL,INQ,,.TDECD,0,<INPUT QUOTA FOR LINK>
ENTRY. SL,OTQ,,.TDECD,0,<OUTPUT QUOTA FOR LINK>
ENTRY. SL,INU,,.TDECD,0,<INPUT BUFFERS IN USE>
ENTRY. SL,OTU,,.TDECD,0,<OUTPUT BUFFERS IN USE>
ENTRY. SL,SST,,.TOCTW,0,<LINK STATUS WORD>
ENTRY. SL,PSM,,.TOCTW,0,<THE PSI MASK>
ENTRY. SL,DRR,,.TDECD,0,<NORMAL DATA REQUESTS TO RESEND>
ENTRY. SL,RSN,,.TDECD,0,<REASON CODE OF DISCONNECT OR REJECT>
ENTRY. SL,PID,,.TXWDW,0,<NSPpid OF PORT>
ENTRY. SL,DNA,,.TNODE,0,<DESTINATION NODE ADDRESS>
ENTRY. SL,SIZ,,.TDECD,0,<SEGMENT SIZE IN BYTES>
ENTRY. SL,CTM,,.TTIME,0,<CONNECT INITIATE TIMER>
ENTRY. SL,WKA,,.TXWDW,0,<ADDRESS OF WAKEUP ROUTINE>
ENTRY. SL,CDM,,.TXWDW,0,<POINTER TO DIS/CONNECT MESSAGE BLOCK>
ENTRY. SL,CBP,,.TXWDW,0,<POINTER TO CONNECT BLOCK FOR PASSIVE TASK>
ENTRY. SL,OTM,,.TXWDW,0,<Ptr to partially filled output message>
ENTRY. SL,UID,,.TTIME,0,<Stale detection timestamp>
ENTRY. SL,BYS,,.TDECD,0,<Bytes sent>
ENTRY. SL,BYR,,.TDECD,0,<Bytes received>
ENTRY. SL,PKS,,.TDECD,0,<Packets sent>
ENTRY. SL,PKR,,.TDECD,2,<Packets received>

ENTRY. SS,OTH,+SL.NSL,.TBOOL,0,<INDICATES THIS IS "NORMAL" SUB-LINK>
ENTRY. SS,XDO,+SL.NSL,.TDECD,0,<SUBLINK TRANSMIT DRQS OUTSTANDING>
ENTRY. SS,RDO,+SL.NSL,.TDECD,0,<SUBLINK RECEIVE DRQS OUTSTANDING>
ENTRY. SS,INQ,+SL.NSL,.TQUE ,2,<SUBLINK INPUT QUEUE>

ENTRY. SS,OTH,+SL.OSL,.TBOOL,0,<INDICATES THIS IS "OTHER" SUB-LINK>
ENTRY. SS,XDO,+SL.OSL,.TDECD,0,<SUBLINK TRANSMIT DRQS OUTSTANDING>
ENTRY. SS,RDO,+SL.OSL,.TDECD,0,<SUBLINK RECEIVE DRQS OUTSTANDING>
ENTRY. SS,INQ,+SL.OSL,.TQUE ,0,<SUBLINK INPUT QUEUE>
>;END OF SLBMAC
DEFINE ELBMAC,<
ENTRY. EL,APQ,,.TXWDW,0,<NEXT IN QUEUE OF ALL LINK BLOCKS>
ENTRY. EL,HBQ,,.TXWDW,0,<NEXT IN QUEUE OF LINKS IN A HASH BUCKET>
ENTRY. EL,JFQ,,.TXWDW,0,<NEXT IN QUEUE OF LINKS NEEDING JIFFY SERVICE>
ENTRY. EL,OJQ,,.TBOOL,0,<LINK IS ON THE JIFFY-REQUEST QUEUE>
ENTRY. EL,SNC,,.TBOOL,0,<SET IF NOT YET TOLD SC ABOUT NO CONF>
ENTRY. EL,CNF,,.TBOOL,0,<SET IF WE HAVE CONFIDENCE IN LINK>
ENTRY. EL,SCM,,.TBOOL,0,<SEND CONNECT MESSAGE NEXT JIFFY>
ENTRY. EL,SDM,,.TBOOL,0,<SEND DISCONNECT CONFIRM MESSAGE NEXT JIFFY>
ENTRY. EL,ABO,,.TBOOL,0,<ABORTING THIS LOGICAL LINK>
ENTRY. EL,DTO,,.TBOOL,0,<DELAY TIMER IS FOR "OTHER" SUBLINK>
ENTRY. EL,STA,,.TSTAN,0,<NSP STATE OF THIS LINK>
ENTRY. EL,SIZ,,.TDECD,0,<MAX SIZE OF A SEGMENT ON THIS LINK>
ENTRY. EL,LLA,,.TOCTW,0,<LOCAL LINK ADDRESS>
ENTRY. EL,RLA,,.TOCTW,0,<REMOTE LINK ADDRESS>
ENTRY. EL,ORQ,,.TXWDW,0,<FIRST MSG ON OUT-IN-ROUTER QUEUE>
ENTRY. EL,ORQ,,.TQUE, 0,<QUEUE OF MSGS OUT IN ROUTER>
ENTRY. EL,CLC,,.TDECD,0,<COUNT-DOWN FOR CLOSE RETRIES>
ENTRY. EL,ORC,,.TDECD,0,<COUNT OF MSGS OUT IN ROUTER>
ENTRY. EL,VER,,.TDECD,0,<VERSION OF REMOTE NSP, SEE VER3.1,VER3.2>
ENTRY. EL,DSG,,.TXWDW,0,<MSG SEGMENT BEING TIMED FOR DELAY CALC>
ENTRY. EL,DTM,,.TTIME,0,< AND TIME IT WAS FIRST SENT>
ENTRY. EL,NNM,,.TNODE,0,<THE REMOTE'S NODE NUMBER>
ENTRY. EL,NDB,,.TXWDW,0,<PTR TO NSP NODE BLOCK>
ENTRY. EL,TMA,,.TTIME,0,<INACTIVITY TIMER>
ENTRY. EL,SCV,,.TXWDW,0,<SESSION CONTROL CALL VECTOR BASE ADDRESS>
ENTRY. EL,SCB,,.TXWDW,0,<SESSION CONTROL BLOCK ID>
ENTRY. EL,CIM,,.TXWDW,0,<PTR TO (R)CI MESSAGE>
ENTRY. EL,DIM,,.TXWDW,0,<PTR TO DI MESSAGE>
ENTRY. EL,CHK,,.TXWDW,2,<ADDRESS OF THIS EL, FOR ADDR CHECK
>
ENTRY. ES,OTH,+EL.NSL,.TBOOL,0,<FALSE SINCE THIS IS THE "NORMAL" SUBLINK>
ENTRY. ES,ACK,+EL.NSL,.TBOOL,0,<SEND ACK FOR THIS SUBLINK NEXT JIFFY>
ENTRY. ES,NAK,+EL.NSL,.TBOOL,0,<SEND NAK TO PH2 NSP (TURN ACK ON TOO)>
ENTRY. ES,ROF,+EL.NSL,.TBOOL,0,<RECEIVE IS OFF>
ENTRY. ES,ROC,+EL.NSL,.TBOOL,0,<RECEIVE OFF HAS CHANGED>
ENTRY. ES,XOF,+EL.NSL,.TBOOL,0,<XMIT IS OFF>
ENTRY. ES,BFR,+EL.NSL,.TBOOL,0,<REMOTE IS "BUFFER-RICH" ON THIS LINK>
ENTRY. ES,RFL,+EL.NSL,.TOCTW,0,<RECEIVE FLOW CONTROL TYPE>
ENTRY. ES,XFL,+EL.NSL,.TOCTW,0,<XMIT FLOW CONTROL TYPE>
ENTRY. ES,GOL,+EL.NSL,.TDECD,0,<DATA REQUEST GOAL>
ENTRY. ES,CGL,+EL.NSL,.TDECD,0,<AFTER-CONGESTION RECOVERY GOAL>
ENTRY. ES,XLD,+EL.NSL,.TDECD,0,<XMIT DRQS OUTSTANDING TO LOCAL SC>
ENTRY. ES,XRD,+EL.NSL,.TDECD,0,<XMIT DRQS OUTSTANDING TO REMOTE NSP>
ENTRY. ES,XSD,+EL.NSL,.TDECD,0,<XMIT DRQS NEED TO SEND TO SC>
ENTRY. ES,RLD,+EL.NSL,.TDECD,0,<RECEIVE DRQS OUTSTANDING TO LOCAL SC>
ENTRY. ES,RRD,+EL.NSL,.TDECD,0,<RECEIVE DRQS OUTSTANDING TO REMOTE NSP>
ENTRY. ES,RSD,+EL.NSL,.TDECD,0,<RECEIVE DRQS NEED TO SEND TO SC>
ENTRY. ES,LMA,+EL.NSL,.TOCTW,0,<LAST MESSAGE NUMBER ASSIGNED>
ENTRY. ES,LAR,+EL.NSL,.TOCTW,0,<LAST ACK RECEIVED (AND PROCESSED)>
ENTRY. ES,LMR,+EL.NSL,.TOCTW,0,<LAST MESSAGE RECEIVED>
ENTRY. ES,AKQ,+EL.NSL,.TQUE ,0,<QUEUE HEADER FOR THE TO-BE-ACKED Q>
ENTRY. ES,RCQ,+EL.NSL,.TQUE ,0,<QUEUE HEADER FOR THE RECEIVE Q>
ENTRY. ES,XMQ,+EL.NSL,.TQUE ,0,<QUEUE HEADER FOR THE XMIT Q>
ENTRY. ES,CWS,+EL.NSL,.TDECD,0,<Current window size>
ENTRY. ES,CDA,+EL.NSL,.TDECD,2,<# of ACK's since last window change
>
ENTRY. ES,OTH,+EL.OSL,.TBOOL,0,<TRUE SINCE THIS IS THE "OTHER" SUBLINK>
ENTRY. ES,ACK,+EL.OSL,.TBOOL,0,<SEND ACK FOR THIS SUBLINK NEXT JIFFY>
ENTRY. ES,NAK,+EL.NSL,.TBOOL,0,<SEND NAK TO PH2 NSP (TURN ACK ON TOO)>
ENTRY. ES,ROF,+EL.OSL,.TBOOL,0,<RECEIVE IS OFF>
ENTRY. ES,ROC,+EL.OSL,.TBOOL,0,<RECEIVE OFF HAS CHANGED>
ENTRY. ES,XOF,+EL.OSL,.TBOOL,0,<XMIT IS OFF>
ENTRY. ES,BFR,+EL.OSL,.TBOOL,0,<REMOTE IS "BUFFER-RICH" ON THIS LINK>
ENTRY. ES,RFL,+EL.OSL,.TOCTW,0,<RECEIVE FLOW CONTROL TYPE>
ENTRY. ES,XFL,+EL.OSL,.TOCTW,0,<XMIT FLOW CONTROL TYPE>
ENTRY. ES,GOL,+EL.OSL,.TDECD,0,<DATA REQUEST GOAL>
ENTRY. ES,CGL,+EL.OSL,.TDECD,0,<AFTER-CONGESTION RECOVERY GOAL>
ENTRY. ES,XLD,+EL.OSL,.TDECD,0,<XMIT DRQS OUTSTANDING TO LOCAL SC>
ENTRY. ES,XRD,+EL.OSL,.TDECD,0,<XMIT DRQS OUTSTANDING TO REMOTE NSP>
ENTRY. ES,XSD,+EL.OSL,.TDECD,0,<XMIT DRQS NEED TO SEND TO SC>
ENTRY. ES,RLD,+EL.OSL,.TDECD,0,<RECEIVE DRQS OUTSTANDING TO LOCAL SC>
ENTRY. ES,RRD,+EL.OSL,.TDECD,0,<RECEIVE DRQS OUTSTANDING TO REMOTE NSP>
ENTRY. ES,RSD,+EL.OSL,.TDECD,0,<RECEIVE DRQS NEED TO SEND TO SC>
ENTRY. ES,LMA,+EL.OSL,.TOCTW,0,<LAST MESSAGE NUMBER ASSIGNED>
ENTRY. ES,LAR,+EL.OSL,.TOCTW,0,<LAST ACK RECEIVED (AND PROCESSED)>
ENTRY. ES,LMR,+EL.OSL,.TOCTW,0,<LAST MESSAGE RECEIVED>
ENTRY. ES,AKQ,+EL.OSL,.TQUE ,0,<QUEUE HEADER FOR THE TO-BE-ACKED Q>
ENTRY. ES,RCQ,+EL.OSL,.TQUE ,0,<QUEUE HEADER FOR THE RECEIVE Q>
ENTRY. ES,XMQ,+EL.OSL,.TQUE ,0,<QUEUE HEADER FOR THE XMIT Q>
ENTRY. ES,CWS,+EL.OSL,.TDECD,0,<Current window size>
ENTRY. ES,CDA,+EL.OSL,.TDECD,2,<# of ACK's since last window change>
>;END OF ELBMAC
	SUBTTL Block Description Tables -- RCB (Router Circuit Block)

	EXTERN .TCKT            ;Type out Circuit Id from internal format

DEFINE RCBMAC,<

ENTRY. RC,NXT,,.TXWDW,0,<Pointer to next circuit block>
ENTRY. RC,LID,,.TCKT, 0,<Circuit ID>
ENTRY. RC,DLB,,.TXWDW,0,<Data link block address>
ENTRY. RC,AJQ,,.TXWDW,0,<Head of queue of adjacencies>
ENTRY. RC,AJQ,,.TQUE, 0,<Count of adjacencies belonging to this circuit>
ENTRY. RC,BCT,,.TBOOL,0,<Broadcast circuit (should be bit 0)>
ENTRY. RC,SRM,,.TBOOL,0,<Send routing message flag>
ENTRY. RC,EBU,,.TBOOL,0,<Emergency buffer is in use>
ENTRY. RC,SHM,,.TBOOL,0,<Send hello message>
ENTRY. RC,DSR,,.TBOOL,0,<We are the designated router (NI only)>
ENTRY. RC,STA,,.TSTAR,0,<Circuit state>
ENTRY. RC,CST,,.TDECD,0,<Circuit cost>
ENTRY. RC,DRT,,.TDECD,0,<Time before we assume DSR role>
ENTRY. RC,TLS,,.TTIME,0,<Time last message of any type was sent>
ENTRY. RC,TLR,,.TTIME,0,<Time last routing message was sent>
ENTRY. RC,TLH,,.TTIME,0,<Time we sent the last hello (NI only)>
ENTRY. RC,TIN,,.TTIME,0,<Time we got protocol up from controller>
ENTRY. RC,TM3,,.TTMRD,0,<Hello message timer>
ENTRY. RC,BSZ,,.TDECD,0,<Maximum block size>
ENTRY. RC,RBS,,.TDECD,0,<Receive block size for this circuit>
ENTRY. RC,PRI,,.TDECD,0,<Our priority to be designated router (NI only)>
ENTRY. RC,MXR,,.TDECD,0,<Maximum routers on this circuit>
ENTRY. RC,NRO,,.TDECD,0,<Number of routers online>
ENTRY. RC,DSH,,.TXWDW,0,<ID of current designated router (NI only)>
ENTRY. RC,DSL,,.TXWDW,0,<Second half of router ID>
IFN FTMP,<
ENTRY. RC,JSQ,,.TQUE, 0,<Queue header for jiffy resend queue>
>
ENTRY. RC,CMQ,,.TDECD,0,<Messages queued for output on this circuit>
ENTRY. RC,CLC,,.TDECD,0,<Number of local messages transmitted>
ENTRY. RC,SLZ,,.TTIME,0,<   (0) Time stamp of when last zeroed>
ENTRY. RC,CAP,,.TDECD,0,< (800) Arriving packets received (to NSP)>
ENTRY. RC,CDP,,.TDECD,0,< (801) Departing packets sent (from NSP)>
ENTRY. RC,CAL,,.TDECD,0,< (802) Arriving congestion loss (to NSP)>
ENTRY. RC,CTR,,.TDECD,0,< (810) Transit packets received>
ENTRY. RC,CTS,,.TDECD,0,< (811) Transit packets sent>
ENTRY. RC,CTL,,.TDECD,0,< (812) Transit congestion loss>
ENTRY. RC,CCD,,.TDECD,0,< (820) Circuit down events>
ENTRY. RC,AJD,,.TDECD,0,<       Adjacency down>
ENTRY. RC,CIF,,.TDECD,0,< (821) Initialization failures>
ENTRY. RC,BSX,,.TDECD,0,<(xxxx) Adjacency block size exceeded /output>
>	;End RCBMAC
	SUBTTL Block Description Tables -- AJB (Adjacency Block)

DEFINE AJBMAC,<
ENTRY. AJ,NXT,,.TXWDW,0,<Pointer to next adjacency block>
ENTRY. AJ,STA,,.TSTAA,0,<Adjacency state>
ENTRY. AJ,NTY,,.TAJTY,0,<Neighbor node type>
ENTRY. AJ,PH4,,.TBOOL,0,<Adjacency is Phase IV>
ENTRY. AJ,VRQ,,.TBOOL,0,<Verification required from remote>
ENTRY. AJ,BLO,,.TBOOL,0,<Blocking is requested by this node>
ENTRY. AJ,RJF,,.TBOOL,0,<Reject flag>
ENTRY. AJ,MTA,,.TBOOL,0,<No multi-cast traffic accepted>
ENTRY. AJ,VER,,.TOCTW,0,<Version of neighbor's router>
ENTRY. AJ,ECO,,.TOCTW,0,<ECO number of neighbor's router>
ENTRY. AJ,CUS,,.TOCTW,0,<Customer version of neighbor's router>
ENTRY. AJ,NAH,,.TXWDW,0,<Hi-order NI address>
ENTRY. AJ,NAL,,.TXWDW,0,<Lo-order NI string format>
ENTRY. AJ,NAA,,.TNODE,0,<Adjacency's node area>
ENTRY. AJ,NAN,,.TNODE,0,<Adjacency's node number>
ENTRY. AJ,RTV,,.TXWDW,0,<Pointer to this adjacencies routing vector>
ENTRY. AJ,CBP,,.TXWDW,0,<Circuit block pointer for this adjacency>
ENTRY. AJ,BSZ,,.TDECD,0,<Block size requested by neighbor>
ENTRY. AJ,NHT,,.TTMRD,0,<Neighbors hello timer>
ENTRY. AJ,TLR,,.TTIME,0,<Time last message received from neighbor>
ENTRY. AJ,PRI,,.TDECD,0,<Adjacent router's priority to be designated router>
ENTRY. AJ,ARE,,.TDECD,0,<Adjacent routers area>
ENTRY. AJ,MPD,,.TOCTW,0,<MPD (reserved)>
>;END OF AJBMAC
	SUBTTL Block Description Tables -- DL (Data Link Block)

DEFINE DLBMAC,<
ENTRY. DL,NXT,,.TXWDW,0,<Link to next data link block>
ENTRY. DL,UID,,.TXWDW,0,<ID supplied by DNADLL user>
ENTRY. DL,DID,,.TCKT,0,<Device ID>
ENTRY. DL,RUN,,.TBOOL,0,<Data link is running>
ENTRY. DL,EBU,,.TBOOL,0,<Emergency buffer in use>
ENTRY. DL,LIU,,.TBOOL,0,<Line in use by circuit>
ENTRY. DL,KNO,,.TOCTW,0,<Kontroller number (DTE only)>
ENTRY. DL,UNB,,.TXWDW,0,<Pointer to the User-NI block>
ENTRY. DL,PID,,.TXWDW,0,<Portal ID>
ENTRY. DL,LTP,,.TXWDW,0,<Line table pointer>
ENTRY. DL,SLZ,,.TDECW,0,<(0) Seconds since last zeroed>
ENTRY. DL,BYR,,.TDECW,0,<(1000) Total bytes received>
ENTRY. DL,BYS,,.TDECW,0,<(1001) Total bytes sent>
ENTRY. DL,DBR,,.TDECW,0,<(1010) Total data blocks received>
ENTRY. DL,DBS,,.TDECW,0,<(1011) Total data blocks sent>
ENTRY. DL,UBU,,.TDECW,0,<(1065) User buffer unavailable>
>;End of DLBMAC
DEFINE LTBMAC,<
ENTRY. LT,LID,,.TCKT,0,<Line ID>
ENTRY. LT,DVE,,.TBOOL,0,<Driver believes device is present>
ENTRY. LT,STA,,.TSTAL,0,< State of line>
ENTRY. LT,CON,,.TDECW,0,<Controller (normal/loopback)>
ENTRY. LT,PRO,,.TDECW,0,<Protocol type>
ENTRY. LT,CTY,,.TDECW,0,<Circuit type>
ENTRY. LT,DBF,,.TDECW,0,<Default number of buffers>
ENTRY. LT,BNO,,.TDECW,0,<Number of buffers to post>
ENTRY. LT,NBP,,.TDECW,0,<Number of buffers posted>

>  ;End of LTBMAC
	SUBTTL Block Description Tables -- MB (Message Block)

DEFINE MBBMAC,<
ENTRY. MB,NXT,,.TXWDW,0,<PTR TO NEXT MESSAGE>
ENTRY. MB,FMS,,.TXWDW,0,<POINTER TO FIRST MSD>
ENTRY. MB,MSN,,.TXWDW,0,<DDCMP MESSAGE NUMBER>
ENTRY. MB,DST,,.TNODE,0,<DESTINATION NODE>
ENTRY. MB,SRC,,.TNODE,0,<SOURCE NODE>
ENTRY. MB,DS1,,.TXWDW,0,< FIRST 32 BITS OF DESTINATION>
ENTRY. MB,SR1,,.TXWDW,0,< FIRST 32 BITS OF SOURCE>
ENTRY. MB,OTH,,.TBOOL,0,<ON THE "OTHER" SUBLINK>
ENTRY. MB,BOM,,.TBOOL,0,<BEGINNING OF MESSAGE>
ENTRY. MB,EOM,,.TBOOL,0,<END OF MESSAGE>
ENTRY. MB,EBF,,.TBOOL,0,<EMERGENCY MESSAGE BLOCK >
ENTRY. MB,PH2,,.TBOOL,0,<PHASE II MESSAGE>
ENTRY. MB,DON,,.TBOOL,0,<"SYNCHRONOUS" INTERLOCK DONE BIT (NSP & SC)>
ENTRY. MB,LCL,,.TBOOL,0,<BOUND FOR THE LOCAL NSP>
ENTRY. MB,UNR,,.TBOOL,0,<UNREACHABLE>
ENTRY. MB,CHN,,.TXWDW,0,<LOOPBACK CHANNEL (CIRCUIT ID)>
ENTRY. MB,PRC,,.TXWDW,0,<PROCEDURE PROCESSOR (NSP & SC)>
ENTRY. MB,AR1,,.TXWDW,0,<ARGUMENT STORAGE #1 (NSP & SC)>
ENTRY. MB,AR2,,.TXWDW,0,<ARGUMENT STORAGE #2 (NSP & SC)>
ENTRY. MB,AR3,,.TXWDW,2,<ARGUMENT STORAGE #3 (NSP & SC)>

ENTRY. RM,OCP,,.TXWDW,0,<OUTPUT CIRCUIT BLK POINTER>
ENTRY. RM,ICP,,.TXWDW,0,<INPUT CIRCUIT BLK POINTER>
ENTRY. RM,OAP,,.TXWDW,0,<OUTPUT ADJACENCY POINTER>
ENTRY. RM,IAP,,.TXWDW,0,<INPUT ADJACENCY POINTER>
ENTRY. RM,FST,,.TDECD,0,<FIRST BYTE IN MESSAGE>
ENTRY. RM,MZ1,,.TBOOL,0,<MBZ>
ENTRY. RM,EVL,,.TBOOL,0,<EVOLUTION BIT (RESERVED)>
ENTRY. RM,MZ2,,.TBOOL,0,<MBZ (III)/INTRA-NI PACKET (IV NI)>
ENTRY. RM,RTS,,.TBOOL,0,<BEING RETURNED TO SENDER>
ENTRY. RM,RQR,,.TBOOL,0,<RETURN REQUESTED (RESERVED)>
ENTRY. RM,MZ3,,.TBOOL,0,<ALARM BIT (DIRECT FROM ENDNODE)>
ENTRY. RM,MB1,,.TBOOL,0,<MUST BE ONE>
ENTRY. RM,CTL,,.TBOOL,0,<CONTROL MESSAGE (NOT DATA)>
ENTRY. RM,CTY,,.TOCTW,0,< CONTROL MESSAGE TYPE>
ENTRY. RM,ODN,,.TBOOL,0,< DON'T ODN THIS MESSAGE>
ENTRY. RM,PH2,,.TBOOL,0,<MESSAGE SEEMS TO BE PHASE II>
ENTRY. RM,TRY,,.TBOOL,0,<NSP wants Router to "TRYHARD" on the NI>
ENTRY. RM,MK1,,.TXWDW,0,<FIRST MARK>
ENTRY. RM,MK2,,.TXWDW,1,<SECOND MARK>

ENTRY. MD,NXT,+RM.MSD,.TXWDW,0,<MUST BE ZERO        ;PTR TO NEXT MSD>
ENTRY. MD,PTR,+RM.MSD,.TXWDW,0,<ILDB PTR INTO MSG   ;IDPB PTR INTO MSG>
ENTRY. MD,AUX,+RM.MSD,.TXWDW,0,<NOT USED            ;ILDB PTR TO BEG OF MSG>
ENTRY. MD,BYT,+RM.MSD,.TDECD,0,<BYTES LEFT TO READ  ;BYTES WRITTEN SO FAR>
ENTRY. MD,VMC,+RM.MSD,.TDECD,0,<VIRTUAL MAP CONTEXT>
ENTRY. MD,ALL,+RM.MSD,.TDECD,0,<ALLOCATED LENGTH IN BYTES>
ENTRY. MD,ALA,+RM.MSD,.TXWDW,2,<ALLOCATED ADDRESS OF SEGMENT'S DATA>

ENTRY. NM,ACK,,.TBOOL,0,<NEEDS TO BE ACKED>
ENTRY. NM,RET,,.TBOOL,0,<RETURN MSG TO Session Control>
ENTRY. NM,SGN,,.TOCTW,0,<MESSAGE SEGMENT NUMBER>
ENTRY. NM,MGF,,.TMGF ,0,<THE MSGFLG FIELD OF THE NSP HEADER>
ENTRY. NM,CNT,,.TDECD,0,<# OF TIMES WE'VE SENT MESSAGE>
ENTRY. NM,TIM,,.TTIME,0,<TIME STAMP>
ENTRY. NM,PRT,,.TXWDW,0,<PTR TO PORT BLOCK>
ENTRY. NM,LLA,,.TOCTW,0,<LOCAL LINK ADDRESS>
ENTRY. NM,RLA,,.TOCTW,0,<REMOTE LINK ADDRESS>
ENTRY. NM,ORQ,,.TXWDW,0,<ORQ queue link>
ENTRY. NM,MAG,,.TXWDW,0,<Magic word for DTESRV, IN OCTAL>
ENTRY. NM,MAG,,.TSIXN,0,<Magic word for DTESRV, IN SIXBIT>
ENTRY. NM,MK1,,.TXWDW,0,<FIRST MARK>
ENTRY. NM,MK2,,.TXWDW,1,<SECOND MARK>

ENTRY. MD,NXT,+NM.MSD,.TXWDW,0,<MUST BE ZERO        ;PTR TO NEXT MSD>
ENTRY. MD,PTR,+NM.MSD,.TXWDW,0,<ILDB PTR INTO MSG   ;IDPB PTR INTO MSG>
ENTRY. MD,AUX,+NM.MSD,.TXWDW,0,<NOT USED            ;ILDB PTR TO BEG OF MSG>
ENTRY. MD,BYT,+NM.MSD,.TDECD,0,<BYTES LEFT TO READ  ;BYTES WRITTEN SO FAR>
ENTRY. MD,VMC,+NM.MSD,.TDECD,0,<VIRTUAL MAP CONTEXT>
ENTRY. MD,ALL,+NM.MSD,.TDECD,0,<ALLOCATED LENGTH IN BYTES>
ENTRY. MD,ALA,+NM.MSD,.TXWDW,2,<ALLOCATED ADDRESS OF SEGMENT'S DATA>

ENTRY. MD,NXT,+UD.MSD,.TXWDW,0,<MUST BE ZERO        ;PTR TO NEXT MSD>
ENTRY. MD,PTR,+UD.MSD,.TXWDW,0,<ILDB PTR INTO MSG   ;IDPB PTR INTO MSG>
ENTRY. MD,AUX,+UD.MSD,.TXWDW,0,<NOT USED            ;ILDB PTR TO BEG OF MSG>
ENTRY. MD,BYT,+UD.MSD,.TDECD,0,<BYTES LEFT TO READ  ;BYTES WRITTEN SO FAR>
ENTRY. MD,VMC,+UD.MSD,.TDECD,0,<VIRTUAL MAP CONTEXT>
ENTRY. MD,ALL,+UD.MSD,.TDECD,0,<ALLOCATED LENGTH IN BYTES>
ENTRY. MD,ALA,+UD.MSD,.TXWDW,0,<ALLOCATED ADDRESS OF SEGMENT'S DATA>

>;END OF MBBMAC
	SUBTTL Block Description Tables -- CDB (CTERM Data Block)

DEFINE CDBMAC,<
ENTRY. CH,IMB,,.TXWDW,0,<ADDRESS OF CTERM MESSAGE INPUT BUFFER>
ENTRY. CH,UID,,.TXWDW,0,<UNIQUE ID>
ENTRY. CH,CO1,,.TXWDW,0,<CCOC WORDS LAST SENT TO SERVER>
ENTRY. CH,CO2,,.TXWDW,1,<CCOC WORDS LAST SENT TO SERVER>
ENTRY. CH,BR1,,.TXWDW,0,<BREAK MASK LAST SENT TO SERVER>
ENTRY. CH,BR2,,.TXWDW,0,<BREAK MASK LAST SENT TO SERVER>
ENTRY. CH,BR3,,.TXWDW,0,<BREAK MASK LAST SENT TO SERVER>
ENTRY. CH,BR4,,.TXWDW,0,<BREAK MASK LAST SENT TO SERVER>
ENTRY. CH,RFL,,.TXWDW,0,<START-READ FLAGS>
ENTRY. CH,LIN,,.TTTY, 0,<TOPS-20 TERMINAL LINE NUMBER>
ENTRY. CH,CHL,,.TDECD,0,<DECNET CHANNEL NUMBER>
ENTRY. CH,INC,,.TDECD,1,<COUNT OF CHARACTERS IN INPUT BUFFER>
ENTRY. CH,STS,,.TOCTW,0,<CURRENT STATE OF DECNET LINK>
ENTRY. CH,STA,,.TSTCF,1,<CURRENT CTERM STATE>
ENTRY. CH,SSZ,,.TDECD,0,<MAXIMUM CHARACTERS IN A SEGMENT FOR THIS LINK>
ENTRY. CH,MAX,,.TDECD,0,<MAXIMUM INPUT BUFFER LENGTH>
ENTRY. CH,RLN,,.TDECD,1,<START-READ LENGTH>
ENTRY. CH,RBL,,.TDECD,1,<^R BUFFER LENGTH>
ENTRY. CH,RDA,,.TBOOL,0,<A READ REQUEST IS ACTIVE IN THE SERVER>
ENTRY. CH,MRD,,.TBOOL,0,<INPUT DATA IS AVAILABLE IN THE SERVER>
ENTRY. CH,MRD,,.TBOOL,0,<THERE IS MORE READ DATA AVAILABLE IN THE SERVER>
ENTRY. CH,SSD,,.TBOOL,0,<SET "DO NOT DISCARD" IN NEXT WRITE>
ENTRY. CH,DSO,,.TBOOL,0,<DISCARD OUTPUT>
ENTRY. CH,RCX,,.TBOOL,0,<CRLF IS NOT IN THE BREAK MASK>
ENTRY. CH,CLI,,.TBOOL,0,<CLEAR INPUT BUFFER>
ENTRY. CH,ASR,,.TBOOL,0,<SEND ANOTHER START-READ>
ENTRY. CH,COC,,.TBOOL,0,<SEND CCOC WORDS>
ENTRY. CH,EDT,,.TBOOL,0,<SERVER SUPPORTS CONTINUATION READ>
ENTRY. CH,BIN,,.TBOOL,0,<LAST MESSAGE SEND TO SERVER WAS BINARY>
ENTRY. CH,RTI,,.TBOOL,0,<SERVER SUPPORTS REMOTE TEXTI>
>
	SUBTTL Block Description Tables -- CHB (CH blocks)

;Core handler structure

DEFINE CHBMAC,<

ENTRY. XH,BOT,,.TXWDW,0,<Pointer to free pool start>
ENTRY. XH,PTR,,.TXWDW,0,<Pointer to first free block>
ENTRY. XH,AVL,,.TDECD,0,<Number of available blocks>
ENTRY. XH,LWM,,.TDECD,0,<Low water mark>
ENTRY. XH,REQ,,.TDECD,0,<Size requested>
ENTRY. XH,NUM,,.TDECD,0,<Total blocks, alloc & unalloc.>
ENTRY. XH,SIZ,,.TDECD,0,<Size of block>
>  ;End of CHBMAC

DEFINE REBMAC,<
ENTRY.	RE,BAS,,.TXWDW,0,<Starting address of free space>
ENTRY.	RE,END,,.TXWDW,0,<Address of last word of free space>
ENTRY.	RE,TOT,,.TDECD,0,<Total size of free space in blocks>
ENTRY.	RE,PR1,,.TDECD,0,<Priority one threshold>
ENTRY.	RE,GRO,,.TDECD,0,<Lock down threshold>
ENTRY.	RE,BTB,,.TXWDW,0,<Address of start of bit table>
ENTRY.	RE,BTL,,.TDECD,0,<Length of bit table (words)>
ENTRY.	RE,TFR,,.TDECD,0,<Total remaining unallocated blocks>
ENTRY.	RE,FFB,,.TDECD,0,<Number of block just past end of free space>
ENTRY.	RE,PMX,,.TDECD,0,<Number of pools>
ENTRY.	RE,QTA,,.TXWDW,0,<Addr of block containing quota for each pool>
ENTRY.	RE,PFR,,.TXWDW,0,<Addr of block containing count of unallocated blocks>
>  ;End of REBMAC
	SUBTTL TDB Description Tables

DEFINE TDBMAC,<
ENTRY. T,T%SAL,,.TBOOL,0,<Sendall being done to this line>
ENTRY. T,T%SHT,,.TBOOL,0,<This is a short block>
ENTRY. T,T%MES,,.TBOOL,0,<This is a system message block>
ENTRY. T,T%OTP,,.TBOOL,0,<Output is enroute to the line>
ENTRY. T,T%FWK,,.TBOOL,0,<Forced wakeup>
ENTRY. T,T%SFG,,.TBOOL,0,<Stopped on end-of-page>
ENTRY. T,T%RFG,,.TBOOL,0,<Repeat last character (BKJFN)>
ENTRY. T,T%WFG,,.TBOOL,0,<Blocked on input>
ENTRY. T,T%PRM,,.TBOOL,0,<Don't deallocate dynamic data>
ENTRY. T,T%BAC,,.TBOOL,0,<Permanent and becoming active>
ENTRY. T,T%NXO,,.TBOOL,0,<Pause on end-of-page mode>
ENTRY. T,T%BKO,,.TBOOL,0,<Fork blocked for output event on this line>
ENTRY. T,T%NUS,,.TBOOL,0,<Net user state>
ENTRY. T,T%DD1,,.TBOOL,0,<Device dependent bit>
ENTRY. T,T%NPM,,.TBOOL,0,<MCB NVT old page mode>
ENTRY. T,T%RXF,,.TBOOL,0,<Have received XOFF on line>
ENTRY. T,T%FLO,,.TBOOL,0,<Flushing output at TTSND>
ENTRY. T,T%HPO,,.TBOOL,0,<High priority output queued>
ENTRY. T,T%DAL,,.TBOOL,0,<Deallocate of block requested>
ENTRY. T,T%XFF,,.TBOOL,0,<Force XOFF/XON status to front-end>
ENTRY. T,T%SEC,,.TBOOL,0,<Server should echo>
ENTRY. T,T%WKC,,.TBOOL,0,<Wake-up set has changed>
ENTRY. T,T%SPG,,.TBOOL,0,<Page stop is turned on in the server>
ENTRY. T,TLCK,,.TDECD,0,<Count of locks on this block>
ENTRY. T,YLMD,,.TDECD,0,<Terminal data mode for last input char>
ENTRY. T,TOCN,,.TDECD,0,<Count of extra buffers>
ENTRY. T,TOMX,,.TBOOL,0,<Extra buffers in use>
ENTRY. T,TTYP,,.TDECD,0,<Terminal type>
ENTRY. T,INTL,,.TOCTW,0,<Internal line number (index into static data)>
ENTRY. T,LTYP,,.TDECD,0,<Line type (same as TTSTY)>
ENTRY. T,SALT,,.TDECD,0,<Sendall timeout count>
ENTRY. T,SALC,,.TDECD,0,<Sendall character count>
ENTRY. T,TSAL2,,.TXWDW,0,<Sendall byte pointer>
ENTRY. T,TDEV,,.TXWDW,0,<Device dependent word>
ENTRY. T,OWRN,,.TDECD,0,<Count in ouput buffer for wakeup>
ENTRY. T,TNIN,,.TDECD,0,<Number input buffers>
ENTRY. T,TNOU,,.TDECD,0,<Number output buffers>
ENTRY. T,IMAX,,.TDECD,0,<Max bytes in input buffer>
ENTRY. T,OMAX,,.TDECD,0,<Max bytes in output buffer>
ENTRY. T,TOCT,,.TDECD,0,<Number characters in output buffer>
ENTRY. T,TOOUT,,.TXWDW,0,<Pointer for removing char from output buffer>
ENTRY. T,TOIN,,.TXWDW,0,<Pointer for entering char into output buffer>
ENTRY. T,TUPC,,.TOCTW,0,<Unpause on page character>
ENTRY. T,YLCH,,.TOCTW,0,<Last char removed from input buffer>
ENTRY. T,PWID,,.TDECD,0,<Page width>
ENTRY. T,TPPC,,.TOCTW,0,<Pause/Unpause on page character>
ENTRY. T,TICT,,.TDECD,0,<Number characters in input buffer>
ENTRY. T,TIOUT,,.TXWDW,0,<Pointer for removing char from input buffer>
ENTRY. T,TIIN,,.TXWDW,0,<Pointer for entering char into input buffer>
ENTRY. T,MOD1,,.TXWDW,0,<Control character output control words>
ENTRY. T,MOD2,,.TXWDW,0,<Control character output control words>
ENTRY. T,TDPSI,,.TXWDW,0,<Bit for terminal code set if deferred interrupt>
ENTRY. T,TPSI,,.TXWDW,0,<Bit for terminal code set if interrupt>
ENTRY. T,TLNK,,.TXWDW,0,<Lines linked to (9 bits per line)>
ENTRY. T,PGPS,,.TDECD,0,<Current line position within page>
ENTRY. T,LNPS,,.TDECD,0,<Current character position within line>
ENTRY. T,OFLG,,.TBOOL,0,<^O was typed>
ENTRY. T,PLEN,,.TDECD,0,<Page length>
ENTRY. T,TDUM,,.TBOOL,0,<Duplex mode>
ENTRY. T,CJOB,,.TDECD,0,<Controlling job number>
ENTRY. T,WFRK,,.TOCTW,0,<Number of fork in input wait on this line>
ENTRY. T,TPSFK,,.TOCTW,0,<Fork which is top fork of a SCTTY tree>
ENTRY. T,TPFK,,.TOCTW,1,<PSI fork for non control TTY PSI's>
ENTRY. T,CHR1,,.TXWDW,0,<Wake up character mask (ASCII codes 0-31.)>
ENTRY. T,CHR2,,.TXWDW,0,<Wake up character mask (ASCII codes 32.-63.)>
ENTRY. T,CHR3,,.TXWDW,0,<Wake up character mask (ASCII codes 64.-95.)>
ENTRY. T,CHR4,,.TXWDW,0,<Wake up character mask (ASCII codes 96.-127.)>
ENTRY. T,TIPSI,,.TOCTW,0,<Input PSI level>
ENTRY. T,TOPSI,,.TOCTW,0,<Ouput PSI level>
ENTRY. T,TFCNT,,.TDECD,0,<Byte count for wake-up (0=disabled for wake up)>
ENTRY. T,TLINE,,.TDECD,0,<Line counter>
ENTRY. T,TULL,,.TOCTW,0,<Net user logical link - when TTLMAX not in use>
ENTRY. T,TUEC,,.TOCTW,0,<Net user escape char>
ENTRY. T,TFLA,,.TBOOL,0,<First character seen flag>
ENTRY. T,TETP,,.TDECD,0,<Type>
ENTRY. T,TCH1,,.TOCTW,0,<First character>
ENTRY. T,TCH2,,.TOCTW,0,<Second character>
ENTRY. T,TSVPD,,.TXWDW,0,<Saved line speed>
> ;END TDBMAC
	SUBTTL Expand the Table Building Macros

	DOBLK SJB
	DOBLK SLB
	DOBLK ELB
	DOBLK RCB
	DOBLK CDB
	DOBLK PRT
	DOBLK MBB
	DOBLK AJB
	DOBLK DLB
	DOBLK LTB
	DOBLK CHB
	DOBLK REB
	DOBLK TDB
	SUBTTL .Txxx - Local Typeout Routines

;Call:	T2/ Resolved Byte Pointer to first word of queue header
;	CALL .TQUE
;	Normal Return

.TQUE:	MOVE T1,QH.CNT(T2)	;GET MAX,,COUNT
	PUSH P,T1
	HLRZS T1		;ISOLATE THE MAX FIELD
	CALL .TDECD		;TYPE OUT IN DECIMAL
	MOVEI T1,","		;LOAD A COMMA
	CALL .TCHAR		; TO SEPARATE MAX FROM COUNT
	POP P,T1
	HRRZS T1		;ISOLATE THE COUNT FIELD
	CALLRET .TDECD		;TYPE OUT IN DECIMAL

;Call:	T1/ value in milliseconds
;	CALL .TTMRD
;	Normal return

.TTMRD:	IDIVI T1,^D1000		;Convert form milleseconds to seconds
	CALLRET .TDECD


;Call:	T1/ value,  0=Passive  1=Active
;	CALL .TPTYP
;	Normal Return

.TPTYP:	SKIPE T1		   ;THE PORT TYPE, 0=Passive  1=Active
	 SKIPA T1,[[ASCIZ /DCN:/]] ;ACTIVE
	  MOVEI T1,[ASCIZ /SRV:/]  ;PASSIVE
	CALLRET .TSTRG

;Call:	T1/ value (node number)
;	CALL .TNODE
;	Normal Return

.TNODE:	PUSH P,T1		;SAVE WHOLE NODE NUMBER
	ASH T1,-12		;GET AREA NUMBER ONLY
	CALL .TDECD		;PRINT IT WITH A DOT FOLLOWING
	POP P,T1		;RECOVER WHOLE NODE NUMBER
	ANDI T1,1777		;GET NODE-WITHIN-AREA NUMBER
	CALLRET .TDECW		;PRINT WITHOUT DOT FOLLOWING
;Call:	T1/ Session Control State code
;	CALL .TSTAS
;	Normal Return

.TSTAS:	MOVEI T2,STASBL		; Get state table address
	MOVEI T3,STASLN		;  and its length
	CALLRET .TSTAT		; Call common state output routine

DEFINE STACOD(code),<
  IF2,<IFN .NSS'code-.+STASBL,<PRINTX ?STASBL (code) table is defined wrong>>
	EXP ASCIZ /code/
>

STASBL:	ASCIZ /??/
	STACOD CW		;CONNECT WAIT
	STACOD CR		;CONNECT RECEIVED
	STACOD CS		;CONNECT SENT
	STACOD RJ		;REMOTE REJECTED CONNECT INIT
	STACOD RN		;LINK IS UP AND RUNNING
	STACOD DR		;DISCONNECT RECEIVED
	STACOD DS		;DISCONNECT SENT
	STACOD DC		;DISCONNECT CONFIRMED
	STACOD CF		;NO CONFIDENCE
	STACOD LK		;NO LINK
	STACOD CM		;NO COMMUNICATION
	STACOD NR		;NO RESOURCES
STASLN==.-STASBL-1
;Call:	T1/ NSP State code
;	CALL .TSTAN
;	Normal Return

.TSTAN:	MOVEI T2,STANBL		; Get state table address
	MOVEI T3,STANLN		;  and its length
	CALLRET .TSTAT

DEFINE STACOD(code),<
  IF2,<IFN NPS.'code-.+STANBL,<PRINTX ?STANBL (code) table is defined wrong>>
	EXP ASCIZ /code/
>

STANBL:	ASCIZ /??/
	STACOD	OP	;OPEN, WAITING FOR ENTER ACTIVE FROM SC
	STACOD	CI	;CONNECT INITIATE SENT
	STACOD	CD	;CONNECT DELIVERED
	STACOD	CR	;CONNECT RECEIVED
	STACOD	CC	;CONNECT CONFIRM
	STACOD	DR	;DISCONNECT REJECT
	STACOD	RC	;DISCONNECT REJECT COMPLETE (DRC)
	STACOD	RN	;RUN
	STACOD	RJ	;REJECT
	STACOD	DI	;DISCONNECT INITIATE
	STACOD	IC	;DISCONNECT INITIATE COMPLETE (DIC)
	STACOD	DN	;DISCONNECT NOTIFICATION
	STACOD	CN	;CLOSE NOTIFICATION
	STACOD	NR	;NO RESOURCES
	STACOD	NC	;NO COMMUNICATION
	STACOD	CL	;CLOSED
	STACOD	DP	;DESTROY PORT
STANLN==.-STANBL-1
;Call:	T1/  Router circuit block state code
;	CALL .TSTAR
;	Normal Return


.TSTAR:	MOVEI T2,STARBL		; Get state table address
	MOVEI T3,STARLN		;  and its length
	CALLRET .TSTAT

DEFINE STACOD(code),<
  IF2,<IFN RCS.'code-.+STARBL,<PRINTX ?STARBL (code) table is defined wrong>>
	EXP ASCIZ /code/
>

STARBL:	STACOD OF		;OFF
	STACOD RJ		;Rejected
	STACOD FA		;Failed
	STACOD WT		;WAITING FOR PROTOCOL UP
	STACOD TI		;WAITING FOR TI
	STACOD TV		;WAITING FOR TV
	STACOD TT		;TESTING
	STACOD RN		;RUNNING
STARLN==.-STARBL-1
;Call:	T1/ Line state from DNADLL line table
;	CALL .TSTAL
;	Normal Return

.TSTAL:	MOVEI T2,STALBL		; Get state table address
	MOVEI T3,STALLN		;  and its length
	CALLRET .TSTAT

DEFINE STACOD(code),<
  IF2,<IFN LS.'code-.+STALBL,<PRINTX ?STALBL (code) table is defined wrong>>
	EXP ASCIZ /code/
>
STALBL:	STACOD ON		;ON
	STACOD OFF		;Off
	STACOD SRV		;Service
	STACOD CLR		;Cleared
STALLN==.-STALBL-1
;Call:	T1/ Router adjacency block state code
;	CALL .TSTAA
;	Normal Return

.TSTAA:	MOVEI T2,STAABL
	MOVEI T3,STAALN
	CALLRET .TSTAT

DEFINE STACOD(code),<
  IF2,<IFN ADJ.'code-.+STAABL,<PRINTX ?STAABL (code) table is defined wrong>>
	EXP ASCIZ /code/
>

STAABL:	STACOD UN		;This entry is currently unused
	STACOD IN		;Currently initializing
	STACOD UP		;Adjacency is up
	STACOD OL		;Adjacency is off-line
STAALN==.-STAABL-1
;Call:	T1/ CTERM State code
;	CALL .TSTCF
;	Normal Return

.TSTCF:	MOVEI T2,STAFBL		; Get state table address
	MOVEI T3,STAFLN		;  and its length
	CALLRET .TSTAT

DEFINE STACOD(code),<
  IF2,<IFN .ST'code-.+STAFBL,<PRINTX ?STAFBL (code) table is defined wrong>>
	EXP ASCIZ /code/
>
STAFBL:	STACOD INI		;initializing
	STACOD FND		;foundation started
	STACOD RUN   		;running
	STACOD SHU		;shutting down
STAFLN==.-STAFBL-1
;Call:	T1/ State code
;	T2/ State table
;	T3/ State table length
;	CALL .TSTAT
;	Normal Return

.TSTAT:	STKVAR <STATE,STATAB,STALEN>
	MOVEM T1,STATE		; Save state
	MOVEM T2,STATAB		;  and state table address
	MOVEM T3,STALEN		;  and the table's length
	CALL .TDECW		; Type state in decimal
	CALL .TSPAC
	MOVEI T1,"("
	CALL .TCHAR
	MOVE T1,STATE		; Get state
	MOVE T2,STALEN		;  and table length
	CAMLE T1,T2		; Be sure within range of table
	IFSKP.
	  MOVE T1,STATAB	; O.K., compute offset into state table
	  ADD T1,STATE
	ELSE.
	  MOVEI T1,[ASCIZ /???/] ;  else, type this
	ENDIF.
	CALL .TSTRG		; Type the state
	MOVEI T1,")"
	CALLRET .TCHAR
;
;Call:	T1/ Router adjacency type code
;	CALL .TAJTY
;	Normal Return

.TAJTY:	PUSH P,T1		;SAVE STATE CODE
	CALL .TDECW		;TYPE STATE IN DECIMAL
	CALL .TSPAC
	MOVEI T1,"("
	CALL .TCHAR
	POP P,T1
	CAILE T1,AJTBLN		;WE UNDERSTAND THE STATE?
	MOVEI T1,0		;NO, USE ILLEGAL STATE
	MOVEI T1,AJTTBL(T1)	;GET POINTER TO ASCIZ STRING
	CALL .TSTRG		;TYPE IT OUT
	MOVEI T1,")"
	CALLRET .TCHAR

DEFINE ADJTYP(code),<
  IF2,<IFN ADJ.'code-.+AJTTBL,<PRINTX ?AJTTBL (code) table is defined wrong>>
	EXP ASCIZ /code/
>

AJTTBL:	ADJTYP 3F		;Phase III non-routing node
	ADJTYP 3S		;Phase III routing node
	EXP 0			;Unused
	ADJTYP L2		;Phase IV level II router
	ADJTYP L1		;Phase IV level I router
	ADJTYP LN		;Phase IV non-routing
AJTBLN==.-AJTTBL-1
;Call:	T1/ Message type from NMMGF field
;	CALL .TMGF
;	Normal Return

.TMGF:	MOVE T2,T1              ;COPY MGF FIELD
	LSH T2,-2		;SET UP TO READ MSGTBL (MESSAGE TABLE)
	CAILE T2,RCVMAX		;IS IT A LEGAL MESSAGE TYPE?
	  CALLRET .TDECD        ;NO, TYPE IN DECIMAL
	MOVE T1,MSGTBL(T2)	;GET NAME OF MSG TYPE IN SIXBIT
	CALLRET .TSIXN          ;TYPE IT OUT

;This table is copied from LLINKS.MAC.  Only the first field (type) is used.

DEFINE MGTYPS,<						  ;{subtype,type}
MSGTYP(MIDSEG,RCVMDS,UPTOSG,NORMAL,NRQACK,RESPOND,FLOW  ) ; 0:   {0,0}
MSGTYP(ACK,   RCVACK,UPTOAK,NORMAL,REQACK,NO.RESP,NOFLOW) ; 1:   {0,1}
MSGTYP(NOP,   RCVNOP,UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ; 2:   {0,2}
MSGTYP(<0,3>, RCVILM,UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ; 3:   {0,3}
MSGTYP(LNKSRV,RCVLKS,UPTOSG,OTHER ,NRQACK,RESPOND,NOFLOW) ; 4:   {1,0}
MSGTYP(OTHACK,RCVACK,UPTOAK,OTHER ,REQACK,NO.RESP,NOFLOW) ; 5:   {1,1}
MSGTYP(CI,    RCVCI, UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ; 6:   {1,2}
MSGTYP(<1,3>, RCVILM,UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ; 7:   {1,3}
MSGTYP(BEGSEG,RCVBGS,UPTOSG,NORMAL,NRQACK,RESPOND,FLOW  ) ;10:   {2,0}
MSGTYP(CA,    RCVCA, UPTODL,NORMAL,NRQACK,NO.RESP,NOFLOW) ;11:   {2,1}
MSGTYP(CC,    RCVCC, UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ;12:   {2,2}
MSGTYP(<2,3>, RCVILM,UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ;13:   {2,3}
MSGTYP(INTSEG,RCVONS,UPTOSG,OTHER ,NRQACK,RESPOND,FLOW  ) ;14:   {3,0}
MSGTYP(<3,1>, RCVILM,UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ;15:   {3,1}
MSGTYP(DI,    RCVDI, UPTOSL,NORMAL,NRQACK,RESPOND,NOFLOW) ;16:   {3,2}
MSGTYP(<3,3>, RCVILM,UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ;17:   {3,3}
MSGTYP(ENDSEG,RCVENS,UPTOSG,NORMAL,NRQACK,RESPOND,FLOW  ) ;20:   {4,0}
MSGTYP(<4,1>, RCVILM,UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ;21:   {4,1}
MSGTYP(DC,    RCVDC, UPTOSL,NORMAL,NRQACK,NO.RESP,NOFLOW) ;22:   {4,2}
MSGTYP(<4,3>, RCVILM,UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ;23:   {4,3}
MSGTYP(<5,0>, RCVILM,UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ;24:   {5,0}
MSGTYP(<5,1>, RCVILM,UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ;25:   {5,1}
MSGTYP(<5,2>, RCVILM,UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ;26:   {5,2}
MSGTYP(<5,3>, RCVILM,UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ;27:   {5,3}
MSGTYP(ONYSEG,RCVONS,UPTOSG,NORMAL,NRQACK,RESPOND,FLOW  ) ;30:   {6,0}
MSGTYP(<6,1>, RCVILM,UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ;31:   {6,1}
MSGTYP(RCI,   RCVCI, UPTOMG,NORMAL,NRQACK,RESPOND,NOFLOW) ;32:   {6,2}
>;END OF MGTYPS MACRO

DEFINE MSGTYP(type,routine,upto,sublink,ack,respond,flow),<
	SIXBIT \type\
>
MSGTBL:	MGTYPS                  ;EXPAND A TABLE OF MSG TYPE NAMES
RCVMAX==.-MSGTBL		;LENGTH OF MSGTBL
	PRGEND
	TITLE SPYTMP -- One of several Block Description Subprograms

;This and following modules are separate programs so that they can build
;tables based on different universals which contain conflicting symbols.

;All SPYxxx modules search these:
	SEARCH MACSYM
	SEARCH DCNSPY

;The following universals are searched for symbols in the xxxMAC tables:
	SEARCH D36PAR,SCPAR

;And now glue the various subprograms together:

	EXTERN .TTTY,  .TBOOL, .TDECD, .TDECW, .TSIXN, .TOCTW, .TXWDW, ERRSTR
	EXTERN .TSPAC, .TTABC
	SUBTTL Block Description Tables -- DECnet/CI tables

Repeat 1,<			;Temporary
;This structure contains the DECnet data representing a CI controller

	INTERN CB.PRT           ;Let main program see CB.PRT

BEGSTR CB			;DECnet/CI controller block
	FIELD CPU,3		;Cpu #
	FIELD CI,3		;Ci interface #
	FIELD KLP,1		;CI ("KLIPA") interface present
	HWORD LPT		;Local port #
	WORD CID		;Connect ID of current listener
	WORD PRT,^D16		;Pointers to port blocks, indexed by port #
ENDSTR

;This structure represents a port on a CI controller

BEGSTR PB
	WORD CB			;Pointer to DECnet/CI controller block
	WORD CID		;Connect ID
	WORD DID		;DNADLL ID for this circuit
	HWORD STA		;Connect state for port
	HWORD PNR		;Port # of this port
	HWORD DRE		;Disconnect reason
	WORD BYR		;# of bytes received
	WORD BYS		;# of bytes sent
	WORD DGR		;# of datagrams received
	WORD DGS		;# of datagrams sent
	WORD DDG		;# of datagrams dropped by DECnet
	WORD SDG		;# of datagrams dropped by SCA
ENDSTR

;The Port connection states are:
	XP .PSOFF,0		;OFF
	XP .PSLIS,1		;LISTEN
	XP .PSACC,2		;ACCEPT
	XP .PSCDOWN,3		;CONNECT, remote believed down
	XP .PSCUP,4		;CONNECT, remote believed up
	XP .PSCSE,5		;CONNECT sent
	XP .PSRUN,6		;RUN

> ;End rept 1

DEFINE CBBMAC,<

;DECnet/CI controller block

ENTRY. CB,CPU,,.TDECD,0,<Cpu #>
ENTRY. CB,CI,,.TDECD,0,<CI interface #>
ENTRY. CB,KLP,,.TBOOL,0,<CI ("KLIPA") interface present>
ENTRY. CB,LPT,,.TDECD,0,<Local port #>
ENTRY. CB,CID,,.TXWDW,2,<Connect ID of current listener>
ENTRY. CB,PRT,+^D0,.TXWDW,0,<Pointer to port block, indexed by port 0>
ENTRY. CB,PRT,+^D1,.TXWDW,0,<Pointer to port block, indexed by port 1>
ENTRY. CB,PRT,+^D2,.TXWDW,0,<Pointer to port block, indexed by port 2>
ENTRY. CB,PRT,+^D3,.TXWDW,0,<Pointer to port block, indexed by port 3>
ENTRY. CB,PRT,+^D4,.TXWDW,0,<Pointer to port block, indexed by port 4>
ENTRY. CB,PRT,+^D5,.TXWDW,0,<Pointer to port block, indexed by port 5>
ENTRY. CB,PRT,+^D6,.TXWDW,0,<Pointer to port block, indexed by port 6>
ENTRY. CB,PRT,+^D7,.TXWDW,0,<Pointer to port block, indexed by port 7>
ENTRY. CB,PRT,+^D8,.TXWDW,0,<Pointer to port block, indexed by port 8>
ENTRY. CB,PRT,+^D9,.TXWDW,0,<Pointer to port block, indexed by port 9>
ENTRY. CB,PRT,+^D10,.TXWDW,0,<Pointer to port block, indexed by port 10>
ENTRY. CB,PRT,+^D11,.TXWDW,0,<Pointer to port block, indexed by port 11>
ENTRY. CB,PRT,+^D12,.TXWDW,0,<Pointer to port block, indexed by port 12>
ENTRY. CB,PRT,+^D13,.TXWDW,0,<Pointer to port block, indexed by port 13>
ENTRY. CB,PRT,+^D14,.TXWDW,0,<Pointer to port block, indexed by port 14>
ENTRY. CB,PRT,+^D15,.TXWDW,2,<Pointer to port block, indexed by port 15>

>

DEFINE PBBMAC,<

;DECnet/CI port block

ENTRY. PB,CB ,+CB.LEN,.TXWDW,0,<Pointer to DECnet/CI controller block>
ENTRY. PB,CID,+CB.LEN,.TXWDW,0,<Connect ID>
ENTRY. PB,DID,+CB.LEN,.TXWDW,0,<DNADLL ID for this circuit>
ENTRY. PB,STA,+CB.LEN,.TCCIP,0,<Connect state for port>
ENTRY. PB,PNR,+CB.LEN,.TDECD,0,<Port # of this port>
ENTRY. PB,DRE,+CB.LEN,.TOCTW,0,<Disconnect reason>
ENTRY. PB,BYR,+CB.LEN,.TDECD,0,<# of bytes received>
ENTRY. PB,BYS,+CB.LEN,.TDECD,0,<# of bytes sent>
ENTRY. PB,DGR,+CB.LEN,.TDECD,0,<# of datagrams received>
ENTRY. PB,DGS,+CB.LEN,.TDECD,0,<# of datagrams sent>
ENTRY. PB,DDG,+CB.LEN,.TDECD,0,<# of datagrams dropped by DECnet>
ENTRY. PB,SDG,+CB.LEN,.TDECD,0,<# of datagrams dropped by SCA>

>
	SUBTTL Expand the Table Building Macros

	DOBLK CBB
	DOBLK PBB
;Call:	T1/ DECnet/CI port state
;	CALL .TCCIP
;	Normal return
.TCCIP:	PUSH P,T1		;Save state code
	CALL .TDECW		;Type it in decimal
	CALL .TSPAC		; and a space
	MOVX T1,"("		;  and (
	CALL .TCHAR
	POP P,T1
	CAILE T1,CIPSLN		;Do we know the port state?
	SETO T1,		; -no use illegal port state
	MOVE T1,CIPSTB(T1)	;Get string pointer
	CALL .TSTRG		; and type it
	MOVX T1,")"		;  followed by )
	CALLRET .TCHAR

DEFINE PSCOD(code) <
  IF2,<IFN .PS'code-.+CIPSTB,<PRINTX ?CIPSTB (code) is defined wrong>>
	[ASCIZ /code/ ]
>

	ASCIZ /???/
CIPSTB:	PSCOD OFF
	PSCOD LIS
	PSCOD ACC
	PSCOD CDOWN
	PSCOD CUP
	PSCOD CSENT
	PSCOD RUN
CIPSLN==.-CIPSTB-1
	PRGEND
	TITLE SPYLAT -- One of several Block Description Subprograms

;This and following modules are separate programs so that they can build
;tables based on different universals which contain conflicting symbols.

;All SPYxxx modules search these:
	SEARCH MACSYM,MONSYM
	SEARCH DCNSPY

;The following universals are searched for symbols in the xxxMAC tables:


;And now glue the various subprograms together:

	EXTERN .TTTY,  .TBOOL, .TDECD, .TDECW, .TSIXN, .TOCTW, .TXWDW, ERRSTR
	EXTERN .TSPAC, .TTABC, XPEEKX, NODBLK, SCNCHN
	EXTERN SETSPY, LENGTH, TYPTAD, TYPBLK, NODADR, SCNTAD, GETTDB
	EXTERN CHNBAS, PORBAS, SCNIDX
	SUBTTL Block Description Tables -- LAT BEGSTRs

	ML.NNM==6		;Max length of node name
	ML.SYS==^D16		;Max length of system name
	ML.LOC==^D64		;Max length of location field
	ML.DSC==^D64		;Max length of description field
	ML.SNM==^D16		;Max length of service name
	ML.SID==^D64		;Max length of service identification field
	ML.SLN==^D16		;Max length of slot name

;Host Node Data Structures
;

	INTERN GB.LEN
BEGSTR	GB			;SERVICE BLOCK
	WORD RAT		;Service Rating.
	HWORD NC		;Count of bytes in service name.
	HWORD LC		;Count of bytes in service description
;	WORD NAM,<<ML.SNM+4>/5>	;Storage for up to 16 bytes of service name.
;	WORD HID,<<ML.SID+4>/5>	;Storage for up to 64 bytes of service id.
ENDSTR

	INTERN HN.LEN
BEGSTR	HN			;HOST NODE Data Base
	FIELD FLG,^D18
	 BIT RUN		;NI run state
	 BIT ANY		;Reconstruct of START msg necessary
	 BIT CIP		;Virtual circuit connect in progress
	FILLER ^D10
	FIELD CFL,^D8		;Multicast message change flags
	 BIT OTH		;Something other than above changed
	 BIT FIL
	 BIT CLS		;A host service class changed
	 BIT SVD		;A host service description changed
	 BIT SVR		;A host service rating changed
	 BIT SVN		;A host service name changed
	 BIT NDD		;Host Node Description changed
	 BIT ACS		;Access Codes changed
				;START OF PARAMETERS DISPLAYED BY  .LASCH 
	HWORD MXC		;Maximum allocatable circuit blocks
	HWORD NCC		;Number of currently allocated circuit blocks
	HWORD MAC		;Maximum number of active circuits
	HWORD NAC		;Number of currently active circuits
	HWORD MCO		;Maximum number of simultaneous connects
	HWORD CON		;Current number of active connects
	HWORD NUM		;Host number
	HWORD LAS		;LAT access state
	HWORD RLI		;Virtual circuit message retransmit limit
	HWORD TIM		;Virtual circuit timer initial value (sec)
	HWORD MTI		;Multicast timer initial value (sec)
				; END OF PARAMETERS DISPLAYED BY .LASCH 
	HWORD RAT		;Host node dynamic rating
	HWORD PRG		;Host progress timer
	HWORD NRB		;Number of receive buffers allocated
	WORD HST		;Address of state table
	WORD QAC,2		;Queue header for active circuit blocks
	WORD QIC,2		;Queue header for inactive circuit blocks
	WORD NIQ,2		;Interrupt level message queue
	WORD SCQ,2		;Scheduler level message queue
	WORD PID		;NI Portal ID
	HWORD NXI		;Next circuit block index to assign
	HWORD NSV		;Number of offered services
	WORD LOK		;Lock for HN data base
	HWORD NMC		;Host node name count
	HWORD IDC		;Host identification string count
	WORD NAM,2		;Host node name string
;	WORD ID,<<ML.DSC+4>/5>	;Host identification string
;	WORD SMT,<<<ML.HSM+3>/4>+SBF.OF>;Start message template
;	WORD MCM,<<ML.HMC+3>/4>	;Copy of the multicast message.
;	WORD SRV,<GB.LEN*MXHSRV>;Storage for service blocks
ENDSTR

	INTERN AC.LEN
BEGSTR	AC,HN.LST		;ACCESS CODES
	WORD LNG		;Access code string length in bytes
	WORD COD,^D32		;Storage for 256 bit bit-mask
ENDSTR

;LAT Circuit counters for all servers

	INTERN HC.LEN
BEGSTR	HC,AC.LST	
	WORD RCV		;Messages received
	WORD XMT		;Messages transmitted
	WORD RTR		;Messages retransmitted
	WORD SEQ		;Receive message sequence errors
	WORD IMR		;Illegal messages received
	WORD ISR		;Illegal slots received
	WORD RES		;Resource errors
	WORD MSK		;Illegal message error mask
ENDSTR
	SUBTTL	CIRCUIT BLOCK data structure definitions

	INTERN CB.LEN
BEGSTR	CB			;CIRCUIT BLOCK
	WORD LNK,2		;Queue Link words (must be first words)
	HWORD RID		;Circuit handle assigned by the remote
	HWORD LID		;Local circuit index
	FIELD FLG,3		;Virtual circuit flags
	 BIT RRF		;Reply requested flag
	 BIT MRS		;Must reply soon flag
	 BIT MRN		;Must reply now flag
	HWORD CSB		;Count since balanced
	HWORD SDC		;Number of slots with data waiting
	HWORD TSQ		;Next transmit sequence number
	HWORD RSQ		;Next expected receive sequence number
	HWORD LRA		;Sequence number of last message ack'd by remote node.
	WORD TIM		;Current value of circuit timer.
	HWORD RTC		;Current retransmit count
	HWORD KAV		;2*Server Keep-alive-timer in ms.
	WORD KAT		;TODCLK last time message receieved from server
	HWORD QUA		;Circuit quality
	HWORD ERR		;Reason code for last time circuit stopped
	HWORD DLL		;Number of transmit buffers in the DLL
	WORD XBQ,2		;Queue of free transmit buffers
	WORD AKQ,2		;Unacknowledged queue header
	WORD SBQ,2		;Circuit slot queue
	WORD DNI,2		;NI address of remote server
	HWORD MTF		;Maximum transmit frame size for circuit
	HWORD RPV		;Remote protocol version and ECO
	HWORD MSL		;Maximum slots allowed by remote
	HWORD NBF		;Additional transmit buffers allowed by remote
	HWORD CTI		;Value of remote's circuit timer
	HWORD KTI		;Value of remote's keep-alive timer
	HWORD PTC		;Product type code for remote node
	HWORD STA		;Virtual circuit state
	HWORD NUM		;Remote's system number
	HWORD RSC		;Remote's system name count
	HWORD RLC		;Remote's location text count
	WORD SNM,<<ML.SNM+4>/5>	;Remote's system name
	WORD LOC,<<ML.LOC+4>/5>	;Remote's location string	
ENDSTR
	INTERN CC.LEN
BEGSTR	CC,CB.LST		;CIRCUIT COUNTERS
	WORD RCV		;Messages received
	WORD XMT		;Messages transmitted
	WORD RTR		;Messages retransmitted
	WORD SEQ		;Receive message sequence errors
	WORD IMR		;Illegal messages received
	WORD ISR		;Illegal slots received
	WORD RES		;Resource errors
	WORD MSK		;Illegal message error mask
ENDSTR
	SUBTTL	SLOT BLOCK data structure definitions

BEGSTR	SB
	WORD LNK,2		;Queue link word (must be first)
	FIELD FLG,^D18		;Flags
	  BIT SDP		;Slot data present (must be sign bit)
	  BIT REJ		;Send REJECT Slot
	  BIT STR		;Send START Slot
	  BIT FOU		;Flush output
	  BIT OUT		;Output data available
	  BIT FCC		;Flow control change
	  BIT STO		;Send STOP Slot(Must be last)
	HWORD ATS		;Maximum attention slot size
	HWORD MDS		;Maximum slot data size
	HWORD STA		;Slot state
	HWORD RID		;Remote slot id
	HWORD LID		;Local slot id
	HWORD XCR		;Transmit credits available to us
	HWORD RCR		;Receive credits still outstanding
	HWORD REA		;Reason code for stop or reject
	HWORD SNC		;Source slot name count
	WORD SNM,<<ML.SLN+4>/5>	;Source slot name (16 characters max)
	WORD TDB		;Terminal data block
	WORD CBA		;Circuit block address for this slot
ENDSTR
	SUBTTL	PORT STORAGE DEFINITIONS

BEGSTR PS
	WORD NXT		;Pointer to next channel block
	WORD PCB		;PORT CONTROL BLOCK BASE ADDRESS (VIRTUAL)
	WORD PBA		;PORT CONTROL BLOCK PHYSICAL BASE ADDRESS
	WORD PTT		;VIRTUAL ADDRESS OF PROTOCOL TYPE TABLE
	WORD MTT		;VIRTUAL ADDRESS OF MULTICAST ADDRESS TABLE
	WORD INT		;INTERRUPT LEVEL CONTROL BUFFER
	WORD NON		;NON-INTERRUPT LEVEL CONTROL BUFFER
	WORD LPT		;LOAD PTT TABLE BUFFER ADDRESS
	WORD LMT		;LOAD MULTICAST ADDRESS TABLE BUFFER ADDRESS
	WORD WSI		;WRITE STATION INFO BUFFER ADDRESS
	WORD RSI		;READ STATION INFO BUFFER ADDRESS
	NXTWRD 3		;PSEUDO PTT FOR UNKNOWN PROTOCOL TYPE QUEUE
	FIELD FLG,18		;FLAGS WORD
	 BIT SLS		;1=LINE STATE NEEDS REPORTED
	 BIT WUL		;1=WAITING FOR UCODE TO BE LOADED
	 BIT STP		;1=WAITING FOR PORT RESTART
	 BIT BIG		;1=KNISTP BUGINF REPORTED
	 BIT LSI		;1=NEED TO WRITE STATION INFORMATION
	 BIT LMC		;1=NEED TO DO LOAD MULTICAST TABLE COMMAND
	 BIT LPP		;1=NEED TO DO LOAD PROTOCOL TABLE COMMAND
	 BIT VAD		; 1=PSHAD/LAD is valid
	NXTWRD
	FIELD RUN,1,0		;Channel is running, should be 1b0
	FIELD SST,9,26		;Channel substate
	FIELD EXS,9,35		;Channel external state
	WORD HAD		;STORED HIGH ORDER STATION ADDRESS
	WORD LAD		;STORED LOW ORDER STATION ADDRESS
	WORD SAD,2		;Shadowed address
	WORD HRA		;STORED HIGH ORDER ROM ADDRESS
	WORD LRA		;STORED LOW ORDER ROM ADDRESS
	FIELD VAR,4		;STORED VARIBLES
	 ;--IMPORTANT--  THE FOLLOWING 4 BITS MUST BE IN SAME ORDER AS WSVAR
	  BIT CRC		;ALLOW RECEIPT OF FRAMES WITH CRC ERRORS
	  BIT PMC		;STATION IS IN PROMISCIOUS MULTICAST MODE
	  BIT H40		;H4000 MODE IF 1
	  BIT PRM		;PROMISCIOUS MODE IF 1
	FIELD SVA,4		; Shadowed variables (what the port contains)
	FIELD VBT,4		; Valid bits in PSVAR (same order as PSVAR)
	  BIT VCR		;   PSCRC is valid
	  BIT VPM		;   PSPMC is valid
	  BIT VH4		;   PSH40 is valid
	  BIT VPR		;   PSPRM is valid
	FIELD RSP,8		;MAXIMUM NUMBER OF ENTRIES ON THE RESPONSE QUE
	FIELD CHN,4		; Logical channel number
	FIELD CBA,3		; CBUS address
	WORD CHK		; Check word, contains magic value
	WORD TLR		; Time of last response
	WORD CNO		; CONO KNI,(T1)
	WORD CNI		; CONI KNI,T1
	WORD DTO		; DATAO KNI,T1
	WORD DTI		; DATAI KNI,T1
	WORD CQA		; CONO KNI,CO.BTS+CO.CQA or NOP
	WORD MXT		; # of Multicasts transmitted
	HWORD UMA		; Major version #
	HWORD UMI		; Minor version #
	WORD UED		; Edit #
	WORD TPC		;UDT OF PORT CRASH
	WORD LAR		;LAR AT TIME OF UCODE CRASH
	WORD CRL		;LEFT HAND CRAM BITS AT TIME OF CRASH
	WORD CRR		;RIGHT HAND CRAM BITS AT TIME OF CRASH
	WORD TLZ		;TIME AT WHICH PORT COUNTERS WERE ZEROED
	WORD SHC		;ADDRESS OF SHADOW COUNTERS BLOCK
ENDSTR
	SUBTTL Macro Definitions -- BEGSTRS

;+
; Data Structures
; Portal Table block

BEGSTR PR
	WORD	NXT		;POINTER TO NEXT BLOCK (MUST BE FIRST)
	FIELD	FLG,9		;FLAGS FOR THIS PORTAL
	  BIT	CLO		;PORTAL IS CLOSING
	  BIT	PAD		;PAD FLAG
	FIELD   MYP,9		; BIT VALUE FOR MY PORTAL 
	HWORD	BSZ		;RECEIVE BUFFER SIZE
	WORD	UID		;WHAT USER WANTS ON CALL BACK
	HWORD	PMD		;PACKING MODE
	HWORD	PRO		;PROTOCAL TYPE
	WORD	CHN		;PHYSICAL CHANNEL
	WORD	MUL		;BIT VECTOR OF ENABLED MULTICASTS
	WORD	POS		;ADDRESS OF POSTING ADDRESS VECTOR
	WORD	CHK		;ADDRESS OF THIS BLOCK (CONSISTENCY CHECK)
	WORD	FQA		;FREE QUEUE HEADER ADDRESS
	WORD	TLZ		;TIME AT WHICH COUNTERS WERE ZEROED
	WORD	BYR		;BYTES RECEIVED
	WORD	DGR		;DATAGRAMS RECEIVED
	WORD	BYS		;BYTES SENT
	WORD	DGS		;DATAGRAMS SENT
	WORD	UBU		;USER BUFFER UNAVAILABLE
ENDSTR
	SUBTTL Block Description Tables -- LAT Tables


;Host Node Data Structures
;

;SERVICE BLOCK
DEFINE GBBMAC,<
ENTRY. GB,RAT,,.TDECD,0,<Service Rating.>
ENTRY. GB,NC,,.TDECD,0,<Count of bytes in service name.>
ENTRY. GB,LC,,.TDECD,0,<Count of bytes in service description>
;ENTRY. GB,NAM,,.TSTRG,0,<Storage for up to 16 bytes of service name.>
;ENTRY. GB,HID,,.TSTRG,0,<Storage for up to 64 bytes of service id.>
>;END GBBMAC

;HOST NODE Data Base
DEFINE HNBMAC,<
ENTRY. HN,RUN,,.THNRN,0,<NI run state>
ENTRY. HN,ANY,,.TBOOL,0,<Reconstruct of START msg necessary>
ENTRY. HN,CIP,,.TBOOL,0,<Virtual circuit connect in progress>
ENTRY. HN,OTH,,.TBOOL,0,<Something other than above changed>
ENTRY. HN,CLS,,.TBOOL,0,<A host service class changed>
ENTRY. HN,SVD,,.TBOOL,0,<A host service description changed>
ENTRY. HN,SVR,,.TBOOL,0,<A host service rating changed>
ENTRY. HN,SVN,,.TBOOL,0,<A host service name changed>
ENTRY. HN,NDD,,.TBOOL,0,<Host Node Description changed>
ENTRY. HN,ACS,,.TBOOL,2,<Access Codes changed>
				;START OF PARAMETERS DISPLAYED BY  .LASCH 
ENTRY. HN,MXC,,.TDECD,0,<Maximum allocatable circuit blocks>
ENTRY. HN,NCC,,.TDECD,0,<Number of currently allocated circuit blocks>
ENTRY. HN,MAC,,.TDECD,0,<Maximum number of active circuits>
ENTRY. HN,NAC,,.TDECD,0,<Number of currently active circuits>
ENTRY. HN,MCO,,.TDECD,0,<Maximum number of simultaneous connects>
ENTRY. HN,CON,,.TDECD,0,<Current number of active connects>
ENTRY. HN,NUM,,.TDECD,0,<Host number>
ENTRY. HN,LAS,,.TDECD,0,<LAT access state>
ENTRY. HN,RLI,,.TDECD,0,<Virtual circuit message retransmit limit>
ENTRY. HN,TIM,,.TDECD,0,<Virtual circuit timer initial value (sec)>
ENTRY. HN,MTI,,.TDECD,2,<Multicast timer initial value (sec)>
				; END OF PARAMETERS DISPLAYED BY .LASCH 
ENTRY. HN,RAT,,.TDECD,0,<Host node dynamic rating>
ENTRY. HN,PRG,,.TTIME,0,<Host progress timer>
ENTRY. HN,NRB,,.TDECD,0,<Number of receive buffers allocated>
ENTRY. HN,HST,,.TXWDW,0,<Address of state table>
ENTRY. HN,QAC,,.TXWDW,0,<Queue header for active circuit blocks>
ENTRY. HN,QIC,,.TXWDW,0,<Queue header for inactive circuit blocks>
ENTRY. HN,NIQ,,.TXWDW,0,<Interrupt level message queue>
ENTRY. HN,SCQ,,.TXWDW,0,<Scheduler level message queue>
ENTRY. HN,PID,,.TXWDW,0,<NI Portal ID>
ENTRY. HN,NXI,,.TXWDW,0,<Next circuit block index to assign>
ENTRY. HN,NSV,,.TDECD,0,<Number of offered services>
ENTRY. HN,LOK,,.TDECD,0,<Lock for HN data base>
ENTRY. HN,NMC,,.TDECD,0,<Host node name count>
ENTRY. HN,IDC,,.TDECD,0,<Host identification string count>
;	WORD NAM,2		;Host node name string
;	WORD ID,<<ML.DSC+4>/5>	;Host identification string
;	WORD SMT,<<<ML.HSM+3>/4>+SBF.OF>;Start message template
;	WORD MCM,<<ML.HMC+3>/4>	;Copy of the multicast message.
;	WORD SRV,<GB.LEN*MXHSRV>;Storage for service blocks
>;END HNBMAC

;LAT Circuit counters for all servers

DEFINE HCBMAC,<
ENTRY. HC,RCV,,.TDECD,0,<Messages received>
ENTRY. HC,XMT,,.TDECD,0,<Messages transmitted>
ENTRY. HC,RTR,,.TDECD,0,<Messages retransmitted>
ENTRY. HC,SEQ,,.TDECD,0,<Receive message sequence errors>
ENTRY. HC,IMR,,.TDECD,0,<Illegal messages received>
ENTRY. HC,ISR,,.TDECD,0,<Illegal slots received>
ENTRY. HC,RES,,.TDECD,0,<Resource errors>
ENTRY. HC,MSK,,.TXWDW,0,<Illegal message error mask>
>;END HCBMAC
	SUBTTL	CIRCUIT BLOCK data structure definitions

DEFINE CBLMAC,<
ENTRY. CB,LNK,,.TXWDW,0,<Queue Link words (must be first words)>
ENTRY. CB,RID,,.TXWDW,0,<Circuit handle assigned by the remote>
ENTRY. CB,LID,,.TXWDW,0,<Local circuit index>
ENTRY. CB,RRF,,.TBOOL,0,<Reply requested flag>
ENTRY. CB,MRS,,.TBOOL,0,<Must reply soon flag>
ENTRY. CB,MRN,,.TBOOL,0,<Must reply now flag>
ENTRY. CB,CSB,,.TDECD,0,<Count since balanced>
ENTRY. CB,SDC,,.TDECD,0,<Number of slots with data waiting>
ENTRY. CB,TSQ,,.TDECD,0,<Next transmit sequence number>
ENTRY. CB,RSQ,,.TDECD,0,<Next expected receive sequence number>
ENTRY. CB,LRA,,.TDECD,0,<Sequence number of last message ack'd by remote node.>
ENTRY. CB,TIM,,.TDECD,0,<Current value of circuit timer.>
ENTRY. CB,RTC,,.TDECD,0,<Current retransmit count>
ENTRY. CB,QUA,,.TDECD,0,<Circuit quality>
ENTRY. CB,ERR,,.TDECD,0,<Reason code for last time circuit stopped>
ENTRY. CB,DLL,,.TDECD,0,<Number of transmit buffers in the DLL>
ENTRY. CB,XBQ,,.TXWDW,0,<Queue of free transmit buffers>
ENTRY. CB,AKQ,,.TXWDW,0,<Unacknowledged queue header>
ENTRY. CB,SBQ,,.TXWDW,0,<Circuit slot queue>
ENTRY. CB,DNI,,.TXWDW,0,<NI address of remote server>
ENTRY. CB,MTF,,.TDECD,0,<Maximum transmit frame size for circuit>
ENTRY. CB,RPV,,.TDECD,0,<Remote protocol version and ECO>
ENTRY. CB,MSL,,.TDECD,0,<Maximum slots allowed by remote>
ENTRY. CB,NBF,,.TDECD,0,<Additional transmit buffers allowed by remote>
ENTRY. CB,CTI,,.TDECD,0,<Value of remote's circuit timer>
ENTRY. CB,KTI,,.TDECD,0,<Value of remote's keep-alive timer>
ENTRY. CB,PTC,,.TDECD,0,<Product type code for remote node>
ENTRY. CB,STA,,.TDECD,0,<Virtual circuit state>
ENTRY. CB,NUM,,.TDECD,0,<Remote's system number>
ENTRY. CB,RSC,,.TDECD,0,<Remote's system name count>
ENTRY. CB,RLC,,.TDECD,2,<Remote's location text count>
ENTRY. CB,KAV,,.TDECD,0,<Host keep alive timer value in ms.>
ENTRY. CB,KAT,,.TDECD,0,<TODCLK last time message received from server>
>;END CBLMAC

DEFINE CCLMAC,<
ENTRY. CC,RCV,,.TDECD,0,<Messages received>
ENTRY. CC,XMT,,.TDECD,0,<Messages transmitted>
ENTRY. CC,RTR,,.TDECD,0,<Messages retransmitted>
ENTRY. CC,SEQ,,.TDECD,0,<Receive message sequence errors>
ENTRY. CC,IMR,,.TDECD,0,<Illegal messages received>
ENTRY. CC,ISR,,.TDECD,0,<Illegal slots received>
ENTRY. CC,RES,,.TDECD,0,<Resource errors>
ENTRY. CC,MSK,,.TDECD,0,<Illegal message error mask>
>;END CCLMAC
	SUBTTL	SLOT BLOCK data structure definitions

DEFINE SLTMAC,<
ENTRY. SB,LNK,,.TXWDW,0,<Queue link word (must be first)>
ENTRY. SB,SDP,,.TBOOL,0,<Slot data present (must be sign bit)>
ENTRY. SB,REJ,,.TBOOL,0,<Send REJECT slot>
ENTRY. SB,STR,,.TBOOL,0,<Send START Slot>
ENTRY. SB,FOU,,.TBOOL,0,<Flush output>
ENTRY. SB,OUT,,.TBOOL,0,<Output data available>
ENTRY. SB,FCC,,.TBOOL,0,<Flow control change>
ENTRY. SB,STO,,.TBOOL,0,<Send STOP Slot (Must be last)>
ENTRY. SB,ATS,,.TDECD,0,<Maximum attention slot size>
ENTRY. SB,MDS,,.TDECD,0,<Maximum slot data size>
ENTRY. SB,STA,,.TSLTS,0,<Slot state>
ENTRY. SB,RID,,.TOCTW,0,<Remote slot id>
ENTRY. SB,LID,,.TOCTW,0,<Local slot id>
ENTRY. SB,XCR,,.TDECD,0,<Transmit credits available to us>
ENTRY. SB,RCR,,.TDECD,0,<Receive credits still outstanding>
ENTRY. SB,REA,,.TDECD,0,<Reason code for stop or reject>
ENTRY. SB,SNC,,.TDECD,0,<Source slot name count>
;ENTRY. SB,SNM,,.TDECD,0,<Source slot name (16 characters max)>
ENTRY. SB,TDB,,.TXWDW,0,<Terminal data block>
ENTRY. SB,CBA,,.TXWDW,0,<Circuit block address for this slot>
>; END SLTMAC
	SUBTTL	Data Structure Definitions - PSB (PRT STORAGE BLOCK)

DEFINE PSBMAC,<
ENTRY. PS,NXT,,.TXWDW,0,<Pointer to next channel block>
ENTRY. PS,PCB,,.TXWDW,0,<Port control block base address (virtual)>
ENTRY. PS,PBA,,.TXWDW,0,<Port control block physical base address>
ENTRY. PS,PTT,,.TXWDW,0,<Virtual address of protocol type table>
ENTRY. PS,MTT,,.TXWDW,0,<Virtual address of multicast address table>
ENTRY. PS,INT,,.TXWDW,0,<Interrupt level control buffer>
ENTRY. PS,NON,,.TXWDW,0,<Non-interrupt level control buffer>
ENTRY. PS,LPT,,.TXWDW,0,<Load PTT table buffer address>
ENTRY. PS,LMT,,.TXWDW,0,<Load multicast address table buffer address>
ENTRY. PS,WSI,,.TXWDW,0,<Write station info buffer address>
ENTRY. PS,RSI,,.TXWDW,0,<Read station info buffer address>
ENTRY. PS,SLS,,.TBOOL,0,<Line state needs reported>
ENTRY. PS,WUL,,.TBOOL,0,<Waiting for ucode to be loaded>
ENTRY. PS,STP,,.TBOOL,0,<Waiting for port restart>
ENTRY. PS,BIG,,.TBOOL,0,<KNISTP BUGINF reported>
ENTRY. PS,LSI,,.TBOOL,0,<Need to write station information>
ENTRY. PS,LMC,,.TBOOL,0,<Need to do load multicast table command>
ENTRY. PS,LPP,,.TBOOL,0,<Need to do load protocol table command>
ENTRY. PS,VAD,,.TBOOL,0,<PSHAD/LAD is valid>
ENTRY. PS,RUN,,.TBOOL,0,<Channel is running, should be 1B0>
ENTRY. PS,SST,,.TOCTW,0,<Channel substate>
ENTRY. PS,EXS,,.TOCTW,0,<Channel external state>
ENTRY. PS,HAD,,.TXWDW,0,<Stored high order station address>
ENTRY. PS,LAD,,.TXWDW,0,<Stored low order station address>
ENTRY. PS,SAD,,.TXWDW,0,<Shadowed address>
ENTRY. PS,HRA,,.TXWDW,0,<Stored high order rom address>
ENTRY. PS,LRA,,.TXWDW,0,<Stored low order rom address>
ENTRY. PS,CRC,,.TBOOL,0,<Allow receipt of frames with CRC errors>
ENTRY. PS,PMC,,.TBOOL,0,<Station is in promiscious multicast mode>
ENTRY. PS,H40,,.TBOOL,0,<H4000 mode if 1>
ENTRY. PS,PRM,,.TBOOL,0,<Promiscious mode if 1>
ENTRY. PS,SVA,,.TOCTW,0,<Shadowed variables (what the port contains)>
ENTRY. PS,VCR,,.TBOOL,0,<PSCRC is valid>
ENTRY. PS,VPM,,.TBOOL,0,<PSPMC is valid>
ENTRY. PS,VH4,,.TBOOL,0,<PSH40 is valid>
ENTRY. PS,VPR,,.TBOOL,0,<PSPRM is valid>
ENTRY. PS,RSP,,.TDECD,0,<Maximum number of entries on the response queue>
ENTRY. PS,CHN,,.TOCTW,0,<Logical channel number>
ENTRY. PS,CBA,,.TOCTW,0,<CBUS address>
ENTRY. PS,CHK,,.TXWDW,0,<Check word, contains magic value>
ENTRY. PS,TLR,,.TXWDW,0,<Time of last response>
ENTRY. PS,CNO,,.TXWDW,0,<CONO KNI,(T1)>
ENTRY. PS,CNI,,.TXWDW,0,<CONI KNI,T1>
ENTRY. PS,DTO,,.TXWDW,0,<DATAO KNI,T1>
ENTRY. PS,DTI,,.TXWDW,0,<DATAI KNI,T1>
ENTRY. PS,CQA,,.TXWDW,0,<CONO KNI,CO.BTS+CO.CQA or NOP>
ENTRY. PS,MXT,,.TDECD,0,<# Of multicasts transmitted>
ENTRY. PS,UMA,,.TOCTW,0,<Major version #>
ENTRY. PS,UMI,,.TOCTW,0,<Minor version #>
ENTRY. PS,UED,,.TOCTW,0,<Edit #>
ENTRY. PS,TPC,,.TXWDW,0,<UDT of port crash>
ENTRY. PS,LAR,,.TXWDW,0,<LAR at time of Ucode crash>
ENTRY. PS,CRL,,.TXWDW,0,<Left hand CRAM bits at time of crash>
ENTRY. PS,CRR,,.TXWDW,0,<Right hand CRAM bits at time of crash>
ENTRY. PS,TLZ,,.TTIME,0,<Time at which port counters were zeroed>
ENTRY. PS,SHC,,.TXWDW,0,<Address of shadow counters block>
> ;END PSBMAC
	SUBTTL	Data Structure Definitions - PTB (PORTAL TABLE BLOCK)

DEFINE PTBMAC,<
ENTRY. PR,NXT,,.TXWDW,0,<Pointer to next block (must be first)>
ENTRY. PR,CLO,,.TBOOL,0,<Portal is closing>
ENTRY. PR,PAD,,.TBOOL,0,<PAD flag>
ENTRY. PR,MYP,,.TOCTW,0,<Bit value for my portal>
ENTRY. PR,BSZ,,.TOCTW,0,<Receive buffer size>
ENTRY. PR,UID,,.TXWDW,0,<What user wants on call back>
ENTRY. PR,PMD,,.TOCTW,0,<Packing mode>
ENTRY. PR,PRO,,.TOCTW,0,<Protocal type>
ENTRY. PR,CHN,,.TDECD,0,<Physical channel>
ENTRY. PR,MUL,,.TXWDW,0,<Bit vector of enabled multicasts>
ENTRY. PR,POS,,.TXWDW,0,<Address of posting address vector>
ENTRY. PR,CHK,,.TXWDW,0,<Address of this block (consistency check)>
ENTRY. PR,FQA,,.TXWDW,0,<Free queue header address>
ENTRY. PR,TLZ,,.TTIME,0,<Time at which counters were zeroed>
ENTRY. PR,BYR,,.TDECD,0,<Bytes received>
ENTRY. PR,DGR,,.TDECD,0,<Datagrams received>
ENTRY. PR,BYS,,.TDECD,0,<Bytes sent>
ENTRY. PR,DGS,,.TDECD,0,<Datagrams sent>
ENTRY. PR,UBU,,.TXWDW,0,<User buffer unavailable>
> ;END PTBMAC
      SUBTTL Expand the Table Building Macros

        DOBLK GBB
        DOBLK HNB
	DOBLK CBL
	DOBLK HCB
	DOBLK CCL
	DOBLK SLT
	DOBLK PSB
	DOBLK PTB
	SUBTTL LAT Block-Finding Code

	SUBTTL TYPCBL - Type out LAT's CB Table

;Call:
;	CALL TYPCBL
;	  Error return to stop DPY loop
;	Normal return

TYPCBL::SAVEAC P1
	STKVAR <CBLADR>
	MOVX T1,HN.LEN          ;Read all of the HN block,
	MOVE T2,LAHNDB##        ; pointer from T2
	XMOVEI T3,NODBLK	; to NODBLK
	CALL XPEEKX		;  by way of XPEEK
	 ERR ?Can't XPEEK LAT's CB block

	MOVX T1,CB.LEN          ;Read all of the CBL block,
	LOAD T2,HNQAC,+NODBLK   ;Get addr of first active circuit
	SKIPN T2
	  ERR %No active LAT circuits
	MOVEM T2,CBLADR         ;Save address of CB
	XMOVEI T3,NODBLK	; to NODBLK
	CALL XPEEKX		;  by way of XPEEK
	 ERR ?Can't XPEEK LAT's CB block

	MOVE P1,SCNCHN          ;Get 'channel' number
	DO.
	  SOJLE P1,ENDLP.
	  MOVX T1,CB.LEN        ;Read all of the CBL block,
	  LOAD T2,CBLNK,+NODBLK ;Get addr of first active circuit
	  SKIPN T2
	    ERR %No more active LAT circuits
	  MOVEM T2,CBLADR
	  XMOVEI T3,NODBLK	; to NODBLK
	  CALL XPEEKX		;  by way of XPEEK
	   ERR ?Can't XPEEK CB block
	  LOOP.
	ENDDO.

	MOVEI T1,[ASCIZ "LAT's CB block #"]
	CALL .TSTRG		;Type out text
	SKIPG T1,SCNCHN          ;Get 'channel' number
	 MOVEI T1,1
	CALL .TDECD
	MOVEI T1,[ASCIZ ", at address "]
	CALL .TSTRG		;Type out text
	MOVE T1,CBLADR		;Get address of CBL block
	CALL .TXWDW		; and type in halfword format

	CALL .TCRLF		;Give a CRLF before typing name strings
	CALL .TCRLF		; and another one
	XMOVEI T1,CB.SNM+NODBLK ;Pointer to System name
	CALL .TSTRG		;Type out text
	CALL .TCRLF
	XMOVEI T1,CB.LOC+NODBLK ;Pointer to Location String
	CALL .TSTRG		;Type out text
	CALL .TCRLF		;Give a CRLF before typing table
	CALL .TCRLF		; and another one
	MOVE T1,CBLPTR          ;Get AOBJN pointer to CBL table
	CALL TYPBLK##		; and write HC to screen
	RETSKP			;Return success to allow a new pass
	SUBTTL TYPBLK Service Subrs

;Routine to type out LAT's impression of NI state
;Call:
;	T1/ State Code
;	CALL .THNRN
;	Only Return

.THNRN:	SKIPE T1                ;HNRUN flag set?
	SKIPA T1,[[ASCIZ "Stop"]] ;Yes, that means stop!
	MOVEI T1,[ASCIZ "Run"]    ;No, that means run!
	CALLRET .TSTRG
	SUBTTL TYPSLT - Type out a Message Block

;Call:
;	CALL TYPSLT		;NO ARGS IN ACS
;	  Error Return to stop DPY loop
;	normal Return

TYPSLT::CALL GETTDB		;GET THE TDB FOR THIS TERMINAL
	 RET			;FAILED
	LOAD T1,TLTYP,+NODBLK	;GET THE TERMINAL TYPE
	CAIE T1,5		;LAT TERMINAL?
	 ERR ?Specified terminal is not a LAT terminal
	MOVEI T1,SB.LEN		;LENGTH OF SLOT BLOCK
	LOAD T2,TTDEV,+NODBLK	;GET DEVICE SPECIFIC CODE
	MOVEM T2,NODADR		;SAVE IT
	MOVEI T3,NODBLK		;INTO NODE BLOCK
	CALL XPEEKX		;READ IT
	 ERR ?Failed to read Slot Block
	MOVEI T1,[ASCIZ /SLOT Block at /]
	CALL .TSTRG		;HEADER TEXT
	MOVE T1,NODADR		;GET ADDRESS OF SLOT BLOCK
	CALL .TXWDW		;DISPLAY IT
	CALL .TCRLF		;<CRLF>
	CALL .TCRLF		;<CRLF>
	MOVE T1,SLTPTR		;GET AOBJN POINTER TO MBBTBL
	CALL TYPBLK		;TYPE OUT THE SB
	RETSKP			;SUCCESS RETURN

;
;DISPLAY THE SLOT STATE AS 'HALTED' OR 'RUN'
;
.TSLTS:	SKIPN T1		;RUN?
	SKIPA T1,[[ASCIZ/HALTED/]] ;NO. HALTED
	MOVEI T1,[ASCIZ/RUN/]	;YES. SAY SO
	CALLRET .TSTRG		;SHOW IT
	SUBTTL TYPPSB - DISPLAY A PORT STORAGE BLOCK

;Call:
;	CALL TYPPSB		;NO ARGS IN ACS
;	  Error Return to stop DPY loop
;	normal Return

TYPPSB::SKIPN T2,CHNBAS		;GET ADDRESS OF FIRST PSB
	 ERR ?No PSB for specified channel value
	MOVE P1,SCNIDX		;GET THE INDEX COUNT
NXTPSB:	SOJL P1,DOPSB		;IS THIS THE PSB WE WANT?
	CALL GETPSB		;NO. READ ADDRESS OF NEXT PSB INTO T2
	 ERR ?No PSB for specified channel value
	JRST NXTPSB		;SEE IF THIS IS THE ONE WE WANT
DOPSB:	MOVEM T2,NODADR		;SAVE ADDRESS OF THIS BLOCK
	MOVEI T1,PS.LEN		;LENGTH OF PSB TO READ
	MOVEI T3,NODBLK		;STORE DATA IN NODE BLOCK
	CALL XPEEKX		;READ THE BLOCK
	 ERR ?Couldn't read PSB
	MOVEI T1,[ASCIZ/PSB number /]
	CALL .TSTRG		;HEADER TEXT
	MOVE T1,SCNIDX		;GET INDEX NUMBER
	CALL .TDECD		;DISPLAY IT
	MOVEI T1,[ASCIZ/ at address /]
	CALL .TSTRG		;SHOW IT
	MOVE T1,NODADR		;GET ADDRESS OF THIS BLOCK
	CALL .TXWDW		;DISPLAY IT
	CALL .TCRLF		;SEPARATE IT
	CALL .TCRLF		;...
	MOVE T1,PSBPTR		;GET THE BLOCK POINTER
	CALL TYPBLK		;AND DISPLAY THIS PSB
	RETSKP			;DONE

; GETPSB - READ ADDRESS OF NEXT PSB
; CALL:
;	CALL GETPSB	T2/ADDRESS OF THIS PSB
; RETURNS:
;	+1:	FAILED
;	+2:	SUCCESS, ADDRESS OF NEXT BLOCK IN T2

GETPSB:	ADDI T2,PS.NXT		;MAKE ADDRESS OF NEXT PSB
	MOVEI T1,1		;ONE WORD
	MOVEI T3,NODADR		;WHERE TO STORE ADDRESS OF BLOCK
	CALL XPEEKX		;GET NEXT PSB ADDRESS
	 ERR ?Couldn't read address of next PSB
	SKIPN T2,NODADR		;IS THERE ANOTHER BLOCK?
	 RET			;NO RETURN +1
	RETSKP
	SUBTTL TYPPTB - DISPLAY A PORTAL TABLE BLOCK

;Call:
;	CALL TYPPTB		;NO ARGS IN ACS
;	  Error Return to stop DPY loop
;	normal Return

TYPPTB::SKIPN T2,PORBAS		;GET ADDRESS OF FIRST PTB
	 ERR ?No PTB for specified index
	MOVE P1,SCNIDX		;GET THE CHANNEL COUNT
NXTPTB:	SOJL P1,DOPTB		;IS THIS THE PTB WE WANT?
	CALL GETPTB		;NO. READ ADDRESS OF NEXT PTB INTO T2
	 ERR ?No PTB for specified channel value
	JRST NXTPTB		;SEE IF THIS IS THE ONE WE WANT
DOPTB:	MOVEM T2,NODADR		;SAVE ADDRESS OF THIS PTB
	MOVEI T1,PR.LEN		;LENGTH OF PTB TO READ
	MOVEI T3,NODBLK		;STORE DATA IN NODE BLOCK
	CALL XPEEKX		;READ THE BLOCK
	 ERR ?Couldn't read PTB
	MOVEI T1,[ASCIZ/PTB number /]
	CALL .TSTRG		;HEADER TEXT
	MOVE T1,SCNIDX		;GET INDEX NUMBER
	CALL .TDECD		;DISPLAY IT
	MOVEI T1,[ASCIZ/ at address /]
	CALL .TSTRG		;SHOW IT
	MOVE T1,NODADR		;GET ADDRESS OF THIS BLOCK
	CALL .TXWDW		;DISPLAY IT
	CALL .TCRLF		;SEPARATE IT
	CALL .TCRLF		;...
	MOVE T1,PTBPTR		;GET THE BLOCK POINTER
	CALL TYPBLK		;AND DISPLAY THIS PTB
	RETSKP			;DONE

; GETPTB - READ ADDRESS OF NEXT PTB
; CALL:
;	CALL GETPTB	T2/ADDRESS OF THIS PTB
; RETURNS:
;	+1:	FAILED
;	+2:	SUCCESS, ADDRESS OF NEXT BLOCK IN T2

GETPTB:	ADDI T2,PR.NXT		;MAKE ADDRESS OF NEXT PTB
	MOVEI T1,1		;ONE WORD
	MOVEI T3,NODADR		;WHERE TO STORE ADDRESS OF BLOCK
	CALL XPEEKX		;GET NEXT PTB ADDRESS
	 ERR ?Couldn't read address of next PTB
	SKIPN T2,NODADR		;IS THERE ANOTHER BLOCK?
	 RET			;NO RETURN +1
	RETSKP
	SUBTTL End of Program

	END