Google
 

Trailing-Edge - PDP-10 Archives - AP-4178E-RM - swskit-sources/impdv.mac
There are 16 other files named impdv.mac in the archive. Click here to see a list.
;<3A-MONITOR>IMPDV.MAC.3, 22-Apr-78 20:38:25, Edit by BORCHEK
;SPEED UP NETWORK CODE
;REMOVE USELESS INSTRUCTION IN BYTE LOOPS
;<3A.MONITOR>IMPDV.MAC.2, 19-Mar-78 13:15:57, Edit by BORCHEK
;SPREAD OUT STARTUP RST'S SO BUFFER SPACE IS NOT DEPLETED
;<4.MONITOR>IMPDV.MAC.1,  6-Dec-77 17:12:18, EDIT BY CROSSLAND
;FIX ASNSQ TO USE RIGHT REGISTER IN CONSTRUCTING DIFFERENCE.
;<3-MONITOR>IMPDV.MAC.18,  7-Nov-77 13:02:31, EDIT BY KIRSCHEN
;MORE COPYRIGHT UPDATING...
;<3-MONITOR>IMPDV.MAC.17, 25-Oct-77 01:27:23, EDIT BY CROSSLAND
;CLEAR RFNM COUNT, RETRANSMISSION FLAG AND BUFFER BEFORE UNLOCKING
;BUFFERS ON INTERFACE RESET TO PREVENT IMPMSO BUGINF'S
;<3-MONITOR>IMPDV.MAC.16, 19-Oct-77 00:57:51, EDIT BY CROSSLAND
;REPLACE JFCL'S IN LOGGING ROUTINE WITH ERJMP'S
;<3-MONITOR>IMPDV.MAC.15, 12-Oct-77 13:51:00, EDIT BY KIRSCHEN
;UPDATE COPYRIGHT FOR RELEASE 3
;<3-MONITOR>IMPDV.MAC.14,  7-Oct-77 02:46:23, EDIT BY CROSSLAND
;MOVE REQUEST FOR RESCANNING OF NVT LINE IF OUTSTANDING TTMSG.
;<3-MONITOR>IMPDV.MAC.13, 28-Sep-77 04:30:00, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.12, 24-Sep-77 23:56:20, EDIT BY CROSSLAND
;FLUSH TTMSG'S TO NVT'S ON EXPIRATION OF TIMER
;<3-MONITOR>IMPDV.MAC.11, 23-Jul-77 22:54:02, EDIT BY CROSSLAND
;MOVE BUFFERS TO ANBSEC SECTION
;<3-MONITOR>IMPDV.MAC.10, 29-Jun-77 04:20:07, EDIT BY CROSSLAND
;FIX MODEL B ADDRESSING PROBLEMS
;<3-MONITOR>IMPDV.MAC.9, 17-Jun-77 05:36:10, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.8,  9-Jun-77 04:25:26, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.7,  6-Jun-77 00:45:43, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.6, 21-May-77 19:28:58, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.5, 14-May-77 19:25:42, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.4,  8-May-77 18:29:58, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.3,  5-May-77 10:39:47, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.2, 27-Apr-77 15:28:18, EDIT BY CROSSLAND
;TCO 1742 MERGE ARPANET SOURCES
;<101B-MONITOR>IMPDV.MAC.3,  3-Apr-77 14:04:51, EDIT BY CROSSLAND
; REPAIR RACE IN HANDLING OF JOBBIT IN ULKIDV -- ALSO CAUSE NCP FORK
; TO RUN ON Q1 ALWAYS
;<101B-MONITOR>IMPDV.MAC.2, 29-Mar-77 10:32:09, EDIT BY CROSSLAND
;TCO 1764 - REPAIR JOBBIT DIDDDLING IN IMP LOCK/UNLOCK CODE
;<CLEMENTS>IMPDV.MAC.17,  5-Aug-76 15:41:19, EDIT BY CLEMENTS
; REMOVE NVT HANDLING INTO "NVT.MAC"
; REMOVE PHYSICAL IMP HANDLER TO IMPPHY
; CHANGE THE HALFWORD DEFS OF =<Z XX-NVTLO> FORM
;ADD TEMPORARY-PARAMETERS AT ***TEMP-PARAMS***
;LS BECOMES RS
;ADJUST BUGXXX STATEMENTS
;<CLEMENTS>IMPDV.MAC.1, 15-Jul-76 16:49:08, EDIT BY CLEMENTS
; ADJUST TITLE, END AND SEARCH STATEMENTS
;<134-TENEX>IMPDV.MAC;361     2-DEC-75 10:31:23    EDIT BY TOMLINSON
;<134-TENEX>IMPDV.MAC;360     2-DEC-75 10:22:37    EDIT BY TOMLINSON
;<134-TENEX>IMPDV.MAC;359    10-NOV-75 13:44:21    EDIT BY ALLEN
; INCREASE IMPNLK TO ^D200
;<134-TENEX>IMPDV.MAC;358    26-OCT-75 11:48:06    EDIT BY TOMLINSON
;<134-TENEX>IMPDV.MAC;357    21-OCT-75 12:38:48    EDIT BY TOMLINSON
; MORE RCTE FIXUPS
;<134-TENEX>IMPDV.MAC;355     9-OCT-75 13:15:48    EDIT BY ALLEN
; MAKE SURE IMIB NOT ON FREELIST IN IMPEIN
;<134-TENEX>IMPDV.MAC;353    24-SEP-75 09:46:23    EDIT BY TOMLINSON
; DEFER OKINT IN NVTCOB 'TIL AFTER SENDING DATA MARK
;<134-TENEX>IMPDV.MAC;352    22-SEP-75 11:46:31    EDIT BY CLEMENTS
; On startup, (IMPRC1), only send RST's to hosts in name table.
;<134-TENEX>IMPDV.MAC;351    19-SEP-75 12:28:44    EDIT BY TOMLINSON
; MORE RCTE BUG FIXES
;<134-TENEX>IMPDV.MAC;350    17-SEP-75 14:55:18    EDIT BY TOMLINSON
;<134-TENEX>IMPDV.MAC;348    17-SEP-75 14:41:56    EDIT BY TOMLINSON
; RCTE BUG FIXES
;<134-TENEX>IMPDV.MAC;344    15-SEP-75 17:12:18    EDIT BY ALLEN
;<134-TENEX>IMPDV.MAC;343    15-SEP-75 16:39:45    EDIT BY ALLEN
; TEMPORARILY NOP'ED NVTCIB
;<134-TENEX>IMPDV.MAC;342    12-SEP-75 15:31:45    EDIT BY ALLEN
; ADD CHECKS TO BE SURE THAT WE NEVER LOCK OR UNLOCK A BUFFER ON THE
; FREELIST
;<TOMLINSON>IMPDV.MAC;1    10-SEP-75 08:34:36    EDIT BY TOMLINSON
; RCTE FIXES
;<134-TENEX>IMPDV.MAC;336     5-SEP-75 15:48:23    EDIT BY ALLEN
; RESTORE ORIGINAL ACTIVATION CRITERIA
;<134-TENEX>IMPDV.MAC;335     5-SEP-75 15:38:54    EDIT BY ALLEN
;<134-TENEX>IMPDV.MAC;334     3-SEP-75 22:01:33    EDIT BY ALLEN
; NEW ACTIVATION LOGIC AND FIX INPUT BUFFER FETCH LOGIC
;<134-TENEX>IMPDV.MAC;333    28-AUG-75 16:32:26    EDIT BY ALLEN
; SLIGHT MOD DUE TO CHANGE IN LOCK-UNLOCK MACROS
;<134-TENEX>IMPDV.MAC;332    19-AUG-75 15:40:48    EDIT BY ALLEN
; REPAIR TO PKQOB TO STORE ACTUAL WORDS IN USE IN HEADER SO
; OUTPUT ROUTINES DON'T TRY TO SEND THE WHOLE BUFFER
;<134-TENEX>IMPDV.MAC;331    14-AUG-75 15:18:49    EDIT BY ALLEN
; ELIMINATE LOCKUP DUE TO RUNNING OUT OF BUFFERS
;<134-TENEX>IMPDV.MAC;330    12-AUG-75 17:07:12    EDIT BY ALLEN
; FIX AT PKMS5 TO KEEP PKMSG FROM GOING NUTS WHEN ASNTBF FAILS
;<134-TENEX>DCAIMP.MAC;9     6-AUG-75 11:19:35    EDIT BY ALLEN
; END INPUT ROUTINE RECORDS ACTUAL COUNT IN BUFFER HEADER
;<134-TENEX>DCAIMP.MAC;8     5-AUG-75 13:57:29    EDIT BY ALLEN
; Various bug fixes to new buffer management
;<134-TENEX>DCAIMP.MAC;7     4-AUG-75 10:46:05    EDIT BY ALLEN
; VARIOUS CHANGES FOR NEW BUFFER MANAGEMENT
;<134-TENEX>IMPDV.MAC;328    11-JUL-75 17:17:33    EDIT BY ALLEN
; MINOR FIX
;<134-TENEX>IMPDV.MAC;327    11-JUL-75 16:12:43    EDIT BY ALLEN
; DELETE CALL IMPKO1 AT PKMSD 4
;<134-TENEX>DCAIMP.MAC;3    11-JUL-75 09:59:54    EDIT BY ALLEN
; PKMSG USES REMAINING SPACE IN CURRENT OUTPUT BUFFER UNLESS
; THIS WOULD CAUSE A CONTROL MESSAGE TO CROSS A NET MESSAGE BOUNDARY.
; PKMSG1 ADDED -- SAME AS PKMSG BUT DOESN'T ATTEMPT TO SEND THE
; CURRENT MESSAGE. CALLED BY NETTCS SO THAT SIZE OF NET MESSAGE
; IS NOW LIMITED ONLY BY AVAILABLE CHARACTERS IN TTY BUFFERS, 
; BY ALLOCATION, OR BY SIZE OF OUTPUT BUFFER, NOT BY SIZE
; OF NETTCS' STACK BUFFER.
;<134-TENEX>IMPDV.MAC;326    15-MAY-75 07:51:23    EDIT BY TOMLINSON
; CHANGE REFERENCES TO NLINES TO NVTHI
;<134-TENEX>IMPDV.MAC;325    21-APR-75 11:34:59    EDIT BY TOMLINSON
; Limit special queues on message basis rather than buffer space
;<134-TENEX>IMPDV.MAC;324    14-APR-75 17:08:59    EDIT BY OPERATOR
; CORRECT INITIALIZATION OF IDVLCK
;<134-TENEX>IMPDV.MAC;323    14-APR-75 15:37:09    EDIT BY ALLEN
; AVOID SMASHING AC1 IN PIE-SLICE VERSION OF LCKID1
;<134-TENEX>IMPDV.MAC;322    11-APR-75 17:08:19    EDIT BY ALLEN
; REPAIRS TO NEW LOCKING STUFF
;<134-TENEX>IMPDV.MAC;319    10-APR-75 22:18:40    EDIT BY ALLEN
; MAKE USE OF NEW SCHEDULING FOR LCKERS
;<134-TENEX>IMPDV.MAC;318     4-APR-75 18:00:19    EDIT BY CLEMENTS
; FIX TO PREVENT UNKNOWN LINK IMPBUGS IF REMOTE CLOSES A
;  SEND SOCKET WHICH HAS AN OUTSTANDING RFNM
;<134-TENEX>IMPDV.MAC;317    12-MAR-75 14:08:45    EDIT BY PLUMMER
; CHANGE SIQCHK TO FLUSH ENTIRE Q IF NOT ACTIVE
;<134-TENEX>IMPDV.MAC;316    27-FEB-75 15:50:47    EDIT BY CLEMENTS
; INCREASE NUMBER OF CHARACTERS PROCESSED IN NETTCS FROM 32 TO 64
; INCREASE SIZE OF PI-LEVEL STACK, DUE TO DEBUG ROUTINES
;<134-TENEX>IMPDV.MAC;315    10-JAN-75 10:32:56    EDIT BY ALLEN
; REPLENISH INPUT BUFFERS IF IMPNFI .LT. 8
;<133-TENEX>IMPDV.MAC;314    24-DEC-74 08:32:56    EDIT BY TOMLINSON
; DISABLE RCTE UNTIL DEBUGGED THOROUGHLY
;<133-TENEX>IMPDV.MAC;313    18-DEC-74 15:40:48    EDIT BY TOMLINSON
;<133-TENEX>IMPDV.MAC;312    17-DEC-74 16:17:00    EDIT BY TOMLINSON
; CAUSE INITIAL SB STRING FOR RCTE
;MISC BUG FIXES TO RCTE
;<133-TENEX>IMPDV.MAC;311    16-DEC-74 15:50:14    EDIT BY TOMLINSON
; TAKE OUT CODE TO TURN ON RCTE IN ASNNVT. CAN'T DO IT BECAUSE NCPLCK IS SET.
;<133-TENEX>IMPDV.MAC;309    13-DEC-74 12:41:16    EDIT BY TOMLINSON
; INITITATE TURN ON OF RCTE AND SUPPRESS GA
;<133-TENEX>IMPDV.MAC;308    13-DEC-74 12:32:18    EDIT BY TOMLINSON
; BUG FIXES TO RCTE
; PKBY1: MOVE SOS IMPLT4 TO AFTER ASNTBF CALL
; UPBRB: CHANGE BUG MSG
; IM8RAS:  ACCOUNT FOR BUFFERS IN CONNECTION QUEUE WHEN RESETTING ALLOC
;<133-TENEX>IMPDV.MAC;306     8-DEC-74 18:28:13    EDIT BY CLEMENTS
; FIX MISSING EXTERN ON SKPRET
;<133-TENEX>IMPDV.MAC;303     3-DEC-74 10:25:14    EDIT BY TOMLINSON
; Added RCTE code
;<133-TENEX>IMPDV.MAC;300    29-OCT-74 08:22:03    EDIT BY TOMLINSON
;<133-TENEX>IMPDV.MAC;299     1-OCT-74 13:16:36    EDIT BY TOMLINSON
; REMOVE SUPERFLUOUS INSTRINCTION AT IMPRAP+2
;<133-TENEX>IMPDV.MAC;298    25-SEP-74 12:47:56    EDIT BY TOMLINSON
; (1) MARK HOST USING NEW PROTOCOL AS UNDERSTANDING SAME.
; (2) RELEASE BOTH HALVES OF AN NVT WHEN RECEIVING NXS/R
; (3) FIX BUGIMH ARG IN BADLKS/R
; (4) BUGCHK IF IMPLT4 IS OVERDECREMENTED IN UPBRB
;<133-TENEX>IMPDV.MAC;297    22-AUG-74 16:28:54    EDIT BY CLEMENTS
;<TENEX-132>IMPDV.MAC;296    22-JUN-74 13:07:40    EDIT BY TOMLINSON
; NOP IMPCHK IF IMPRDY = 0

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

	SEARCH PROLOG,MACSYM,MONSYM
	TTITLE	IMPDV


;***TEMP-PARAMS***
PIESLC==0
;***TEMP-PARAMS



;ACCUMULATORS

DEFAC (IMPUN,Q1)		;SAME AS "UNIT" ELSEWHERE

;PARAMETERS

SIQMAX==6			;MAXIMUM MESSAGES ALLOWED ON SIQ
RFNTMO==^D20000			;RFNM TIME-OUT INTERVAL (THREE OF THESE)
UPROBI==^D300000		;INTERVAL AT WHICH TO PROBE EVERY UP HOST
UPROBT==^D60000			;TIME TO SPEND PROBING EVERY DOWN HOST
SIQTM0==^D120000		;SPECIAL QUEUE TIME-OUT INTERVAL
NINBFS==10			;NUMBER OF IMP INPUT BUFFERS TO KEEP READY
;MACROS

;LOCK IMP DEVICE LOCK

DEFINE ILOCK (A)
<	CALL LCKIDV
IFB <A>,<0>
IFNB<A>,<A>
>

;UNLOCK IMP DEVICE LOCK

DEFINE IUNLK
<	CALL ULKIDV>

;CALL CLOCK SWITCH CODE

DEFINE	IMSCLK(CLOCK)<
	MOVE T1,[IFIW!CLOCK]
	CALL IMUCLK>
;CALLED BY PERIODIC CHECK ROUTINE

	SWAPCD

CHKNET::
	IFDEF POLLF,<		;DO THIS PRINTOUT ONLY IF POLLF IS DFND
;THIS POLLING LOGIC IS USELESS ON THE ARPANET THESE DAYS, BECAUSE
; THERE ARE JUST TOO MANY HOSTS. BUT ON A SMALL PRIVATE NET, IT WOULD
; PROBABLY BE USEFUL AND POLLF SHOULD BE DEFINED AS 1.

	MOVSI IMPUN,-IMPLBT	;SETUP TO SCAN HOST BIT TABLES
CHKN2:	MOVE T3,IMPHL1(IMPUN)	;BIT SET IF HOST HAS GONE DOWN SINCE LAST
	JFFO T3,[MOVE T3,BITS(T4) ;FOUND ONE
		ANDCAM T3,IMPHL1(IMPUN) ;RESET BITS
		ANDCAM T3,IMPHL2(IMPUN)
		HRROI T1,[ASCIZ /HOST /]
		PSOUT		;REPORT DOWNAGE
		MOVEI T1,.PRIOU
		MOVEI T2,0(IMPUN) ;COMPUTE HOST NUMBER
		IMULI T2,^D36	;MULTIPLY BY 36
		ADDI T2,0(T4)	;ADD IN BIT POSITION
		MOVEI T3,^D8	;OCTAL FOR NOUT
		CVHST		;TYPE HOST NAME IF ANY,
		NOUT		;BUT IF THAT FAILS, TYPE NUMBER
		 ERJMP .+1
		HRROI T1,[ASCIZ / DOWN
/]
		PSOUT
		JRST CHKN2]
	MOVE T3,IMPHL2(IMPUN)	;STATE OF HOSTS AS REPORTED
	XOR T3,IMPHRT(IMPUN)	;COMPARE WITH STATE FROM NCP
	JFFO T3,[MOVE T3,BITS(T4) ;FOUND A DIFFERENCE
		XORM T3,IMPHL2(IMPUN) ;UPDATE LOGGED TABLE
		HRROI T1,[ASCIZ /HOST /]
		PSOUT		;REPORT CHANGE ON LOG TTY
		MOVEI T1,.PRIOU
		MOVEI T2,0(IMPUN) ;COMPUTE HOST NUMBER
		IMULI T2,^D36
		ADDI T2,0(T4)
		MOVEI T3,^D8	;OCTAL FOR NOUT
		CVHST		;TYPE HOST NAME
		NOUT		;OR HOST NUMBER
		 ERJMP .+1
		MOVE T3,BITS(T4)
		HRROI T1,[ASCIZ / UP
/]
		TDNN T3,IMPHL2(IMPUN)
		HRROI T1,[ASCIZ / DOWN
/]
		PSOUT
		JRST CHKN2]
	AOBJN IMPUN,CHKN2	;SCAN TABLES
>				;END OF IFDEF POLLF AT CHKNET
;FALL THRU
;FURTHER BACKGROUND PROCESS CHECKS.

;FALLS THRU FROM ABOVE
	SKIPE NETTCH		;CHANGE OF STATE?
	CALL CHKN5		;YES
	SKIPE IMPGDM		;ANY "IMP GOING DOWN" MESSAGES?
	CALL CHKN7		;YES, GO PRINT IT
	RET

;LOG NWORK CHANGE OF STATE

CHKN5:	HRROI T1,[ASCIZ /
***** NETWORK /]
	PSOUT
	HRROI T1,[ASCIZ /ON/]
	SKIPN NETON
	HRROI T1,[ASCIZ /OFF/]
	PSOUT
	HRROI T1,[ASCIZ /, IMP /]
	PSOUT
	HRROI T1,[ASCIZ /ON/]
	SKIPN IMPRDY
	HRROI T1,[ASCIZ /OFF/]
	PSOUT
	MOVEI T1," "
	PBOUT
	SETZM NETTCH		;NOTE THAT CHANGE HAS BEEN REPORTED
	CALL LGTAD		;REPORT TIME OF THIS CHANGE
	SKIPGE T2,T1		;IF TIME KNOWN
	JRST CHKN5X		;NOT KNOWN.
	MOVEI T1,.PRIOU		;STILL ON CTY
	MOVEI T3,0
	ODTIM
CHKN5X:	TMSG <
>
	RET
;BROADCAST IMP GOING DOWN MESSAGE

CHKN7:	HRROI T1,1(P)		;BUFFER ON PDL
	ADJSP P,20		;20 WORDS OF BUFFER
	HRROI T2,[ASCIZ /IMP GOING DOWN FOR /]
	SETZ T3,		;END ON NULL
	SOUT
	LDB T2,[POINT 10,IMPGDM,31] ;GET NUMBER OF FIVE MINUTE INTERVALS
	IMULI T2,5		;MULTIPLY BY 5 TO GET MINUTES
	MOVEI T3,^D10		;AND REPORT AS DECIMAL NUMBER
	NOUT
	 ERJMP .+1
	HRROI T2,[ASCIZ / MIN IN /]
	SETZ T3,		;END ON NULL
	SOUT
	LDB T2,[POINT 4,IMPGDM,21] ;GET 5 MIN. INTERVALS
	IMULI T2,5		;MULTIPY BY 5 TO GET MINUTES
	MOVEI T3,^D10		;REPORT AS DECIMAL NUMBER
	NOUT
	 ERJMP .+1
	HRROI T2,[ASCIZ / MIN DUE TO /]
	SETZ T3,		;TERMINATE ON NULL
	SOUT
	LDB T2,[POINT 2,IMPGDM,17] ;GET REASON
	HRRO T2,[[ASCIZ /PANIC
/]
		[ASCIZ /SCHED HDWRE PM
/]
		[ASCIZ /SOFTWRE RELOAD
/]
		[ASCIZ /EMRGNCY RESTRT
/]](T2)
	SOUT
	HRROI T2,-17(P)		;GET POINTER TO BUFFER ON STACK
	SETO T1,		;SEND TO EVERYONE
	TTMSG
	ADJSP P,-20		;CLEAN UP STACK
	SETZM IMPGDM		;ZERO MESSAGE WORD
	RET

	RESCD
;ROUTINES TO MAKE FOOTPRINTS FOR DEBUGGING

;TAKE IMP FOOTPRINTS JSYS
;CALL:	T1	JFN OF OUTPUT FILE
;	T2	WORD COUNT (STOPS AT FIRST OPPORTUNITY PAST THIS)
;	T3	RE-INIT FLAG (NON-ZERO TO RESET POINTERS)

;THERE IS NO JSYS DEFINED FOR DBGIM

REPEAT 0,<
.DBGIM::MCENT
	HRRZS T1		;DON'T ALLOW BYTE POINTERS
	MOVX T4,SC%WHL!SC%NWZ
	TDNN T4,CAPENB		;MUST BE WHEEL OR NET-WIZARD
	EMRETN (NTWZX1)		;GIVE ERROR TRAP
	JUMPE T3,DBGIM0		;SKIP INIT STUFF
	NOSKED
	SETZM DBGNWD		;ZERO NUMBER OF WORS IN BUFFER
	SETZM DBGSP		;ZERO POINTER FOR ADDING ENTRIES
	SETZM DBGFAC		;ZERO COUNT OF FAILURES
	OKSKED
	SETZM DBGRP		;ZERO POINTER FOR REMOVING ENTRIES
	AOS DBGRP		;POINT AT FIRST WORD
DBGIM0:	PUSH P,T2		;SAVE COUNT ON STACK
	PUSH P,T1		;AND JFN
DBGDBL:	SKIPG T3,DBGNWD		;ANYTHING IN BUFFER?
	JRST DBGDBW		;NO.  WAIT
	MOVEI T4,DBGNBF		;GET SIZE OF BUFFER
	SUB T4,DBGRP		;GET SPACE TO END OF BUFFER
	CAMGE T3,T4
	MOVEM T3,T4		;KEEP MIN COUNT OF HOW MUCH TO WRITE
	MOVN T3,T4		;GET NEGATIVE COUNT OF WORDS USED
	MOVE T2,DBGRP		;GET POINTER FOR REMOVING FROM BUFFER
	ADD T2,[POINT 36,DBGBUF] ;MAKE IT POINT TO BUFFER
	SOUT			;WRITE TO FILE
	MOVN T3,T4		;GET NEGATIVE OF AMOUNT WRITTEN
	ADDM T3,DBGNWD		;UPDATE NUMBER OF WORDS USED IN BUFFER
	ADDB T4,DBGRP		;AND POINTER FOR REMOVING WORDS
	CAIL T4,DBGNBF		;AT END OF BUFFER
	SETZB T4,DBGRP		;YES RESET POINTER FOR REMOVING
	ADDB T3,-1(P)		;COUNT WORDS WRITTEN
	JUMPG T3,DBGDBL		;CONTINUE IF STILL .GR. 0
	UMOVEM T3,T3		;ELSE RETURN UPDATED COUNT
	ADJSP P,-2		;CLEAN UP STACK
	SMRETN			;SKIP RETURN


DBGDBW:	MOVEI T1,DBGNWD		;SET UP FOR WAIT.
	CALL DISG		;GO WAIT
	MOVE T1,0(P)		;GET JFN BACK
	JRST DBGDBL		;GO WRITE THEM TO THE FILE

;DBGIIM - STASH INPUT IRREGULAR MSG

;	T1/  IRREGULAR MESSAGE HEADER

DBGIIM:	PUSH P,T2		;SAVE T2
	MOVEI T2,1		;ADDINF 1 WORD ENTRY
DBGSIM:	CALL DBGCKS		;CHECK FOR SPACE
	 JRST DBGXIT		;NO SPACE LEAVE
	CALL DBGS2B		;STORE COUNT AND TIME STAMP
	MOVE T2,T1		;GET HEADER IN T2
	CALL DBGS1B		;STORE HEADER
DBGXIT:	OKSKED
	POP P,T2		;RESTORE T2
	RET


;DBGIM - STASH HEADER OF INCOMMING MSG.   BUFFER IN T1

DBGIM:	PUSH P,T2		;SAVE T2
	MOVE T2,1(T1)		;GET HEADER
	TXNE T2,LD%LNK		;LINK = 0
	SKIPA T2,[3]		;NO. SAY 3 WORD ENTRY
	HRRZ T2,0(T1)		;YES.  SAVE ENTIRE MESSAGE
DBGSM:	SOS T2			;DO NOT SAVE BUFFER HEADER
	CALL DBGCKS		;GO RESERVE SPACE
	 JRST DBGXIT		;NO SPACE. EXIT
	PUSH P,T1		;SAVE BUFFER ADDRESS
	CALL DBGS2B		;WHRITE HEADER AND TIME STAMP
	HRRZS T2		;GET NUMBER OF WORDS
	MOVE T1,0(P)		;GET BUFFER ADDRESS BACK
	PUSH P,T2		;SAVE WORD COUNT
DBGSLP:	SOSGE 0(P)		;DECREMENT COUNT
	JRST DBGSL1		;FINISHED.  GET OUT
	MOVE T2,1(T1)		;GET WORD
	CALL DBGS1B		;STORE IT
	AOJA T1,DBGSLP		;GO DO NEXT WORD
DBGSL1:	POP P,T2		;CLEAN UP STACK
	POP P,T1		;RESTORE T1
	JRST DBGXIT		;LEAVE


;DBGOM - STASH HEADERS OF OUTPUT MSG.  BUFFER IN T1

DBGOM:	PUSH P,T2		;SAVE T2
	MOVE T2,1(T1)		;GET HEADER
	TXNE T2,LD%MST		;WAS IT A NOP
	JRST [ HRROI T2,2	;RESERVE TO WORDS AND INDICATE OUTPUT
		JRST DBGSM]
	TXNE T2,LD%LNK		;IS LINK ZERO?
	SKIPA T2,[-1,,3]	;NO JUST DO HEADER, INDICATE OUT.
	HRRO T2,0(T1)		;YES.  DO ENTIRE MSG.  INDICATE OUT.
	JRST DBGSM
;STORE HEADER WORD (IN T2) AND TIME STAMP

DBGS2B:	CALL DBGS1B		;STORE ENTRY HEADER WORD
	PUSH P,T2		;SAVE T2
	EXCH T1,T2		;EXCHANGE T1 AND T2
	GTAD			;GET TIME AND DATE
	EXCH T1,T2		;PUT IT IN T2
	CALL DBGS1B		;STORE TIME AND DATE
	POP P,T2		;RESTORE T2
	RET

;STORE 1 WORD (IN T2) IN DEBUG BUFFER

DBGS1B:	PUSH P,T1		;SAVE T1
	AOS T1,DBGSP		;GET POINTER FOR ADDING ENTRIES
	CAIL T1,DBGNBF		;AT END OF BUFFER
	SETZB T1,DBGSP		;YES.  RESET POINTERS
	MOVEM T2,DBGBUF(T1)	;STORE WORD IN BUFFER
	AOS DBGNWD		;INCREMENT NUMBER OF WORDS IN BUFFER
	POP P,T1		;RESTORE T1
	RET

;CHECK FOR SUFFICIENT SPACE TO MAKE NEW ENTRY
; NUMBER OF WORDS (NOT INCLUDING ENTRY HEADER AND TIME) IN RH OF T2

DBGCKS:	SKIPE DBGFAC		;ANY INTERVENING FAILURES?
	 AOJA T2,DBGCK2		;YES
DBGCK1:	PUSH P,T1		;SAVE T1
	NOSKED
	MOVE T1,DBGNWD		;GET NUMBER OF WORDS IN BUFFER
	ADDI T1,2(T2)		;ADD IN WORDS FOR THIS ENTRY
	CAIG T1,DBGNBF		;BUFFER FULL
	AOSA -1(P)		;NO.  SKIP RETURN
	AOS DBGFAC		;INDICATE FAILURE
	POP P,T1		;RESTORE T1
DBGCK3:	RET

DBGCK2:	CALL DBGCK1		;GO AHEAD AND DO CURRENT ENTRY + 1
	 SOJA T2,DBGCK3		;DID NOT HAVE SPACE
	EXCH T2,DBGFAC		;GET COUNT OF LOST ENTRIES
	HRLI T2,1		;INDICATE TYPE OF ENTRY
	CALL DBGS1B		;TELL THEM HOW MANY WERE LOST
	SOS T2,DBGFAC		;RESTORE T2 TO ORIGINAL VALUE
	SETZM DBGFAC		;ZERO COUNTER OF LOST ENTRIES
	RET
>

DBGIM:				;DUMMY ROUTINES
DBGIIM:
DBGOM:	RET
;IMP ASYNCHRONOUS PROCESS
;STARTED ONCE, CALL FROM RUNDD

IMPBEG::MOVX T1,CR%CAP		;CREATE FORK OF JOB 0 WITH SAME CAPABILITIES
	CFORK
	BUG(HLT,IMPCCF,<CAN'T CREATE IMP FORK>)
	MOVEI T2,IMPBP0
	MSFRK			;START FORK IN MONITOR
	RET

;INIT

IMPBP0:	SE1ENT			;ENTER SECTION 1
	MCENTR
	MOVE T1,FORKX		;GET FORK NUMBER
	MOVEM T1,NCPFRK		;AND SAVE IT AWAY
	MOVE T1,[XWD ITFPC,IMPUXI] ;SET UP TRAP ADDRESS
	MOVEM T1,MONBK
	MOVE T1,CHNSON		;SET UP CHANNELS TO TRAP
	MOVEM T1,MONCHN
	MOVEI T1,NINBFS
	MOVEM T1,IMPNIB		;INIT NUMBER OF BUFFERS TO KEEP ON TAP
	CALL HSTINI		;GET THE SYSTEM TO KNOW NAMES OF SITES
	 BUG(INF,IMPHIF,<HSTINI FAILED TO FIND HOST NAME FILE>)
	MOVEI T1,101		;SET TO ALWAYS BE ON HIGH QUEUE
	MOVEM T1,JOBBIT
	CALL IMPINI		;INITIALIZE THE IMP
	MOVEI T1,T2
	MOVEM T1,IMCLST		;MAKE LAST CLOCK BE DUMMY (AC 2)
;FALL THRU
;FALLS THRU FROM ABOVE
; ALSO RETURNS HERE FROM JRST-EXITS OF BACKGROUD LOOP CHECKS

IMPBP1:	IMSCLK (IMCIDL)		;START CHARGING TIME TO IMCIDL
	PUSH P,[MSEC1,,IMPBP1]	;RETURN FOR FOLLOWING DISPATCHES
	SETZM IMPFLG		;CLEAR REQUEST FLAG
	SKIPL NLHOST		;DO NOTHING IF SETSPD HASNT SET SITE.
	CALL IMPSTT		;CHECK STATE OF NET AND IMP
	 JRST IMPBP3		;DOWN OR SITE NOT YET KNOWN
	SKIPE IMINFB		;GARBAGE BUFFERS TO RELEASE?
	JRST IMINRB		;YES
	MOVE T1,LNKNDL		;DELETES IN LINK TABLE
	CAIL T1,IMPNLK/2	;TIME FOR GC?
	JRST IMPGC		;YES
	SKIPE IMPNCL		;CONTROL MSGS FOR PROCESSING?
	JRST IMPCN0		;YES
	SKIPE IMPIBO		;INPUT BUFFERS READY?
	JRST IMIP1		;YES
	SKIPE IMP8XC		;IRREG MSGS FOR PROCESSING?
	JRST IMP8XM		;YES
	MOVE T1,NETFRE+2	;GET NUMBER OF WORDS OF BUFFER
				; SPACE NOW AVAILABLE
	SKIPE TTNOF		;SCAN OF NET TTYS REQUESTED?
	CAMG T1,ASNTHR		;AND ENOUGH SPACE LEFT?
	 SKIPA			;NO, DON'T SCAN
	JRST IMPTS		;YES
	MOVE T1,IMPNFI
	CAMGE T1,IMPNIB		;NEED INPUT BUFFERS?
	CALL IMPGIB		;YES
	SKIPE IMPNOS		;NEED OUTPUT SCAN?
	CALL IMPOS		;YES
	IMSCLK (IMCIDL)		;BACK TO IMCIDL FOR CHARGING
;FALL THRU
;FALLS THRU FROM ABOVE

IMPBP2:	MOVE T1,TODCLK
	CAML T1,IMPTIM		;TIME FOR LOCAL CHECKS?
	JRST NETCH0		;YES
	CAML T1,RFNTIM		;TIME FOR OVERDUE RFNM CHECK?
	JRST RFNCHK		;YES
	CAML T1,NETTIM		;TIME FOR NETWRK CHECKS?
	 JRST [	IMSCLK (IMCNCC)
		JRST NETCHK]	;YES
	CAML T1,NEGTIM
	 JRST NEGCHK		;CHECK INCOMPLETE NEGOTIATIONS
	CALL SIQCHK		;CHECK SPECIAL QUEUES
	CAMLE T1,IMPTIM
	MOVE T1,IMPTIM		;FIND MINIMUM CLOCK AND USE IT AS
	CAMLE T1,NETTIM		;NEXT TIME TO WAKEUP
	MOVE T1,NETTIM
	CAMLE T1,RFNTIM
	MOVE T1,RFNTIM
	CAMLE T1,NEGTIM
	MOVE T1,NEGTIM
	MOVEM T1,IBPTIM		;SAVE TIME TO DIMISS TILL
	MOVEI T1,IMPBPT		;ADDRESS OF DISMISS ROUTINE
	MDISMS			;DISMISS UNTIL SOMETHING TO DO
	SKIPN ITMSTM		;ANY TTMSG'S OUT
	RET			;NOTHING TO DO RETURN
	AOS TTNOF		;YES, INDICATE THEY NEED TO BE CHECKED
	RET
;SCHEDULER ACTIVATION TEST FOR NCP FORK

IMPBPT:	SKIPE IMPFLG		;FLAG SET?
	JRST 1(T4)		;YES, WAKEUP
	MOVE T1,TODCLK		;CHECK ALARM CLOCK
	CAML T1,IBPTIM		;TIME YET?
	JRST 1(T4)		;YES
	SKIPGE IDVLCK		;LOCK CLEAR AND OUT SCAN NEEDED?
	SKIPG IMPNOS
	JRST 0(T4)		;NO
	JRST 1(T4)		;YES, WAKEUP

IMPBP3:	MOVE T1,TODCLK		;GET TIME OF DAY
	CAML T1,NETTIM		;TIME TO CHECK
	CALL NETCHK		;CONTINUE CALLING NETCHK IF NET DOWN
	MOVEI T1,^D10000
	DISMS			;WAIT 10 SEC
	RET			;THEN TRY AGAIN



;UNEXPECTED INTERRUPT

IMPUXI:	BUG(CHK,IMPUX0,<IMP JB0 FORK - UNEXPECTED INTERRUPT>)
	SE1ENT			;ENTER SECTION 1
	MCENTR
	JRST IMPBP1		;CONTINUE PROCESSING

;UPDATE IMP CLOCKS

IMUCLK:	PUSH P,T1		;SAVE T1
	SUBI T1,IMCIDL		;SUBTACT ADDRESS OF FIRST CLOCK
	AOS IMNIDL(T1)		;COUNT ENTRIES
	CALL GETFRT		;GET FORK RUNTIME IN T1, IN HP UNITS
	SUB T1,IMCCLK		;TIME SINCE LAST MEASUREMENT
	ADDM T1,IMCCLK		;UPDATE TO BE TIME OF THIS CLOCK MEASUREMENT
	ADDM T1,@IMCLST		;CHARGE TO CURRENT CLOCK
	POP P,IMCLST		;SET TO NEW CLOCK
	RET

;SET IDVLCK

IFE PIESLC,<			;VERSION FOR NON-PIE SLICE SCHEDULER
LCKIDV:	PUSH P,T1		;SAVE T1
	NOINT
	LOCK IDVLCK,<JRST LCKID1>
LCKID0:	MOVE T1,JOBBIT		;SAVE THE OLD VALUE OF JOBBIT Q LIMITS.
	MOVEM T1,IMPOJB		;THIS IS NOT A GOOD SYSTEM. SHOULD BE
				;SEPARATE SCHEDULER INFO LIKE IN PIESLC.
	MOVEI T1,101		;HIGH-QUEUE MYSELF WHILE I HAVE LOCK
	DPB T1,[POINT 12,JOBBIT,35] ;AND SAVE THE OLD VALUE.
	MOVE T1,FORKX		;GET FORK NUMBER
	MOVEM T1,IDVLLK		;AND SAVE IT
	POP P,T1		;RESTORE T1
	RETSKP

LCKID1:	MOVE T1,-1(P)		;GET ERROR RETURN INSTRUCTION
	SKIPE (T1)		;IF 0 WAIT WANTED?
	JRST ULKID2		;NO ,RETURN
	MOVEI T1,IDVTST
	MDISMS
	JRST LCKID0

> ;END NON-PIE-SLICE CONDITIONAL

IFN PIESLC,<			;VERSION FOR PIE-SLICE SCHEDULER
LCKIDV:	NOINT
	LOCK IDVLCK,<JRST LCKID1>,SPQ
LCKID0:	PUSH P,FORKX		;SAVE FORK NUMBER
	POP P,IDVLLK
	RETSKP

LCKIDT1:	PUSH P,1
	MOVE T1,-1(P)		;GET ERROR RETURN INSTRUCTION
	SKIPE (T1)		;IF 0 WAIT WANTED?
	 JRST [POP P,T1
		OKINT
		JRST RELSPQ##]	;RETURN VIA RELSPQ, NORMAL SCHEDULING
	MOVEI T1,IDVTST
	MDISMS
	POP P,T1
	JRST LCKID0
> ; END OF IFN PIESLC CONDITIONAL

;UNLOCK IDVLCK

ULKIDV:
IFE PIESLC,<
	PUSH P,T1		;SAVE T1
	MOVE T1,IMPOJB		;RESTORE JOBBIT FROM LOCK ABOVE
	DPB T1,[POINT 12,JOBBIT,35] ;JUST THE QUEUE LIMITS
ULKID2:	POP P,T1
>
REPEAT 0,<	UNLOCK IDVLCK,RESIDENT,SPQ>
REPEAT 1,<			;(TENEX LOCKING MECHANISM NOT SUPRTD
	UNLOCK IDVLCK>		;FREE IMP LINK TABLES AND DEVICE

	OKINT
	RET

IDVTST:	AOSE IDVLCK		;UNLOCKED YET?
	 JRST 0(T4)		;NO CONTINUE WAIT
	JRST 1(T4)		;YES
;RELEASE BUFFERS LEFT BY PI ROUTINES

IMINRB:	IMSCLK (IMCNRB)		;CHARGE TIME TO RELEASING BUFFERS
	SETZ T4,
	EXCH T4,IMINFB		;GET ALL GARBAGE BUFFERS
IMINR1:	JUMPE T4,R		;QUIT WHEN ALL RELEASED
	HRLI T4,ANBSEC		;SET SECTION NUMBER
	MOVE T2,T4		;GET BUFFER ADDRESS INTO T2
	HLRZ T4,0(T4)		;GET NEXT BUFFER IN CHAIN
	CALL RLNTBF		;RELEASE ONE
	JRST IMINR1		;TRY NEXT BUFFER

;GET ONE BUFFER FOR INPUT AND LOCK IT IN CORE

IMPGIB:	IMSCLK (IMCGIB)		;CHARGE TO IMCGIB
IMPGI1:	MOVEI T2,MAXWPM		;FOR MAX INPUT MSG
	CALL ASNTBF		;ASSIGN FROM POOL
	 JRST IMPB03		;NO BUFFERS
	MOVE T2,T1		;GET ADDRESS IN T2
	CALL IMPLKB		;LOCK BUFFER
	PIOFF
	EXCH T2,IMPFRI		;PUT BFR ON INPUT FREE LIST
	HRLM T2,0(T1)		;PUT OLD TOP OF LIST IN NEW BUFFER
	AOS T2,IMPNFI		;COUNT NUMBER FREE, IF WAS 0, THEN
	PION
	SKIPN IMIB		;INPUT IS OFF?
	SKIPG IMPNFI		;YES, BUFFERS AVAILABLE?
	 CAIA			;NO
	CALL IMISRT		;YES, RESTART
	MOVE T2,IMPNFI		;GOT ENOUGH BUFFERS?
	CAMGE T2,IMPNIB
	 JRST IMPGI1		;NO
	RET
;SCAN NET TTY LINES

IMPTS:	IMSCLK (IMCTS)		;CHARGE TO IMCTS
	SETZM TTNOF		;INDICATE THAT NVTS HAVE BEEN SCANNED
	MOVE P1,NVTPTR		;COUNT THRU NVT LINES
IMPTS1:	HRR T2,P1		;GET TERMINAL NUMBER IN T2
	CALL LCKTTY		;GET ADDRESS OF DYNAMIC DATA
	 JUMPLE T2,IMPTS2	;IF NON-STANDARD BLOCK CHECK FOR OUTPUT
	PUSH P,T2		;SAVE ADDRESS OF DYNAMIC DATA
	CALL TTSOBE		;ANY OUTPUT?
	 CALL NETTCS		;YES
	POP P,T2		;GET BACK ADDRESS OF DYNAMIC DATA
IMPTS2:	CALL ULKTTY		;UNLOCK TTY DATABASE
	AOBJN P1,IMPTS1
	SKIPN T2,ITMSTM		;ANY TTMSG'S OUT
	RET			;NOTHING TO DO RETURN
	CAMLE T2,TODCLK		;TIME TO FLUSH YET?
	RET			;NO, RETURN
	NOSKED			;PREVENT ANYONE ELSE FROM CHANGE DATA
	CALL TMSNTR		;FLUSH ALL TTMSG'S TO NVT'S
	OKSKED
	SETZM ITMSTM		;CLEAR TIMER
	RET



;SCAN ALL CONNECTIONS FOR OUTPUT POSSIBLE
;CALLED BY ASYNCH PROCESS

IMPOS:	IMSCLK (IMCOS)		;CHARGE TO IMCOS
	MOVSI Q2,-IMPNLK	;SET UP AOBJN POINTER -# LINKS,,0
	SETZM IMPNOS		;CANCEL REQUEST FOR SCAN
IMPOS2:	HRRZ T2,IMPLT1(Q2)	;GET STATE OF LINK
	TXNE T2,L1%SND		;OUTPUT CONNECTION HAS SEND BIT ON
	TXNE T2,L1%FRE		;AND NOT FREE
IMPOS1:	AOBJN Q2,IMPOS2		;NO.  NOT OUTPUT TRY NEXT ONE
	JUMPGE Q2,[ADJSP P,-1	;RETURN TO CALLER'S CALLER (IMPBP1)
		RET]
	ILOCK(<JRST [AOS IMPNOS	;TRY AGAIN LATER
		RET]>)		;RETURN IF CAN'T SET LOCK
	MOVEI T1,0(Q2)		;GET INDEX IN T1
	CALL IMPKO1		;CHECK AND SEND IF POSSIBLE
	JRST IMPOS1
;ASYNCH PROCESS TO PUT BUFFERS ON PROPER CONNECTION QUEUES

IMIP1:	IMSCLK (IMCP1)		;CHARGE TO IMCP1
	MOVE T2,IMPIBO		;TRY TO GET NEXT BUFFER
	JUMPE T2,R		;NONE LEFT
	PIOFF			;TURN OFF PI TO PROTECT BUFFERS
	HLRZ T3,0(T2)		;GET NEXT BUFFER IN CHAIN
	JUMPN T3,IMIP1A		;IS THERE ONE
	SETZM IMPIBI		;NO.  ZERO POINTER FOR REMOVING
	SKIPA			;DO NOT SET SECT NUMBER SO PTR WILL = 0
IMIP1A:	HRLI T3,ANBSEC		;SET SECTION NUMBER
	MOVEM T3,IMPIBO		;UPDATE POINTER FOR REMOVING BUFFERS
	PION			;FINISHED WITH POINTERS TURN PI ON
	PUSH P,T2		;SAVE BFR ADDRESS
	MOVE T1,T2		;GET BUFFER ADDRESS INTO T1
	CALL DBGIM		;GO SAVE THINGS FOR DEBUGGING
	NOSKED
	HRRZ T2,0(T2)		;GET SIZE FIELD
	CAILE T2,MAXWPM		;MAKE SURE ITS NOT ON FREELIST
	 BUG(HLT,IMPUFB,<IMIP1: ATTEMPT TO UNLOCK BUFFER ON FREELIST>)
	MOVE T2,0(P)		;RESTORE T2
	CALL MULKSP		;UNLOCK HEAD
	HRRZS 0(T2)		;CLEAR FWD POINTER
	MOVE T1,1(T2)		;GET HEADER
	ANDX T1,<LD%FIM!LD%LNK>	;EXTRACT LINK + FROM IMP BIT
	CAML T1,[MAXNCP]	;NORMAL LINK?
	 JRST IMIPSQ		;NO, DISPATCH TO SPECIAL Q
	OKSKED
	LOAD T1,<LD%HST!LD%LNK>,1(T2) ;GET HOST-LINK
	ILOCK
	CALL LNKLUK		;SEE IF CONNECTION EXISTS
	 JRST [	TXNE T1,L1%LNK	;DOESN'T, CONTROL LINK?
		JRST IMIBB	;LINK NON-EXISTANT
		MOVEI T3,^D8	;CREATE CONNECTION, BYTE SIZE IS 8
		CALL IMPOP1
		HRROS IMPLT1(T1) ;MAKE UNIT -1
		MOVEI T3,377777
		HRRM T3,IMPLT4(T1) ;SET INFINITE MSG ALLOC
		AOS IMPNCL	;COUNT CONTROL CONNECTIONS
		JRST .+1]
	POP P,T2		;RESTORE T2 BUFFER ADDRESS
	HRRZ T3,IMPLT2(T1)	;GET ADD. OF LAST BUFFER FOR THIS CONN
	HRRM T2,IMPLT2(T1)	;SAVE NEW LAST BUFFER ADDRESS
	JUMPE T3,[HRLM T2,IMPLT3(T1) ;NO OLD BUFFER. SET REMOVAL PTR
		JRST IMIP1B]	;NO QUEUE TO UPDATE
	HRLI T3,ANBSEC		;SET SECTION NUMBER FOR BUFFERS
	HRLM T2,0(T3)		;PUT MSG ON QUEUE FOR CONN
IMIP1B:	HLRE IMPUN,IMPLT1(T1)	;GET CONNECTION NUMBER
	IUNLK
	JUMPL IMPUN,R		;SEE IF NVT CONNECTION
	LOAD T2,ANNVT,(IMPUN)	;GET NVT NUMBER
	CALL NVTCHK		;IS IT AN NVT
	 RET			;ISN'T
	PUSH P,T2		;SAVE ADDRESS OF DYNAMIC DATA
	PUSH P,T1		;SAVE LT INDEX
	IMSCLK (IMCNVI)		;ACCOUNT THE TIME FOR NVT INPUT
	POP P,T1		;RESTORE LT INDEX
	POP P,T2		;GET BACK ADDRESS OF TTY DYNAMIC DATA
	CALL NVTUPI		;UNPACK NVT INPUT
	CALL ULKTTY		;UNLOCK DATA BASE
	RET
;IMIPSQ - ADD MESSAGE TO SPECIAL QUEUE

;	T2/  BUFFER ADDRESS

IMIPSQ:	MOVSI T3,-NSQ		;SET UP AOBJN POINTER.  -# OF SP. Q,,0
IMIPS1:	SKIPGE T1,SQJOB(T3)	;IN USE?
	JRST IMIPQA		;NO
	LSH T1,2		;ALIGN VALUE WITH INTERNET DISPATCH
	XOR T1,5(T2)		;COMPARE
	LSH T1,6		;ALIGN WITH MASK
	AND T1,SQJOB(T3)	;MASK BITS TO COMPARE
	TLNE T1,177400		;ONLY CONSIDER THESE BITS
	JRST IMIPQA		;NO MATCH
	MOVE T1,1(T2)		;GET HEADER
	XOR T1,SQVAL(T3)	;COMPARE TO VALUE
	TDNE T1,SQMSK(T3)	;YES, EQUAL?
IMIPQA:	AOBJN T3,IMIPS1		;NO OR NO.  TRY NEXT QUEUE
	JUMPGE T3,IMIPS2	;FOUND NOBODY, GO THROW AWAY
	MOVE T1,SIQSPC(T3)	;HOW MUCH SPACE IN USE?
	CAIL T1,SIQMAX		;LESS THAN MAX?
	JRST IMIPS2		;NO, TOO MUCH, GO THROW AWAY
	MOVE T1,TODCLK		;GET TIME OF DAY
	ADDI T1,SIQTM0		;ADD SPECIAL Q TIME LIMIT
	SKIPN T4,SIQIBI(T3)	;FIRST BUFFER (QUEUE EMPTY?)
	JRST [MOVEM T1,SIQTIM(T3) ;RECORD DISCARD TIME
		MOVEM T2,SIQIBO(T3) ;UPDATE REMOVAL POINTER ALSO
		JRST IMPSQ4]	;NO QUEUE TO UPDATE
	HRLM T2,0(T4)		;CHAIN IN NEW BUFFER
IMPSQ4:	MOVEM T2,SIQIBI(T3)	;SAVE NEW BUFFER ADDRESS
	AOS SIQSPC(T3)		;COUNT MESSAGES ON QUEUE
	OKSKED
	JRST IMIPS3		;FIX UP STACK AND RETURN

IMIPS2:	OKSKED
	CALL RLNTBF		;THROW MESSAGE AWAY
IMIPS3:	ADJSP P,-1		;RETURN TO CALLER'S CALLER (IMPBP1)
	RET
;IMIBB - SEND NXR AND DO UNKNOWN LINK BUGINF

;	T1/  HOST AND LINK RIGHT JUSTIFIED
;	BUFFER ADDRESS ON TOP OF STACK

IMIBB:	IUNLK
	LSHC T1,-8		;HOST IN T1
	ROT T2,8		;LINK IN T2
	ANDX T1,HSTMSK		;JUST HOST
	ANDX T2,L1%LNK		;AND JUST LINK
	PUSH P,T1		;SAVE T1 AND T2 FOR BUGINF
	PUSH P,T2
	CALL IMPNXR		;SEND NXR
	POP P,T2		;RESTORE T1 AND T2
	POP P,T1
	BUG(INF,IMPMUL,<RECEIVED MSG FOR UNKNOWN LINK>,<T1,T2>)
	POP P,T2		;GET BUFFER ADDRESS BACK
	CALLRET RLNTBF		;RELEASE BUFFER
;SEND RST TO ALL NAMED HOSTS ON STARTUP

NETCH0:	IMSCLK (IMCNCK)		;CHARGE TO IMCNCK
	SKIPGE Q3,IMPCCH	;SENDING RST'S?
	JRST IMPET		;NO.
IMPRC1:	MOVE T1,NETFRE+2	;Don't deplete all buffers
	CAMLE T1,ASNTHR		;Wait for reasonable reserve
	CALL IMPRCC		;CHECK FOR SPACE IN LINK TABLE
	 JRST [	MOVEI T1,^D50	;GO WAIT 50 MSEC.
		JRST IMPET1]
	HRRZ T2,Q3		;GET THE HOST WE ARE WORKING ON
	CAMN T2,NLHOST		;LOCAL HOST?
	JRST IMPRC2		;NEVER SEND RESET TO LOCAL HOST
	MOVEI T1,377777		;NIL DESIGNATOR FOR CVHST
	CVHST			;SEE IF THE HOST HAS A NAME
	 JRST IMPRC2		;IT DOESN'T. DON'T SWAMP NET WITH 
				; RESETS TO NONEXISTENT HOSTS.
	HRRZ T1,Q3		;RESTORE HOST NUMBER FOR IMSRST
	HRRZ T2,Q3		;HOST EXISTS. SEE IF IT'S UP ALREADY
	IDIVI T2,^D36		;GET WORD IN BIT TABLE
	MOVE T3,BITS(T3)	;AND BIT
	TDNN T3,IMPHRT(T2)	;NO RESET IF ALREADY UP
	CALL IMSRST		;NOT UP SO SEND RESET
IMPRC2:	CAIG Q3,NHOSTS		;DONE ALL HOST YET?
	AOJA Q3,IMPRC1		;NO GO DO NEXT ONE
IMPEET:	SETZM IMPHCT		;YES.  ZERO RECENT MESSAGE SENT 
	MOVE T1,[IMPHCT,,IMPHCT+1] ;BIT TABLE
	BLT T1,IMPHCT+IMPLBT-1
	MOVSI Q3,-IMPNLK	;INDICATE NOW ECHO CHECKING
	MOVE T1,[UPROBI-UPROBT]	;SET TIME TO WAKE UP
	JRST IMPET1		;GO FINISH

IMPRCC:	MOVE T1,IMPNOL		;NUMBER OF LINKS IN USE
	CAIG T1,IMPNLK/4-10	;QUATER FULL?
	AOS 0(P)		;NO.  INDICATE ROOM
	RET			;YES INDICATE NO ROOM
;ECHO TESTER

IMPET:	MOVEI T1,^D120000	;TIME FOR NEXT TEST
	SKIPL IMPRDY		;IMP UP?
	JRST IMPCC6		;DON'T PROBE IF NCP NOT FULLY UP
	CALL IMPRCC		;CHECK SPACE IN LINK TABLE
	 JRST [	MOVEI T1,^D5000	;TRY AGAIN IN 5 SECONDS
		JRST IMPCC6]
	MOVE T1,IMPLT1(Q3)	;GET STATE, HOST AND LINK #
	TXNE T1,L1%FRE		;ACTIVE?
	JRST IMPET4		;NO, GET NEXT
	LSH T1,-8
	ANDX T1,HSTMSK		;GET THE HOST
	MOVE T2,T1		;GET HOST IN T2
	IDIVI T2,^D36		;COMPUTE BIT TABLE INDEX
	MOVE T3,BITS(T3)
	TDNE T3,IMPHCT(T2)	;RECENTLY SENT A MESSAGE
	 JRST [	ANDCAM T3,IMPHCT(T2)
		JRST IMPET4]	;CLEAR SO WE WILL SEND NEXT TIME NOT THIS
	IORM T3,IMPHCT(T2)	;REMEMBER WE HAVE SENT ONE
	MOVE T2,T1		;IF UP, DATA=HOST
	CALL IMPNOP		;AND SEND NOP (ECHO MIGHT BE BETTER)
IMPET4:	AOBJP Q3,IMPEET
	TRNE Q3,7		;WAIT EVERY EIGHTH ENTRY
	 JRST IMPET		;NOT TIME TO WAIT.  TRY ANOTHER
	MOVEI T1,UPROBT*8/IMPNLK ;DELAY FOR CORRECT INTERVAL
IMPET1:	MOVEM Q3,IMPCCH		;SAVE CURRENT STATE
IMPCC6:	ADD T1,TODCLK		;COMPUTE WHEN TO DO IT AGAIN
	MOVEM T1,IMPTIM		;STORE TIME AWAY
	RET
;CHECK FOR OVERDUE RFNM'S
;COUNT DOWN RFNM COUNT FIELD IF NON-ZERO.
;IF IT REACHES 0, THEN GENERATE BUGINF BECAUSE RFNM SEEMS LOST

RFNCHK:	IMSCLK (IMCRFN)		;CHARGE IMCRFN
	MOVSI P1,-IMPNLK	;SET TO SCAN CONN TABLE
RFNCK0:	MOVX Q2,RFNMCM		;GET RFNM COUNT MASK
	MOVX IMPUN,L1%FRE	;CONNECTION IN USE BIT
RFNCK2:	TDNN IMPUN,IMPLT1(P1)	;CONNECTION IN USE?
	TDNN Q2,IMPLT2(P1)	;YES. RFNM SET HERE?
RFNCK1:	AOBJN P1,RFNCK2		;NO.  TRY NEXT ONE
	JUMPGE P1,RFNCK4	;FINISHED ALL OF TABLE
	LOAD Q3,RFNMC,(P1)	;GET RFNM COUNT FIELD
	SOJE Q3,RFNCK5		;DECREMENT COUNT, JUMP IF EXHAUSTED
	STOR Q3,RFNMC,(P1)	;STORE UPDATED COUNT
	JRST RFNCK1		;GO TRY NEXT ONE

RFNCK5:	PIOFF			;PREVENT CONFUSION IF PI STORES BUFFER
	HRRZ T2,IMPLT3(P1)	;WHILE WE GET MESSAGE TO RETRANSMIT
	HLLZS IMPLT3(P1)	;AND CLEAR THE POINTER
	PION
	JUMPE T2,RFNCK3		;APPARENTLY HASN'T MADE IT THRU Q YET
	HRLI T2,ANBSEC		;SET THE BUFFER SECTION NUMBER
	HRRZ T3,IMPLT1(P1)	;GET HOST/LINK
	ROT T3,-8		;SHIFT DOWN TO HOST
	ANDX T3,HSTMSK		;RETAIN ONLY HOST
	MOVSI IMPUN,(RXMTF)	;RETRANMISSION FLAG
	CAME T3,NLHOST		;IF LOCAL HOST
	TDNE IMPUN,IMPLT2(P1)	;OR RETRANSMISSION WANTED?
	JRST RFNCK7		;THEN RETRANSMIT
	CALL RLNTBF		;ELSE RELEASE THE BUFFER
	STOR Q3,RFNMC,(P1)	;ZERO RFNM COUNT
	HRRZ T2,IMPLT1(P1)	;RFNM LOST. GET HOST-LINK
	CALL IMP8X1		;REFORMAT FOR BUG MSG
	BUG(INF,IMPRNO,<RFNM OVERDUE>,T2)
	AOS IMPNOS		;CAUSE OUTPUT SCAN TO RESTART OUTPUT
RFNCK6:	AOBJN P1,RFNCK0		;RESET IMPUN AND Q2
RFNCK4:	MOVEI T1,RFNTMO		;FINISHED.  GET RFNM TIME OUT INTERVAL
	ADD T1,TODCLK		;SET NEXT CHECK FOR RFNTMO MSEC.
	MOVEM T1,RFNTIM		;STORE TIME
	RET

RFNCK7:	IORM Q2,IMPLT2(P1)	;SET RFNM COUNT AGAIN
	CALL IMPQOA		;PUT MESSAGE BACK ON OUTPUT QUEUE
	JRST RFNCK6		;GO TO NEXT ITEM

RFNCK3:	IORM Q2,IMPLT2(P1)	;SET RFNM COUNT AGAIN
	HRRZ T2,IMPLT1(P1)	;GET HOST/LINK
	CALL IMP8X1		;FORMAT FOR BUG MSG
	BUG(INF,IMPMSO,<MESSAGE STUCK IN OUTPUT QUEUE>,T2)
	JRST RFNCK6		;GO ON TO NEXT ITEM
;QUEUE IRREG MSG

IMP8XQ::AOS T3,IMP8XI		;INCREMENT INPUT INDEX
	CAIL T3,IMP8XS		;END OF BUFFER?
	SETZB T3,IMP8XI		;YES.  RESET POINTERS
	CAMN T3,IMP8XO		;OVERFLOW?
	BUG(INF,IMPXBO,<IRREG MSG BUFFER OVERFLOW>)
	MOVEM T2,IMP8XB(T3)	;SAVE MESSAGE IN BUFFER
	AOS IMP8XC		;ACCOUNT FOR THIS MESSAGE
	RET

IMP8XM:	IMSCLK (IMC8XM)		;CHARGE TO IMC8XM
	AOS T3,IMP8XO		;RETRIEVE STUFF FROM QUEUE
	CAIL T3,IMP8XS		;END OF BUFFER?
	SETZB T3,IMP8XO		;YES.  RESET POINTERS
	MOVE T1,IMP8XB(T3)	;GET MESSAGE
	SOS IMP8XC		;ACCOUNT FOR REMOVAL OF MESSAGE
	CALL DBGIIM		;SAVE INFO FOR DEBUGING
	LOAD T3,LD%MST,T1	;GET MESSAGE TYPE CODE
	LOAD T2,<LD%HST!LD%LNK>,T1 ;GET HOST-LINK
	XCT IMPMTT(T3)		;DISPATCH TO APPROPRIATE ROUTINE
	RET

XX==JRST IMP8XX			;UNIMPLEMENTED CODE

IMPMTT:	BUG(HLT,IMPRMI,<IMP - REGULAR MESSAGE ON IRREG QUEUE>)
	JRST IMPEC1		;ERROR
	JRST IMPDN2		;IMP GOING DOWN
	XX			;FORMERLY BLOCKED LINK
	JFCL			;NOP
	JRST IMRFNM		;RFNM
	JRST IMPEC6		;DEAD HOST STATUS
	JRST IMPEC7		;DESTINATION DEAD
	JRST IMPEC8		;ERROR
	JRST IMPEC9		;INCOMPLETE TRANSMISSION
	JRST IMPE10		;IMP DROPPED READY LINE
	XX			;CEASE TIMEOUT
	XX			;CEASE SENT
	XX			;UNASSIGNED
	XX			;"
	JFCL			;TREAT LONG LEADER TYPE AS NOP
;IRREGULAR MESSAGE PROCESSORS

;	T1/  CONTAINS MESSAGE
;	T2/  CONTAINS HOST-LINK
;	T3/  CONTAINS MESSAGE TYPE

;ERROR IN LEADER (TYPE 1)

IMPEC1:	TXNN T1,<LD%HST!LD%LNK>	;ARE HOST AND LINK BOTH ZERO?
	RET			;YES. DISCARD, ELSE WILL BE ERROR.
	TRNN T1,377B31		;SUB-TYPE 0?
	JRST IMPEC8		;YES, RETRANSMIT
	JRST BADIRM		;GO CAUSE IT TO BE PRINTED

;IMP GOING DOWN (TYPE 2)

IMPDN2:	MOVEM T1,IMPGDM		;SAVE IT FOR PRINTING
	AOS JB0FLG		;REQUEST JOB 0 SERVICE
	MOVEM T1,IGDMSG		;SAVE FOR LAST IMP GOING DOWN MSG
	GTAD			;GET TIME AND DATE
	MOVEM T1,IGDTIM		;SAVE TIME MESSAGE WAS RECIEVED
	RET

;RFNM (TYPE 5)

IMRFNM:	MOVEI T1,L1%SND(T2)	;HOST AND LINK, DENOTE SEND CONNECTION
	ILOCK
	CALL LNKLUK		;LOOKUP IN LINK TABLE
	 JRST BADIRY		;NOT FOUND.  GO DO BUGINF
	PUSH P,T1		;SAVE INDEX TO LINK TABLES
	MOVX T2,RFNMCM		;GET RFNM COUNT BITS
	PIOFF			;IF RFNM RETURNS BEFORE MSG OUT DONE
	ANDCAM T2,IMPLT2(T1)	; CLEAR RFNM AND CHECK FLAGS
	HRRZ T2,IMPLT3(T1)	;GET RETRANSMIT BUFFER
	HLLZS IMPLT3(T1)	;ZERO RETRANSMISSION BUFFER ADD.
	PION
	HRLI T2,ANBSEC		;SET BUFFER SECTION NUMBER
	TRNE T2,-1		;WAS THERE A BUFFER
	CALL RLNTBF		;YES.  RELEASE IT
	POP P,T1		;GET LINK TABLE INDEX BACK
	HLRE IMPUN,IMPLT1(T1)	;GET IMPUN
	MOVSI T2,(RXMTF)	;GET RETRANSMISSION FLAG
	TDNN T2,IMPLT2(T1)	;HAVE WE BEEN RETRANSMITTING?
	JRST IMPKO1		;NO. JUST SEND NEXT MESSAGE
	ANDCAM T2,IMPLT2(T1)	;YES. STOP RETRANSMITTING
	CALL IMPKO1		;SEND NEXT MESSAGE
	JUMPGE IMPUN,SVCRST	;IF NOT CTRL GENERATE SERVICE RESTORED
	RET
;DEAD HOST STATUS (TYPE 6)

IMPEC6:	TLNE T1,(1B1)		;USUAL TYPE?
	RET			;NO. IGNORE IT
	ROT T2,-9		;GET HOST NUMBER/2 LOW BIT IN B0
	LSH T1,-4		;GET MSG ID -- SUBTYPE
	ANDI T1,177777		;KEEP 16 BITS
	IORI T1,1B18+1B19	;MARK INFO VALID AND DEAD
	HRRZ T3,T2		;GET JUST RIGHT HALF FOR INDEX
	JUMPL T2,[		;ODD HOST?
		HRRM T1,HSTSTS(T3) ;YES, STORE IN RH
		JRST .+2]
	HRLM T1,HSTSTS(T3)	;NO, STORE IN LH
	ANDI T1,17		;EXTRACT SUB-TYPE
	CAIE T1,2		;IS IT SIMPLY TARDY?
	CAIN T1,^D10		;OR AT A BPT
	RET			;YES, NO FURTHER ACTION
	ROT T2,9		;NO. GET BACK HOST/LINK
	JRST IMPDD1		;AND DECLARE IT DEAD

;DESTINATION DEAD (TYPE 7)

IMPEC7:	PUSH P,T2		;SAVE HOST-LINK
	LOAD T1,L1%HST,T2	;EXTRACT HOST NUMBER
	IDIVI T1,^D36
	MOVE T1,IMPHRT(T1)	;GET HOST UP BITS
	AND T1,BITS(T2)		;MASK IN THE CORRECT ONE
	POP P,T2		;RETORE HOST-LINK
	JUMPE T1,IMPDD1		;IF ALREADY DOWN, CALL IT DOWN
	MOVE T1,T2		;HOST/LINK
	IORX T1,L1%SND		;SEND
	ILOCK
	CALL LNKLUK		;FIND THE LINK
	 JRST BADIRY		;GO LOG ERROR WITH BUGINF
IMPECC:	MOVSI T2,(RXMTF)	;GET RETRANSMISSION FLAG
	IORM T2,IMPLT2(T1)	;CAUSE RETRANSMISSION
	HLRE IMPUN,IMPLT1(T1)	;GET "UNIT"
	IUNLK
	JUMPL IMPUN,R		;DONE IF CONTROL CONNECTION
	CALL SVCINT		;ELSE PERFORM SERVICE INTERRUPTION
	RET

IMPDD1:	LOAD T1,L1%HST,T2	;EXTRACT HOST NUMBER
HSTDED::MOVEI T3,0(T1)		;GET HOST NUMBER IN T3
	IDIVI T3,^D36		;GET WORD AND BIT FOR TABLE
	MOVE IMPUN,BITS(T4)
	TDNE IMPUN,IMPHRT(T3)	;DID WE ALREADY KNOW HE WAS DOWN?
	IFDEF POLLF,<
	IORM IMPUN,IMPHL1(T3)>	;REQUEST OBITUARY
	ANDCAM IMPUN,IMPHRT(T3)	;MARK HIM DOWN
	CALL IMPXLT		;CLEAR LINK TABLE FOR DEAD HOST
	CALL NETHDN		;CLEAN UP ANY CONNECTIONS TO HOST
	RET
;ERROR IN DATA & INCOMPLETE TRANSMISSION (TYPES 8 & 9)

IMPEC8:
IMPEC9:	MOVEI T1,L1%SND(T2)	;SEND CONNECTION
	ILOCK
	CALL LNKLUK		;GET LT INDEX FOR THIS ONE
	 JRST BADIRY		;NOT THERE, CAN'T RETRANSMIT. LOG ERROR
	PIOFF			;PREVENT PI FROM STORING IN IMPLT3
	HRRZ T2,IMPLT3(T1)	;GET BUFFER FOR RETRANSMISSION
	HLLZS IMPLT3(T1)	;CLEAR RETRANSMISSION BUFFER ADDRESS
	PION
	JUMPE T2,IMPECC		;NONE THERE NOW. RETRANSMIT LATER
	IUNLK
	HRLI T2,ANBSEC		;SET SECTION NUMBER
	CALL IMPQOA		;PUT IT BACK ON OUTPUT QUEUE
	RET
;INTERFACE RESET (TYPE 10)

IMPE10:	MOVSI T1,-IMPNLK	;SET UP TO SCAN LINK TABLES
IMPRSY:	PUSH P,T1		;SAVE INDEX
	ILOCK
	MOVE T2,IMPLT1(T1)	;GET STATE HOST AND LINK
	TXNE T2,L1%FRE		;IN USE?
	JRST IMPZSY		;NO
	TXNN T2,L1%LNK		;LINK ZERO?
	JRST IMPZSY		;YES.  CONTROL
	TXNE T2,L1%SND		;SEND?
	JRST IMPSSY		;YES
	LOAD T2,LTLINK,(T1)	;GET LINK NUMBER
	LOAD T1,LTHOST,(T1)	;GET HOST NUMBER
	IUNLK
	CALL IMPRAP		;SEND RAP
	JRST IMPXSY


IMPSSY:	CALL IMPSYN		;RESYNC ALLOCATION
IMPZSY:	IUNLK
IMPXSY:	POP P,T1		;RESTORE INDEX
	AOBJN T1,IMPRSY		;TRY NEXT ENTRY
	AOS IMPNOS		;DONE. SCAN FOR OUTPUT TO PICK UP RARRF'S
	RET
;CHECK IF HOST FOR CONTROL MESSAGE KNOWS ABOUT NEW PROTOCOL STUFF

;	T1/  HOST NUMBER

CHKNWP:	PUSH P,T2		;SAVE T2 AND T1
	PUSH P,T1
	IDIVI T1,^D36		;CALCULATE WORD AND BIT FOR TABLE
	MOVE T2,BITS(T2)
	TDNE T2,NWPBT(T1)	;DOES IT UNDERSTAND NEW PROTOCOL
	AOS -2(P)		;YES SKIP RETURN
	POP P,T1		;RESTORE T1 AND T2
	POP P,T2
	RET

; MARK NEW PROTOCOL BIT FOR HOST

;	T1/  HOST NUMBER

MRKNWP:	PUSH P,T1		;SAVE T1 AND T2
	PUSH P,T2
	IDIVI T1,^D36		;CALCULATE WORD AND BIT FOR TABLE
	MOVE T2,BITS(T2)
	IORM T2,NWPBT(T1)	;INDICATE THAT HE UNDERSTANDS NEW PROTOCOL
	POP P,T2		;RETORE T2 AND T1
	POP P,T1
	RET

;ERROR TAIL ENDS FOR IRREGULAR MSG PROCESSORS

BADIRY:	IUNLK
	MOVE T2,IMP8XO		;GET POINTER FOR REMOVING IRREG. MSG.
	MOVE T1,IMP8XB(T2)	;GET IRREGULAR MESSAGE AGAIN
	LOAD T2,<LD%HST!LD%LNK>,T1 ;GET HOST-LINK
BADIRM:
IMP8XX:	CALL IMP8X1		;FORMAT HOST LINK
	BUG(INF,IMPXUT,<RECEIVED IRREG MSG WITH UNKNOWN LINK OR TYPE>,<T1,T2,T3>)
	RET

IMP8X1:	DPB T2,[POINT 8,T2,9]	;UNPACK HOST-LINK IN B20-35 INTO
	LSH T2,-^D8		;XWD LINK,HOST
	TRZ T2,777400
	RET

;SCAN FOR INPUT READY ON CONTROL LINK CONNECTION

IMPCN0:	IMSCLK (IMCCNP)		;CHARGE TO IMCCNP
	MOVX IMPUN,L1%SND!L1%FRE!L1%LNK ;CONNECTION MUST BE RECEIVE, LINK 0
	PUSH P,BHC		;PUT A ZERO ON STACK
	MOVSI Q2,-IMPNLK	;SET UP TO SCAN ENTIRE TABLE
IMPCN4:	TDNE IMPUN,IMPLT1(Q2)	;DESIRED CONNECTION?
	AOBJN Q2,IMPCN4		;NO.  TRY NEXT ONE
	JUMPGE Q2,IMPCN5	;DONE?
	AOS 0(P)		; NO.  COUNT NUMBER OF MSGS SEEN
	MOVEI T1,0(Q2)		;CONN INDEX
	PUSH P,IMPUN		;SAVE IMPUN AND Q2
	PUSH P,Q2
	CALL IMPCNP		;GO PROCESS THIS HOST'S CONTROL MSGS
	POP P,Q2		;RESTORE Q2 AND IMPUN
	POP P,IMPUN
	MOVEI T1,0(Q2)		;GET INDEX IN T1 AGAIN
	CALL IMPCLL		;CLOSE "CONNECTION"
	JRST IMPCN4
IMPCN5:	POP P,T1		;DONE. GET COUNT OF PROCESSED MSGS
	JUMPN T1,R		;IF ANY, DONE.
	BUG(INF,IMPCTH,<IMPNCL TOO HIGH>)
	SOS IMPNCL		;COUNT IT DOWN SO DON'T LOOP.
	RET

;CONTROL TABLE FOR CONTROL OPCODES

	DEFINE CTOP (A,C)
<	XWD IM8'A,C>

IM8RTS=RECRTS			;CODE IN NETWRK
IM8STR=RECSTR			;CODE IN NETWRK
IM8CLS=RECCLS			;CODE IN NETWRK


I8CCM:	CTOP NOP,0
	CTOP RTS,441000
	CTOP STR,441000
	CTOP CLS,440000
	CTOP ALL,124000

	CTOP GVB,111000
	CTOP RET,124000
	CTOP INR,100000
	CTOP INS,100000
	CTOP ECO,100000

	CTOP ERP,100000
	CTOP ERR,144200
	CTOP RST,0
	CTOP RRP,0
	CTOP RAR,100000

	CTOP RAS,100000
	CTOP RAP,100000
	CTOP NXR,100000
	CTOP NXS,100000
I8NCCM==.-I8CCM
;PROCESS CONTROL MESSAGE

IMPCNP:	LOAD T2,LTHOST,(T1)	;GET HOST NUMBER
	MOVEM T2,IMPCHO		;AND LEAVE IT FOR FOLLOWING COMMANDS
	IDIVI T2,^D36		;COMPUTE INDEX TO BIT TABLES
	MOVE T3,BITS(T3)
	TDNE T3,IMPBHT(T2) 	;BAD HOST?
	RET			;YES. LET IMPCLL FLUSH IT
	SETZM IMPCHU		;SAY HOST NOT READY (NO RST/RRP)
	TDNE T3,IMPHRT(T2)	;UNLESS IT IS UP
	SETOM IMPCHU		;THEN SAY IT'S UP
IMP8T6:	CALL UPBYT		;GET NEXT OP CODE
	 RET			;NONE LEFT...DONE
	CAIL T3,I8NCCM		;LEGAL CODE?
	JRST IMP8T4		;NO, FLUSH WHOLE MESSAGE
	MOVEI Q2,I8CCM(T3)	;ADDRESS OF TABLE ENTRY FOR THIS CODE
	HRLI Q2,220300		;PNTR FOR 3-BIT BYTES SPECIFYING FIELDS
	HLRZ Q3,I8CCM(T3)	;GET ROUTINE DISPATCH ADDRESS
	MOVEI T4,I8CAL		;ARGS BUFFER
IMP8T1:	ILDB IMPUN,Q2		;NUMBER OF (8-BIT) BYTES IN NEXT ARG
	SETZ T2,		;CLEAR WORD TO CONSTRUCT ARG
	JUMPN IMPUN,IMP8T2	;0 MEANS NO MORE ARGS
	CAIN Q3,IM8NOP		;CHECK FOR NOP'S AT THIS LEVEL
	JRST IMP8T6		;NOP.  GO GET NEXT OP CODE
	CAIE Q3,IM8RST		;IS RST?
	CAIN Q3,IM8RRP		;OR RRP?
	SETOM IMPCHU		;YES, CONSIDER HIM UP
	SKIPN IMPCHU		;IS HE UP?
	MOVEI Q3,IMSRST		;NO. FORCE CALL TO SEND RST
	PUSH P,T1		;PRESERVE T1
	MOVE Q2,[XWD IMPCHO,1]	;MOVE ARGS TO ACS 1-6
	BLT Q2,Q2		;T1 (IMPCHO) ALWAYS GETS HOST NUMBER
	CALL 0(Q3)		;DO FUNCTION
	POP P,T1		;RESTORE 1 (LT INDEX)
	JRST IMP8T6		;SEE IF ANOTHER

IMP8T2:	PUSH P,T2		;PRESERVE T2
	CALL UPBYT		;GET A BYTE OF ARGUMENT
	 JRST IMP8T5		;WHOOPS, SHORT MESSAGE
	POP P,T2
	ROT T3,-8		;AND SHIFT IT
	LSHC T2,8		;INTO THE ARG BEING ACCUMULATED
	SOJG IMPUN,IMP8T2	;ALL BYTES PACKED?
	MOVEM T2,0(T4)		;YES, STORE ARG IN BUFFER
	AOJA T4,IMP8T1		;AND SEE IF MORE ARGS

IMP8T5:	ADJSP P,-1		;CLEAN UP STACK
IMP8T4:	MOVE T2,IMPCHO		;SCREWED UP CONTROL MSG
	BUG(INF,IMPIFC,<ILL FMT CTL MSG>,<T2,T3>)
	RET			;LET IMPCLL FLUSH REST OF MESSAGE(S)
;CONTROL ROUTINES

;	T1/  HOST NUMBER
;	T2/  LINK NUMBER USUALLY
;	T3-T6/  8 BITS OF ARGUMENT


;NOP (TYPE 0)

IM8NOP:	RET			;NOTHING TO DO



;RECEIVER TO SENDER REQUEST FOR CONNECTION (TYPE 1)

;IM8RTS=RECRTS			;CODE IN NETWRK



;SENDER TO RECEIVER REQUEST FOR CONNECTION (TYPE 2)

;IM8STR=RECSTR			;CODE IN NETWRK



;CLOSE CONNECTION (TYPE 3)

;IM8CLS=RECCLS			;CODE IN NETWRK
;ALLOCATE (TYPE 4)

IM8ALL:	LSH T1,^D8		;CONCAT HOST AND LINK
	IORI T1,L1%SND(T2)	;BIT FOR SEND CONNECTION
	ILOCK
	CALL LNKLUK		;LOOKUP IN CONNECT TABLE
	 CALL BADLKS		;NOT FOUND
	HLRE IMPUN,IMPLT1(T1)	;GET UNIT
	JUMPL IMPUN,ULKIDV	;CONTROL CONNECTION, SHOULDN'T HAPPEN
	MOVSI T2,(RARF)		;WAITING FOR RAR?
	TDNE T2,IMPLT2(T1)
	JRST ULKIDV		;YES, IGNORE ALL ALLOCATES
	HRRZ T2,IMPLT4(T1)	;GET CURRENT MSG ALLOC
	ADD T2,T3		;ADD REQUESTED ALLOCATION
	CAILE T2,777777		;BIGGER THAN MAX?
	JRST IMPB06		;YES
	HRRM T2,IMPLT4(T1)	;STORE NEW ALLOCATION
	ADDB T4,NETBAL(IMPUN)	;UPDATE BIT ALLOCATION
	CAML T4,[1B3]		;EXCESSIVE?
	JRST IMPB06		;YES.
	LOAD T2,ANNVT,(IMPUN)	;GET NVT NUMBER
	CALL NVTCHK		;NVT ATTACHED?
	 JRST IMPKO1		;NO, TEST MORE OUTPUT FOR REG. CONNET'N
	IUNLK
	PUSH P,T2		;SAVE ADDRESS OF DYNAMIC DATA FOR TTY
	CALL NETTCS		;PACK UP MORE CHARACTERS
	POP P,T2		;GET BACK ADDRESS OF DYNAMIC DATA
	CALL ULKTTY		;UNLOCK DATA BASE
	JRST IMPCKO		;AND TRY TO SEND


IMPB06:	IUNLK
	MOVE T2,T1		;GET HOST-LINK NUMBER
	CALL IMP8X1		;FORMAT AS LINK,,HOST
	BUG(INF,IMPREA,<RECD EXCESS ALL>,T2)
	RET
;GIVE BACK (CODE 5)

IM8GVB:	LSH T1,^D8		;GIVE BACK REQUESTED
	IORI T1,L1%SND(T2)	;CONSTRUCT HOST-LINK FOR SEND SOCKET
	ILOCK
	CALL LNKLUK
	 CALL BADLKS		;NOT FOUND
	HLRE IMPUN,IMPLT1(T1)	;GET UNIT
	JUMPL IMPUN,ULKIDV	;CONTROL CONN, SHOULDN'T HAPPEN
	HRRZ T2,IMPLT4(T1)	;MSG ALLOC
	CAIL T3,200		;ALL?
	JRST IM8GV1		;YES
	IMUL T2,T3		;NO, CALC HOW MUCH
	IDIVI T2,200
IM8GV1:	HRRZ T3,IMPLT4(T1)
	SUB T3,T2		;REDUCE CURRENT MSG ALLOC
	HRRM T3,IMPLT4(T1)	;AND STORE IT
	PUSH P,T2		;SAVE AMOUNT TO BE RETURNED
	MOVE T2,NETBAL(IMPUN)	;BIT ALLOCATION
	CAIL T4,200		;RETURN ALL?
	JRST IMPGV2		;YES
	MUL T2,T4		;NO, CALC HOW MUCH
	DIVI T2,200
IMPGV2:	MOVN T3,T2		;GET NEGATIVE OF AMOUNT REQUESTED
	ADDM T3,NETBAL(IMPUN)	;REDUCE BIT ALLOC
	MOVE T4,T2		;SETUP CALL FOR RET
	POP P,T3		;GET BACK AMOUNT OF MSG ALLOC. RETURNED
	LOAD T2,LTLINK,(T1)	;GET LINK NUMBER
	LOAD T1,LTHOST,(T1)	;GET HOST NUMBER
	IUNLK
	CALL IMPRET		;SEND THE RET
	RET




;RETURN (CODE 6)

IM8RET:	RET			;NEVER SEND GVB/ NVER GET RET
;INTERRUPT FROM RECEIVER (CODE 7)

IM8INR:	MOVE T3,T1		;GET HOST NUMBER INTO T3
	LSH T1,^D8		;CONSTRUCT HOST-LINK FOR LOOKUP
	IORI T1,L1%SND(T2)	;WE MUST BE A SEND CONNECTION
	ILOCK
	CALL LNKLUK		;SEE IF CONNECTION EXIST
	 CALL BADLKS		;NO SUCH CONNECTION
	HLRE IMPUN,IMPLT1(T1)	;UNIT
	IUNLK
	JUMPL IMPUN,R		;CONTROL CONNECTION, SHOULDN'T HAPPEN
				; NOT SPECIFIED FOR NVT
	MOVE T1,T3		;GET HOST BACK INTO T1
	CALLRET RECINR

;INTERRUPT FROM SENDER (CODE 8)

IM8INS:	MOVE T3,T1		;GET HOST NUMBER INTO T3
	LSH T1,^D8
	IORI T1,0(T2)		;COMBINE HOST-LINK
	ILOCK
	CALL LNKLUK		;LOOK UP HOST-LINK CONNECTION
	 CALL BADLKR		;NOT THERE REPORT ERROR
	HLRE IMPUN,IMPLT1(T1)
	IUNLK
	JUMPL IMPUN,R		;IGNORE IF CONTROL CONNECTION
	MOVE T1,T3		;GET HOST NUMBER BACK IN T1
	LOAD T2,ANNVT,(IMPUN)	;GET NVT NUMBER
	CALL NVTCHK		;IS IT AN NVT
	JRST RECINS		;ISN'T NVT, GO DO REGULAR CONNECTION
	PUSH P,T2		;SAVE ADDRESS OF DYNAMIC DATA FOR TTY
	CALL NVTDSC		;DECREMENT SYNC COUNT AND RE-ALLOCATE
				; IF NECESSARY
	POP P,T2		;GET BACK ADDRESS OF DYNAMIC DATA
	CALL ULKTTY		;UNLOCK DATA BASE
	RET


;ECHO AND ECHO REPLY (CODE 9 & 10)

IM8ECO:	CALL IMPERP		;SEND REPLY
	RET

IM8ERP:	CAME T1,T2		;WE SEND ECHO WITH DATA = HOST
	JFCL			;NOT EQUAL ... OH WELL
	RET
;ERROR (CODE 11)

;	T1/  HOST NUMBER
;	T2/  TPYE OF ERROR

IM8ERR:	BUG(INF,IMPRNE,<RECD NCP ERR>,<T1,T2>)
	RET

;RESET AND RESET-REPLY CTRL MSG (CODES 12 & 13)

IM8RST:	PUSH P,T1		;SAVE HOST NUMBER
	CALL RECRST		;NOTIFY FSM
	POP P,T1		;RESTORE HOST NUMBER
IM8RRP:	ROT T1,-1		;HALVE
	MOVX T2,1B18		;VALID INFO, HOST UP
	JUMPL T1,[		;IF ODD HOST NUMBER
		HRRM T2,HSTSTS(T1);PUT INTO RH
		JRST .+2]
	HRLM T2,HSTSTS(T1)	;EVEN GOES IN LEFT HALF
	ROT T1,1		;RESTORE HOST NUMBER
	IDIVI T1,^D36		;GET BIT FOR HOST TABLES
	MOVE IMPUN,BITS(T2)
	IORM IMPUN,IMPHRT(T1)	;MARK HOST ALIVE
	RET



;RESET ALLOCATE BY RECEIVER (CODE 14)

IM8RAR:	CALL MRKNWP		;MARK THIS HOST AS USING NEW PROTOCOL
	LSH T1,^D8		;MAKE HOST-LINK NUMBER
	IORI T1,L1%SND(T2)	;AND SEND CONNECTION
	ILOCK
	CALL LNKLUK		;LOOK UP CONNECTION
	 CALL BADLKS		;REPORT ERROR
	HLRE IMPUN,IMPLT1(T1)
	JUMPL IMPUN,ULKIDV	;IGNORE CONTROL CONNECTIONS
	MOVSI T2,(RARF)
	ANDCAM T2,IMPLT2(T1)	;CLEAR RESYNC IN PROGRESS FLAG
	CALLRET ULKIDV
;RESET ALLOCATE BY SENDER (CODE 15)

IM8RAS:	CALL MRKNWP		;MARK THIS HOST AS USING NEW PROTOCOL
	LSH T1,8		;FORM HOST-LINK NUMBER
	IORI T1,0(T2)
	ILOCK
	CALL LNKLUK		;LOOK UP CONNECTION
	 CALL BADLKR		;REPORT ERROR
	HLRE IMPUN,IMPLT1(T1)
	JUMPL IMPUN,ULKIDV	;IGNORE CONTROL CONNECTIONS
	HLLZS IMPLT4(T1)	;ZERO MSG ALLOCATION
	HLRZ T4,IMPLT4(T1)	;ANY CURRENT BUFFER?
	JUMPE T4,IM8RA1		;NO
	HRLI T4,ANBSEC		;SET SECTION NUMBER
	MOVE T4,2(T4)		;ACCUMULATE BYTES
IM8RA1:	HLRZ T2,IMPLT3(T1)	;GET BUFFER
	JUMPE T2,IM8RA3		;NONE
IM8RA2:	HRLI T2,ANBSEC		;SET SECTION NUMBER
	LOAD T3,LD%BYC,2(T2)	;NUMBER OF BYTES
	ADD T4,T3		;ACCUMULATE BYTES
	AOS IMPLT4(T1)		;COUNT MSGS
	HLRZ T2,0(T2)		;GET NEXT BUFFER
	JUMPN T2,IM8RA2		;WAS THERE ONE
IM8RA3:	LOAD T3,IMPBS,(T1)	;GET BYTE SIZE
	IMUL T3,T4		;CALCULATE BITS IN MSGS
	MOVEM T3,NETBAL(IMPUN)	;SAVE NEW BIT ALLOACATION
	IUNLK
	LOAD T2,LTLINK,(T1)	;GET LINK NUMBER
	LOAD T1,LTHOST,(T1)	;GET HOST NUMBER
	CALL IMPRAR		;SEND RAR
	LOAD T2,ANNVT,(IMPUN)	;GET NVT NUMBER
	CALL NVTCHK		;NVT ?
	 JRST NETRAL		;NO.  DO NORMAL REALLOCATION
	PUSH P,T2		;SAVE ADDRESS OF DYNAMIC DATA FOR TTY
	CALL NVTRAL		;REALLOCATE FOR NVT
	POP P,T2		;GET BACK ADDRESS OF DYNAMIC DATA
	CALL ULKTTY		;UNLOCK DATA BASE
	RET
;RESET ALLOCATE PLEASE (CODE 16)

IM8RAP:	CALL MRKNWP		;MARK THIS HOST AS USING NEW PROTOCOL
	LSH T1,8		;MAKE HOST-LINK NUMBER
	IORI T1,L1%SND(T2)	;MUST BE A SEND CONNECTION
	ILOCK
	CALL LNKLUK		;GO LOOKUP HOST-LINK
	 CALL BADLKS		;ERROR. GO REPORT IT
	HLRE IMPUN,IMPLT1(T1)
	JUMPL IMPUN,ULKIDV	;IGNORE CONTROL CONNECTIONS
	MOVSI T2,(RARF!RARRF)	;GET RAR EXPECTED AND SEND RAS WHEN NO
	IORM T2,IMPLT2(T1)	; RFNM'S OUT FLAGS AND SET THEM
	CALLRET IMPKO1		;GO CHECK CONNECTION FOR OUTPUT POSSIBLE



;NON-EXISTENT LINK FROM RECEIVER AND SENDER (CODES 17 & 18)

IM8NXR:	IORX T2,L1%SND		;INDICATE SEND CONNETION FOR LOOKUP
IM8NXS:	CALL MRKNWP		;MARK THIS HOST AS USING NEW PROTOCOL
	LSH T1,8		;MAKE HOST-LINK NUMBER
	IOR T1,T2
	ILOCK
	CALL LNKLUK		;GO LOOKUP HOST-LINK
	 JRST ULKIDV		;NOT THERE GO UNLOCK
	HLRE IMPUN,IMPLT1(T1)	;GET IMPUN
	JUMPL IMPUN,ULKIDV	;IGNORE IF CONTROL CONN
	IUNLK
	CALL SK2DWN		;GO CLOSE CONNECTION
	RET
;LINK LOOKUP FAILURE FOR RECEIVERS AND SENDERS

BADLKR:	SKIPA T3,[IMPNXR]	;CLOSE ROUTINE FOR RECIEVE CONNECTION
BADLKS:	MOVEI T3,IMPNXS		;CLOSE ROUTINE FOR SEND CONNECTION
	IUNLK
	MOVE T2,T1		;GET COPY OF HOST-LINK NUMBER IN T2
	LSH T1,-8		;SHIFT LINK OUT OF T1, LEAVING HOST
	ANDX T1,HSTMSK		;SAVE JUST HOST IN T1
	ANDX T2,L1%LNK		;SAVE JUST LINK IN T2
	PUSH P,T2		;SAVE LINK FOR BUGINF
	PUSH P,T1		;SAVE HOST TOO.
	CALL 0(T3)		;GO CLOSE CONNECTION
	POP P,T1		;GET BACK HOST
	POP P,T2		;AND LINK
	POP P,T3		;AND ADDRESS OF CALLER
	BUG(INF,IMPCUL,<RECD CTL MSG FOR UNKNOWN LINK>,<T1,T2,T3>)
	RET
;CALLS FROM NCP

;OPEN LINK, I.E. ASSOCIATE HOST-LINK AND UNIT
;	T1/ HOST
;	T2/ LINK
;	T3/ BYTE SIZE

IMPOPL::ILOCK
	LSH T1,^D8
	IORI T1,0(T2)		;CONCAT HOST AND LINK
	CALL LNKLUK		;NOW IN TABLE?
	 JRST IMPOP0		;NO, SLOT TO USE RETURNED IN T2
	IUNLK
	PUSH P,T1		;SAVE HOST-LINK
	EXCH T1,T2		;GET A COPY INT0 T2
	CALL IMP8X1		;GO GET LINK,,HOST IN T2
	BUG(INF,IMPLAE,<IMPOPL: LINK ALREADY EXISTS>,T2)
	EXCH T1,T2		;RETORE T2
	POP P,T1		;AND T1
	RET

IMPOP0:	CALL IMPOP1		;NEW CONNECTION GO UPDATE TABLES
	IUNLK
	RET

IMPOP1:	EXCH T1,T2		;GET HOST-LINK INTO T1
	MOVEM T2,IMPLT1(T1)	;SAVE HOST-LINK
	HRLM IMPUN,IMPLT1(T1)	;SAVE UNIT NUMBER
	SETZM T2,IMPLT2(T1)	;ZERO ADDING POINTER AND FLAGS
	SETZM IMPLT3(T1)	;ZERO OUT AND RETRANS. BUFFER ADD.
	SETZM IMPLT4(T1)	;ZERO CURRENT BUFFER AND MSG. ALLOC.
	STOR T3,IMPBS,(T1)	;SET BYTE SIZE
	RET
;CLOSE LINK, INVERSE OF ABOVE
;	T1/  LT INDEX

IMPCLL::ILOCK
	CALL IMPLL0		;GO DO THE WORK
	IUNLK
	RET

IMPLL0:	MOVX T2,L1%FRE		;GET IN USE BIT
	TDNE T2,IMPLT1(T1)	;WAS CONNECTION IN USE?
	RET			;NO, DO NOTHING ELSE
	EXCH T2,IMPLT1(T1)	;SET ENTRY TO DELETED
	TXNE T2,L1%LNK		;CONTROL LINK?
	 JRST IMPLL9		;NO, SKIP THIS
	TXNE T2,L1%SND		;SEND?
	SOSA IMPNOL		;YES, DECREASE COUNT OF SEND CL'S
	SOS IMPNCL		;ELSE DECREASE COUNT OF RECV CL'S
IMPLL9:	AOS LNKNDL		;COUNT DELETES
	CALL IMPLL1		;FLUSH MESSAGES
	RET
;SET DONE FLAG FOR CONNECTION
;	T1/ CONN INDEX

IMPSDB::MOVSI T2,(LTDF)		;GET DONE FLAG
	IORM T2,IMPLT2(T1)	;SET IT
	AOS IMPNOS		;MAKE OUTPUT BE LOOKED AT
	RET

;ABORT LINK (CALLED BY NCP IF TRANSMISSION ABORTED)

IMPABL::ILOCK
	CALL IMPLL3		;CLEAR QUEUES, DON'T CLEAR RFNM COUNT
	IUNLK
	RET

;CLEAR LINK TABLE FOR PARTICULAR HOST

IMPXLT:	STKVAR <IMPXT1,IMPXHS>
	MOVEM T1,IMPXT1		;SAVE T1
	HRRZ T1,T1		;GET JUST HOST
	MOVEM T1,IMPXHS		;SAVE IT
	ILOCK			;LOCK
	MOVSI T1,-IMPNLK	;SET TO SCAN CONN TABLE
IMPXLL:	LOAD T2,LTHOST,(T1)	;GET HOST NUMBER
	CAME T2,IMPXHS		;SPECIFIED ONE?
	 JRST IMPXLN		;NO. GO TRY NEXT ONE
	LOAD T2,LTLINK,(T1)	;GET LINK NUMBER
	JUMPE T2,[CALL IMPLL0	;IF CONTROL LINK, FLUSH ALL
		JRST IMPXLN]	;GO TRY NEXT ONE
	CALL IMPLL1		;ELSE FLUSH QUEUED MESSAGES
IMPXLN:	AOBJN T1,IMPXLL		;ANY MORE?
	IUNLK			;UNLOCK
	MOVE T1,IMPXT1		;RESTORE T1
	RET

;RESYNC ALLOCATION

IMPSYN::PUSH P,1		;SAVE T1,  LT INDEX
	LOAD T1,LTHOST,(T1)	;GET HOST NUMBER
	CALL CHKNWP		;NEW PROTOCOL?
	 JRST [	POP P,T1	;NO RETURN
		RET]
	POP P,T1		;RETORE LT INDEX
	MOVSI T2,(RARF!RARRF)	;SET RAR EXPECTED AND SEND RAS WHEN
	IORM T2,IMPLT2(T1)	; NO RFNM'S OUT
	AOS IMPNOS		;MAKE IT SCAN OUTPUT CONNECTIONS
	RET
;FLUSH ALL MESSAGES FOR A CONNECTION

IMPLL3:	TDZA T2,T2		;DON'T CLEAR RFNM COUNT
IMPLL1:	MOVX T2,RFNMCM		;CLEAR RFNM COUNT
	STKVAR <IMPLFG,IMPLLT>
	MOVEM T2,IMPLFG		;SAVE FOR A BIT LATER ON
	HLRZ T2,IMPLT4(T1)	;GET CURRENT BUFFER ADDRESS
	HRRZS IMPLT4(T1)	;ZERO CURRENT BUFFER IN TABLE
	MOVEM T1,IMPLLT		;SAVE T1, LT INDEX
	HRLI T2,ANBSEC		;SET SECTION NUMBER
	TRNE T2,-1		;IS THERE A CURRENT BFR?
	CALL RLNTBF		;YES.  RELEASE IT
	MOVE T1,IMPLLT		;GET BACK LT INDEX
	HLLZS IMPLT2(T1)	;FIX POINTER FOR ADDING BUFFERS
	PIOFF
	MOVE T2,IMPLFG		;GET BITS TO CLEAR, 0 OR RFNM COUNT
	ANDCAM T2,IMPLT2(T1)	;CANCEL OUTSTANDING RFNM
	HRRZ T2,IMPLT3(T1)	;GET RETRANSMIT BUFFER
	HLLZS IMPLT3(T1)	;ZERO RETRANSMIR BUFFER IN TABLE
	PION
	HRLI T2,ANBSEC		;SET SECTION NUMBER
	TRNE T2,-1		;WAS THERE A BUFFER
IMPLL2:	CALL RLNTBF		;YES, RELEASE IT
	MOVE T1,IMPLLT		;RETORE T1, LT INDEX
	HLRZ T2,IMPLT3(T1)	;RELEASE ANY BUFFERS ON QUEUE
	JUMPE T2,R		;NO. RETURN
	HRLI T2,ANBSEC		;SET SECTION NUMBER
	HLLZ T3,0(T2)		;GET NEXT BUFFER IN CHAIN
	HLLM T3,IMPLT3(T1)	;SAVE IT'S ADDRESS
	SKIPN T3		;NO MORE BUFFERS
	HRRM T3,IMPLT2(T1)	;IF NO MORE ZERO ADDING POINTER TOO
	JRST IMPLL2		;GO RELEASE BUFFER
;CONTROL MESSAGE SENDERS

;NOP, RTS, STR, CLS, ALL, GVB, RET, INR, INS, ECO, ERP

;PUT ADDRESS OF [ARG DESCRIPTOR,,OPCODE] IN LH OF T1 AND CALL IMPSCM



IMPNOP:	HRLI T1,[XWD 0,0]	;NOP, NO ARGS
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMPRTS::HRLI T1,[XWD 441000,1]	;ARG DESCRIPTOR,,OPCODE
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMPSTR::HRLI T1,[XWD 441000,2]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMPCLS::HRLI T1,[XWD 440000,3]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMPALL::CAIGE T3,0		;DON'T SEND NEG ALLOCS
	SETZ T3,		;IF NEGATIVE MAKE ZERO
	CAIGE T4,0
	SETZ T4,
	PUSH P,T1		;SAVE T1
	LOAD T1,LTIDX,(IMPUN)	;GET CONNECTION INDEX
	PUSH P,T2		;SAVE T2
	MOVSI T2,(RARF)		;WAITING FOR RAS?
	TDNE T2,IMPLT2(T1)
	JRST [	POP P,T2	;YES. DO NOTHING
		POP P,T1	;RESTORE T2 AND T1
		RET]
	POP P,T2		;NO, GET BACK AC2
	ADDM T3,IMPLT4(T1)	;UPDATE MSG ALLOC
	POP P,T1		;GET BACK T1
	ADDM T4,NETBAL(IMPUN)	;BITS
	HRLI T1,[XWD 124000,4]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT
;CONTROL MESSAGE SENDERS (CONTINUED)

;GVB, RET, INR, INS, ECO, ERP, ERR, RST

IMPGVB:	HRLI T1,[XWD 111000,5]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMPRET:	HRLI T1,[XWD 124000,6]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMPINR::HRLI T1,[XWD 100000,^D7]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMPINS::HRLI T1,[XWD 100000,^D8]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMPECO:	HRLI T1,[XWD 100000,^D9]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMPERP:	HRLI T1,[XWD 100000,^D10]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMPERR::HRLI T1,[XWD 144200,^D11]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMSRST::HRLI T1,[XWD 0,^D12]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT
;CONTROL MESSAGE SENDERS (CONTINUED)

;RRP, RAR, RAS, RAP, NXR, NXS


IMPRRP::HRLI T1,[XWD 0,^D13]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMPRAR:	CALL CHKNWP		;IS HE USING NEW PROTOCOL
	 RET			;NO.  RETURN
	HRLI T1,[100000,,^D14]	;YES
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMPRAS:	CALL CHKNWP		;IS HE USING NEW PROTOCOL
	 JRST IM8RAR		;NO.  RESYNC NOT IMPLEMENTED -- SIM RAR
	HRLI T1,[100000,,^D15]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMPRAP:	CALL CHKNWP		;IS HE USING NEW PROTOCOL
	 RET			;DOES NOT UNDERSTAND NEW PROTOCOL
	HRLI T1,[100000,,^D16]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMPNXR:	CALL CHKNWP		;IS HE USING NEW PROTOCOL
	 RET			;NO RETURN
	HRLI T1,[100000,,^D17]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT



IMPNXS:	CALL CHKNWP		;IS HE USING NEW PROTOCOL
	 RET			;NO RETURN
	HRLI T1,[100000,,^D18]
	JRST IMPSCM		;CONSTRUCT MESSAGE AND OUTPUT
;SEND CONTROL MESSAGE
;	T1/  ADDRESS OF [ARG DESCRIPTOR,,OPCODE],,DEST HOST
;	T2 - ??   ARGUMENTS

IMPSCM:	SAVEPQ			;SAVE IMPUN, Q2-Q3 AND P1-P6
	STKVAR <IMPSBP,<IMPSBF,5>>
	HLRZ P4,T1		;GET ADDRESS OF ARG DESCRIPTOR
	MOVE P4,0(P4)		;GET THE ARG DESCRIPTOR
	HRRZS T1		;GET RID OF ADDRESS IN LH
	MOVEI P1,IMPSBF		;GET ADDRESS OF BUFFER
	HRLI P1,(<POINT 8,0,31>);CONSTRUCT BYTE POINTER, 8-BITS
	MOVEM P1,IMPSBP		;SAVE IT FOR LATER USE
	IDPB P4,P1		;STORE OPCODE AS FIRST BYTE OF MESSAGE
	MOVEI P2,1		;INIT MESSAGE BYTE COUNT
	MOVEI P5,2		;INDEX TO ARGS
IMPSC4:	SETZ P3,		;ZERO P3 BEFORE GETTING NEXT ARG DESC.
	LSHC P3,3		;NEXT ARG DESCRIPTOR BYTE
	JUMPN P3,IMPSC3		;0 MEANS DONE
	LSH T1,^D8
	IORX T1,L1%SND		;SEND CONNECTION
	ILOCK
	CALL LNKLUK		;SEE IF CONNECTION NOW EXISTS
	 JRST [	MOVEI T3,^D8	;DOESN'T, CREATE IT 8 BIT BYTES.
		CALL IMPOP1
		AOS IMPNOL	;COUNT OPEN OUTPUT LINKS
		HRROS IMPLT1(T1) ;SET UNIT NEG
		MOVEI T3,377777	;SET INFINITE MSG ALLOC
		HRRM T3,IMPLT4(T1)
		MOVSI T3,(HIPFLG)
		IORM T3,IMPLT2(T1)	;SET HIGH PRIORITY FLAG
		JRST .+1]
	MOVE T3,IMPSBP		;GET BYTE PTR
	MOVEI T4,0(P2)		;GET COUNT
	CALL PKMSG0		;PACK MESSAGE AND SEND IF POSSIBLE
				; DOES IUNLK
	RET


IMPSC3:	ADDI P2,0(P3)		;ACCUMULATE BYTE COUNT OF MESSAGE
	MOVNI Q2,0(P3)		;COMPUTE NUMBER OF BITS TO LEFT OF ARG
	IMULI Q2,^D8		;NUMBER BYTES TIMES BITS PER BYTE
	ADDI Q2,^D36		;SUBTRACTED FROM SIZE OF WORD
	MOVE Q3,0(P5)		;GET NEXT ARG
	LSH Q3,0(Q2)		;SHIFT OUT UNUSED BITS
IMPSC2:	ROT Q3,^D8		;SHIFT NEXT BYTE INTO PLACE
	IDPB Q3,P1		;STORE IT IN MESSAGE BUFFER
	SOJG P3,IMPSC2		;FOR ALL BYTES
	AOJA P5,IMPSC4		;INDEX ARG POINTER
;SPECIAL RAW MESSAGE ROUTINES


;.ASNSQ - ASSIGN A SPECIAL MESSAGE QUEUE

;	T1/  MASK
;	T2/  HEADER VALUE

;	ASNSQ

;RETURNS
;	+1  FAILURE
;	   T1/  ERROR CODE
;	+2  SUCCESS
;	   T1/  SPECIAL QUEUE HANDEL


.ASNSQ::MCENT
	CALL CKNTWZ		;CHECK TO SEE IF NET-WIZARD
	 RETERR			;NO.  GIVE ERROR
	NOINT
	AOSE SQLCK		;SET SPECIAL QUEUE LOCK
	CALL SQLWAT		;SOMEONE ALREADY HAS IT GO WAIT
	MOVSI T3,-NSQ		;SET UP TO SCAN SPECIAL QUEUES
	SETZ T4,		;INIT T4 TO KEEP TRACK OF Q TO BE ASSGND
ASNSQL:	SKIPGE SQJOB(T3)	;ASSIGNED?
	JRST [JUMPL T4,ASNSQN	;NO.  HAVE WE ALREADY FOUND A FREE ONE
		MOVE T4,T3	;NO.    SAVE Q NUMBER IN T4
		JRST ASNSQN]	;CHECK MASK AND VALUE AGAINST THE REST
	UMOVE T1,T1		;GET MASK
	AND T1,SQMSK(T3)	;JOINT MASK
	UMOVE T2,T2		;GET VALUE
	XOR T2,SQVAL(T3)	;DIFFERENCE
	TDNN T1,T2		;MUST BE DIFFERENT IN JOINT MASK BITS
	 JRST ASNSQF		;ELSE FAIL
ASNSQN:	AOBJN T3,ASNSQL		;TEST ALL POSSIBILITIES
	MOVEI T1,ASNSX1		;ASSUME WE DID NOT FIND ONE.
	JUMPGE T4,ASNSF1	;DID WE FIND ONE?
	UMOVE T1,T1		;YES.  GET MASK
	MOVEM T1,SQMSK(T4)	;STORE MASK IN TABLE
	XCTU [AND T1,T2]	;MASK GOOD BITS OF VALUE
	MOVEM T1,SQVAL(T4)	;AND SAVE THEM
	MOVE T1,JOBNO		;GET THE JOB NUMBER
	MOVEM T1,SQJOB(T4)	;AND SAVE IT AS OWNER OF Q
	SETOM SQLCK		;CLEAR LOCK
	XCTU [HRRZM T4,T1]	;RETURN QUEUE NUMBER
	SMRETN			;SKIP RETURN

ASNSQF:	MOVEI T1,ASNSX2		;TELL HIM NOT UNIQUE MASK AND VALUE
ASNSF1:	SETOM SQLCK		;CEAR LOCK
	RETERR
;.RELSQ - RELEASE SPECIAL Q

;	T1/  SPECIAL QUEUE HANDLE OR -1 FOR ALL

;	RELSQ

;RETURNS +1 ALWAYS


.RELSQ::MCENT
	NOINT
	AOSE SQLCK		;TRY TO LOCK SPECIAL QUEUES
	 CALL SQLWAT		;COULDN'T LOCK GO WAIT
	CAMN T1,[-1]		;IS HE ASKING FOR ALL OF THEM
	 JRST RELASQ		;YES GO DO IT
	CAIL T1,0		;LEGAL QUEUE NUMBER
	CAIL T1,NSQ
	 JRST RELSQ1		;NO RETURN
	CALL REL1SQ		;YES.  GO RELEASE IT
RELSQ1:	SETOM SQLCK		;CLEAR LOCK
	MRETNG			;RETURN

RELASQ:	MOVSI T4,-NSQ		;SET UP TO SCAN ALL QUEUES
RELAS1:	HRRZ T1,T4		;GET QUEUE NUMBER IN T1
	CALL REL1SQ		;GO RELEASE IT
	AOBJN T4,RELAS1		;DO NEXT ONE
	JRST RELSQ1		;FINISHED GO CLEAR LOCK AND EXIT

REL1SQ:	MOVE T2,JOBNO		;GET JOB NUMBER
	CAME T2,SQJOB(T1)	;DOES HE OWN THIS QUEUE
	RET			;NO.   RETURN
	SETOM SQJOB(T1)		;YES.  INDICATE QUEUE NO LONGER OWNED
REL1S1:	CALL SIQGET		;ANY MESSAGES ON THE QUEUE
	 RET			;NO.  RETURN
	PUSH P,T1		;YES.  SAVE QUEUE NUMBER
	CALL RLNTBF		;RELEASE BUFFER
	POP P,T1		;RESTORE SPECIAL QUEUE NUMBER
	JRST REL1S1		;SEE IF ANYMORE MESSAGES
;.RCVIM RECEIVE RAW MESSAGES

;ACCEPTS:
;	T1/ SPECIAL QUEUE HANDLE
;	T2/ BUFFER ADDRESS

;	RCVIM

;RETURNS:
;	+1 FAILURE 
;	   T1/  ERROR CODE
;	+2 SUCCESS

.RCVIM::MCENT
RCVIM1:	NOINT
	UMOVE T1,T1		;GET SPECIAL QUEUE HANDLE
	CALL CHKSQ		;CHECK FOR ACCESSIBILITY TO SPECIAL Q
	 RETERR			;NO ACCESS
	CALL SIQGET		;GET THE MESSAGE
	 JRST [	OKINT		;NONE THERE
		MDISMS		;WAIT
		JRST RCVIM1]	;TRY AGAIN
	HRRZS 0(T2)		;ZERO LINK FIELD, SO USER DOESN'T SEE IT
	PUSH P,T2		;SAVE BUFFER ADDRESS
	UMOVE T3,T2		;GET USER'S BUFFER
	MOVE T1,0(T2)		;GET LENGTH FROM BUFFER HEADER
	CALL BLTMU		;TRANSFER TO USER
	POP P,T2		;GET BUFFER ADDRESS BACK
	CALL RLNTBF		;RELEASE THE BUFFER
	SMRETN			;RETURN


SIQGET:	MOVE T2,TODCLK		;GET TIME OF DAY
	ADDI T2,SIQTM0		;ADD IN SPECIAL QUEUE TIME LIMIT
	MOVEM T2,SIQTIM(T1)	;RESET TIME
	NOSKED
	MOVE T2,SIQIBO(T1)	;GET BUFFER ADDRESS
	JUMPE T2,SIQEMT		;NO BUFFER WAIT
	HLRZ T3,0(T2)		;GET NEXT BUFFER IN CHAIN
	JUMPN T3,SIQGT1		;IS THERE ONE
	SETZM SIQIBI(T1)	;NO. ZERO POINTER FOR ADDING BUFFERS
	SKIPA			;SKIP ADDING SEC. NO SO PTR = ZERO
SIQGT1:	HRLI T3,ANBSEC		;SET BUFFER SECTION NUMBER
	MOVEM T3,SIQIBO(T1)	;UPDATE POINTER
	SOS SIQSPC(T1)		;CREDIT SPACE USED
	OKSKED
	RETSKP

SIQEMT:	OKSKED
	HRLZI T1,SIQIBO(T1)	;GET ADDRESS OF POINTER FOR REMOVING
	HRRI T1,DISNT		;AND ADDRESS OF TEST ROUTINE
	RET
;.SNDIM - SEND SPECIAL MESSAGE

;ACCEPTS:
;	T1/ SPECIAL QUEUE HANDLE
;	T2/ BUFFER ADDRESS

;	SNDIM

;RETURNS:
;	+1 FAILURE 
;	   T1/  ERROR CODE
;	+2 SUCCESS


.SNDIM::MCENT
	CALL CHKSQ		;CHECK ACCESS TO SPECIAL Q
	 RETERR			;ERROR RETURN
	UMOVE T4,T2		;GET BUFFER ADDRESS
	UMOVE T2,0(T4)		;GET SIZE
	CAIL T2,2		;MUST BE LARGER THAN 2
	CAILE T2,^D224		;AND LESS THAN MAXIMUM BUFFER SIZE
	 RETERR (SNDIX1)	;BAD SIZE
	UMOVE T1,1(T4)		;GET HEADER WORD
	MOVE T3,T1		;SAVE A COPY IN T3
	ANDX T1,<LD%FIM!LD%LNK>	;GET RID OF EVERYTHING BUT LINK NUMBER
	CAMG T1,[MAXNCP]	;IS IT GREATER THAN LAST NCP LINK NUMBER
	 RETERR (SNDIX3)	;NO. DON'T ALLOW MESSAGES WITH NCP LINKS
	UMOVE T1,T1		;GET SQ INDEX
	XOR T3,SQVAL(T1)	;DIFFERENCE WITH VALUE
	TDNE T3,SQMSK(T1)	;MUST BE EQUAL IN MASKED BITS
	 RETERR (SNDIX4)	;NOT EQUAL.
	NOINT
	CALL ASNTBF		;GET A BUFFER
	 RETERR (SNDIX2)	;NO ROOM
	MOVE T3,T1		;GET MONITOR BUFFER ADDRESS IN T3
	MOVE T2,T4		;GET USER'S BUFFER ADDRESS
	MOVE T4,T1		;GET A COPY OF MONITOR BUFFER ADD. IN T4
	MOVE T1,0(T1)		;GET USERS SIZE.  LEFT BY ASNTBF
	AOS T2			;DON'T TRANSFER FIRST WORD
	AOS T3
	SOS T1			;SO ONE LESS WORD IN LENGTH
	CALL BLTUM		;TRANSFER MESSAGE TO MONITOR SPACE
	MOVE T2,T4		;GET THE BUFFER ADDRESS BACK
	NOSKED
	SKIPL IMPRDY		;LAST MINUTE CHECK IF IMP IS UP
	 RETERR (SNDIX5,<OKSKED
			CALL RLNTBF>) ;NOT UP
	CALL IMPQOA		;PUT ONTO OUTPUT Q
	OKSKED
	SMRETN			;SUCCESS RETURN
;CHKSQ - CHECK FOR ACCESS TO SPECIFIC SPECIAL Q

;ACCEPTS:
;	T1/ SPECIAL QUEUE HANDLE

;	CALL CHKSQ

;RETURNS:
;	+1 FAILURE 
;	   T1/  ERROR CODE
;	+2 SUCCESS

;CLOBBERS T2

CHKSQ:	CAIL T1,0		;MUST BE GREATER THAN 0
	CAIL T1,NSQ		;AND LESS THAN THE NUMBER OF SPECIAL Q'S
	 RETBAD (SQX1)		;NOT IN RANGE
	MOVE T2,JOBNO		;GET JOB NUMBER
	CAMN T2,SQJOB(T1)	;DOES HE OWN THIS SPECIAL QUEUE
	RETSKP			;YES RETURN SUCESS
	MOVEI T1,SQX2		;NO. SET UP ERROR NUMBER
	RETBAD



;CKNTWZ - CHECK FOR NET WIZARDRY

;RETURNS:
;	+1 NOT WIZARD ERROR CODE IN T1
;	+2 WIZARD

;CLOBBERS T2

CKNTWZ:	MOVEI T2,SC%NWZ		;GET NET-WIZARD BIT
	TDNE T2,CAPENB		;DOES HE HAVE THIS CAPABILITY
	RETSKP			;YES.  SKIP RETURN
	MOVEI T1,NTWZX1		;NO.  GET ERROR NUMBER
	RET



;SQLWAT - WAIT FOR SPECIAL QUES TO BECOME UNLOCKED

SQLWAT:	PUSH P,T1		;SAVE T1
	MOVEI T1,SQLTST		;GET SCHEDULAR TEST
	MDISMS			;WAIT
	POP P,T1		;RESTORE T1
	RET

SQLTST:	AOSE SQLCK		;STILL LOCKED
	JRST 0(T4)		;YES
	JRST 1(T4)		;NO
;SIQCHK - CHECK FOR UNCLAIMED MESSAGES

;ACCEPTS:
;	T1/  TIME OF DAY

;RETURNS:
;	T1/  TIME TO SCAN QUEUES AGAIN

SIQCHK:	HRLOI T3,377777		;INITIALIZE T3 TO INFINITY TIME
	MOVE T2,T1		;GET TIME IN T2
	MOVSI T1,-NSQ		;SET UP TO SCAN ALL QUEUES
SIQCKL:	SKIPGE SQJOB(T1)	;IS THIS QUEUE OWNED?
	JRST SIQCKE		;NO.
	CAMG T2,SIQTIM(T1)	;YES.  IS ITS TIME UP?
	JRST SIQCKX		;NO
	PUSH P,T1		;YES SAVE T1, T2 AND T3
	PUSH P,T2
	PUSH P,T3

REPEAT 0,<			;CODE TO DELETE JUST ONE BUFFER
	CALL SIQGET		;GO GET NEXT MSG
	 SKIPA			;WASN'T ANY
	CALL RLNTBF		;RELEASE IT
> ;END OF REPEAT 0 TO DELETE JUST ONE BUFFER


REPEAT 1,<			;CODE TO FLUSH THE WHOLE QUEUE
	CALL REL1S1		;FLUSH THE ENTIRE QUEUE
> ;END OF REPEAT 1 TO FLUSH ALL MSGS IN QUEUE


	POP P,T3		;RESTORE T3, T3 AND T1
	POP P,T2
	POP P,T1
SIQCKX:	CAML T3,SIQTIM(T1)	;THIS TIME LESS THAN NEXT TIME TO SCAN
	 MOVE T3,SIQTIM(T1)	;YES.  SAVE IT INSTEAD
SIQCKE:	AOBJN T1,SIQCKL		;CHECK NEXT QUEUE
	MOVE T1,T3		;RETURN NEXT TIME TO REMOVE MSG. IN T1
	RET
;LOOKUP HOST-LINK

;ACCEPTS  T1/ B20-27, HOST; B28-35, LINK; B18, DIRECTION (1=SEND)

;RETURNS  +1  ENTRY NOT FOUND 
;		T1/  UNCHANGED
;		T2/  LINK TABLE INDEX
;	  +2  ENTRY FOUND
;		T1/  LINK TABLE INDEX

;	T3/  CONTAINS FLAGS
;PRESERVES T3 AND T4

LNKLUK:	STKVAR <LNKLT3,LNKLT4,LNKLPT> ;NOTE THAT THIS STKVAR IS
				; ALSO AT IMPHFL AND IMPPIL
	MOVEM T3,LNKLT3		;SAVE T3
	MOVSI T3,(1B1)		;BIT SAYS NO DELETED ENTRY FOUND
LNKL6:	MOVEM T4,LNKLT4		;SAVE T4
	MOVEM T1,LNKLPT		;SAVE ARG
	IMUL T1,[5654123]	;COMPUTE HASH
	LSH T1,-^D9
	IDIVI T1,IMPNLK		;REMAINDER GIVES INITIAL INDEX
	MOVE T1,T2		;GET COPY OF REMAINDER
	EXCH T1,LNKLPT		;GET HOST-LINK BACK SAVE AWAY REMAINDER
	HRLI T2,-IMPNLK(T2)	;SETUP PTR FOR REMAINDER OF TABLE
LNKL2:	HRRZ T4,IMPLT1(T2)	;GET HOST-LINK OF ENTRY
	CAIN T4,0(T1)		;DESIRED ENTRY?
	JRST [MOVEI T1,0(T2)	;YES GET INDEX IN T1
		MOVE T3,LNKLT3	;RESTORE T3 AND T4
		MOVE T4,LNKLT4
		RETSKP]		;SKIP RETURN
	TXNE T4,L1%FRE		;SPECIAL? I.E. FREE OR DELETED?
	JRST [TLNE T3,(1B2)	;YES, CALLED BY REHASH OR PI LEVEL?
		JRST LNKL4	;YES
		TXNE T4,L1%SND	;THIS A FREE ENTRY?
		JRST LNKL3	;YES, SEARCH DONE, NOT FOUND
		TLZE T3,(1B1)	;THIS FIRST DELETED ENTRY ENCOUNTERED?
		HRRI T3,0(T2)	;YES, SAVE ITS POSITION
		JRST .+1]
LNKL5:	AOBJN T2,LNKL2		;TRY NEXT ENTRY DOWN
	JUMPL T3,[TLNN T3,(1B1)	;TABLE FULL, WAS DELETE SEEN?
		JRST LNKL3	;YES, USE IT
		BUG(CHK,IMPLTF,<IMPLT FULL>)
		JRST LNKL1]	;RETURN NOT FOUND
	MOVN T2,LNKLPT		;WRAPAROUND PTR, SETUP COUNT
	MOVSI T2,0(T2)		;TO LOOK UP TO INITIAL INDEX
	TLO T3,(1B0)		;REMEMBER WRAPAROUND
	JRST LNKL2		;GO CHECK FIRST ENTRY

LNKL3:	TLNN T3,(1B1)		;NOT FOUND, DELETE ENCOUNTERED?
	MOVEI T2,0(T3)		;YES, USE THAT FOR NEW ENTRY
LNKL1:	MOVE T3,LNKLT3		;RESTORE T3 AND T4
	MOVE T4,LNKLT4
	RET			;RETURN NOT FOUND

LNKL4:	TLNE T3,(1B3)		;PI LEVEL CALL?
	 JRST LNKL5		;YES. IGNORE DELETED/FREE ENTRIES
	MOVX T4,L1%FRE		;MAKE DELETED
	MOVEM T4,IMPLT1(T2)
	JRST LNKL5		;GO TRY NEXT ENTRY
;SPECIAL ENTRY USED ONLY BY REHASH ROUTINE
;IT ASSUMES ITEM WILL BE FOUND, AND IT SETS ANY 'FREE' ENTRIES
;ENCOUNTERED TO BE 'DELETED'

IMPHFL:	STKVAR <LNKLT3,LNKLT4,LNKLPT> ;NOTE THAT THIS STKVAR IS
				; ALSO AT IMPHFL AND LNKLUK
	MOVEM T3,LNKLT3		;SAVE T3
	MOVSI T3,(1B2)		;CONTROLS ACTION ON SPECIAL ENTRIES
	JRST LNKL6		;GO DO SCAN

;SPECIAL ENTRY FROM IMODN2 TO FIND ENTRY TO STORE RETRANSMIT BUFFER
;SEARCHES ENTIRE TABLE FOR ENTRY REGARDLESS OF DELETES AND FREES

IMPPIL:	STKVAR <LNKLT3,LNKLT4,LNKLPT> ;NOTE THAT THIS STKVAR IS
				; ALSO AT LNKLUK AND IMPPIL
	MOVEM T3,LNKLT3		;SAVE T3
	MOVSI T3,(1B2+1B3)
	JRST LNKL6		;GO DO SCAN

;ROUTINE TO GARBAGE COLLECT HASH TABLE.
;SETS ALL DELETED ENTRIES TO FREE THEN CALLS LOOKUP ROUTINE TO
;MARK ALL NEEDED ENTRIES DELETED TO ENABLE ALL ENTRIES TO BE FOUND.
;LOOKUP ROUTINE WILL CHANGE ANY 'FREE' ENTRIES PASSED OVER DURING
;A SEARCH TO 'DELETED'.  THUS ALL 'DELETED' ENTRIES NOT CURRENTLY
;NECESSARY WILL BE FLUSHED.

IMPGC:	IMSCLK (IMCGC)		;CHARGE TIME TO IMCGC
	ILOCK
	SETZM LNKNDL		;CLEAR DELETE COUNT
	MOVSI Q3,-IMPNLK	;PREPARE TO SCAN LINK TABLE
	MOVX T1,L1%FRE		;GET FREE OR DELETED FLAG
	MOVX T2,L1%SND!L1%FRE	;GET FREE FLAG
IMPGC1:	TDNE T1,IMPLT1(Q3)	;FREE OR DELETED?
	MOVEM T2,IMPLT1(Q3)	;YES, SET IT TO FREE
	AOBJN Q3,IMPGC1		;DO NEXT ENTRY
	MOVSI Q3,-IMPNLK	;PREPARE TO SCAN AGAIN
IMPGC2:	HRRZ T1,IMPLT1(Q3)	;FOR EVERY ENTRY
	TXNE T1,L1%FRE		;THAT IS NOT
	 JRST IMPGC3		;DELETED OR FREE
	CALL IMPHFL		;MARKED NECESSARY DELETED ENTRIES
	 BUG(CHK,IMPIFH,<IMPGC-IMPOSSIBLE FAILURE OF IMPHFL>)
IMPGC3:	AOBJN Q3,IMPGC2		;TRY NEXT ENTRY
	IUNLK
	RET
;UPBYT - UNPACK BYTE FROM CURRENT MSG FOR A CONNECTION

;	T1/ CONNECTION INDEX

;	RETURNS +1  BYTE IN T3

UPBYT::	ILOCK
	HLRZ T2,IMPLT4(T1)	;GET CURRENT BUFFER
	JUMPN T2,UPBYT1		;IS THERE A BUFFER
	CALL UPBGNB		;NO BUFFER, TRY TO GET ONE
	RET			;FAILED, RETURN NOSKIP
UPBYT1:	HRLI T2,ANBSEC		;SET SECTION NUMBER
	ILDB T3,1(T2)		;GET BYTE, BYTE PTR IN BFR HEADER
	SOSG 2(T2)		;COUNT DOWN BYTES IN BFR
	CALL UPBRB		;NOW EMPTY, RELEASE BFR
	IUNLK
	RETSKP
;UPMSG - UNPACK MESSAGE

;ACCEPTS
;	T1/	LT INDEX
;	T3/	STORE BYTE POINTER
;	T4/	MAX BYTE COUNT

;RETURNS +1  FAILURE NO BUFFER T1 SET UP FOR WAIT
;	 +2  SUCCESS 
;	     T1/   UNCHANGED
;	     T2/   CLOBBERED
;	     T3/   UPDATED
;	     T4/   UPDATED

UPMSG::	STKVAR <UPMSBP,UPMSCT,<UPMST1,2>>
	ILOCK
	MOVEM T3,UPMSBP		;SAVE STORE POINTER
	HLRZ T2,IMPLT4(T1)	;GET CURRENT BUFFER
	JUMPN T2,UPMSG1		;IS THERE ONE
	CALL UPBGNB		;NONE, TRY TO GET ONE
	RETBAD (,<MOVE T3,UPMSBP>) ;FAILED, RETURN BAD, IUNLK DONE
UPMSG1:	HRLI T2,ANBSEC		;SET SECTION NUMBER
	MOVE T3,2(T2)		;GET BUFFER COUNT
	CAML T3,T4		;LESS THAN WHAT HE WANTED?
	MOVE T3,T4		;NO.  GIVE HIM ONLY AS WHAT HE ASKED FOR
	SUB T4,T3		;UPDATE USER'S COUNT
	MOVEM T4,UPMSCT		;SAVE UPDATED COUNT
	JUMPE T3,UPMSG3
	MOVN T4,T3		;GET NEG. NO. OF CHAR. TO PROCESS
	ADDM T4,2(T2)		;UPDATE BUFFER COUNT
	CAIG T3,1		;DON'T BOTHER FOR JUST ONE
	 JRST UPMSG2
	MOVE T3,1(T2)		;CHECK FOR START OF WORD
	TLNE T3,700000		;AS THE P FIELD IN BOTH POINTERS
	 JRST UPMSG2		;IF SO DO A BLT
	MOVE T3,UPMSBP
	TLNE T3,700000
	 JRST UPMSG2
	DMOVEM T1,UPMST1	;SAVE LT AND BUFFER ADR
	MOVN T3,T4		;GET COUNT
	ADJBP T3,1(T2)
	MOVEI T1,(T3)		;GET FINAL ADR
	EXCH T3,1(T2)		;CONVERT POINTER TO ADR
	SUBI T1,(T3)		;FINAL - (START - 1)
	ADDI T2,1(T3)
	MOVN T3,T4		;GET COUNT
	ADJBP T3,UPMSBP
	EXCH T3,UPMSBP		;CONVERT POINTER TO ADR
	MOVEI T3,1(T3)
	CALL XBLTA		;DO RIGHT BLT
	DMOVE T1,UPMST1		;RESTORE LT AND ADR
	JRST UPMSG3		;BYPASS BYTE LOOP
UPMSG2:	ILDB T3,1(T2)		;LOAD BYTE FROM BUFFER USING BYTE
				; POINTER IN BUFFER (IT IS INDEXED BY T2
				; TO GET TO ANBSEC SECTION.)
	IDPB T3,UPMSBP		;STORE BYTE
	AOJL T4,UPMSG2		;GO DO ANOTHER BYTE

UPMSG3:	MOVE T4,UPMSCT		;GET UPDATED COUNT BACK
	SKIPG 2(T2)		;IMP BFR NOW EXHAUSTED?
	CALL UPBRB		;YES, RELEASE IT
	IUNLK
	MOVE T3,UPMSBP		;GET UPDATED BYTE POINTER
	RETSKP
;UPBGNB - TRY TO GET NEXT INPUT BFR

;ACCEPTS
;	T1/  LINK TABLE INDEX

;RETURNS +1  FAILURE
;	     T1/  SET UP FOR WAIT
;	 +2  SUCESS
;	     T1/ UNCHANGED
;	     T2/ BUFFER ADDRESS
;CLOBBERS T3

UPBGNB:	HLRZ T2,IMPLT3(T1)	;CHECK QUEUE OF IN BFRS
	JUMPE T2,UPBG1		;NONE?
	PUSH P,T4		;GOT A BUFFER SAVE T4
	HRLI T2,ANBSEC		;SET SECTION NUMBER
	HLLZ T3,0(T2)		;UNQUEUE THIS BUFFER
	SKIPN T3		;IS THERE ANOTHER BUFFER?
	HLLZS IMPLT2(T1)	;NO.  MAKE INPUT BUFFER LIST EMPTY
	HLLM T3,IMPLT3(T1)	;SAVE NEW OUTPUT BUFFER POINTER
	HRLM T2,IMPLT4(T1)	;SAVE CURRENT BFR ADR
	PUSH P,1(T2)		;SAVE HEADER IN CASE OF ERROR
	PUSH P,2(T2)
	HRRZ T4,0(T2)		;NUMBER WORDS IN BUFFER
	CAIGE T4,3		;AT LEAST OVERHEAD WORDS PRESENT?
	JRST UPBGNE		;NO, MSG TOO SHORT
	LOAD T3,LD%BYC,2(T2)	;NUMBER OF BYTES
	JUMPE T3,UPBGNE		;0 IS ILLEGAL, BUT IN CASE...
	LOAD T4,LD%BYS,2(T2)	;GET BYTE SIZE
	MOVEM T3,2(T2)		;LEAVE BYTE COUNT IN FULL WORD
	LOAD T3,IMPBS,(T1)	;GET BYTE SIZE FOR CONNECTION
	CAME T3,T4		;SAME AS THAT IN BUFFER?
	JRST UPBGNE		;NO
	MOVE T3,[POINT 0,2(T2),35]	;SET UP BYTE POINTER.  NOTE IDEXED BY T2
	TRNN T4,7		;GET BYTE OFFSET RIGHT
	 HRLI T3,(<POINT 0,(T2),31>)
	DPB T4,[POINT 6,T3,11]	;PUT BYTE SIZE IN POINTER IN T3
	MOVEM T3,1(T2)		;SAVE POINTER IN BUFFER
	MOVEI T3,^D36		;COMPUTE MAX BYTES WHICH COULD BE
	IDIV T3,T4		;AS WORDS*(BYTES/WD)
	HRRZ T4,0(T2)		;NUMBER OF WORDS
	IMULI T3,-3(T4)		;BUT NOT COUNTING OVERHEAD
	CAMGE T3,2(T2)		;ACTUAL GREATER THAN MAX?
	JRST UPBGNE		;YES, LOSSAGE
	ADJSP P,-2		;CLEAN UP STACK
	POP P,T4		;RESTORE T4
	RETSKP

UPBGNE:	CALL UPBRB		;RELEASE BUFFER
	POP P,T2		;GET SECOND WORD OF HEADER
	EXCH T1,0(P)		;GET 1ST WORD OF HEADER SAVING LT INDEX
	BUG(INF,IMPBSC,<MESSAGE HAS BAD SIZE OR COUNT>,<T1,T2>)
	POP P,T1		;GET LT INDEX BACK INTO T1
	POP P,T4		;RESTORE T4
	JRST UPBGNB		;TRY NEXT BUFFER
;NO INPUT READY, RETURN ACTIVATION TEST

UPBG1:	MOVSI T1,0(T1)		;CONNECTION INDEX INTO LEFT HALF
	HRRI T1,UPBGT		;WAIT FOR INPUT OR CLOSED CONN
	IUNLK
	RET

;UPBGT - SCHEDULER ACTIVATION TEST

UPBGT:	MOVSI T3,-1		;GET -1 IN LEFT HALF FOR TEST FOR BUFFER
	MOVSI T2,(LTDF)		;CHECK DONE FLAG
	TDNN T2,IMPLT2(T1)	;IF SET, OR
	TDNE T3,IMPLT3(T1)	;IF BFR(S) APPEARED
	JRST 1(T4)		;WAKEUP
	JRST 0(T4)		;OTHERWISE WAIT SOME MORE

;UPBRB - RELEASE INPUT BUFFER

;	T1/  LINK TABLE INDEX
;	T2/  BUFFER ADDRESS

UPBRB:	HRRZS IMPLT4(T1)	;CLEAR CURRENT BUFFER FIELD
	PUSH P,T1		;SAVE T1
	CALL RLNTBF		;RELEASE BFR BACK TO POOL
	POP P,T1		;RESTORE T1
	SOSL IMPLT4(T1)		;COUNT MSGS PROCESSED
	RET
	HRRZ T2,IMPLT1(T1)	;GET HOST-LINK NUMBER
	CALL IMP8X1		;GO UNPACK IT TO LINK,,HOST
	BUG(CHK,IMPREM,<UPBRB: RECEIVED EXCESSIVE MESSAGES>,T2)
	SETZM IMPLT4(T1)	;ZERO COUNT OF MESSAGES
	RET
;IMPCKO AND IMPKO1 - CHECK CONNECTION FOR OUTPUT POSSIBLE
;CALLED ON RECEIPT OF RFNM, ALLOCATION, ETC.
;	T1/ CONNECTION INDEX
;DO OUTPUT IF RFNM CLEAR, MSG ALLOC NON-0, AND OUTPUT EXISTS

IMPCKO:	ILOCK (JRST IMPROS)	;IF CAN'T CHECK NOW, SET REQUEST FLAG
IMPKO1:	MOVX T3,RFNMCM!ILCKB	;RFNM COUNT AND CONNECTION LOCKED FLAGS
	TDNE T3,IMPLT2(T1)	;RFNM OUT OR CONNECTION LOCKED?
	JRST IMPKO2		;YES, WILL TRY AGAIN LATER
	HLRZ T2,IMPLT3(T1)	;GET PTR FOR REMOVING BUFFS FROM CHAIN
	JUMPN T2,[HRLI T2,ANBSEC ;IF BUFFER EXIST SET SECTION NUMBER
		CALL IMPQO1	;IF COMPLETED BUFFERS ON OUTPUT QUEUE,
		JRST IMPKO1]	;GIVE ONE TO IMP TO SEND AND TRY AGAIN
	HLRZ T2,IMPLT4(T1)	;SEE IF PARTIAL BFR EXISTS
	JUMPN T2,[HRLI T2,ANBSEC ;IF BUFFER EXIST SET SECTION NUMBER
		CALL PKQOB	;COMPLETE IT AND SEND
		JRST IMPKO1]	;AND TRY AGAIN
	LOAD T2,LTLINK,(T1)	;GET LINK NUMBER
	JUMPE T2,[CALL IMPLL0	;CONTROL LINK?
		JRST IMPKO2]	;FLUSH CONN IF CTL LINK
	MOVSI T2,(RARRF)	;GET RAS REQUESTED FLAG
	TDNN T2,IMPLT2(T1)	;RAS REQUESTED?
	JRST IMPKO4		;NO
	PUSH P,T1		;YES.  SAVE LT TABLE INDEX
	ANDCAM T2,IMPLT2(T1)	;CLEAR REQUEST FOR RAS
	HLRZ IMPUN,IMPLT1(T1)	;GET UNIT
	SETZM NETBAL(IMPUN)	;ZERO BIT ALLOCATION
	HLLZS IMPLT4(T1)	;AND MSG ALLOCATION
	IUNLK
	LOAD T2,LTLINK,(T1)	;GET LINK NUMB