Google
 

Trailing-Edge - PDP-10 Archives - BB-FP64A-SB_1986 - 10,7/nettst/nettst.mac
There are 3 other files named nettst.mac in the archive. Click here to see a list.
TITLE	NETTST - TEST'S LPT COMPRESSION AND TASK/TASK STUFF
SUBTTL	RIC WERME, SEPT. 1976

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1978,1979,1980 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.

	SEARCH	TULIP,	NETUNV		;TULLIB/ET AL DEFINITIONS
	SEARCH	JOBDAT,	MACTEN,	UUOSYM	;STANDARD DEFINITIONS
	SEARCH	DTEPRM			;SPECIAL DEFINITIONS
	SALL				;PRETTY LISTINGS
	.DIRECT	FLBLST			;PRETTIER LISTINGS

	.TEXT	"/SEARCH/SEG:LOW NETLIB,MACLIB,TULLIB"
VERSION(6,,40)

;The revision history, such as it is

;40	RDH	1-Apr-84
;	Add support for TTY devices: PIMINP/PIMOUT/IMGINP/IMGOUT commands
;	to select I/O modes; NOECHO command to light IO.SUP to suppress
;	ASCII TTY echo; teach test pattern routines about TTY-specific
;	"aspects" (like the extra <LF> in ASCII mode...).
;SYMBOLS
FTGET==1
PCBIAD==2			;MONITOR DATA BASE OFFSETS
PCBICT==3
MON==400000			;SPYSEG OFFSET
PDLLEN==100
.JBREN=:124			;REENTER ADDRESS
CMDMAX==^D12			;CHEAPER BY THE DOZEN
ETCCPN==10			;NUMBER OF CPUS IN COMM REGION
ETCSIZ==400			;MORE THAN SIZE OF COMM REGION
FILGET==FILFEX			;TEST DEVICE HAS EXTRA DATA. THIS OPENS IT
FILFIL==FILFEX+1		;THIS DOES LOOKUP OR ENTER
FILBUF==FILFEX+2		;THIS DOES INBUF OR OUTBUF

.GTNET==141			;NETWORK PERFORMANCE GETTAB
DEFINE GDEF(NAM)<
    IRP NAM,<%NT'NAM==<XX==XX+1>,,.GTNET>>
XX==-1
GDEF<COR,MAX,AVG,BAD,RTP,RMT,RDL,XTP,XMT,XDL,BLC>

;IO CHANNELS
TTY==0
DEV==1
FOX==2
LOG==4
TLK==5
FLAG(BADCMD)			;SET DURING LEXINT SCAN
FLAG(NOSPY)			;SET IF SPY CALLI FAILS
FLAG(F.NODL)			;SET TO REMEMBER TO LIST ALL NODES
FLAG(DEVOPN)			;GOT OUR DEV
FLAG(F.COMP)			;SET WHEN DOING "ONES" COMMAND
FLAG(F.ASCI)			;SET IF DOING "ASCIMP" OR "ASCOUT"
FLAG(F.BIN)			;SET IF DOING "BININP" OR "BINOUT"
FLAG(F.BYTE)			;SET IF DOING "BYTINP" OR "BYTOUT"
FLAG(F.LOOP)			;SET WHEN INDEFINITLY LOOPING
FLAG(F.READ)			;SET WHEN CHECKING DATA
FLAG(F.HASH)			;SET WHEN PRINTING HASHES AS IT RUNS
FLAG(F.STAT)			;ON TO PRINT STAT RATE STATS
FLAG(F.ECHO)			;SET IN ECHO MODE, SEE DOTEST
FLAG(F.CPRM)			;HACK TO ALLOW CHANGING 2 PARAMS AND GET 1 OUTPUT
FLAG(F.TEMP)			;FLAG FOR COMMAND ROUTINES TO USE
FLAG(F.SLP)			;SET WHEN ROUTINE WANTS TO SLEEP IN LOOP MODE
FLAG(F.PRTA)			;THESE 2 FLAGS CONTROL WHAT MONITOR ROUTINES
FLAG(F.PRTE)			; WILL PRINT. IF F.PRTA IS ON, DATA WILL ALWAYS
				; BE PRINTED. OTHERWISE, IF F.PRTE IS SET, DATA
				; WILL PRINT ONLY WHEN AN ERROR IS DETECTED.
				; IF BOTH ARE OFF, DON'T PRINT AT ALL (GOOD
				; TO SET UP OLD DATA AREA).
FLAG(F.TIME)			;SET AFTER TIMESTAMP PRINTS
FLAG(F.ASYN)			;ON IF USING ASYNCHRONOUS IO
FLAG(F.INTR)			;ON IF INTERRUPT WATCHING
FLAG(F.MPX)			;ON IF USING MPX DEVICE
FLAG(F.TTY)			;ON IF USING TTY DEVICE
F.UERR==:1B0			;UUO ERROR FLAG

OPDEF	GTNTN.	[CALLI	165]	;UUO TO CONVERT TTYNNN TO NODE#,,LINE#
OPDEF	GTXTN.	[CALLI	166]	;UUO TO CONVERT NODE#,,LINE# TO TTYNNN
OPDEF	PJRST	[JRST]
OPDEF	PJUMPN	[JUMPN]

UUO(GET)			;GET AC,[GETTAB]. PUTS RESULT IN AC
UUO(WHALF)			;WRITE HALF WORDS
NETSYM				;DEFINE NETWORK UUOS

ESC==ALT			;A TULIP GLITCH!

;TEST BLOCK OFFSETS:
TSTSET==0			;CALLED AT START OF MESSAGE, BUT ONCE PER ECHO PAIR
TSTSTT==1			;CALLED AT START OF MESSAGE
TSTBYT==2			;CALLED TO OUTPUT NEXT BYTE
TSTEND==3			;CALLED AT END OF TEST
DEFINE	LH(ADDR)<	POINT	18,ADDR,17>
DEFINE	RH(ADDR)<	POINT	18,ADDR,35>
DEFINE	WD(ADDR)<	POINT	36,ADDR,35>
DEFINE	LB(ADDR)<	POINT	8,ADDR,35>
DEFINE	HB(ADDR)<	POINT	8,ADDR,27>
DEFINE	CAL(ADDR)<	PUSHJ	P,D.'ADDR;>

DEFINE	DATXPN(NAME)<
XLIST
DEFINE	X(A,B,C,D)<[SIXBIT\A!\]>
.'NAME'UHD:	DATLST
	[SIXBIT\#!\]
.'NAME'DLN==.-.'NAME'UHD

DEFINE	X(A,B,C,D)<[SIXBIT\B!\]>
.'NAME'LHD:	DATLST
	[SIXBIT\#!\]

DEFINE	X(A,B,C,D)<C>
.'NAME'PTR:	DATLST
	POINT	0,0,0

DEFINE	X(A,B,C,D)<D T4>
.'NAME'PRT:	DATLST
	W2CHI	CRLF

LIST
>

DEFINE	DATHED(NAME)<
	MOVSI	U1,-.'NAME'DLN	;;GET DATA LENGTH
	WSIX	@.'NAME'UHD(U1)	;;PRINT TOP LINE HEADER FRAGMENT
	AOBJN	U1,.-1		;;DO REST
	MOVSI	U1,-.'NAME'DLN	;;DO NEXT LINE
	WSIX	@.'NAME'LHD(U1)
	AOBJN	U1,.-1
>

DEFINE	DATDAT(NAME)<
	PUSH	P,P4		;;WE'LL USE THIS
	MOVSI	P4,-.'NAME'DLN	;;LENGTH OF DATA
	LDB	T4,.'NAME'PTR(P4)
	XCT	.'NAME'PRT(P4)
	AOBJN	P4,.-2
	POP	P,P4
>
SUBTTL	COMMAND DATA MACRO

DEFINE	MONLST<
	XLIST
	X(ASCINP,GETFIL)
	X(ASCOUT,GETFOL)
	X(ASYCHRONOUS,ONOFF,F.ASYN)
	X(BADMON)
	X(BININP,GETFIL)
	X(BINOUT,GETFOL)
	X(BUFFERS,DECLXR##,0)
	X(BYTIN,GETFIL)
	X(BYTOUT,GETFOL)
	X(DDT)
	X(DTE,OCTLXR##,32661)
	X(ECHO,ONOFF,F.ECHO)
	X(ENDLOG)
	X(EXIT)
	X(FILL,DECLXR##,0)
	X(FOX,SIXLXR##,-1)
	X(HASH,ONOFF,F.HASH)
	X(HELP)
	X(IMGINP,GETFIL)
	X(IMGOUT,GETFOL)
	X(INCREMENT,DECLXR##,1)
	X(INTERRUPTS,ONOFF,F.INTR)
	X(LISTEN)
	X(LOOP)
	X(LOG)
	X(LOGFILE,GETFLL)
	X(MPX,ONOFF,F.MPX)
	X(NDBMON)
	X(NETMON)
	X(NOFORM)
	X(NOECHO)
	X(NUMLIN,DECLXR##,^D130)
	X(OCNMON)
	X(ONES)
	X(PARAMETERS)
	X(PAUSE,DECLXR##,^D100)
	X(PERIOD)
	X(PIMINP,GETFIL)
	X(PIMOUT,GETFOL)
	X(RELEASE)
	X(RIPPLE)
	X(SCBMON)
	X(SEND,SIXLXR##,0)
	X(SLEEP,DECLXR##,^D10000)
	X(SPACE)
	X(SPEED,SIXLXR##,15)
	X(STAT,ONOFF,F.STAT)
	X(STLEN,DECLXR##,1)
	X(SUMMARY,DECLXR##,^D<10*60*1000>)
	X(SYMSET)
	X(SCNMON)
	X(TALK,SIXLXR##,SIXBIT\TOPS20\)
	X(TTYMAP,SIXLXR##,SIXBIT\ALL\)
	X(ZEROS)
	LIST
>

DEFINE	X(A,B,C)<NMON==NMON+1>
NMON==0
MONLST				;COUNT NUMBER OF COMMANDS
SUBTTL	LOG FILE MACROS AND STATE DEFINITIONS

DEFINE LOGDSP(TYP)<
	LOGSM1(TYP,NAV,	LOGOP1,	CPOPJ##,CPOPJ##)
	LOGSM1(TYP,AVL,	LOGOP1,	CPOPJ##,CPOPJ##)
	LOGSM1(TYP,DAC,	CPOPJ1,	LOGCL1,	LOGILL)
	LOGSM1(TYP,TAC,	CPOPJ1,	LOGCL1,	LOGILL)
	LOGSM1(TYP,LAC,	CPOPJ1,	CPOPJ##,LOGEN1)
>

;DEFINE LOG FILE STATES:
ZZ==-1
DEFINE	LOGSM1(TYP,NAM)<%LG'NAM==<ZZ==ZZ+1>>
	LOGDSP


;DEFINE MACRO TO MAKE DISPATCH TABLES FOR REST OF CODE

DEFINE	LOGSM1(TYP,NAM,ROPN,RCLS,REND)<
	IFIDN <TYP>,<OPN>,<
		ROPN
		>
	IFIDN <TYP>,<CLS>,<
		RCLS
		>
	IFIDN <TYP>,<END>,<
		REND
		>
>
SUBTTL	INITIALIZATION AND MAIN LOOP

	LOC	.JBREN
	REENTR			;REENTER AT COMMAND INPUT ADDRESS
	RELOC

NETTST:	SETZM	ZSTART
	MOVE	T1,[ZSTART,,ZSTART+1]
	BLT	T1,ZEREND
	MOVE	P,[IOWD PDLLEN,PDL]
	START
	FSETUP	TTYFOH		;SETUP TTY FILE BLOCK
	FOOPEN	TTYFOL		;GET IT
	MOVEI	T1,TTYFOL	;MAKE ERROR DEVICE BE TTY
	MOVEM	T1,EFILE##
	FSETUP	DEVFOH		;SO NOFORM WORKS EARLY
	FSETUP	DEVFIH
	FSETUP	LOGFOH
	MOVX	T1,%CNSIZ	;GET SIZE OF MONITOR DATA BASE
	GETTAB	T1,
	 EDISIX	[PUNT,,[SIXBIT\? "%CNSIZ GETTAB CALL FAILED#!\]]
	SPY	T1,		;LOOK AT IT ALL
	 TXO	F,NOSPY		;DO IT THE SLOW WAY

	MOVE	T1,[.GTSLF,,.GTSLF]
	GETTAB	T1,		;FIND START OF GETTAB DISPATCH
	 EDISIX	[PUNT,,[SIXBIT\? .GTSLF GETTAB CALL FAILED#!\]]
	HRRZM	T1,GTADDR	;SAVE FOR GET UUO
	PUSHJ	P,MAKACT	;MAKE ACTIVE JOB STATE LIST
	MOVX	T1,PS.VIP	;CLEAR ALL IN PROGRESS BITS
	ANDCAM	T1,INTVEC+2	;REALLY SHOULD DO THIS MORE CLEANLY....
	ANDCAM	T1,INTVEC+6
	MOVEI	T1,INTVEC	;TELL MONITOR WHERE INTERRUPT VECTORS ARE
	PIINI.	T1,
	  EWSIX	[SIXBIT\"% PIINI. &FAILED.#!\]
	MOVX	T1,PS.FON	;ALWAYS LEAVE INTERRUPTS ON
	PISYS.	T1,
	  EWSIX	[SIXBIT\"% C&AN'T TURN INTERRUPT SYSTEM ON.#!\]
	;..
	;..
REENTR:
MONMN1:	MOVE	P,[IOWD PDLLEN,PDL] ; FOR REENTER CASE
	FISEL	0
	FOSEL	TTYFOL
	MOVEI	T1,TTYFOL	;ON EACH COMMAND
	MOVEM	T1,INDFOL	;FORCE OUTPUT TO TTY, NOT LOG FILE
	WSIX	[SIXBIT\D&O? !\]
	WCHI	0		;THIS FORCES OUT TTY DATA (SEE TTYOUT)
	MOVEI	T1,LEXTAB	;GET EVERYTHING HE'S INTERESTED IN
	PUSHJ	P,LEXINT##
	  JFCL			;FOR NOW
	TXZE	F,BADCMD	;WAS THERE A PROBLEM?
	 JRST	MONMN1		;YEP, TRY AGAIN

	SETOM	LASHED		;FORCE OUT HEADER IF CHKHED IS CALLED
	TXZ	F,F.LOOP!F.SLP	;CLEAR LOOP FROM LAST CMD
	PUSHJ	P,MONIPC	;PRINT EVERYTHING FIRST TIME THRU
MONLOP:	TXZN	F,F.SLP		;DID A LOOP ROUTINE ASK TO SLEEP?
	 JRST	MONLP1		;NO, DON'T SLEEP
	PUSHJ	P,LOGCLS	;THIS MAY TAKE A WHILE, SO CLOSE LOG FILE
	MOVE	T1,VSLEEP	;GET MILLISECONDS TO SLEEP
	HRLI	T1,(HB.RTC)	;ALSO WAKE ON CHARACTER READY
	HIBER	T1,		;WAIT FOR SYSTEM TO CHANGE
	  JFCL			;IGNORE ERRORS
MONLP1:	PUSHJ	P,MONIPL	;NOW ONLY PRINT ON ERRORS
	MOVN	P1,CMDNUM	;MAKE AOBJN WORD FOR # OF COMMANDS
	JUMPE	P1,MONMN1	;DON'T DO ANYTHING IF NO COMMANDS TYPED
	MOVSI	P1,(P1)		; TO EXECUTE
MONLPL:	PUSHJ	P,@CMDLST(P1)	;YES, DO THE ROUTINE
	FISEL	0		;ENSURE WE'RE STILL TALKING TO TERMINAL
	FOSEL	@INDFOL		; CAUSE SOME ROUTINES CHANGE THEM
	SKPINC			;STOP IF ANYTHING TYPED (FOR LOOP MODE)
	 JRST	MONLPA		;NOT YET
	TRZA	F,F.LOOP	;DON'T LET LOOP TEST PASS, EXIT AOBJN
MONLPA:	AOBJN	P1,MONLPL	;DO THE REST
	MOVEI	T1,1		;KLUDGE: I THINK THIS WILL CLEAR
	HIBER	T1,		;  EWAKEB FOR ME!
	  JFCL
	TXNE	F,F.LOOP	;KEEP GOING?
	 JRST	MONLOP		;YEP
	PUSHJ	P,LOGCLS	;ENSURE LOG FILE CLOSED
	JRST	MONMN1		;GO ASK FOR ANOTHER COMMAND

PUNT:	EXIT
SUBTTL	LEXICAL ANALYSIS

	TBLBEG(LEXTAB)

	PROD(	<SG>		,INI , ,      )	;INIT CMDNUM
MONLEX:	PROD(	-<LETTER!DIGIT!BREAK>	,    ,*,.     )	;DISCARD JUNK
	PROD(	<BREAK>		,RET , ,      )	;STOP ON END OF LINE
	PROD(	<SG>		,MON , ,      )	;GET A SIXBIT ATOM
	PROD(	":"		,COLN, ,MONLEX)	;IF A VALUE, GO GET IT
						; (VALUE READER WILL READ :)
	PROD(	<SG>		,NCLN, ,MONLEX)	;MAKE SURE NO VALUE NEED

	TBLEND

A.INI:	SETZM	CMDNUM		;NO COMMANDS YET TYPED
	POPJ	P,

A.MON:	PUSHJ	P,SIXLXC##	;GET A SIXBIT ITEM
	LDB	T3,[POINT 6,T2,5]; MAKE A MASK
	SETO	T2,
	LSH	T2,(T3)
	MOVE	T3,[-NMON,,MONNAM]
	PUSHJ	P,SIXSRC##	;TRY TO FIND IT
	  TDZA	T3,T3		;FLAG FAILURE BY A ZERO
	TLOA	T3,-1		;FLAG GOOD SWITCH VIA MINUS
	  TXOA	F,BADCMD	;DON'T EXECUTE COMMAND
	MOVE	N,MONCAL(T3)	;GET ROUTINE TO CALL, SAVE BELOW
	POPJ	P,

A.COLN:	JUMPE	T3,SIXLXR##	;IF ILLEGAL CMD, TRY TO THROW AWAY ARG
	PUSHJ	P,SAVCMD	;SAVE COMMAND ROUTINE TO CALL
	SKIPN	T2,CLNDSP(T3)	;BETTER BE DISPATCH INFO
	 DISIX	[SIXLXR##,,[SIXBIT\"% % &DOESN'T REQUIRE A VALUE#!\]
		WNAME	MONNAM(T3)]
	HLRZ	P2,T2		;SAVE ADDRESS OF VARIABLE
	PUSHJ	P,(T2)		;CALL VALUE GETTER
	JUMPE	P2,CPOPJ##	;DON'T STORE IF NO VARIABLE
	MOVEM	T1,(P2)		;REMEMBER IT FOR USERS
	TXO	F,F.CPRM	;RIGHT NOW, ALL THESE ARE PARAMETER SETS
	POPJ	P,		;DONE

A.NCLN:	JUMPE	T3,CPOPJ##	;ILLEGAL COMMANDS GET HERE. IGNORE THEM
;	SKIPE	CLNDSP(T3)	;THIS SHOULD SKIP
;	 DISIX	[CPOPJ##,,[SIXBIT\"% % &REQUIRES A VALUE#!\]
;		WNAME	MONNAM(T3)]
SAVCMD:	AOS	T1,CMDNUM	;CHALK UP ANOTHER COMMAND TO CALL
	CAIGE	T1,CMDMAX+1	;GONE TOO FAR?
	 JRST	SAVCM1		;NOT YET, JUST STORE IT
	EDISIX	[[SIXBIT\"%T&OO MANY COMMANDS, % WILL NOT BE CALLED.#!\]
		WNAME	MONNAM(T3)]
	SOSA	CMDNUM		;BACKUP COMMAND COUNT
SAVCM1:	MOVEM	N,CMDLST-1(T1)	;SAVE COMMAND ADDR TO CALL AT MONLOP
	POPJ	P,
SUBTTL	PARSE LEVEL PROCESSING ROUTINES

ONOFF:	PUSHJ	P,SIXLXR##	;GET AN ON OR OFF
	MOVE	T2,ONOFF1	;T2 WILL BE INSTRUCTION TO HANDLE ERROR
	CAMN	T1,[SIXBIT\ON\]
	 MOVSI	T2,(TDO F,(P2))	; OR "ON"
	CAME	T1,[SIXBIT\OF\]
	 CAMN	T1,[SIXBIT\OFF\]
	  MOVSI	T2,(TDZ F,(P2))	; OR "OFF"
	XCT	T2		;SET OR CLEAR APPROPRIATE FLAG
	MOVE	T1,(P2)		;HACK TO PRESERVE SWITCH VALUE WE USED
	POPJ	P,

ONOFF1:	DISIX	[[SIXBIT\"% % &IS AN ILLEGAL VALUE FOR % - USE &ON& OR &OFF#!\]
		WNAME	T1
		WNAME	MONNAM(T3)]


GETFLL:	MOVEI	T1,LOGFOL	;USE LOG FILE BLOCK
	JRST	GETF1

GETFIL:	SKIPA	T1,[DEVFIL]
GETFOL:	MOVEI	T1,DEVFOL	;FILL AN APPROPRIATE FILE BLOCK
GETF1:	PUSHJ	P,FILLXR##	;BY LETTING LEXINT AND FRIENDS DO IT
	 TXO	F,BADCMD	;REMEMBER WE LOST
	POPJ	P,
SUBTTL	ASCII/BINARY/BYTE, INPUT/OUTPUT OPENS

CASCIN:	JSP	T1,IOOPEN	;CONVERT COMMAND TYPE INTO SMALLER #
CASCOU:	JSP	T1,IOOPEN
CPIMIN:	JSP	T1,IOOPEN
CPIMOU:	JSP	T1,IOOPEN
CBYTIN:	JSP	T1,IOOPEN
CBYTOU:	JSP	T1,IOOPEN
CIMGIN:	JSP	T1,IOOPEN
CIMGOU:	JSP	T1,IOOPEN
CBININ:	JSP	T1,IOOPEN
CBINOU:	JSP	T1,IOOPEN

IOOPEN:	SUBI	T1,CASCIN+1	;T1=IO OPERATION
	ANDCM	F,IOCLR(T1)	;CLEAR BITS NEEDING CLEARING
	IOR	F,IOSET(T1)	;SET BITS NEEDING SETTING
	ROT	T1,-1		;PREPARE FOR DEVICE AND DIRECTION DEPENDENT TESTS
	MOVE	T2,IOMODE(T1)	;GET IO MODE TO USE
	HRRI	T1,DEVFOL	;PROBABLY DO OUTPUT
	JUMPL	T1,.+2		;WON'T WE?
	 MOVEI	T1,DEVFIL	;NO, WE'RE INPUTING
	DPB	T2,[POINT 4,FILSTS(T1),35]
	MOVX	T2,UU.AIO	;FOR ASYNC. IO CHECK
	TXNE	F,F.ASYN	;WANT ASYNC IO?
	 IORM	T2,FILSTS(T1)	;YES, TELL MONITOR
	TXNN	F,F.ASYN	;HAVE TO CHECK FOR NOT WANTING IT TOO
	 ANDCAM	T2,FILSTS(T1)	; IN CASE USER SAYS "ASYN:OFF"

	MOVSI	T3,'MPX'	;READY FOR MPX CHECK
	TXNE	F,F.MPX		;IN MPX MODE?
	 EXCH	T3,FILDEV(T1)	;YES, OPEN MPX INSTEAD

	TXNN	F,F.ECHO	;ECHO MODE?
	 JRST	OPNDE1		;NO, ONLY OPEN ONE SIDE
	FIOPEN	(T1)		;WE WILL BE DOING INPUT
	FENT	(T1)		;AND WILL BE DOING OUTPUT
	INBUF	DEV,@VBUFFE	;SETUP BUFFERS FOR BOTH WAYS
	OUTBUF	DEV,@VBUFFE
	JRST	OPNDE2		;REJOIN COMMON CODE
OPNDE1:	XCT	FILGET(T1)	;OPEN IT
	TXNN	F,F.MPX		;MULTIPLEXED IO?
	 XCT	FILFIL(T1)	;NO, OKAY TO DO LOOKUP OR ENTER
	XCT	FILBUF(T1)	;DO INBUF/OUTBUF
OPNDE2:	TXNN	F,F.MPX		;IN MPX MODE?
	 JRST	OPNDE3		;NO, DON'T HAVE TO CONNECT DEVICE
	MOVEM	T3,FILDEV(T1)	;RESTORE DEVICE TO RIGHTFUL SPOT
	MOVEM	T3,MPXCNT+1	;AND PUT IN CNECT BLOCK
	MOVEI	T2,MPXCNT
	CNECT.	T2,		;TRY TO CONNECT DEVICE
	 EDISIX	[CPOPJ##,,[SIXBIT\? CNECT. &ERROR %#!\]
		WOCT	T2]
	MOVEM	T2,FILMPX(T1)	;SAVE UDX FOR ALL IO ON CHANNEL
OPNDE3:	TXO	F,DEVOPN	;REMEMBER
	TXNE	F,F.INTR	;DO WE WANT INTERRUPTS ON?
	 PUSHJ	P,INTCON	;YES, CONNECT THE DEVICE TO INTERRUPT CHANNEL
	SKIPN	T2,FILMPX(T1)	;GET MPX'ED UDX
	MOVEI	T2,DEV		;NOT ON MPX, USE STRAIGHT CHANNEL INSTEAD
	DEVCHR	T2,		;GET DEVICE CHARACTERISTICS
	TXNE	T2,DV.TTY	;TESTING A TTY-TYPE DEVICE?
	TXOA	F,F.TTY		;YES, BEWARE OF PECULIAR BEHAVIOUR
	TXZ	F,F.TTY		;NO, NO SPECIAL KLUDGERY NEEDED
	POPJ	P,

OOPERR:	ERROOP	DEVFOL		;HERE IF FOOPEN FAILED
	PJRST	STPLOP

ENTERR:	ERRENT	DEVFOL		;OR HERE
	PJRST	STPLOP

IOPERR:	ERRIOP	DEVFIL		;HERE IF FIOPEN FAILED
	PJRST	STPLOP

LKERR:	ERRLK	DEVFIL		;OR HERE
	PJRST	STPLOP
;TABLE OF BITS TO CLEAR AS A FUNCTION OF COMMAND TYPE

IOCLR:	F.BIN!F.BYTE		;ASCII INPUT
	F.BIN!F.BYTE!F.READ	;ASCII OUTPUT
	F.ASCI!F.BIN		;PACKED IMAGE INPUT
	F.ASCI!F.BIN!F.READ	;PACKED IMAGE OUTPUT
	F.ASCI!F.BIN		;BYTE INPUT
	F.ASCI!F.BIN!F.READ	;BYTE OUTPUT
	F.ASCI!F.BYTE		;IMAGE INPUT
	F.ASCI!F.BYTE!F.READ	;IMAGE OUTPUT
	F.ASCI!F.BYTE		;BINARY INPUT
	F.ASCI!F.BYTE!F.READ	;BINARY OUTPUT


;TABLE OF BITS TO SET AS A FUNCTION OF COMMAND TYPE

IOSET:	F.ASCI!F.READ		;ASCII INPUT
	F.ASCI			;ASCII OUTPUT
	F.BYTE!F.READ		;PACKED IMAGE INPUT
	F.BYTE			;PACKED IMAGE OUTPUT
	F.BYTE!F.READ		;BYTE INPUT
	F.BYTE			;BYTE OUTPUT
	F.BIN!F.READ		;IMAGE INPUT
	F.BIN			;IMAGE OUTPUT
	F.BIN!F.READ		;BINARY INPUT
	F.BIN			;BINARY OUTPUT


;TABLE OF I/O MODES AS A FUNCTION OF COMMAND TYPE (DIV 2)

IOMODE:	.IOASC			;ASCII
	.IOPIM			;PACKED IMAGE
	.IOBYT			;BYTE
	.IOIMG			;IMAGE
	.IOBIN			;BINARY
SUBTTL	LOG FILE COMMANDS

;COMMAND TO SPECIFY FILENAME TO LOG DATA ON.
CLOGFI:	MOVEI	T1,%LGAVL	;SAY WE CAN NOW USE THE LOG FILE
	MOVEM	T1,LOGSTT
	PUSHJ	P,LOGOPN	;SO WE CAN PRINT A HEADER
	  JRST	CANTLG		;KEEP OUTPUT ON TTY
	DISIX	[CPOPJ##,,[SIXBIT\##NETTST LOG &FILE STARTED %##!\]
		PUSHJ	P,DATTIM##]


;COMMAND TO START LOGGING OUTPUT FROM SUCCEEDING COMMANDS ON COMMAND LINE
CLOG:	PUSHJ	P,LOGOPN	;TRY TO ACCESS LOG DEVICE
	  JRST	CANTLG		;CAN'T, DON'T LOG
	MOVEI	T1,LOGFOL	;REDIRECT TO LOG FILE BY DEFAULT
	PJRST	INDSET		;SAVE FOR REST OF COMMAND


;COMMAND TO CLOSE LOG FILE IF IT IS OPEN
CENDLO:	PUSHJ	P,LOGEND	;MAKE SURE IT'S CLOSED AND STOP LOGGING
CANTLG:	MOVEI	T1,TTYFOL	;REDIRECT BACK TO TTY SINCE NO LOG FILE
INDSET:	MOVEM	T1,INDFOL
	POPJ	P,
SUBTTL	PARAMETER SETTING ROUTINES

CBUFFE:CSTLEN:CINCRE:CNUMLI:
	TXZN	F,F.CPRM	;CLEAR THIS FIRST TIME THRU
	 POPJ	P,		;SO WE ONLY PRINT THIS ONCE WHEN SEVERAL ARE CHANGED
CPARAM:	DISIX	[[SIXBIT\NUMLIN:%, STLEN:%, INCREMENT:%!\]
		WDEC	VNUMLI
		WDEC	VSTLEN
		WDEC	VINCRE]
	MOVE	T1,VNUMLI	;CALC LENGTH OF LAST MESSAGE
	IMUL	T1,VINCRE	;MAKE TOTAL INCREASE
	SUB	T1,VINCRE	;NEED (NUMLIN-1)*VINCRE+STLEN
	ADD	T1,VSTLEN	;MAKE LENGTH OF LAST
	CAME	T1,VSTLEN	;SAME AS FIRST?
	 DISIX	[[SIXBIT\,& SO &MAXLEN:%!\]
		WDEC	T1]
	TXNN	F,DEVOPN	;RUNNING NOW?
	 JRST	CRPOPJ		;NO, CAN'T CALC MAX POSSIBLE
	MOVE	T2,DEVFOL+FILCTR ;GET NUMBER OF BYTES IF BUFFER (SHOULD BE ACCURATE)
	TXNE	F,F.READ	;READING?
	 MOVE	T2,DEVFIL+FILCTR ;YES, USE RIGHT ONE
	JUMPE	T2,.+2		;IF HAVEN'T DONE ANYTHING, DON'T PRINT
	DISIX	[[SIXBIT\#M&AXIMUM POSSIBLE IS %!\]
		WDEC	T2]
CR2POP:	W2CHI	CRLF		;ONE TO END LINE,
CRPOPJ:	W2CHI	CRLF		; ONE FOR BLANK LINE
	POPJ	P,
SUBTTL	DATA TEST ROUTINES

;COMMAND TO PRINT LINES OF SPACES WITHIN ANGLE BRACKETS. MEANT TO TEST
;NETWORK LPT DATA COMPRESSION.
CSPACE:	JSP	T1,DOTEST	;NO SETUP TO SPEAK OF
	 JFCL			;NO SPECIAL SETUP
	 MOVEI	T1,"<"		;ENCLOSE LPT LINES IN BRACKETS
	 MOVEI	T1," "		;ALWAYS PRINT SPACES
	 MOVE	T1,[BYTE(7)">",CR,LF,0]

;COMMAND TO ACT LIKE ABOVE BUT WITH PERIODS. DESIGNED TO TEST LPT DATA
;COMPRESSION.
CPERIO:	JSP	T1,DOTEST	;SIMILAR TO SPACE
	 JFCL
	 MOVEI	T1,"<"
	 MOVEI	T1,"."		;EXCEPT WE SAY PERIODS
	 MOVE	T1,[BYTE(7)">",CR,LF,0]

;COMMAND DESIGNED TO AVOID LPT DATA COMPRESSION AND LET DROPPED OR ADDED
;CHARACTERS TO BE SPOTTED QUICKLY.
CRIPPL:	MOVEI	T3," "		;INITIALIZE FIRST RIPPLE CHARACTER
	JSP	T1,DOTEST	;STANDARD SORT OF RIPPLE TEST
	 PUSHJ	P,RIPSET	;STARTUP RIPPLE
	 PUSHJ	P,RIPSTT	;PICK UP FIRST CHARACTER
	 PUSHJ	P,RIPBYT	;PRINT NEXT BYTE
	 MOVE	T1,[BYTE(7)">",CR,LF,0]

RIPSET:	CAIGE	T3,176		;HAVE WE GONE TOO FAR?
	 AOJA	T3,CPOPJ##	;NOT YET, RIPPLE TO NEXT CHAR
	MOVEI	T3," "		;YES, RESET TO SPACE
	POPJ	P,

RIPSTT:	MOVE	T2,T3		;USE THE CURRENT START CHARACTER
	MOVEI	T1,"<"		;START WITH BRACKETS
	POPJ	P,

RIPBYT:	MOVE	T1,T2		;USE CURRENT CHARACTER
	CAIGE	T2,176		;REACHED END OF CHARACTER SET?
	 AOJA	T2,CPOPJ##	;NOT YET, DO NEXT
	MOVEI	T2," "		;LOOP AROUND
	POPJ	P,
;COMMANDS DESIGNED TO TEST BINARY DATA COMPRESSION.
CONES:	TXOA	F,F.COMP	;ONLY DIFFERENCE IS IN DATA TYPE
CZEROS:	TXZ	F,F.COMP	;FLOATING 0 ISN'T COMPLEMENTED
	JSP	T1,DOTEST	;DO IT
	 JFCL			;NOTHING SPECIAL FOR EACH MESSAGE
	 SKIPA	T2,[1]		;START AT LOW BIT
	 PUSHJ	P,FLTBYT	;SEND A BYTE
	 CAIA			;DON'T DO ANYTHING AT END

FLTBYT:	TXNE	F,F.BIN		;BINARY?
	 JRST	FLTBY1		;YES, NO NEED TO START OVER
	MOVEI	T3,177		;ASSUME ASCII
	TXNE	F,F.BYTE	;REALLY IN BYTE MODE?
	 MOVEI	T3,377		;YES, THEREFORE AN 8 BIT FIELD
	TRNN	T2,(T3)		;DO WE HAVE DATA TO SEND?
	 MOVEI	T2,1		;NO, START OVER
FLTBY1:	TXNN	F,F.COMP	;ONES MODE?
	 SKIPA	T1,T2		;NOPE, USE AS IS
	SETCM	T1,T2		;GET ONES FORM
	TXNN	F,F.BIN		;IF BYTE MODE (AND ASCII)
	 ANDI	T1,377		;SEND NO MORE THAN 8 BITS
	TXNN	F,F.BIN!F.BYTE	;ASCII MODE?
	 ANDI	T1,177		;JUST SEND THIS MUCH
	ROT	T2,1		;PREPARE FOR NEXT BYTE
	POPJ	P,		;DONE
;ROUTINE TO PERFORM A DATA TEST ON A DEVICE OPENED BY A COMMAND LIKE ASCOUT.
;CALL-
;	JSP	T1,DOTEST
;	<INST TO SETUP FOR A NEW LENGTH MESSAGE>
;	<INST TO RETURN FIRST BYTE OF A MESSAGE>
;	<INST TO RETURN MIDDLE BYTES OF A MESSAGE>
;	<INST TO RETURN TRAILING BYTES OF MESSAGE>
;DOTEST RETURNS TO THE CALLER'S CALLER.

DOTEST:	PUSHJ	P,SAVE4##	;WE'LL BE USING THESE
	FISEL	DEVFIL		;DO ALL IO TO THE DEVICE
	FOSEL	DEVFOL
	MOVEM	P,TSTSTK	;IO ERRORS WILL TRAP AND EXIT ROUTINE CALLS VIA THIS
	MOVE	P4,T1		;SAVE ADDRESS OF OUTPUT INSTRUCTIONS
	SETZM	BYTCNT		;COUNT THE BYTES WE XFER, START AT 0
	SETZM	IONUM		;INIT IO INSTRUCTION COUNTERS
	SETZM	IOFAIL
	MSTIME	P1,		;GET START OF TEST FOR BAUD CALC
	MOVEM	P1,TESTTM	;STASH IN OWN CORNER
	TXNE	F,F.READ	;ARE WE READING?
	 JRST	DOCHCK		;YES, CHECK DATA INSTEAD
	TXNN	F,DEVOPN	;CAN WE?
	 EDISIX	[STPLOP,,[SIXBIT\?C&AN'T OUTPUT TIL DEVICE IS OPENED.#!\]]
	MOVE	T1,[DINERR,,DINERR] ;IN CASE F.ECHO IS SET
	MOVEM	T1,DEVFIL+FILER2
	MOVE	P1,VNUMLIN	;GET MESSAGES TO SEND
	SKIPA	P2,VSTLEN	;AND LENGTH OF FIRST
OUTLIN:	ADD	P2,VINCRE	;MAKE LENGTH OF NEXT LINE
	XCT	TSTSET(P4)	;SETUP FOR NEXT LINE
	PUSHJ	P,SNDLIN	;SEND ONE MESSAGE TO DEVICE
	 JRST	OUTLI1		;ERROR
	TXNE	F,F.ECHO	;IF IN ECHO MODE,
	 PUSHJ	P,RCVLIN	; TRY TO READ IT BACK
	SOJG	P1,OUTLIN	;DO SOME MORE
OUTLI1:	TXNE	F,F.HASH	;HASH MODE?
	 OUTSTR	[CRLF_^D22]	;YES, START A NEW LINE
	STATO	DEV,740000	;ANY ERRORS IN ALL THAT?
	 PJRST	DOSTAT		;NOPE, ALL SET
OUTERR:	ERROUT	DEVFOL		;TELL USER
	PUSHJ	P,DOSTAT	;PRINT STATISTICS
	PJRST	STPLOP		;TRY TO STOP
;HERE FROM DOTEST WHEN DOING INPUT TESTS.

DOCHCK:	TXNN	F,DEVOPN	;CAN WE?
CHKNOP:	 EDISIX	[STPLOP,,[SIXBIT\?C&AN'T CHECK INPUT TIL DEVICE IS OPENED.#!\]]
	MOVE	P1,VNUMLIN	;GET MESSAGES TO SEND
	MOVE	P2,VSTLEN	;AND LENGTH OF FIRST
INPLIN:	XCT	TSTSET(P4)	;SETUP NEXT LINE
	PUSHJ	P,RCVLIN	;READ AND CHECK A MESSAGE
	TXNN	F,F.ECHO	;ECHO IT BACK?
	 JRST	INPLI1		;NO, KEEP GOING
	PUSHJ	P,SNDLIN	;SEND A REASONABLE FACSIMILE
	 JRST	INERR1		;ERROR
INPLI1:	ADD	P2,VINCRE	;ADD LINE INCREMENT
	SOJG	P1,INPLIN	;DO NEXT MESSAGE
	JRST	INERR1		;SKIP OVER DINERR

DINERR:	ERRIN	DEVFIL		;SAY WHAT HAPPENED
	PUSHJ	P,STPLOP	;TURN OFF LOOPING
INERR1:	TXNE	F,F.HASH	;HASH MODE?
	 OUTSTR	[CRLF_^D22]	;YES, START A NEW LINE
	AOSE	T1,ERRCNT	;ANY ERRORS?
	 EDISIX	[[SIXBIT\E&RRORS DETECTED: %#!\]
		WDEC	T1]
DOSTAT:	MOVE	P,TSTSTK	;RECOVER STACK INCASE OF ERROR
	TXNN	F,F.STAT	;WANT BAUD RATE?
	  POPJ	P,		;NOPE
	LDB	T1,[POINT 6,DEVFOL+FILPTR,11] ;GET BYTE SIZE
	TXNE	F,F.READ	;MAKE SURE WE GET RIGHT ONE
	 LDB	T1,[POINT 6,DEVFIL+FILPTR,11]
	TXNE	F,F.TTY		;USING A TTY?
	MOVEI	T1,^D10		;YES, ASSUME 1 START, 7 DATA, 1 PARITY, 1 STOP
	IMUL	T1,BYTCNT	;NUMBER OF BITS
	IMULI	T1,^D1000	;MAKE KILO-BITS TO CANCEL 1000 FROM MSTIME
	MSTIME	T2,		;GET UPTIME NOW
	SUB	T2,TESTTM	;MAKE TIME SINCE START OF TEST
	IDIV	T1,T2		;MAKE BAUD
	ADDI	T1,^D50		;TO ROUND TO 100 BAUD
	IDIVI	T1,^D1000	;T1_KBD
	IDIVI	T2,^D100	;T2_10THS OF A KBD
	EDISIX	[[SIXBIT\R&ATE %.% KBD#!\]
		WDEC	T1
		WDEC	T2]
	TXNN	F,F.ASYN	;DOING ASYNC IO?
	 POPJ	P,		;NO, WON'T BE INTERESTED IN STATISTICS
	MOVE	T1,IONUM	;GET NUMBER OF IO INSTRUCTIONS EXECUTED
	MOVE	T2,IOFAIL	;AND NUMBER OF THOSE THAT FAILED
	SUB	T1,T2		;NUMBER SUCCESSFUL MORE USEFUL
	EDISIX	[CPOPJ##,,[SIXBIT\% IO &INSTRUCTIONS SUCCEEDED, % FAILED.#!\]
		WDEC	T1
		WDEC	T2]
;ROUTINE TO SEND ONE MESSAGE OF THE CURRENT TEST.
SNDLIN:	MOVE	P3,P2		;COPY CURRENT LENGTH TO LOOP COUNTER
	XCT	TSTSTT(P4)	;START LINE
	PUSHJ	P,SNDSTR	;SEND IT OUT
SNDLI1:	SOJL	P3,SNDEND	;STOP WHEN WE RUN OUT
	XCT	TSTBYT(P4)	;SEND A BYTE
	PUSHJ	P,SNDSTR	;SEND IT
	JRST	SNDLI1		;TRY AGAIN

SNDEND:	XCT	TSTEND(P4)	;FINISH MESSAGE
	PUSHJ	P,SNDSTR
	TXNE	F,F.HASH	;HASH MODE?
	 OUTCHR	["#"]
	PJRST	DEVOUT		;FORCE OUTPUT


;ROUTINE TO SEND ONE TO FIVE BYTES OF THE CURRENT MESSAGE
SNDSTR:	TXNN	F,F.BIN		;BINARY MODE IS ALWAYS A SINGLE BYTE
	 TXNN	T1,177B6	;IN ASCII MODE, IF THESE ARE OFF, IT'S A BYTE
	  JRST	SNDBYT		;IT IS, BYTE IT
SNDST1:	ROT	T1,7		;SHIFT CHARACTER INTO LOW BITS
	WCH	T1		;SEND IT
	TXZ	T1,377		;CLEAR CHAR AND BIT 35 IN CASE WE GOT 5 BYTES
	TXNE	T1,177B6	;ANYTHING LEFT?
	 JRST	SNDST1		;YEP, DO SOME MORE
	POPJ	P,		;DONE

SNDBYT:	WCH	T1		;SEND IT
	AOS	BYTCNT		;AND ANOTHER HITS THE BIT BUCKET
	POPJ	P,
;ROUTINE TO RECEIVE AND CHECK ONE MESSAGE OF THE CURRENT TEST.

RCVLIN:	SETOM	ERRCNT		;INIT ERROR COUNTER
	TXNN	F,F.TTY		;IF DATA KNOWN TO BE ALIGNED
	SETZM	DEVFIL+FILCTR	;FORCE INPUT TO HAPPEN (MATCHES DOTEST'S OUTPUT)
	MOVE	P3,P2		;COPY CURRENT LENGTH TO LOOP COUNTER
	XCT	TSTSTT(P4)	;START LINE
	PUSHJ	P,CHKSTR	;CHECK START
RCVLI1:	SOJL	P3,RCVEND	;STOP WHEN WE RUN OUT
	XCT	TSTBYT(P4)	;GET WHAT NEXT BYTE SHOULD BE
	PUSHJ	P,CHKSTR	;CHECK IT
	JRST	RCVLI1		;TRY AGAIN

RCVEND:	XCT	TSTEND(P4)	;FINISH MESSAGE
	PUSHJ	P,CHKSTR	;AND CHECK THAT
	TXNN	F,F.TTY		;IF NOT A TTY
	JRST	RCVEN5		;THEN NORMAL BUFFER-ALIGNMENT CHECK

;SPECIAL TTY DEVICE DATA MASSAGING TO "MAKE IT WORK RIGHT"

	TXNN	F,F.ASCI	;ASCII-MODE TTY TESTING?
	JRST	RCVEN7		;NO, ALL DONE
RCVEN3:	RCH	T1		;YES, SLURP UP ANOTHER CHARACTER
	JUMPE	T1,.-1		;EAT NULLS
	CAIE	T1,.CHLFD	;THIS THE "EXTRA" <LF> CHARACTER?
	JRST	RCVEN3		;NO, KEEP SEARCHING FOR IT
	JRST	RCVEN7		;YES, NOW WE'RE READY FOR THE NEXT LINE

;VERIFY DATA ALIGNMENT WITH DATA BUFFERS FOR NORMAL DEVICES

RCVEN5:	TXNN	F,F.BIN!F.BYTE	;IF IN ASCII MODE,
	 JRST	RCVEN7		;WE PROBABLY HAVE EXTRA NONSENSE. IGNORE IT
	SKIPN	DEVFIL+FILCTR	;ANYTHING LEFT?
	 JRST	RCVEN7		;NO, ALL SET
	EDISIX	[[SIXBIT\% &EXTRA DATA BYTES#!\]
		 WDEC	DEVFIL+FILCTR]
RCVEN6:	MOVEI	T1,'???'	;SPECIAL UNMATCHABLE PATTERN
	PUSHJ	P,CHKBYT	;TRY TO MATCH IT
	SKIPE	DEVFIL+FILCTR	;GOT THEM ALL YET?
	 JRST	RCVEN6		;NOPE, KEEP DIGGING
RCVEN7:	TXNE	F,F.HASH	;HASH MODE?
	 OUTCHR	["#"]
	POPJ	P,
;ROUTINE TO CHECK 1-5 BYTES OF THE CURRENT MESSAGE
CHKSTR:	PUSHJ	P,SAVE2##	;NEED MORE ACS
	TXNN	F,F.BIN		;IF BINARY MODE
	 TXNN	T1,177B6	;OR IF FIRST CHAR=0
	  JRST	CHKBYX		;THEN THERE'S ONLY A BYTE TO CHECK
	MOVE	P1,T1		;COPY GOOD DATA
CHKST1:	ROT	P1,7		;POSITION A BYTE IN RIGHT SIDE
	MOVE	P2,P1		;MAKE A SINGLE CHAR COPY OF IT
	ANDI	P2,177		;CAUSE THAT'S THE ONLY WAY WE CAN COMPARE THEM
CHKST2:	RCH	T1		;GET TEST CHAR
	TXNE	F,F.TTY		;IF A TTY
	TXNN	F,F.ASCI	; IN ASCII MODE
	CAIA			;(IT'S NOT)
	JUMPE	T1,CHKST2	;THEN EAT RANDOM NULLS
	CAME	T1,P2		;BETTER MATCH
	 PUSHJ	P,CHKERR	;ARG.
	TXZ	P1,377		;STRIP CHAR AND BIT 35
	TXNE	P1,177B6	;ANOTHER CHARACTER?
	JRST	CHKST1		;TRY SOME MORE
	POPJ	P,

;ROUTINE TO CHECK ONE BYTE OF THE CURRENT MESSAGE
CHKBYT:	PUSHJ	P,SAVE2		;CALL HERE TO SAVE P1 AND P2
CHKBYX:	MOVE	P2,T1		;PUT WHERE CHKERR EXPECTS
CHKBY1:	RCH	T1		;GET CHAR TO TEST
	TXNE	F,F.TTY		;IF A TTY
	TXNN	F,F.ASCI	; IN ASCII MODE
	CAIA			;(IT'S NOT)
	JUMPE	T1,CHKBY1	;THEN EAT RANDOM NULLS
CHKBY2:	AOS	BYTCNT		;RECORD FOR BAUD RATE CALCS
	CAMN	T1,P2		;MATCH?
	 POPJ	P,		;JUST FINE AND DANDY
CHKERR:	PUSHJ	P,SAVE1##	;SIGH. NO FREE REGISTERS
	TXZ	F,F.LOOP	;ABORT LOOP IF IT WAS ON
	AOSN	P1,ERRCNT	;CHALK IT UP
	 EWSIX	[SIXBIT\#   GOOD     BAD#!\]
	CAIGE	P1,^D10		;TOO MANY TO INTEREST US FURTHER?
	 EDISIX	[[SIXBIT\% %#!\]
		WOCT	7,P2
		WOCT	7,T1]
	POPJ	P,
;COMMAND TO JUST EAVESDROP ON A DEVICE
CLISTE:	PUSHJ	P,SAVE2##	;WHY NOT
	TXNN	F,DEVOPN	;BETTER BE
	 JRST	CHKNOP		;DO DOCHCK'S NOT OPEN STUFF
	FISEL	DEVFIL		;OKAY TO READ FROM THIS
	MOVE	T1,[LINERR,,LINERR] ;USE OUR OWN ERROR ROUTINE
	MOVEM	T1,DEVFIL+FILER2
	MOVE	P1,VNUMLIN	;READ THIS MANY BUFFERS MAX
	TXNN	F,F.BIN!F.BYTE	;SETUP INDEX TO OUTPUT INSTRUCTIONS
	 TDZA	P2,P2		;ASCII
	MOVEI	P2,1		;BINARY OR BYTE
CLIST1:	RCH	T1		;GET A CHARACTER
	XCT	LISTBY(P2)	;PRINT IT
	SKIPE	DEVFIL+FILCTR	;END OF BUFFER?
	 JRST	CLIST1		;NO, DO MORE
	JUMPE	T1,.+2		;IGNORE TRAILING NULLS FOR LF CHECK IN LISTNL
	 MOVE	T2,T1		;NOT A NULL, RECORD IT
	XCT	LISTNL(P2)	;MAKE A NEW LINE
	SOJN	P1,CLIST1	;DO NEXT BUFFER
	PJRST	CRPOPJ

LINERR:	ERRIN	DEVFIL		;SAY WHAT HAPPENED
	PJRST	STPLOP		;AND STOP

LISTBY:	WCH	T1		;ASCII IS ASCII
	DISIX	[[SIXBIT\% !\]
		WOCT	T1]

LISTNL:	PUSHJ	P,[CAIE T2,"J"&37 ;DO CRLF IF LAST CHARACTER DIDN'T
		    W2CHI CRLF
		   POPJ P,]
	W2CHI	CRLF		;ALWAYS IF BINARY
SUBTTL	INTERRUPT COMMAND AND CODE

CINTER:	TXNN	F,DEVOPN	;IS DEVICE OPENED?
	 POPJ	P,		;CAN'T DO ANYTHING 'TIL IT IS!
INTCON:	MOVE	T1,[PS.FAC![DEV
		PS.RID!PS.REF!PS.RIE!PS.ROD!PS.ROE!PS.RDO!PS.ROL
		0]]
	TXNN	F,F.INTR	;WE DID WANT IT ON, DIDN'T WE?
	 HRLI	T1,(PS.FRC)	;NOPE, TURN IT OFF
	PISYS.	T1,		;PUT DEVICE ON INTERRUPT SYSTEM
	 EDISIX	[[SIXBIT\"% PISYS. &ERROR %#!\]
		WOCT	T1]
	POPJ	P,


;INTERRUPT ROUTINES. PRESENTLY ALL WE USE THE INTERRUPT SYSTEM FOR IS A VISUAL
;CHECK OF OPERATION. WHEN WE START RUNNING INTO PROBLEMS, THEN I'LL START
;VERIFYING PROPER OPERATION.

INTERR:	PUSH	P,T1		;JUST LIKE INTDEV
	PUSH	P,T2
	EWSIX	[SIXBIT\I&NTERRUPT TO WRONG INTERRUPT BLOCK"!#!\]
	HRRZ	T1,INTVEC+.PSVFL+4 ;GET REASON BITS
	IORM	T1,INTVEC+.PSVFL ;SAVE FOR INTDEV
	MOVE	T1,INTVEC+.PSVOP+4 ;NEED PC TOO
	MOVEM	T1,INTVEC+.PSVOP
	JRST	INTER1		;JOIN INTDEV CODE

INTDEV:	PUSH	P,T1		;HAVE TO SAVE ALL ACS HERE
	PUSH	P,T2
INTER1:	HRRZ	T1,INTVEC+.PSVFL ;GET FLAGS WORD
	ANDCAM	T1,INTVEC+.PSVFL ;CLEAR THEM OUT
	JUMPN	T1,.+2		;AT LEAST CHECK FOR SOME BITS
	 EWSIX	[SIXBIT\? I&NTERRUPT BUT NO STATUS BITS ARE SET.#!\]
	TXNN	T1,PS.RDO	;IS DEVICE OFFLINE?
	 JRST	INTDE0		;NOPE, DON'T HAVE TO DO MAGIC
	HRRZ	T2,INTVEC+.PSVOP ;GET PC OF WHERE TO RETURN TO
	CAIN	T2,INUUO	;WERE WE DOING INPUT?
	 MOVEI	T2,INFIX	;YES, RETURN TO HIBERNATE
	CAIN	T2,OUTUUO	;GIVE SAME TREATMENT TO OUTPUT
	 MOVEI	T2,OUTFIX
	HRRM	T2,INTVEC+.PSVOP ;SAVE FOR DEBRK.
	HRRM	T2,INTVEC+.PSVOP+4 ;AND IN CASE WE GOT HERE SOMEHOW
INTDE0:	TXNE	F,F.HASH	;ARE WE REALLY INTERESTED?
INTDE1:	 JFFO	T1,INTDE2	;YES, PICK UP A BIT
	  POP	P,T2
	POP	P,T1
	DEBRK.			;DISMISS
	 EDISIX	[CEXIT,,[SIXBIT\? DEBRK. &NOT IMPLEMENTED.#!\]]
	 EDISIX	[CEXIT,,[SIXBIT\? DEBRK. &WHEN NOT IN INTERRUPT CODE.#!\]]

INTDE2:	TDZ	T1,BITTAB(T2)	;TURN OFF THAT BIT
	OUTSTR	@INTCHR-22(T2)	;PRINT ASSOCIATED CHARACTER
	JRST	INTDE1		;SEE IF ANYTHING ELSE
SUBTTL	TERMINAL RELATED COMMANDS

;COMMAND DESIGNED TO SIMULATE MULTIPLE SEND COMMANDS TO ANOTHER TERMINAL.
CSEND:	SKIPN	T2,VSEND	;GET TTY TO USE
	 DISIX	[STPLOP,,[SIXBIT\?M&UST SPECIFY A &TTY#!\]]
	JUMPG	T2,[HLRZ T2,T2	;ASSUME HE LEFT OFF 'TTY'
		    HRLI T2,'TTY' ;SO WE HAVE TO PUT IT BACK
		    JRST .+1]	;RETURN TO MAIN CODE
	IONDX.	T2,		;CONVERT TO UDX FOR TRMOP.
	  DISIX	[STPLOP,,[SIXBIT\?IONDX. &ERROR %#!\]
		WOCT	T2]
	WSIX	[SIXBIT\T&YPE MESSAGE, END WITH &ESC#!\]
	WCHI	0		;FORCE OUT MESSAGE
	MOVE	T1,[BYTE(7)"G"&37,"M"&37,"J"&37,"[","G"&37]
	MOVEM	T1,SNDMSG	;PRECEDE FIRST MSG WITH BELLS AND CRLF
	MOVEI	T1,SNDLEN-6	;GET AMOUNT OF SPACE LEFT IN BUFFER
	MOVE	T4,[POINT 7,SNDMSG+1] ;AND POINTER TO IT
CSEND2:	RCH	T3		;GET A CHARACTER. THIS IS TOO EASY TO
	CAIN	T3,ESC		;  USE LEXINT. ESCAPE?
	 JRST	CRPOPJ		;YES, ALL DONE
	CAIE	T3,CR		;IF CARRIAGE RETURN, CLOSE BRACKETS
	 JRST	CSEND3		;NOPE, KEEP GOING
	MOVEI	T3,"]"		;CLOSE OUT
	IDPB	T3,T4
	MOVEI	T3,CR		;NOW DO THE CARRIAGE RETURN AGAIN
CSEND3:	IDPB	T3,T4		;SAVE CHARACTER TO SEND
	CAIE	T3,"J"&37	;LINE FEED?
	 SOJG	T1,CSEND2	;NOPE, TRY TO PACK MORE
	SETZ	T3,		;ASCIZ STRING NEEDED
	IDPB	T3,T4		;STUFF IN OUTPUT BUFFER
	MOVEI	T1,.TOOUS	;OUTPUT STRING FUNCTION
	MOVEI	T3,SNDMSG	;WHERE PARSE LEVEL STORED IT
	MOVE	T4,[3,,T1]	;PARAMETER FOR TRMOP.
	TRMOP.	T4,
	  DISIX	[STPLOP,,[SIXBIT\?.TOOUS &ERROR %#!\]
		WOCT	T4]
	MOVEI	T1,SNDLEN-2	;ALLOW FULL STRING
	MOVE	T4,[POINT 7,SNDMSG]
	MOVEI	T3,"["		;START OUT WITH A BRACKET
	IDPB	T3,T4		;SO PERSON WHO GETS THIS WON'T BE TOO CONFUSED
	JRST	CSEND2		;DO NEXT LINE
;COMMAND TO COMMUNICATE TO NVTHAK SERVER FOR DECNET TESTING AND USE.

CTALK:	MOVEM	P,SAVEP		;FOR ABORT CODE
	MOVE	T1,VTALK	;GET TARGET NODE
	MOVEM	T1,NODBL2+1
	MOVE	T1,[2,,NODBL2]	;SETUP FOR NODE UUO TO CONVERT TO NUMBER
	NODE.	T1,
	 EDISIX	[CPOPJ##,,[SIXBIT\NODE. UUO &FAILED, CODE %#!\]
		WOCT	T1]
	SETZ	T2,		;SPREAD NUMBER APART
	LSHC	T1,-3		;SEPARATE DIGITS
	LSH	T1,3		;SEPARATE
	LSHC	T1,^D9		;POSITION
	IOR	T1,[SIXBIT\TSK00\] ;MAKE TSK NAME
	FSETUP	TLKFIH		;READY TALK FILE BLOCKS
	FSETUP	TLKFOH
	MOVEM	T1,TLKFIL+FILDEV ;SAVE IT
	FIOPEN	TLKFIL		;READY ONE SIDE
	FENT	TLKFOL		;MAKE CONNECTION
	SETSTS	TTY,IO.SUP!.IOPIM ;GET EVERYTHING WITHOUT ECHOING
CTALK1:	PUSHJ	P,CTALIN	;GET CHARACTER FROM NET
	PUSHJ	P,CTALIT	;PROCESS CHARACTERS FROM TTY
	  JRST	CTAXIT		;^Y TYPED
	TXZE	F,F.TEMP	;OUTPUT PENDING?
	OUTPUT	TLK,		;SHOULD WE CHECK ERRORS?
	MOVX	T1,HB.RIO!^D10000!HB.RTC ;WAIT FOR MORE ACTIVITY
	HIBER	T1,
	  JFCL
	JRST	CTALK1		;DO MORE

CTALIN:	SOSGE	TLKFIL+FILCTR	;ANYTHING THERE?
	 JRST	CTALN1		;NO, DO INPUT
	ILDB	T1,TLKFIL+FILPTR ;GET CHARACTER
	OUTCHR	T1		;PRINT IT
	JRST	CTALIN		;DO MORE

CTALN1:	IN	TLK,		;GET A BUFFER
	  JRST	CTALIN		;GOT ONE
	STATO	TLK,760000	;ERRORS?
	  POPJ	P,		;NO, ASYNC IO SAYS NOTHING THERE
	JRST	CTAABT		;ABORT ON ERRORS
CTALIT:	INCHRS	T1		;TRY TO READ A CHARACTER
	JRST	CPOPJ1##	;NOTHING THERE
	ANDI	T1,177		;CAN'T HANDLE BINARY
	CAIGE	T1,40		;CONTROL?
	 XCT	CTALTB(T1)	;YES, SEE IF ANYTHING MAGIC TO DO
	AOS	(P)		;WE KNOW WE WANT TO KEEP GOING
	TXO	F,F.TEMP	;NOTE THAT WE HAVE TO DO OUTPUT
CTALT2:	SOSGE	TLKFOL+FILCTR	;ROOM LEFT?
	 JRST	CTALT1		;NO, DO OUTPUT
CTALT0:	IDPB	T1,TLKFOL+FILPTR ;STUFF IT
	POPJ	P,

CTALT1:	OUT	TLK,		;SEND IT
	  JRST	CTALT0		;TRY AGAIN
	STATZ	TLK,760000	;ERROR?
	 JRST	CTAABT		;YES, ABORT
	MOVX	T1,HB.RIO	;ASYNC IO WON'T LET US OUTPUT
	HIBER	T1,		;SO WAIT A WHILE
	  JFCL
	JRST	CTALT0		;THEN TRY AGAIN

;HERE WHEN RECEIVE CARRIAGE RETURN
CTALCR:	PUSHJ	P,CTALT2	;SEND CARRIAGE RETURN
	MOVEI	T1,LF		;MAKE REST OF CALL BE LF
	POPJ	P,		;RETURN TO CTALIT

CTAABT:	EWSIX	[SIXBIT\#TTY &DISCONNECTED!\] ;WHY NOT?
	MOVE	P,SAVEP		;RECOVER STACK
CTAXIT:	SETSTS	TTY,.IOASC	;BACK TO SOMETHING REASONABLE
	EWSIX	[SIXBIT\#!\]	;CAN'T USE TTY CHANNEL WITHOUT SAYING FOSEL
	FREL	TLKFIL		;RELEASE TLK CHANNEL
	FOSEL	TTYFOL
	W2CHI	CRLF		;NEED AFTER ^Y
	POPJ	P,		;EXIT TALK COMMAND

CTAOPN:	ERRIOP	TLKFIL
	POPJ	P,

CTAENT:	ERRENT	TLKFIL
	POPJ	P,
CTALTB:	REPEAT	40,<JFCL>

DEFINE	CTALMC(CTRL,INST)<
	  RELOC	  CTALTB+"CTRL"&37
	  INST
>

	CTALMC(@,JRST	CTALIT)
;	CTALMC(M,<PUSHJ P,CTALCR>)
	CTALMC(O,CLRBFO)
	CTALMC(Y,JRST	CTAXIT)

	RELOC	CTALTB+40
;COMMAND DESIGNED TO LOAD DOWN TTYS WITHOUT IMPACTING SYSTEM
;I BELIEVE THAT THE .TOOUS TRMOP. NO LONGER BEHAVES AS DESIRED. DON'T USE
;THIS COMMAND.

CFOX:	PUSHJ	P,SAVE2##	;NEED AC MUCH LATER
	SKIPGE	T2,VFOX		;GET PARAMETER, PLUS MEANS NODE NUMBER
	 JRST	CFOTTY		;  AND MINUS IS TTYNNN
	JUMPE	T2,CFOUDX	;AND ZERO SAYS USE LAST ONE
	SETZ	T1,		;CONVERT SIXBIT TO BINARY IN T1
CFOX1:	LSH	T2,3		;STRIP SIXBIT CHARACTER AWAY
	LSHC	T1,3		;AND MOVE DATA INTO T1
	JUMPN	T2,CFOX1	;DO REST
	PJOB	T2,		;GET OUR JOB NUMBER, USE AS LINE NUMBER
	HRLI	T2,(T1)		;MAKE UUO ARG
	GTXTN.	T2,		;MAKE INTO TTYNNN FORM
	 DISIX	[STPLOP,,[SIXBIT\?C&AN'T ACCESS &TTY& ON NODE %#!\]
		WOCT	T1]
CFOTTY:	SETZB	T1,T3		;MAKE SURE IT'S AVAILABLE TO US
	OPEN	FOX,T1
	  DISIX	[STPLOP,,[SIXBIT\?%& IS NOT AVAILABLE#!\]
		WNAME	T2]
	RELEASE	FOX,
	IONDX.	T2,		;GET IO INDEX FOR TRMOPS
	  DISIX	[STPLOP,,[SIXBIT\?IONDX. &ERROR %#!\]
		WOCT	T2]
	MOVEM	T2,FOXUDX	;REMEMBER WHO WE LAST OUTPUT TO
CFOUDX:	MOVE	T2,FOXUDX	; FOR DEFAULT CASE
	MOVEI	T1,.TOTSP+1000	;SET TRANSMIT SPEED
	MOVE	T3,VSPEED
	MOVE	T4,[3,,T1]
	TRMOP.	T4,
	  DISIX	[[SIXBIT\"%TRMOP. &ERROR % TRYING TO SET SPEED#!\]
		WOCT	T4]
	MOVEI	T1,.TOFLC+1000	;NOW SET FILL CLASS
	MOVE	T3,VFILL	; TO WHATEVER WE WANT
	MOVE	T4,[3,,T1]	;IN CASE OF PREVIOUS ERROR
	TRMOP.	T4,
	  DISIX	[[SIXBIT\"%TRMOP. &ERROR % DOING FILL %#!\]
		WOCT	T4
		WDEC	VFILL]
	MOVEI	T1,.TOOUS	;NOW TO BUSINESS
	MOVEI	T3,FOXSTR	;PRINT FOXES
	MOVE	T4,[3,,T1]
	MOVE	P1,VNUMLIN	;DO THIS MANY (0=INDEFINITE)
CFOX2:	TRMOP.	T4,		;FOX IT
	  DISIX	[STPLOP,,[SIXBIT\?TRMOP. &ERROR % OUTPUTTING STRING#!\]
		WOCT	T4]
	SOJN	P1,CFOX2	;DO REST
	POPJ	P,

FOXSTR:	ASCIZ\THE QUICK BROWN FOX JUMPED OVER THE LAZY NODE'S CTY
\
;SPEED COMMAND. THIS IS ONLY DESIGNED TO INTEREACT WITH THE FOX COMMAND.
CSPEED:	HRLOI	T2,7777		;START POTENTIAL MASK AT 1 CHARACTER
	SKIPA	T1,VSPEED	;GET PARSE LEVEL CODE
CSPEE1:	LSH	T2,-6		;SHIFT ANOTHER CHARACTER
	TDNE	T1,T2		;SKIP WHEN HAVE PROPER MASK
	 JRST	CSPEE1		;NOT YET
	SETCA	T2,		;NEED COMPLEMENT
	MOVE	T3,[-SPDLEN,,SPDTBL]
	PUSHJ	P,SIXSRC##	;TRY TO FIND A MATCH
	  POPJ	P,		;RETURN, SIXSRC PRINTED ERROR
	HRRZM	T3,VSPEED	;FOUND IT, INDEX IS VALUE
	POPJ	P,		;DONE

;TABLE TO CONVERT SPEED TO 4 BIT NUMBER. SIXSRC WANTS IT IN ALPHABETIC
;ORDER BUT IT TURNS OUT THAT INCREASING LENGTH ALSO WORKS.

SPDTBL:	SIXBIT\0\
	SIXBIT\50\
	SIXBIT\75\
	SIXBIT\110\
	SIXBIT\134\
	SIXBIT\150\
	SIXBIT\200\
	SIXBIT\300\
	SIXBIT\600\
	SIXBIT\1200\
	SIXBIT\1800\
	SIXBIT\2400\
	SIXBIT\4800\
	SIXBIT\9600\
	SIXBIT\EXTA\
	SIXBIT\EXTB\
SPDLEN==.-SPDTBL
;COMMAND TO PRINT MAP OF ALL TTYS ON A NODE. CALLED WITH
;NODE NAME/NUMBER READY TO BE PICKED UP.

CTTYMA:	MOVE	T1,VTTYMAP	;GET COMMAND PARAMETER
	CAMN	T1,[SIXBIT\ALL\];WANT ALL OF THEM?
	 JRST	ALLMAP		;YEP.
	MOVEM	T1,NODBL2+1	;SAVE FOR NODE FUNCTION 2 (CVT TO BINARY #)
	MOVEM	T1,NODBL5+1	;AND FOR FUNCTION 5 (GET CONFIG DATA)
	MOVE	T1,[2,,NODBL2]	;GET BINARY NODE NUMBER
	NODE.	T1,
	  JRST	CTTYM1		;COMPLAIN
	MOVSI	T4,(T1)		;SAVE FOR NODE(5) CALLS BELOW
	MOVE	T1,[5,,NODBL5]	;NOW FIND OUT HOW MANY TTYS
	NODE.	T1,
CTTYM1:	 DISIX	[CPOPJ##,,[SIXBIT\?N&O NODE NAMED %#!\]
			WNAME VTTYMAP]
	HLRZ	T1,NODBL5+3	;GET # OF TTYS
	JUMPN	T1,.+2		;BETTER BE SOME
	 DISIX	[CPOPJ##,,[SIXBIT\?N&O &TTY&S ON NODE %#!\]
			WNAME	VTTYMAP]
	WASC	TTYHED
CTTYM2:	FSETUP	TTYPOH		;RESET STRING
	FOSEL	TTYPOL		;OUTPUT TO INTERNAL STRING
	TXZ	F,F.TEMP	;SAY NOTHING WORTH NOTING IN THIS LINE
	DISIX	[[SIXBIT\#%"!!\]
		WOCTI	3,(T4)]
	MOVSI	T2,-10		;DO TERMINALS 10 AT A TIME
CTTYML:	MOVE	T3,T4		;SAVE PARAMETER FROM DESTRUCTION
	GTXTN.	T3,		;GET CORRESPONDING TTY NAME
	 SETZ	T3,		;ASSUME IT ISN'T CONNECTED
	MOVSI	T3,(T3)		;JUST GET THE NUMBER PART
	DISIX	[[SIXBIT\ %!\]
		WSIX	3,T3]
	ADDI	T4,1		;STEP TO NEXT TTY
	JUMPE	T3,.+2		;DID WE JUST PRINT SOMETHING REASONABLE?
	 TXO	F,F.TEMP	;YES, LET'S REMEMBER TO PRINT IT
	AOBJN	T2,CTTYML	;DO REST OF LINE
	WCHI	0		;MAKE OUTPUT STRING BE ASCIZ
	FOSEL	@INDFOL		;OUTPUT TO REAL DEVICE
	TRNE	F,F.TEMP	;WORTH PRINTING?
	 WASC	TTMBUF		;YEP, DO IT
	SUBI	T1,10		;DONE THIS MANY
	JUMPG	T1,CTTYM2	;DO REST OF LINES
	PJRST	CR2POP		;CLEANUP AND EXIT
;HERE IF REQUEST IS TO PRINT ALL TTYS ON SYSTEM.
ALLMAP:	MOVX	T1,%CNLNP	;GET TTY PARAMETERS
	GETTAB	T1,
	  DISIX	[CPOPJ##,,[SIXBIT\?GETTAB FOR "%CNLNP &FAILED#!\]]
	HRRI	T1,0		;MAKE INTO AOBJN POINTER
	WASC	ALLHED		;PRINT WIDER HEADER
	JRST	ALLMA0		;START IN THE MIDDLE

ALLMAL:	TRNE	T1,7		;TIME FOR NEW LINE?
	 JRST	ALLMA2		;NO, KEEP GOING
	WCHI	0		;MAKE OUTPUT STRING BE ASCIZ
	FOSEL	@INDFOL		;OUTPUT TO REAL DEVICE
	TXZE	F,F.TEMP	;SEEN ANYTHING INTERESTING?
	 WASC	TTMBUF		;YES, PRINT IT
ALLMA0:	FSETUP	TTYPOH		;SET UP FOR NEW LINE
	FOSEL	TTYPOL		;STORE IN MEMORY
	TXZ	F,F.TEMP	;ENSURE THIS IS INITIALLY OFF
	DISIX	[[SIXBIT\#%"!!\]
		WOCTI	3,(T1)]
ALLMA2:	MOVEI	T2,(T1)		;COPY LINE NUMBER
	MOVEI	T3,'000'	;TO MAKE SIXBIT
ALLMA1:	LSHC	T2,-3		;MOVE AN OCTIT
	ROT	T3,-3		;SIXBITIZE IT
	JUMPN	T2,ALLMA1	;DO REST
	HLRZ	T3,T3		;COPY FOR GTNTN.
	HRLI	T3,'TTY'	;MAKE REAL TTY NAME
	GTNTN.	T3,		;GET NODE,,LINE
	  DISIX	[ALLMAA,,[SIXBIT\       !\]]
	TXO	F,F.TEMP	;REMEMBER THIS IS A USEFUL LINE
	HLRZ	T2,T3		;BREAK INTO 2
	DISIX	[[SIXBIT\ %_%!\]
		WOCT	2,T2
		WOCTI	(T3)]
	TRNN	T3,700		;KLUDGE TO PRINT 3 LEFT JUSTIFIED DIGITS
	 WCHI	" "		;LESS THAN 100 NEEDS AT LEAST 1 MORE
	TRNN	T3,770		;LESS THAN 10 NEEDS 2 MORE
	 WCHI	" "
ALLMAA:	AOBJN	T1,ALLMAL	;DO REST
	FOSEL	@INDFOL		;BACK TO THE TTY
	PJRST	CR2POP		;ONE TO END LINE, ONE FOR BLANK LINE
TTYHED:	ASCIZ/
  \   0   1   2   3   4   5   6   7
   \--------------------------------/

ALLHED:	ASCIZ/
  \     0      1      2      3      4      5      6      7
   \--------------------------------------------------------/
SUBTTL	DTE20 PROCOTOL COMMANDS

;QUEUED PROTOCOL COMM REGION DUMPER. WOULD BE A LOT MORE USEFUL IF WAS
;MORE INTELLIGENT

CDTE:	TXNN	F,F.PRTA	;ONLY PRINT WHEN EVERYONE ELSE IS TOO.
	 POPJ	P,
	PUSHJ	P,SAVE2##	;NEED A COUPLE
CDTE1:	DATHED(DT)		;SAY WHAT WE'RE DISPLAYING
	MOVSI	T1,-ETCSIZ-ETCCPN ;ABOUT LARGE ENOUGH
COPCR1:	MOVEI	T2,(T1)		;COPY OFFSET INTO COMM REGION TO LOOK AT
	ADD	T2,VDTE		;CONVERT TO ABS. ADDR.
	PEEK	T2,		;GET IT
	MOVEM	T2,LOCHED(T1)	;STORE IN OUR OWN TABLE
	AOBJN	T1,COPCR1	;DO REST

	HRROI	P1,-ETCCPN	;GET NEGATIVE THE NUMBER OF CPUS IN REGION
DTEHE1:	MOVE	T1,LOCRGN(P1)	;GET HEADER WORD
	DATDAT(DT)		;DUMP IT
	AOJL	P1,DTEHE1	;DO REST

	SETZB	P1,P2		;START AT INDEX 0, CPU 0
DTECR1:	PUSHJ	P,DTECAR	;DUMP COMM AREA FOR THIS CPU
	LOAD.	P1,EC.NCA,+LOCRGN(P1) ;GET INDEX OF NEXT AREA
	ADDI	P2,1		;STEP TO NEXT CPU
	JUMPN	P1,DTECR1	;DO NEXT
	PJRST	CRPOPJ
DTECAR:	PUSHJ	P,SAVE2##	;P1/ INDEX, P2/ COUNTER
	PUSHJ	P,DTEOSC	;DUMP OWNER'S SECTION
	LOAD.	P2,EC.NPR,+LOCRGN(P1) ;GET # OF CPUS IN AREA
	ADDI	P1,ETOSIZ*10	;SKIP OVER IT
DTECA1:	SOJLE	P2,CPOPJ##	;STOP WHEN WE RUN OUT
	PUSHJ	P,DTETSC	;DO TO CPU SECTION
	ADDI	P1,ET2SIZ*10	;MAKE INDEX OF NEXT SECTION
	JRST	DTECA1		;DO NEXT

DTEOSC:	PUSHJ	P,SAVE1##	;P1/AOBJN POINTER TO TABLE
	DISIX	[[SIXBIT\##O&WNER'S SECTION, PROCESSOR %#!\]
		WOCTI	(P2)]
	DATHED(DT)
	HRLI	P1,-ETOSIZ*10	;MAKE AOBJN POINTER TO SECTION
DTEOS1:	MOVE	T1,LOCRGN(P1)	;GET WORD FROM SECTION
	DATDAT(DT)		;DUMP IT
	AOBJN	P1,DTEOS1	;DO MORE
	POPJ	P,


DTETSC:	PUSHJ	P,SAVE1##	;P1/AOBJN POINTER
	LOAD.	T1,EC.TPN,+LOCRGN(P1) ;GET CPU #
	LOAD.	T2,EC.10C,+LOCRGN(P1) ;GET QUEUE COUNTS
	LOAD.	T3,EC.11C,+LOCRGN(P1)
	DISIX	[[SIXBIT\#T&O SECTION FOR PROCESSOR %, !\]
		WOCT	T1]
	SKIPGE	LOCRGN(P1)	;SKIP IF -11
	 DISIX	[DTETS2,,[SIXBIT\KL10, !\]]
	LOAD.	T1,EC.DTN,+LOCRGN(P1) ;GET DTE NUMBER
	DISIX	[[SIXBIT\DTE %, !\]
		WOCT	T1]
DTETS2:	DISIX	[[SIXBIT\TO10IC=%, TO11IC=%#!\]
		WOCT	T2
		WOCT	T3]
	HRLI	P1,-ET2SIZ*10	;MAKE AOBJN POINTER TO SECTION
DTETS1:	MOVE	T1,LOCRGN(P1)	;GET DATA WORD
	DATDAT(DT)		;DUMP IT
	AOBJN	P1,DTETS1	;DO REST
	POPJ	P,
;BYTE POINTERS FOR PIECES OF THE -11 WORDS
DEFINE	TOP(ADDR)<	POINT	4,ADDR,3>	;TOP WORD ONLY 4 BITS
DEFINE	MIDDLE(ADDR)<	POINT	16,ADDR,19>	;MIDDLE WORD
DEFINE	MHB(ADDR)<	POINT	8,ADDR,11>	;  HIGH BYTE
DEFINE	MLB(ADDR)<	POINT	8,ADDR,19>	;  LOW BYTE
DEFINE	BOTTOM(ADDR)<	POINT	16,ADDR,35>	;LOW WORD
;USE LB AND HB FOR ITS BYTES

DEFINE	DATLST<
	X(OFF,SET,RH(P1),CAL(WSOCT))
	X(   PDP-10 &FORMAT,   &LEFT ,LH(T1),<WOCT 10,>)
	X(,  ,<WD(<[",,"]>)>,W2CH)
	X(, &RIGHT,RH(T1),<WOCT 6,>)
	X(       PDP-11 &WORDS  ,      &HI,TOP(T1),<WOCT 10,>)
	X(, &MIDDLE,MIDDLE(T1),<WOCT 7,>)
	X(, &BOTTOM,BOTTOM(T1),<WOCT 7,>)
	X(           PDP-11 &BYTES    ,      &LOW,TOP(T1),<WOCT 11,>)
	X(,  &LOW,MLB(T1),<WOCT 5,>)
	X(, &HGH,MHB(T1),<WOCT 4,>)
	X(,  &LOW,LB(T1),<WOCT 5,>)
	X(, &HGH,HB(T1),<WOCT 4,>)
>

	DATXPN(DT)


D.WSOC:	TRNN	T4,400000	;SIGNED?
	 JRST	WSOC1		;NOPE
	W2CHI	" -"		;MAKE IT LOOK NEGATIVE
	MOVN	T4,T4		;MAKE IN RIGHT SENSE
	WCHI	"0"(T4)		;CHEAT - WE KNOW IT'S A SINGLE CHARACTER
	POPJ	P,		;DONE

WSOC1:	WOCT	3,T4		;EASY IF POSITIVE
	POPJ	P,
SUBTTL	NETWORK MONITORING COMMANDS.

;COMMAND TO READ .STB FILES IS IN NETLIB, CALL THERE DIRECTLY.
CSYMSET==LODSYF##		;JUST LOAD SYMBOLS

;COMMAND TO FONDLE THE INTERVAL TIME FOR PRINTING ALL ERROR INFORMATION
CSUMMA:	SKIPN	VSUMMA		;IS THERE A SUMMARY VALUE AT ALL?
	 AOSA	T1,VSUMMA	;NO, MAKE IT MINUTE
	MOVEI	T1,^D60000	;CHANGE MINUTES SUPPLIED
	IMULM	T1,VSUMMA	;TO MILLISECONDS
	POPJ	P,
;COMMAND TO PRINT DDCMP MESSAGE STATISTICS STORED IN NODES AROUND
;THE NETWORK.
COCNMO:	PUSHJ	P,SETNOD##	;LOCK, INIT N, ETC.
	  POPJ	P,		;COULDN'T LOCK
	PUSHJ	P,SAVE1##	;FOR LINE NUMBER COUNTER
	TXO	F,F.SLP!F.TEMP	;FLAG THAT LOOPING MEANS WE HAVE TO SLEEP FIRST
				; F.TEMP REMEMBERS IF WE SHOULD DO CRLF AT END
COCNNL:	MOVSI	P1,-4		;LOOK AT 4 LINES
COCNPL:	NSVEC	@LBLK(P1)	;GET DATA FROM RIGHT LINE BLOCK
	JUMPL	F,COCNPA	;NO SUCH SYMBOL, TRY ANOTHER
	NVGTW	2,LB.STS##	;GET STATUS AND LINK
	JUMPL	F,COCNNA	;GIVE UP IF NODE OFFLINE
	SKIPN	STCDAT##+1	;IS THERE A LINK WORD?
	 ANDI	P1,-1		;NO, FORCE SCAN TO STOP
	MOVE	T1,STCDAT	;GET STATUS WORD
	TRNE	T1,1		;IN START MODE?
	 JRST	COCNPA		;YES, SKIP DATA
	SETOM	SLEDAT		;FLAG THAT WE DON'T HAVE SLE DATA
	NVGTW	2,LB.SLE##	;TRY TO GET SLE DATA
	JUMPL	F,COCNM1	;NODE DOESN'T HAVE THAT INFO
	DMOVE	T1,STCDAT##	;GET SLE DATA
	DMOVEM	T1,SLEDAT	;SAVE FROM FUTURE GETS
COCNM1:	NVGTW	10,LB.OCN##	;GET OCN, ICN INFO
	JUMPL	F,COCNNA	;NODE NOT THERE, ERROR PRINTED
	DMOVE	T1,SLEDAT	;PUT SLE DATA
	DMOVEM	T1,STCDAT##+10	; WHERE NCMP WILL LOOK AT IT
	NCMP	12,@OCNOLD(P1)	;COMPARE THAT TO THE OLD DATA
	PUSHJ	P,CHKCMP	;SHOULD WE PRINT ANYTHING ABOUT THIS?
	  JRST	COCNPA		;NOPE.
	PUSHJ	P,MONCHK	;SHOULD WE PRINT THE HEADER?
	  JRST	COCNO2		;NO, JUST THE DATA
	DATHED(LB)		;TELL HIM WHAT WE'RE DOING
COCNO2:	DATDAT(LB)		;PRINT IT OUT
	TXZ	F,F.TEMP	;REMEMBER TO PRINT CRLF AT END
COCNPA:	AOBJN	P1,COCNPL	;LOOP THROUGH LINES
COCNNA:	AOBJN	N,COCNNL	;DO REST OF THE NODES
	TXNN	F,F.TEMP	;SHOULD WE PRINT CRLF?
	 W2CHI	CRLF		;YEP
	POPJ	P,
LBLK:	ZZ==-1
    REPEAT 4,<
	CONC(LBLK,\<ZZ==ZZ+1>,<##>)
    >

DEFINE	DATLST<
	X(N&ODE  , ID   ,WD(NODNAM##(N)),<WSIX 6,>)
	X( L&INE,  &NUM,RH(P1),<WOCT 5,>)
	X( OUTPUT,   G&OOD,RH(STCDAT),<WOCT 7,>)
	X(-----, NAK&S,RH(STCDAT+1),<WOCT 5,>)
	X(-----,  REP,RH(STCDAT+2),<WOCT 5,>)
	X(-----,  BCC,RH(STCDAT+3),<WOCT 5,>)
	X(-----, ROOM,RH(STCDAT+4),<WOCT 5,>)
	X(  INPUT-,    G&OOD,RH(STCDAT+5),<WOCT 10,>)
	X(-----,  BCC,RH(STCDAT+6),<WOCT 5,>)
	X(-----, NREP,RH(STCDAT+7),<WOCT 5,>)
	X( LB.SLE,  &COUNT,RH(SLEDAT),CAL(SLE))
	X(-------, &STATUS,RH(SLEDAT+1),CAL(SLE))
>

DATXPN(LB)

D.SLE:	SKIPL	SLEDAT		;DOES THIS NODE HAVE SLE DATA?
	 WOCT	7,T4		;YES, PRINT IT
	POPJ	P,		;LOOK FOR MORE
;COMMAND TO PRINT INTERESTING INFORMATION CONTAINED IN ALL SCBS IN
;USE THROUGHOUT THE ENTIRE NETWORK.
CSCBMO:	TXNE	F,F.PRTA	;LIMIT OUTPUT SINCE WE DON'T LOOK FOR ERRORS
	 PUSHJ	P,SETNOD##	;INIT MONITORING ROUTINE
	  POPJ	P,		;COULDN'T LOCK
	PUSHJ	P,SAVE2##	;FOR SCB POINTER AND SB.NNM
	TXO	F,F.SLP		;FLAG THAT LOOPING MEANS WE HAVE TO SLEEP FIRST
CSCBNL:	MOVSI	P1,-SCBN	;LOOP THRU ALL SCBS
CSCBPL:	NSVEC	@SCB(P1)	;SELECT NEXT SCB
	JUMPL	F,CSCBPA	;DOESN'T GO THAT FAR
	NVGTW	1,SB.NNM##	;FIND OUT WHO IT GOES TO
	JUMPL	F,CSCBNA	;NODE MUST BE DOWN
	MOVE	P2,STCDAT##	;SAVE NODE INFO FOR DISPLAY
	NVGTW	3,SB.FLG##	;GET FLAGS AND MESSAGE COUNTS
	JUMPL	F,CSCBNA	;BUT IT WAS JUST THERE!
	MOVE	T1,STCDAT##	;SEE IF SCB IS IN USE
	TRNN	T1,1
	 JRST	CSCBPA		;NO, DON'T SAY ANYTHING ABOUT IT
	NCMP	3,@SCBOLD(P1)	;DID ANYTHING CHANGE WORTH NOTING?
	PUSHJ	P,CHKCMP	;FIND OUT FROM CHKCMP
	  JRST	CSCBPA		;NOPE, TRY NEXT SCB
	PUSHJ	P,MONCHK	;PRINT HEADER?
	 JRST	CSCB1		;NOPE
	DATHED(SB)
CSCB1:	DATDAT(SB)		;PRINT DATA FROM THIS SCB
CSCBPA:	AOBJN	P1,CSCBPL	;LOOP ON SCBS
	W2CHI	CRLF		;SEPARATE EACH NODE
CSCBNA:	AOBJN	N,CSCBNL	;LOOP ON NODES
	POPJ	P,		;UNLOCK AND RETURN
SCB:	OURSCB##		;FIRST TWO SPECIAL ONES
	TENSCB##
	ZZ==-1
    REPEAT SCBN-2,<
	CONC(SCB,\<ZZ==ZZ+1>,<##>)
    >

DEFINE	DATLST(SB)<
	X(N&ODE  , ID   ,WD(NODNAM##(N)),<WSIX 6,>)
	X(SCB, ID,RH(P1),<WOCT 3,>)
	X( NNM,    ,WD(P2),<WOCT 3,>)
	X( HXN,    ,LB(STCDAT+1),<WOCT 4,>)
	X( LAN,    ,HB(STCDAT+1),<WOCT 4,>)
	X( RMN,    ,LB(STCDAT+2),<WOCT 4,>)
	X( TIM,    ,HB(STCDAT+2),<WOCT 4,>)
>

DATXPN(SB)
SUBTTL	NETWORK DATA BASE DUMPER

;COMMAND TO PRINT USEFUL INFORMATION FROM ALL THE NDBS CURRENTLY IN USE
;BY NETSER.
CNDBMO:	TXNN	F,F.PRTA	;ONLY PRINT WHEN EVERYTHING SHOULD BE PRINTED
	 POPJ	P,		;OTHERWISE LOOP NDBMON WOULD PRINT TOO MUCH
	PUSHJ	P,SAVE4##
	TXO	F,F.SLP		;IN CASE LOOP TYPED, WAIT A WHILE
	PUSHJ	P,MONCHK	;PRINT HEADER?
	 JRST	CNDBM1		;NOPE
	DATHED(NB)		;PRINT HEADER
CNDBM1:	MOVSI	P1,-NNDB-1	;EXTRA MINUS ONE FOR AOBJP BELOW
	GET	P2,[%CNNDB]	;GET ADDRESS OF FIRST NDB
CNDBML:	AOBJP	P1,CNDBM2	;JUMP IF NO MORE ROOM TO SAVE NDB ADDRESSES
	MOVEM	P2,NDBADR-1(P1)	;SAVE ADDR OF THIS NDB FOR USE BELOW
CNDBM2:	JUMPE	P2,NDBQ1H	;STOP AFTER STORING THE 0
	MOVEI	N,(P2)		;COPY FOR DATDAT
	HRLI	P2,-NDBLEN	;READ IN AN NDB
	MOVEI	P3,NDBBUF-1	;STORE IT HERE
DONDBL:	HRRZ	T1,P2		;COPY ADDRESS TO GET
	PEEK	T1,		;AND GET IT FROM MONITOR
	PUSH	P3,T1		;SAVE
	AOBJN	P2,DONDBL

	DATDAT(NB)		;PRINT IT ALL
	HRRZ	P2,NDBNNM	;GET ADDRESS OF NEXT ONE
	JRST	CNDBML		;DO IT IF THERE IS ONE
NDBQ1H:	MOVSI	P1,-NNDB	;SCAN ENTIRE NDB LIST
NDBQ1L:	MOVE	P3,NDBADR(P1)	;GET ADDRESS OF CURRENT NDB
	JUMPE	P3,CPOPJ##	;EXIT AFTER LAST NDB
	ADDI	P3,NDBQUE-NDBBUF ;POINT TO LIST HEADER OF UN ACKED MSGS.
	PEEK	P3,		;GET LIST HEADER
	ANDI	P3,-1		;JUST OUTPUT MESSAGES
	JUMPE	P3,NDBQ1A	;NULL LIST MEANS NOTHING TO PRINT
	PUSHJ	P,MONCHK	;PRINT HEADER?
	  JRST	NDBQ11		;NOPE
	DATHED(MS)
NDBQ11:	MOVE	T2,NDBADR(P1)	;GET NDB ADDRESS
	ADDI	T2,NDBSNM-NDBBUF ;POINT TO WORD POINTING TO NAME
	PEEK	T2,		;GET IT
	HLRZ	T2,T2		;POINT TO NAME
	PEEK	T2,		;GET NAME
	DISIX	[[SIXBIT\#M&ESSAGES SENT TO %#!\]
		WNAME	T2]
	MOVSI	P2,-NMSG	;GET ALL THE ADRESSES OF THE MESSAGES ON THE LIST
NDBQ2L:	ANDI	P3,-1		;JUST ADDRESS OF NEXT MESSAGE ON LIST
	MOVEM	P3,MSGADR(P2)	;REMEMBER WHERE IT IS
	JUMPE	P3,NDBQPH	;IF DONE, PRINT THEM OUT
	PEEK	P3,		;GET ADDRESS OF NEXT MESSAGE
	HLLM	P3,MSGADR(P2)	;SAVE FLAGS FOR LAST ONE
	AOBJN	P2,NDBQ2L	;GET SOME MORE
NDBQPH:	MOVSI	P3,-NMSG	;PRINT OUT DATA FROM WHAT WE GATHERED
NDBQPL:	SKIPN	MSGADR(P3)	;STILL MORE TO DO?
	 JRST	NDBQ1A		;NO, TRY NEXT NDB
	DATDAT(MS)		;PRINT DATA ABOUT MESSAGE
	AOBJN	P3,NDBQPL	;DO REST
NDBQ1A:	AOBJN	P1,NDBQ1L	;DO REST OF NDBS
	PJRST	CRPOPJ
DEFINE	DATLST<
	X(,  ADDR,WD(N),<WOCT 6,>)
	X(, NNM,LH(NDBNNM),<WOCT 4,>)
	X(,   NAME,LH(NDBSNM),CAL(PNAM))
	X(, LAR,NDBLAR,<WOCT 4,>)
	X(, LAP,NDBLAP,<WOCT 4,>)
	X(, LMS,NDBLMS,<WOCT 4,>)
	X(, LMA,NDBLMA,<WOCT 4,>)
	X(, LAS,NDBLAS,<WOCT 4,>)
	X(, LMR,NDBLMR,<WOCT 4,>)
	X(, LMP,NDBLMP,<WOCT 4,>)
;;	X(,  ATQ,RH(NDBATQ),CAL(ATQ))
	X(,      NDBQUE   ,WD(NDBQUE),<WHALF 2,>)
>

D.PNAM:	PEEK	T4,		;GET NODE NAME
	WCHI	" "
	WSIX	6,T4		;PRINT SPACE AND NAME
	POPJ	P,

DATXPN(NB)

DEFINE DATLST<
	X(,  &ADDR,RH(MSGADR(P3)),<WOCT 6,>)
	X(, NCN,<POINT 8,MSGADR(P3),17>,<WOCT 4,>)
>

DATXPN(MS)
CNETMO:	TXNN	F,F.PRTA	;ONLY PRINT THIS WHEN TIME FOR SUMMARIES
	 POPJ	P,		;NOT YET.
	PUSHJ	P,SAVE1##	;SAVE ONE OF OUR PERMANENT ACS
	TXO	F,F.SLP		;TO PAUSE IF LOOPING
	PUSHJ	P,MONCHK	;TIMESTAMP
	  JFCL			;WE DON'T HAVE A HEADER
	GET	T1,[%NTCOR]
	GET	T2,[%NTMAX]
	GET	T3,[%NTAVG]
	IDIVI	T3,^D10000
	DISIX	[[SIXBIT\C&ORE%%%%.%#!\]
		WDEC	6,T1
		WDEC	6,T2
		WDEC	6,T3
		TXO	F,LZEFLG
		WDEC	4,T4]
	TXZ	F,LZEFLG
	MOVSI	P1,-6
NETMS1:	WNAME	NETNAM(P1)
	GET	T1,NETSUB(P1)
	LDB	T2,[POINT 9,T1,8]
	MOVSI	T1,(T1)
	HRRI	T1,.GTNET
NETMS2:	GET	T3,T1
	WDEC	6,T3
	ADD	T1,[1,,0]
	SOJGE	T2,NETMS2
	W2CHI	CRLF
	AOBJN	P1,NETMS1
	PJRST	CRPOPJ		;FINISH OFF WITH A BLANK LINE

DEFINE	NETDAT<
	XLIST
	X(RTP,10)
	X(XTP,10)
	X(RMT,10)
	X(XMT,10)
	X(RDL,12)
	X(XDL,12)
	LIST
>

DEFINE	X(A,B)<
	SIXBIT\A\>
NETNAM:	NETDAT

DEFINE X(A,B)<%NT'A>
NETSUB:	NETDAT
DEFINE	BYT(STR)<
	 PUSHJ	P,GETBYT
	 DISIX	[[SIXBIT\STR'!\]
		WOCT	P1]
>

CBADMO:	GET	T1,[%NTBAD]	;HAS THE BAD MESSAGE COUNTER CHANGED?
	CAMN	T1,OLDBAD
	 TXZA	F,F.UERR	;NO, REMEMBER THAT
	 TXO	F,F.UERR	;YES, INCREASE CHANCES OF PRINTING
	MOVEM	T1,OLDBAD	;SAVE FOR NEXT PASS
	PUSHJ	P,CHKCMP	;SHOULD WE PRINT?
	 JRST	[TXO F,F.SLP	;NO, WAIT BEFORE NEXT LOOK
		POPJ P,]
	PUSHJ	P,SAVE4##	;NEED LOTS MORE ACS
	PUSHJ	P,MONCHK	;TIMESTAMP
	  JFCL			;NO HEADER
	GET	T2,[%NTBLC]	;GET POINTERS TO DATA
	HLRZ	T3,T2		;ISOLATE PC
	DISIX	[[SIXBIT\B&AD MESSAGE % FOUND AT %#!\]
		WDEC	OLDBAD
		WOCT	T3]
	TXNE	F,NOSPY
	 DISIX	[CPOPJ##,,[SIXBIT\N&EED &SPY &PRIVS TO GET DATA.#!\]]
	MOVE	P3,MON+PCBIAD(T2);GET BYTE POINTER TO BAD DATA
	ADDI	P3,MON		;"RELOCATE" IT
	HRRZ	P2,MON+PCBICT(T2);ALSO NEED BYTE COUNT
				;  HOPE THE NEXT BAD ONE DOESN'T COME NOW
	MOVEM	P,SAVSTK	;STACK FOR WHEN WE RUN OUT OF MESSAGE
	SETZ	P4,		;FOOL GETBYT LONG ENOUGH TO READ HEADER
	PUSHJ	P,GETBYT	;GET NCT FIELD
	ANDI	T1,7		;INTERESTED ONLY IN MESSAGE TYPE NOW
	MOVEM	T1,MSGTYP	;NEED TO SAVE THAT FOR A WHILE
	DISIX	[[SIXBIT\%(%)!\]
		WNAME	NCMTYP(T1)
		WOCT	P1]
	TRNN	P1,10		;ROUTING HEADER PRESENT?
	 JRST	BADMO1		;NO, SKIP DNA AND SNA FIELDS
	BYT< &TO %>
	BYT< &FROM %>
BADMO1:	BYT<, NCA:%>
	BYT<, NCN:%>
	SKIPE	T1,MSGTYP	;GET MESSAGE TYPE BACK
	 JRST	@NCMDSP(T1)	;DO MESSAGE DEPENDENT PROCESSING
BANMSG:	PUSHJ	P,GETBYT	;NUMBERED MESSAGE. GET DLA FIELD
	JUMPE	P1,BADNCM	;0 MEANS NUMBERED CONTROL MESSAGE, DO IT
	DISIX	[BADMSG,,[SIXBIT\, &LINK %#!\]
		WOCT	P1]
BNODID:
BSTART:	BYT<, NNM:%>
	WSIX	[SIXBIT\ SNM: !\]
	PUSHJ	P,TYPEAS	;PRINT EXTENSIBLE ASCII STRING
	WSIX	[SIXBIT\ SID: !\]
	PUSHJ	P,TYPEAS
	WSIX	[SIXBIT\ &DATE: !\]
	PUSHJ	P,TYPEAS
	JRST	BADMSG

BADNCM:	PUSHJ	P,GETBYT	;GET LENGTH OF SUBMESSAGE
	MOVEI	P4,1(P1)	;REMEMBER FOR GETBYT
	MOVEM	P,SAVST2	;STACK FOR WHEN SUBMESSAGE RUNS OUT
	PUSHJ	P,GETBYT	;GET NUMBERED MESSAGE TYPE
	CAILE	P1,7		;ONLY ALLOW A FEW
	 DISIX	[BADMSG,,[SIXBIT\ % %!\]
		WOCTI	3,-1(P4)
		WOCT	3,P1]
	DISIX	[[SIXBIT\#  %(%)!\]
		WNAME	NCNTYP(P1)
		WOCT	P1]
	PUSHJ	P,@NCNDSP(P1)	;PRINT REST OF SUBMESSAGE
BADNC2:	PUSHJ	P,GETBYT	;GET LEFTOVER BYTES
	WOCT	4,P1
	JRST	BADNC2		;FINISH SUBMESSAGE, GETBYT WILL SEND US TO BADNC1
BCONN:	BYT< DLA:%>
	BYT< SLA:%>
	BYT< DPN:%>
	BYT< SPN:%>
	BYT< MML:%>
	BYT< FEA %>
	POPJ	P,

BDISC:	BYT< DLA:%>
	BYT< SLA:%>
	BYT< RSN:%>
	POPJ	P,

BNGHBR:	BYT< (NNM:%>
	BYT< LVL:%)>
	JRST	BNGHBR

BCONFG:	BYT< (OBJ:%>
	BYT< NDEV:%>
	WSIX	[SIXBIT\ PID: !\]
	PUSHJ	P,TYPEAS
	WCHI	")"
	JRST	BCONFG

BDATRQ:	BYT< DLA:%>
	BYT< DRQ:%>
	POPJ	P,

BADMSG:	SETZ	P4,		;FOR GET REST OF MESSAGE
BADMS1:	PUSHJ	P,GETBYT	;GET A BYTE
	WOCT	4,P1		;PRINT IT
	JRST	BADMS1		;DO REST OF MESSAGE
TYPEAS:	PUSHJ	P,GETBYT	;GET A CHARACTER
	WCHI	(P1)		;PRINT IT
	TRNE	P1,200		;MORE COMING?
	 JRST	TYPEAS		;YES, KEEP GOING
	POPJ	P,		;DONE


GETBYT:	SOJGE	P2,GETBY1	;ANYTHING LEFT?
	MOVE	P,SAVSTK	;NOPE, RESTORE STACK
	PJRST	CRPOPJ		;THIS IS HOW CBADMON EXITS (?!?)

GETBY1:	SOJN	P4,GETBY2	;ANYTHING LEFT IN SUBMESSAGE?
	MOVE	P,SAVST2	;NO,RESTORE STACK
	W2CHI	CRLF		;FORCE OUT MESSAGE
	AOJA	P2,BADNCM	;AND TRY FOR ANOTHER SUBMESSAGE

GETBY2:	ILDB	T1,P3		;GET NEXT BYTE
	MOVEI	P1,(T1)		;MAKE A PERMANENT COPY TOO
	POPJ	P,

DEFINE	SIXREP(LST)<
	XLIST
	IRP LST<<SIXBIT\LST\>>
	LIST
>

NCMDSP:	EXP	BANMSG,BADMSG,BADMSG,BADMSG,BSTART,BADMSG,BNODID,BADMSG

NCMTYP:	SIXREP	<DATA,ACK,NAK,REP,START,STACK,NODEID,ILLGAL>

NCNDSP:	EXP	BADMSG,BCONN,BDISC,BNGHBR,CPOPJ,BCONFG,BDATRQ,BADMSG

NCNTYP:	SIXREP	<ILLGAL,CONN,DISC,NGHBR,REQCNF,CONFIG,DATREQ,STCTRL>
CSCNMO:	PUSHJ	P,SAVE3##
	TXO	F,F.SLP		;WAIT IF LOOPING
	PUSHJ	P,MONCHK	;TIMESTAMP
	  JRST	.+2		;DON'T HAVE TO PRINT HEADER
	WSIX	[SIXBIT\     RCV     XMT    ECHO   ACT SIZE  BAUD#!\]
	GET	T1,[%SCNRI]	;GET RECEIVE INTERRUPTS
	GET	T2,[%SCNXI]	;TRANSMIT
	GET	T3,[%SCNEI]	;AND ECHO
	SUB	T1,OLDRI	;CALCULATE NUMBERS SINCE LAST
	ADDM	T1,OLDRI
	SUB	T2,OLDXI
	ADDM	T2,OLDXI
	SUB	T3,OLDEI
	ADDM	T3,OLDEI
	SUB	T2,T3		;REMOVE ECHO CHARS FROM XMIT
	GET	T4,[%SCNAL]	;GET ACTIVE LINES
	MOVE	P1,T1		;SUM EVERYTHING TO CALC. BAUD
	ADD	P1,T2
	ADD	P1,T3
	GET	P2,[%CVUPT]	;GET UPTIME IN JIFFIES
	SUB	P2,OLDTIM
	ADDM	P2,OLDTIM
	IMULI	P1,^D600	;*10 FOR BITS/CH, *60 FOR JIFFIES/SEC
	IDIV	P1,P2		;DIVIDE # BITS*JIFFIES/SEC BY JIFFIES
	GET	P3,[%SCNMB]	;INCLUDE MAX. BUFFER SIZE
	DISIX	[[SIXBIT\%%%%%%  !\] ;PRINT IT ALL
		WDEC	8,T1
		WDEC	8,T2
		WDEC	8,T3
		WDEC	6,T4
		WDEC	5,P3
		WDEC	6,P1]
	IDIVI	P1,^D500	;P1_ # OF 500 BAUDS (0 TO 10 OR SO)
MSG1:	WCHI	"*"		;AND PRINT THAT MANY *S AS A HISTOGRAM
	SOJGE	P1,MSG1		;WHERE 1 * IS 0-499, ETC.
	PJRST	CR2POP		;DONE, FINISH LINE AND BLANK ANOTHER
SUBTTL	TRIVIAL COMMANDS

ZZ==<NMON+7>/10			;NUMBER OF LINES TO PRINT

CHELP:	WSIX	[SIXBIT\C&URRENTLY AVAILABLE:#!\]
	MOVSI	T1,-ZZ		;LINE LOOPER
CHEL1L:	MOVSI	T2,-10		;COLUMN LOOPER
	MOVEI	T3,(T1)		;HOLDS COMMAND NUMBER TO PRINT
CHEL2L:	CAIL	T3,NMON		;GONE TOO FAR?
	 JRST	CHEL1A		;YES, MARK THIS AS END OF LINE
	TRNE	T2,-1		;AT BEGINNING OF LINE?
	 WCHI	TAB		;NO, NEED A TAB TO LINE UP COLUMNS
	WNAME	MONNAM(T3)	;PRINT CURRENT COMMAND
	ADDI	T3,ZZ		;POINT TO NEXT COMMAND TO PRINT
	AOBJN	T2,CHEL2L	;LOOP ON COLUMNS
CHEL1A:	W2CHI	CRLF		;DO A CRLF AT END OF LINE
	AOBJN	T1,CHEL1L	;LOOP ON REST OF ROWS
	PJRST	CRPOPJ

CEXIT:	PUSHJ	P,CRELEA	;RELEASE OUTPUT DEVICE
	MONRT.			;ALL DONE
	POPJ	P,		;IF HE INSISTS

CLOOP:	TXOA	F,F.LOOP	;REMEMBER TO LOOP THIS LINE
STPLOP:	TXZ	F,F.LOOP	;EXIT LOOP MODE ROUTINE
	POPJ	P,

CNOFOR:	TXNE	F,DEVOPN	;CAN WE NOW?
	 SETSTS	DEV,IO.SFF	;YES, DO IT
	MOVEI	T1,IO.SFF	;NO, DO IT AT OPEN TIME
	MOVEM	T1,DEVFOL+FILSTS
	POPJ	P,

CNOECH:	TXNE	F,DEVOPN	;CAN WE NOW?
	 SETSTS	DEV,IO.SUP	;YES, DO IT
	MOVEI	T1,IO.SUP	;NO, DO IT AT OPEN TIME
	MOVEM	T1,DEVFIL+FILSTS
	MOVEM	T1,DEVFOL+FILSTS
	POPJ	P,

CRELEA:	TXZ	F,DEVOPN	;NO LONGER OPEN
	RELEASE	DEV,
	POPJ	P,

CPAUSE:	MOVE	T1,VPAUSE	;GET PAUSE INTERVAL
	HIBER	T1,		;WAIT THAT LONG
	 POPJ	P,		;IF WE LOSE, TOO BAD
	POPJ	P,

CDDT:	SKIPE	.JBBPT		;DO WE HAVE A DDT?
	JRST	CDDT2		;YES
	WSIX	[SIXBIT\N&O &DDT#!\]
	POPJ	P,

CDDT2:	JSR	@.JBBPT		;FORCE UNSOLICITED BREAKPOINT
NETDDT::POPJ	P,		;RETURN FROM COMMAND
SUBTTL	UUO LEVEL ROUTINES
OPDEF	UUOSKP	[AOS	-4(P)]	;TO LET UUOS SKIP

UGET:	MOVE	U2,(U1)		;GET GETTAB WORD
	HLRZM	U2,GTINDX	;SAVE INDEX HALF
	HRRZM	U2,GTTABL	;AND TABLE NUMBER
	TXNE	F,NOSPY		;CAN WE SPY?
	 JRST	UGET1		;NO, DO IT THE SLOW WAY
	ADD	U2,GTADDR	;U2_ADDR OF TABLE POINTER
	MOVE	U2,MON(U2)	;GET IT
	ADD	U2,GTINDX	;U2_ADDRESS OF ENTRY
	MOVE	U2,MON(U2)	;GET THE ENTRY
	MOVEM	U2,(U3)		;SAVE IN USER'S ACS
	POPJ	P,

UGET1:	GETTAB	U2,		;GET THE DATA
	 EDISIX	[CPOPJ##,,[SIXBIT\? GETTAB &ON %,,% FAILED#!\]
		WOCT	GTINDX
		WOCT	GTTABL]
	MOVEM	U2,(U3)		;RETURN IN AC
	POPJ	P,

;UUO TO PRINT A LOCATION IF HALFWORD FORMAT. THE AC FIELD SPECIFIES
;THE NUMBER OF LEADING SPACES TO PRINT
UWHALF:	JUMPE	U3,UWHAL1	;USE AC FIELD TO PRINT LEADING SPACES
	WCHI	" "		;PRINT ONE OF THEM
	SOJG	U3,.-1		;AND THE REST
UWHAL1:	PUSH	P,F		;SAVE FLAGS WORD
	TXO	F,LZEFLG	;CAUSE WE NEED TO SET THIS
	MOVS	U2,(U1)		;GET USER'S DATA
	WOCTI	6,(U2)		;DO LEFT HALF
	WCHI	" "		;SEPARATE
	HLRZ	U2,U2		;GET RIGHT HALF BACK
	WOCTI	6,(U2)		;AND PRINT THAT
	POP	P,F
	POPJ	P,		;DONE
;TTY OUTPUT ROUTINE TO STRIP TRAILING BLANKS FROM TTY OUTPUT FOR
;THE TTYMAP ROUTINES

TTYOUT:	PUSH	P,U1		;SAVE CHARACTER
	ANDI	U1,177		;REMOVE NONSENSE
	CAIN	U1,"M"&37	;CARRIAGE RETURN?
	 JRST	TTYOU2		;YES, CLEAR SPACE COUNTER AND DO CR
	CAIN	U1," "		;SPACE?
	 JRST	TTYOU4		;YES, BUMP SPACE COUNTER AND DON'T PRINT
	MOVEI	U1," "		;PRINT ANY SAVED UP SPACES
TTYOU1:	SOSGE	SPCCNT		;ANY MORE TO DO?
	 JRST	TTYOU2		;NO, EXIT
	PUSHJ	P,O1BYTE##	;PRINT ONE
	JRST	TTYOU1		;DO REST

TTYOU2:	SETZM	SPCCNT		;NO SPACES PENDING
	MOVE	U1,(P)		;GET THE CHARACTER AGAIN
	PUSHJ	P,O1BYTE##	;PRINT THE CHARACTER
	ANDI	U1,177		;AND JUST ASCII AGAIN
	CAIE	U1,"J"&37	;FORCE OUT LINE ON LINEFEED
	 PJUMPN	U1,.+2		;OR NULL
	  OUTPUT TTY,		;TO LET USER SEE WHAT HE'S MISSING
	POP	P,U1		;GET BACK CHARACTER TO PRINT
	POPJ	P,	

TTYOU4:	AOS	SPCCNT		;CHALK UP ANOTHER TO DO
	POP	P,U1		;RESTORE THE SPACE
	POPJ	P,		;AND DON'T PRINT IT
;ROUTINES TO HANDLE ASYNCHRONOUS IO TO TEST DEVICES

DEVOBY:	SOSGE	FILCTR(U2)	;ROOM IN BUFFER?
	 JRST	DEVOB1		;NO, DO OUTPUT
	IDPB	U1,FILPTR(U2)	;YES, PUT CHARACTER IN BUFFER
	POPJ	P,

DEVOB1:	PUSHJ	P,DEVOUT	;DO OUTPUT
	  PJRST	DEVOER		;ABORT UUO, ERROR OCCURRED
	JRST	DEVOBY		;NO WE CAN STORE IT IN THE BUFFER

DEVOUT:	AOS	IONUM		;WE DID ANOTHER
OUTUUO:	OUT	DEV,		;SEND THE DATA
	 PJRST	CPOPJ1##	;OK
OUTFIX:	AOS	IOFAIL		;CHALK UP AN ERROR
	STATZ	DEV,IO.ERR	;REAL ERROR?
	  POPJ	P,		;TELL CALLER
	PUSHJ	P,DEVHIB	;WAIT FOR IO ACTIVITY
	JRST	DEVOUT


DEVIBY:	SOSGE	FILCTR(U2)	;ROOM IN BUFFER?
	 JRST	DEVIB1		;NO, DO INPUT
	ILDB	U1,FILPTR(U2)	;YES, GET CHARACTER FROM BUFFER
	POPJ	P,

DEVIB1:	PUSHJ	P,DEVIN		;DO INPUT
	  PJRST	DEVIER		;ABORT UUO, ERROR OCCURRED
	JRST	DEVIBY		;WE SHOULD HAVE SOME DATA NOW

DEVIN:	AOS	IONUM		;WE DID ANOTHER
INUUO:	IN	DEV,		;GET SOME DATA
	 PJRST	CPOPJ1##	;OK
INFIX:	AOS	IOFAIL		;CHALK UP AN ERROR
	STATZ	DEV,IO.ERR!IO.EOF ;REAL ERROR OR END OF FILE?
	  POPJ	P,		;TELL CALLER
	PUSHJ	P,DEVHIB	;WAIT FOR IO ACTIVITY
	JRST	DEVIN

DEVIER:	STATO	DEV,IO.EOF	;END OF FILE?
DEVOER:	 SKIPA	U1,FILER2(U2)	;NO, GET IO ERROR ROUTINE
	 HLRZ	U1,FILER2(U2)	;GET EOF PROCESSER
	PJRST	UERXIT##	;AND ABORT UUO

DEVHIB:	TXNE	F,F.HASH	;INTERESTED IN GOINGS ON?
	 OUTCHR	["A"]		;YES, FLAG THAT ASYNC IO DID ITS THING
	MOVX	U3,HB.RIO!HB.RPT!HB.RTL!^D10000
	HIBER	U3,		;WAIT FOR ASYNC. IO TO FREE A BUFFER
	  EWSIX	[SIXBIT\%HIBER. UUO &FAILED#!\]
	POPJ	P,		;TRY AGAIN
SUBTTL	MONITORING ROUTINES

MONIPL:	TXZ	F,F.TIME!F.PRTA	;ONCE PER LOOP INITIALIZATION
	MSTIME	T1,		;SEE IF TIME FOR A SUMMARY
	IDIV	T1,VSUMMA	;T1_"SECTION" OF DAY
	CAMN	T1,SUMSCT	;STILL IN THAT SECTION?
	 POPJ	P,		;YEP, DON'T DO SUMMARY
	MOVEM	T1,SUMSCT	;REMEMBER FOR NEXT CALL
	TXO	F,F.PRTA!F.PRTE	;PRINT EVERYTHING
	SETOM	LASHED		;FOR MONCHK TO NOT SKIP TO FORCE HEADING OUT
	POPJ	P,		;DONE

MONIPC:	SETOM	SUMSCT		;PER COMMAND
	POPJ	P,

MONCHK:	PUSHJ	P,MONTIM	;TIMESTAMP IF NECESSARY
	HRRZ	T1,(P)		;GET PC OF CALLER
	CAMN	T1,LASHED	;SAME AS LAST GUY?
	 POPJ	P,		;YEP, DON'T HAVE TO PRINT HEADER
	MOVEM	T1,LASHED	;NEW GUY. MAKE HIM BE OLD
	PJRST	CPOPJ1##	;AND FORCE HEADER TO PRINT

MONTIM::TXON	F,F.TIME	;HAVE WE TIMESTAMPED YET?
	 DISIX	[[SIXBIT\#[%]#!\] ;NO, STAMP LINE
		PUSHJ	P,TIMPRT##]
	POPJ	P,


;ROUTINE TO LOOK AT F.UERR, F.PRTA, AND F.PRTE FLAGS TO DECIDE IF
;WE SHOULD PRINT OUT THE DATA WE JUST GAVE TO NCMP.

CHKCMP:	TXNE	F,F.PRTA	;ARE WE PRINTING EVERYTHING?
	 PJRST	CPOPJ1##	;YES, NO NEED TO LOOK FURTHER.
	TXNE	F,F.PRTE	;PRINTING ERRORS?
	 JUMPL	F,CPOPJ1##	;YES, PRINT IF NCMP SAID DIFFERENCES
	POPJ	P,		;NO ERRORS, DON'T PRINT
SUBTTL	ACTIVE JOB SUBROUTINES

MAKACT:	GET	P1,[.GTWSN,,.GTSLF];PREPARE TO READ WAIT STATE CODES
	LSH	P1,-^D27	;RIGHT JUSTIFY LENGTH OF TABLE
	MOVEI	P2,.GTWSN	;NOW READ IT
	SETZ	P3,		;THIS IS AOBJN/POINTER TO ACTTAB
MAKAL1:	GET	P4,P2		;READ CURRENT WORD
	ADD	P2,[1,,0]	;POINT TO NEXT
	MOVE	T1,[POINT 12,P4] ;PREPARE TO READ EACH WAIT STATE CODE
	HRLI	P3,-3		;DO THREE ENTRIES IN ACTTAB
MAKAL2:	ILDB	T2,T1		;GET A WAIT STATE CODE
	MOVSI	T3,-ACTLEN	;NOW SEARCH ACTNAM
	CAME	T2,ACTNAM(T3)	;THIS IT?
	 AOBJN	T3,.-1		;NO, TRY NEXT
	JUMPGE	T3,MAKAA2	;DON'T RECORD THIS IF NOT FOUND
	SETOM	ACTTAB(P3)	;MARK THIS AS AN ACTIVE WAIT STATE
MAKAA2:	AOBJN	P3,MAKAL2	;DO SOME MORE IN THIS WORD
	SOJG	P1,MAKAL1	;DO THE REST OF THE TABLE
	POPJ	P,		;ALL SETUP

ACTNAM:	EXP	'RN','WS','TS','DS','PS','AU','IO','DI'
ACTLEN==.-ACTNAM

GETACT:	GET	P1,[%NSHJB]	;GET THE HIGHEST JOB IN USE
	MOVEI	P2,.GTSTS	;SCAN JBTSTS TABLE
	SETO	T1,		; DON'T INCLUDE OURSELF AS ACTIVE
GETACL:	ADD	P2,[1,,0]	;STEP TO NEXT JOB
	GET	T2,P2		;GET JBTSTS ENTRY
	JUMPGE	T2,GETACS	;IF RUN BIT OFF, IT ISN'T ACTIVE
	LDB	T2,[POINT 5,T2,14];EXTRACT WAIT STATE
	SKIPE	ACTTAB(T2)	;IS THIS AN ACTIVE JOB WAIT STATE CODE?
	 ADDI	T1,1		;YES. CHALK IT UP
GETACS:	SOJG	P1,GETACL	;LOOP FOR MORE
	POPJ	P,		;FINIS, RETURN ANSWER IN T1
SUBTTL	LOG FILE SUBROUTINES AND CONTROL

LOGOPN:	MOVE	T1,LOGSTT	;GET STATE OF LOG FILE
	JRST	@.+1(T1)	;TO LOGOP1 IF WE HAVE TO OPEN IT
	LOGDSP(OPN)

LOGOP1:	MOVE	T1,.JBFF##	;REMEMBER WHERE BUFFERS START SO WE CAN FREE THEM LATER
	MOVEM	T1,LOGBFS
	MOVE	T1,LOGFOL+FILDEV ;GET DEVICE WE'RE LOGGING ON
	DEVTYP	T1,		;SO WE CAN FIND OUT WHAT SORT OF DEVICE IT IS
	 EDISIX	[LOGNAV,,[SIXBIT\? L&OGGING DEVICE WENT AWAY#!\]]
	ANDI	T1,77		;JUST DEVICE TYPE
	CAIN	T1,.TYDSK	;DISK?
	 JRST	LOGOPD		;YES, APPEND TO IT
	CAIE	T1,.TYTTY	;TTY?
	 SKIPA	T1,[%LGLAC]	;NO, ASSUME LPT-LIKE NEW STATE NEEDED
	 MOVEI	T1,%LGTAC	;YES, ENTER TTY ACTIVE STATE
	FOOPEN	LOGFOL		;GET IT
	JRST	LOGOP2		;STORE NEW LOG FILE STATE

LOGOPD:	FAPEND	LOGFOL		;APPEND TO FILE
	MOVEI	T1,%LGDAC	;ENTER DISK ACTIVE STATE
LOGOP2:	MOVEM	T1,LOGSTT	;REMEMBER NEW STATE
	SKIPN	LOGFOL+FILHDR	;BUFFER MADE UP YET?
	 OUTBUF	LOG,		;NO, MAKE SOME
	MOVE	T1,.JBFF##	;REMEMBER END OF BUFFERS
	MOVEM	T1,LOGBFE	;SO WE CAN TRY TO FREE THEM LATER
	PJRST	CPOPJ1##	;SUCCESS RETURN

LOGOPE:	MOVE	T1,LOGSTT	;DID WE THINK IT WAS AVAILABLE?
	CAIN	T1,%LGAVL	;ONLY COMPLAIN IF IT WAS
	 ERROOP	LOGFOL		;OPEN FAILED.
LOGNAV:	MOVEI	T1,%LGNAV	;MARK IT UNAVAILABLE
	PJRST	LOGNST		;SO WE WON'T COMPLAIN NEXT TIME
LOGCLS:	MOVE	T1,LOGSTT	;IS THIS A DEVICE WE CAN CLOSE NOW?
	JRST	@.+1(T1)	;FIND OUT
	LOGDSP(CLS)

LOGCL1:	FOCLOS	LOGFOL		;IT WAS
	MOVE	T1,LOGBFE	;DID ANYTHING GET ALLOCATED AFTER END OF OUR BUFFERS?
	MOVE	T2,LOGBFS	;IF SO, SET MEMORY BACK TO HERE
	CAMN	T1,.JBFF##
	 MOVEM	T2,.JBFF##	;SO WE DON'T CONTINUOUSLY GROW
	MOVEI	T1,%LGAVL	;BACK TO AVAILABLE STATE
LOGNST:	MOVEM	T1,LOGSTT	;REMEMBER IT
	POPJ	P,


LOGEND:	PUSHJ	P,LOGCLS	;CLOSE IT
	MOVE	T1,LOGSTT	;SEE WE WE'RE DONE
	JRST	@.+1(T1)
	LOGDSP(END)

LOGEN1==LOGCL1			;JUST CLOSE FILE (HERE ONLY IF WAS IN %LGLAC STATE)

LOGILL:	EDISIX	[LOGNAV,,[SIXBIT\? LOG &FILE ROUTINE FOUND ILLEGAL STATE (%)#!\]
		WDEC	LOGSTT]
SUBTTL	DATA BASE

;INTERRUPT DATA BASE

INTVEC:	INTDEV
	0
	PS.VTO
	0
	INTERR			;SHOULD NEVER USE THIS, BUT IT HAPPENS
	0
	PS.VTO
	0


;TABLE OF CHARACTERS FOR INTDEV TO PRINT

DEFINE	INTCH<
	X(ID,I)
	X(OD,O)
	X(EF,<<EOF>>)
	X(IE,<<INPUT ERROR>>)
	X(OE,<<OUTPUT ERROR>>)
	X(DO,<<OFFLINE>>)
	X(OL,<<ONLINE>>)
>

DEFINE	X(BIT,STRING)<
	RELOC	INTCHR+^L<PS.R'BIT>-22
	[ASCIZ\STRING\]
>

INTCHR:	REPEAT 22,<[ASCIZ\?\]>
	INTCH			;OVERLAY TABLE WITH KNOWN REASONS

	RELOC	INTCHR+22	;GET BACK TO NORMAL NUMBERING
CMPLOT(OCN,NPPPPNPPPN,OC,4)

CMPLOT(SCB,NNN,SB,SCBN)


ZZ==-1				;MAKE A TABLE OF BITS
BITTAB:
REPEAT 44,<
	XLIST
	1B<ZZ==ZZ+1>
>
	LIST
TTYFOH:	FILE	TTY,O,TTYFOL,<DEV(TTY),NAME(TTYMON),EXT(LST),<INST(<PUSHJ P,TTYOUT>)>>

DEVFOH:	FILE	DEV,O,DEVFOL,<DEV(OUT),NAME(NETTST),EXT(LST),OTHER(DEVFIL),OUTPUT(OUTERR)
		,<INST(<PUSHJ P,DEVOBY>)>,OPEN(OOPERR),ENTER(ENTERR)>
		,<<FOGET DEVFOL>,<FENT DEVFOL>,<OUTBUF DEV,@VBUFFE>>

DEVFIH:	FILE	DEV,I,DEVFIL,<DEV(IN),NAME(NETTST),EXT(LST),OTHER(DEVFOL),
		<INST(<PUSHJ P,DEVIBY>)>,OPEN(IOPERR),LOOKUP(LKERR)>,
		<<FIGET DEVFIL>,<FLOOK DEVFIL>,<INBUF DEV,@VBUFFE>>

LOGFOH:	FILE	LOG,A,LOGFOL,<DEV(LPT),NAME(NETTST),EXT(LOG),OPEN(LOGOPE)>

TTYPOH:	PFILE	TTYPOL,<IDPB U1,TTYPOL+FILPEX>,<<POINT 7,TTMBUF>>

TLKFIH:	FILE	TLK,I,TLKFIL,<NAME(NVTHAK),STATUS(UU.AIO),OTHER(TLKFOL),OPEN(CTAOPN)>

TLKFOH:	FILE	TLK,O,TLKFOL,<NAME(NVTHAK),OTHER(TLKFIL),ENTER(CTAENT)>

	UUOTAB			;ASSEMBLE UUO DISPATCH

DEFINE	X(A,B)<<SIXBIT\A\>>
MONNAM:	MONLST

DEFINE	X(A,B)<IFDEF	C'A,<C'A
;>	CPOPJ##>
MONCAL:	MONLST

DEFINE	X(A,B,C)<IFNB <C>,<V'A:	C>>
	MONLST

DEFINE	X(A,B,C)
    <IFNB <B>,<
	IFNB <C>,<V'A,,B
	    ;>	    0,,B
	;>	0
>
CLNDSP:	MONLST
NODBL2:	2			;ALWAYS NUMBER OF ARGS
	0			;NODE NAME STORED HERE

NODBL5:	4			;LENGTH
	0			;NODE NAME ALSO STORED HERE
	0			;RESERVED FOR FUTURE
	3			;DEVICE WE'RE INTERESTED IN

MPXCNT:	.CNCCN,,DEV		;CNECT. BLOCK TO CONNECT A DEVICE
	BLOCK	1		;OPNDEV FILLS THIS IN

PATCH:				;HANDY AREA FOR EXPERIMENTS
PAT:	BLOCK	100

ZSTART:
PDL:	BLOCK	PDLLEN

NDBBUF:
NDBNNM:	BLOCK	1
NDBSID:	BLOCK	1
NDBSNM:	BLOCK	1
NDBMNM:	BLOCK	1
NDBFEK:	BLOCK	1
NDBQUE:	BLOCK	1
NDBATQ:
NDBCTL:	BLOCK	1
NDBTOP:	BLOCK	8
SCBSTS:	BLOCK	1
SCBOPR:	BLOCK	1
SCBCTL:	BLOCK	1
SCBRQB:	BLOCK	1
SCBTTY:	BLOCK	1
SCBNBP:	BLOCK	1
SCBDEV:	BLOCK	1
NDBLEN==.-NDBBUF

NDBLAR==<POINT 8,NDBMNM,11>
NDBLAP==<POINT 8,NDBMNM,19>
NDBLMS==<POINT 8,NDBMNM,27>
NDBLMA==<POINT 8,NDBMNM,35>
NDBLAS==<POINT 8,NDBFEK,17>
NDBLMR==<POINT 8,NDBSNM,35>
NDBLMP==<POINT 8,NDBSNM,27>

NDBADR:	BLOCK	<NNDB==20>
MSGADR:	BLOCK	<NMSG==40>
SNDMSG:	BLOCK	<SNDLEN==^D100>/5

CMDNUM:	BLOCK	1		;NUMBER OF COMMANDS TYPED ON LINE
CMDLST:	BLOCK	CMDMAX		;TABLE OF COMMAND ROUTINES TO CALL
INDFOL:	BLOCK	1		;FILE BLOCK OF DEFAULT OUTPUT DEVICE (TTY OR LOG)
SAVEP:	BLOCK	1		;PUT STACK HERE IF YOU NEED TO KEEP IT

ERRCNT:	BLOCK	1		;# OF ERRORS FOUND BY DOCHCK

GTADDR:	BLOCK	1		;ADDRESS OF GETTAB TABLE POINTERS
GTINDX:	BLOCK	1		;INDEX USED IN LAST GET UUO
GTTABL:	BLOCK	1		;TABLE USED IN LAST GET UUO
SPCCNT:	BLOCK	1		;COUNT OF SPACES PENDING FOR TTY

TSTSTK:	BLOCK	1		;STACK SAVED HERE WHILE DOING A TEST
TESTTM:	BLOCK	1		;UPTIME OF START OF TEST
BYTCNT:	BLOCK	1		;NUMBER OF BYTES TRANSFERRED DURING TEST
IONUM:	BLOCK	1		;NUMBER OF IO INSTS. DONE IN TEST
IOFAIL:	BLOCK	1		;NUMBER OF THOSE THAT FAILED

FOXUDX:	BLOCK	1		;UDX OF LAST TTY FOX USED

LOGSTT:	BLOCK	1		;LOG FILE STATE
LOGBFS:	BLOCK	1		;START OF LOG FILE BUFFERS
LOGBFE:	BLOCK	1		;END OF BUFFERS (USED TO FREE THEM AT CLOSE TIME)

ACTTAB:	BLOCK	32		;-1 IF THIS IS A ACTIVE WAIT STATE CODE

OLDBAD:	BLOCK	1		;NUMBER OF KNOWN BAD MESSAGES RECEIVED
SAVSTK:	BLOCK	1		;HOLD STACK TO USE WHEN BADMON RUNS OUT OF MESSAGE
SAVST2:	BLOCK	1
MSGTYP:	BLOCK	1		;NCL MESSAGE TYPE TEMP LOCATION

OLDRI:	BLOCK	1		;ACCUMULATED # OF RECEIVER INTS.
OLDXI:	BLOCK	1		;TRANSMITTER
OLDEI:	BLOCK	1		;ECHO INTS
OLDTIM:	BLOCK	1		;UPTIME IN JIFFIES

LOCHED:	BLOCK	ETCCPN		;LOCAL COPY OF COMM REGION
LOCRGN:	BLOCK	ETCSIZ		;  DON'T SEPARATE FROM ABOVE LINE
LASHED:	BLOCK	1		;ADDRESS OF LAST CALLER TO CHKHED
SUMSCT:	BLOCK	1		;SECTION OF DAY FOR SUMMARY ROUTINE
SLEDAT:	BLOCK	2		;TEMP SAVE AREA FOR OCNMON'S SLE DATA

TTYFOL:	BLOCK	FBSIZE
DEVFOL:	BLOCK	FBSIZE+3	;RESERVE EXTRA SPACE FOR EXTRA DATA
DEVFIL:	BLOCK	FBSIZE+3
LOGFOL:	BLOCK	FBSIZE
STBFIL:	BLOCK	FBSIZE
TTYPOL:	BLOCK	PBSIZE+1
TLKFIL:	BLOCK	FBSIZE
TLKFOL:	BLOCK	FBSIZE
TTMBUF:	BLOCK	^D80/5

ZEREND==.-1
END	NETTST