Google
 

Trailing-Edge - PDP-10 Archives - dec-10-omona-u-mc9 - netser.mac
There are 13 other files named netser.mac in the archive. Click here to see a list.
TITLE NETSER - COMMUNICATION DEVICE INDEPENDENT NETWORK SERVICE ROUTINES - V112
SUBTTL D. TODD/DRT/EJW   05 APR 77
	SEARCH F,S,NETPRM
	$RELOC
	$HIGH
;*** COPYRIGHT 1974,1975,1976,1977 DIGITAL EQUIPMENT CORP., MAYNARD, MASS. ***
XP	VNETSER,112	;PUT VERSION NUMBER IN GLOB AND LOADER MAP

NETSER::ENTRY	NETSER	;LOADING IF IN LIBRARY SEARCH MODE

COMMENT\			;;;REVISION HISTORY

V0		;INITIAL PRODUCT IMPLEMENTATION
\
	EXTERNAL	DEVNET



SUBTTL TABLE ON CONTENTS
;               TABLE OF CONTENTS FOR NETSER
;
;
;                        SECTION                                   PAGE
;    1. TABLE OF CONTENTS.........................................   2
;    2. DEVICE DATA BLOCKS........................................   3
;    3. TSTNET - FIND OUT IF A DEVICE EXISTS ON THE NETWORK.......   5
;    4. INTERFACE TO COMCON FOR THE "NODE" COMMAND................   8
;    5. INTERFACE TO UUOCON FOR THE NODE UUO......................   9
;    6. NODE.1 - ASSIGN A REMOTE DEVICE...........................  10
;    7. NODE.2	 RETURN A NODE NUMBER IN THE AC...................  11
;    8. NODE.3 STATION CONTOL MESSAGES............................  12
;    9. NODE.4 AUTO RELOAD OF DOWN LINE DAS80 SERIES STATIONS.....  13
;   10. LOCATE & WHERE COMMAND/UUOS...............................  14
;   11. SCB INTERFACE ROUTINES....................................  17
;   12. MAKDDB - SURROUTINE TO BUILD A NETDDB.....................  18
;   13. MBF - INTERNAL MONITOR BUFFER ROUTINES....................  19
;   14. AVOMBF - AVDVNCE AN OUTPUT MONITOR BUFFER.................  20
;   15. MAKPCB - BUILD A PROTOCOL DATA BLOCK......................  21
;   16. RMV??? REMOVE DATA BLOCKS TO FEE CORE.....................  22
;   17. SUROUTINE TO RETURN STORAGE DATA BLOCK TO THE MONITOR.....  23
;   18. SUBROUTINES TO SEARCH AND DEFINE DDB' NDT'S ETC...........  27
;   19. ROUTINE TO GENERATE THE NCL PROTOCOL HEADERS..............  28
;   20. UNNUMBERED NCS CONTOL MESSAGES............................  29
;   21. NCS NUMBER CONTROL MESSAGES...............................  32
;   22. MEMORY CONTROL ROUTINES...................................  41
;   23. COMMON SUBROUTINES TO CONVERT EXTENSIBLE ASCII/BINARY.....  43
;   24. NETINI - INITILIZATION/ONCE A SECOND CODE.................  47
;   25. NETCTC - CALL ON RESET OR ^C^C AND NOT CCON/CON...........  48
;   26. FEKINT INTERRUPT LEVEL PROCESSINT.........................  49
;   27. OUTINT - OUTPUT INTERRUPT PROCESSOR FOR ALL FEK'S.........  51
;   28. NETWRT - SEND A MESSAGE TO THE FRONT END KONTROLLER FEK...  52
;   29. NETHIB/NETWAK - HIBERNATE AND SLEEP ROUTINE...............  53
;   30. INPDIS - DISMISS THE INPUT INTERRUPT......................  54
;   31. INPINT - INPUT INTERRUPT PROCESSOR FOR ALL FEK'S..........  56
;   32. CHKNCA - CHECK ACK'S FOR MESSAGE SENT BUT BEING HELD......  57
;   33. - PROCESS THE TOPS MESSAGE ON THE QUEUE IN SEQUENCE.......  58
;   34. INCTID - NODE ID MESSAGE PROCESSOR........................  59
;   35. INCTDM - PROCESS OF NUMBERED CONTROL/DATA MESSAGES........  63
;   36. ICMXXX MESSAGE PROCESSORS.................................  64
;   37. ICMCNN - NODE IS ATTEMPTING TO CONNECT TO A DEVICE OR TASK  65
;   38. ICMDSC - DISCONNECT.......................................  66
;   39. RQBOOT - AUTO RELOAD OF A DAS80,81,82,DC72 REMOTE STATION.  72
;   40. NCSIDC - DEVICE CONTROL FOR INPUT MESSAGES................  73
;   41. IDCDAT (1) DATA WITHOUT END OF RECORD.....................  74
;   42. IDCDAR (2) DATA WITH END OF RECORD (MTA'S)................  74
;   43. IDCSTS (3) STATUS.........................................  75
;   44. IDCCMN (4) CONTROL MESSAGE................................  76
;   45. IDCUID (5) USER ID........................................  77
;   46. IDCFSP (6) FILE SPEC......................................  77
;   47. COMMON DEVICE DEPENDENT ROUTINES..........................  82
;   48. TELETYPE DEVICE-DEPENDENT CODE............................  83
;   49. TTYDSC REMOTE DATA SET CONTOL FOR DAS80'S SERIES..........  91
;   50. TTYSTS/TTYCHR STATUS AND CHARASTICS.......................  92
;   51. NCS CONTROL MESSAGES......................................  93
;   52. DAP CONTROL MESSAGES......................................  94
;   53. HOST.U - SET HOST UUO TO SWITCH BETWEEN COMMAND DECODERS.. 111
;   54. HOST.C - SET HOST COMMAND TO SWITCH BETWEEN MCR'S......... 112
;   55. LOCAL STORAGE FOR NETSER.................................. 113
;   56. DEVICE DATA BLOCKS........................................ 114
;   57. LPTCRF - PRINT A CRLF AS FIRST OUTPUT AFTER INIT.......... 118
;   58. DEVICE DATA BLOCKS........................................ 120
;   59. DEVICE DATA BLOCKS........................................ 131
SUBTTL	DEVICE DATA BLOCKS AND OTHER SYMBOLS

;SPECIAL BITS IN LH(S)

IOSCLO==400		;DEV HAS BEEN CLOSED
IOSREL==1000		;DEV HAS BEEN RELEASED
IOSUUD==2000		;UUO PROCESSING DELAYED
IOSCON==4000		;DEVICE IS CONNECTED
IOSERR==10000		;ERROR DETECTED AT INT. LEVEL
IOSHDV==100000		;HUNG DEVICE

;HIGH TWO BITS ARE FOR DEVICE-DEPENDENT FUNCTIONS

TIMFAC==^D9835		;FACTOR USED BY NET2ND TO KEEP AN EXPONENTIAL
			; AVERGE OF BUFFER USAGE WITH A ONE MINUTE
			; TIME CONSTANT.  THIS VALUE IS EQUAL TO
			; EXP(-1/TIMECONSTANT)


;ENTRY FROM COMCON WITH A NETWORK ASSIGN COMMAND

;	ASSIGN	NODENAME_DEV:LOGICAL

;COMCON HAS ALREADY SCANNED OF THE NODE NAME 
;T2=NODE NAME
;T3=DELIMETER
NETASG::			;ENTRY
	MOVE	P1,T2		;SAVE THE STATION NAME
	CAIN	T3,"_"		;TERMINATED BY A _
	PUSHJ	P,COMTYS##	;YES, SKIP THE CHARACTER
	MOVE	T1,P1		;GET THE NODE NAME AGAIN
	PUSHJ	P,CVTOCT##	;TRY FOR OCTAL
	  CAIA			;NO MUST BE SIXBIT
	MOVE	P1,T1		;YES, USED OCTAL NAME

	PUSHJ	P,CTXDEV##	;GET THE DEVICE NAME
	JUMPE	T2,NOTENF##	;ILLEGAL ARG LIST
	MOVE	P2,T2		;SAVE THE DEVICE NAME
	TRNE	T2,505050	;MUST BE NUMBERIC GGNN,GG,N
	JRST	NOTDEV##	;ERROR RETURN

;HERE TO VALIDATE THE STATION NAME
	MOVE	T1,P1		;COPY THE STATION NAME
	PUSHJ	P,SRCNDB	;DOES THE STATION EXIST
	  JRST	[HRRZ T1,NRTUNN	;TYPE AN ERROR
		PJRST	ERRMES##]	;ERROR MESSAGE
	CAMN	P1,JBTLOC##	;LOCAL NODE
	JRST	ASSIGC##	;YES, JUST RETURN
	MOVEI	P1,(W)		;SAVE THE NDB POINTER

;HERE TO VALIDATE THE REMOTE DEVICE NAME
	HLRZ	T1,P2		;GENERIC NAME ONLY FROM THE LEFT HALF
	TRNN	P2,505050	;MUST BE LEFT HALF NUMBERIC OR ZEROS
	PUSHJ	P,SRCNDT	;SEARCH THE NDT
	  PJRST	NOTDEV##	;NOT A LEGAL DEVICE
	HLL	P2,NDTNAM##(W)	;COPY THE GENERIC -10 DEVICE NAME
	MOVEI	W,(P1)		;GET THE NODE POINER BACK
	HLRZ	P1,NDBNNM##(W)	;PUT THE NODE NUMBER IN P1

;HERE TO CONVER THE DEVICE NAME INTO A NETWORK NAME
;DEVICE MUST BE OF THE FORM(S) GGGNNU, GGGNN, GGGU,OR GGG

	MOVEI	T1,(P1)		;CONVERT THE NODE NUMBER TO SIXBIT
	TRO	T1,77700	;FORCE CONVERSION TO LINE UP
	PUSHJ	P,CVTSBT##	;IN UUOCON
	MOVEI	T2,(P2)		;COPY THE STATION AND UNIT NUMBER IF ANY
	TRNE	T2,7700		;USER SUPPLY A STATION NUMBER
	JRST	NETAS1		;YES,
	LSH	T2,-14		;SHIFT THE UNIT NUMBER IF ANY TO LOW ORDER
	IORI	T2,(T1)		;COMBINE THE RIGHT HALF
	HLL	T2,P2		;AND INSERT THE GENERIC NAME
	JRST	ASSIGC##	;RETURN COMCON WITH T2=GGGNN(U)
NETAS1:				;USER SUPPLIED A STATION NUMBER
				;FORM IS GGGNN OR GGGNNU
	TRZ	T2,77		;REMOVE THE UNIT NUMBER IF ANY
	CAIE	T2,(T1)		;NAME AND NUMBER MUST MATCH
	JRST	NOTDEV##	;NO, NOT A LEGAL DEVICE NAME
	MOVE	T2,P2		;YES, USE THE USERS NAME
	JRST	ASSIGC##	;RETURN TO COMCON
SUBTTL TSTNET - FIND OUT IF A DEVICE EXISTS ON THE NETWORK
;SUBROUTINE TSTNET - AS A DDB FOR THE DEVICE IF IT EXISTS
;CALL	MOVE	T1,DEVICE NAME
;	PUSHJ	P,TSTNET
;RETURN	CPOPJ		;DEVICE DOES NOT EXIST/NOT AVAILABLE
;	CPOPJ1		;DEVICE EXISTS AND IS AVAILABLE

TSTNET::			;ENTRY FROM UUOCON
	HLRZ	T2,M		;GET THE UUO
	ANDI	T2,777000	;ONLY THE UUO OP CODE
	CAIE	T2,(OPEN)	;IS IT
	POPJ	P,		;NO, GET THE ASSIGN LATER
	TRNE	T1,7700		;IS THERE A STATION NUMBER
	PUSHJ	P,DVSCVT##	;GET THE STATION NUMBER
	  POPJ	P,		;NOT A STATION NUMBER
	PUSH	P,T1		;SAVE THE NAME
	DPB	T1,[POINT 6,T1,23]	;MOVE THE UNIT NUMBER OVER
	TRZ	T1,7777		;CLEAR THE JUNK
	PUSHJ	P,GENNET	;GO ASSIGN THE DEVICE
	  PJRST	TPOPJ		;NO SUCH DEVICE
	PJRST	TPOPJ1##	;DEVICE ASSIGNED F=DDB

;SUBROUTINE GENNET - TEST FOR A GENERIC NETWORK DEVICE
;CALL	MOVE	T1,[SIXBIT /DEVNAME/]
;	MOVE	T2,STATION NUMBER
;	PUSHJ	P,GENNET
;RETURN	POPJ			;NO ON THE NETWORK OR AVAILABLE
;	CPOPJ1			;F=DDB ADDRESS

GENNET::			;ENTRY FROM UUOCON
	CAMN	T2,JBTLOC##	;LOCAL STATION
	POPJ	P,		;YES, RETURN
	PUSHJ	P,SAVT##	;NO, SAVE THE T'S
	MOVEI	T4,(P)		;GET THE STACK ADDRESS
	CAMG	T4,LOCORE##	;RUNNING AT CLOCK LEVEL
	POPJ	P,		;YES, DON'T TRY THE NETWORK
	PUSHJ	P,SAVJW		;SAVE J AND W
	PUSHJ	P,SAVE3##	; AND THE P'S
	MOVE	P2,T1		;COPY THE DEVICE NAME
	MOVEI	T1,(T2)		;PUT THE STATION NUMBER IN T1
	PUSHJ	P,SRCNDB	;DOES THE STATION EXIST
	  POPJ	P,		;NO EXIT
	MOVEI	P1,(W)		;SAVE THE NDB POINTER
	SETZ	P3,		;CLEAR THE LOCAL NAME 
	HLRZ	T1,P2		;GET THE GENERIC DEVICE NAME
	PUSHJ	P,SRCNDT	;SEE IF IT EXISTS AT THE STATION
	  POPJ	P,		;NO, EXIT
	PUSHJ	P,MAKDDB	;YES, MAKE A DDB
	  POPJ	P,		;CAN'T
	PUSHJ	P,NCSCNT	;CONNECT THE DEVICE
	  PJRST	UNLDDB		;FAILED DISCARD DDB
	PJRST	CPOPJ1##	;WE WON
NODERT:	XWD	[ASCIZ  / Assigned/]
NRTDNA:	XWD	[ASCIZ  /Device Not Available/]
NRTNCE:	XWD	[ASCIZ	/Network Capacity Exceeded/]
NRTTNA:	XWD	[ASCIZ  /Task Not Available/]
NRTUNT:	XWD	[ASCIZ  /Undefined Network Task/]
NRTUNN::XWD	[ASCIZ  /Undefined Network Node/]
NRTUND:	XWD	[ASCIZ  /Undefined Network Device/]
SUBTTL INTERFACE TO COMCON FOR THE "NODE" COMMAND

;	C	NODE,NODE.C##,NOCORE

NODE.C::SKIPN	JBTADR##(J)	;ANY CORE ASIGNED
	PUSHJ	P,GETMIN##	;NO, GET SOME CORE
	JUMPE	R,DLYCM##	;WAIT
	PUSHJ	P,SAVCTX##	;SAVE THE CONTEXT OF THE JOB
	PUSHJ	P,CTEXT1##	;GET THE ARGUMNET
	SKIPN	T1,T2		;CHECK FOR AN ARG
	JRST	NODEC1		;NONE LIST ALL
	PUSHJ	P,CVTOCT##	;CONVERT TO OCTAL IF POSSIBLE
	  JFCL			;NO, MUST HAVE BEEN A NODE NAME
;	JRST	NODEC6		;FALL THRU
;TYPE OUT  A PARTICULAR NODE NAME
NODEC6:	PUSHJ	P,SRCNDB	;FIND THE NODE BLOCK
	  PJRST	[HRRZ	T1,NRTUNN	;GET THE ERROR MESSGE
		PJRST	ERRMESS##]	;TYPE IT
	PJRST	NODEC2		;TYPE THE INFO
;TYPE OUT THE KNOWN NODES
NODEC1:				;NO ARG ON NODE COMMAND
	MOVEI	W,NETNDB##	;GET THE START OF THE CHAIN
NODEC7:	PUSHJ	P,NODEC2	;TYPE OUT THE PARAMS
	HRRZ	W,NDBNNM##(W)	;GET THE NEXT NDB
	JUMPN	W,NODEC7	;CONTINUE
	POPJ	P,		;RETURN

NODEC2:	PUSHJ	P,TYPNDB	;TYPE IT
	PUSHJ	P,INLMES##	;TYPE CR-LF-TAB
	ASCIZ	/
	/
	MOVSI	P1,-<OBJ.MX+1>	;GET THE DEVICE TABLE SIZE
NODEC4:	LDB	T1,NETCNF##(P1)	;GET THE NUMBER OF DEVICES
	JUMPE	T1,NODEC5	;NONE DON'T PRINT
	MOVEI	T1,(P1)		;GET THE DEVICE NUMBER
	ROT	T1,-1		;DEVICE BY 2
	HLLZ	T2,NETDVN##(T1)	;GET THE EVEN DEVICE NAME
	SKIPGE	T1		;SKIP IF EVEN
	HRLZ	T2,NETDVN##(T1)	;GET THE ODD ENTRY
	PUSHJ	P,PRNAME##	;PRINT IT OUT
	MOVEI	T3,"["		;BRACKET
	PUSHJ	P,COMTYO##	;TYPE
	LDB	T1,NETCNF##(P1)	;GET THE NUMBER OF ENTRIES
	PUSHJ	P,RADX10##	;PRINT
	PUSHJ	P,INLMES##	;BRACKET SPACE
	ASCIZ	/] /
NODEC5:	AOBJN	P1,NODEC4	;CONTINUE TO THE END
	PJRST	PCRLF##		;CR-LF
SUBTTL INTERFACE TO UUOCON FOR THE NODE UUO

;	X	NODE.,NODE.U##,UU.LEA

NODE.U::			;ENTRY POINT
	HLRZ	T4,T1		;GET THE FUNCTION IN T4
	SKIPE	T4		;NOT ZERO
	CAILE	T4,NUULEN	;CHECK THE LENGTH
	JRST	ECOD1##		;ILLEGAL RETURN 1
	HRRI	M,(T1)		;GET THE ARG LIST IN M
	JRST	UUOTAB-1(T4)	;JUMP ON THE FUNCTION TYPE

UUOTAB:				;NODE UUO FUNCTIONS
	JRST	NODE.1		;ASSIGN A DEVICE
	JRST	NODE.2		;RETURN A NODE NUMBER
	JRST	NODE.3		;STATION CONTOL MESSAGE
	JRST	NODE.4		;AUTO RELOAD OF DAS 80 SERIES
	JRST	NODE.5		;RETURN CONFIG INFO FOR NODE
NUULEN==.-UUOTAB		;LENGTH OF THE TABLE
SUBTTL NODE.1 - ASSIGN A REMOTE DEVICE
NODE.1:	PUSHJ	P,SAVE4##	;SAVE THE P'S
	PUSHJ	P,GETWDU##	;GET THE ARGUMENT LIST SIZE
	CAIE	T1,4		;MUST HAVE FOUR ARGS
	JRST	ECOD1##		;ILLEGAL ARG LIST
	PUSHJ	P,GETWD1##	;GET THE NODE NAME
	PUSHJ	P,SRCNDB	;CHECK IF DEFINED
	  JRST	ECOD2##		;NO, ILLEGAL NODE NAME
	HLRZ	T1,NDBNNM##(W)	;GET NODE NUMBER
	CAMN	T1,JBTLOC##	;IS IT LOCAL SITE?
	JRST	ECOD2##		;YES, CAN'T ASSIGN LOCAL DEVICE
	MOVEI	P1,(W)		;SAVE THE NODE DATA BLOCK
	PUSHJ	P,GETWD1##	;GET THE PHYSICAL DEVICE NAME
	SKIPN	P2,T1		;COPY THE NAME
	JRST	ECOD3##		;ZERO IS ILLEGAL
	HLRZS	T1		;GENERIC NAME ONLY FOR SEARCH
	PUSHJ	P,SRCNDT	;SEARCH THE DEFINED NAME TABLE
	  JRST	ECOD3##		;ILLEGAL DEVICE NAME
	PUSHJ	P,GETWD1##	;GET THE LOGICAL NAME
	MOVE	P3,T1		;COPY THE NAME
	PUSHJ	P,MAKDDB	;MAKE A REMOTE NETWORK DDB
	  JRST	ECOD4##		;NO CORE AVAILABLE
	PUSHJ	P,NCSCNT	;CONNECT THE DEVICE
	  JRST	[MOVEI	T1,10(T1);STEP UP THE ERROR NUMBER
		 PUSHJ	P,STOTAC##  ;TELL CALLER WHY IT FAILED
		 PJRST	UNLDDB]	;REMOVE DDB FROM SYSTEM
	JRST	CPOPJ1##	;CONNECT OK EXIT
SUBTTL NODE.2	 RETURN A NODE NUMBER IN THE AC
NODE.2:				;ENTRY
	PUSHJ	P,GETWDU##	;GET THE ARG COUNT
	CAIE	T1,2		;MUST BE A 2
	JRST	ECOD1##		;NO ILLEGAL FUNCTION
	PUSHJ	P,GETWD1##	;GET THE NODE NAME
	PUSHJ	P,NODE.S	;FIND CORRECT NDB
	  PJRST	ECOD2##		;ILLEGAL NODE
	MOVE	T2,T1		;COPY ARGUMENT
	HLRZ	T1,NDBSNM##(W)	;GET THE NAME POINTER
	MOVE	T1,(T1)		;GET THE NAME
	TLNE	T2,-1		;WANTS A NAME?
	HLRZ	T1,NDBNNM##(W)	;NO, GET THE NODE NUMBER
	PJRST	STOTC1##	;RETURN NODE NUMBER IN AC

;SUBROUTINE TO FIND NDB FOR NODE.UUO FUNCTIONS
;CALL T1 = ARGUMENT TO NODE.UUO
;RETURNS CPOPJ IF NOT FOUND
;	CPOPJ1 WITH W SET TO NDB, RESPECTS T1

NODE.S:	PUSH	P,T1		;SAVE ARGUMENT
	PUSHJ	P,CVTOCT##	;CHECK #
	MOVE	T1,0(P)		;NOPE, RESTORE ARG
	PUSHJ	P,SRCNDB	;SCAN NDB'S
	  PJRST	TPOPJ##		;NOPE, GIVE ERROR
	PJRST	TPOPJ1##	;RETURN WITH W SET UP
SUBTTL NODE.3 STATION CONTROL MESSAGES
;FORMAT OF THE UUO ARGS
;	XWD	TIME,COUNT
;	SIXBIT	/NODE NAME/ OR NUMBER
;	XWD	COUNT,ADR OF OUTPUT BUFFER
;	XWD	COUNT,ADR OR RESPONSE BUFFER

NODE.3:	PUSHJ	P,SAVE4##	;SAVE P1
	MOVE	R,JBTADR##(J)	;GET THE RELOCATION
	MOVSI	T1,JP.POK	;CHECK FOR A POKE
	PUSHJ	P,PRVBIT##	;CHECK IT
	  CAIA			;YES
	JRST	ECOD3##		;NOT A PRIV JOB
	MOVSI	T1,NSHF!NSWP	;LOCKED BITS
	TDNN	T1,JBTSTS##(J)	;IS THE LOW SEGMENT ALREADY LOCKED?
	JRST	ECOD5##		;MUST BE LOCKED IN CORE
	TRNN	M,777760	;NO IN THE AC'S
	PJRST	ECOD1##		;ERROR
	MOVEI	P1,(M)		;SAVE THE UUO POINTER
	HRLI	P1,(J)		;AND THE JOB NUMBER
	PUSHJ	P,GETWDU##	;GET THE ARGUMENT COUNT AND FLAGS
	MOVS	P3,T1		;COPY THE TIME
	ANDI	T1,-1		;SAVE THE ARG COUNT
	CAIL	T1,3		;CHECK THE COUNT
	CAILE	T1,4		;FOR RANGE 3-4
	JRST	ECOD3##		;ERROR
	PUSHJ	P,GETWD1##	;GET THE NODE NAME
	PUSHJ	P,SRCNDB	;FINDE THE STATION
	  JRST	ECOD2##		;ILLEGAL STATION OR NUMBER
	HLRZ	T1,NDBNNM##(W)	;GET THE NODE NUMBER
	CAMN	T1,JBTLOC##	;IS THIS THE LOCAL STATION
	JRST	ECOD2##		;YES, GIVE AN ERROR
	SKIPE	T1,SCBCTL##(W)	;IS STATION CONTROL AVAILABLE
	JRST	ECOD4##		;NO NOT AVAILABLE IN USE
	PUSHJ	P,GETWD1##	;GET THE MESSAGE POINTR
	MOVE	P4,T1		;SAVE THE ARG
	JUMPE	T1,ECOD1##	;ILLEGAL
	ANDI	T1,-1		;ONLY 18 BITS
	PUSHJ	P,IADRCK##	;CHECK THE ADDRESS(MAY PAGE FAULT)
	  PJRST	ECOD1##		;NOT IN RANGE
	HLRZ	T2,P4		;GET THE BYTE COUNT
	ROT	T2,-2		;CONVER TO WORDS
	TLNE	T2,600000	;CHECK FOR A CARRY
	ADDI	T2,1		;STEP WORD BY ONE
	ADDI	T1,-1(T2)	;END OF THE ARRAY
	TRNN	T2,777400	;ONLY 512 BYTE IS MAX
	PUSHJ	P,IADRCK##	;CHECK IT
	  PJRST	ECOD1##		;ADDRESS ERROR
	HLRZ	T1,P3		;ARG COUNT
	CAIE	T1,4		;RESPONSE ?
	JRST	CPOPJ1##	;NONE
	PUSHJ	P,GETWD1##	;GET THE INPUT BUFFER ADDRESS
	JUMPE	T1,CPOPJ1##	;NO RESPONSE REQUIRED
	MOVE	P2,T1		;SAVE
	ANDI	T1,-1		;CLEAR THE BYTE COUNT
	PUSHJ	P,IADRCK##	;CHECK IT
	  JRST	ECOD1##		;ERROR
	HLRZ	T1,P2		;GET THE BYTE COUNT
	ROT	T2,-2		;CONVERT TO WORDS
	TLNE	T2,600000	;CARRY
	ADDI	T2,1		;ONE MORE WORD
	ADDI	T1,-1(T2)	;POINT TO THE END OF THE ARRAY
	PUSHJ	P,IADRCK##	;CHEDK IT
	  JRST	ECOD1##		;ERROR
	MOVEM	P1,SCBCTL##(W)	;STORE THE POINTER
	MOVE	T1,P4		;FINALLY TIME TO SEND STATION CONTROL MSG
	PUSHJ	P,NCSCTL	;BUILD AND SEND IT
	 JRST	[SETZM SCBCTL##(W)  ;NO ROOM I GUESS. FREE THIS
		 JRST ECOD4##]	;AND RETURN ERROR TO CALLER
	HLRZ	T1,NDBNNM##(W)	;GET THE NODE NUMBER
	PUSH	P,T1		;SAVE OVER CALL FOR HIBER
	MOVEI	T1,(P3)		;GET THE TIME REQUEST
	ANDI	T1,777		;ONLY NINE BITS WORTH
	IMULI	T1,^D1000	;MS TO SLEEP
	PUSHJ	P,HIBER##	;WAIT
	  JFCL
	POP	P,T1		;RESTORE THE NODE NUMBER
	PUSHJ	P,SRCNDB	;IS THE NODE STILL UP
	  JRST	ECOD2##		;NODE WENT AWAY
	SKIPE	SCBCTL##(W)	;WAKE FOR US
	JRST	[SETZM SCBCTL##(W)	;TIMED OUT
		JRST	ECOD6##]	;GIVE ERROR RETURN
	PJRST	CPOPJ1##	;EXIT MESSAGE SENT/RECEIVED
SUBTTL NODE.4 AUTO RELOAD OF DOWN LINE DAS80 SERIES REMOTE STATIONS
;FORMAT OF THE UUO ARGS
;	XWD	TIME,COUNT
;	XWD	0,0
;	XWD	0,0
;	XWD	COUNT,ADR OF RESPONSE BUFFER

NODE.4:				;ENTRY
	PUSHJ	P,SAVE2##	;SAVE P1,2,3
	MOVEI	W,NETNDB##	;SEARCH FOR A NODE WITH A BOOT MESSAGE
NODE41:	HRRZ	W,NDBNNM##(W)	;GET THE NEXT ENTRY
	JUMPE	W,ECOD2##	;NONE AVAILABLE
	HRRZ	P1,SCBRQB##(W)	;IS A REQUEST BOOT AVAILABLE
	JUMPE	P1,NODE41	;CONTINUE
	SETZM	SCBRQB##(W)	;MAKE BOOT AVAILABLE
	ADDI	M,1		;POINT TO THE NODE NAME WORD
	HLRZ	T1,NDBSNM##(W)	;GET THE NAME POINTER
	MOVE	T1,(T1)		;GET THE NAME
	PUSHJ	P,PUTWDU##	;STORE THE NAME IN THE ARG LIST
	ADDI	M,2		;POINT TO THE RECEIVE BUFFER
	PUSHJ	P,GETWDU##	;GET THE ARGUMENT
	MOVE	P2,T1		;COPY
	JUMPE	T1,ECOD1##	;ILLEGAL
	ANDI	T1,-1		;ADDRESS CHECK
	PUSHJ	P,IADRCK##	;THE BUFFER ADDRESS
	  PJRST	ECOD1##		;ILLEGAL
	HLRZ	T2,P2		;GET THE BYTE LENGTH
	ADDI	T2,3		;ROUND UP
	LSH	T2,-2		;TO WORDS
	ADDI	T1,-1(T2)	;POINT TO THE END OF THE ARRAY
	PUSHJ	P,IADRCK##	;ADDRESS CHECK
  	PJRST	ECOD1##		;ERROR
	HLRZ	T2,P2		;GET THE BYTE COUNT
	HRRZ	T1,(P1)		;GET THE BYTE COUNT
	CAIGE	T2,(T1)		;WILL IT FIT
	MOVEI	T1,(T2)		;NO, USER THE USERS SIZE (TRUNCATE)
	HRLI	P2,(T1)		;STORE THE READ BYTE COUNT
	ADDI	T1,3		;CONVERT TO WORDS
	LSH	T1,-2		;AND ROUND UP
	ADDI	T1,-1(P2)	;TERMINATE THE BLT POINTER
	HRLI	T2,1(P1)	;BLT POINTER
	HRRI	T2,(P2)		;TO MOVE THE MESSAGE
IFN FTKA10,<
	ADDI	T1,(R)		;RELOCATE FOR KA10
	ADDI	T2,(R)		;..
>
	EXCTXU	<BLT	T2,(T1)>;MOVE THE MESSAGE
	MOVE	T1,P2		;GET THE ARGUMENT
	PUSHJ	P,PUTWDU##	;STORE THE BYTE COUNT
	HLRZ	T1,(P1)		;GET THE SIZE
	MOVEI	T2,(P1)		;GET THE ADDRESS
	PUSHJ	P,GIVZWD	;RETURN THE SPACE
	PJRST	CPOPJ1##	;EXIT
SUBTTL	NODE.5	RETURN CONFIG INFO FOR NODE
;FORMAT OF THE UUO ARGS
;	XWD	0,,COUNT
;	SIXBIT	/NODE NAME/ OR NUMBER
;	0			RESERVED FOR DATE AND NAME
;	BLOCK	<COUNT-3> INFO RETURNED HERE

NODE.5:	PUSHJ	P,SAVE1##	;SAVE P1 FIRST
	PUSHJ	P,GETWDU##	;GET ARGUMENT LIST SIZE
	SUBI	T1,3		;DEDUCT OVERHEAD
	CAIG	T1,^D1000	;RIDICULOUS SIZE
	SKIPG	P1,T1		;ANY ROOM LEFT FOR ANSWER
	PJRST	ECOD1##		;NO, ILLEGAL ARG LIST
	PUSHJ	P,GETWD1##	;GET NODE NAME
	PUSHJ	P,NODE.S	;FIND CORRECT NDB
	  PJRST	ECOD2##		;ILLEGAL NODE
	PUSHJ	P,GETWD1##	;GET RESERVED WORD
	JUMPN	T1,ECOD7##	;MUST BE ZERO
NODE51:	PUSHJ	P,GETWD1##	;GET DEVICE TYPE REQUEST
	MOVSI	T2,-<OBJ.MX+1> ;NUMBER OF KNOWN DEVICES
	MOVE	T3,[POINT 6,NETTRN##] ;TRANSLATION TABLE
NODE52:	ILDB	T4,T3		;GET A TYPE
	CAIE	T4,(T1)		;FOUND REQUEST
	AOBJN	T2,NODE52	;NO, TRY ANOTHER TYPE
	SKIPGE	T2		;FIND ANY
	SKIPE	SCBTTY##(W)	;ANY OUTSTANDING CONNECTS
	TDZA	T2,T2		;NONE OF REQUESTED TYPE
	LDB	T2,NETCNF##(T2)	;GET NUMBER OF THAT TYPE
	HRL	T1,T2		;INSERT COUNT FOR USER
	PUSHJ	P,PUTWDU##	;STORE BACK
	SOJG	P1,NODE51	;DO FOR ALL ARGS
	PJRST	CPOPJ1##	;GIVE GOOD RETURN
SUBTTL	SCB INTERFACE ROUTINES
;SUBROUTINE TO LOAD INTO T1 THE TTY NUMBER OF THE OPR'S
;  TTY FOR THE STATION WHOSE NUMBER IS IN T1.

STBOPR::PUSH	P,U		;SAVE U
	HRRZS	T1		;STATION NUMBER IN T1
	PUSHJ	P,SRCNDB	;FIND THE NODE BLOCK
	  JRST	LCLOPR		;NO, USE LOCAL OPR
	HRRZ	U,SCBOPR##(W)	;GET THE OPR LDB
	SKIPN	U		;ANY ASSIGNED
LCLOPR:	MOVE	U,OPRLDB##	;NO, USE LOCAL OPR
	LDB	T1,LDPLNO##	;GET NUMBER OF TTY IN U
	JRST	UPOPJ##		;RESTORE U AND EXIT.

;SUBROUTINE STBSCA - RETURN THE STATION NUMBER
;CALL	MOVEI	T1,NNM
;	PUSHJ	P,STBSCA
;RETURN	CPOPJ			;NO SUCH STATION
;	CPOPJ1			;STATION VALID T1=NNM

STBSCA::			;ENTRY
	PUSHJ	P,SAVJW		;SAVE J AND W
	PUSHJ	P,SRCNDB	;SEARCH THE NODE DATA BLOCKS
	  POPJ	P,		;RETURN INVALID STATION
	HLRZ	T1,NDBNNM##(W)	;GET THE STATION NUMBER
	PJRST	CPOPJ1##	;EXIT
SUBTTL MAKDDB - SUBROUTINE TO BUILD A NETDDB
;CALL	MOVE	P1,NDB POINTER
;	MOVE	P2,DEVICE NAME
;	MOVE	P3,LOGICAL NAME
;	MOVE	W,NDT POINTER
;	PUSHJ	P,MAKDDB
;RETURN	CPOPJ		;NO SPACE AVAILABLE
;	CPOPJ1		;F=DDB POINTER,U=PCB

MAKDDB::MOVEI	T2,NETLEN##	;GET THE LENGTH OF THE PROTOTYPE DDB
	PUSHJ	P,GETZWD	;ALLOCATE THE SPACE
	  POPJ	P,		;SPACE NOT AVAILABLE
	MOVEI	F,(T1)		;COPY THE DDB POINTER
	HRLI	T1,NETDDB##	;BLT POINT TO COPY THE PROTOTYPE DDB
	BLT	T1,NETLEN##-1(F);COPY IT
	HRRZM	P1,DEVNET(F)	;STORE THE NDB POINTER
	MOVEM	P2,DEVNAM(F)	;STORE THE DEVICE NAME
	MOVEM	P3,DEVLOG(F)	;STORE THE LOGICAL NAME
	HLRZ	T1,NDBNNM##(P1)	;GET THE NODE NUMBER
	DPB	T1,PDVSTA##	;STORE AS THE STATION NUMBER
	HLRZ	T1,NDBNNM##(P1)	;GET THE NODE NUMBER
	TRO	T1,77700	;FORCE A STATION NUMBER ALIGNMENT
	PUSHJ	P,CVTSBT##	;CONVERT TO SIXBIT
	MOVE	T2,P2		;COPY THE DEVICE NAME
	TRNN	T2,7777		;CHECK FOR GGGU
	LSH	T2,-14		;YES, SHIFT FOR THE UNIT NUMBER
	ANDI	T2,77		;ONLY ONE DIGIT
	IORI	T1,(T2)		;INSERT THE DIGIT
	HRRM	T1,DEVNAM(F)	;STORE IN THE DEVNAME
	ANDI	T1,77		;SAVE LAST DIGIT
	SKIPN	T1		;IS IT A BLANK IE GENERIC
	TROA	T1,177		;YES, USE 177 FOR GENERIC SEARCH
	ANDI	T1,7		;ONLY THREE BITS WORTH (FOR GGGNNU)
	DPB	T1,PUNIT##	;STORE THE UNIT NUMBER
MAKDD6:	MOVSI	T1,DVCNET	;GET THE NETWORK OWNERSHIP BIT
	IORM	T1,DEVCHR(F)	;STORE WE OWN IT
	DPB	J,PJOBN##	;STORE THE JOB NUMBER
	LDB	T1,NDTBFZ##	;GET THE DEFAULT BUFFER SIZE
	DPB	T1,PBUFSZ##	;STORE THE BUFFER SIZE
	LDB	T1,NDTTYP##	;GET THE DEVICE TYPE
	DPB	T1,DEYTYP##	;STORE THE DEVICE TYPE
	MOVE	T1,NDTMOD##(W)	;GET THE DEVMOD BITS
	MOVEM	T1,DEVMOD(F)	;STORE DEVMOD
	HRLM	W,DEVNET##(F)	;LINK THE NDT TO THE DDB
;HERE TO ASSIGN A SLA
	PUSHJ	P,GETSLA	;GET A SOURCE LINK ADDRESS
	  JRST	RMVNE1		;NONE AVAILABLE
	DPB	T1,NETSLA##	;STORE THE SLA
	HRRZM	F,NETLAT##(T1)	;STORE THE NETDDB ADDRESS IN THE TABLE
	PUSHJ	P,LNKDDB	;LINK UP THE DDB
	JRST	CPOPJ1##	;EXIT WITH F=NETDDB, U=PCB, W=NDT
SUBTTL MBF - INTERNAL MONITOR BUFFER ROUTINES
;
;		FORMAT OF THE INTERNAL MONITOR BUFFERS
;
	PHASE	0
MBFMXC::!0			;MAX NUMBER OF MBF BUFFERS
MBFBFC::!0			;CURRENT FILLED BUFFER COUNT
MBFIBC::!0			;INPUT BUFFER POINTER
MBFOBC::!0			;OUTPUT BUFFER POINTER
MBFCHK::!0			;CHECKSUM FOR BINARY CARDS
MBFMBF::!BLOCK	0*0		;MONITOR BUFFERS
MBFSDS::!			;LENGTH
	DEPHASE
	RELOC	.-MBFSDS	;RECLAIM STORAGE SPACE


;SUBROUTINE BLDMBF - BUILD A SET OF INPUT MONITOR BUFFERS
;CALL	MOVE	T1,[XWD #BUFFERS,SIZE]
;	PUSHJ	P,BLDMBF
;RETURN	CPOPJ			;WHEN THE BUFFERS ARE BUIT

BLDMBF::			;ENTRY
	SKIPE	NETDEV##(F)	;DOES A BUFFER EXIST
	STOPCD	.+1,DEBUG,MBE,;++MONITOR BUFFER EXISTS
	PUSH	P,T1		;SAVE THE ARGUMENT
	HLRZ	T2,T1		;NUMBER OF BUFFERS
	IMULI	T2,(T1)		;TIMES THE SIZE OF EACH
	ADDI	T2,MBFMBF-MBFMXC;PLUS THE CONTROL INFORMATION
	HRLM	T2,NETDEV##(F)	;STORE THE SIZE
	PUSHJ	P,SLPZWD	;ALLOCATE THE SPACE
	HRRM	T1,NETDEV##(F)	;STORE THE POINTER TO THE BUFFER
	HLRZ	T2,(P)		;GET THE NUMBER OF BUFFERS BACK
	MOVEM	T2,MBFMXC(T1)	;STORE THE BUFFER COUNT
	JRST	TPOPJ##		;RESTORE THE ARG AND EXIT

;SUBROUTINE NETBCL - CLEAR A USER'S BUFFER
;CALL	PUSHJ	P,NETBCL
;RETURN	CPOPJ

NETBCL::LDB	T1,[POINT 12,@DEVIAD(F),17]	;GET THE BUFFER SIZE
	MOVEI	T2,@DEVIAD(F)	;BUFFER ADDRESS
	HRLI	T2,2(T2)	;FIRST DATA WORD
	ADDI	T2,3		;FIRST DATA WORD
	SETZM	-1(T2)		;CLEAR THE FIRST WORD
	ADDI	T1,-3(T2)	;END OF THE BUFFER
	BLT	T2,(T1)		;CLEAR IT
	POPJ	P,		;RETURN
SUBTTL AVOMBF - AVDVNCE AN OUTPUT MONITOR BUFFER
;CALL	MOVEI	F,DDB
;	PUSHJ	P,AVOMBF
;RETURN	CPOPJ			;NO DATA PENDING
;	CPOPJ1			;BUFFER IS AVDVNCED AND CONTAINS NEW DATA

AVOMBF::
	SKIPN	T2,NETDEV##(F)	;GET THE MONITOR BUFFER ADDRESS
	JRST	AVIMB1		;NONE,  BAD NEWS
	AOS	T1,MBFOBC(T2)	;ADVANCE TO THE NEXT BUFFER
	CAMN	T1,MBFMXC(T2)	;TIME TO WRAP AROUND
	SETZM	MBFOBC(T2)	;YES, RESET TO ZERO
	SOSLE	T1,MBFBFC(T2)	;REDUCE THE AMOUNT OF BUFFER IN USE
	AOS	(P)		;ANOTHER CARD
	SKIPGE	T1		;DID INTERRUPT LEVEL CHANGE THE COUNT
	AOS	MBFBFC(T2)	;YES, ACCOUNT FOR THE SOS
	POPJ	P,		;RETURN NO BUFFERS AVAILABLE

;SUBROUTINE AVIMBF - AVOANCE AN INPUT MONITOR BUFFER
;CALL	MOVEI	F,DDB
;	PUSHJ	P,AVIMBF
;RETURN	CPOPJ			;BUFFER IS AVOANCED

AVIMBF::
	SKIPN	T2,NETDEV##(F)	;GET THE MONITOR BUFFER ADDRESS
AVIMB1:	STOPCD	CPOPJ##,DEBUG,NMF,;++NO MONITOR BUFFER
	AOS	T1,MBFIBC(T2)	;UPDATE THE BUFFER COUNT
	CAMN	T1,MBFMXC(T2)	;TIME TO WRAP AROUND
	SETZM	MBFIBC(T2)	;YES, RESET TO ZERO
	AOS	MBFBFC(T2)	;INCREMENT THE NUMBER OF BUFFERS WITH DATA
	POPJ	P,		;RETURN

;SUBROUTINE DRQMBF - ROUTINE TO SEND DATA REQUEST BASED ON EMPTY MONITOR BUFFERS
;CALL	MOVEI	F,DDB
;	PUSHJ	P,DRQMBF
;RETURN	CPOPJ

DRQMBF::			;ENTRY
	SKIPN	T4,NETDEV##(F)	;GET THE MONITOR BUFFER ADDRESS
	JRST	AVIMB1		;NO MONITOR BUFFER
	MOVE	T1,MBFMXC(T4)	;GET THE NUMBER OF BUFFERS ALLOWED
	SUB	T1,MBFBFC(T4)	;MINUS CUFFERNT COUNT =FREE
	JUMPLE	T1,CPOPJ##	;NONE AVAILABLE
	HLRZ	T2,NETDRQ##(F)	;GET THE NUMBER OF OUTSTANDING RQUESTS
	SUBI	T1,(T2)		;MINUS THE OUTSTANDING REQUESTS
	JUMPLE	T1,CPOPJ##	;NON NEED FOR MORE
	PUSH	P,T1		;SAVE THE COUNT
DRQMB1:PUSHJ	P,NCSDRQ	;SEND THE REQUESTS
	  JRST	[PUSHJ	P,NETSLP	;WAIT FOR FREE CORE
		MOVE	T1,(P)		;GET THE COUNT BACK
		JRST	DRQMB1]	;TRY AGAIN
	POP	P,T1		;GET THE REQUEST COUNT BACK
	HRLZS	T1		;IN THE LEFT HALF
	ADDM	T1,NETDRQ##(F)	;STORE THE UPDATD COUNT
	POPJ	P,		;RETURN
SUBTTL MAKPCB - BUILD A PROTOCOL DATA BLOCK
;SUBROUTINE MAKPCB - BUILD A PROTOCOL DATA BLOCK
;CALL	MOVEI	F,DDB OR 0 IF AN NCL MESSAGE
;	MOVEI	W,NDB
;	PUSHJ	P,MAKNDB
;RETURN	CPOPJ			;NO SPACE AVAILABLE
;	CPOPJ1			;U=PCB POINTER

MAKPCB:	MOVEI	T2,PCBLEN##	;GET THE LENGTH
	PUSHJ	P,GETZWD	;GET A ZERO BLOCK ON FREE CORE
	  POPJ	P,		;NO SPACE
	MOVEI	U,(T1)		;COPY THE PCB POINTER
	HRRM	W,PCBNDB(U)	;STORE THE NDB POINTER
	JUMPE	F,CPOPJ1##	;EXIT IF FOR NCS
	HRLM	F,PCBDDB##(U)	;STORE THE DDB POINTER OR ZERO
	PJRST	CPOPJ1##	;EXIT U=PCB

;SUBROUTINE MAKNDB - BUILD A NODE DATA BLOCK (NDB)
;CALL	MOVEI	J,FEK
;	MOVEI	T1,NNM
;	PUSHJ	P,MAKNDB
;RETURN	CPOPJ		;NO CORE
;	CPOPJ1			;W=NDB

MAKNDB:				;ENTRY
	PUSH	P,T1		;SAVE THE NODE NUMBER
	MOVEI	T2,NDBLEN##	;LENGTH
	PUSHJ	P,GETZWD	;ALLOCAT
	  PJRST	TPOPJ##	;NO SPACE
	MOVEI	W,(T1)		;COPY THE POINTER
	HRRM	J,NDBFEK##(W)	;STORE THE FEK POINTER
	HRRZ	T1,NETNDB##	;GET THE START OF THE NDB CHAIN
	HRRM	T1,NDBNNM##(W)	;LINK THIS NDB TO THE START
	HRRM	W,NETNDB##	;LINK
	POP	P,T1		;GET THE NODE NUMBER
	HRLM	T1,NDBNNM##(W)	;STORE
	PJRST	CPOPJ1##	;EXIT

;SUBROUTINE GETSLA - GET A SOURCE LINK ADDRESS FROM THE LAT TABLE
;CALL	PUSHJ	P,GETSLA
;RETURN	CPOPJ			;NONE AVAILABLE
;	CPOPJ1			;T1=SLA

GETSLA:				;ENTRY
	MOVNI	T1,LATLEN##	;GET THE LENGTH OF THE TABLE
	MOVSI	T1,(T1)		;MAKE A POINTER WORD
	SKIPE	NETLAT(T1)	;LOOK FOR AN AVAILABLE SLOT
	AOBJN	T1,.-1		;CONTINUE STEPING
	JUMPGE	T1,CPOPJ##	;NONE AVAILABLE
	JRST	CPOPJ1##	;T1=SLA
SUBTTL RMV??? REMOVE DATA BLOCKS TO FEE CORE
;SUBROUTINE RMVPCB - REMOVE THE PCB FROM FREE CORE
;CALL	MOVEI	U,PCB
;	PUSHJ	P,RMVPCB
;RETURN	CPOPJ

RMVPCB:	MOVSI	T1,PCB.TY##	;CHECK FOR A TTY PCB
	TDNE	T1,PCBBLK##(U)	;IN THE FLAG WORD
	JRST	[SETZM	PCBNDB##(U)  ;TTY PCB, CLEAR THE NDB POINTER
		POPJ	P,]		;RETURN
	HLRZ	T1,PCBICT##(U)	;GET THE COUNT
	JUMPE	T1,RMVPC1	;NONE
	HRRZ	T2,PCBIAD##(U)	;GET THE INPUT POINTER
	PUSHJ	P,GIVZWD	;REMOVE THE SPACE
RMVPC1:	HLRZ	T1,PCBOC2##(U)	;GET THE DATA COUNT
	JUMPE	T1,RMVPC3	;NONE
	HRRZ	T2,PCBOA2##(U)	;GET THE ADDRESS
	PUSHJ	P,GIVZWD	;RETURN THE SPACE
RMVPC3:	MOVEI	T2,(U)		;COPY THE ADDRESS
	MOVEI	T1,PCBLEN##	;GET THE LENGTH
	PJRST	GIVZWD		;RETURN THE SPACE

;SUBROUTINE RMVNET - ROUTINE TO REMOVE A NET DDB FROM THE ADDRESS SPACE
;CALL	MOVE	F,DDB		;MUST NOT BE LINKED
;	PUSHJ	P,RMVNET
;RETURN	CPOPJ

UNLDDB::MOVEI	T2,NETDDB##	;GET THE STARTING DDB
UNLDB1:	MOVE	T1,T2		;FOLLOW THE DDB CHAIN
	HLRZ	T2,DEVSER(T1)	;NEXT DDB
	JUMPE	T2,CPOPJ##	;WENT AWAY
	CAIE	T2,(F)		;IS THIS THE ONE
	JRST	UNLDB1		;NO CONTINUE
	HLRZ	T2,DEVSER(F)	;GET THE NEXT DDB
	HRLM	T2,DEVSER(T1)	;REMOVE THE DDB LINKS
RMVNET:
RMVNE1:
	LDB	T1,NETSLA##	;GET THE SOURCE LINK ADDRESS
	SKIPE	T1		;SEE ASSIGNED
	SETZB	T1,NETLAT(T1)	;YES, CLEAR THE ENTRY
	DPB	T1,NETSLA##	;CLEAR THE SOURCE
IFN FTTSK,<
	LDB	T1,DEYTYP##	;GET THE DEVICE TYPE
	CAIN	T1,<.TYTSK/.TYEST>	;A RASK
	PUSHJ	P,RMVTSK##	;YES, REMOVE THE TASK
>;END FTTSK
	HRRZ	T2,NETDEV##(F)	;CHECK FOR A MONITOR BUFFER
	JUMPE	T2,RMVNE2	;NO
	HLRZ	T1,NETDEV##(F)	;YES, GET THE SIZE
	PUSHJ	P,GIVZWD	;RETURN THE SPACE
RMVNE2:	MOVEI	T2,(F)		;GET THE DDB ADDRESS
	MOVEI	T1,NETLEN##	;ANE THE LENGTH
	PJRST	GIVZWD		;REMOVE THE DDB AND EXIT
SUBTTL SUBROUTINE TO RETURN STORAGE DATA BLOCK TO THE MONITOR
;SUBROUTINE RMVNDB - REMOVE A NODE DATA BLOCK NDB
;CALL	MOVEI	W,NDB
;	PUSHJ	P,RMVNDB
;RETURN	CPOPJ

RMVNDB:	PUSHJ	P,SAVJW		;SAVE J AND W
	PUSHJ	P,SAVE1##	;SAVE P1
	PUSHJ	P,OFLNDB	;TYPE OFFLINE MESSAGE
IFN FTPI,<
	PUSHJ	P,PSINTC##	;SIGNAL NETWORK TOPOLOGY CHANGE TO THOSE INTERESTED
>
;HERE TO CHECK FOR STATION CONTROL RESOURCE
	SKIPN	T1,SCBCTL##(W)	;IS IT IN USE
	JRST	RMVNT0		;NO CONTINUE
	HLRZS	T1		;PUT THE JOB NUMBER IN T1(RT)
	PUSH	P,W		;SAVE W
	PUSHJ	P,WAKJOB##	;WAKE UP THE JOB
	POP	P,W		;RESTORE W

;REMOVE THE DEVICES CONNECT TO THIS NODE
;HERE TO REMOVE THE TTY'S
RMVNT0:	MOVE	P1,NETRTY##	;GET THE POINTER TO THE REMOTE TTY'S
RMVNT1:	MOVE	U,LINTAB##(P1)	;GET A TTY LDB
	HLRZ	T1,LDBREM##(U)	;GET THE NDB POINTER
	CAIE	T1,(W)		;ATTACHED TO THIS NDB
	JRST	RMVNT5		;NO, LEAVE IT ALONE
	PUSHJ	P,CLRTTY	;CLEAR THE LDB FOR THIS TTY
	PUSHJ	P,RMVTTY	;DETACH THE TTY
RMVNT5:	AOBJN	P1,RMVNT1	;TRY FOR ANOTHER TTY

RMVOAD:	MOVE	J,NDBFEK##(W)	;MARK MESSAGES QUEUED TO THIS NODE
				; AS INVALID FOR OUTINT
	HRRZ	U,FEKOAD##(J)	;LOOK AT MESSAGE NOW GOING TO -11
	JUMPE	U,RMVNV0	;NOTHING THERE, EASY
	MOVSI	P1,PCB.OF##	;GET NODE OFFLINE FLAG
RMVOA1:	HRRZ	T1,PCBNDB##(U)	;GET NDB WHO WILL GET THIS MESSAGE
	CAIN	T1,(W)		;SAME ONE WE WANT TO REMOVE?
	IORM	P1,PCBBLK##(U)	;YEP, MARK MESSAGE INVALID
	HRRZ	U,PCBBLK##(U)	;STEP TO NEXT MESSAGE
	JUMPN	U,RMVOA1	; AND CHECK IT
;HERE TO REMOVE THE PHYSICAL DEVICE (NOT TTY'S)
RMVNV0:	MOVNI	P1,LATLEN##	;GET THE LENGTH OF THE LAT TABLE
	MOVSI	P1,(P1)		;MAKE AN AOBJN POINTER
RMVNV1:	SKIPG	F,NETLAT##(P1)	;GET AN ENTRY
	JRST	RMVNV4		;NULL ENTRY
	HRRZ	T1,DEVNET(F)	;GET THE NODE POINTER
	CAIE	T1,(W)		;CONNECTED TO THIS NODE
	JRST	RMVNV4		;NO, TRY ANOTHER
	LDB	J,PJOBN##	;GET THE JOB NUMBER
	HRROS	DEVNAM(F)	;KILL THE DEVICE NAME
	PUSH	P,W
IFN FTPI,<
	PUSHJ	P,PSIDWN##	;SIGNAL DEVICE IS DOWN
>
	MOVEI	T1,NRTUNN-NODERT;GET NO SUCH NODE ERROR CODE
	DPB	T1,NETRSN##	;SET THE REASON FOR WAKE UP
	PUSHJ	P,NETWAK	;WAKE THE JOB UP
	MOVSI	S,IOSCON	;GET THE CONNECT BIT
	ANDCAB	S,DEVIOS(F)	;CLEAR IT SO WE WON'T SEND A DISCONNECT
	MOVEI	T1,ASSCON	;GET ASSIGN BY CONSOLE
	ANDCAB	T1,DEVMOD(F)	;CLEAR IT SO RELEASE WILL WORK
	TRNN	T1,ASSPRG	;IS THE DEVICE INITED
	JRST	RMVNV2		;NO
	TDO	S,[XWD IOSERR,IOIMPM!IODERR!IODTER!IOBKTL];SET SOME ERROR FLAGS
	TRZE	S,IOACT		;CLEAR IO ACT
	PUSHJ	P,SETIOD##	;SET IO DONE IF ACTIVE
	PUSHJ	P,STOIOS##	;STORE S
	JRST	RMVNV3		;UUO LEVEL WILL CLEAR THE DDB FROM DEVLST
RMVNV2:	PUSHJ	P,RELEA9##	;NO REMOVE THE DDB
RMVNV3:	POP	P,W		;RESTORE THE NDB
RMVNV4:	AOBJN	P1,RMVNV1	;CONTINUE
;HERE TO PURGE THE NDB NAME POINTERS
	MOVEI	T1,^D8		;FOUR WORDS TO REMOVE
	HLRZ	T2,NDBSID##(W)	;GE THE SOFTWARE ID POINTER
	SKIPE	T2		;ASSIGNED
	PUSHJ	P,GIVZWD	;RETURN THE SPACE
	MOVEI	T1,^D8		;FOUR WORDS TO RETURN
	HRRZ	T2,NDBSID##(W)	;GET THE ADDRESS
	SKIPE	T2		;NOT ASSIGNED
	PUSHJ	P,GIVZWD	;REMOVE THE SPACE
	MOVEI	T1,1		;ONE WORD
	HLRZ	T2,NDBSNM##(W)	;GET THE STATION NAME
	SKIPE	T2		;NOT ASSIGNED
	PUSHJ	P,GIVZWD	;RETURN THE SPACE
;HERE TO REMOVE THE QUEUES FOR THE NODES
	HRRZ	P1,NDBQUE##(W)	;GET THE POINTER
	JUMPE	P1,RMVND2	;EMPTY
RMVND1:	MOVEI	U,(P1)		;GET THE NEXT ENTRY
	HRRZ	P1,PCBBLK##(U)	;GET THE NEXT ENTRY
	PUSHJ	P,RMVPCB	;REMOVE THE QUEUE ENTRY
	JUMPN	P1,RMVND1	;CHECK FOR THE END
RMVND2:
	HLRZ	P1,NDBQUE##(W)	;GET THE POINTER
	JUMPE	P1,RMVND4	;EMPTY
RMVND3:	MOVEI	U,(P1)		;GET THE NEXT ENTRY
	HRRZ	P1,PCBBLK##(U)	;GET THE NEXT ENTRY
	PUSHJ	P,RMVPCB	;REMOVE THE QUEUE ENTRY
	JUMPN	P1,RMVND3	;CHECK FOR THE END
RMVND4:
	PUSH	P,W		;SAVE THE NDB POINTER
	HLRZ	T1,NDBNNM##(W)	;GET THE NODE NUMBER
	MOVEI	W,NETNDB##	;GET OUR NODE BLOCK
	PUSHJ	P,SRCTOP	;FIND OUT IF A NEIGHBOR
	  JRST	RMVND7		;NO
	SETZ	T1,		;MAKE A ZERO
	DPB	T1,T4		;REMOVE THE NEIGHBOR
	PUSHJ	P,SETNBN	;SET UP TO SEND NEIGHBORS
RMVND7:	POP	P,W		;RESTORE THE NODE DATA BLOCK
	MOVEI	T1,NETNDB##	;GET THE START OF THE NDB CHAIN
RMVND5:	HRRZ	T2,NDBNNM##(T1)	;GET THE NEXT POINTER
	JUMPE	T2,CPOPJ##	;EXIT IF END
	CAIN	T2,(W)		;IS THIS THE BLOCK
	JRST	RMVND6		;YES,
	MOVEI	T1,(T2)		;NO, STEP ALONG
	JRST	RMVND5		;TRY AGAIN
RMVND6:	HRRZ	T3,NDBNNM##(W)	;GET THE FORWARD LINK
	HRRM	T3,NDBNNM##(T1)	;STORE BACKWARD
	MOVEI	T1,NDBLEN##	;GET THE LENGTH
	PJRST	GIVZWD		;RELEASE THE BLOCK
;SUBROUTINE LNKDDB - ADD THE DDB(F) INTO THE DDB CHAIN
;CALL	MOVEI	F,DDB
;	PUSHJ	P,LNKDDB
;RETURN	CPOPJ

LNKDDB:	PUSHJ	P,SAVE1##	;SAVE P1
	PUSH	P,F		;SAVE THE DDB POINTER
	MOVE	T1,DEVLOG(F)	;GET THE LOGICAL NAME
	PUSHJ	P,DEVLG##	;CHECK FOR IN USE
	  JRST	LNKDD1		;NO,
	SETZM	DEVLOG(F)	;YES, CLEAR THE LOGICAL NAME
	MOVE	T2,DEVMOD(F)	;GET THE DEV MODE BITS
	TLNE	T2,DVDSK	;IS IT A DSK
	TRNE	T2,ASSPRG	; AND INIT'ED
	JRST	LNKDD1		;NO IGNORE
	PUSHJ	P,CLRDVL##	;CLEAR LOGICAL NAME TABLE ENTRY
	PUSHJ	P,CLRDDB##	;YES, CLEAR THE DDB
LNKDD1:	POP	P,F		;RESTORE THE DDB POINTER
	PUSHJ	P,SETDVL##	;SET UP THE LOGICAL NAME
	SKIPN	DEVLOG(F)	;WAS IT BEING CLEARED
	PUSHJ	P,ASSCK1##	;YES, RECLAIM SPACE
	MOVEI	T1,NETDDB##	;GET THE PROTOTYPE
	HLRZ	T2,DEVSER(T1)	;GT THE LINK POINTER
	HRLM	T2,DEVSER(F)	;LINK THIS TO THE PROTOTYPE
	HRLM	F,DEVSER(T1)	;AND THE PROTOTYPE
	POPJ	P,		;RETURN

;SUBROUTINE ZAPDDB - REMOVE THE DDB ON A RELEASE
;CALL	MOVEI	F,DDB
;	PUSHJ	P,ZAPNET
;RETURN	CPOPJ

ZAPNET::			;ENTRY FROM UUOCON (RELEA6)
	MOVSI	T1,IOSCON	;GET THE CONNECT BIT
	TDNN	T1,DEVIOS(F)	;IS THE DDB CONNECTED
	PJRST	UNLDDB		;NO, REMOVE THE DDB
	MOVE	T1,.C0JOB##	;GET THE JOB NUMBER
	LDB	T2,PJOBN##	;GET JOB #
	SKIPN	T2		;DON'T CHANGE IF THERE IS ONE
	DPB	T1,PJOBN##	;MUST BE A JOB NUMBER FOR THE DISCONNECT
	HRRZ	W,DEVNET##(F)	;GET THE NDB POINTER
ZAPNE1:	LDB	T1,NETDLA##	;GET THE DLA
	MOVEI	T2,0		;DISCONNECT NORMAL
	PUSHJ	P,NCSDSC	;SEND THE MESSAGE
	  JRST	[PUSHJ	P,NETSLP	;WAIT FOR CORE TO BECOME AVAIL
		JRST	ZAPNE1]		;TRY AGAIN
	POPJ	P,		;EXIT
SUBTTL SUBROUTINES TO SEARCH AND DEFINE DDB' NDT'S ETC
;SUBROUTINE SRCNDT - SEARCH THE NETWORD DEVICE TABLE
;CALL	HRRZ	T1,(SIXBIT /GENERICE NETWORK DEVICE NAME/)
;	MOVEI	P1,NDB
;	PUSHJ	P,SRCNDT
;RETURN	CPOPJ			;DEVICE NOT FOUND
;	CPOPJ1			;DEVICE FOUND W(RT)=THE NDT POINTER
SRCNDT::MOVE	W,NDTPTR##	;GET THE SEARCH POINTER
SRCNDC:	HLRZ	T2,NDTNAM##(W)	;GET THE -10 DEVICE NAME
	HRRZ	T3,NDTNAM##(W)	;GET THE -11 DEVICE NAME
	CAIE	T1,(T2)		;IS IT A -10 DEVICE
	CAIN	T1,(T3)		;OR A -11 DEVICE
	JRST	SRCNDD		;CHECK THE CONFIGURATION
	ADDI	W,NDTLEN##-1	;NO, STEP TO THE NEXT ENTRY
	AOBJN	W,SRCNDC	;AND TRY AGAIN
	POPJ	P,		;DEVICE NOT FOUND
SRCNDD:	PUSH	P,W		;SAVE THE NDT POINTER
	LDB	T1,NDTOBJ##	;GET THE DEVICE TYPE
	MOVEI	W,(P1)		;COPY THE NDB POINTER
	LDB	T1,NETCNF##(T1)	;GET THE CONFIGURATION COUNT
	JUMPE	T1,WPOPJ##	;THAT NODE DOES NOT HAVE ANY
	PJRST	WPOPJ1##	;DEVICE IS OK


;SUBROUTINE SRCNDB - SEARCH THE NODE DATA BLOCK
;CALL	MOVE	T1,NNM		;NODE NUMBER
;OR	MOVE	T1,[SIXBIT /NODE NAME/]	;SIXBIT NODE NAME
;	PUSHJ	P,SRCNDB
;RETURN	CPOPJ			;NOT FOUND
;	CPOPJ1			;FOUND W=NDB POINTER
SRCNDB::JUMPE	T1,CPOPJ##	;NETSER ON ZERO
	MOVEI	W,NETNDB##	;GET THE STARTING NDB
SRCND1:	HLRZ	T3,NDBNNM##(W)	;GET THE NODE NUMBER
	TLNE	T1,-1		;NUMBER OR SIXBIT
	JRST	SRCND2		;SIXBIT
	CAIN	T1,(T3)		;COMPARE
	JRST	CPOPJ1##	;YES, EXIT
	JRST	SRCND3		;NO, STEP TO THE NEXT
SRCND2:	HLRZ	T2,NDBSNM##(W)	;GET THE STATION NAME POINTER
				;INSERT CODE HERE FOR LONG STATION NAMES
	CAMN	T1,(T2)		;MATCH
	JRST	CPOPJ1##	;YES, EXIT
SRCND3:	HRRZ	W,NDBNNM##(W)	;GET THE NEXT POINTER
	JUMPE	W,CPOPJ##	;END OF LIST
	JRST	SRCND1		;NO, CONTINUE
SUBTTL ROUTINE TO GENERATE THE NCL PROTOCOL HEADERS
;SUBROUTINE NCSHDR - CREATE<NCT><DNA><SNA><NCA><NCN>
;CALL	MOVEI	U,PCB
;	MOVEI	W,NDB
;	MOVEI	T1,NCT MESSAGE TYPE
;	PUSHJ	P,NCSHDR
;RETURN	CPOPJ			;NO CORE
;	CPOPJ1			;P3=COUNT, P2=CURRENT BYTE POINTER

NCSHDR:				;ENTRY
	MOVE	P1,T1		;COPY THE FLAGS
	MOVEI	T2,^D16		;TEMP***
	PUSHJ	P,GETZWD	;ALLOCATE THE MESSAGE SPACE
	  POPJ	P,		;NO SPACE AVAILABLE
	MOVEI	P2,(T1)		;MAKE A BYTE POINTER
	HRLI	P2,(POINT 8)	;FOR THE MESSAGE OUTPUT
	MOVEM	P2,PCBOAD##(U)	;STORE THE BYTE POINTER
	MOVSI	T1,^D16		;GET THE SIZE
	MOVEM	T1,PCBOCT##(U)	;STORE
;ENTRY FOR GENERATE A HEADER FOR TTY OUTPUT
NCSTTY:
	SETZ	P3,		;CLEAR THE COUNT FIELD
	LDB	T1,NDBRFL##	;GET THE NODE FLAGS ROUTINE ETC
	IORI	P1,NCT.RH!NCT.SQ(T1)	;INSERT THE ADDITIONAL FLAGS
				; AND THE ROUTING HEADER FLAGS
;NCT
	MOVE	T1,P1		;COPY THE FLAGS
	PUSHJ	P,BI2EBI	;OUTPUT THE FLAGS
;DNA
	HLRZ	T1,NDBNNM##(W)	;GET THE DESTINATION NODE ADDRESS
	PUSHJ	P,BI2EBI	;OUTPUT
;SNA
	MOVEI	T1,NETNDB##	;ADDRESS OF THE NODE DTAT BLOCK
	HLRZ	T1,NDBNNM##(T1)	;GET THE SOURCE NODE ADDRESS (US)
	PUSHJ	P,BI2EBI	;OUTPUT
;NCA
				;REAL MESSAGE NUMBER ARE ASSIGN BY NETWRT
	MOVEI	T1,0		;DUMMY MESSAGE NUMBER NOW
	PUSHJ	P,DPBBIN	;STORE
;NCN
	MOVEI	T1,0		;AGAIN
	PUSHJ	P,DPBBIN
;EXIT
	MOVSI	T1,PCB.NM##	;GET NUMBERED MESSAGE FLAG
	TRNN	P1,NCT.TP	;NUMBERED MESSGE
	IORM	T1,PCBBLK##(U)	;YES, SET THE FLAG
	ADDM	P3,PCBOCT##(U)	;UPDATE THE CURRENT COUNT
	SETZ	P3,		;CLEAR THE COUNT FIELD
	PJRST	CPOPJ1##	;EXIT
SUBTTL UNNUMBERED NCS CONTOL MESSAGES
;SUBROUTINE NCSSTR/NCSSAK - SEND A START/STACK MESSAGE
;CALL	MOVEI	W,NDB		;WHERE TO SEND THE MESSAGE
;	PUSHJ	P,NCSSTR/NCSSTK
;RETURN	CPOPJ			;CAN'T NO CORE
;	CPOPJ1			;OK

NCSSTR:	MOVSI	T1,NDB.SK##	;GET THE STACK BIT
	ANDCAM	T1,NDBFEK##(W)	;CLAR IT
	MOVEI	T1,NCT.ST	;START FLAGS
	SKIPA
NCSSTK:	MOVEI	T1,NCT.SK	;START ACK FLAGS
	PUSHJ	P,SAVE3##	;SAVE THE P'S
	PUSH	P,T1		;SAVE THE FLAGS
	SETZ	F,		;NCS MESSAGE
	PUSHJ	P,MAKPCB	;MAKE A PCB U=PCB
	  PJRST	TPOPJ##		;EXIT NO CORE
	MOVE	T1,(P)		;GET THE MESSAGE TYPE BACK
	PUSHJ	P,NCSHDR	;WRITE THE HEADER
	  JRST	[POP	P,T1	;RESTORE T1
		PJRST	RMVPCB]	;REMOTE THE PCB
	PUSHJ	P,NCSOPD	;GET THE <NNM><SNM><SID>
	ADDM	P3,PCBOCT(U)	;UPDATE THE COUNT
	POP	P,T2		;RESTORE THE FLAGS
	MOVSI	T1,NDB.ST##	;GET THE START BIT
	CAIE	T2,NCT.ST	;IS IT A START
	MOVSI	T1,NDB.SK##	;NO, SET STACK
	IORM	T1,NDBFEK##(W)	;STORE THE START BIT
	PJRST	NETWSR		;SEND THE MESSAGE
;SUBROUTINE NCSNID - SEND A NODE ID MESSAGE
;CALL	MOVEI	J,FEK
;	PUSHJ	P,NCSNID
;RETURN	CPOPJ			;NO CORE ETC
;	CPOPJ1			;SENT

NCSNID:	PUSHJ	P,SAVE3##	;SAVE THE P'S
	SETZB	W,F		;NO DDB OR NDB
	PUSHJ	P,MAKPCB	;GET A PCB
	  POPJ	P,		;NO SPACE
	MOVEI	T2,^D16		;MESSAGE SIZE
	PUSHJ	P,GETZWD	;ALLOCATE THE MESSAGE SPACE
	  PJRST	RMVPCB		;NO SPACE AVAILABLE
	MOVEI	P2,(T1)		;MAKE A BYTE POINTER
	HRLI	P2,(POINT 8)	;FOR THE MESSAGE OUTPUT
	MOVEM	P2,PCBOAD##(U)	;STORE THE BYTE POINTER
	SETZ	P3,		;CLEAR THE COUNT FIELD
	MOVSI	T1,^D16		;GET THE SIZE
	MOVEM	T1,PCBOCT##(U)	;STORE
;NCT
	MOVEI	T1,NCT.ID!NCT.SQ	;GET ID FLAGS
	PUSHJ	P,BI2EBI	;WRITE THE FLAGS
;NCA
	MOVEI	T1,0		;NO, ACKS FOR MESSAGE NUMBERS
	PUSHJ	P,BI2EBI	;WRITE
;NCN
	MOVEI	T1,0		;SAME AS ABOVE
	PUSHJ	P,BI2EBI	;WRITE
;OPD
	PUSHJ	P,NCSOPD	;SEND THE <NNM><SNM><SID>
	MOVSI	T1,FK.NID##	;GET NODE ID FLAG
	IORM	T1,FEKBLK##(J)	;SET FLAG NODE ID SENT
	ADDM	P3,PCBOCT##(U)	;UPDATE THE COUNT
IFN FTCMSR,<
	AOS	NCLXTP+NCT.ID
>
	AOS	(P)		;SKIP RETURN
	CONO	PI,PIOFF	;NO RACE, "NETWRT" WILL RESTORE PI'S
	PJRST	FRCWRT		;FORCE WRITE THE MESSSAGE
;SUBROUTINE NCSOPD - GENERATE THE OPTIONAL DATA <NNM><SNM><SID>
;CALL	MOVEI	U,PCB
;	PUSHJ	P,NCSOPD
;RETURN	CPOPJ

NCSOPD:				;ENTRY
	PUSH	P,W		;SAVE THE NDB POINTER
	MOVEI	W,NETNDB##	;GET THE NODE DATA BLOCK
;NNM
	HLRZ	T1,NDBNNM##(W)	;GET THE NODE NUMBER
	PUSHJ	P,BI2EBI	;WRITE
;SNM
	HLRZ	T1,NDBSNM##(W)	;GET THE POINTER TO THE SYSTEM NAME
	MOVE	T1,(T1)		;GET THE NAME
	PUSHJ	P,SX2EAS	;WRITE
;SID
	HRRZ	P1,NDBSID##(W)	;SOFTWARE NAME
	PUSHJ	P,AS2EAS	;WRITE
	HLRZ	P1,NDBSID##(W)	;CREATION DATE
	POP	P,W		;RESTORE THE NDB
	PJRST	AS2EAS		;WRITE

;SUBROUTINE NCSACK - NCSNAK SEND AN ACK MESSAGE
;CALL	MOVEI	W,NDB
;PUSHJ	P,NCSACK/NCSNAK
;RETURN	CPOPJ			;ERROR
;	CPOPJ1			;OK

NCSACK:	LDB	T1,NDBNCA##	;GET LAST ACK SENT
	LDB	T2,NDBLAS##	;AND LAST ACK PROCESSED
	CAIN	T1,(T2)		;IS AN ACK REQUIRED
	POPJ	P,		;NO, EXIT
NCSAKK:	MOVEI	T1,NCT.AK	;GET THE ACK TYPE
	SKIPA
NCSNAK:	MOVEI	T1,NCT.NK	;GET THE NACK
	PUSHJ	P,SAVE3##	;SAVE THE P'
	PUSH	P,F		;SAVE F
	SETZ	F,		;CLEAR F NCS MESSAGE
	PUSH	P,T1		;SAVE THE TYPE
	PUSHJ	P,MAKPCB	;MAKE A PCB
	  JRST	[POP	P,T1	;RESTORE T1
		PJRST	FPOPJ##]	;EXIT
	POP	P,T1		;RESTORE THE FLAG
	PUSHJ	P,NCSHDR	;WRITE THE HEADER
	  JRST	[POP	P,F	;RESTORE F
		PJRST	RMVPCB]	;REMOVE THE PROTOCOL BLOCK
	POP	P,F		;RESTORE F
	PJRST	NETWSR		;SEND THE MESSAGE
SUBTTL NCS NUMBER CONTROL MESSAGES
;SUBROUTINE NCNHDR - WRITE THE HEADER FOR NUMBER CONTROL MESSAGES
;CALL	MOVEI	F,DDB OR 0
;	MOVEI	W,NDB
;	PUSHJ	P,NCMHDR
;RETURN	CPOPJ			;NO CORE
;	CPOPJ1			;OK U=PCB

NCMHDR:			;ENTRY
	PUSHJ	P,MAKPCB	;MAKE A PCB
	  POPJ	P,		;NO CORE
	MOVEI	T1,0		;CONTROL MESSAGE
	PUSHJ	P,NCSHDR	;OUTPUT THE HEADER
	  PJRST	RMVPCB		;NO CORE, REMOVE THE PCB AND EXIT
	MOVEI	T1,0		;NUMBERED CONTROL MESSGE
	PUSHJ	P,BI2EBI	;DEPOSITE
	AOS	PCBOCT##(U)	;COUNT THE FIRST BYTE
	AOS	PCBOCT##(U)	;COUNT THE SECOND BYTE
	SETZ	P3,		;CLEAR THE COUNT FIELD
	IBP	P2		;STEP OVER THE <CNT> FIELD
	PJRST	CPOPJ1##	;EXIT P2 IS UPDATED
;SUBROUTINE NCSCNT - SEND A CONNECT MESSAGE
;CALL	MOVEI	F,DDB
;	PUSHJ	P,NCSCNT

;RETURN	CPOPJ			;NO SPACE AVAILABLE
;
				;P2=CURRENT OUTPUT BYTE POINTER
NCSCNT::PUSHJ	P,SAVJW		;SAVE W AND J
	PUSHJ	P,SAVE3##	;SAVE P1,P2,P3
	HRRZ	W,DEVNET##(F)	;GET THE NODE DATA BLOCK
	PUSHJ	P,NCMHDR	;WRITE NUMBER MESSAGE HEADER
	  JRST	[MOVEI	T1,NRTNCE-NODERT
		 POPJ	P,]	;GIVE CAPACITY EXCEEDED ERROR
	PUSH	P,P2		;SAVE THE <CNT> POSITION
	MOVEI	T1,NC.CNT	;CONNECT MESSAGE TYPE
	PUSHJ	P,BI2EBI	;OUTPUT
;DLA
	LDB	T1,NETDLA##	;GET THE DESTINATION ADDRESS
	PUSHJ	P,BI2EBI	;OUTPUT
;SLA
	LDB	T1,NETSLA##	;GET THE SOURCE PROCESS NUMBER
	PUSHJ	P,BI2EBI	;OUTPUT
;DPN
	HLRZ	W,DEVNET##(F)	;GET THE NDT POINTER
	LDB	T1,NDTOBJ##	;GET THE OBJECT TYPE
IFN FTTSK,<
	CAIE	T1,OBJ.TK	;CONNECTING A TASK
	JRST	NCSCN0		;NO, CONTINUE BELOW
	PUSHJ	P,TSKCNM##	;YES, CALL TSKSER TO SEND THE NAMES
	JRST	NCSCN5		;CONTINUE BELOW
NCSCN0:
>;END FTTSK
	PUSHJ	P,BI2EBI	;OUTPUT
	LDB	T1,PUNIT##	;GET THE UNIT NUMBER
	PUSHJ	P,DPBBIN	;SEND THE UNIT NUMBER
;SPN
	MOVEI	T1,OBJ.TK	;OBJECT IS A JOB
	PUSHJ	P,BI2EBI	;OUTPUT
	MOVE	T1,JBTNAM##(J)	;GET THE PROCESS NAME
	PUSHJ	P,SX2EAS	;OUTPUT
	LDB	T1,P2		;GET THE LAST CHARACTER BACK
	TRO	T1,200		;SET THE CONTINUE BIT
	DPB	T1,P2		;STORE AGAIN
	MOVE	T1,JBTPPN##(J)	;GET THE PPN
	PUSHJ	P,PP2EAS	;OUTPUT AS [P,P]
;MML
NCSCN5:	HRRZ	W,PCBNDB##(U)	;GET THE NDB POINTER
	LDB	T1,NDBMML##	;GET THE DDCMP MESSAGE LENGTH
	PUSHJ	P,BI2EBI	;OUTPUT
;FEA
;DCM
	HLRZ	W,DEVNET##(F)
	LDB	T1,NDTDCM##	;GET THE DEVICE MODES POSSIBLE
	PUSHJ	P,BI2EBI	;WRITE
;RNL
	MOVEI	T1,0		;RECORD LENGTH VALIABLE
	PUSHJ	P,BI2EBI	;WRITE
;DVT
	LDB	T1,NDTDVT##	;GET THE DEVICE ATTRIBUTES
	PUSHJ	P,BI2EBI	;WRITE
;CNT
NCSCN1:	POP	P,T1		;RESTORE THE <CNT> POINTER
	DPB	P3,T1		;STORE THE <CNT>
	ADDM	P3,PCBOCT##(U)	;UPDATE THE PROTOCOL MESSAGE LENGTH
	PUSHJ	P,NETWRT	;SEND THE CONNECT
	JUMPE	F,CPOPJ1##	;EXIT IF CONNECT RESPONSE
	LDB	T1,NETDLA##	;GET THE DESTINATION LINK
	JUMPN	T1,CPOPJ1##	;EXIT IF THIS IS A CONFIRM MESSAGE
NCSCN3:	PUSHJ	P,NETHIB	;WAIT FOR A RESPONSE
	LDB	T1,NETRSN##	;NO, GET THE REASON BYTE
	JUMPN	T1,CPOPJ##	;RETURN ERROR CODE IF UNSUCCESSFUL
	MOVSI	T1,IOSCON	;IF WE AREN'T CONNECTED YET
	TDNN	T1,DEVIOS(F)
	JRST	NCSCN3		;THEN WAIT SOME MORE.
	PJRST	CPOPJ1##	;GOOD EXIT
;SUBROUTINE NCSDSC - SEND A DISCONNECT MESSAGE
;CALL	MOVEI	T1,DLA
;	MOVEI	T2,REASON
;	MOVEI	F,DDB OR 0 IF REJECT/CONFIRM
;	MOVEI	W,NDB
;	PUSHJ	P,NCSDSC
;RETURN	CPOPJ			;NO CORE
;	CPOPJ1

NCSDSC::			;ENTRY
	PUSHJ	P,SAVE3##	;SAVE THE P'2
	PUSHJ	P,SAVJW		;SAVE J AND W
	PUSH	P,F		;SAVE THE DDB
	SKIPE	F		;SKIP IF A REJECT
	HRROS	DEVNAM(F)	;CLEAR THE DEVICE NAME(UUOCON WON'T CALL AGAIN)
	SETZ	F,		;SET CONTROL MESSAGE (IE RESPONSE)
	HRRI	P1,(T1)		;COPY THE DLA
	HRLI	P1,(T2)		;AND THE REASON
	PUSH	P,P1		;SAVE THE FLAGS
	PUSHJ	P,NCMHDR	;WRITE THE NUMBERED HEADER
	  JRST	[POP P,P1	;RESTORE P1
		JRST FPOPJ]	;EXIT
	POP	P,P1		;RESTOE THE FLAGS
	PUSH	P,P2		;SAVE THE COUNT BYTE POINTER
	MOVEI	T1,NC.DSC	;DISCONNECT MESSAGE
	PUSHJ	P,BI2EBI	;WRITE
;DLA
	HRRZ	T1,P1		;GET THE DLA
	PUSHJ	P,BI2EBI	;WRITE
;SLA
	MOVEI	T1,0		;SOURCE LINK = 0
	PUSHJ	P,BI2EBI	;WRITE
;RSN
	HLRZ	T1,P1		;GET THE REASON
	PUSHJ	P,BI2EBI	;WRITE
;CNT
	POP	P,T1		;GET THE COUNT FIELD BYTE POINTER BACK
	DPB	P3,T1		;STOE THE COUNT
	ADDM	P3,PCBOCT##(U)	;STORE THE COUNT
	PUSHJ	P,NETWRT	;SEND THE MESSAGE
	POP	P,F		;RESTORE THE DDB
	JUMPE	F,CPOPJ1##	;EXIT IF CONFIRM OR REJECT
	MOVSI	T1,IOSCON	;GETT THE CONNECT BIT
	ANDCAM	T1,DEVIOS(F)	;CLEAR IT DISCONNECT SENT
NCSDS1:	PUSHJ	P,NETHIB	;WAIT FOR RESPONSE
	MOVSI	T1,NT.DSC##	;HAS A DISCONNECT COME IN
	TDNN	T1,NETSTS##(F)	;FOR US YET?
	JRST	NCSDS1		;NO, WAIT LONGER
	PUSHJ	P,UNLDDB	;REMOVE THE DDB
	PJRST	CPOPJ1##	;EXIT
;SUBROUTINE	 NCSNBN - SEND NEIGHBOR NAME MESSAGE
;CALL	PUSHJ	P,NCSNBN
;RETURN	CPOPJ
;	CPOPJ1

NCSNBN:				;ENTRY
	PUSHJ	P,SAVE3##	;SAVE THE P'S
	PUSHJ	P,SAVJW		;SAVE J AND W
	SETZ	F,		;CONTROL MESSAGE
	PUSHJ	P,NCMHDR	;WRITE NUMBERED HEADER
	  POPJ	P,		;NO CORE
	PUSH	P,P2		;SAVE THE LOCATION
	MOVEI	T1,NC.NBN	;GET HEIGHBOR NAMES
	PUSHJ	P,BI2EBI	;WRITE
	PUSH	P,W		;SAVE THE NDB POINTER
	MOVEI	W,NETNDB##	;GET OUR NDB
	MOVE	T4,[POINT 18,NDBTOP##(W)] ;SEARCH THE TOPOLOGY TABLE
	MOVSI	T3,-<^D16>	;TABLE SIZE
;NNM
NCSNB1:	ILDB	T1,T4		;GET A NODE NUMBER
	JUMPE	T1,NCSNB2	;EMPTY SLOT
	LSH	T1,-^D8		;POSITION THE NODE NUMBER
	ANDI	T1,77		;ONLY SIX BITS
	PUSHJ	P,DPBBIN	;WRITE
;LVL
	LDB	T1,T4		;GET THE LINK VALUE
	ANDI	T1,377		;AND THE LINK VALUE
	PUSHJ	P,DPBBIN	;SEND
NCSNB2:	AOBJN	T3,NCSNB1	;TRY AGAIN
	POP	P,W		;RESTORE THE TARGET NODE
	POP	P,T1		;GET THE POSITION OF <CNT>
	DPB	P3,T1		;STORE <CNT>
	ADDM	P3,PCBOCT##(U)	;UPDATE THE OUTPUT COUNT
	MOVSI	T1,NDB.NB##	;GET NEIGHBORS SENT
	IORM	T1,NDBFEK##(W)	;SET IT
	PJRST	NETWSR		;SEND THE MESSAGE

;SUBROUTINE SETNBN - SET THE BITS TO SEND NEIGHBORS MESSAGES TO ALL
;CALL	PUSHJ	P,SETNBN
;RETURN	CPOPJ

SETNBN:				;ENTRY ON CHANGE OF NEIGHBORS
	PUSHJ	P,SAVJW		;SAVE J AND W
	MOVSI	T1,NDB.NB##	;GET NEIGHBORS BIT
	MOVEI	W,NETNDB##		;START OF NDB'S
SETNB1:	HRRZ	W,NDBNNM##(W)	;GET THE FIRST NDB LESS OURS
	JUMPE	W,CPOPJ##	;END OF LIST
	ANDCAM	T1,NDBFEK##(W)	;CLEAR THE BIT
	JRST	SETNB1		;CONTINUE
;SUBROUTINE NCSRCF - REQUEST CONFINURATION MESSAGE
;CALL	MOVEI	W,NDB
;	PUSHJ	P,NCSRCF
;RETURN	CPOPJ		;NO CORE
;	CPOPJ1		;RETURN

NCSRCF:				;ENTRY
	PUSHJ	P,SAVE3##	;SAVE THE P'S
	PUSHJ	P,SAVJW		;SAVE J AND W
	SETZ	F,		;CONTROL MESSAGE
	PUSHJ	P,NCMHDR	;WRITE A HEADER
	  POPJ	P,		;CAN'T
	PUSH	P,P2		;SAVE THE COUNT POSITION
	MOVEI	T1,NC.RCF	;TYPE REQUEST CONFIGURATION
	PUSHJ	P,BI2EBI	;SEND
	POP	P,T1		;GET THE COUNT POSITION BACK
	DPB	P3,T1		;STORE THE COUNT
	ADDM	P3,PCBOCT##(U)	;UPDATE THE PCB
	MOVSI	T1,NDB.CF##	;CONFIGURATION BIT
	IORM	T1,NDBFEK##(W)	;STORE THE BIT
	PJRST	NETWSR		;SEND THE MESSAGE

;SUBROUTINE NCSCNF - SEND A CONFIGURATION MESSAGE UPON REQUEST
;CALL	MOVEI	W,NDB
;	PUSHJ	P,NCSCNF
;RETURN	CPOPJ
;	CPOPJ1

NCSCNF:				;ENTERY
	PUSHJ	P,SAVE3##	;SAVE THE P'S
	PUSHJ	P,SAVJW		;SAVE J W
	SETZ	F,		;CLEAR THE DDB
	PUSHJ	P,NCMHDR	;GET A HEADER
	  POPJ	P,		;NO CORE AVAILABLE
	PUSH	P,P2		;SAVE THE COUNT POSITION
	MOVEI	W,NETNDB##	;GET OUR NODE DATA BLOCK
	MOVEI	T1,NC.CNF	;CONFIGURATION MESSAGE
	PUSHJ	P,BI2EBI	;SEND
;OBJ
	MOVSI	P1,-<OBJ.MX+1>	;NUMBER OF DEVICE TYPES
NCSCF1:	LDB	T1,NETCNF##(P1)	;GET THE COUNT
	JUMPE	T1,NCSCF2	;DON'T HAVE ANY
	MOVEI	T1,(P1)		;GET THE TYPE BACK
	PUSHJ	P,BI2EBI	;SEND THE DEVICE TYPE
;NDV
	LDB	T1,NETCNF##(P1)	;DEVICE COUNT
	PUSHJ	P,BI2EBI	;SEND
;PID
	MOVEI	T1,0		;ZERO PID
	PUSHJ	P,BI2EBI	;SEND
NCSCF2:	AOBJN	P1,NCSCF1	;CONTINUE THROUGH THE LIST
	POP	P,T1		;RESTORE THE COUNT POSTION
	DPB	P3,T1		;STORE THE COUNT
	ADDM	P3,PCBOCT##(U)	;UPDATE THE PCB COUNT
	PJRST	NETWSR		;SEND THE MESSAGE
;SUBROUTINE NCSDRQ - SEND A DATA REQUEST
;CALL	MOVEI	T1,DATA REQUEST COUNT
;	MOVEI	F,DDB
;	PUSHJ	P,NCSDRQ
;RETURN	CPOPJ			;NO CORE
;	CPOPJ1			;REQUEST SENT

NCSDRQ::			;ENTRY
	PUSHJ	P,SAVE3##	;SAVE THE P'S
	PUSHJ	P,SAVJW		;SAVE J AND W
	PUSH	P,U		;SAVE U (SELF CONTAINED ROUTINE)
	HRRZ	W,DEVNET##(F)	;GET THE NDB
	PUSH	P,T1		;SAVE THE DRQ
	PUSHJ	P,NCMHDR	;WRITE THE HAEDER
	  JRST	[POP	P,T1	;RESTORE THE DRQ
		PJRST	UPOPJ##];EXIT
	POP	P,P1		;RESTORE THE DRQ
	PUSH	P,P2		;SAVE THE COUNT POINTER
	MOVEI	T1,NC.DQR	;DATA REQUEST
	PUSHJ	P,BI2EBI	;WRITE
;DLA
	LDB	T1,NETDLA##	;GET THE DESTINATION LINK ADDRESS
	PUSHJ	P,BI2EBI	;WRITE
;DQR
	MOVEI	T1,(P1)		;GET THE DQR
	PUSHJ	P,BI2EBI	;WRITE
;CNT
	POP	P,T1		;GET THE COUNT POINTER BACK
	DPB	P3,T1		;STORE THE COUNT
	ADDM	P3,PCBOCT##(U)	;AND IN THE PCB
	PUSHJ	P,NETWRT	;SEND THE MESSAGE
	PJRST	UPOPJ1##	;SKIP EXIT
;SUBROUTINE NCSCTL - SEND A STATION CONTROL MESSAGE
;CALL	MOVEI	W,NDB
;	MOVE	T1,[XWD COUNT,ADDR]
;	PUSHJ	P,NCSCTL
;RETURN	CPOPJ			;NO CORE
;	CPOPJ1			;MESSAGE SENT

NCSCTL:				;ENTRY
	PUSHJ	P,SAVE3##	;SAVE THE P'S
	PUSHJ	P,SAVJW
	PUSH	P,T1		;SAVE THE ARGUMENT
NCSCT1:	SETZ	F,		;NCS MESSAGE
	PUSHJ	P,NCMHDR	;WRITE A NUMBERED MESSAGE HEADER
	  JRST	TPOPJ##		;EXIT
	HLRZ	T1,(P)		;GET THE USER COUNT SIZE
	HRRZM	T1,PCBOC2##(U)	;STORE THE COUNT
	ADDI	T1,1		;<CNT><TYP>
	LSHC	T1,-7		;GET LOW POSITION
	ROT	T2,7		;FIRST
	TRO	T2,200
	DPB	T2,P2		;STORE
	IDPB	T1,P2		;STORE HIGH HALF
	ADDI	P3,1		;INCREMET THE COUNT FIELD
	MOVEI	T1,NC.CTL	;STATION CONTROL TYPE
	PUSHJ	P,BI2EBI	;SEND
	HLRZ	T2,(P)		;GET THE # OF BYTES
	ADDI	T2,3		;ROUND UP
	LSH	T2,-2		;CONVERT TO WORDS
	PUSHJ	P,GETZWD	;ALLOCATE A BUFFER
	  JRST	TPOPJ##		;ERROR RETURN
	HRLI	T1,(POINT 8)	;MAKE A BYTE POINTER
	MOVEM	T1,PCBOA2##(U)	;STORE IN THE PCB
	HLRZ	T3,(P)		;GET THE BYTE COUNT
	ADDI	T3,3		;ROUND UP
	LSH	T3,-2		;INTO WORDS
	HRLM	T3,PCBOC2##(U)	;STORE
	ADD	T3,PCBOA2##(U)	;POINT TO THE END OF THE BUFFER
	SUBI	T3,1		;LESS ONE
	POP	P,T1		;GET THE USER ADDRESS
IFN FTKA10,<
	ADDI	T1,(R)		;POINT TO FIRST NEW IN USER'S AREA
>
	HRLS	T1		;PUT IN THE LEFT HALT
	HRR	T1,PCBOA2##(U)	;GET THE BUFFER ADDRESS
	EXCTUX	<BLT	T1,(T3)>	;MODE THE DATA
	ADDM	P3,PCBOCT##(U)	;STORE THE COUNT
	PJRST	NETWSR		;SEND THE MESSAGE
SUBTTL MEMORY CONTROL ROUTINES
;SUBROUTINE SLPZWD - GET WORDS FROM MONITOR FREE CORE AND SLEEP UNTIL AVAILABLE
;CALL	MOVEI	T2,#WORDS
;	PUSHJ	P,SLPZWD
;RETURN	CPOPJ				;WHEN AVAILABLE

SLPZWD::			;ENTRY
	PUSHJ	P,GETZWD	;TRY TO ALLOCATE
	  SKIPA			;NOT AVAILABLE
	POPJ	P,		;RETURN
	PUSHJ	P,NETSLP	;SLEEP FOR TWO SECONDS
	JRST	SLPZWD

;SUBROUTINE GETZWD - GET A BLOCK OF MONITOR FREE CORE AND ZERO
;CALL	MOVEI	T2,#WORDS
;	PUSHJ	P,GETZWD
;RETURN	CPOPJ			;NO CORE AVAILABLE
;	CPOPJ1			;T1=ADDRESS

GETZWD:	PUSH	P,T2		;SAVE THE NUMBER OF WORDS
	HLRE	T1,FREPTR##	;GET LENGTH OF FREE CORE MAP
	MOVNS	T1
	IMULI	T1,^D36		;MAKE #4 WORD BLOCKS (=1/4 FREE CORE TOTAL)
	CAML	T1,%NTCOR	;DON'T USE MORE THAN 1/4 OF FREE CORE
	PUSHJ	P,GETWDS##	;ALOCATE THE SPACE
	  PJRST	T2POPJ##	;NO, SPACE AVAILABLE
	SETZM	(T1)		;CLEAR THE FIRST WORD
	MOVE	T2,(P)		;GET THE NUMBER OF WORDS
	ADDM	T2,%NTCOR	;ACCOUNT FOR CORE USED
	MOVEM	T1,(P)		;SAVE THE STARTING ADDRESS
	ADDI	T2,-1(T1)	;POINT TO THE END OF THE LIST
	HRLI	T1,1(T1)	;MAKE A BLT POINTER
	MOVSS	T1		;FROM,,TO
	BLT	T1,(T2)		;CLEAR THE BLOCK
IFN FTCMSR,<
	MOVE	T1,%NTCOR	;IF WE NOW ARE USING MORE
	CAMLE	T1,%NTMAX	; CORE THAN EVER BEFORE
	MOVEM	T1,%NTMAX	; RECORD FOR PRYING EYES
>
	PJRST	TPOPJ1##	;RESTORE THE ADDRESS AND EXIT

;SUBROUTINE GIVZWD	- RETURN MONITOR FREE CORE
;CALL	MOVEI	T1,#WORDS
;	MOVEI	T2,ADDRESS
;	PUSHJ	P,GIVZWD
;RETURN	CPOPJ
GIVZWD:			;ENTRY
	PUSH	P,T1		;SAVE NUMBER OF WORDS
	MOVNS	T1		;NEGATE
	ADDB	T1,%NTCOR	;REDUCE CORE USED
	SKIPGE	T1		;CHECK RESULT
	STOPCD	TPOPJ##,DEBUG,CWN,;++CORE ALLOCATION WENT NEGATIVE
	POP	P,T1		;RESTORE WORD COUNT
	PJRST	GIVWDS##	;RETURN THE CORE
;SUBROUTINE SAVJW SAVE AC'S W AND J
;CALL	PUSHJ	P,SAVJW
;RETURN	CPOPJ

SAVJW::	EXCH	J,(P)		;SAVE J AND GET THE RETURN
	PUSH	P,W		;SAVE W
	MOVEM	J,1(P)		;SAVE THE RETURN
	MOVE	J,-1(P)		;RESTORE J
	PUSHJ	P,@1(P)		;RETURN
	  SKIPA			;SKIP RETURN NO
	AOS	-2(P)		;SKIP YES
	POP	P,W		;RESTORE W
	PJRST	JPOPJ##		;RESTORE J AND EXIT

;SUBROUTINE SVEVM - SAVE THE JOB EVM AND RESTORE ON POPJ
;CALL	PUSHJ	P,SVEVM
;RETURN	CPOPJ

IFE FTKI10!FTKL10,<SVEVM==CPOPJ##>
IFN FTKI10!FTKL10,<
SVEVM::SKIPN	DEVEVM(F)	;ANY EVM
	POPJ	P,		;NO RETURN
	PUSHJ	P,RTEVM##	;YES, RETURN THE EVM
	POP	P,(P)		;PUT THE RETURN ON THE END OF THE STACK
	PUSHJ	P,@1(P)		;RETURN TO THE CALLER
	  PJRST	RSTEVM##	;NON-SKIP RESTORE EVM
	AOS	(P)		;SKIP RETURN
	PJRST	RSTEVM##	;RESTORE EVM AND EXIT
>
SUBTTL COMMON SUBROUTINES TO CONVERT EXTENSIBLE ASCII/BINARY
;SUBROUTINE EAS2SX CONVERT EXTENSIBLE ASCII TO SIXB
;CALL	MOVEI	P1,[INPUT POINTER]
;	PUSHJ	P,EAS2SX
;RETURN	CPOPJ			;T1=SIXIT

EAS2SX::MOVE	T2,[POINT 6,T1]	;GET  BYTE POINTER
	SETZB	T1,T4		;CLEAR OUTPUT
EAS2S1:	SOJL	P4,CPOPJ##	;EXIT IF NO MORE DATA
	ILDB	T3,P1		;GET THE BYTE
	TRZN	T3,200		;CONTINUE BIT
	SETO	T4,		;NO, SET FLAG
	TRNE	T3,140		;MAKE SURE ASCII BEFOR SUBI
	SUBI	T3,40		;CONVERT TO SIXBIT
	TRNN	T3,177		;CHECK FOR A BLANK CHARACTER
	JUMPE	T1,EAS2S2	;AND A LEADING BLANK
	CAIE	T3,'['		;CHECK TO [XXX,XXX]
	CAIN	T3,']'		;AND EXIT
	POPJ	P,		;IF FOUND
	CAIN	T3,','		;ALSO A COMMA
	POPJ	P,		;WILL EXIT
	TLNE	T2,(77B5)	;END OF WORD
	IDPB	T3,T2		;STORE WORD
EAS2S2:	JUMPGE	T4,EAS2S1	;NO CONTINUE
	POPJ	P,		;RETURN

;SUBROUTINE SX2EAS CONVERT SIXBIT TO EXTENSIBLE ASCII
;CALL	MOVE	T1,[SIXBIT /.../]
;	MOVE	P2,[OUTPUT BYTE POINTER]
;	PUSHJ	P,SX2EAS
;RETURN CPOPJ			;P3 COUNTED UP

SX2EAS::SKIPE	T2,T1		;COPY THE SIXBIT NAME
SX2EA1:	SETZ	T1,		;CLEAR THE OUTPUT AC
	LSHC	T1,6		;GET A SIXBIT CHARACTER
	ADDI	T1,240		;CONVERT TO ASCII WITH CONTINUE BIT
	IDPB	T1,P2		;STORE CHARACTER
	ADDI	P3,1		;COUNT THE CHARACTER
	JUMPE	T2,CLRBT8	;EXIT AND CLEAR CONTINUE BIT
	JRST	SX2EA1		;COUNT AND CONTINUE

;SUBROUTINE AS2EAS CONVERT ASCIZ TO EXTENSIBLE ASCII
;CALL	MOVE	P1,[INPUT BYTE POINTER] ASCII 7
;	MOVE	P2,[OUTPUT BYTE POINTER] EXTENSIBLE ASCII 8
;	PUSHJ	P,AS2EAS
;RETURN	CPOPJ		;P3 UPDATED WITH CHARACTER COUNT


AS2EAS::TLNN	P1,-1		;IS THERE A BYTE POINTER
	HRLI	P1,(POINT 7)	;NO, SUPPLY ONE
AS2EA1:	SOJL	P4,CPOPJ##	;EXIT IF THE END OF DATA
	ILDB	T1,P1		;GET AN ASCII CHARACTER
	JUMPE	T1,CLRBT8	;JUMPE IF END
	TRO	T1,200		;SETHIGH ORDER BIT
	IDPB	T1,P2		;STORE 8 BIT BYTE
	AOJA	P3,AS2EA1	;COUNT CHARACTER TRY AGAIN
CLRBT8:	LDB	T1,P2		;GET LAST STORED CHARACTER BACK
	TRZ	T1,200		;CLEAR THE CONTINUE BIT
	DPB	T1,P2		;STORE CHARACTER
	POPJ	P,		;RETURN

;SUBROUTINE EAS2AS CONVERT AN EXTENSIBLE ASCII STRING TO ASCIZ
;CALL	MOVE	P1,[INPUT BYTE POINTER]
;	MOVE	P2,[OUTPUT BYTE POINTER]
;	PUSHJ	P,EAS2AS
;EXIT

EAS2AS::HRLI	P2,(POINT 7)	;MAKE A BYTE POINTER
	MOVEI	T2,^D37		;ALLOW A MAX CHARACTER COUNT
EAS2A1:	SOJLE	P4,CPOPJ##	;EXIT IF NO MORE
	ILDB	T1,P1		;GET AN 8 BIT CHARACTER
	IDPB	T1,P2		;STORE A SEVEN BIT CHARACTER
	TRNE	T1,200		;IS CONTINUE BIT ON
	SOJG	T2,EAS2A1	;YES, CONTINUE
	SETZ	T1,		;SET UP A NULL
	IDPB	T1,P2		;STORE THE NULL
	POPJ	P,		;RETURN
;SUBROUTINE BI2EBI CONVERT A BINARY NUMBER TO EXTENSIBLE BINARY
;CALL	MOVE	T1,[A BINARY NUMBER]
;	MOVE	P2,[OUTPUT BYTE POINTER] 8 BIT
;	PUSHJ	P,BI2EBI,OCT2EBI,DE2EBI
;RETURN	CPOPJ		;P3 UPDATED
BI2EBI::CAIG	T1,177		;GREATER THAN 177
	JRST	DPBBIN		;NO OUTPUT
	LSHC	T1,-7		;SHIFT OFF THE BITS
	ROT	T2,7		;SAVE IN T2
	TRO	T2,200		;SET CONTINUE BIT
	IDPB	T2,P2		;STORE IN MESSAGE
	AOJA	P3,BI2EBI	;CONTINUE
DC2EAS:	SKIPA	T3,[^D10]	;DECIMAL CONVERSION
OC2EAS:	MOVEI	T3,^D8		;OCTAL CONVERSION
RX2EBI:	IDIVI	T1,(T3)		;SEPERATE AGAIN
	HRLM	T2,(P)		;STORE THE BYTE
	SKIPE	T1		;ANY LEFT NOW
	PUSHJ	P,RX2EBI	;YES, TRY AGAIN
	HLRZ	T1,(P)		;GET THE LAST DIGIT BACK
	ADDI	T1,"0"		;NO CONVERT TO ASCII
DPBEAS:	TRO	T1,200		;SET THE CONTINUE BIT
DPBBIN:	ADDI	P3,1		;COUNT
	IDPB	T1,P2		;NO STORE THE DIGIT
	POPJ	P,		;RETURN

;SUBROUTINE EBI2BI TO CONVER EXTENSIBLE BINARY TO BINARY
;CALL	MOVE	P1,[INPUT BYTE POINTER
;	PUSHJ	P,EBI2BI
;RETURN	CPOPJ			;T1=BINARY NUMBER 

EBI2BI::SETZ	T1,		;CLEAR THE OUTPUT
	MOVE	T3,[POINT 7,T1,35]	;OUTPUT BYTE POINTER
EBI2B1:	SOJL	P4,CPOPJ##	;EXIT IF THE END OF DATA
	ILDB	T2,P1		;GET THE NEXT CHARACTER
	DPB	T2,T3		;STORE THE NEXT DIGIT
	TRNN	T2,200		;IS THE NUMBER EXTENDED
	POPJ	P,		;NO, EXIT
	ADD	T3,[7B5]	;YES, STEP LEFT ONE 7 BIT BYTE
	JRST	EBI2B1		;CONTINUE

;SUBROUTINE PP2EAS - OUTPUT A PPN IN EXTENSIVE ASCII
;CALL	MOVE	T1,[PPN]
;	PUSHJ	P,PP2EAS
;RETURN	CPOPJ

PP2EAS::PUSH	P,T1		;SAVE THE PPN
	MOVEI	T1,"["		;OPEN BRACKET
	PUSHJ	P,DPBEAS	;OUTPUT
	HLRZ	T1,(P)		;GET THE PROGRAMMER NUMBER
	PUSHJ	P,OC2EAS	;OUTPUT
	MOVEI	T1,","		;SEPERATOR
	PUSHJ	P,DPBEAS	;OUTPUT
	POP	P,T1		;RESTORE THE STACK GET PROGRAMMER #
	HRRZS	T1		;RT HALF
	PUSHJ	P,OC2EAS	;OUTPUT
	MOVEI	T1,"]"		;CLOSING BRACKET
	PUSHJ	P,DPBEAS	;OUTPUT
	PJRST	CLRBT8		;CLEAR THE LAST BIT

;SUBROUTINE EAS2PP - INPUT A PROCESS ANEM AND UIC
;CALL	PUSHJ	P,EAS2PP
;RETURN	CPOPJ

IFN FTTSK,<
EAS2PP::			;ENTRY
	PUSHJ	P,EAS2SX		;GET THE SIXBIT NAME
	PUSH	P,T1		;SAVE
	SETZ	T2,		;CLEAR THE PPN WORD
	CAIE	T3,'['		;DOES A PPN FOLLOW
	PJRST	TPOPJ##		;NO EXIT T1=NAME T2=PPN
	PUSHJ	P,EAS2SX	;GET THE PROJECT NUMBER
	PUSHJ	P,CVTOCT##	;CONVERT TO OCTAL
	  SETZ	T1,		;ILLEGAL SET TO ZERO
	PUSH	P,T1		;SAVE THE PROJECT NUMBER
	PUSHJ	P,EAS2SX	;GET THE PROGRAMMER NUMBER
	PUSHJ	P,CVTOCT##	;CONVERT TO OCTAL
	  SETZ	T1,		;ILLEGAL
	HRL	T1,(P)		;GET THE PROGRAMMER NUMBER BACK
	MOVE	T2,T1		;COPY TO T2
	POP	P,(P)		;REMOVE SCRATCH FROM THE STACK
	PJRST	TPOPJ##		;EXIT T1=NAME T2=PPN
>;END FTTSK
SUBTTL NETINI - INITILIZATION/ONCE A SECOND CODE
;NETINI	CALLED BY ONCE ONLY
NETINI::
	PUSH	P,J		;SAVE J
	HRRZ	J,NETFEK	;FIRST FEK ADDRESS
NETIN1:	HRRZS	FEKBLK(J)	;CLEAR THE KONTROLLER FLAGS
	XCT	FEKONC##(J)	;CALL THIS CNTROLLER
	HRRZ	J,FEKBLK##(J)	;GET THE NEXT KONTROLLER
	JUMPN	J,NETIN1	;END OF LIST ... CONTINUE
	PJRST	JPOPJ##		;RESTORE J AND EXIT

;CALLED ONCE A SECOND
NET2ND::PUSHJ	P,SAVJW		;SAVE J AND W ETC
IFN FTCMSR,<
	MOVE	T1,%NTCOR	;COMPUTE AVERAGE BUFFER USAGE
	IMULI	T1,^D10000-TIMFAC  ;EACH SECOND COUNTS THIS MUCH
	MOVE	T2,%NTAVG
	MULI	T2,TIMFAC	;MAKE ROOM FOR IT IN THE OLD AVERAGE
	DIVI	T2,^D10000
	ADD	T1,T2
	MOVEM	T1,%NTAVG	;AVERAGE FOR THIS SECOND
>
NETFEK:	MOVEI	J,0		;ADDRESS IS MODIFIED BY LINK 10
	.LNKEND	FEKLNK,.-1	;START OF LINK
NET2N1:	XCT	FEKSEC##(J)	;CALL THE CONTROLLER ROUTINE
	SKIPL	T1,FEKBLK##(J)	;IS HTHIS KONTROLLER ONLINE
	JRST	NET2N4		;NO, SKIP
	TLNN	T1,FK.NID##	;NODE ID SENT
	PUSHJ	P,NCSNID	;NO, SEND IT
	  JFCL			;ERROR NO CORE (SEND NEXT TIME)
	SKIPGE	FEKBSI##(J)	;INPUT BUSY
	PUSHJ	P,NETRDD	;NO, MAKE IT BUSY
NET2N4:
	HRRZ	J,FEKBLK##(J)	;GET THE NEXT CONTROLLER
	JUMPN	J,NET2N1	;CONTINUE

;SCAN THE NDB'S
	MOVEI	W,NETNDB##	;STARTING NODE
NET2N2:	MOVE	J,NDBFEK##(W)	;IS THIS NODE STARTED
	TRNN	J,-1		;ANY FEK ASSIGNED
	JRST	NET2N5		;NO, IGNORE
	JUMPL	J,NET2N3	;IS THE NODE STARTED
	PUSHJ	P,NCSSTR	;NO, SEND A START
	  JFCL			;NEXT TIME
NET2N3:	TLNN	J,NDB.SK##	;STACK SENT OR RECEIVED
	JRST	NET2N5		;NO, WAIT FOR THE STACK
	TLNN	J,NDB.CF##	;CONFIGURATION REQUEST
	PUSHJ	P,NCSRCF	;NO SEND IT
	  JFCL			;TRY LATER
	TLNN	J,NDB.NB##	;NEED NEIGHBORS
	PUSHJ	P,NCSNBN	;YES, SEND IT
	  JFCL			;LATER
	MOVSI	T2,-1		;INCREMENT COUNTER TO TIME OUT BOOT REQUESTS
	ADDB	T2,SCBRQB##(W)	; IN CASE NETLDR DIES
	JUMPGE	T2,NET2N5	;NOT YET
	ANDI	T2,-1		;ISOLATE ADDRESS
	JUMPE	T2,NET2N5	;NOTHING THERE TO START WITH
	HLRZ	T1,(T2)		;GET LENGTH
	PUSHJ	P,GIVZWD	;RELEASE SPACE
	SETZM	SCBRQB##(W)	;RELEASE RESOURCE
NET2N5:	HRRZ	W,NDBNNM##(W)	;NEXT NODE
	JUMPN	W,NET2N2	;YES, TRY AGAIN
	POPJ	P,		;RETURN TO "CLOCK1"
SUBTTL NETCTC - CALL ON RESET OR ^C^C AND NOT CCON/CON
NETCTC::			;CALLED BY UUOCON
	PUSHJ	P,SAVJW		;SAVE J AND W
;CHECK FOR REMOTE DIALER IN USE
	HLRZ	T1,DILLDB	;GET THE JOB NUMBER (IF ANY)
	ANDI	T1,777		;ONLY NONE BITS WORTH
	CAIN	T1,(J)		;IS THIS JOB
	SETZM	DILLDB		;YES, CLEAR THE DIALER


;CLEAR THE STATION CONTROL DEVICE IF THERE
NETCT0:	MOVSI	T1,NSHF!NSWP	;MUST BE LOCKED IN CORE TO HAVE THE DEVICE
	TDNN	T1,JBTSTS##(J)	;IS IT
	JRST	NETCT3		;NONE
	MOVEI	W,NETNDB##	;GET THE START ON THE NDB CHAIN
NETCT1:	SKIPN	T1,SCBCTL##(W)	;IS STATION CONTROL BUSY
	JRST	NETCT2		;NO, CONTINUE
	HLRZS	T1		;GET THE JOB NUMBER FOR COMPARE
	CAIN	T1,(J)		;DOES THIS JOB HAVE THE DEVICE
	SETZM	SCBCTL##(W)	;YES, CLEAR THE DEVICE
NETCT2:	HRRZ	W,NDBNNM##(W)	;GET THE NEXT STATION POINTER
	JUMPN	W,NETCT1	;CONTINUE UNLESS THE END OF NDB

;HERE TO CHECK FOR PENDING CONNECT/DISCONNECT MESSAGES

NETCT3:
	PUSHJ	P,FNDPDS##	;FIND THE PDB FOR THE JOB
	PUSH	P,F		;SAVE THE DDB POINTER
	HLRZ	F,.PDNET##(W)	;GET THE POSSIBLE DDB POINTER
	JUMPE	F,NETCT4	;NONE
	HRRZS	.PDNET##(W)	;CLEAR THE POINTER
	MOVE	S,DEVIOS(F)	;IF THE DEVICE NEVER GOT CONNECTED
	TLNN	S,IOSCON	;OR IS BEING DISCONNECTED,
	PUSHJ	P,UNLDDB	;UNLINK THE DDB
NETCT4:	JRST	FPOPJ##		;RESTORE F AND EXIT
SUBTTL FEKINT INTERRUPT LEVEL PROCESSINT
;CALL	MOVE	J,[XWD	FLAGS,FEK]
;	PUSHJ	P,FEKINT##
;RETURN	CPOPJ		;CALLING ROUTINE MUST DISMISS THE INTERRUPT

FEKINT::			;ENTRY ON INTERRUPT
	TRNN	J,-1		;MUST HAVE AN ADDRESS
	JRST	FEKINX		;NO ERROR
	TLNE	J,FI.IN##	;INPUT INTERRUPT
	JRST	INPINT		;YES
	TLNE	J,FI.OUT##	;OUTPUT INTERRUPT
	JRST	OUTINT		;YES
	TLNE	J,FI.DWN##	;DID THE KONTROLER GO DOWN
	JRST	KONDWN		;YES, PROCESS DOWN
	TLNE	J,FI.DAE##		;DAEMON ERROR REPORT
	JRST	DAEINT		;YES
FEKINX:	STOPCD	CPOPJ##,DEBUG,IFU,;++INTERRUPT FLAG UNRECONIZED

;HERE TO PROCESS A DAEMON REQUEST
DAEINT:			;ENTRY FROM INTERRUPT LEVEL
	HRRI	T1,50		;GET THE FLAG
	HRLI	T1,FEKERR##(J)	;AND THE POINTER TO THE ERROR TABLE
	PUSH	P,J		;SAVE J
	PUSHJ	P,DAEEIM##	;CALL DAEMON
	  JFCL			;IGNORE ERRORS
	PJRST	JPOPJ##		;RESTORE THE FEK AND RETURN
;HERE WHEN A KONTROLLER GOES DOWN
KONDWN:	PUSHJ	P,SAVE1##	;SAVE P1
	HRRZS	FEKBLK##(J)	;CLEAR THE FLAGS
;HERE TO CHECK THE INPUT QUEUE
	SKIPGE	FEKBSI##(J)	;IS THERE AN INPUT REQUEST
	JRST	KONDW1		;NO,
	HRRZ	U,FEKIAD##(J)	;YES, GET THE PCB
	PUSHJ	P,RMVPCB	;REMOVE THE FEK
KONDW1:	SETOM	FEKBSI##(J)	;CLEAR BUSY
	SETZM	FEKIAD##(J)	;CLEAR PCB POINTER

;HERE TO CHECK THE OUTPUT QUEUE
	SKIPGE	FEKBSO##(J)	;IS OUTPUT BUSY
	JRST	KONDW3		;NO
	HRRZ	P1,FEKOAD##(J)	;GET THE PCB POINTER
KONDW2:	MOVEI	U,(P1)		;COPY THE ADDRESS
	HRRZ	P1,PCBBLK##(U)	;GET THE NEXT PCB
	PUSHJ	P,RMVPCB	;REMOVE THE PCB
	JUMPN	P1,KONDW2	;CONTINUE IF ANOTHER PCB
KONDW3:	SETOM	FEKBSO##(J)	;CLEAR BUSY
	SETZM	FEKOAD##(J)	;CLEAR THE PCB POINTER

;HERE TO CHECK FOR NODES CONNECTED TO THE KONTROLLER

KONDW7:	MOVEI	P1,NETNDB##	;GET THE START OF THE NDB CHAIN
KONDW4:	HRRZ	W,NDBNNM##(P1)	;SKIP THE PROTOTYPE
	JUMPE	W,KONDW6	;END OF LIST
	HRRZ	T1,NDBFEK##(W)	;GET THE FEK POINTER
	CAIE	T1,(J)		;IS THIS NODE CONNECTED
	JRST	KONDW5		;NO, STEP THE CHAIN
	PUSHJ	P,RMVNDB	;REMOVE THE NDB
	JRST	KONDW7		;TRY AGAIN
KONDW5:	MOVEI	P1,(W)		;COPY THE POINTE
	JRST	KONDW4		;TRY AGAIN
KONDW6:	POPJ	P,		;DISMISS THE INTERRUPT
SUBTTL OUTINT - OUTPUT INTERRUPT PROCESSOR FOR ALL FEK'S
;SUBROUTINE OUTINT - OUTPUT INTERRUPT
;CALL	MOVE	J,[XWD FLAGS,FEK]
;	PUSHJ	P,OUTINT
;RETURN	CPOPJ

OUTINT:				;ENTRY
	PUSH	P,U		;SAVE U
	PUSH	P,W		;SAVE W
	HRRZ	U,FEKOAD##(J)	;GET THE PCB
	MOVE	T1,PCBBLK##(U)	;GET THE FLAGS AND POINTER
	TLNE	T1,PCB.OF##	;DID DESTINATION GO OFFLINE?
	TLZ	T1,PCB.UN##	;YES, DON'T LET PCB.UR!PCB.NM DO THEIR THING
	PUSH	P,T1		;SAVE PCB.UR FLAG FOR OUTIN4
	HRRZM	T1,FEKOAD##(J)	;STORE THE NEXT PCB
	HLLZS	PCBBLK##(U)	;CLEAR THE LINK POINTER
	HLRZ	F,PCBDDB##(U)	;GET THE DDB IF ANY
	HRRZ	W,PCBNDB##(U)	;GET THE NODE DATA BLOCK
	JUMPGE	T1,OUTIN4	;UNNUMBERED DO NO QUEUE
	LDB	T1,PCBMSN##	;GET THE NUMBER OF THE MESSAGE SENT
	DPB	T1,NDBLMS##	;SAVE AS LAST SENT
	HRRZ	T2,NDBQUE##(W)	;GET THE OUTPUT QUEUE POINTER
	JUMPN	T2,OUTIN1	;JUMP IF QUEUE NOT EMPTY
	HRRM	U,NDBQUE##(W)	;YES, THIS IS THE ONLY PCB
	JRST	OUTIN2		;CONTINUE

OUTIN1:	MOVEI	T1,(T2)		;SEARCH FOR THE END OF THE QUEUE
	HRRZ	T2,PCBBLK##(T1)	;GET THE NEXT ENTRY
	JUMPN	T2,OUTIN1	;CONTINUE TO THE END
	CAIN	U,(T1)		;CHECK FOR LINK TO SELF
	STOPCD	.+1,DEBUG,LTS,	;LINK TO SELF
	HRRM	U,PCBBLK##(T1)	;LINK TO THE END
OUTIN2:
OUTIN3:	SKIPA			;NUMBERED MESSAGE
OUTIN4:	PUSHJ	P,RMVPCB	;NO REMOVE THE PCB
	SOSGE	FEKBSO##(J)	;ANOTHER MESSAGE TO SEND?
	JRST	OUTIN7		;NO, CLEAN UP AFTER LAST MESSAGE
	MOVE	U,FEKOAD##(J)	;LOOK AT CURRENT MESSAGE
	MOVE	T1,PCBBLK##(U)	;GET FLAGS AND NEXT PCB
	TLNN	T1,PCB.OF##	;IF DESTINATION IS STILL ONLINE,
	JRST	OUTIN6		; SEND IT THERE
	HRRM	T1,FEKOAD##(J)	;DELINK USELESS MESSAGE
	JRST	OUTIN4		;DISCARD IT AND TRY AGAIN

OUTIN6:	XCT	FEKWRT##(J)	;SEND IT
OUTIN7:	POP	P,T1		;GET PCBBLK BACK
	TLNN	T1,PCB.UR##	;WAS THERE USER DATA?
	JRST	OUTIN5		;NOPE, RETURN
	MOVEI	T1,NDPODN##	;GET OUTPUT DONE INDEX
	HLRZ	T2,DEVNET(F)	;GET NDT ADDRESS
	PUSHJ	P,@NDTNDP##(T2) ;CALL THE DEVICE SERVICE ROUTINE
OUTIN5:	POP	P,W		;RESTORE W
	PJRST	UPOPJ##		;RESTORE U AND DISMISS THE INTERRUPT
SUBTTL NETWRT - SEND A MESSAGE TO THE FRONT END KONTROLLER FEK
;SUBROUTINE NETWRT - SEND A MESSAGE
;CALL	MOVEI	F,DDB OR 0 IF A NCL MESSAGE
;	MOVEI	U,PCB
;	PUSHJ	P,NETWRT	;CALLED AT INTERRUPT OR UUO LEVEL
;RETURN	CPOPJ			;ALWAYS

NETWSR:	AOS	(P)		;SKIP RETURN
NETWRT::			;ENTRY
	PUSHJ	P,SAVJW		;SAVE J/W
	HRRZ	W,PCBNDB##(U)	;GET THE NDB POINTER
	HRRZ	J,NDBFEK##(W)	;GET THE FEK POINTER
IFN FTCMSR,<
	MOVE	T4,PCBOAD(U)	;GET ADDRESS OF MESSAGE
	HRLI	T4,(POINT 8,0,7)  ;POINT TO NCT
	LDB	T1,T4		; AND GET IT
	ANDI	T1,NCT.TP	;ISOLATE MESSAGE TYPE
	AOS	NCLXTP(T1)	;COUNT IT
	JUMPN	T1,NETWR2	;WE'RE DONE IF THIS IS UNNUMBERED CONTROL
	ADD	T4,[<POINT 8,1,15>-<POINT 8,0,7>]  ;POINT TO DLA
	LDB	T1,T4		; AND GET IT
	JUMPN	T1,NETWR1	;NON-ZERO MEANS DATA MESSAGE
	IBP	T4		;SKIP CNT
	ILDB	T1,T4		;GET NUMBERED MESSAGE TYPE
	CAIG	T1,NC.MAX	;IN RANGE?
	AOS	NCLXMT(T1)	;YES, COUNT IT
	JRST	NETWR2		;ALL DONE, OKAY TO SEND

NETWR1:	MOVE	T1,PCBOCT(U)	;GET LENGTH OF ENTIRE MESSAGE
	ADD	T1,PCBOC2(U)	;INCLUDING USER DATA, IF ANY
	MOVEI	T1,-6(T1)	;DISCARD PROTOCOL OVERHEAD
	CAIGE	T1,1_<DLHSIZ-1>  ; IN RANGE OF TABLE?
	JFFO	T1,.+2		;YES, GET APPROPRIATE RANGE
	TDZA	T1,T1		;OUT OF RANGE, INCREMENT ENTRY 0
	MOVNI	T1,-^D36(T2)	;MAKE ASCENDING ENTRIES MEAN LONGER LENGTHS
	AOS	NCLXDL(T1)	; AND RECORD IT
>
NETWR2:	CONO	PI,PIOFF	;TURN OF THE PI SYS
				;ASSIGN MESAGE NUMBERS HERE
;NCA
	MOVE	T4,PCBOAD##(U)	;GET THE OUTPUT POINTER
	HRLI	T4,(POINT 8,0,31)	;POINT TO THE NCA/NCN FIELDS
	LDB	T1,NDBNCA##	;GET THE LAST MESSAGE ACK'ED
	DPB	T1,NDBLAS##	;SAVE AS LAST ACK
	DPB	T1,T4		;STORE THE ACK NUMBER
;NCN
	LDB	T1,NDBLMA##	;GET THE LAST MESSAGE NUMBER ASSIGNED
	SKIPGE	PCBBLK##(U)	;NUMBERED MESSAGE
	ADDI	T1,1		;YES, UPATE THE COUNT
	DPB	T1,NDBLMA##	;STORE AS LAST ASSIGNED
	IDPB	T1,T4		;STORE THIS MESSAGE NUMBER
	DPB	T1,PCBMSN##	;SAVE THE MESSAGE NUMBER OF THIS PCB
FRCWRT:	AOSE	FEKBSO##(J)	;IS THE KONTROLLER BUSY
	JRST	NETWQU		;YES, MUST QUEUE THE REQUEST
	HRRZM	U,FEKOAD##(J)	;STORE THE PCB POINTER
	CONO	PI,PION		;BACK ON
	XCT	FEKWRT##(J)	;CALL THE KONTROLLER
	POPJ	P,		;RETURN

;HERE TO QUEUE A REQUEST FOR A FEK
;NCL MESSAGE GO TO THE BACK OF THE QUEUE
;USER MESSAAGE GO TO THE BACK OF THE QUEUE
NETWQU:	HRRZ	T2,FEKOAD##(J)		;GET THE CURRENT PCB POINTER
NETWQ1:	MOVEI	T1,(T2)		;STEP DOWN THE QUEUE LIST
	HRRZ	T2,PCBBLK##(T1)	;GET THE NEXT ENTRY
	JUMPN	T2,NETWQ1	;END OF LIST
	HRRM	T2,PCBBLK##(U)	;LINK THE NEW PCB
	HRRM	U,PCBBLK##(T1)	;TO LAST OR FIRST IN THE QUEUE
	PJRST	ONPOPJ##	;TURN THE INTERRUPT SYSTEM ON RETURN
SUBTTL NETHIB/NETWAK - HIBERNATE AND SLEEP ROUTINE FOR JOB ON THE NET
;SUBROUTINE NETHIB - PUT THE JOB IN THE HIBER STATE
;CALL	MOVEI	F,DDB
;	PUSHJ	P,NETHIB
;RETURN	CPOPJ			;WHEN AWAKEN BY NETWAK

NETHIB::			;ENTRY
	SKIPN	F		;MUST HAVE A DDB
	STOPCD	CPOPJ##,STOP,FFU,;++F FOULED UP
	PUSHJ	P,SAVJW		;SAVE W AND J
	PUSHJ	P,SVEVM		;SAVE ANY EVM
	LDB	J,PJOBN##	;GET THE JOB NUMBER
	PUSHJ	P,FNDPDS##	;GET THE PDB
	HRLM	F,.PDNET(W)	;STORE THE DDB POINTER IN CASE OF RESET(^C^C)
	MOVEI	T1,EV.NET	;GET REASON FOR EVENT WAKE
	PUSHJ	P,ESLEEP##	;WAIT
	HRRZ	W,JBTPDB##(J)	;GET THE PDB BACK
	HRRZS	.PDNET##(W)	;CLEAR THE POINTER
	POPJ	P,		;YES, EXIT TO CALLER


;SUBROUTINE NETWAK - WAKE THE JOB UP PUT TO SLEEP BY NETHIB
;CALL	MOVEI	F,DDB
;	PUSHJ	P,NETWAK
;RETURN	CPOPJ			;JOB(PC) WILL BE @ NETHIB

NETWAK::PUSHJ	P,SAVJW		;SAVE J AND W
	LDB	T1,PJOBN##	;GET THE JOB NUMBER
	PJRST	EWAKE##		;WAKE THE JOB

;SUBROUTINE NETSLP - PUT THE JOB TO SLEEP FOR 2 SECONDS
;CALL	MOVEI	F,DDB
;	PUSHJ	P,NETSLP
;RETURN	CPOPJ			;AFTER 2 SECOND

NETSLP::PUSHJ	P,SAVJW		;SAVE J AND W
	PUSHJ	P,SAVT##	;SAVE THE T'S DON'T KNOW WHO IS CALLING
	PUSHJ	P,SVEVM		;SAVE ANY EVM THE JOB MAY HAVE
	LDB	J,PJOBN##	;GET THE JOB NUMBER
	MOVEI	T1,2		;TWO SECONDS
	PUSHJ	P,SLEEP##	;SLEEP
	  JFCL			;MAYBE
	POPJ	P,		;RETURN
SUBTTL INPDIS - DISMISS THE INPUT INTERRUPT
;SUBROUTINE INCTBD - RECORD AND DISCARD A BAD INPUT MESSAGE
;CALL	MOVEI	U,PCB
;	MOVEI	J,FEK
; 	MOVEI	T1,.
;	PUSHJ	P,INCTBD	;USUALLY PJSP	T1,INCTBD
;RETURN CPOPJ

INCTBD:	AOS	%NTBAD		;COUNT THIS MESSAGE
	HRRZ	W,PCBNDB(U)	;ENSURE W IS SETUP (MAY BE 0)
	HRLI	U,(T1)		;KEEP PC OF FINDER IN LH OF %NTBLC
	EXCH	U,%NTBLC	;SAVE, GET LAST ONE
	HRRZM	U,FEKIAD(J)	;USE THAT (OR 0) FOR NEXT MSG (SEE NETRDX)
	PJRST	INPDI1		;DISMISS INTERRUPT

;SUBROUTINE INPDIS - DISMISS THE INTERRUPT
;CALL	MOVEI	U.PCB
;	MOVEI	J,FEK
;	PUSHJ	P,INPDIS
;RETURN	CPOPJ			;USUALLY TO THE FEK FOR A DISMISS

INPDIS:	HRRZ	W,PCBNDB(U)	;ENSURE W SETUP
INPDI1:	SOSGE	FEKBSI##(J)	;REDUCE THE INPUT READ REQUEST
	PJRST	NETRDX		;READ ANOTHER BUFFER
	STOPCD	INPDI2,DEBUG,BFU,;++BUSY FOULED UP
INPDI2:	SETOM	FEKBSI##(J)	;SET IT IDLE
	POPJ	P,		;RETURN



;SUBROUTINE NETHRU - SEND A ROUTE THROU MESSAGE
;CALL	MOVEI	U,PCB
;	JRST	NETHRU
;RETURN	(NEVER)		;GO TO INPDIS

NETHRU:				;ENTRY
	PUSH	P,J		;SAVE THE INPUT FEK
	PUSHJ	P,SRCNDB	;FIND THE NODE TO SEND THE MESSAGE
	  JSP	T1,[POP P,J	;RESTORE THE INPUT FEK
		JRST INCTBD]	;ILLEGAL MESSAGE
	HRRZ	J,NDBFEK##(W)	;GET THE OUTPUT FEK
	CONO	PI,PIOFF	;TURN OFF THE PI SYSTEM(FRCWRT TURNS ON)
	PUSHJ	P,FRCWRT	;SEND THE MESSAGE
	POP	P,J		;RESTORE THE INPUT FEK
	SETZB	W,FEKIAD##(J)	;CLEAR THE PCB AND INPUT POINTER
	JRST	INPDIS		;DISMISS THE INTERRUPT
;SUBROUTINE NETRDD - SET UP A READ REQUEST TO THE FRONT END
;CALL	MOVEI	J,FEK		;FEK TO READ
;	PUSHJ	P,NETRDD
;RETURN	CPOPJ

NETRDD:	SETZ	W,		;CLEAR THE NODE POINTER
NETRDX:	CONO	PI,PIOFF##	;TURN THE PI OFF
	SKIPL	FEKBSI##(J)	;IS THERE A READ REQUEST
	PJRST	ONPOPJ##	;YES, EXIT
	AOS	FEKBSI##(J)	;SET BUSY
	CONO	PI,PION##	;TURN PI ON
	SETZ	F,		;CLEAR THE DDB POINTER
	HRRZ	U,FEKIAD##(J)	;THE THE PCB POINTER
	JUMPN	U,NETRD1	;JUMP IF ALLOCATED
	PUSHJ	P,MAKPCB	;MAKE A PCB
	  JRST	INPDI2		;CLEAR BUSY AND EXIT
	SETZM	PCBNDB##(U)	;CLEAR THE NDB POINTER
	MOVEI	T2,^D128		;BUFFER SIZE
	PUSHJ	P,GETZWD	;GET THE BUFFER SPACE
	  JRST	[SETOM FEKBSI##(J)	;CLEAR BUSY
		PJRST	RMVPCB]		;NONE AVAILABLE REMOVE THE PCB
	JRST	NETRD2		;CONTINUE
NETRD1:	HRRZ	T1,PCBIAD##(U)	;GET THE BUFFER POINTER
NETRD2:	HRLI	T1,(POINT 8)	;EIGHT BIT BYTE POINTER
	MOVEM	T1,PCBIAD##(U)	;STORE IN THE PCB
	MOVE	T1,[XWD ^D128,^D512] ;GET THE COUNT FIELD
	MOVEM	T1,PCBICT##(U)	;STORE THE COUNT FIELD
	HRRZM	U,FEKIAD##(J)	;STORE THE PCB POINTER
	PUSH	P,W		;SAVE THE NDB POINTER
	XCT	FEKRDD##(J)	;CALL THE FRONT END KONTROLLER
	POP	P,W		;RESTORE NDB
	JUMPE	W,CPOPJ##	;EXIT IF NO NDB (ROUTE THRU)
	MOVSI	T1,.RMSUI##	;GET THE IDLE BIT
	TDNE	T1,SCBSTS##(W)	;IS IT IDLE
	PJRST	SCNTTO		;NO, SCAN THE TTY'S
	POPJ	P,		;YES, EXIT
SUBTTL INPINT - INPUT INTERRUPT PROCESSOR FOR ALL FEK'S
;SUBROUTINE INPINT - INPUT INTERRUPT
;CALL	MOVE	J,[XWD FLAGS,FEK]
;	PUSHJ	P,INPINT
;RETURN	CPOPJ

INPINT:	PUSHJ	P,SAVE4##	;SAVE THE P'
	MOVEI	P4,300		;DUMMY COUNT FOR HEADER PORTION OF A MESSAGE
	SETZB	W,F		;CLEAR THE NDB POINTER,DDB POINTER
	HRRZ	U,FEKIAD##(J)	;GET THE INPUT PCB POINTES
	MOVE	P1,PCBIAD##(U)	;GET THE IOPUT MESSAGE POINTER
	HRRE	T1,PCBICT##(U)	;GET THE INPUT BYTE COUNT
	JUMPLE	T1,INPIN0	;ZERO LENGTH IS ILLEGAL
	IDIVI	T1,4		;CONVERT TO WORDS AND BYTES
	ADDI	T1,(P1)		;RELOCATE TO THE BUFFER
	ADD	T1,[POINT 8,0,7 ;BUILD A DEPOSITE TABLE
		POINT	8,0,15
		POINT	8,0,23
		POINT	8,0,31](T2)
	DPB	W,T1		;SET A TERMINATING 0 BYTE
;NCT
	PUSHJ	P,EBI2BI	;READ THE FLAGS
	HRLI	U,(T1)		;COPY THE FLAGS
	ANDI	T1,NCT.TP	;JUST THE MESSAGE TYPE
IFN FTCMSR,<
	AOS	NCLRTP(T1)	;TALLY
>
	TLNE	U,NCT.RH	;ROUTINE HEADER PRESENT
	JRST	INPIN1		;YES,
	CAIE	T1,NCT.ID	;IS THIS AN ID MESSAGE
INPIN0:	PJSP	T1,INCTBD	;NO, BAD MESSAGE (N.B. HERE FROM ABOVE TO SETUP T1)
	JRST	INCTID		;YES, PROCESS NODE ID MESSAGE
INPIN1:
;DNA
	PUSHJ	P,EBI2BI	;GET <DNA>
	SKIPN	T1		;IS IT NULL
	MOVEI	T1,OURNNM##	;USER OURS
	CAIE	T1,OURNNM##	;FOR THIS NODE
	JRST	NETHRU		;RE-ROUTE THE MESSAGE OUT THE OTHER END
;SNA
	PUSHJ	P,EBI2BI	;YES, GET THE <SNA>
	PUSHJ	P,SRCNDB	;FIND THE NODE BLOCK
	PJSP	T1,INCTBD	;SOURCE WENT AWAY
	HRRZM	W,PCBNDB##(U)	;SAVE THE NDB POINTER
;NCA

	ILDB	T1,P1		;GET THE ACK NUMBER
	PUSHJ	P,CHKNCA	;ACK ALL MESSAGE POSSIBLE
;NCN
	ILDB	T1,P1		;GET THIS MESSAGE NUMBER
	TLNE	U,NCT.TP	;NUMBERED MESSAGE
	JRST	INCTUN		;NO, UNNUMBERED
	DPB	T1,NDBLMR##	;STORE LAST MESAGE RECEIVED
	LDB	T2,NDBLMP##	;GET LAST MESSAGE PROCESSED
	ADDI	T2,1		;GET NEXT SEQUENTIAL MESSAGE NUMBER
	ANDI	T2,377		;ONLY 8 BITS
;*****	CAIN	T1,(T2)		;IS THIS MESSAGE IN SEQUENCE
	JRST	INCTNM		;YES, SEQUENTIAL MESSAGE

;HERE IF A MESSAGE ARRVICES OUT OF ORDER

SUBTTL CHKNCA - CHECK ACK'S FOR MESSAGE SENT BUT BEING HELD
;SUBROUTINE CHKNCA - DELETE MESSAGE THE HAVE ACK'S
;CALL	MOVEI	W,NDB
;	MOVEI	T1,NCA - MESSAGE ACK NUMBER
;RETURN	CPOPJ

CHKNCA:				;ENTRY
	JUMPE	W,CPOPJ##	;EXIT IN NDB UNDEFINED
	PUSHJ	P,SAVE1##	;SAVE P1
	MOVEI	P1,(T1)		;COPY THE ACK
	PUSH	P,U		;SAVE THE OLD PCB
	DPB	T1,NDBLAR##	;SAVE THE LAST ACK RECEIVED
CHKNC1:	LDB	T2,NDBLAP##	;LST ACK PROCESSED
CHKNC2:	CAIN	T2,(P1)		;PROCESSED ALL ?
	JRST	UPOPJ##		;ALL DONE
	MOVEI	T1,(P1)		;GET ACK NUMBER
	SUBI	T1,(T2)		;MINUS THE LAST ACK PROCESSED
	ANDI	T1,377		;MAKE 8 BITS ONLY
	LDB	T3,NDBLMS##	;GET LAST MESSAGE SENT
	SUBI	T3,(T2)		;MINUS LAST ACK PROCESSED
	ANDI	T3,377		;8 BITS
	CAIGE	T3,(T1)		;IS THIS ACK IN RANGE
	JRST	UPOPJ##		;NO IGNORE THE ACK
	ADDI	T2,1		;UPDATE ACK COUNT
	ANDI	T2,377		;ONLY 8 BITS
	DPB	T2,NDBLAP##	;REMEMBER
	HRRZ	U,NDBQUE##(W)	;GET THE QUEUE POINTER
	JUMPE	U,CHKNC2	;NO ENTRIES
	LDB	T3,PCBMSN##	;GET THIS MESSAGES NUMBER
	CAIE	T3,(T2)		;IS THIS THE ONE
	JRST	CHKNC2		;NO, CHECK THE NEXT
	MOVE	T3,PCBBLK##(U)	;GET THE QUEUE LINK
	HRRM	T3,NDBQUE##(W)	;STEP TO THE NXT MESSAGE
	PUSHJ	P,RMVPCB	;REMOVE THE PCB
	JRST	CHKNC1		;TRY THE NEXT PCB
SUBTTL - PROCESS THE TOPS MESSAGE ON THE QUEUE IN SEQUENCE
INCTNM:				;HERE FOR NEXT MESSAGE
	JUMPN	W,.+2		;IF THERE'S A SOURCE PROCESS MESSAGE
	PJSP	T1,INCTBD	;ELSE COMPLAIN ABOUT BAD MESSAGE
	DPB	T1,NDBLMP##	;SAVE LAST MESAGE PROCESSED
	JRST	INCTDM		;PROCESS NUMBERED DATA MESSAGE

INCTUN:	HLRZ	T1,U		;GET THE FLAGS
	ANDI	T1,NCT.TP	;GET THE TYPE FIELD
	JRST	@NCTTBL(T1)	;DISPATCH BY THE MESSAGE TYPE

NCTTBL:	JRST	INCTDM		;(0) DATA MESSAGE
	JRST	INCTAK		;(1) ACK
	JRST	INCTNK		;(2) NAK
	JRST	INCTRP		;(3) REP
	JRST	INCTST		;(4) START
	JRST	INCTSK		;(5) STACK
	JRST	INCTID		;(6) NODE ID
	JRST	INPDIS		;(7) ILLEGAL INPUT MESSAGE TYPE
SUBTTL INCTID - NODE ID MESSAGE PROCESSOR
INCTID:				;ENTRY
;NCA
	ILDB	T1,P1		;GET THE ACK START
;NCN
	ILDB	T1,P1		;GET THE STARTING MESSAGE NUMBER
;NNM
	PUSHJ	P,EBI2BI	;READ THE NODE NUMBER
	PUSHJ	P,SRCNDB	;DOES THE NODE EXIST
	  CAIA			;NO
	JRST	INCTI0		;YES, MUST BE A RESTART
	PUSHJ	P,MAKNDB	;MAKE A NODE DATA BLOCK
	  JRST	INPDIS		;NO CORE DO IT NEXT TIME
;OPD
INCTI0:	PUSHJ	P,RDOPDD	;READ THE OPTIONAL DATA
	  PJRST	INPDIS		;DISMISS
	PUSH	P,W		;SAVE THE NDB POINTER
	HLRZ	T1,NDBNNM##(W)	;GET THE NODE NUMBER
	MOVEI	W,NETNDB##	;GET OUR NODE BLOCK
	PUSHJ	P,SRCTOP	;DO WE KNOW HIM
	  CAIA			;NO
	JRST	INCTI1		;YES, DO NOT MAKE AN ENTRY
	PUSH	P,T1		;SAVE THE NODE NUMBER
	SETZ	T1,		;SEARCH FOR AN OPEN SLOT
	PUSHJ	P,SRCTOP	;IN THE TOPOLOGY TABLE
	  JRST	INCTI1		;NONE AVAILABLE
	POP	P,T1		;RESTORE THE NODE NUMBER
	LSH	T1,^D8		;POSITION
	IORI	T1,1		;ADD THE LINK VALUE
	DPB	T1,T4		;STORE THE NEIGHBOR
	PUSHJ	P,SETNBN	;SET UP TO SEND NEIGHBORS
INCTI1:	POP	P,W		;RESTORE THE NDB POINTER
	JRST	INPDIS		;DISMISS

;INCTST - START MESSAGE PROCESSOR
INCTST:				;ENTRY
;NNM
	PUSHJ	P,EBI2BI	;READ THE NODE NUMBER
	PUSHJ	P,SRCNDB	;DOES THE NDOE EXIST
	  JRST	INPDIS		;NO, WAIT FOR A NEIGHBORS MESSAGE
	HRLZI	T1,NDBCLR##(W)	;GET FIRST WORD TO CLEAR
	HRRI	T1,NDBCLR##+1(W);SECOND WORD
	SETZM	NDBCLR##(W)	;CLEAR THE FIRST WORD
	BLT	T1,NDBLEN##(W)	;CLEAR THE REST OF THE BLOCK
	PUSHJ	P,RDOPDD	;READ THE OPTIONAL DATA
	  PJRST	INPDIS		;DISMISS
	MOVSI	T1,NDB.ST##	;GET THE START BIT
	IORM	T1,NDBFEK##(W)	;STORE
	PUSH	P,U		;SAVE THE PCB POINTER
	PUSHJ	P,NCSSTK	;SEND A STACK BACK
	  JFCL			;TRY LATER
	POP	P,U		;RESTORE THE PCB
	JRST	INCTS1		;COMMON EXIT TO CLEAR NUMBERS

;SUBROUTINE INCTSK - STACK MESSAGE PROCESSOR
INCTSK:				;ENTRY
;NNM
	PUSHJ	P,EBI2BI	;READ THE NODE NUMBER
	PUSHJ	P,SRCNDB	;FIND THE NDB
	  JRST	INPDIS		;WAIT FOR A NODE DATA BLOCK
	PUSHJ	P,RDOPDD	;READ THE OPTIONAL DATA
	  PJRST	INPDIS		;DISMISS THE INTERRUPT
	MOVSI	T1,NDB.SK##	;GET START FLAG
	IORM	T1,NDBFEK##(W)	;SET THE FLAG
INCTS1:	JRST	INPDIS		;DISMISS THE INTERRUPT

;SUBROUTINE INCTAK - ACK MESSAGE PROCESSOR
INCTAK:				;ENTRY
				;ACK'S HAPPEN IN THE HEADER ROUTINE
	JRST	INPDIS		;DISMISS THE INTERRUPT

;SUBROUTINE INCTNK NAK MESSAGE PROCESSOR
INCTNK:				;ENTRY
	JUMPE	W,INPDIS	;JUNK IN THE PIPE
	PUSH	P,P1		;SAVE P1
	PUSH	P,U		;SAVE THE PCB
	HRRZ	P1,NDBQUE##(W)	;GET THE POINTER
	HLLZS	NDBQUE##(W)	;NO LONGER WAITING FOR ACK
	JUMPE	P1,INCTN2	;EMPTY
INCTN1:	MOVEI	U,(P1)		;GET THE NEXT ENTRY
	HRRZ	P1,PCBBLK##(U)	;GET THE NEXT ENTRY
	PUSHJ	P,NETWRT	;RESEND THE MESSAGE
	JUMPN	P1,INCTN1	;CHECK FOR THE END
INCTN2:	POP	P,U		;RESTOE THE PCB
	POP	P,P1		;RESTORE P1
	JRST	INPDIS		;DISMISS THE INTERRUPT

;SUBROUTINE INCTRP REP PROCESSOR
INCTRP:				;ENTRY
	JUMPE	W,INPDIS	;JUNK IN THE PIPE
	PUSH	P,P1		;SAVE P1
	PUSH	P,U		;SAVE THE PCB
	HLRZ	P1,NDBQUE##(W)	;GET THE INPUT QUEUE POINTER
	JUMPE	P1,INCTR2	;NONE MUST SEND AN ACK
INCTR1:	MOVEI	U,(P1)		;COPY THE PCB POINTER
	HRRZ	P1,PCBBLK##(U)	;STEP TO THE NEXT ENTRY
	PUSHJ	P,RMVPCB	;REMOVE THIS PCB
	JUMPN	P1,INCTR1	;CONTINUE
	LDB	T1,NDBLMP##	;GET LAST MESSAGE PROCESSED
	DPB	T1,NDBLMR##	;STORE AS LAST MESSAGE RECEIVED
	PUSHJ	P,NCSNAK	;SEND A NAK
	  JFCL			;DON'T CARE
	JRST	INCTR3		;CONTINUE TO EXIT
INCTR2:	PUSHJ	P,NCSAKK	;SEND A ACK
	  JFCL			;DON'T CARE
INCTR3:	POP	P,U		;RESTORE U
	POP	P,P1		;RESTORE P1
	JRST	INPDIS		;DISMISS THE INTERRUPT
;SUBROUTINE RDOPDD - INSERT THE SOFTWARE ID <NNM><SNM><SID>
;CALL	MOVEI	U,PCB
;	MOVEI	W,NDB OR 0
;	PUSHJ	P,RDOPDD
;RETURN	CPOPJ		;NO CORE
;	CPOPJ1		;W=NDB


RDOPDD:				;ENTRY
	SETZB	T1,NDBMNM##(W)	;CLEAR THE MESSAGE NUMBER
	DPB	T1,NDBLAS##	;AND THE ACK COUNTERS
	HLLZS	NDBSNM##(W)	;..
;SNM
	HLRZ	P2,NDBSNM##(W)	;CHECK FOR A POINTER
	JUMPN	P2,RDOPD1	;YES
	MOVEI	T2,1		;STATION NAME POINTER(SIXBIT)
	PUSHJ	P,GETZWD	;ALLOCATE SPACE
	  POPJ	P,		;NO, SPACE
	HRLM	T1,NDBSNM##(W)	;STORE THE POINTER
	MOVEI	P2,(T1)		;OUTPUT POINTER FOR COPY
RDOPD1:	PUSHJ	P,EAS2SX	;COPY THE STATION NAME
	MOVEM	T1,(P2)		;STORE THE STATION NAME
;SID
	HRRZ	P2,NDBSID##(W)	;CHECK FOR A POINTER
	JUMPN	P2,RDOPD2	;YES
	MOVEI	T2,^D8		;ALLOCATE SPACE FOR THE SYSTEM NAME
	PUSHJ	P,GETZWD	;FROM FREE CORE
	  POPJ	P,		;NO CORE
	HRRM	T1,NDBSID##(W)	;STORE THE POINTER
	MOVEI	P2,(T1)		;GET THE POINTER
RDOPD2:	PUSHJ	P,EAS2AS	;COPY THE SYSTEM NAME
	HLRZ	P2,NDBSID##(W)	;GET THE POINTER
	JUMPN	P2,RDOPD3	;JUMP IF ONE
	MOVEI	T2,^D8		;ALLOCATE SPACE FOR THE CREATION DATE
	PUSHJ	P,GETZWD	;FROM FREE CORE
	  POPJ	P,		;NO SPACE
	HRLM	T1,NDBSID##(W)	;STORE THE POINTER
	MOVEI	P2,(T1)		;COPY THE POINTER
RDOPD3:	PUSHJ	P,EAS2AS	;COPY THE CREADTION DATE
	PUSHJ	P,ONLNDB	;TYPE ONLINE MESSAGE
	PJRST	CPOPJ1##	;EXIT
SUBTTL INCTDM - PROCESS OF NUMBERED CONTROL/DATA MESSAGES
INCTDM:				;ENTRY
;DLA
	PUSHJ	P,EBI2BI	;GET THE DESTINATION LINK ADDRESS
	JUMPN	T1,IDCCTL	;DEVICE CONTROL MESSAGE
;
;HERE TO PROCESS NUMBERD CONTROL MESSAGES
;
;CNT
NCTDSP:	MOVEI	P4,2		;ALLOW 2 BYTES OF COUNT
	PUSHJ	P,EBI2BI	;GET THE MESSAGE COUNT FIELD
	MOVEI	P4,(T1)		;COPY THE COUNT FIELD
	JUMPE	P4,INPDIS	;END OF MESSAGE
;CM
	PUSHJ	P,EBI2BI	;GET THE MESSAGE TYPE
	CAILE	T1,NC.MAX	;IN RANGE?
	PJSP	T1,INCTBD	;NO, DISCARD
IFN FTCMSR,<
	AOS	NCLRMT(T1)	;RECORD THIS ONE
>
	PUSHJ	P,ICMTBL(T1)	;DISPATCH TO THE CONTROL PROCESSORS
	  PJSP	T1,INCTBD	;ILLEGAL MESSAGE
NCTDS1:	JUMPLE	P4,NCTDSP	;TRY ANOTHER MESSAGE
	PUSHJ	P,EAS2SX	;REMOVE THE EXTRA PART OF THE MESSAGE
	JRST	NCTDS1		;TRY AGAIN

ICMTBL:
	JRST	CPOPJ##		;<0> IS ILLEGAL
	JRST	ICMCNT		;<1> CONNECT
	JRST	ICMDSC		;<2> DISCONNECT
	JRST	ICMNBN		;<3> NEIGHBOURS
	JRST	ICMRCF		;<4> REQUEST CONFIGURATION
	JRST	ICMCNF		;<5> CONFIGURATION
	JRST	ICMDRQ		;<6> DATA REQUEST
	JRST	ICMCTL		;<7> STATION CONTROL
SUBTTL ICMXXX MESSAGE PROCESSORS
;SUBROUTINE ICMCNT - CONNECT
ICMCNT:				;ENTRY
;DLA
	PUSHJ	P,EBI2BI	;GET THE DESTINATION LINK ADDRESS
	JUMPE	T1,ICMCNN	;THIS IS A CONFIRM COMMECT CALL
	CAIGE	T1,LATLEN##	;YES, CHECK RANGE
	SKIPN	F,NETLAT##(T1)	;GET THE DDB ADDRESS
	POPJ	P,		;BAD MESSAGE
	JUMPL	F,TTYCNX	;ITS A LDB IE TTY CONNECT CONFIRM
;SLA
	PUSHJ	P,EBI2BI	;GET THE SOURCE NODE ADDRESS
	JUMPE	T1,CPOPJ##	;ILLEGAL MESSAGE IF SOURCE IS ZERO
	DPB	T1,NETDLA##	;SAVE THE SOURCE
;DPN
;OBJ
	PUSHJ	P,EBI2BI	;GET THE OBJECT TYPE
;PID
	PUSHJ	P,EBI2BI	;GET THE UNIT NUMBER
;SPN
;OBJ
	PUSHJ	P,EBI2BI	;GET THE SOURCE OBJECT TYPE
IFN FTTSK,<
	CAIN	T1,OBJ.TK	;TASK CONFIRM
	JRST	ICMCN1		;YES, IGNORE THE REST OF THE MESSAGE
>
;PID
	PUSHJ	P,EBI2BI	;UNIT NUMBER
	ANDI	T1,7		;ONLY THREE BITS WORTH
	DPB	T1,PUNIT##	;STORE AS THE REAL UNIT NUMBER
	ADDI	T1,'0'		;TO SIXBIT
	DPB	T1,[POINT 6,DEVNAM(F),35] ;STORE THE UNIT NUMBER
;MML
	PUSHJ	P,EBI2BI	;GET THE MAX RECORD LENGTH
;FEA
;DCM
	PUSHJ	P,EBI2BI	;GET THE MODE FIELD
;RLN
	PUSHJ	P,EBI2BI	;GET THE RECORD LENGTH
	DPB	T1,NETRLN##	;STORE RECORD LENGTH
;DVT
	PUSHJ	P,EBI2BI	;GET THE DEVICE ATTRIBUTES
	DPB	T1,NETDVT##	;STORE IN THE DDB
ICMCN1:	MOVSI	S,IOSCON	;DEVICE NOW CONNECTED
	IORM	S,DEVIOS(F)	; AND READY FOR USE
	SETZ	T1,		;SET THE REASON TO ZERO FOR SUCCESS
	DPB	T1,NETRSN##	;SET THE REASON BYTE
	PUSHJ	P,NETWAK	;WAKE THE JOB
	PJRST	CPOPJ1##	;EXIT
SUBTTL ICMCNN - ANOTHER NODE IS ATTEMPTING TO CONNECT TO OUT DEVICE OR TASK
ICMCNN:				;ENTRY FROM ABOVE
	PUSH	P,U		;SAVE THE PCB
;SNA
	PUSHJ	P,EBI2BI	;GET THE SNA
	PUSH	P,T1		;SAVE THE SNA
;DPN
;OBJ
	PUSHJ	P,EBI2BI	;GET THE OBJECT TYPE
	MOVE	T2,(P)		;GET THE LINK ADDRESS
	SETZ	T3,
	CAIN	T1,OBJ.TT	;TTY CONNECT TO MCR?
	MOVEI	T3,TTYCNZ	;YES
IFN FTTSK,<
	CAIN	T1,OBJ.TK	;TASK?
	MOVEI	T3,TSKCNT##	;YES
>
	JUMPE	T3,ICMCN2	;DISCONNECT IF NOT A RECOGNIZED DEVICE
	PUSHJ	P,(T3)		;TRY TO CONNECT
	  JRST	ICMCN3		;CAN'T, SEND DISCONNECT
	POP	P,T1
	JRST	UPOPJ1##	;CONNECTION COMPLETE

ICMCN2:	MOVEI	T2,RSN.OT	;OBJECT TYPE NOT AVAILABLE
ICMCN3:	POP	P,T1		;RESTORE LINK ADDRESS
	MOVEI	F,0		;ENSURE NCSDSC WON'T WAIT FOR RESPONSE
	PUSHJ	P,NCSDSC	;SEND A DISCONNECT
	  JFCL			;IGNORE ERROR (PICKED UP LATER)
	JRST	UPOPJ1##	;DISMISS THE MESSAGE
SUBTTL ICMDSC - DISCONNECT
ICMDSC:				;ENTRY
;DLA
	PUSHJ	P,EBI2BI	;GET THE DESTINATION LINK ADDRSS
	JUMPE	T1,CPOPJ##	;ILLEGAL MUST HAVE A DESTINATION
	CAIGE	T1,LATLEN##	;CHECK RANGE
	SKIPN	F,NETLAT##(T1)	;GET THE DDB
	POPJ	P,		;MUST HAVE A DDB
	JUMPL	F,DSCTTY	;DISCONNECT A TTY
	MOVSI	T1,NT.DSC##	;LET NCSDSC FIGURE OUT THAT
	IORM	T1,NETSTS##(F)	;DISCONNECT SEQUENCE IS COMPLETE
	MOVE	S,DEVIOS(F)
	TLZN	S,IOSCON	;SAY WE'RE NO LONGER CONNECTED
	JRST	ICMDS1		;NO NEED TO CALL TSKDSC IF A CONFIRM
IFN FTTSK,<
	LDB	T1,DEYTYP##	;GET THE DEVICE TYPE
	CAIN	T1,<.TYTSK/.TYEST>;IS IT A TSK
	PUSHJ	P,TSKDSC##	;YES, SPECIAL DISCONNECT FOR A TSK
>;END FTTSK
;SLA
ICMDS1:	PUSHJ	P,EBI2BI	;GET THE SOURCE (IGNORE)
;RSN
	PUSHJ	P,EBI2BI	;GET THE REASON FOR THE DISCONNECT
	DPB	T1,NETRSN##	;STORE STATUS
	PUSHJ	P,NETWAK	;YES, WAKE THE JOB
	AOS	(P)		;FOR SUCCESSFUL RETURN
	PJRST	STOIOS##	;REMEMBER NEW S
;SUBROUTINE ICMNBN - NEIGHBOURS
ICMNBN:				;ENTRY
	PUSH	P,U		;SAVE THE PCB
	HRLI	T1,NDBTOP##(W)	;MUST CLEAR THE OLD TABLE FIRST
	HRRI	T1,NDBTOP##+1(W)	;...
	SETZM	NDBTOP##(W)
	BLT	T1,NDBTOP##+7(W)
	MOVE	T4,[POINT 18,NDBTOP##(W)]	;POINTER TO THE TOP TABLE
	MOVEI	T3,^D16		;MAX SISTEEN NEIGHBORS PER NODE
ICMNB1:	JUMPLE	P4,ICMNB2	;END OF MESSAGE EXIT
	PUSHJ	P,EBI2BI	;GET A NODE NUMBER
	LSH	T1,^D8		;POSITION
	ILDB	T2,P1		;GET THE LINK VALUE
	SUBI	P4,1		;COUNT THE CHARACTER
	ANDI	T2,377		;ONLY EIGHT BITS WORTH
	IORI	T1,(T2)		;COMBINE
	IDPB	T1,T4		;STORE IN THE TABLE
	SOJG	T3,ICMNB1	;CONTINUE

;HERE TO RECOMPUT THE TOPOLOGY OF THE NETWORK BASED ON A NEIGHBORS CHANG


ICMNB2:	PUSH	P,W		;SAVE THE NDB POINTER
	MOVEI	W,NETNDB##	;START THE SEARCH WITH OUR NEIGHBORS
	PUSHJ	P,SRCNBN	;START THE SEARCH

;HERE TO SEARCH FOR LOST NODES IN THE NETWORK
ICMNB3:	MOVEI	W,NETNDB##	;GET THE START OF THE LIST
ICMNB4:	HRRZ	W,NDBNNM##(W)	;GET THE NEXT NODE DATA BLOCK
	JUMPE	W,ICMNB5	;END OF BLOCKS
	MOVSI	T1,NDB.TP##	;GET THE TOPOLOGY SEARCH FLAG
	TDNE	T1,NDBFEK##(W)	;WAS THIS NODE SEEN
	JRST	ICMNB4		;YES, CONTINUE
	PUSHJ	P,RMVNDB	;NO LOST NODE REMOVE IT
	JRST	ICMNB3		;CONTINUE
;HERE TO REMOVE ALL THE NDB.TP FLAGS
ICMNB5:	MOVEI	W,NETNDB##	;START AT THE FIRST OF THE LIST
	MOVSI	T1,NDB.TP##	;GET THE TOPOLOGY SEARCH FLAG
ICMNB6:	HRRZ	W,NDBNNM##(W)	;GET THE NEXT NDB
	JUMPE	W,ICMNB7	;END OF THE LIST
	ANDCAM	T1,NDBFEK##(W)	;CLEAR IT
	JRST	ICMNB6		;CONTINUE
ICMNB7:	POP	P,W		;RESTORE THE NDB POINTER
	JRST	UPOPJ1##	;DISMISS THE MNESSAGE

SRCNBN:	PUSH	P,[POINT 18,NDBTOP##(W)]	;POINTER TO THE TOPOLOGY TABLE
SRCNB1:	ILDB	T1,(P)		;GET THE NEXT ENTRY
	LSH	T1,-^D8		;POSITION THE NNM
	HRRZ	T2,(P)		;GET THE POSITION IN THE TABLE
	CAILE	T2,NDBTOP##+^D7 ;STILL IN RANGE
	JRST	TPOPJ##		;NO END OF TABLE
	JUMPE	T1,SRCNB1	;ZERO ENTRY GET THE NEXT ENTRY
	PUSH	P,W		;AVE THE NDB POINTER
	PUSHJ	P,SRCNDB	;IS THIS ENTRY DEFINED
	  CAIA			;IS THIS A KNOWN NODE
	JRST	SRCNB2		;YES,
	PUSHJ P,MAKNDB		;MAKE A NODE DATA BLOCK FOR THIS NODE
	  JRST	[POP P,W	;RESTORE THE NDB POINTER
		JRST	SRCNB1]	;CONTINUE
SRCNB2:	MOVSI	T2,NDB.TP##	;GET THE TOPOLOGY SEARCH BIT
	TDNE	T2,NDBFEK##(W)	;WAS THIS NODE SEEN BEFORE
	JRST	[POP P,W	;YES, THIS IS A MULTI PATCH
		JRST	SRCNB1]	;CONTINUE SEARCH
	IORM	T2,NDBFEK##(W)	;NO, BUT NOW WE SEE IT DON'T WE
	PUSHJ	P,SRCNBN	;SEARCH HIS TABLES
	POP	P,W		;RESTORE OUT NDB
	JRST	SRCNB1		;CONTINUE THE SEARCH
;SUBROUTINE SRCTOP - SEARCH A TOPOLOGY TABLE AND RETURN THE ENTRY
;CALL	MOVEI	W,NDB
;	MOVEI	T1,NNM		;TO SEARCH FOR
;RETURN	CPOPJ			;NOT FOUND
;	CPOPJ1			;FOUND T4=BYTE POINTER

SRCTOP:				;ENTRY
	PUSH	P,T1		;SAVE THE ARGUMENT
	LSH	T1,^D8		;POSITION FOR COMPARE
	MOVE	T4,[POINT 18,NDBTOP##(W)]	;START OF TABLE
	MOVSI	T3,-<^D16>	;MAX ENTRIES
SRCTO1:	ILDB	T2,T4		;GET THE NEXT ENTRY
	ANDI	T2,377400	;ONLY THE NODE NUMBER
	CAIN	T1,(T2)		;IS THIS THE ENTRY
	JRST	TPOPJ1##	;YES, EXIT
	AOBJN	T3,SRCTO1	;TRY AGAIN
	PJRST	TPOPJ##		;NO SUCH ENTRY
;SUBROUTINE ICMRCF - REQUEST CONFIGURATION
ICMRCF:				;ENTRY
	PUSH	P,U		;SAVE THE PCB
	PUSHJ	P,NCSCNF	;SEND THE CONFIGURATION MESSAGE
	  JFCL			;LATER
	PJRST	UPOPJ1##	;EXIT


;SUBROUTINE ICMCNF - CONFIGURATION
ICMCNF:				;ENTRY
	MOVSI	T1,NDB.CF##	;GET THE CONFIGURATION BIT
	IORM	T1,NDBFEK##(W)	;SEEN THE CONFIGURATION MESSAGE
	JUMPE	P4,CPOPJ1##	;NO DEVICES
ZZ==0
REPEAT <OBJ.MX/4>+1,<
	SETZM	SCBDEV##+ZZ(W)	;CLEAR THE DEVICE TABLE(S)
ZZ==ZZ+1
>;END OF REPEAT
	PUSH	P,P2		;SAVE P2
ICMCF1:
;OBJ
	PUSHJ	P,EBI2BI	;GET THE OBJECT TYPE
	CAILE	T1,OBJ.MX	;CHECK THE RANGE
	JRST	[POP	P,P2	;RESTORE P2
		POPJ	P,]	;DISMISS THE MESSAGE
	MOVEI	P2,(T1)		;COPY THE DEVICE NUMBER
;NDEV
	PUSHJ	P,EBI2BI	;GET THE COUNT
	CAILE	T1,200		;ALLOW ONLY 128 FOR NOW
	MOVEI	T1,200
	DPB	T1,NETCNF##(P2)	;STORE NEW COUNT
	CAIN	P2,OBJ.TY	;IS IT A TTY?
	MOVEM	T1,SCBTTY##(W)	;STORE TTY COUNT
;PID
ICMCF3:	PUSHJ	P,EAS2SX	;GET THE PID
	JUMPG	P4,ICMCF1	;CONTINUE THROUGH THE MESSAGE
	POP	P,P2		;RESTORE P2
	MOVEI	T1,ST.NRT
	TDNE	T1,STATES##
	JRST	CPOPJ1##
	PJRST	TTYCNT		;CONNECT ANY NEW TTY'S
;SUBROUTINE ICMDRQ - DATA REQUEST
ICMDRQ:				;ENTRY
;DLA
	PUSHJ	P,EBI2BI	;GET THE DESTINATION LINK
	JUMPE	T1,CPOPJ##	;ILLEGAL IF 0
	CAIGE	T1,LATLEN##	;CHECK THE RANGE
	SKIPN	F,NETLAT##(T1)	;GET THE DDB
	PJSP	T1,INCTBD	;OUT OF RANGE
;DRQ
	PUSHJ	P,EBI2BI	;GET THE REQUEST COUNT
	JUMPL	F,TTYDRQ	;YES, GO TO TTY ROUTINE
	ANDI	T1,777		;ONLY ALLOW A REQUEST THAT IS REASONABLE
	ADDM	T1,NETDRQ##(F)	;UPDATE THE OUTPUT DATA REQUEST COUNT
	AOS	(P)		;SKIP RETURN
	MOVEI	T1,DEPAIO	;NON, BLOCKING I/O
	TDNN	T1,DEVAIO(F)	;FOR THIS DEVICE
	PJRST	NETWAK		;NO, WAKE UP THE JOB
	PUSH	P,DEVIOS(F)	;SAVE THE REAL DEVIOS
	MOVSI	S,IO		;GET THE DIRECTION BIT
	IORB	S,DEVIOS(F)	;SET DIRECTION AS OUTPUT
	TLZ	S,IOSTBL	;CLEAR TROUBLE SO SETIOD WILL CALL PSIIOD
	PUSHJ	P,SETIOD##	;SET IO DONE
	POP	P,DEVIOS(F)	;RESTORE THE REAL DEVIOS
	POPJ	P,		;RETURN
;SUBROUTINE ICMCTL - STATION CONTOL
ICMCTL:				;ENTRY
	PUSHJ	P,SAVJW		;SAVE J AND W
	JUMPLE	P4,ICMCT5	;END OF MESSAGE
	PUSH	P,P1		;SAVE THE POSITION
	IBP	P1		;SKIP THE LINE NUMBER
	ILDB	T1,P1		;GET THE FUNCTION
	POP	P,P1		;NO, RESTORE THE BYTE POINTER
	SKIPE	T4,SCBCTL##(W)	;IS THE STATION CONTROL DEVICE ASSIGNED
	JRST	ICMCT0		;YES, PROCESS THE MESSAGE
	CAIE	T1,15		;IS THIS A REQUEST TO BOOT A STATION
	CAIN	T1,14		;IS THIS A REQUEST TO LOAD A STATION
	JRST	RQBOOT		;YES, GO LOAD THE BOOT STRAP ROUTINE
	POPJ	P,		;EXIT NO WAITING PROCESS
ICMCT0:	HLRZ	J,T4		;YES GET THE JOB NUMBER
IFN FTKI10!FTKL10,<
	PUSHJ	P,SVEUB##	;MAKE THE JOB ADDRESSABLE
>;END OF IFN FTKI10!FTKL10
IFN FTKA10,<
	MOVE	R,JBTADR##(J)	;GET THE RELOCATION
	ADDI	T4,(R)		;RELOCATE
>
	EXCTUX	<HLRZ	T3,3(T4)>	;GET THE BYTE COUNT
	MOVNS	T3		;NEGATE
	HRLZS	T3		;MAKE A COUNTER
	EXCTUX	<HRRZ	T4,3(T4)>;GET THE BUFFER ADDRESS
IFN FTKA10,<
	ADDI	T4,(R)		;RELOCATE
>
	HRLI	T4,(POINT 8)	;MAKE A BYTE POINTER
ICMCT1:	SOJL	P4,ICMCT5	;END OF MESSAGE
	ILDB	T1,P1		;GET A CHARACTER
	EXCTUU	<IDPB T1,T4>		;STORE THE CHARACTER
	AOBJN	T3,ICMCT1	;CONTINUE
ICMCT5:	HRRZ	T4,SCBCTL##(W)	;GET THE UUO ARG POINTER AGAIN
IFN FTKA10,<
	ADDI	T4,(R)		;RELOCATE
>
	EXCTUU	<HRLM	T3,3(T4)>;STORE THE STORED BYTE COUNT
	MOVEI	T1,(J)		;COPY THE JOB NUMBER
	PUSH	P,W		;SAVE THE NDB POINTER
	PUSHJ	P,WAKJOB##	;WAKE THE JOB
	POP	P,W		;RESTORE
	SETZM	SCBCTL##(W)	;CLEAR THE STATION CONTOL BUSY
	JRST	CPOPJ1##	;AND EXIT
SUBTTL RQBOOT - AUTO RELOAD OF A DAS80,81,82,DC72 REMOTE STATION

RQBOOT:	SKIPGE	DEBUGF##	;WAS THE MONITOR LOADED WITH DEBUG
	PJRST	CPOPJ1##	;YES, THEN NO AUTO DOWN LINE LOAD
	MOVEI	T1,ST.DDL	;GET DOWN LINE LOAD BIT
	TDNE	T1,STATES##	;IS SCHED SET?
	PJRST	CPOPJ1##	;YES, IGNORE THE REQUEST(WILL SEND AGAIN)
	HRRZ	T1,SCBRQB##(W)	;IS THERE A PENDING BOOT REQUEST?
	PJUMPN	T1,CPOPJ1##	;NON ZERO SAYS YES, IGNORE IT.
	PUSH	P,U		;SAVE THE PCB
	PUSHJ	P,GETLDB	;GET A LINE DATA BLOCK FOR THE FORCE COMMAND
	  PJRST	UPOPJ1##	;NONE AVAILABLE
	MOVEI	T2,(P4)		;GET THE NUMBER OF BYTES IN THE MESSAGE
	ADDI	T2,7		;ROUND UP (+ 1 WORD)
	LSH	T2,-2		;TO WORDS
	PUSH	P,T2		;SAVE THE SIZE
	PUSHJ	P,GETZWD	;ALLOCATE SPACE FOR THE MESSAGE
	  JRST	[POP	P,T2	;RESTORE THE SIZE
		JRST	UPOPJ1##];EXIT
	POP	P,T2		;RESTORE THE SIZE
	HRLM	T2,(T1)		;STORE THE SIZE
	HRLI	T1,^D10		;SET TIMER FOR NET2ND
	MOVEM	T1,SCBRQB##(W)	;STORE THE POINTER
	HRLI	T1,(POINT 8,0,35);MAKE A BYTE POINTER TO STORE THE MESSAGE
	SETZ	T3,		;CLEAR THE COUNTER
RQBOO1:	SOJL	P4,RQBOO3	;END OF MESSAGE
	ILDB	T2,P1		;GET NEXT CHARACTER
	IDPB	T2,T1		;STORE IN THE TEMP BUFFER
	AOJA	T3,RQBOO1	;COUNT AND CONTINUE
RQBOO3:	HRRZ	T1,SCBRQB##(W)	;GET THE ADDRESS BACK
	HRRM	T3,(T1)		;STORE THE CHARACTER COUNT
	PUSH	P,W		;SAVE W
	MOVEI	T1,TTFCXL##	;FORCE RUN THE AUTO LOADER
	PUSHJ	P,TTFORC##	;WHICH DOES THE BOOT
	PUSHJ	P,CLRTTY	;MAKE THE TTY AVAILABLE AGAIN
	POP	P,W		;RESTORE W
	PJRST	UPOPJ1##	;EXIT AND DISMISS THE MESSAGE
SUBTTL NCSIDC - DEVICE CONTROL FOR INPUT MESSAGES
;SUBROUTINE IDCCTL - DEVICE CONTROL MESSAGES
;CALL	MOVEI	U,PCB
;	MOVEI	W,NDB
;	MOVEI	T1,DLA
;	PUSHJ	P,IDCCTL
;RETURN	JRST	INPDIS

IDCCTL:				;ENTRY
;DLA
	CAIGE	T1,LATLEN##	;CHECK THE LENGTH OF THE LINK ADDRESS
	SKIPN	F,NETLAT##(T1)	;IS THE DDB DEFINED?
	PJSP	T1,INCTBD	;NO DLA IS ILLEGAL
	HRRZ	T2,DEVNET(F)	;CHECK TO MAKE SURE MESSAGE CAME FROM RIGHT NODE
	JUMPG	F,.+2		;SKIP IF A DEVICE
	HLRZ	T2,LDBREM##(F)	;LDB - NDB ADDR IS HERE
	CAIE	T2,(W)		;BETTER MATCH
	PJSP	T1,INCTBD	;NOPE, DONT LET MESSAGE BE PROCESSED
IFN FTCMSR,<
	MOVE	T1,PCBICT(U)	;GET MESSAGE LENGTH
	MOVEI	T1,-6(T1)	;DISCOUNT PROTOCOL
	CAIGE	T1,1_<DLHSIZ-1>	;IN RANGE FOR JFFO?
	JFFO	T1,.+2		;GET HIGHEST BIT NUMBER
	TDZA	T1,T1		;OUT OF RANGE, USE ENTRY 0
	MOVNI	T1,-^D36(T2)	;IN RANGE, PUT IN PROPER ORDER
	AOS	NCLRDL(T1)	;RECORD DATA LENGTH
>
	PUSH	P,F		;SAVE THE DDB ADDRESS/LDB
;CNT
DAPDSP:	MOVEI	P4,2		;ALLOW TWO BYTES COUNT
	MOVE	F,(P)		;RELOAD THE DDB ADDRESS
	PUSHJ	P,EBI2BI	;GET THE DATA COUNT
	JUMPE	T1,[POP	P,F	;RESTORE F
		JRST	INPDIS]	;END OF MESSAGE
	MOVEI	P4,(T1)		;KEEP THE DATA
;TYP
	PUSHJ	P,EBI2BI	;GET THE IDC TYPE FIELD
	CAIL	T1,0		;REALLY BAD
	CAILE	T1,DC.MAX	;CHECK THE RANGE
	JSP	T1,[POP P,F	;RESTORE F
		PJRST	INCTBD]	;DISMISS
	JUMPL	F,DAPDS2	;JUST DISPATCH IF TTY
	MOVSI	S,IOSCON	; DEVICE, SEE IF WE'RE COMPLETELY
	TDON	S,DEVIOS(F)	; CONNECTED YET/STILL
	JSP	T1,[POP P,F	;NOPE, DISCARD MESSAGE
		    PJRST INCTBD]
	SKIPA	T1,IDCTBL(T1)	;GET DEVICE DISPATCH
DAPDS2:	MOVE	T1,IDCTTY(T1)	;GET TTY DISPATCH
	PUSHJ	P,(T1)		;GO TO THE ROUTINE
	  JSP	T1,[POP P,F
		PJRST INCTBD]	;ILLEGAL MESSAGE
DAPDS1:	JUMPLE	P4,DAPDSP	;END OF MESSAGE?
	PUSHJ	P,EAS2SX	;NO, READ THE REMAINDER
	JRST	DAPDS1		;TRY FOR ANOTHER MESSAGE
IDCTBL:				;DISPATCH TABLE FOR DEVICE CONTROL
	JRST	CPOPJ##		;(0) ILLEGAL MESSGE
	JRST	IDCDAT		;(1) DATA WITHOUT END OF RECORD
	JRST	IDCDAR		;(2) DATA WITH END OF RECORD (MTA'S)
	JRST	IDCSTS		;(3) STATUS
	JRST	CPOPJ##		;(4) CONTROL MESSAGE - ONLY USED ON TTY'S NOW
	JRST	IDCUID		;(5) USER ID
	JRST	IDCFSP		;(6) FILE SPEC


;TTY DEVICE CONTROL DISPATCH TABLE

IDCTTY:
	JRST	CPOPJ##		;(0) ILLEGAL MESSGE
	JRST	TTYDAT		;(1) DATA WITHOUT END OF RECORD
	JRST	TTYDAR		;(2) DATA WITH END OF RECORD (MTA'S)
	JRST	TTYSTS		;(3) STATUS
	JRST	TTYCTL		;(4) CONTROL MESSAGE
	JRST	CPOPJ##		;(5) USER ID
	JRST	CPOPJ##		;(6) FILE SPEC
SUBTTL IDCDAT (1) DATA WITHOUT END OF RECORD
IDCDAT:

SUBTTL IDCDAR (2) DATA WITH END OF RECORD (MTA'S)
IDCDAR:	MOVEI	T1,NDPIDT##	;GET INPUT DATA INDEX
	HLRZ	T2,DEVNET##(F)	;GET NDT ADDRESS
	PUSHJ	P,@NDTNDP##(T2)	;CALL THE DEVICE ROUTINE
	AOS	(P)		;SKIP RETURN
	MOVEI	T1,DEPAIO	;NON, BLOCKING I/O
	TDNN	T1,DEVAIO(F)	;FOR THIS DEVICE
	PJRST	NETWAK		;NO, WAKE IT UP
	PUSH	P,DEVIOS(F)	;SAVE THE REAL DEVIOS
	MOVSI	S,IO		;GET THE DIRECTION BIT
	ANDCAB	S,DEVIOS(F)	;SET DIRECTION AS INPUT
	PUSHJ	P,SETIOD##	;SET IO DONE
	POP	P,DEVIOS(F)	;RESTORE THE REAL DEVIOS
	POPJ	P,		;RETURN
SUBTTL IDCSTS (3) STATUS
IDCSTS:	MOVEI	T1,NDPIST##	;GET STATUS INDEX
	HLRZ	T2,DEVNET##(F)	; AND NDT
	PJRST	@NDTNDP##(T2)	;GIVE TO SERVICE ROUTINE
SUBTTL IDCCMN (4) CONTROL MESSAGE
IDCCMN:
	POPJ	P,		;DISMISS THE MESSAGE
SUBTTL IDCUID (5) USER ID
IDCUID:
	POPJ	P,		;DISMISS THE MESSAGE

SUBTTL IDCFSP (6) FILE SPEC
IDCFSP:
	POPJ	P,		;DISMISS THE MESSAGE
;SUBROUTINE DAPHDR - WRITE A NCS/DEVICE CONTROL HEADER
;CALL	MOVEI	F,DDB
;	MOVEI	W,NDB
;	PUSHJ	P,DAPHDR
;RETURN	CPOPJ			;NO CORE
;	CPOPJ1		;T1=BYTEPOINTER OF THE COUNT FIELD


DAPHDR::TDZA	T1,T1		;CLEAR NCS NEADER BYTE
DAPHDI::MOVEI	T1,NCT.IT	;INTERRUPT MESSAGE
	PUSH	P,T1		;SAVE THE NCS HEADER FLAG
	PUSHJ	P,MAKPCB	;MAKE A PCB
	  PJRST	TPOPJ##		;RESTORE T1 AND EXIT
	POP	P,T1		;GET THE FLAGS BACK
	PUSHJ	P,NCSHDR	;WRITE A NCS HEADER
	  PJRST	RMVPCB		;REMOVE THE PCB
	LDB	T1,NETDLA##	;GET THE DESTINATION LINK ADDRESS
	PUSHJ	P,BI2EBI	;WRITE
	PJRST	CPOPJ1##	;EXIT DAP HDR WRITTEN

;SUBROUTINE DAPWRT - WRITE A DATA MESSAGE
;CALL	MOVEI	F,DDB
;	MOVEI	U,PCB
;	PUSHJ	P,DAPWRT	OR DAPWRC (FOR DATA COMPRESSION)

;RETURN	CPOPJ			;WRITEN

DAPWRB::MOVEI	T1,PCV.BN##	;BINARY MODE0
	JRST	DAPWR0		;CONTINUE
DAPWRT::TDZA	T1,T1		;ENTRY
DAPWRC::MOVEI	T1,PCV.LC##	;LINE PRINTER COMPRESSION
DAPWR0:	DPB	T1,PCBPCV##	;STORE TYPE
	MOVSI	T1,PCB.UR##	;GET THE USER DATA FLAG
	IORM	T1,PCBBLK##(U)	;STORE
	PJRST	NETWRT		;SEND THE MESSAGE

;SUBROUTINE DAPSST/DAPCST SET AND CLEAR STATUS BITS
;CALL	MOVEI	T1,BITS		;TO BE CLEARED OR SET
;	PUSHJ	P,DAPSST/DAPCST
;	CPOPJ			;NO CORE
;	CPOPJ1			;MESSAGE SENT

DAPSST::SKIPA	T2,[1]		;SET STATUS
DAPCST::MOVEI	T2,2		;CLEAR STATUS
	PUSHJ	P,SAVE3##	;SAVE THE P'S
	PUSH	P,T1		;SAVE STD
	PUSH	P,T2		;SAVE STC
	PUSHJ	P,DAPHDI	;WRITE INTERRUPT HEADER
	  JRST	[POP P,T2	;RESTORE THE MESSAGE TYPE
		PJRST	TPOPJ##]	;AND EXIT
;CNT
	SETZ	P3,		;CLEAR THE COUNT FIELD
	IBP	P2		;STEP OVER THE COUNT FIELD
	MOVE	P1,P2		;SAVE THE COUNT POSITION
	MOVEI	T1,DC.STS	;GET STATUS MESSAGE CODE
	PUSHJ	P,BI2EBI	;WRITE
;STC
	POP	P,T1		;GET THE STC
	PUSHJ	P,BI2EBI	;WRITE
;STD
	POP	P,T1		;GET THE STD
	PUSHJ	P,BI2EBI	;WRITE
;CNT
	DPB	P3,P1		;STORE THE COUNT FIELD
	AOS	PCBOCT##(U)	;UPDATE THE COUNT FIELD
	AOS	PCBOCT##(U)	;UPDATE THE COUNT FIELD
	ADDM	P3,PCBOCT##(U)	;UPDATE THE MESSAGE LENGTH
	PJRST	NETWSR		;WRITE THE MESSAGE
;SUBROUTINE DLYDRQ - DELAY A JOB FOR A DATA REQUEST
;CALL	MOVEI	F,DDB
;	MOVEI	W,NDB
;	PUSHJ	P,DLYDRQ
;RETURNS CPOPJ IF NONBLOCKING I/O
;RETURNS CPOPJ1 IF NORMAL I/O AFTER DATA REQUESTS ARRIVE
DLYDRQ::MOVEI	T1,DEPAIO	;GET NON BLOCKINT BIT
	TDNE	T1,DEVAIO(F)	;IS IT SET
	POPJ	P,		;YES,EXIT
	PUSHJ	P,NETHIB	;HIBERNATE
	JRST	CPOPJ1##	;SEE IF WE HAVE SOME NOW

;SUBROUTINE CHKDRQ - CHECK FOR A DATA REQUEST AND COUNT IT DOWN
;CALL	MOVEI	F,DDB
;	PUSHJ	P,CHKDRQ
;	  POPJ	P,		;NO DATA REQUEST ARE AVAILABLE
;	CPOPJ1			;DATA REQUEST AVAILABLE AND COUNTED DOWN

CHKDRQ::CONO	PI,PIOFF##	;RACE HERE - WE COULD LET NETDRQ GO NEGATIVE
	HRRZ	T1,NETDRQ##(F)	;GET THE OUTPUT DATA REQUEST COUNT
	JUMPE	T1,ONPOPJ##	;NO DATA REQUESTS AVAILABLE
	SOS	NETDRQ##(F)	;YES, REDUCE IT
	CONO	PI,PION##	;SAFE NOW
	JRST	CPOPJ1##	;SKIP RETURN


;SUBROUTINE SETUP - SET UP AC'S F,W,R,J
;CALL	PUSHJ	P,SETUP
;RETURN	CPOPJ

SETUP::			;ENTRY
	LDB	J,PJOBN##	;GET THE JOB NUMBER OF THE DEVICE
	MOVE	R,JBTADR##(J)	;GET THE RELOCATION
	HRRZ	W,DEVNET##(F)	;GET THE NODE DATA BLOCK POINTE
	MOVE	S,DEVIOS(F)	;GET IOS
	POPJ	P,		;RETURN
;SUBROUTINE ONLNDB/OFLNDB - TYPE ONLINE/OFFLINE FOR A NETWORK NODE
;CALL	MOVEI	W,NDB
;	PUSHJ	P,ONLNDB/OFLNDB
;RETURN	CPOPJ

ONLNDB:	SKIPA	T1,[[ASCIZ /	 ON-LINE
/]]
OFLNDB:	MOVEI	T1,[ASCIZ /	 OFF-LINE
/]
	SKIPGE	DEBUGF##	;CHECK FOR DEBUG
	POPJ	P,		;YES, SKIP THE MESSAGES
	PUSH	P,U
	PUSH	P,T1		;SAVE THE MODE
	HRRZ	U,OPRLDB##	;GET THE OPERATOR LINE
	PUSHJ	P,INLMES##	;TYPE %%
	ASCIZ	/
%%/
	PUSHJ	P,TYPNDB	;TYPE OUT THE NDB IFO
	POP	P,T1		;GET ONLINE/OFFLINE BACK
	PUSHJ	P,CONMES##	;TYPE IT
	PJRST	UPOPJ##		;EXIT
;SUBROUTIN TYPNDB - TYPE OUT THE NODE INFOR
;CALL	MOVEI	U,LDB
;	PUSHJ	P,TYPENDB
;RETURN	CPOPJ

TYPNDB::PUSHJ	P,INLMES##	;PRINT MESSAGE
	ASCIZ	/NODE	/
	HLRZ	T1,NDBSNM##(W)	;GET THE STATION NAME POINTER
	MOVE	T2,(T1)		;GET THE STATION NAME
	SKIPE	T1		;DEFINED YET
	PUSHJ	P,PRNAME##	;PRINT IT
	MOVEI	T3,"("		;PAREN
	PUSHJ	P,COMTYO##	;PRINT
	HLRZ	T1,NDBNNM##(W)	;GET THE NODE NUMBER
	PUSHJ	P,PRTDI8##	;TYPE
	PUSHJ	P,INLMES##	;TYPE A SEPERATOR
	ASCIZ	/) /
	HRRZ	T1,NDBSID##(W)	;GET THE MONITOR NAME
	SKIPE	T1		;SKIP IF UNKNOWN
	PUSHJ	P,CONMES##	;TYPE
	PUSHJ	P,PRSPC##	;SPACE
	HLRZ	T1,NDBSID##(W)	;GET THE CREATION DATE
	JUMPE	T1,CPOPJ##	;EXIT IF UNKNOWN
	PJRST	CONMES##	;TYPE
SUBTTL COMMON DEVICE DEPENDENT ROUTINES
;COME HERE ON THE RELEASE UUO.

NETRLS::MOVSI	S,IOSTBL+IOSERR+IOSHDV ;CLEAR TROUBLE FLAGS
	ANDCAM	S,DEVIOS(F)
	MOVSI	S,IOSCON	;IS DEVICE CONNECTED?
	TDNN	S,DEVIOS(F)
	POPJ	P,		;NO, NO MORE ACTION REQUIRED
	MOVSI	S,IOSREL	;YES, SET "RELEASE" BIT IN DEVIOS
	IORM	S,DEVIOS(F)
	POPJ	P,		;EXIT

NETHNG::MOVSI	S,IOSHDV	;HUNG BIT
	IORB	S,DEVIOS(F)	;STORE BIT
	PUSHJ	P,DEVERR##	;DEVICE ERROR
	PJRST	CPOPJ1##	;EXIT NO MESSAGE

NTDONL::TLNN	S,IOSERR+IOSHDV	;OFF LINE?
	AOS	(P)		;NO
	POPJ	P,		;RETURN

;SUBROUTINE NET$IN CHECK FOR INPUT READY
;CALL	MOVEI	F,DDB
;	PUSHJ	P,NET$IN
;RETURN	CPOPJ		;NO
;	CPOPJ1		;YES

NET$IN::CDR$IN::RDA$IN::	;ENTRY FROM MSGSER
	SKIPE	T1,NETDEV##(F)	;GET THE LOCATION OF THE MONITOR BUFFERS
	JRST	NET$I1		;NO BUFFER
	LDB 	T1,PBUFSZ##	;GET THE BUFFER SIZE
	HRLI	T1,2		;NUMBER OF BUFFERS
	PUSHJ	P,BLDMBF	;BUILD THE BUFFERS
	MOVE	T1,NETDEV##(F)	;LOAD THE POINTER TO THE MBF
NET$I1:	SKIPN	MBFBFC(T1)	;ANY DATA PENDING
	PJRST	DRQMBF		;SEND DATA REQUESTS
	JRST	CPOPJ1##	;YES, EXIT
SUBTTL	TELETYPE DEVICE-DEPENDENT CODE

;DISPATCH TABLE FOR TELETYPES:

REMDSP::JRST	D85TYP		;TYPE CHAR IN T3
	JRST	CPOPJ##		;MODEM CONTROL
	JRST	CPOPJ##		;ONCE A SECOND STUFF
	JRST	CPOPJ##		;INITIALIZE
	JRST	D85CHP		;CHANGE HARDWARE PARMS
	JRST	D85LPC		;LINE PARM CONTROL
	JRST	D85ELE		;SET TTY ELEMENT
	JRST	D85REM		;STUFF FOR REMOTE TTYS
	JRST	D85OFL		;IS THE LINE DEFINED ON THE STATION



;HERE TO CHECK FOR A LDB BEING ATTACHED TO A NODE
D85OFL:	HLRZ	T1,LDBREM##(U)	;GET THE NDB POINTER
	SKIPE	T1		;IS THERE A NDB
	AOS	(P)		;YES, SKIP RETURN
	POPJ	P,		;NO, NON-SKIP RETURN

D85ELE:					;CALL ON ELEMENT CHANGE FOR 2741
	PUSHJ	P,TTYCHK	;IS IT A CONNECTED TTY
	  PJRST	CPOPJ1##	;NO, DO NOT SET BITS
	PUSHJ	P,ELEINX##	;CONVERT TO AN INDEX
	  POPJ	P,		;ILLEGAL
	DPB	T2,LDPELE	;STORE THE ELEMENT NUMBER INDEX
D85EL1:	PUSH	P,U		;SAVE U
	PJRST	TTYSET		;SET PARAMETER CHANGE

D85LPC:				;LINE PARAMETER CHANGE
	CAIN	T3,<LPCUKB>B27	;UNLOCK KEYBOARD OR TTY INPUT WAIT
	PUSHJ	P,TTYCHK	;YES, SET IF A TTY
	  POPJ	P,		;NOT CONNECTED IGNORE
	MOVSI	T1,LRDTIW##	;TI WAIT BIT
	TDNE	T1,LDBREM##+2(U);IS IT ALREADY SET
	POPJ	P,		;YES, DO NOT SET IT AGAIN
	IORM	T1,LDBREM##+2(U);SET IT
	SOS	(P)		;TTYSET WILL POPJ1 MAKE IT A POPJ
	JRST	D85EL1		;COMMON EXIT
IFN FTMODM,<
;HERE FOR MODEM CONTROL FROM SCNSER
D85DSC::			;ENTRY
	PUSHJ	P,TTYCHK	;SEE IF A LEGAL TTY
	  JRST	ECOD4##		;NOT A TTY
	SKIPL	T2,LDBREM##+2(U);IS THIS A DATA SET LINE
	JRST	ECOD4##		;NO
	CAIN	T3,DSTSTS##	;STATUS?
	JRST	D85STS		;YES
	CAIN	T3,DSTOFF##	;MODEM OFF
	JRST	D85OFF		;YES,
	CAIN	T3,DSTON##	;MODEM ON
	JRST	D85ON		;YES
	CAIN	T3,DSTCRQ##	;REQUEST DIAL OUT
	JRST	D85CRQ		;YES
	JRST	ECOD3##		;NONE OF ABOVE


D85OFF:	PUSH	P,U		;FOR CALL TO DSCOFF
	JRST	DSCOFF		;HANG UP PHONE
D85ON:	MOVSI	T2,LRDDTR	;DATA TERMINAL READY
	IORM	T2,LDBREM##+2(U)	;SET IT
	JRST	D85EL1		;SEND IT
D85CRQ:				;AUTO DIAL
	MOVSI	T2,LRDADL##	;GET AUTO DIAL LINE BIT
	TDNN	T2,LDBREM##+2(U);IS THIS A AUTO DIAL LINE
	PJRST	ECOD4##		;NOPE FAIL
D85CR1:	SKIPN	DILLDB		;IS THE DIALER AVAILABLE
	JRST	D85CR2		;YES, CONTINUE
	MOVEI	T1,5		;NO
	PUSHJ	P,SLEEP##	;SLEEP FOR FIVE SCONDS
	JRST	D85CR1		;TRY AGAIN
D85CR2:	HRRZM	U,DILLDB	;STORE THE LDB OF THE REQUESTER
	HRLM	J,DILLDB	;STORE THE JOM NUMBER IN THE LEFT HALF
	PUSHJ	P,GETWRD##	;GET PART ONE OF THE NUMBER
	  PJRST	ECOD3##		;BAD ADDRESS
	MOVEM	T1,TELNUM	;STORE PART ONE
	AOS	M		;SECOND PART
	PUSHJ	P,GETWRD##	;GET SECOND PART
	  PJRST	ECOD3##		;ADDRESS CHECK
	TRO	T1,17		;FORCE AN END CHARACTER
	MOVEM	T1,TELNUM+1	;STORE PART TWO
	MOVEI	T2,LRRADL##	;GET AUTO DIAL REQUEST BIT
	PUSHJ	P,D85TY1	;SET IT AND CAUSE AN INTERRUPT
D85CR3:	MOVEI	T1,^D3		;WAIT FOR THREE SECONDS
	PUSHJ	P,SLEEP##	;AND THEN CHECK FOR S RESPONSE
	SKIPL	T1,DILLDB	;CHECK FOR A COMPLETED CALL
	JRST	D85CR3		;NO, WAIT AGAIN
	SETZM	DILLDB		;YES, MAKE THE DIALER AVAILABLE
	TLNE	T1,200000	;ERROR BIT UP
	JRST	CPOPJ1##	;NO, GOOD RETURN
	JRST	ECOD5##		;GIVE AN ERROR RETURN

D85STS:	MOVSI	T2,LRDDSR##	;CARRIER ON BIT
	TDNN	T2,LDBREM+2(U)	;IS IT?
	TDZA	T1,T1		;NO
	MOVSI	T1,DSCHWC##	;YES
	JRST	STOTC1##	;STORE ANSWER FOR USER
>	;END IFN FTMODM
;COME HERE FROM SCNSER WITH A CHARACTER TO OUTPUT IN T3.
;  U POINTS TO THE LDB.

D85TYP:	DPB	T3,[POINT 9,LDBREM##(U),35] ;SAVE CHAR
	PUSHJ	P,TTYCHK	;IS LDB ADDRESS VALID?
	  POPJ	P,		;NO, IGNORE.
	MOVE	T2,LDBREM##+1(U);GET THE STATUS BITS
	TRNE	T2,STY.DE	;IN DEFERRED ECHO
	JRST	D85TY3		;YES
	MOVE	T2,LDBDCH##(U)	;LOAD SCNSER FLAGS
	TLNN	T2,LDLECH##	;ANY ECHO BIT ON
	JRST	D85TY3		;NO
	MOVEI	T2,LRRCHP	;YES, GET PARAMETER CHANGE FLAG
	IORM	T2,LDBREM##(U)	;SET IT
D85TY3:	MOVE	T2,LDBREM##(U)	;GET THE STATUS AND CHARACTER
	TRCE	T2,LRRIMO##+1B27	;CHECK FOR A MODE CHANGE
	TRCN	T2,LRRIMO##+1B27	;BOTH IMAGE
	JRST	D85TY0		;NO CHANGE
	MOVEI	T2,LRRIMO##	;YES, FLIP THE BIT IN MEMORY
	XORM	T2,LDBREM##(U)	;FOR A CHANGE OF STATES
	MOVEI	T2,LRRCHP##	;GET CHANGE OF PARAMETERS BIT
	TROA	T2,LRRTTO##	;SET TTY OUTPUT
D85TY0:	MOVEI	T2,LRRTTO##	;ENTRY FOR NO MODE CHANGE
D85TY1:	IORM	T2,LDBREM##(U)	;IN LDB
D85RQS:	MOVSI	T2,.RMSUI##	;STATION NO LONGER IDLE
	IORM	T2,SCBSTS##(W)
	PUSHJ	P,NTYSET##	;SET THE TTY BUSY
	CONSZ	PI,NETIIP##	;AT INTERRUPT LEVEL
	POPJ	P,		;YES, ALL DONE.
	CONO	PI,PIOFF##	;TURN OFF THE PI SYS
	HRRZM	W,NETFLG	;SET THE SOFTWARE INTERRUPT FLAG
	CONO	PI,REQNET##+PI.ON	;REQUEST AN INTERRUPT
	SKIPE	NETFLG		;WAIT FOR IT TO HAPPEN
	JRST	.-1		;CONTINUE
	POPJ	P,		;ALL DONE NOW

;SUBROUTINE TO VALIDATE THE LDB ADDRESS IN U.
;  SKIP RETURN IF OK. (SCB ADDRESS IN T1)

TTYCHK:	EXCH	W,(P)		;MUST SAVE W AROUD THE CALL
	PUSH	P,[WPOPJX##]	;RETURN ADDRESS (WILL HANDLE SKIP RETURN)
	PUSH	P,W		;SAVE THE CALLER'S ADDRESS
	SKIPE	W,LDBREM##+4(U)	;IS THERE A SLA AND DLA
	HLRZ	W,LDBREM##(U)	;POINT TO SCB
	JUMPE	W,CPOPJ##	;EXIT IF NO STATION OR SLA DLA
	LDB	T2,LDPLNO##	;YES, GET PHYSICAL LINE NO.
	SUBI	T2,NETOFS##	;RELOCATE TO A REMOTE LINE
	JUMPL	T2,CPOPJ##	;NOR IN RANGE
	CAIG	T2,M.RTTY##	;CHECK LENGTH
	AOS	(P)		;OK
	POPJ	P,		;NO ERROR
;COME HERE ON SPECIAL CALLS FROM SCNSER

;CODE IN T3:
;1 = BUFFER LOW
;2 = CHARACTER NOT STORED
;3 = CONTROL O PROCESSING.

D85REM:	CAIL	T3,1		;VALIDATE RANGE
	CAILE	T3,3
	POPJ	P,		;IGNORE IF NOT IN RANGE
	JRST	@.(T3)		;OTHERWISE DISPATCH
	EXP	TTYBFL		;BUFFER LOW
	EXP	TTYCNS		;CHARACTER NOT STORED
	EXP	TTYCTO		;CONTROL O

;THESE ARE NO-OPS FOR NOW.

TTYBFL==CPOPJ1##	
TTYCNS==CPOPJ##

;COME HERE ON CONTROL O ACTION.  THE CONTROL O MAY HAVE BEEN
;  SET EITHER ON OR OFF.  CHECK THE LDB TO DETERMINE WHICH AND
;  SEND A CHARACTER GOBBLER IF IT HAS BEEN SET ON.

TTYCTO:	PUSHJ	P,TTYCHK	;YES, IS STATION OK?
	  POPJ	P,		;NO, IGNORE.
	MOVEI	T2,LRRSCG##	;YES, SEND CHAR GOBBLER
				; (SCB ADDRESS IN T1)
	PUSHJ	P,D85TY1	;REST SAME AS D85TYP.
TTYWAT:	MOVEI	T2,LRRTTO##	;CHECK FOR CHAR WAITING
	TRO	T2,LRRTTW##
	TDNN	T2,LDBREM##(U)	;ANY WAITING?
	POPJ	P,		;NO.
	ANDCAM	T2,LDBREM##(U)	;YES, DONT SEND IT
	PUSH	P,U		;SAVE LDB POINTER
	LDB	U,LDPLNO##	;GET LINE NUMBER
	PUSHJ	P,XMTINT##	;GIVE XMT INTERRUPT
	PJRST	UPOPJ##		;RETURN SCNSER/RMVNDB
;COME HERE ON LINE PARM CONTROL AND CHANGE HARDWARE PARMS.

D85CHP:
	PUSHJ	P,TTYCHK	;IS LDB ADDRESS VALID? (SET UP T1)
	  POPJ	P,		;NO, IGNORE CALL.
	MOVEI	T2,LRRCHP##	;YES, FLAG TO CHANGE PARMS
	IORM	T2,LDBREM##(U)	;LET NEXT REAL ACTIVITY TRY TO SEND
	POPJ	P,		;MESSAGE SINCE UUOLDB CALLS US SO OFTEN

NETINT::			;ENTRY FOR SOFTWARE INTERRUPT
	SKIPN	NETFLG		;FOR US
	JRST	NETINT		;NO CONTINUE DOWN THE SKIP CHAIN
	CONO	PI,CLRNET##	;CLEAR THE INTERRUPT
	JSR	NETSAV##	;YES, SAVE THE AC'S
	MOVEI	W,0		;GET A ZERO TO CLEAR THE FLAG
	EXCH	W,NETFLG	;LOAD THE NDB AND CLEAR THE FLAG
;	PJRST	SCNTTO		;SCAN THE TTY'S
;SUBROUTINE SCNTTO - ROUTINE TO OUTPUT TO A TTY
;CALL	MOVEI	W,NDB
;RETURN	CPOPJ

SCNTTO:	PUSHJ	P,NTYBSY##	;FIND A BUSY TTY
	  POPJ	P,		;NONE EXIT
	PUSH	P,U		;SAVE THE LDB
	PUSHJ	P,GETNBP##	;GET A BUFFER FROM THE POOL
	  JRST	UPOPJ##		;NONE THERE
	HRRZM	U,SCBNBP##(W)	;SAVE THE PCB POINTER
	SETZM	@PCBOAD(U)	;INDICATE THAT TTYHDR HASN'T BEEN CALLED YET
	MOVE	U,(P)		;RESTORE THE LDB
	PUSHJ	P,SCNTT7	;PROCESS IT
	  JFCL			;MAY SKIP RETURN
	HRRZ	U,SCBNBP##(W)	;GET THE PCB POINTER
	SKIPN	@PCBOAD##(U)	;ANYTHING IN THE BUFFER
	JRST	SCNTT3		;NOTHING IN THE BUFFER
	PUSHJ	P,NETWRT	;SEND THE MESSAGE
	JRST	SCNTT4		;COMMON EXIT
SCNTT2:	HRRZ	U,SCBNBP##(W)	;GET THE PCB POINTER
SCNTT3:	SETZM	PCBNDB##(U)	;CLEAR THE NDB POINT TO MAKE IT AVAILABLE
SCNTT4:	POP	P,U		;RESTORE THE LDB
	MOVEI	T1,LRRIDL##	;GET THE IDL/BUSY BITS AGAIN
	TDNN	T1,LDBREM##(U)	;STILL BUSY
	PUSHJ	P,NTYCLR##	;NO, CLEAR THE BUSY FLAG
	PUSHJ	P,NCSACK	;SEND AN ACK IF NECESSARY
	  POPJ	P,		;RETURN
	POPJ	P,		;RETURN
;COME HERE WITH LDB ADDRESS IN U WHEN OUTPUT IS FOUND.

SCNTT7:	PUSHJ	P,SAVE4##	;SAVE THE P'S
	MOVE	T1,LDBREM##(U)	;GET REMOTE STATION BITS
	TRNE	T1,LRRSCG##	;CHARACTER GOBBLER WANTED?
	PUSHJ	P,TTXGBL	;YES, GO SEND IT.
	MOVE	T1,LDBREM##(U)	;GET REMOTE STATION BITS
	TRNE	T1,LRRCHP##	;PARM CHANGE NEEDED?
	PUSHJ	P,TTYCHP	;YES, GO DO IT.
	MOVE	T1,LDBREM##(U)	;GET REMOTE STATION BITS
	TRNE	T1,LRRTTO##	;OUTPUT WAITING
	PUSHJ	P,TTXDAT	;SEND THE DATA
	MOVEI	T1,LRRADL##	;GET AUTO DIAL BIT
	TDNE	T1,LDBREM##(U)	;AUTO DIAL REQUEST
	PUSHJ	P,TTX801	;YES, SEND THE NUMBER
	MOVEI	T1,LRREPW##	;IS ECHO PIPELINE MARKER WAITING?
	TDNE	T1,LDBREM##(U)
	PUSHJ	P,TTYOKE	;IS IT OK TO LOCAL ECHO?
	  POPJ	P,		;NO.  CHECK NEXT LINE.
	PJRST	TTXEPM		;YES, SEND AN ECHO PIPE LINE MARKER
;COME HERE AT INTERRUPT LEVEL WHEN WE NEED TO CHANGE PARMS.
; LDB ADDRESS IN T2.

TTYCHP:	PUSHJ	P,SAVE1##	;SAVE THE P'S
TTYCH1:	SETZ	P1,		;LH = BITS TO SET, RH = CLEAR
	PUSHJ	P,TTYOKE	;CHECK ON ECHOING MODE
	  TLO	P1,STY.DE	;DEFER ECHO
	MOVE	T1,LDBDCH##(U)	;CHECK FOR LC TO UC INPUT XLATION
	TLNN	T1,LDLLCT##
	TROA	P1,STY.CV	;DONT TRANSLATE
	TLO	P1,STY.CV	;TRANSLATE
	SKIPL	LDBPAG##(U)	;OUTPUT STOPPED BY ^S?
	TROA	P1,STY.XS	;NO.
	TLO	P1,STY.XS	;YES.
	TLNN	T1,LDLIMI##	;IMAGE INPUT?
	TROA	P1,STY.II	;NO.
	TLO	P1,STY.II	;YES.
	MOVEI	T1,LRRIMO##	;IMAGE OUTPUT BIT
	TDNN	T1,LDBREM##(U)	;IMAGE OUTPUT?
	TROA	P1,STY.IO	;NO
	TLO	P1,STY.IO	;YES
	MOVE	T1,LDBPAG##(U)	;IS "TTY PAGE" IN EFFECT?
	TLNN	T1,LPLPAG##
	TROA	P1,STY.TP	;NO.
	TLO	P1,STY.TP	;YES.
	MOVE	T1,LDBBY2##(U)
	TLNN	T1,L2LTAP##	;CHECK "TTY TAPE" BIT
	TROA	P1,STY.TT	;NOT IN TTY TAPE MODE
	TLO	P1,STY.TT	;IN TTY TAPE MODE
	MOVE	T1,LDBDCH##(U)
	TLNN	T1,LDLTAB##	;HARDWARE TABS?
	TROA	P1,STY.HT	;NO.
	TLO	P1,STY.HT	;YES.
	TLNN	T1,LDLFRM##	;HDW FORM FEEDS
	TROA	P1,STY.FF	;NO
	TLO	P1,STY.FF	;YES
	TLNN	T1,LDLNFC##	;CHECK FOR FREE CR-LF
	TROA	P1,STY.CR	;YES
	TLO	P1,STY.CR	;NO
SUBTTL TTYDSC REMOTE DATA SET CONTOL FOR DAS80'S SERIES

	SKIPL	T1,LDBREM##+2(U);DATA SET LINE
	JRST	TTYCH4		;NO CONTINUE
	TLNE	T1,LRDDTR##	;CARRIER UP
	TLOA	P1,STY.DT	;YES
	TRO	P1,STY.DT+STY.RG  ;NO
TTYCH4:	TLNE	T1,LRDTIW##	;INPUT WAIT
	TLOA	P1,STY.TI	;YES
	TRO	P1,STY.TI	;NO
SUBTTL TTYSTS/TTYCHR STATUS AND CHARASTICS
	PUSH	P,P1		;SAVE STATUS SET & CLEAR BITS
	HLRZ	T1,0(P)		;BITS TO SET
	ANDCM	T1,LDBREM##+1(U) ;WILL ANY BITS REALLY BE SET?
	JUMPE	T1,TTYCH2	;NO, SKIP SET SECTION
	IORM	T1,LDBREM##+1(U)  ;REMEBER SO WE DON'T SEND AGAIN
	PUSHJ	P,TTXSST	;SET THE BITS TO SET
TTYCH2:	HRRZ	T1,0(P)		;GET BITS TO CLEAR
	AND	T1,LDBREM##+1(U) ;WILL ANY BITS ACTUALLY CLEAR?
	JUMPE	T1,TTYCH3	;NO, SKIP CLEAR CODE
	ANDCAM	T1,LDBREM##+1(U)  ;REMEMBER SO WE DON'T SEND AGAIN
	PUSHJ	P,TTXCST	;SEND THE BITS TO CLEAR
TTYCH3:	MOVEI	T1,LRRCHP##	;CLEAR PARM SEND BIT
	ANDCAM	T1,LDBREM##(U)
	POP	P,T1		;DISCARD BITS

;COME HERE TO SEND CHARACTERISTICS MESSAGE IF THE CHARACTERISTICS
;  HAVE CHANGED.

TTYCH6:	MOVSI	T1,400000	;BUILD ENCODED CHARASTICS
	LDB	T2,LDPFLC##	;GET FILL CLASS
	DPB	T2,[POINT 4,T1,35] ;BITS 35-32
	LDB	T2,LDPRSP##	;GET RECEIVE SPEED
	DPB	T2,[POINT 4,T1,31] ;BITS 31-28
	LDB	T2,LDPTSP##	;GET TRANSMIT SPEED
	DPB	T2,[POINT 4,T1,27] ;BITS 27-24
	LDB	T2,LDPWID##	;GET WIDTH
	DPB	T2,[POINT 8,T1,23] ;BITS 23-16
	LDB	T2,LDPACR##	;GET AUTO CRLF POINT
	DPB	T2,[POINT 8,T1,15] ;BITS 15-8
	LDB	T2,LDPELE##	;GET THE ELEMNET NUMBER
	DPB	T2,[POINT 4,T1,7] ;BITS 4-7
	MOVE	T2,LDBISR##(U)	;GET THE CONTROL BITS
	TLNE	T2,LILAPL##	;APL MODE
	TLO	T1,(1B3)	;YES
	TLNE	T2,LILDBK##	;DEBREAK
	TLO	T1,(1B2)	;YES
	TLNE	T2,LILTDY##	;TIDY?
	TLO	T1,(1B1)	;YES

;BIT 1 NOT USED

	EXCH	T1,LDBREM##+3(U) ;STORE NEW CHAR., GET OLD
	CAME	T1,LDBREM##+3(U) ;ANY CHANGE?
	PUSHJ	P,TTXTCR	;SEND TTY CHARASTICS
	  POPJ	P,		;NO ROOM, TRY LATER
	POPJ	P,		;LATER
SUBTTL NCS CONTROL MESSAGES
;COME HERE ON DATA REQUEST

TTYDRQ:	PUSH	P,U		;SAVE THE PCB
	MOVEI	U,(F)		;COP THE LDB POINTER
	LDB	T2,LDPDRQ##	;GET THE CURRRENT DATA REQUEST COUNT
	ADD	T2,T1		;FORM NEW SUM
	CAILE	T2,^D256	;UNREASONABLE?
	PJRST	UPOPJ##		;YES, IGNORE THE REQUEST
	DPB	T2,LDPDRQ##	;STORE THE NEW COUNT
	MOVEI	T1,LRRTTW##	;IS THIS TTY WAITING?
	TDNN	T1,LDBREM##(U)
	PJRST	UPOPJ1##	;NO, RETURN.
	ANDCAM	T1,LDBREM##(U)	;YES, CLEAR WAITING BIT
	MOVEI	T1,LRRTTO##	;AND SET OUTPUT BIT
	IORM	T1,LDBREM##(U)
	PUSHJ	P,D85RQS	;REQUEST WRVICE ON THE NODE
	JRST	UPOPJ1##	;THEN RETURN.
SUBTTL DAP CONTROL MESSAGES
TTYCTL:			;SET LDB FIELDS AS FROM "TTY" COMMAND.
	PUSH	P,U		;SAVE THE PCB
	MOVEI	U,(F)	;COPY THE LDB POINTER
;DCT
	PUSHJ	P,EBI2BI	;READ THE TYPE OF CONTROL
	CAIN	T1,DCT.EP	;ECHO PIPLINE
	JRST	TTYEPM		;YES
	CAIN	T1,DCT.CG	;CHARACTER GOBBLER
	JRST	TTYGBL		;YES,
	CAIN	T1,DCT.TC	;TTY CHARASTICS
	JRST	TTYCHR		;YES,
	CAIN	T1,DCT.AD	;AUTO DIAL
	JRST	TTYATO		;YES,
	JRST	UPOPJ##		;NONE OF THE ABOVE EXIT
;DISPATCH TABLE FOR CONTROL MESSAGES
TTYGBL:
TTYATO:
	PJRST	UPOPJ1##	;NOT IMPLEMENTED

;COME HERE FOR AN ECHO PIPELINE MARKER

TTYEPM:
;CDT
	ILDB	T1,P1		;GET THE SERIAL NUMBER
	SUBI	P4,1		;REDUCE THE COUNT
	DPB	T1,LDPEPM##	;STORE THE PIP LINE MARKER
	PUSHJ	P,TTYOKE	;OK TO ECHO (TEST THE LDB)?
	  JRST	TTYEP2		;NO, SEND EPM LATER.
	MOVEI	T2,LRREPW##	;RETURN MARKER AT ONCE
	PUSHJ	P,D85TY1	; SINCE DEFERRED ECHO NOT NEEDED
	JRST	UPOPJ1##
;COME HERE IF THE EPM CANNOT BE SENT RIGHT AWAY.

TTYEP2:	MOVEI	T1,LRREPW##	;MARK IT AS WAITING
	IORM	T1,LDBREM##(U)
	PJRST	UPOPJ1##	;EXIT
;COME HERE FOR CHARASTICS MESSAGE
TTYCHR:
;READ THE TIMES AND IGNORE
REPEAT 6,<
	PUSHJ	P,EBI2BI	;READ THE TIME
>
	PUSHJ	P,EBI2BI	;GET THE RECEIVE SPEED
	MOVEI	T2,(T1)		;COPY TO T2
	PUSHJ	P,TTCSP1##	;GET THE SPEED INDEX
	CAIA			;DON'T SAVE INVALID SPEED
	DPB	P2,LDPRSP##	;STORE
	PUSHJ	P,EBI2BI	;GET THE TRANSMIT SPEED
	MOVEI	T2,(T1)		;COPY THE SPEED
	PUSHJ	P,TTCSP1##	;GET THE SPEED INDEX
	CAIA			;DON'T SAVE INVALID SPEED
	DPB	P2,LDPTSP##	;STORE
	LDB	T2,LDPRSP##	;GET THE RECEIVE SPEED BACK
	MOVEI	T1,LDR274##	;GET 2741 BIT
	CAIN	T2,(P2)		;RECEIVE AND TRANSMITT THE SAME
	CAIE	T2,LS0134##	;IS IT AN IBM 2741
	SKIPA	T2,[ANDCAM T1,LDBDCH##(U)]	;CLEAR THE BIT
	MOVE	T2,[IORM T1,LDBDCH##(U)]	;SET THE BIT
	XCT	T2		;DO IT
	PUSHJ	P,EBI2BI	;WIDTH OF TTY CHARRIAGE
	SKIPE	T1
	DPB	T1,LDPWID##	;STORE
	PUSHJ	P,EBI2BI	;GET THE AUTO CRLF
	SKIPE	T1
	DPB	T1,LDPACR##	;STORE
	PUSHJ	P,EBI2BI	;READ THE ELEMENT #
	MOVE	T3,T1		;COPY TO T3
	PUSHJ	P,ELEINX##	;GET THE INDEX
	  SETZ	T2,		;ILLEGAL
	DPB	T2,LDPELE##	;STORE THE ELEMENT NUMBER
	PUSHJ	P,EBI2BI	;GET THE 2741 BITS
	MOVE	T2,LDBISR##(U)	;GET THE FLAGS
	TRNE	T1,CDT.PL	;APL
	TLOA	T2,LILAPL##	;YES, SET
	TLZ	T2,LILAPL##	;NO, CLEAR
	TRNE	T1,CDT.CB	;DEBREAK
	TLOA	T2,LILDBK##	;YES, SET
	TLZ	T2,LILDBK##	;NO, CLEAR
	TRNE	T1,CDT.TD	;TIDY MODE?
	TLOA	T2,LILTDY##	;YES, SET
	TLZ	T2,LILTDY##	;NO, CLEAR
	HLLM	T2,LDBISR##(U)	;STORE THE RESULT
	PJRST	TTYSET		;SET CHANGE OF PARAMETERS AND EXIT
;COME HERE FOR A TTY DATA MESSAGE.  SEND THE CHARACTERS
;  TO SCNSER.

TTYDAR:				;DATA WITH END OF RECORD
TTYDAT:	PUSH	P,U		;SAVE THE PCB
	MOVEI	U,(F)		;COP THE LDB POINTER
TTYDA1:	SOJL	P4,[PUSHJ P,NCSACK	;ACK THE MESSAGE
		PJRST	UPOPJ1##	;EXIT
		PJRST	UPOPJ1##]	;EXIT
	ILDB	T3,P1		;GET NEXT CHARACTER
	PUSH	P,U		;SAVE THE LINE DATA BLOCK
	LDB	U,LDPLNO##	;GET LINE NUMBER (LINTAB INDEX)
	PUSHJ	P,RECINT##	;PROCESS CHARACTER
	POP	P,U		;RESTORE PCB POINTER
	JRST	TTYDA1		;AND PROCESS NEXT CHAR, IF ANY.
;COME HERE FOR A STATUS MESSAGE

TTYSTS:	PUSH	P,U		;SAVE THE PCB
	MOVEI	U,(F)		;COP THE LDB POINTER
;STC
	PUSHJ	P,EBI2BI	;GET THE STATUS CODE
				;IGNORE FOR TTY'S
;STY
	PUSHJ	P,EBI2BI	;GET THE STATUS BITS
	HRRM	T1,LDBREM##+1(U) ;STORE STATUS BITS
	TRNN	T1,STY.DE	;DEFERED ECHO MODE?
	SKIPA	T2,[IORM T3,LDBREM##(U)] ;NO
	MOVE	T2,[ANDCAM T3,LDBREM##(U)] ;YES
	MOVEI	T3,LRRLEO##	;SET OR CLEAR LOCAL ECHO BIT
	XCT	T2
	MOVSI	T3,LRDTIW##	;GET THE INPUT WAIT BIT
	TRNE	T1,STY.TI	;STILL IN INPUT WAIT
	JRST	TTYTIW		;KEY BOARD STILL UN-LOCKED
	HLL	U,LDBDCH##(U)	;GET THE BITS
	SKIPE	LDBBKC##(U)	;ANY BREAK CHARACTER IN THE INPUT BUFFER
	JRST	TTYST1		;YES, IGNORE CLEAR
	TLNE	U,LDLCOM##	;AT COMMAND LEVEL
	JRST	TTYTIW		;YES, DON'T LOCK KEYBOARD
	SKIPGE	LDBDCH##(U)	;OR OUTPUT IN PROCESS
TTYST1:	ANDCAM	T3,LDBREM##+2(U);NO, UNLOCK THE KEYBOARD
TTYTIW:
IFN FTMODM,<
	SKIPL	T2,LDBREM##+2(U);DO WE KNOW IT AS A DATA SET LINE
	JRST	TTYSET		;NO, IGNORE THE DATA SET BITS
	MOVSI	T2,LRDDTR	;GET DATA SET READY
	TRNE	T1,STY.DT	;IS IT
	JRST	TTYST2		;YES
	TDNE	T2,LDBREM+2(U)	;IS THE BIT SET
	JRST	DSCOFF		;NO
	TRNN	T1,STY.RG		;IS RING UP
	JRST	TTYSET		;NO
	JRST	DSCRNG		;YES
TTYST2:	TDNE	T2,LDBREM##+2(U);CHECK FOR DATA TERMINAL READY
	JRST	TTYST3		;YES
	IORB	T2,LDBREM##+2(U);NO
	MOVSI	T2,LRDDSR##	;GET DATA SET READY
	ANDCAM	T2,LDBREM##+2(U);CLEAR IT
TTYST3:	TRNE	T1,STY.RG	;IS THERE RING
	JRST	DSCCRA		;
	JRST	TTYSET
DSCRNG:	MOVE	T2,STATES##	;NO, GET THE STATES WORD
	TRNE	T2,ST.NRL	;CHECK WCHEDULE FOR DATA SETS
	JRST	TTYSET		;DATA SETS NOT ALLOWED
	MOVSI	T2,LRDDTR##	;GET DATA TERMINAL READY
	IORM	T2,LDBREM##+2(U);SET THE STATUS
IFN FTPI,<
	MOVEI	T3,DSTRNG##	;DATA SET RING
	PUSHJ	P,DSCSG		;SIGNAL THAT
>
	JRST	TTYSET		;SET THE BITS
DSCCRA:				;CARRIER ON
	MOVSI	T2,LRDDSR##	;GET THE CARRIER ON BIT
	TDNE	T2,LDBREM##+2(U);SEEN BEFORE
	JRST	TTYSET		;YES
	PUSH	P,W		;SAVE W
	PUSHJ	P,TSETBI##	;CLEAR THE INPUT BUFFER
	HRRZ	T1,DILLDB	;GET THE DIALER LDB
	CAIE	T1,(U)		;DIAL REQUEST ON THIS LINE
	JRST	DSCCRB		;NO
	MOVSI	T2,600000	;GET BUSY AND ARROR FLAG
	IORM	T2,DILLDB	;YES, SET THE BUSY FLAGS
	JRST	DSCCRC		;CONTINUE
DSCCRB:	MOVEI	T1,TTFCXH##	;GET HELLO INDEX
	PUSHJ	P,TTFORC##	;FORCE THE COMMAND
DSCCRC:	MOVSI	T2,LRDDSR##	;GET DATA SET READY
	IORM	T2,LDBREM##+2(U);SET IT ON
IFN FTPI&FTMODM,<
	MOVEI	T3,DSTON##	;DATA SET ON
	PUSHJ	P,DSCSG		;SIGNAL THAT
>
	JRST	DSCPOW		;COMMON EXIT TO SET BITS
DSCOFF:
IFN FTPI&FTMODM,<
	MOVEI	T3,DSTOFF##	;DATA SET OFF
	PUSHJ	P,DSCSG		;SIGNAL THAT
>
DSCOF2:	HRRZ	T2,DILLDB	;GET THE AUTO DIAL LDB
	MOVSI	T3,400000	;GET THE INUSE BIT
	CAIN	T2,(U)		;THIS LINE
	IORM	T3,DILLDB	;SET IT
	PUSH	P,W		;SAVE W
	PUSHJ	P,RMVTTY	;DETACH THE TTY
DSCOF1:	MOVSI	T1,LRDCLR##	;CLEAR THE FLAGS
	ANDCAM	T1,LDBREM##+2(U);CLEAR IT
DSCPOW:	POP	P,W		;RESTORE W
>	;END IFN FTMODM
TTYSET:	MOVEI	T1,LRRCHP##	;SEND PARMS IF ANY DISAGREEMENT
	IORM	T1,LDBREM##(U)	;TO AVOID RACE CONDITION.
	PUSHJ	P,D85RQS	;CAUSE AN INTERRUPT
				;TO BE PENDING FOR THE STATUS
	PJRST	UPOPJ1##	;EXIT

IFN FTPI&FTMODM,<
DSCSG:	PUSH	P,T1
	PUSH	P,F
	PUSHJ	P,SIGDSC##	;SIGNAL DATA SET STATUS CHANGE
	POP	P,F
	JRST	TPOPJ##
>
;SUBROUTINE TO TEST THE LDB AND SKIP RETURN IF LOCAL
;  ECHOING SHOULD BE ALLOWED.
;LDB ADDRESS IN P3.

TTYOKE:	MOVE	T1,LDBREM##(U)	;GET REMOTE STATION BITS
	TRNN	T1,LRRTTO##	;OUTPUT IN PROGRESS?
	TRNE	T1,LRRTTW##	;OR WAITING?
	POPJ	P,		;YES, DONT SEND EPM.
	MOVE	T1,LDBBY2##(U)	;NO, GET MISC. TTY BITS
	SKIPL	LDBDCH##(U)	;HAS SCNSER OUTPUT TO DO?
	TLNE	T1,L2LDEL##	;NO, ARE WE IN RUBOUT SEQUENCE?
	POPJ	P,		;YES, DONT RETURN EPM.
	MOVE	T1,LDBDCH##(U)	;GET STATUS BITS
	TLNE	T1,LDLNEC##	;PROGRAM CONTROL
	POPJ	P,		;YES
	TLNN	T1,LDLLCP##	;"NO ECHOING" SPECIFIED?
	TLNE	T1,LDLBKA##	;OR BREAK ON ALL CHARS?
	POPJ	P,		;YES, DONT DO LOCAL ECHOING.
	JRST	CPOPJ1##	;OKAY IF -11 ECHOS.
;SUBROUTINE TTYTCR  SEND CHARACTERISTICS MESSAGE.
;CALL	MOVEI	U,LDB
;	PUSHJ	P,DTTYTCR
;RETURN	CPOPJ			;NO CORE
;	CPOPJ1			;MESSAGE SENT
TTXTCR:	PUSHJ	P,TTYHDI	;NO, SETUP INTERRUPT HEADER
;CNT
	PUSH	P,P2		;SAVE THE COUNT POSITION
;TYP
	MOVEI	T1,DC.CTL	;SET UP CONTROL MESSAGE
	PUSHJ	P,BI2EBI	;WRITE
;DCT
	MOVEI	T1,DCT.TC	;TELETYPE CHARASTICS
	PUSHJ	P,BI2EBI	;WRITE
;CDT
	LDB	T1,[POINT 2,LDBREM##+3(U),35] ;FILL CLASS
	MOVE	P1,FILTAB(T1)	;GET POINTER TO CONSTANTS
	MOVEI	T4,6		;COUNTER
TTYTC1:	ILDB	T1,P1		;GET FILL VALUE
	LDB	T2,[POINT 4,LDBREM##+3(U),27] ;XMIT SPEED
	MOVE	T2,LSPTAB##(T2)	;GET SPEED VALUE
	SKIPN	T2		;PRESENT?
	MOVEI	T2,^D110	;NO, ASSUME 110 BAUD.
	MOVEI	T3,^D10000	;COMPUTE BAUD RATE FACTOR
	CAIN	T2,^D110	;110 BAUD?
	MOVEI	T3,^D11000	;YES, ASSUME 11-UNIT CODE
	IMUL	T1,T3		;MULTIPLY BY FACTOR
	IDIV	T1,T2		;COMPUTE WAIT TIME IN MS.
	PUSHJ	P,BI2EBI	;WRITE
	SOJG	T4,TTYTC1	;DO FOR ALL SIX TIMES
	LDB	T1,[POINT 4,LDBREM##+3(U),31]
	MOVE	T1,LSPTAB##(T1)	;GET RECEIVE SPEED
	PUSHJ	P,BI2EBI	;WRITE
	LDB	T1,[POINT 4,LDBREM##+3(U),27]
	MOVE	T1,LSPTAB##(T1)	;GET TRANSMIT SPEED
	PUSHJ	P,BI2EBI	;WRITE
	LDB	T1,[POINT 8,LDBREM##+3(U),23]
	PUSHJ	P,BI2EBI	;WRITE
	LDB	T1,[POINT 8,LDBREM##+3(U),15]
	PUSHJ	P,BI2EBI	;WRITE
	LDB	T1,LDPELE##	;ELEMENT NUMBER NOT IMPLEMENTED
	MOVE	T1,ELETAB##(T1)	;GET THE VALUE FROM THE TABLE
	PUSHJ	P,BI2EBI	;WRITE
	MOVEI	T1,0		;IBM 2741 BITS
	MOVE	T2,LDBREM##+3(U);GET THE 2741 BITS
	TLNE	T2,(1B3)	;APL MODE
	TRO	T1,CDT.PL	;YES, SET THE BIT
	TLNE	T2,(1B2)	;DEBREAK FEATURE
	TRO	T1,CDT.CB	;YES, SET THE BIT
	TLNE	T2,(1B1)		;TIDY?
	TRO	T1,CDT.TD	;YES
	PUSHJ	P,BI2EBI	;WRITE
	PJRST	TTXUPD		;UPDATE THE COUNTERS
;TABLES FOR FILL.  THE TABLE ENTRIES ARE FOR BS, TAB, LF, VT,
;  FF AND CR FROM LEFT TO RIGHT, AND FILL 0-3 FROM TOP
;  TO BOTTOM.  THE VALUE OF THE ENTRY IS THE NUMBER OF FILL
;  CHARACTERS.  THIS IS CONVERTED TO MILLISECONDS BY DIVIDING
;  BY THE TRANSMIT SPEED OVER 1000.  SOMEDAY MAYBE THE USER
;  WILL BE ABLE TO SET THE TIMES DIRECTLY, BUT THIS METHOD
;  IS USED NOW FOR COMPATABLILTY WITH LOCAL FILLING, WHICH SENDS
;  RUBOUTS INSTEAD OF USING TIMEING.

FILTAB:	POINT 6,[BYTE (6) 0,0,0,0,00,0] ;CLASS 0
	POINT 6,[BYTE (6) 2,2,2,2,14,2] ;CLASS 1
	POINT 6,[BYTE (6) 6,0,6,6,25,4] ;CLASS 2
	POINT 6,[BYTE (6) 6,2,6,6,25,4] ;CLASS 3


;SUBROUTINE TTYSST/TTYCST SET AND CLEAR STATUS BITS
;CALL	MOVEI	T1,BITS		;TO BE CLEARED OR SET
;	PUSHJ	P,TTYSST/TTYCST
;	CPOPJ			;NO CORE
;	CPOPJ1			;MESSAGE SENT

TTXSST:	SKIPA	T2,[1]		;SET STATUS
TTXCST:	MOVEI	T2,2		;CLEAR STATUS
	PUSH	P,T1		;SAVE STD
	PUSH	P,T2		;SAVE STC
	PUSHJ	P,TTYHDI	;YES, WRITE INTERRUPT HEADER
	MOVE	P1,P2		;SAVE THE COUNT POSITION
	MOVEI	T1,DC.STS	;GET STATUS MESSAGE CODE
	PUSHJ	P,BI2EBI	;WRITE
;STC
	POP	P,T1		;GET THE STC
	PUSHJ	P,BI2EBI	;WRITE
;STD
	POP	P,T1		;GET THE STD
	PUSHJ	P,BI2EBI	;WRITE
;CNT
	DPB	P3,P1		;STORE THE COUNT FIELD
	PJRST	TTXUP1		;UPDATE THE COUNTS
;SUBROUTINE TTYCNT - CONNECT A TTY
;CALL	MOVEI	W,NDB
;	PUSHJ	P,TTYCNT
;RETURN	CPOPJ			;NO CORE
;	CPOPJ1			;CONNECT SENT

TTYCNT:				;ENTRY
	PUSHJ	P,SAVE3##	;SAVE THE P'S
	PUSHJ	P,SAVJW		;SAVE J AND W
	SKIPG	SCBTTY##(W)	;GET THE TTY CONFIGURATION BACK
IFN FTPI,<
	PJRST	PSINTC##
>
IFE FTPI,<
	POPJ	P,		;NO NEW TTY'S
>
	SOS	J,SCBTTY##(W)	;COUNT THIS TTY
	PUSH	P,U		;SAVE THE REQUESTING PCB
	MOVE	T1,J
	PUSHJ	P,GETLDB	;GET A FREE REMOTE LDB
	  PJRST	UPOPJ##		;NONE AVAILABLE
	JRST	TTYHCQ		;SKIP THE HOST ENTRY
TTYHCN:	PUSHJ	P,SAVE4		;SAVE CONNECT INITATE POINTER
	PUSH	P,U		;SAVE THE LDB FOR REMOTE CONNECT
TTYHCQ:	HLRZ	T1,J		;GET THE DLA IF ANY
	DPB	T1,LDPDLA##	;STORE DLA
	SETZ	F,		;CLEAR THE DDB POINTER
	PUSHJ	P,GETSLA	;GET A SOURCE LINK ADDRESS
	  JRST	[PUSHJ P,CLRTTY	;NONE AVAILABLE
		 PJRST UPOPJ##]
	MOVSI	T2,(1B0)	;GET A SIGN BIT
	HRRI	T2,(U)		;INSERT THE LDB ADDRESS
	MOVEM	T2,NETLAT##(T1)	;SET ON FOR A TTY
	DPB	T1,LDPSLA##	;STORE THE SOURCE LINK ADDRESS
	PUSH	P,U		;SAVE THE LDB
	PUSHJ	P,NCMHDR	;WRITE A HEADER
	  JRST	[POP	P,U	;NO CORE AVAILABLE
		 PUSHJ P,CLRTTY	;FREE THE LDB
		 PJRST UPOPJ##]
	EXCH	U,(P)		;SAVE THE PDB AND GET THE LDB
	PUSH	P,P2		;SAVE THE COUNT POSITION
;TYP
	MOVEI	T1,NC.CNT	;GET CONNECT TYPE
	PUSHJ	P,BI2EBI	;SEND
;DLA
	LDB	T1,LDPDLA##	;GET THE DESTINATION ADDRESS
	PUSHJ	P,BI2EBI	;SEND
;SLA
	LDB	T1,LDPSLA##	;GET THE SLA
	PUSHJ	P,BI2EBI	;SEND (FROM THE NETLAT INDEX)
;DPN
	MOVEI	T1,OBJ.TY	;DESTINATION DEVICE IS A TTY
	PUSHJ	P,BI2EBI	;SEND
;NAME
	LDB	T1,LDPRLN##	;GE THE REMOTE PHYSICAL LINE NUMBER
	PUSHJ	P,BI2EBI	;SEND
;SPN
	MOVEI	T1,OBJ.TT	;FROM THE TTY HANDLER
	PUSHJ	P,BI2EBI	;SEND
;NAME
	MOVE	T1,[SIXBIT/NETSER/]
	PUSHJ	P,SX2EAS	;SEND
;MML
	LDB	T1,NDBMML##	;GET THE MESSAGE LENGTH
	PUSHJ	P,BI2EBI	;SEND
;FEA
;DCM
	MOVEI	T1,DCM.AS	;ASCII MODE
	PUSHJ	P,BI2EBI	;SEND
;RNL
	MOVEI	T1,^D80		;EIGHTY CHARACTER RECORDS
	PUSHJ	P,BI2EBI	;SEND
;DTY
	MOVEI	T1,DTY.MC!DTY.AB!DTY.SB!DTY.27	;ATTRIBUTES
	PUSHJ	P,BI2EBI	;SEND
;CNT
	POP	P,T1		;GET THE COUNT POSITION BACK
	DPB	P3,T1		;STORE THE COUNT
	POP	P,U		;GET THE PCB POINTER BACK
	ADDM	P3,PCBOCT##(U)	;STORE THE MESSGE LENGTH
	PUSHJ	P,NETWRT	;SEND THE MESSAGE
	PJRST	UPOPJ1##	;RESTORE THE PCB AND EXIT

;SUBROUTINE DSCTTY - DISCONNECT A TTY
;CALL	MOVEI	T1,DLA
;	PUSHJ	P,DSCTTY
;RETURN	CPOPJ

DSCTTY:
	PUSH	P,U		;SAVE THE PDB
	MOVEI	U,(F)		;COPY THE LDB POINTER
	PUSHJ	P,CLRTTY	;CLEAR THE LDB
	PUSHJ	P,TTYCNT	;TRY FOR ANOTHER TTY
	  JRST	UPOPJ1##	;EXIT
	JRST	UPOPJ1##	;EXIT

CLRTTY:	LDB	T1,LDPSLA	;WERE WE CONNECTED?
	JUMPE	T1,CLRTY1	;NO, DON'T TOUCH SCBOPR OR NETLAT
	LDB	T2,LDPRLN##	;GET THE REMOVE LINE NUMBER
	CAIN	T2,0		;IS THIS AN OPR LINE
	HLLZS	SCBOPR##(W)	;YES, CLEAR THE OPR POINTER
	SETZM	NETLAT##(T1)	;CLEAR THE POINTER
CLRTY1:	PUSHJ	P,NTYCLR##	;FORCE TTY TO BE IDLE
	SETZM	LDBREM##(U)	;CLEAR THE SCB POINTER
	POPJ	P,		;EXIT
;SUBROUTINE TTYCNX - CONNECT TTY CONFIRM MESSAGE
TTYCNX:				;ENTRY FROM ICMCNT
	PUSH	P,U		;SAVE THE PCB
	MOVEI	U,(F)		;GET THE LDB POINTER
;SLA
	PUSHJ	P,EBI2BI	;GET THE SOURCE NODE ADDRESS
	DPB	T1,LDPDLA##	;STORE AS THE DESTINATION LINK
;DPN
	PUSHJ	P,EBI2BI	;SKIP THE OBJECT TYPE
;PID
	PUSHJ	P,EBI2BI	;IGNORE THE NAME
;SPN
	PUSHJ	P,EBI2BI	;GET THE OBJECT TYPE
;PID
	PUSHJ	P,EBI2BI	;GET THE PID
	CAIA			;SKIP THE HOST ENTRY
TTYHCX:	PUSH	P,U		;SAVE THE LDB
	DPB	T1,LDPRLN##	;GET THE REMOTE LINE NUMBER
	CAIN	T1,0		;OPERATOR LINE
	HRRM	U,SCBOPR##(W)	;YES, MAKE HIM THE OPR
;MML
	PUSHJ	P,EBI2BI	;IGNORE THE LENGTH
;FEA
;DCM
	PUSHJ	P,EBI2BI	;IGNORE
;RLN
	PUSHJ	P,EBI2BI	;IGNORE
;DVT
	PUSHJ	P,EBI2BI	;GET THE FEATURES
	TRNN	T1,DTY.MC	;MODEM CONTROL ON THIS LINE
	TDZA	T2,T2		;NON-DATA SET
	MOVSI	T2,LRDDSL##	;DATA SET LINE
	TRNE	T1,DTY.AD	;AUTO DIAL LINE (BELL 801)
	TLO	T2,LRDADL##	;YES, SET BIT
	TRNE	T1,DTY.AB	;AUTO BAULD LINE
	TLO	T2,LRDATO##	;YES, SET THE BIT
	TRNE	T1,DTY.27	;IBM 2741
	TLO	T2,LRD741##	;YES, SET THE BIT
	HLLM	T2,LDBREM##+2(U);STORE THE BITS
	JUMPL	T2,TTYCNY	;JUMP ON DATA SET
	LDB	T2,LDPLNO##	;GET LINE NUMBER
	MOVE	T2,LINTAB##(T2)	;GET WORD WITH TTVINI IN IT
	MOVEI	T1,TTFCXR##	;PRINT GREETING ON THE TTY
	TLNE	T2,TTVINI##	;MONGEN WANTS INITIA RUN
	MOVEI	T1,TTFCXI##	;YES
	PUSHJ	P,TTFORC##	;NO, FORCE THE COMMAND
TTYCNY:	MOVEI	T1,LRRCHP##	;CHARASTICS CHANGE BIT
	IORM	T1,LDBREM##(U)	;STORE
	PUSHJ	P,TTYCNT	;TRY FOR ANOTHER CONNECT
	  JRST	UPOPJ1##	;FAILED FOR ANOTHER
	JRST	UPOPJ1##	;WON ANOTHER TTY
TTYCNZ:			;ENTRY FROM ICMCNN ON A CONNECT
;T1=OBJ T2=SLA
	MOVEI	T1,ST.NRT	;IS SYSTEM STANDALONE?
	TDNE	T1,STATES##	;IF SO TTY WILL BE LOST
	JRST	TTYOT		;STANDALONE
	PUSHJ	P,SAVJW		;SAVE THE FEK AND NDB
	PUSH	P,T2		;SAVE THE SLA
;PID
	PUSHJ	P,EAS2SX	;SKIP THE NAME
;PID
	PUSHJ	P,EBI2BI	;READ THE SOURCE OBJECT TYPE
	CAIE	T1,OBJ.TY	;IS IT A TTY
	JRST	T2POPJ##	;NO, ILLEGAL
	PUSHJ	P,EBI2BI	;READ THE REMOTE LINE NUMBER
	MOVEI	J,(T1)		;COPY TO J
	POP	P,T2		;RESTORE THE SLA
	HRLI	J,(T2)		;PUT IN THE LEFT HALF
	PUSHJ	P,GETLDB	;GET A LINE DATA BLOCK
	  POPJ	P,		;CAN'T N0NE AVAILABLE
	PUSHJ	P,TTYHCN	;SEND A CONNECT CONFIRM
	  POPJ	P,		;CAN'T  ICMCNN WILL REJECT
	MOVEI	T1,(J)		;GET THE LINE NUMBER
	PJRST	TTYHCX		;READ THE REST ON THE MESSAGE

TTYOTP:	POP	P,T2		;CLEANUP STACK
TTYOT:	SKIPA	T2,[RSN.OT]	;SAY NOT AVAILABLE
TTYXN:	MOVEI	T2,RSN.XN	;SAY CAPACITY EXCEEDED
	POPJ	P,		;LET ICMCNN SEND DISCONNECT
;SUBROUTINE GETLDB - SEARCH FOR A FREE TTYDDB/LDB
;CALL	PUSHJ	P,GETLDB
;RETURN	CPOPJ				;NO TTY'S FREE
;	CPOPJ1			;FOUND A FREE LDB/DDB U=LDB

GETLDB:				;ENTRY
	PUSH	P,T1		;SAVE THE PHYSICAL UNIT NUMBER
	MOVE	T4,NETRTY##	;GET THE POINTER TO THE REMOTE TTY'S
GETLD1:	MOVE	U,LINTAB##(T4)	;GET THE LDB POINTER
	MOVEI	T1,LDRREM##	;GET REMOTE TTY LINE BIT
	TDNN	T1,LDBDCH##(U)	;IS THIS A REMOTE LINE
	JRST	GETLD9		;NO SKIP THE LINE
	HLRZ	T1,LDBREM##(U)	;GET THE STATION POINTER
	JUMPN	T1,GETLD9	;ALREADY ASSIGNED
	HRLZM	W,LDBREM##(U)	;NO, ASSIGN TO THIS STATION
	SETZM	LDBREM##+1(U)	;CLEAR THE BLOCK
	SETZM	LDBREM##+2(U)	;..
	SETZM	LDBREM##+3(U)	;..
	SETZM	LDBREM##+4(U)	;..
	POP	P,T1		;RESTOE THE REMOTE LINE NUMBER
	DPB	T1,LDPRLN##	;STORE IN THE LDB
	PUSH	P,T4		;SAVE THE LINTAB INDEX
	PUSHJ	P,LDBINI##	;INITIALIZE THE LDB
	MOVSI	T1,777740	;CLEAR THE BAUD SPEED AND FLAGS
	ANDCAM	T1,LDBISR##(U)	;IN THE LDB
	HRL	U,(P)		;PUT THE PHYSICAL -10 LINE IN THE LEFT
	PJRST	TPOPJ1##	;EXIT U=LDB
GETLD9:	AOBJN	T4,GETLD1	;CONTINUE
	PJRST	TPOPJ##		;RESTORE THE UNIT NUMBER AND EXIT

;SUBROUTINE RMVTTY - DETACH A TTY FROM THE JOB
;CALL	MOVEI	U,LDB
;	PUSHJ	P,RMVTTY
;RETURN	CPOPJ

RMVTTY:	PUSHJ	P,SAVT##	;SAVE THE TEMP
	PUSHJ	P,SAVJW		;SAVE F,W
	PUSH	P,F		;SAVE F
	HRRZ	F,LDBDDB##(U)	;GET THE DDB
	JUMPE	F,RMVTT3	;EXIT IF NO DDB
	LDB	J,PJOBN##	;GET THE JOB NUMBER
	MOVE	T1,DEVMOD(F)	;CHARACTERISTICS
	TLNE	T1,TTYATC	;CONSOLE TTY?
	JRST	RMVTT1		;YES, DETACH IT
	MOVEI	S,IOIMPM!IODERR!IODTER!IOBKTL  ;ERROR BITS
	IORB	S,DEVIOS(F)	;LITE THEM FOR THE OWNER OF THIS TTY
	JRST	RMVTT2		;DON'T DETACH TTY BEING USED AS AN I/O DEVICE
RMVTT1:	PUSHJ	P,TTYDET##	;CALL SCNSER
RMVTT2:
IFN FTPI,<
	PUSHJ	P,PSIDWN##	;SIGNAL DEVICE DOWN
>
RMVTT3:	PUSHJ	P,LDBCLR##	;CLEAR BITS THAT 10 BELIEVES ARE TRUE
	PUSHJ	P,TSETBO##	;THROW AWAY STUFF IN CHUNKS
	JRST	FPOPJ##		;EXIT
;SUBROUTINE TTXEPM - SEND AN ECHO PIPE LINE MARKER
;CALL	MOVEI	U,LDB
;	PUSHJ	P,TTXEPM
;RETURN	CPOPJ			;NO CORE
;	CPOPJ1			;MESSAGE SENT

TTXEPM:
	PUSHJ	P,TTYHDI	;NO, SEND A TTY HEADER
;CNT
	PUSH	P,P2		;SAVE THE POSITION
;TYP
	MOVEI	T1,DC.CTL	;CONTROL MESSAGE
	PUSHJ	P,BI2EBI	;SEND

;DCT
	MOVEI	T1,DCT.EP	;PIPE LINE MARKER FLAG
	PUSHJ	P,BI2EBI	;SEND

;CDT
	LDB	T1,LDPEPM##	;GET THE PIP LINE MARKER
	PUSHJ	P,DPBBIN	;SEND
;CNT

	MOVEI	T1,LRREPW##	;EPM NO LONGER WAITING
	ANDCAM	T1,LDBREM##(U)	;CLEAR
	PJRST	TTXUPD		;UPDATE THE COUNT

;SUBROUTINE TTXGBL - SEND A CHARACTER GOBBLER
;CALL	PUSHJ P,TTXGBL
;RETURN	CPOPJ		;MESSAGE SENT

TTXGBL:			;ENTRY
	PUSHJ	P,TTYHDI	;NO, SEND A HEADER
;CNT
	MOVEI	T1,2		;TWO CHARACTER MESSAGE
	DPB	T1,P2		;STORE THE COUNT
;TYP
	MOVEI	T1,DC.CTL	;TELETYPE CONTROL MESSAGE
	PUSHJ	P,BI2EBI	;SEND
;DCT
	MOVEI	T1,DCT.CG	;CHARACTER GOBLER CODE
	PUSHJ	P,BI2EBI	;SEND
	MOVEI	T1,LRRSCG##	;CHARACTER GOBBLER BIT
	ANDCAM	T1,LDBREM##(U)	;CLEAR IT
	PJRST	TTXUP1		;UPDATE THE COUNTS AND EXIT
;SUBROUTINE TTX801 - SEND A AUTO DIAL MESSAGE TO THE REMOTE DN80
;CALL	MOVEI	U,LDB
;	PUSHJ	P,TTX801
;RETURN	CPOPJ			;NO CORE
;	CPOPJ1			;MESSAGE SENT

TTX801:				;ENTRY
	PUSHJ	P,TTYHDI	;SET UP AN INTERRUPT HEADER
;CNT
	PUSH	P,P2		;SAVE THE COUNT POSITION
;TYP
	MOVEI	T1,DC.CTL	;CONTROL MESSAGE
	PUSHJ	P,BI2EBI	;SEND
;DCT
	MOVEI	T1,DCT.AD	;AUTO DIAL CODE
	PUSHJ	P,BI2EBI	;SEND
;CDT
	MOVE	T4,[POINT 4,TELNUM]	;GET THE POINTER TO THE PHONE NUMBER
TTX802:	ILDB	T1,T4		;GET A DIGIT
	ADDI	T1,"0"+200	;MAKE EXTENSIBLE ASCII
	IDPB	T1,P2		;STORE IN THE MESSAGE
	CAIE	T1,17+"0"+200 	;IS IT THE END
	AOJA	P3,TTX802	;COUNT THE CHARACTER
	ADDI	P3,1		;COUNT THE LAST BYTE
	TRZ	T1,200		;CLEAR THE CONTINUE BIT
	DPB	T1,P2		;RESTORE IT
	HRRZ	U,DILLDB	;GET THE LDB FOR THE DIAL
	MOVSI	T1,LRDDTR##	;GET DATA TERMONAL READY
	IORM	T1,LDBREM##+2(U);SET IT ON
	MOVEI	T1,LRRADL##	;GET THE AUTO DIAL BIT
	ANDCAM	T1,LDBREM##(U)	;CLEAR THE REQUEST
	JRST	TTXUPD		;UPDATE THE COUNT AND EXIT
;SUBROUTINE TTXDAT - SEND A DATA MESSAGE
;CALL	PUSHJ	P,TTXDAT
;RETURN	CPOPJ			;MESSAGE APPENDED TO OUTPUT

TTXDAT:				;ENTRY
	LDB	T1,LDPDRQ##	 ;GET DATA REQUEST COUNT
	JUMPE	T1,TTXDA3	;NO MORE, DELAY CHARACTER.
	SUBI	T1,1		;REDUCE THE COUNT
	DPB	T1,LDPDRQ##	 ;STORE THE NEW COUNT
;CNT
	PUSHJ	P,TTYHDR	;SEND A HEADER
	PUSH	P,P2		;SAVE THE COUNT POS
;TYP
	MOVEI	T1,DC.DAT	;GET THE DAP CODE
	PUSHJ	P,BI2EBI	;SEND
;DAT
	PUSH	P,W		;SAVE W PSISER IS BOUND TO DISTROY IT
TTXDA1:	LDB	T1,[POINT 8,LDBREM##(U),35]
	IDPB	T1,P2		;ADD CHARACTER TO STRING
	ADDI	P3,1		;INCREMENT STRING LENGTH
	MOVEI	T1,LRRTTO##	;CLEAR OUTPUT BIT
	ANDCAM	T1,LDBREM##(U)
	PUSH	P,U		;SAVE LDB ADDRESS
	LDB	U,LDPLNO##	;BY SIGNALING AN XMT INTERRUPT
	PUSHJ	P,XMTINT##	;TO SCNSER
	POP	P,U		;RESTORE REGISTERS CLOBBERED BY
	CAIL	P3,NBPBFL##	;ANY ROOM IN MONITOR BUFFER?
	JRST	TTXDA4		;NO.
	MOVEI	T1,LRRSCG##	;SCNSER WANT A CHARACTER GOBBLER
	TRO	T1,LRRCHP##	;OR PARAMETER CHANGE
	TDNE	T1,LDBREM##(U)	;
	JRST	TTXDA4		;YES EXIT
	MOVEI	T1,LRRTTO##	;NO, IS ANOTHER CHAR WAITING?
	TDNE	T1,LDBREM##(U)
	JRST	TTXDA1		;YES, APPEND IT TO STRING.
	MOVEI	T1,LRREPW##	;TRY TO SEND AN ECHO PIPELINE MARKER
	IORM	T1,LDBREM##(U)	;  TO LET THE REMOTE ECHO
TTXDA4:	POP	P,W		;RESTORE W
	HRRZ	T1,SCBNBP##(W)	;GE THE PCB POINTER
	MOVSI	T2,(<NCT.IT>B7)	;GET THE INTERRUPT BIT
	ANDCAM	T2,@PCBOAD##(T1);CLEAR IT (COUNTS DATA REQ.)
TTXUPD:	POP	P,T1		;GET THE COUNT POSITION
	DPB	P3,T1		;STORE THE COUNT
TTXUP1:	HRRZ	T1,SCBNBP##(W)	;GET THE PDB POINTER
	ADDM	P3,PCBOCT##(T1)	;UPDATE THE PCB
	IBP	P2		;SKIP THE NEW COUNT FIELD
	SETZ	P3,		;CLEAR THE CURRENT COUNT
	AOS	PCBOCT##(T1)	;COUNT THE COUNT FILED
	POPJ	P,		;RETURN
;COME HERE IF DATA REQUESTS ARE DEPLETED.

TTXDA3:	MOVEI	T1,LRRTTW##	;SET WAITING FOR DATA REQUEST
	IORM	T1,LDBREM##(U)	;IN THE LDB
	MOVEI	T1,LRRTTO##	;CLEAR THE OUTPUT WAITING
	ANDCAM	T1,LDBREM##(U)	;IN THE LDB
	POPJ	P,		;RETURN
;SUBROUTINE TTYHDR - MAKE A PCB FOR TTY OUTPUT
;CALL	PUSHJ	P,TTYHDR
;RETURN	CPOPJ		;U=PCB

TTYHDR:	TDZA	P1,P1		;NORMAL MESSAGE REDUCE DATA REQUEST
TTYHDI:	MOVEI	P1,NCT.IT	;INTERRUPT MESSAGE
	PUSH	P,U		;SAVE THE LINE DATA BLOCK
	HRRZ	U,SCBNBP##(W)	;POINT THETHE TTY PCB
	SKIPE	@PCBOAD##(U)	;WAS THE HEADER WRITTEN
	JRST	UPOPJ##		;YES
	MOVE	P2,PCBOAD##(U)	;NO, LOAD THE OUTPUT BYTE POINTER
	SETZM	PCBOCT##(U)	;CLEAR THE COUNT FIELD
	PUSHJ	P,NCSTTY	;WRITE THE NCS HEADER
	  JFCL			;CAN'T FAIL
	EXCH	U,(P)		;GET THE LDB BACK
	LDB	T1,LDPDLA##	;GET THE DESTINATION ADDRESS
	SETZ	P3,		;CLEAR THE COUNT
	PUSHJ	P,BI2EBI	;SEND
	POP	P,T1		;GET THE PCB
	ADDM	P3,PCBOCT##(T1)	;COUNT THE DLA
	SETZ	P3,		;CLEAR THE COUNT FIELD
	IBP	P2		;SKIP THE <CNT> FIELD
	POPJ	P,		;EXIT
SUBTTL HOST.U - SET HOST UUO TO SWITCH BETWEEN COMMAND DECODERS
HOST.U::			;ENTRY FROM COMCON ON SET HOST UUO
	PUSHJ	P,SAVE4##	;SAVE THE P'S
IFN FTMS,<
	PUSHJ	P,ONCPU0##	;GET TO CPU 0
>
	HRR	M,T2		;LOC OF ARGUMENT
	PUSHJ	P,GETWDU##	;GET ARG
	SKIPE	P2,T1		;COPY THE ARG
	PUSHJ	P,SRCNDB	;FIND THE NODE
	  POPJ	P,		;NO SUCH NODE
	LDB	T1,NETCNF##	;SEE IF A MCR
	JUMPE	T1,CPOPJ##	;NOPE
	PUSHJ	P,TTYSRC##	;FIND THE USER'S TTY IF ANY
	  POPJ	P,		;NONE
	PUSHJ	P,TTYCHK	;CHECK FOR A NETWORK TTY
	  POPJ	P,		;NOT LEGAL ON LOCAL TTY'S
	AOS	(P)		;SET SKIP RETURN
	JRST	HOSTDT		;GO DETACH THE TTY
SUBTTL HOST.C - SET HOST COMMAND TO SWITCH BETWEEN COMMAND DECODERS
HOST.C::
	PUSHJ	P,TTYCHK	;CHECK FOR A REMOTE NODE TTY
	  JRST	[MOVEI T1,[ASCIZ /DECsystem-10 TTY's can not be switched via HOST/]
		PJRST	ERRMES##];TYPE AND EXIT
	SKIPN	JBTADR##(J)	;ANY CORE ASSIGNED
	PUSHJ	P,GETMIN##	;NO, ALLOCATE SOME
	JUMPE	R,DLYCM##	;NO, DELAY THE COMMAND
	PUSHJ	P,SAVCTX##	;SAVE THE CONTEXT
	PUSHJ	P,SAVE4##	;SAVE THE P'S
	PUSHJ	P,CTEXT1##	;GET THE USER'S ARGUMENT
	JUMPE	T2,NOTENF##	;MUST HAVE A NODE NAME ETC
	MOVE	P2,T2		;COPY THE NAME
	MOVE	T1,T2		;COPY
	PUSHJ	P,CVTOCT##	;CHECK FOR A NUMBER
	  CAIA			;NO WAS A NAME
	MOVE	P2,T1		;COPY THE NAME
	PUSHJ	P,SRCNDB	;FIND THE NDB
	  JRST	[HRRZ	T1,NRTUNN	;NO SUCH NODE
		PJRST	ERRMES##]	;TYPE AN ERROR MESSAGE
	LDB	T1,NETCNF##	;SEE IF NTE NODE HAS A COMMAND DECODER
	JUMPE	T1,[MOVEI T1,[ASCIZ /NODE does not support a command decoder/]
		PJRST	ERRMES##];TYPE THE ERROR
HOSTDT:
	PUSH	P,U		;SAVE THE LDB
	MOVSI	T1,JLOG		;GET THE LOGGED IN BIT
	TDNE	T1,JBTSTS##(J)	;IS THE JOB LOGGED IN
	PUSHJ	P,TTYDET##	;DET THE TTY
	HLRZ	P4,NDBNNM##(W)	;REMEMBER WHO WE'RE GOING TO
	HLRZ	W,LDBREM##(U)	;GET THE OWNER OF THE TTY
HOSTD1:	SETZ	F,		;CONTROL MESSAGE
	PUSHJ	P,NCMHDR	;WRITE THE NUMBERED HEADER
	  JRST	[PUSHJ	P,NETSLP	;WAIT FOR CORE
		JRST	HOSTD1]	;TRY AGAIN
	PUSH	P,P2		;SAVE THE COUNT BYTE POINTER
	MOVEI	T1,NC.DSC	;DISCONNECT MESSAGE
	PUSHJ	P,BI2EBI	;WRITE
;DLA
	EXCH	U,-1(P)		;SAVE THE PCB RESTORE THE LDB
	LDB	T1,LDPDLA	;GET THE DESTINATION LINK ADDRESS
	PUSHJ	P,BI2EBI	;WRITE
;SLA
	MOVEI	T1,0		;SLA IS ZERO (EXEC)
	PUSHJ	P,BI2EBI	;WRITE
;RSN
	MOVEI	T1,10		;GET THE REASON AND NODE
	PUSHJ	P,BI2EBI	;WRITE
	MOVE	T1,P4		;GET THE NEW NODE NUMBER
	PUSHJ	P,BI2EBI	;SEND IT
;CNT
	POP	P,T1		;GET THE COUNT FIELD BYTE POINTER BACK
	EXCH	U,(P)		;SAVE THE LDB RESTORE THE PDB
	DPB	P3,T1		;STORE THE COUNT
	ADDM	P3,PCBOCT##(U)	;STORE THE COUNT
	PUSHJ	P,NETWRT	;SEND THE MESSAGE
	POP	P,U		;RESTORE THE LDB
	PJRST	CLRTTY		;CLEAR OUT THE LDB
SUBTTL LOCAL STORAGE FOR NETSER
	$LOW
DILLDB:	BLOCK	1		;LDB WAITING FOR A DIAL REQUEST
TELNUM:	BLOCK	2		;PHONE NUMBER FOR REMOTE DIALER
NETFLG:	Z			;CONTAINS A NDB POINTER IF INTERRUPT PENDING
IFN FTCMSR,<
	DEFINE	SUBTBL(MAX,LOC)<<MAX>B8+LOC-NETGTT>
	DLHSIZ==12		;LENGTH OF HISTOGRAM BLOCKS
NETGTT::
%NTCOR:	0			;# WORDS OF FREE SPACE NOW IN USE
%NTMAX:	0			;MAXIMUM %NTCOR HAS GONE
%NTAVG:	0			;EXPONENTIAL AVERAGE OF %NTCOR * 10^4
%NTBAD:	0			;# BAD MESSAGES RECEIVED AND IGNORED
%NTRTP:	SUBTBL(NCT.TP,NCLRTP)
%NTRMT:	SUBTBL(NC.MAX,NCLRMT)
%NTRDL:	SUBTBL(DLHSIZ-1,NCLRDL)
%NTXTP:	SUBTBL(NCT.TP,NCLXTP)
%NTXMT:	SUBTBL(NC.MAX,NCLXMT)
%NTXDL:	SUBTBL(DLHSIZ-1,NCLXDL)
%NTBLC:	0			;LH - PC OF DETECTION OF BAD MESSAGE
				;RH - PCB ADDRESS OF BAD MESSAGE

;ADD FIXED-OFFSET ENTRIES ABOVE THIS POINT
NCLRTP:	BLOCK	NCT.TP+1	;RECEIVED NCL TYPES
NCLRMT:	BLOCK	NC.MAX+1	;RECEIVED NUMBERED TYPES
NCLRDL:	BLOCK	DLHSIZ		;RECEIVED DATA LENGTHS BY POWERS OF 2
NCLXTP:	BLOCK	NCT.TP+1	;TRANSMITTED COUNTER PARTS OF ABOVE
NCLXMT:	BLOCK	NC.MAX+1
NCLXDL:	BLOCK	DLHSIZ

;ADD SUBTABLE DATA ENTRIES ABOVE THIS POINT
.NTMXL==:<.-NETGTT-1>_9
>	;END IFN FTCMSR
IFE FTCMSR,<			;SOME DATA IS NECESARY
%NTCOR:	0
%NTBAD:	0
%NTBLC:	0
>
	$LIT
NETEND::PRGEND
TITLE NETLPT - NETWORK LINE PRINTER ROUTINES
	SEARCH	S,NETPRM
	$RELOC
	$HIGH
NETLPT::ENTRY	NETLPT
;LINE PRINTER
SUBTTL	DEVICE DATA BLOCKS

;SPECIAL BITS IN LH(S)

IOSCLO==400		;DEV HAS BEEN CLOSED
IOSREL==1000		;DEV HAS BEEN RELEASED
IOSUUD==2000		;UUO PROCESSING DELAYED
IOSCON==4000		;DEVICE IS CONNECTED
IOSERR==10000		;ERROR DETECTED AT INT. LEVEL
IOSHDV==100000		;HUNG DEVICE

;BITS IN LPT IOS STATUS REGISTER

LPTNFF==100		;SUPPRESSS FORM FEED AT START/END
	JRST	NTDONL##	;(-5) CHECK IF DEVICE IS ON LINE
	POPJ	P,0		;(-4) SPECIAL ERROR STATUS
	JRST	LPTBFZ		;(-3) BUFFER SIZE
	JRST	CPOPJ##		;(-2) INITILIATION
	JRST	NETHNG##	;(-1) HUNG DEVICE
NDEVLP::JRST	NETRLS##	;RELEASE
	JRST	LPTCLS		;CLOSE OUTPUT
	JRST	LPTOUT		;OUTPUT
	JRST	ILLINP##	;INPUT

LPTNDP::JRST	CPOPJ##		;NO DATA FOR LINE PRINTERS
	JRST	LPTSTS		;CALL WITH ERROR STATUS
	JRST	LPTINT		;CALL FROM INTERRUPT LEVEL

LPTBFZ:	MOVSI	S,IOSCLO!IOSREL!IOSHDV
	ANDCAB	S,DEVIOS(F)	;CLEAR THE BITS
	PJRST	REGSIZ##	;GET THE BUFFFER SIZE FROM THE DDB
;LPT OUTPUT ROUTINE
LPTOUT:				;CALLED FROM UUOCON
	PUSHJ	P,SAVE3##	;SAVE THE P'S
	PUSHJ	P,SETUP##		;SET UP R,W,S
LPTOU1:	MOVSI	S,IO		;GET THE DIRECTION BIT
	IORB	S,DEVIOS(F)	;STORE THE BIT
	TLNN	S,IOSCON	;STILL CONNECTED?
	JRST	[MOVEI S,IOIMPM!IODERR!IODTER!IOBKTL ;NO, KILL IT
		 IORB S,DEVIOS(F)
		 POPJ	P,]
	PUSHJ	P,NTDONL##	;ERROR DETECTED AT INT. LEVEL?
	  JRST	.+2		;YES, STOP JOB
	JRST	LPTOU0		;NO
	MOVEI	T1,DVOFLN
	IORM	T1,DEVCHR(F)	;MARK DEVICE OFF LINE
	PUSHJ	P,HNGSTP##	;YES, PRINT MSG AND STOP JOB
	MOVSI	S,IOSHDV	;CLEAR HUNG FLAG
	ANDCAB	S,DEVIOS(F)	;AND LOAD S
	JRST	LPTOU1		;REDO UUO
LPTOU0:	TLZN	S,IOBEG		;FIRST OUTPUT AFTER INIT
	JRST	LPTGO		;NO
	ANDB	S,DEVIOS(F)	;YES, CLEAR IOBEG
	PUSHJ	P,LPTCRF	;YES PRINT CR FF
LPTGO:	MOVEI	P1,@DEVOAD(F)	;GET THE POINTER TO THE OUTPUT BUFFER
	SKIPG	1(P1)		;EMPTY BUFFER
	JRST	LPTADV		;YES, ADVANCE TO THE NEXT BUFFER
	TLNE	S,IOSERR	;ANY ERRORS AT INTERRUPT LEVEL
	JRST	LPTOFF		;YES, SHUT DOWN THE LPT
	PUSHJ	P,CHKDRQ##	;ANY DATA REQUESTS
	  CAIA			;NO, MUST SHUT DOWN
	JRST	LPTOU2		;YES, CONTINUE
	TRNN	S,IOACT		;IS I/O ACTIVE
	PUSHJ	P,DLYDRQ##	;NO, WAIT FOR A DATA REQUEST
	  JRST	DEVERR##	;SET IOSTBL FOR NON-BLOCKING I/O
	JRST 	LPTOU1		;TRY AGAIN
LPTOU2:	PUSHJ	P,DAPHDR##	;MAKE A HEADER/PCB
	  JRST	[TDNE	S,[XWD IOSERR,IOACT]	;IS I/O ACTIVE
		JRST	LPTOFF	;TURN OF THE LPT
		PUSHJ P,NETSLP##	;NO, WAIT FOR CORE
		JRST	LPTOU2]	;TRY AGAIN
	TRNN	S,IOACT		;IS I/O ACTIVE
	PUSHJ	P,SETACT##	;NO SET IT ACTIVE
	MOVEI	P1,@DEVOAD(F)	;GET THE OUTPUT BUFFER BACK
	HRRZ	T1,1(P1)	;GET THE WORD COUNT
	IMULI	T1,5		;CONVERT TO BYTES
	MOVEM	T1,PCBOC2##(U)	;STORE THE BYTE COUNT
	ADDI	T1,1		;COUNT THE TYPE FIELD
	PUSHJ	P,BI2EBI##	;OUTPUT THE COUNT FIELD
	MOVEI	T1,DC.DAR	;TYPE FIELD DATA WITH EOR
	PUSHJ	P,BI2EBI##	;WRITE
	ADDM	P3,PCBOCT##(U)	;UPDATE THE PROTOCOL COUNT
	MOVEI	T1,2(P1)	;POINT TO THE DATAFIELD
	HRLI	T1,(POINT 7)	;MAKE A BYTE POINTER
	MOVEM	T1,PCBOA2##(U)	;STORE THE POINTER
	PUSHJ	P,DAPWRC##	;SEND THE MESSAGE
	POPJ	P,		;EXIT
;COME HERE AT INTERRUPT LEVEL WHEN A MESSAGE HAS BEEN SENT BY THE FEK

LPTINT:	PUSHJ	P,SAVE3##	;SAVE THE P'S
	PUSHJ	P,SAVJW##		;SAVE J AND W
	PUSHJ	P,SETUP		;SET UP THE ACS
	JRST	LPTADV		;YES, ADVANCE THE BUFFER

;COME HERE ON LINE PRINTER STATUS MESSAGE
;SUROUTINE LPTSTS - INTERRUPT THE STATUS MESSAGE
;CALL	PUSHJ	P,-5 VIA DEVSER(F)
;RETURN CPOPJ

LPTSTS:	AOS	(P)		;SKIP RETURN
;STC
	PUSHJ	P,EBI2BI##	;GET THE BINARY STSTUS CODE
;STD
	PUSHJ	P,EBI2BI##	;GET THE DEVICE STSTUS
	HRLM	T1,DEVSTS(F)	;STORE THE STATUS
	IORM	T1,DEVSTS(F)	;OR THE RIGHT HALF
	TRNN	T1,SLP.OL	;IS THE LPT OFFLINE
	JRST	LPTST1		;NO.

;COME HERE IF LINE PRINTER GOES OFF LINE.

	MOVSI	S,IOSERR+IOSTBL
	IORB	S,DEVIOS(F)	;SET ERROR BITS
	PUSHJ	P,DEVERR##	;SET THE ERROR IN JOB
	PJRST	NETWAK##	;WAKE THE JOB IF WAITING

;COME HERE IF LINE PRINTER GOES ON LINE AGAIN

LPTST1:	MOVSI	S,IOSERR+IOSTBL
	ANDCAM	S,DEVIOS(F)	;CLEAR ERROR BITS
	PJRST	NETWAK##	;WAKE THE JOB IF WAITING
;HERE TO ADVANCE TO THE NEXT BUFFER
LPTADV:				;ADVANCE TO THE NEXT BUFFER
	TLZN	S,IOSCLO	;INTERRUPT FROM A CLOSE
	PUSHJ	P,ADVBFE##	;NO, ADVANCE
	  JRST	LPTOFF		;NONE LEFT
LPTWCK:
	PUSHJ	P,SETIOD##	;SET I/O DONE
	PUSHJ	P,STOIOS##	;STORE IOS
	PJRST	LPTGO		;TRY ANOTHER BUFFER
LPTOFF:
IFN FTKI10!FTKL10,<
	PUSHJ	P,RTEVM##	;IF WE HAVE TO STOP BECAUSE OF NO DATA
				; REQUESTS, WE HAVE TO RETURN EVM
>
	TRNE	S,IOACT		;DON'T SAY DONE UNLESS WE REALLY ARE
	PUSHJ	P,SETIOD##	;SET IO DONE
	PJRST	CLRACT##	;EXIT THE INTERRUPT
SUBTTL LPTCRF - PRINT A CRLF AS FIRST OUTPUT AFTER INIT
;CALL	PUSHJ	P,LPTCRF
;RETURN	CPOPJ

LPTCRF:				;ENTRY
	TRNE	S,LPTNFF	;SUPPRESS EXTRA FF
	POPJ	P,		;RETURN
LPTCR1:	PUSHJ	P,SAVE4##	;SAVE THE P'S
	PUSHJ	P,DAPHDI##	;MAKE A HEADER MESSAGE
	  JRST	[PUSHJ P,NETSLP##	;WAIT FOR A BUFFER
		JRST	LPTCR1]	;TRY AGAIN
	MOVEI	T2,1		;GET ONE WORD
	PUSHJ	P,SLPZWD##	;ALLOCATE
	HRLI	T1,(POINT 8)	;ASCII BYTE POINTER
	MOVEM	T1,PCBOA2##(U)	;STORE IN PCB
	MOVE	T1,[XWD 1,2]	;GET THE COUNT FIELD
	MOVEM	T1,PCBOC2##(U)	;STORE
	MOVSI	T1,(BYTE (8)215,214) ;GET A CR FF
	MOVEM	T1,@PCBOA2##(U)	;STORE IN THE BUFFER
	MOVEI	T1,3		;<CNT><TYP><CR><FF>
	PUSHJ	P,BI2EBI##	;STORE IN PROTOCOL WORD
	MOVEI	T1,DC.DAR	;DATA WITH END OF RECORD
	PUSHJ	P,BI2EBI##	;STORE
	ADDM	P3,PCBOCT##(U)	;STORE THE COUNT
	PUSHJ	P,NETWRT##	;SEND THE MESSAGE
	POPJ	P,		;RETURN
;COME HERE ON CLOSE UUO

LPTCLS:	MOVSI	S,IOSCLO	;SET CLOSE BIT
	IORM	S,DEVIOS(F)
	PUSHJ	P,OUT##		;FLUSH THE LAST BUFFER
	  JFCL			;MAY BE
	PJRST	LPTCRF		;WRITE LAST FORM FEED

;HERE ON HUNG DEVICE
	$LIT
	PRGEND
TITLE NETCDR - NETWORK CARD READER ROUTINES
	SEARCH	S,NETPRM
	$RELOC
	$HIGH
NETCDR::ENTRY	NETCDR
SUBTTL	DEVICE DATA BLOCKS

;SPECIAL BITS IN LH(S)

IOSCLO==400		;DEV HAS BEEN CLOSED
IOSREL==1000		;DEV HAS BEEN RELEASED
IOSUUD==2000		;UUO PROCESSING DELAYED
IOSCON==4000		;DEVICE IS CONNECTED
IOSERR==10000		;ERROR DETECTED AT INT. LEVEL
IOSHDV==100000		;HUNG DEVICE

;BITS IN LH(S) FOR CARD READER

CDR026==400000		;IN 026 CHARACTER SET MODE
CDREOF==200000		;WE HAVE SEEN AN EOF CARD
;INTERNAL DATA STORAGE FOR CARD READER BUFFERS
;POINTED TO BY "NETDEV" IN THE DDB
;AND INDEXED BY "P3"
	CDRNBF==2		;NUMBER OF CARD READER BUFFERS
	CDRBFL==<^D80/3>+1	;LENGTH OF THE MONOTOR BUFFER



;CARD READER
	JRST	NTDONL##	;(-5) SEE IF DEVICE IS ON LINE
	POPJ	P,0		;(-4) SPECIAL ERROR STATUS
	JRST	CDRBFZ		;(-3) BUFFER SIZE
	JRST	CPOPJ##		;(-2) INITILIATION
	JRST	NETHNG##	;(-1) HUNG DENETE
NDEVCD::JRST	NETRLS##	;(0) RELEASE
	JRST	ILLOUT##	;(1) CLOSE
	JRST	ILLOUT##	;(2) OUTPUT
	JRST	CDRINP		;(3) INPUT

CDRNDP::JRST	CDRDAT		;DATA MESSAGE
	JRST	CDRSTS		;ERROR STATUS FROM INTERRUPT LEVEL
	JRST	CPOPJ##		;INTERRUPT CALL
CDRBFZ:	MOVSI	S,IOSCLO+IOSREL+IOSHDV+CDR026+CDREOF
	ANDCAB	S,DEVIOS(F)	;CLEAR I/O STATUS BITS
	MOVSI	T1,SCD.SR	;GET READER STOP BIT
	ANDM	T1,DEVSTS(F)	;CLEAR ALL OTHER BITS
	MOVEI	T1,^D18		;ASSUME ASCII.
	TRNN	M,10		;C(UUO) IS USER'S INIT ARG.
	JRST	CDRBF1		;ASCII.
	MOVEI	T1,^D27		;NOT ASCII. ASSUME BINARY.
	TRNE	M,4		;BINARY?
	JRST	CDRBF1		;YES.
	MOVEI	T1,^D28		;MUST BE IMAGE MODE.
CDRBF1:	TRZ	M,1B29		;SUPER MODE NOT ALLOWED
	POPJ	P,		;RETURN WITH BUFFER SIZE

;HERE ON A RELEASE UUO
;CARD READER INPUT ROUTINE
CDRINP:				;ENTRY FROM INPUT UUO
	PUSHJ	P,SAVE3##	;SAVE THE P'S
CDRINX:	PUSHJ	P,SETUP##	;LOAD THE ACS
	SKIPE	P3,NETDEV##(F)	;GET MONITOR BUFFER ADDRESS
	JRST	CDRIN3		;BUFFER EXISTS
	MOVE	T1,[XWD CDRNBF,CDRBFL]; NUMBER,SIZE
	PUSHJ	P,BLDMBF##	;BUILD THE BUFFERS
	MOVE	P3,NETDEV##(F)	;LOAD THE POINTER TO THE MBF
CDRIN3:	SKIPE	MBFBFC##(P3)	;ANY DATA IN MONITOR BUFFERS?
	JRST	CDRIN2		;YES, PROCESS IT.
	MOVSI	S,IO		;SET UP INPUT
	ANDCAB	S,DEVIOS(F)	;CLEAR THE BIT
	TLNE	S,IOEND		;END OF FILE
	POPJ	P,		;YES RETURN TO UUOCON
	TLNN	S,IOSCON	;STILL CONNECTED?
	JRST	[MOVEI S,IOIMPM!IODERR!IODTER!IOBKTL  ;NO, KILL IT
		 IORB	S,DEVIOS(F)
		 POPJ	P,]
	PUSHJ	P,NTDONL##	;ERROR DETECTED AT INT. LEVEL?
	  CAIA			;YES
	JRST	CDRIN4		;NO, CONTINUE
	MOVEI	T1,SCD.SR	;GET READER STOP
	PUSHJ	P,DAPCST##	;CLEAR IT
	  JFCL
	MOVEI	T1,DVOFLN
	IORM	T1,DEVCHR(F)	;MARK DEVICE OFF LINE
	PUSHJ	P,HNGSTP##	;STOP THE JOB
	MOVSI	S,IOSHDV	;GET THE HUNG BIT
	ANDCAB	S,DEVIOS(F)	;CLEAR IT
	JRST	CDRIN3		;TRY AGAIN
CDRIN4:	PUSHJ	P,CDRSRQ	;VIA DATA REQUEST
	JRST	CDRIN3		;NO, TRY AGAIN
CDRIN2:	PUSHJ	P,SETACT##	;SET I/O ACTIVE
	TLZN	S,IOBEG		;FIRST TIME?
	JRST	CDRGO		;NO.
	ANDB	S,DEVIOS(F)	;STORE S
	MOVSI	T2,PCDRAS##	;YES, SET UP BYTE POINTERS
	TRNN	S,10		;ASCII?
	JRST	CDRIN1		;YES.
	MOVSI	T2,PCDRBI##	;NO, TRY BINARY OR IMAGE
REPEAT 0,<
	TRNE	S,100		;SUPER-IMAGE?
	MOVSI	T2,PCDRSI##	;YES.
>
CDRIN1:	MOVEM	T2,DEVOAD(F)	;STORE BYTE POINTER IN DDB
CDRGO:	PUSHJ	P,NEWBUF##	;INITIALIZE NEW BUFFER
	  JRST	ADRERR##	;ADDRESS CHECK
CDRGO1:	MOVE	P1,MBFOBC##(P3)	;COMPUTE BUFFER POINTER
	IMULI	P1,CDRBFL	;BUFFER OFFSET * SIZE
	ADD	P1,[POINT 12,MBFMBF##(P3)]
	MOVEI	P2,^D80		;YES, SET P2 TO COL. COUNT
	TRNE	S,10		;ASCII?
	JRST	CDRNAS		;NO.
	ILDB	T3,P1		;GET COL. 1
	CAIN	T3,4242		;SWITCH TO 026 CODE?
	JRST	CRS026		;YES.
	CAIN	T3,5252		;NO, SWITCH TO 029 CODE?
	JRST	CRS029		;YES.
	CAIN	T3,7417		;EOF CODE?
	JRST	CRSEOF		;YES.
	JRST	CDRAS1		;NO, PROCESS THE CHAR NORMALLY
CDRASC:	ILDB	T3,P1		;GET NEXT COL.
;COME HERE TO TRANSLATE 12-BIT CHARACTERS TO ASCII AND PUT THEM
;  IN THE USER'S BUFFER.  THE CODE TO DO THIS WAS
;  TAKEN FROM CDRSRX, HENCE THE PAUCITY OF
;  COMMENTS.

CDRAS1:	SETZB	T1,T2		;CLEAR T1 AND T2
	JUMPE	T3,CDRAS2	;BLANKS ARE VERY SIMPLE
	CAIN	T3,5000		;12-0?
	MOVEI	T3,4242		;YES, TREAT AS 12-8-2 ([)
	CAIN	T3,3000		;NO, 11-0?
	MOVEI	T3,2202		;YES, TREAT AS 11-8-2 (!)
	LDB	T2,[POINT 3,T3,26]
	TRNE	T3,3		;DIDDLE T1 AND T2 TO FORM
	TRC	T2,7		;INDEXES INTO CHAR TABLE
	TRNE	T3,74
	TRO	T2,10
	TRNE	T3,314
	TRO	T1,2
	TRNE	T3,525
	TRO	T1,1
	TLNE	S,CDR026	;IN 026 CHAR SET MODE?
	TRO	T2,20		;NO, USE SECOND TABLE
CDRAS2:	LDB	T3,CRCVPT##(T1)	;GET 7-BIT TRANSLATION
	IDPB	T3,DEVOAD(F)	;PUT IN USER'S CORE
	SOSLE	DEVCTR(F)	;ANY ROOM IN USER'S BUFFER?
	SOJG	P2,CDRASC	;YES, TRANSLATE ANOTHER CHAR

;COME HERE ON END-OF-CARD

CDRENA:	MOVEI	T1,15		;INSERT CARRIAGE-RETURN LINE-FEED
	IDPB	T1,DEVOAD(F)	;IN USER'S BUFFER
	MOVEI	T1,12		;TO MARK THE END OF THE CARD
	IDPB	T1,DEVOAD(F)
	JRST	CDRDON		;DONE WITH CARD.

;COME HERE TO DO SPECIAL PROCESSING FOR COL. 1.

CRS026:	SKIPA	T1,[IORB S,DEVIOS(F)]
CRS029:	MOVE	T1,[ANDCAB S,DEVIOS(F)]
	MOVSI	S,CDR026	;LOAD 026 BIT
	XCT	T1		;SET OR CLEAR IT AS REQ'D
	JRST	CDRIGN		;IGNORE THE CARD OTHERWISE

;COME HERE ON END-OF-FILE INDICATION

CRSEOF:	MOVSI	S,CDREOF	;SET EOF PENDING BIT
	IORB	S,DEVIOS(F)
	JRST	CDRIGN		;AND IGNORE REST OF CARD

;COME HERE IF THE MODE IS NOT ASCII.

CDRNAS:	TRNN	S,4		;IMAGE MODE?
	JRST	CDRIMG		;YES, NO SPECIAL PROCESSING
	ILDB	T1,P1		;GET COL. 1
	SOS	P2		;DECREMENT COL. COUNT
	MOVEI	T2,-5(T1)	;7-9 PUNCH?
	TRNE	T2,17
	TRO	S,IOIMPM	;NO, SET ERROR BIT
	LSH	T1,-6		;COL'S 12-3 ARE WORD COUNT
	JUMPE	T1,CDRIGN	;IGNORE IF WC = 0
	MOVE	T3,T1		;COPY WORD COUNT
	IMULI	T3,3		;COMPUTE BYTE COUNT
	CAMGE	T3,DEVCTR(F)	;TOO MUCH FOR USER'S BUFFER?
	MOVEM	T3,DEVCTR(F)	;YES, SHORTEN AMOUNT
	HRRM	T1,@DEVOAD(F)	;PUT WC IN RH OF FIRST BUFFER WORD
	ILDB	T1,P1		;GET COL. 2 (CHECKSUM)
	SOS	P2		;DECREMENT COL. COUNT
	MOVSM	T1,MBFCHK##(P3)	;STORE IN DDB
	HRLM	T1,@DEVOAD(F)	;AND IN LH OF WORD COUNT WORD
CDRBIN:	ILDB	T1,P1		;FETCH CHARACTER
	IDPB	T1,DEVOAD(F)	;PUT IN USER'S BUFFER
	SOSLE	DEVCTR(F)	;ROOM LEFT?
	SOJG	P2,CDRBIN	;YES

;COME HERE AT THE END OF A BINARY CARD

CDRENB:	MOVEI	T2,@DEVIAD(F)	;BUFFER ADDRESS
	PUSHJ	P,CKS12##	;COMPUTE CHECKSUM
	CAME	T1,MBFCHK##(P3)	;MATCH?
	TRO	S,IODTER	;NO.  SIGNAL ERROR.
	JRST	CDRDON		;DONE WITH CARD.

;COME HERE ON IMAGE MODE.

CDRIMG:	MOVEI	T1,@DEVIAD(F)	;BUFFER POINTER
	MOVEI	T2,2(T1)	;START OF DATA
	HLRZ	T1,0(T1)	;BUFFER LENGTH
	CAILE	T1,CDRBFL	;LONGER THAN A CARD?
	MOVEI	T1,CDRBFL	;YES, SHORTEN
	MOVE	T3,T1		;SAVE BUFFER LENGTH
	ADDI	T1,-1(T2)	;POINT T1 TO END OF BUFFER
	HRLI	T2,@P1		;BUILD BLT WORD
	BLT	T2,(T1)		;MOVE DATA TO USER CORE
	ADDM	T3,DEVOAD(F)	;INCREMENT DEVOAD AS THOUGH BY IDPB'S

;FALL INTO CDRDON

;COME HERE WHEN THE CARD IS DONE

CDRDON:	MOVEI	T1,@DEVOAD(F)	;LAST ADDRESS
	MOVEI	T2,@DEVIAD(F)	;FIRST ADDRESS - 1
	SUBI	T1,1(T2)	;COMPUTE NUMBER OF WORDS STORED
	HRRM	T1,1(T2)	;STORE IN FIRST WORD OF BUFFER
	PUSHJ	P,SETIOD##	;SET I/O DONE
	PUSHJ	P,ADVBFF##	;ADVANCE BUFFERS
	  TRZ	S,IOACT		;NONE--I/O NO LONGER ACTIVE
	PUSHJ	P,AVOMBF##	;ADVANCE THE OUTPUT BUFFER
	  CAIA			;NO, DATA IN THE BUFFER
	TRNE	S,IODERR+IOIMPM+IODTER ;ANY ERRORS?
	TRZ	S,IOACT		;YES (OR NO MORE BUFFERS),
				; NO MORE UNTIL NEXT UUO
	PUSHJ	P,STOIOS##	;RESET HUNG DEVICE COUNT
	TRNE	S,IOACT		;IS I/O STILL ACTIVE?
	JRST	CDRGO		;YES, DO ANOTHER BUFFER

;COME HERE WHEN I/O GOES INACTIVE FOR ANY REASON.
;  IF THERE HAVE BEEN NO ERRORS, ATTEMPT TO KEEP THE MONITOR BUFFERS
;  FULL.  IF THERE HAVE BEEN ERRORS, TAKE BACK DATA REQUESTS.

IFN FTKI10!FTKL10,<
	PUSHJ	P,RTEVM##	;RETURN ANY EVM
>
	TDNE	S,[XWD IOEND+CDREOF,IODERR+IOIMPM+IODTER]
	POPJ	P,		;ANY ERRORS OR EOF YES, EXIT
	PJRST	CDRSRQ		;NO, SEND DATA REQUESTS AND EXIT

CDRIGN:	PUSHJ	P,AVOMBF##	;ADVANCE THE OUTPUT BUFFER
	  JRST	CDRINX		;CHECK FOR ANOTHER CARD/DATA REQUEST
	JRST	CDRGO1		;YES, PROCESS THE CARD
;COME HERE IF THE USER ISSUES AN INPUT UUO AND THE BUFFERS
;  ARE EMPTY OR RIGHT AFTER TAKING SOME DATA FROM THE BUFFERS.
;  ISSUE DATA REQUESTS IF REQUIRED TO KEEP THE MONITOR BUFFERS
;  FILLED.  IF THE BUFFERS ARE EMPTY IT IS LEGITIMATE TO CHECK
;  THE STATUS REGISTER FOR UNUSUAL CONDITIONS.

CDRSRQ:	SKIPE	MBFBFC##(P3)	;ANY DATA LEFT IN MONITOR?
	JRST	CDRSR2		;YES, PROCESS IT.
	HLRZ	T1,DEVSTS(F)	;NO, GET STATUS
	TRNN	T1,SCD.ME!SCD.CZ!SCD.HZ		;ERROR OR END-OF-FILE?
	JRST	CDRSR2		;NO, SEND DATA REQUESTS
	TRNN	T1,SCD.HZ!SCD.CZ		;YES, END-OF-FILE?
	JRST	CDRSR3		;NO.  CHECK FOR TROUBLE.

;COME HERE ON END-OF-FILE DETECTION

	MOVSI	S,IOEND+IOBEG	;SET THESE BITS
	IORM	S,DEVIOS(F)
	MOVSI	S,IOSERR+IOSTBL+CDREOF ;AND CLEAR THESE BITS
	ANDCAB	S,DEVIOS(F)
	PUSHJ	P,SETIOD##	;RESTART JOB IF WAITING
	PJRST	CLRACT##	;TERMINATE READING.

;COME HERE ON TROUBLE

CDRSR3:	TRNN	T1,SCD.OR	;OVERRUN?
	JRST	CDRSR4		;NO, LET OPR TRY TO RECOVER
	MOVEI	S,IODERR	;SET DEVICE ERROR BIT
	IORB	S,DEVIOS(F)
CDRSR4:	MOVSI	S,IOSERR+IOSTBL	;SET ERROR BITS FOR UUO LEVEL
	IORB	S,DEVIOS(F)
IFN FTKI10!FTKL10,<
	PUSHJ	P,SVEVM##		;SAVE THE EVM OVER THE CALL TO DEVERR
>;END FTKI10!FTKL10
	PJRST	DEVERR##	;MAKE UUO LEVEL CALL HNGSTP
;COME HERE IF THERE ARE NO INTERESTING STATUS BITS TO
;  LOOK AT.

CDRSR2:	PUSHJ	P,DRQMBF##	;SEND THE DATA REQUESTS
;COME HERE WHEN DATA REQUEST HAS BEEN TAKEN CARE OF

CDRSR1:	MOVE	S,DEVIOS(F)	;GET DEVIOS
;	TRNE	S,IOACT		;IS IO ACTIVE
;	SKIPE	MBFBFC(P3)	;YES, IS THERE ANY DATA?
;	POPJ	P,		;I/O NOT ACTIVE OR DATA PRESENT
CDRSR7:	HLRZ	T1,DEVSTS(F)	;GET LATEST STATUS
	TRNN	T1,SCD.SR	;HAS READING STOPPED
	JRST	CDRSR6		;NO
	MOVEI	T1,SCD.SR	;GET OFF-LINE BIT
	PUSHJ	P,DAPCST##	;CLEAR THE STATUS BIT
	  JRST	CDRSR6		;WAIT FOR THE DATA
	MOVSI	T1,SCD.SR	;YES, CLEAR CARD READ STOP BIT
	ANDCAM	T1,DEVSTS(F)	;SO WE WONT SEND MSG AGAIN
CDRSR6:	PUSHJ	P,NETHIB##	;WAIT
	POPJ	P,		;RETURN
;COME HERE ON CARD READER STATUS MESSAGE
;SUBROUTINE CDRSTS - STATUS MESSAGE RECEIVED
;CALL	PUSHJ	P,-5 VIA DEVSER(F)
;RETURN	CPOPJ

CDRSTS:	AOS	(P)		;SKIP RETURN
;STD
	PUSHJ	P,EBI2BI##	;GET THE BINARY CODE
;STC
	PUSHJ	P,EBI2BI##	;GET THE DEVICE STATUS
	HRLM	T1,DEVSTS(F)	;STORE THE STSTUS
	IORM	T1,DEVSTS(F)	;OR IN THE RIGHT HALF
	TRNE	T1,SCD.ME	;ANY ERRORS
	PJRST	NETWAK##		;YES, CATCH THEM WHEN BUFFERS EMPTY
	MOVSI	S,IOSERR+IOSTBL!IOSHDV	;NO, CLEAR ERROR BITS
	ANDCAM	S,DEVIOS(F)
	PJRST	NETWAK##		;WAKE THE JOB IF SLEEPINT
;COME HERE ON CARD READER DATA MESSAGE

CDRDAT:	SKIPN	P3,NETDEV##(F)	;GET THE BUFFER AREA
	POPJ	P,		;IGNORE THE DATA
	MOVE	P2,MBFIBC##(P3)	;COMPUTE BUFFER LOCATION
	IMULI	P2,CDRBFL
	ADDI	P2,MBFMBF##(P3)	;ADD THE OFFSET
	HRLI	P2,(POINT 12)	;COLUMN BYTE POINTE
	MOVEI	T1,1(P2)	;CLEAR THE BUFFER
	HRLI	T1,(P2)		;WITH A BLT POINTER
	SETZM	(P2)
	BLT	T1,CDRBFL-1(P2)	;CLEAR IT
;COPY THE DATA TO THE MONITOR BUFFER (12 COL _8 BIT)
CDRCV1:	SETZ	T4,		;CLEAR REPEAT COUNT
CDRCV0:	SOJL	P4,CDRDA1	;END OF DATA
	ILDB	T1,P1		;GET THE NEXT BYTE
	TRZN	T1,200		;CHECK FOR 1CCCCCCC
	JRST	CDRCV2		;NO
	IDIVI	T1,20		;SEPERATE THE ZONES
	LSHC	T2,-2		;COMPUTE THE INDEX TO THE CONVERSION TABLE
	TLZN	T3,(1B0)	;CHECK WHICH HALF
	SKIPA	T2,CDRCTB(T2)	;GET THE LEFT HALF
	HRLZ	T2,CDRCTB(T2)	;NO RIGHT HALT
	TLZE	T3,(1B1)	;WHICH QUARTER
	LSH	T2,11		;LOW QUARTER
	LSHC	T1,-33		;GET THE WHOLE COLUMN
	JRST	CDRCV5		;STORE THE BYTE
CDRCV2:	TRZN	T1,100		;REPEAT OF BLANKS
	JRST	CDRCV3		;NO
	SOJL	T1,CDRCV1	;REDUCE COUNT OF BLANKS
	IBP	P2		;SKIP FOR A BLANK
	JRST	.-2		;CONTINUE
CDRCV3:	TRZN	T1,40		;REPEAT COUNT
	JRST	CDRCV4		;NO
	MOVEI	T4,(T1)		;YES, COPY THE REPEAT COUNT
	JRST	CDRCV0		;TRY AGAIN
CDRCV4:	TRNE	T1,20		;CHECK FOR RESERVED OF 12 BIT BYTES
	JRST	CDRCV1		;RESERVED IGNORE
	MOVEI	T2,(T1)		;COPY TO T2
	LSH	T2,10		;MAKE ROOM FOR SECOND HALT
	SOJL	P4,CDRDA1	;END OF DATA
	ILDB	T1,P1		;GET THE NEXT BYTE
	IORI	T2,(T1)		;INSERT
CDRCV5:	IDPB	T2,P2		;STORE THE OUTPUT BYTE
	SOJG	T4,CDRCV5	;CHECK FOR A REPEAT COUNT
	JRST	CDRCV1		;GET NEXT BYTE
CDRDA1:	PUSHJ	P,AVIMBF##	;ADVANCE THE INPUT MONITOR BUFFER
	HRLZI	T1,-1		;DECREMENT THE DATA REQ'S
	ADDM	T1,NETDRQ##(F)	;IN THE DDB
	POPJ	P,		;END OF PROCESSING.
;CONVERSION TABLES
CDRCTB:
	BYTE	(9)000,400,200,100
	BYTE	(9)040,020,010,004
	BYTE	(9)002,001,202,102
	BYTE	(9)042,022,012,006

	$LIT
	END