perm filename IMPCLK[S,SYS] blob sn#332541 filedate 1978-02-08 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00023 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00004 00002	BEGIN IMPSER ↔SUBTTL ARPANET NCP FOR THE IMP -  JAM SEPT '71
C00007 00003	 OPCODE DEFINITIONS FOR SECOND LEVEL PROTOCOL
C00011 00004	 PROTOCOL ERROR CODES
C00013 00005		A BRIEF DESCRIPTION OF THE PROTOCOL
C00018 00006			MORE PROTOCOL DESCRIPTIONS
C00022 00007	 BYTE POINTERS TO PARTS OF MESSAGE HEADER.
C00025 00008	 SPECIAL BITS IN RH OF IOS
C00028 00009	IMPSET IMPDD1 IMPCLR IMPCL1
C00029 00010	IMPCLK TIMCHL TIMN TIMC TIMCHI
C00032 00011	IMPMES PSCAN MTDSP
C00034 00012	TRCMES FRIMP EWOMI IMPGD IMPDD
C00036 00013	IMPLLP IMPDDI IMPDD4 IMPFDL IMPDD6
C00038 00014	IMPTMO IMPTM1 IMPTM2 IMPTM3
C00040 00015	BLKLNK LTABF RFNM L0RFNM HOST0 NOPCN
C00042 00016	DDEAD DDL DDLINC MRKD DDGOT
C00045 00017	INCT EWMI STERB L0EWMI L0EWL L0EWIN L0MRKE
C00048 00018	UNL UNLMER NODDB
C00049 00019	L0PTR CLRBL0
C00050 00020	UNBL0 L0FL L0INCR L0TRY NOLNKS
C00052 00021	CWL0 CWL0A CWL0G UNLCW CWL0NN
C00054 00022	FLCWL0 FLCWA FLCG
C00055 00023	UNBLOK UNBLK1 ILLUNB FNDLNK FNDL1 FNDL3 FNDL2
C00057 ENDMK
C⊗;
BEGIN IMPSER ↔SUBTTL ARPANET NCP FOR THE IMP -  JAM SEPT '71

HISYS

; ERROR TYPEOUT ROUTINE. INCREMENTS APPROPRIATE ERROR COUNTER THEN
; TYPES CTY MESSAGE.

DEFINE TELCTR (CTR,MESS) <
	AOS CTR
	SKIPN IMPPMS	; DO WE PRINT TODAY?
	JRST .+7	; NO, SKIP OVER ERROR MESSAGE
	PUSHJ P,DISDATE
	PUSHJ P,DISERR
	[ASCIZ / IMP, M#/]
	DISARG DEC,CTR
	[ASCIZ /
/]
	-1
>

DEFINE ERRCTR (CTR,MESS) <
	AOS CTR
	PUSHJ P,DISDATE
	PUSHJ P,DISERR
	[ASCIZ / IMP, M#/]
	DISARG DEC,CTR
	[ASCIZ /
/]
	-1
>

; DATA BLOCK DEFINITIONS . . .

TLINK←←0	; <NEXT MESSAGE>,,<NEXT BLOCK THIS MESSAGE>
TWC←←1		; DATA WORD COUNT
TLEN←←2		; LENGTH OF DATA PORTION OF BLOCK
TBP←←3		; INPUT BYTE POINTER
TDATA←←4	; BEGINNING OF DATA AREA
TLNG←←50	; LENGTH OF ENTIRE BLOCK
↑TDLEN←←TLNG-TDATA
		; LENGTH OF DATA PORTION ONLY

; DEBUGGING MASKS

LEADM←←741774007777	; MASK FOR LEADER
SCM←←740077777400	; MASK FOR SIZE AND COUNT FIELDS
; OPCODE DEFINITIONS FOR SECOND LEVEL PROTOCOL

NOP←←0		; NO-OPERATION
RTS←←1		; ESTABLISH CONNECTION, SENT FROM RECEIVER TO SENDER
		; FOLLOWED BY 32 BITS OF RECEIVE SOCKET,
		; 32 BITS OF SEND SOCKET, AND 8 BITS OF LINK NUMBER
STR←←2		; ESTABLISH CONNECTION, SENT FROM SENDER TO RECEIVER
		; FOLLOWED BY 32 BITS OF SEND SOCKET,
		; 32 BITS OF RECEIVE SOCKET, AND 8 BITS OF BYTE SIZE.
CLS←←3		; CLOSE CONNECTION. FOLLOWED BY 32 BITS LOCAL SOCKET
		; NUMBER AND 32 BITS FOREIGN SOCKET NUMBER
ALL←←4		; ALLOCATE. SENT FROM RECEIVER TO SENDER TELLING HOW
		; MUCH DATA MAY BE SENT AT A TIME. FOLLOWED BY
		; 8 BITS OF LINK NUMBER, 16 BITS OF MESSAGE SPACE
		; AND 32 BITS OF BIT SPACE.
GVB←←5		; GIVE BACK ALLOCATION. SENT FROM RECEIVER TO SENDER
		; TO REQUEST RETURN OF STORAGE. FOLLOWED BY 8 BITS
		; OF LINK NUMBER, 8 BITS OF A 7-FIXED-BINARY-PLACE
		; FRACTION WHICH IS THE FRACTION OF THE MESSAGE
		; SPACE TO BE RETURNED, AND 8 BITS OF FRACTION WHICH
		; IS THE FRACTION OF THE BIT SPACE TO BE RETURNED.
RET←←6		; RETURN STORAGE. SENT FROM SENDER TO RECEIVER EITHER
		; SPONTANEOUSLY OR IN RESPONSE TO A GVB COMMAND. FOLLOWED
		; BY 8 BITS OF LINK, 16 BITS OF MESSAGE SPACE, AND 32
		; BITS OF BIT SPACE.
INR←←7		; INTERRUPT BY RECEIVER. ASKS THE SENDER TO CEASE.
		; FOLLOWED BY 8 BITS OF LINK NUMBER.
INS←←10		; INTERRUPT BY SENDER. TELLS RECEIVER TO INTERRUPT
		; RECEIVING PROCESS. A SPECIAL CHARACTER IS INCLUDED
		; IN THE TEXT STREAM TO MARK WHERE IN TIME THE INTERRUPT
		; IS TO OCCUR. FOLLOWED BY 8 BITS OF LINK NUMBER.
ECO←←11		; ECHO TEST. FOLLOWED BY 8 BITS OF TEST DATA. RECEIVING
		; HOST IS TO RETURN SAID DATA VERBATUM VIA FOLLOWING COMMAND.
ERP←←12		; ECHO REPLY. FOLLOWED BY 8 BITS OF RETURNED TEST DATA.
ERR←←13		; ERROR. FOLLOWED BY 8 BITS OF ERROR CODE AND
		; 80 BITS OF ERROR DATA.
RST←←14		; RESET. ASKS HOST TO CLEAR ALL TABLES AND CONNECTIONS
		; HAVING TO DO WITH US.
RRP←←15		; RESET REPLY. INDICATES THE RESET HAS BEEN DONE.
; PROTOCOL ERROR CODES

ILO←←1		; ILLEGAL OPCODE. AN ILLEGAL OPCODE WAS DETECTED IN
		; A CONTROL MESSAGE. THE "dATA" FIELD CONTAINS THE TEN BYTES OF
		; THE AILING CONTROL MESSAGE BEGINNING WITH THE BYTE CONTAINING
		; THE ILLEGAL OPCODE.
SPS←←2		; SHORT PARAMETER SPACE. THE END OF A CONTROL MESSAGE
		; WAS ENCOUNTERED BEFORE ALL THE REQUIRED PARAMETERS OF
		; THE CONTROL COMMAND BEING DECODED WERE FOUND. THE "dATA"
		; FIELD CONTAINS THE COMMAND IN ERROR.
BDP←←3		; BAD PARAMETERS. ERRONEOUS PARAMETERS WERE FOUND
		; IN A CONTROL COMMAND. DATA FIELD CONTAINS AILING COMMAND.
NES←←4		; NON-EX SOCKET. A COMMAND OTHER THAN STR OR RTS WAS
		; RECEIVED FOR A CONNECTION FOR WHICH NO REQUEST FOR
		; CONNECTION HAS BEEN MADE.
LNC←←5		; LINK NOT CONNECTED. CONTROL COMMAND CONTAINING
		; A LINK NUMBER FOR WHICH NO CONNECTION EXISTS.

; WHEN THE ERROR CODE IS ZERO, THE NEXT 8 BIT BYTE IS THE STANFORD
; PECULIAR ERROR CODE, FOLLOWED BY 72 BITS OF THE AILING COMMAND
; RETURNED. HERE ARE THE STANFORD ERROR CODES.

CTO←←1		; COUNTER OVERFLOW. EITHER MESSAGE SPACE EXCEEDED
		; OR BIT SPACE EXCEEDED BY THE LAST MESSAGE. THE
		; MESSAGE WAS DISCARDED.
ILB←←2		; ILLEGAL BYTE SIZE FOR CONTROL MESSAGE. MESSAGE
		; WAS DISCARDED.
COMMENT ⊗	A BRIEF DESCRIPTION OF THE PROTOCOL
	THE PROTOCOL IS  IN  ABOUT  3  LAYERS.  THE  FIRST  LAYER  IS
IMP-HOST PROTOCOL. THE IMP SENDS US EACH MESSAGE PREFACED BY A 32-BIT
LEADER WHICH LOOKS LIKE THIS:

  0   1     2    3    4       7  8         15  16          23
**************************************************************
*   *    *     *     *         *             *               *
* 0 * FI * TRC * OCT *   TYPE  *     HOST    *      LINK     *
*   *    *     *     *         *             *               *
**************************************************************

	THE FI BIT MEANS THE MESSAGE IF FROM THE IMP TTY. THIS CAN BE
GENERATED USING THE CROSSPATCH MODE AND TYPING A MESSAGE TO  STANFORD
FROM  THE  TTY.  OUR  SYSTEM IGNORES SUCH MESSAGES. THE TRC BIT MEANS
THIS MESSAGE IS FOR TRACING FOR TEST PURPOSES AND WAS ISSUED FROM BBN
OR NMC. WE IGNORE IT ALSO. WE IGNORE THE OCT BIT. THE TYPE FIELD IS A
4-BIT OPCODE TELLING WHAT KIND OF MESSAGE THIS IS. ALL DATA  MESSAGES
FROM  FOREIGN HOSTS ARE TYPE 0 AND ARE CALLED "rEGULAR" MESSAGES. THE
OTHER TYPES ARE DESCRIBED IN BBN DOCUMENT  1822  "SPECIFICATIONS  FOR
THE  INTERCONNECTION  OF  A HOST AND AN IMP". I WILL BRIEFLY DESCRIBE
THEM HERE.
	TYPES 1, 3, 6, 7, 8, AND 9 ARE ALL ERRORS OF DIFFERENT KINDS.
IT MEANS THE LAST MESSAGE YOU SENT OUT WAS FLUSHED. TYPE 1  IS  ERROR
WITHOUT  MESSAGE  IDENTIFICATION.  TYPE  3  IS BLOCKED LINK, WHICH IS
MEANS WE GOOFED. WHEN YOU SEND A MESSAGE OUT, THE LINK (IDENTIFIED BY
THE  HOST-LINK  NUMBER, 16 BITS) BECOMES BLOCKED UNTIL THE MESSAGE IS
EITHER  FLUSHED  OR  DELIVERED  TO  THE  DESTINATION  COMPUTER.   THE
DESTINATION  IMP  THEN  RETURNS  THE REQUEST FOR NEW MESSAGE, TYPE 5,
BACK TO THE SENDING HOST. IF WE SEND OUT A MESSAGE  BEFORE  THE  RFNM
COMES  BACK,  WE  GET  A "bLOCKED LINK" ERROR, TYPE 3. TYPE 6 IS LINK
TABLE FULL. THIS MEANS WE SENT  OUT  SO  MANY  MESSAGES  ON  SO  MANY
DIFFERENT  LINKS  THAT COMBINED WITH THE MESSAGES ALREADY IN THE IMP,
WE OVERFLOWED ITS TABLES. TYPE 7 MEANS THE  DESTINATION  COMPUTER  OR
IMP  IS  DEAD, AS DETERMINED BY THE MESSAGE STAYING IN THE IMP SYSTEM
FOR 90 SECONDS. THE MESSAGE IS TIMES OUT AND FLUSHED. TYPE 8 IS ERROR
WITH  MESSAGE  IDENTIFICATION  AND TYPE 9 IS INCOMPLETE TRANSMISSION.
THESE ARE VERY NEBULOUS ERRORS. IT GENERALLY MEANS YOU SENT A MESSAGE
LONGER  THAN  8092  BITS,  OR  SENT  AN ILLEGAL TYPE IN THE LEADER OR
SOMETHING.
	TO SUMMARIZE, THE NORMAL SEQUENCE OF EVENTS IS THAT  WE  SEND
OUT A MESSAGE AND SOME TIME LATER GET A RFNM BACK.
		MORE PROTOCOL DESCRIPTIONS

	THE SECOND LEVEL PROTOCOL GOES AS FOLLOWS. WHEN A  CONNECTION
IS  OPEN,  THERE  IS  A  UNIQUE HOST-LINK NUMBER ASSOCIATED WITH EACH
DIRECTION OF COMMUNICATION. MESSAGES GO BACK  AND  FORTH  AS  REGULAR
MESSAGES.  OPENING  AND  CLOSING  CONNECTIONS  IS  THE HARD PART. ALL
"cONTROL" MESSAGES, THAT IS MESSAGES REGARDING  OPENING  AND  CLOSING
AND REGULATING CONNECTIONS THEMSELVES, GO ON LINK ZERO. MOST OF THESE
COMMANDS HAVE SOME IDENTIFYING FIELD THAT TELLS WHAT CONNECTION  THEY
ARE  TALKING  ABOUT.  OPENING  AND  CLOSING  A CONNECTION (BEFORE THE
UNIQUE LINK NUMBER IS ASSIGNED) IS DONE WITH THE CODES STR, RTS,  AND
CLS AND CARRY ALONG WHAT ARE CALLED SOCKET NUMBERS. THESE NUMBERS ARE
32-BITS LONG.
	TO  ESTABLISH  A CONNECTION, YOU NEED A FOREIGN SOCKET NUMBER
TO CONNECT TO. THERE  IS  DEFINED  TO  BE  AT  EACH  SITE  A  LOGGER,
LISTENING  TO  SOCKET 1, WHICH RETURNS YOU A SOCKET NUMBER FOR YOU TO
CONNECT TO. TO OPEN A CONNECTION, YOU SEND A STR OR A RTS,  DEPENDING
ON  WHETHER  YOU  ARE  SENDING OR RECEIVING. THESE OPERATIONS CARRY A
LOCAL SOCKET NUMBER AND A FOREIGN SOCKET NUMBER  AND  ONE  ADDITIONAL
BYTE,  WHICH  IS  A  CONNECTION BYTE SIZE IF RTS AND A LINK NUMBER IF
STR. A CONNECTION IS OPEN WHEN  STR  AND  RTS  WITH  MATCHING  SOCKET
NUMBERS  HAVE  BEEN  EXCHANGED.  A  CONNECTION IS HALF-DUPLEX. TO GET
TRANSMISSION BOTH WAYS, YOU NEED TO OPEN TWO CONNECTIONS.  THE  USUAL
WAY  IS  TO  OPEN  A CONNECTION ON THE SOCKET NUMBER YOU GET FROM THE
LOGGER AND ON THAT NUMBER PLUS ONE.
	A  CONNECTION  MAY  BE  CHANGED  IN  AT  LEAST  TWO WAYS. THE
SIMPLEST IS THE RESET (RST). A HOST RECEIVING A RESET IS SUPPOSED  TO
BREAK  ALL  CONNECTIONS  TO THE HOST SENDING THE RESET. THE RECEIVING
HOST IS TO RETURN A RESET REPLY (RRP) AS WELL.
	THE  GRACEFUL  WAY  TO  BREAK A CONNECTION IS TO SEND A CLOSE
(CLS) WITH THE PAIR OF SOCKET NUMBERS. THE HOST RECEIVING THE CLS  IS
TO  RETURN  A  CLS  WITH  THE SAME SOCKET NUMBERS IN IT AND CAUSE THE
CONNECTION TO BE BROKEN. THE CONNECTION IS NOT BROKEN UNTIL CLSS HAVE
BEEN EXCHANGED.
	WHEN A CONNECTION IS OPEN, THE RECEIVER SENDS THE  SENDER  AN
ALLOCATE  MESSAGE  (ALL) TELLING THE SENDER HOW MUCH BUFFERING HE HAS
AVAILABLE. EVERY TIME THE SENDER SENDS A MESSAGE, HE DECREMENTS  THIS
NUMBER.  EACH TIME THE SENDER RECEIVES AN ALLOCATE OPERATION, HE ADDS
THE NEW ALLOCATION INTO THE CURRENT ALLOCATION. ⊗
; BYTE POINTERS TO PARTS OF MESSAGE HEADER.
; ASSUMES POINTER TO FIRST BLOCK OF MESSAGE IN AC1

IMPBP:	POINT 1,TDATA(AC1),1	; 'MESSAGE FROM IMP' BIT
TRACEP:	POINT 1,TDATA(AC1),2	; TRACE MESSAGE BIT. MEANS MESSAGE IS
				; BEING ROUTED AROUND THE NETWORK FOR
				; ROUTING AND TIMING MEASUREMENT.
OCTALP:	POINT 1,TDATA(AC1),3	; MEANS MESSAGE IS FROM IMP DDT AND
				; IS TEXT FOR OCTAL NUMBERS
TYPEP:	POINT 4,TDATA(AC1),7	; IMP MESSAGE TYPE POINTER.
SRCP:	POINT 8,TDATA(AC1),15	; HOST NUMBER POINTER
LINKP:	POINT 8,TDATA(AC1),23	; LINK NUMBER POINTER
ELINKP:	POINT 16,TDATA(AC1),23	; PICKS UP 16 BIT HOST AND LINK NUMBER
SIZEP:	POINT 8,TDATA+1(AC1),11	; GETS BYTE SIZE FIELD
COUNTP:	POINT 16,TDATA+1(AC1),27
				; BYTE COUNT FIELD

; SPECIAL DEFINITIONS FOR 2ND LEVEL PROTOCOL

OPCDP:	POINT 8,TDATA+2(AC1),7
OLINKP:	POINT 8,TDATA+2(AC1),15
SZLKP:	POINT 8,TDATA+4(AC1),15	; FOR STR, IS BYTE SIZE, FOR RTS, IS LINK NUMBER
SOK1AP:	POINT 24,TDATA+2(AC1),31; POINTS TO FIRST PART OF FIRST SOCKET NUMBER FOR STR, RTS, AND CLS
SOK1BP:	POINT 8,TDATA+3(AC1),7	; POINTS TO SECOND PART OF FIRST SOCKET NUMBER
SOK2AP:	POINT 24,TDATA+3(AC1),31; FIRST PART OF SECOND SOCKET NUMBER
SOK2BP:	POINT 8,TDATA+4(AC1),7	; SECOND PART OF SECOND SOCKET NUMBER
BYTE2P:	POINT 8,TDATA+2(AC1),15	; SECOND BYTE OF MESSAGE
BYTE3P:	POINT 8,TDATA+2(AC1),23	; THIRD BYTE OF MESSAGE

; POINTERS INTO TIMEOUT FIELDS. EACH FIELD IS NUMBER OF 2-SECOND UNITS

CLSTP:	POINT 6,TIMES(DDB),5	; HOW LONG WE WILL WAIT FOR RETURN CLOSE
RFNMTP:	POINT 6,TIMES(DDB),11	; FOR RFNM ON ZERO OR NON-ZERO LINK
ALLTP:	POINT 6,TIMES(DDB),17	; FOR ALLOCATION
RFCTP:	POINT 6,TIMES(DDB),23	; FOR RETURN RFC
INPTP:	POINT 6,TIMES(DDB),29	; FOR INPUT
; SPECIAL BITS IN RH OF IOS

HDEAD←←002000		; HOST DEAD
CTROV←←001000		; HOST OVERFLOWED OUR ALLOCATION
RSET←←000400		; HE SENT US A RESET
TMO←←000200		; TIMEOUT ON WAIT STATE OCCURRED
BLOK←←000100		; THIS LINK IS BLOCKED

; LH BITS

DEFINE Z(SYM,VAL) <SYM←←VAL ↔ ANYW←←ANYW!VAL>

ANYW←←0
Z(INPW,200000)		; INPUT WAIT
Z(LNK0W,100000)		; CONTROL LINK WAIT
Z(BLOKW,040000)		; WAITING FOR LINK TO BECOME UNBLOCKED
Z(ALLW,020000)		; ALLOCATION WAIT
Z(TIMEW,010000)		; TIMEOUT WAIT
Z(RFCW,004000)		; WAIT FOR REQUEST FOR CONNECTION - LISTENING OR CONNECTION REQUESTED
Z(CLSW,002000)		; CLOSE WAIT. ONE CLOSE HAS BEEN SENT

; BITS IN LH OF STATE WORD IN IMPSTB

ANYC←←400000		; ANY CHANGE OF STATE
RFCS←←200000		; RFC HAS BEEN SENT
RFCR←←100000		; RFC HAS BEEN RECEIVED
CLSS←←040000		; CLS SENT
CLSR←←020000		; CLS RECEIVED
LONCE←←010000		; HCLSS HAS BEEN HERE ONCE
LGONCE←←004000		; LOGGER HAS BEEN HERE ONCE (NOT USED BY SYSTEM, BUT
			; LOGGER SETS THIS FLAG)

; OTHER PARAMETERS . . .

MAXCNT←←2*=60*=60	; THIS IS HOW LONG WE WILL WAIT FOR THE IMP TO GOBBLE
			; OUR OUTPUT
MAXMAL←←2000/TLNG	; MAXIMUM MESSAGE ALLOCATION FOR FOREIGNERS
MAXBAL←←40*2000		; MAXINAL BIT ALLOCATION
MINMAL←←2		; MINIMUM MESSAGE ALLOCATION
MINBAL←←=36*4		; MINIMUM BIT ALLOCATION
DEFMAL←←TDLEN		; DEFAULT MESSAGE ALLOCATION
DEFBAL←←44*TDLEN	; DEFAULT BIT ALLOCATION

; TABLE OF BITS PER WORD FOR DIFFERENT CONNECTION BYTE SIZES
; -1 MEANS THIS BYTE SIZE NOT ALLOWED.

BPW:	44 ↔ 44 ↔ 44 ↔ 44 ↔ 44 ↔ -1 ↔ 44 ↔ 44
	40 ↔ 44 ↔ -1 ↔ -1 ↔ 44 ↔ -1 ↔ -1 ↔ -1
	40 ↔ -1 ↔ 44 ↔ -1 ↔ -1 ↔ -1 ↔ -1 ↔ -1
	-1 ↔ -1 ↔ -1 ↔ -1 ↔ -1 ↔ -1 ↔ -1 ↔ -1
	40 ↔ -1 ↔ -1 ↔ -1 ↔ 44
;IMPSET IMPDD1 IMPCLR IMPCL1

; ROUTINES TO MAKE AND RELEASE IMP DEVICE DATA BLOCKS

↑IMPSET:
	MOVEI AC3,IMPDLN
	PUSHJ P,FSGET
	JRST IMPDD1
	HRRI DDB,1(AC1)
	HRLI AC1,DDBMDL-1
	BLT AC1,IMPTIM(DDB)
	HRLM DDB,DDBMDL+DEVSER
	SETZM DDBMDL+DEVLOG
	POPJ P,

IMPDD1:	SUB P,[XWD 3,3]
	JRST DLYCM1

↑IMPCLR:
	SETZB IOS,DEVIOS(DDB)
	MOVEI AC1,DDBMDL
IMPCL1:	MOVE TAC1,AC1
	HLRZ AC1,DEVSER(TAC1)
	JUMPE AC1,CPOPJ
	CAIE AC1,(DDB)
	JRST IMPCL1
	MOVE DDB,DEVSER(AC1)
	HLLM DDB,DEVSER(TAC1)
	SOJA AC1,FSGIVE
;IMPCLK TIMCHL TIMN TIMC TIMCHI

; CLOCK LEVEL ROUTINE. CALLED EVERY TICK. EXAMINES INPUT MESSAGES

↑IMPCLK:
	SKIPE IMPINF
	PUSHJ P,IMPINI		;DON'T RUN IMP UNTIL CLOCK IS ON
	MOVEM P,IMPFP
	SKIPE IMPCLW		; WAITING FOR FREE STORAGE?
	JRST CLKWT		; YES, DO NOTHING ELSE FOR A WHILE
	SKIPE ILIST		; ANY INCOMMING MESSAGES?
	JRST IMPMES		; YES, GO PROCESS THEM
	SOSG IMPOCT		; HOW LONG HAVE WE BEEN WAITING FOR OUTPUT TO FINISH?
	PUSHJ P,IMPTMO		; TOO DAMN LONG. GO SEE ABOUT IT
	SKIPE RECOVER		; HAS ERROR RECOVERY SYSTEM BEEN INVOKED?
	PUSHJ P,ERRREC		; YES, GO KEEP ON RECOVERING.
	SOSGE POLCNT		; TIME TO POLL YET?
	PUSHJ P,POLL		; YES, DO IT NOW
	SKIPE TIMWAIT		; ANYONE WAITING FOR A TIMEOUT?
	SOSLE TIMCNT		; YES, IS IT TIME TO CHECK?
	POPJ P,
	MOVEI AC1,2*JIFSEC	; YES, WAIT FOR ANOTHER SECOND
	MOVEM AC1,TIMCNT	; RESET COUNTDOWN
	SKIPN AC3,FFLNK		; ANYONE TO CHECK?
	POPJ P,			; NO, DON'T BOTHER
TIMCHL:	SKIPE DDB,IMPDDB-1(AC3)	; ANYONE HOME?
	SKIPGE AC1,IMPTIM(DDB)	; YES, IS HE WAITING FOR US?
	JRST TIMCHI		; NO TO EITHER OR BOTH
	SUB AC1,TIME		; GET DIFFERENCE BETWEEN CRITICAL TIME AND RIGHT NOW
	JUMPL AC1,TIMN		; DIFFERENT ROUTINE FOR NEGATIVE DIFFERENCE
	CAML AC1,[=12*=60*JIFMIN]
	SUB AC1,JIFDAY		; WRAP IT BACK AROUND TO GET A SMALL NUMBER
	JRST TIMC		; NOW CHECK IT

TIMN:	CAMGE AC1,[-=12*=60*JIFMIN]
	ADD AC1,JIFDAY
TIMC:	JUMPG AC1,TIMCHI	; IF DIFFERENCE IS POSITIVE, HASN'T EXPIRED YET
	MOVEI IOS,TMO		; NOTE THAT A TIMEOUT HAS HAPPENED
	ORM IOS,DEVIOS(DDB)
	PUSHJ P,QRUN
	SKIPLE TIMWAIT		; ANYONE ELSE?
TIMCHI:	SOJG AC3,TIMCHL		; YES, GO BACK FOR MORE
	POPJ P,
;IMPMES PSCAN MTDSP

; WE GET HERE IF THERE ARE MESSAGES WAITING ON THE INPUT LIST

IMPMES:	HRRZ AC1,ILIST		; YES, PICK UP ADDRESS OF FIRST MESSAGE
	PUSHJ P,LEGAL		; IS THIS A REASONABLE BLOCK
	JRST [	SETZM ILIST	; NO, FLUSH THE LIST
		JRST IMPCLK]
	LDB AC2,IMPBP		; SEE IF IT IS FROM THE IMP
	JUMPN AC2,FRIMP		; YES, DISCARD.
	LDB AC2,TRACEP		; IS IT A TRACE MESSAGE
	JUMPN AC2,TRCMES	; YES, DISCARD IT.
	LDB AC2,TYPEP		; PICK UP MESSAGE TYPE
	CAIGE AC2,MAXMT		; IS IT LEGAL?
	JRST @MTDSP(AC2)	; YES, DISPATCH TO IT
	TELCTR(ILLMT,<ILLEGAL MESSAGE TYPE>)
PSCAN:	PUSHJ P,POPMESS		; TAKE MESSAGE OFF LIST AND RELEASE STORAGE
	JRST IMPCLK

; DISPATCH TABLE FOR MESSAGE TYPES

MTDSP:	REGULAR		; REGULAR MESSAGE. ALL DATA AND CONTROL COME THROUGH HERE.
	EWOMI		; ERROR WITHOUT MESSAGE IDENTIFICATION
	IMPGD		; IMP GOING DOWN
	BLKLNK		; BLOCKED LINK - WE GOOFED!
	NOPCN		; NO OPERATION.
	RFNM		; READY FOR NEXT MESSAGE, UNBLOCK LINK
	LTABF		; LINK TABLE FULL - HORRIBLE IMP ERROR!
	DDEAD		; HOST OR DESTINATION IMP DEAD
	EWMI		; ERROR WITH MESSAGE IDENTIFICATION
	INCT		; INCOMPLETE TRANSMISSION
MAXMT←←.-MTDSP
;TRCMES FRIMP EWOMI IMPGD IMPDD

; MESSAGE TYPE DISPATCHES - TRACE, FROM IMP, IMP GOING DOWN
; TRACE MESSAGE. LOG THEN DISCARD.

TRCMES:	AOSA TRACES
FRIMP:	AOS FRMIMP
	JRST PSCAN

EWOMI:	TELCTR(ERWOMI,<ERROR WITHOUT MESSAGE IDENTIFICATION>)
	SKIPN RECOVER
	SETOM RECOVER
	JRST PSCAN

IMPGD:	AOS NIMPDN
	PUSHJ P,IMPDD		; BRING DOWN IMP SYSTEM
	JRST IMPCLK		; GO THROUGH THE LOOP AGAIN

IMPDD:	SETOM IMPDEAD		; SHUT DOWN THE IMP
	HRLOI AC1,377777
	MOVEM AC1,IMPOCT
	CONO IMP,ODPIEN!IDPIEN!IEPIEN
	SETZM IMPECT		; SET ERROR COUNT TO ZERO
	PUSHJ P,DISDATE
	PUSHJ P,DISMES
	ASCIZ /IMP IS DEAD
/
	SKIPE AC1,ILIST		; NOW WE HAVE TO GIVE BACK ALL THE BUSINESS IN PROGRESS
	PUSHJ P,RELBLS
	SETZM ILIST
	SKIPE AC1,OLIST		; OUTPUT LIST TOO
	PUSHJ P,RELBLS
	SETZM OLIST
	SKIPE AC1,L0CWTL
	PUSHJ P,RELBLS
	SETZM L0CWTL
;FALLS THROUGH
;IMPLLP IMPDDI IMPDD4 IMPFDL IMPDD6

; IMP DEAD CODE - RUN DOWN LINK TABLE AND WAKE UP ANY WAITERS
;FALLS THROUGH FROM PREVIOUS PAGE

	SKIPN AC3,FFLNK		; NOW SEE IF THERE ARE ANY QUEUED RFC'S TO BE RELEASED
	JRST IMPDD4
IMPLLP:	SKIPE AC1,IMPRFQ-1(AC3)	; IS THERE ANOTHER RFC LIST
	PUSHJ P,RELBLS
	SETZM IMPRFQ-1(AC3)
	SKIPN DDB,IMPDDB-1(AC3)
	JRST IMPDDI
	MOVE IOS,DEVIOS(DDB)
	ORI IOS,HDEAD!IODTER
	ANDCMI IOS,BLOK
	TLZE IOS,ANYW		; BRING THIS GUY OUT OF WAIT STATE
	PUSHJ P,QRUN
	MOVEM IOS,DEVIOS(DDB)
IMPDDI:	SOJG AC3,IMPLLP
IMPDD4:	SKIPLE AC1,IMPITOP	; GIVE BACK ANY PARTIALLY IMPUTTED MESSAGE
	PUSHJ P,RELLST
	SETZM IMPITOP
	SKIPE AC1,IMPSPARE	; GIVE BACK ANY SPARE BLOCKS WHAT MAY BE
	PUSHJ P,IMPREL
	SETZM IMPSPARE
	SKIPN AC1,IMPFSL
	JRST IMPDD6		; IF NO SPARE LIST, FORGET IT
IMPFDL:	PUSH P,(AC1)		; SAVE ADDRESS OF NEXT BLOCK
	PUSHJ P,FSGIVE
	POP P,AC1
	JUMPN AC1,IMPFDL
	SETZM IMPFSL
IMPDD6:	POPJ P,
;IMPTMO IMPTM1 IMPTM2 IMPTM3

; INTERFACE TIMED OUT (SHUDDER!). BRING THE SYSTEM DOWN.

IMPTMO:	ERRCTR(OPTMO,<INTERFACE TIMED OUT>)
	MOVE AC1,OPTMO
	CAIL AC1,10
	JRST IMPDD		; IF TOO MANY TIMEOUTS, BRING DOWN THE IMP
	SKIPLE NOPCNT
	JRST IMPTM3
	SKIPE AC1,IMPOCUR	; PICK UP CURRENT OUTPUT BLOCK
	PUSHJ P,RELLST		; GIVE BACK THE REST OF IT
	SETOM RECOVER
	SKIPN AC1,OLIST
	JRST IMPTM2
	HLRZ AC2,TLINK(AC1)	; GET LINK TO NEXT OUTPUT REQUEST
	HRRM AC2,OLIST		; MAKE IT NEW CURRENT REQUEST
	SKIPN AC2
	SETZM OLIST
	HRRZS AC1
	CONO IMP,FINO		; MAKE SURE INTERFACE THINKS WE ARE DONE
	MOVEI AC3,200
IMPTM1:	CONSO IMP,ODONE
	SOJG AC3,IMPTM1
	JRST QIDLE		; TRY TO START THE NEXT TRANSFER

IMPTM2:	SETZM IMPOACT
	HRLOI AC1,377777
	MOVEM AC1,IMPOCT
	POPJ P,

IMPTM3:	SETOM RECOVER
	CONO PI,IMPOFF
	CONO IMP,FINO		;TRY TO UNHANG OUTPUT IF POSSIBLE
	MOVEI AC3,200
	CONSO IMP,ODONE
	SOJG AC3,.-1
	JRST SNDNOP		;WILL DO CONO PI,IMPON
;BLKLNK LTABF RFNM L0RFNM HOST0 NOPCN

; BLOCKED LINK, LINK TABLE FULL, RFNM, AND NOP

BLKLNK:	SKIPE RECOVER
	JRST PSCAN
	SETOM RECOVER
	TELCTR(NBLNKS,<BLOCKED LINK>)
	JRST STERB

LTABF:	TELCTR(LTFULL,<LINK TABLE FULL!!?!?!>)
	JRST STERB

; REQUEST FOR NEW MESSAGE. UNBLOCK LINK AND WAKE UP ANY WAITERS.

RFNM:	LDB AC2,ELINKP		; PICK UP HOST-LINK NUMBER
	TRNN AC2,177400		; HOST ZERO?
	JRST HOST0		; YES, NO SUCH HOST
	TRNN AC2,377		; LINK 0?
	JRST L0RFNM		; YES, UNBLOCK IT SEPARATELY
	PUSHJ P,FNDLNK		; NO, SEARCH LINK TABLE FOR IT
	JRST UNL		; NOT THERE, SEND BACK UNKNOWN LINK ERROR
	SKIPE DDB,IMPDDB-1(AC3)	; LINK THERE, DOES IT HAVE A DDB?
	PUSHJ P,UNBLOK		; YES, UNBLOK IT AND RESUME ANY RELEVANT PROCESS
	JRST PSCAN		; IF NO DDB, PROCESS MIGHT HAVE BEEN RESET, SO DON'T WORRY ABOUT IT

L0RFNM:	PUSHJ P,UNBL0		; UNBLOCK LINK 0 AND SEND ANY WAITING CONTROL MESSAGES
	JRST PSCAN

HOST0:	AOS NHOST0
	JRST PSCAN

; NO-OPERATION. LOG AND LEAVE.

NOPCN:	AOS FLNOPS		; NUMBER OF FIRST-LEVEL NO-OPS
	JRST PSCAN
;DDEAD DDL DDLINC MRKD DDGOT

; HOST OR DESTINATION IMP DEAD. MARK HOST DEAD AND GIVE EVERYBODY ERRORS.
; WAKE ANYBODY UP WAITING FOR US. FLUSH WAITING CLOCK LEVEL CONTROL MESSAGES.

DDEAD:	PUSHJ P,FLCWL0		; FLUSH WAITING CONTROL MESSAGES
	LDB AC2,ELINKP		; PICK UP HOST-LINK NUMBER
	ANDCMI AC2,377		; CLEAR LINK NUMBER
	SKIPN AC3,FFLNK		; PICK UP NUMBER OF FIRST FREE ENTRY IN LINK TABLE
	JRST MRKD		; NONE THERE, MARK HOST DEAD AND LEAVE
DDL:	MOVEI TAC,(AC2)		; SAVE COPY OF HOST NUMBER
	XOR TAC,LNKTAB-1(AC3)	; COMPARE IT WITH HOST NUMBER IN LINK TABLE
	TRNN TAC,177400		; DO HOST NUMBERS MATCH?
	JRST DDGOT		; YES, WAKE HIM UP IF NECESSARY
DDLINC:	SOJG AC3,DDL		; LOOP AROUND FOR NEXT LINK TABLE ENTRY
MRKD:	LDB TEM,LINKP		; PICK UP LINK NUMBER
	JUMPN TEM,PSCAN
	PUSHJ P,L0PTR		; PICK UP POINTER INTO HOST TABLES
	ANDCAM AC3,L0BLOK(AC2)	; CLEAR LINK
	JRST PSCAN

; COME HERE WITH DDB OF AN ACTIVE CONNECTION TO SEE IF IT SHOULD
; BE AWAKENED.

DDGOT:	MOVE TEM,IMPSTB-1(AC3)	; PICK UP THIS HOLE'S STATUS BITS
	TLNE TEM,RFCR!RFCS	; ANY CONNECTION HERE?
	SKIPN DDB,IMPDDB-1(AC3)	; IS THERE A DDB?
	JRST DDLINC		; NO, LOOP AROUND
	MOVE IOS,DEVIOS(DDB)	; YES, PICK UP STATUS WORD
	TLNE IOS,LNK0W		; WAITING FOR LINK 0?
	SOS L0WAIT		; YES, DECREMENT COUNT OF PEOPLE WAITING FOR LINK 0
	ORI IOS,HDEAD!IODTER
	ANDCMI IOS,BLOK		; UNBLOCK LINK
	TLZE IOS,ANYW		; ANY WAIT STATE?
	PUSHJ P,QRUN		; YES, REQUE TO RUN STATE.
	MOVEM IOS,DEVIOS(DDB)	; RESTORE STATUS WORD
	JRST DDLINC		; GO LOOK AT NEXT ONE
;INCT EWMI STERB L0EWMI L0EWL L0EWIN L0MRKE

; INCOMPLETE TRANSMISSION, ERROR WITH MESSAGE IDENTIFICATION

INCT:	AOSA INCMTR
EWMI:	AOS ERWMI
STERB:	LDB AC2,ELINKP		; PICK UP HOST-LINK NUMBER
	TRNN AC2,177400
	JRST HOST0		; NO HOST ZERO
	TRNN AC2,377		; LINK 0?
	JRST L0EWMI		; YES, CLEAR IT SEPARATELY
	PUSHJ P,FNDLNK		; NO, LOCATE POSITION IN LINK TABLE
	JRST PSCAN		; UNKNOWN LINK. DO NOT SEND ERROR MESSAGE!
	SKIPN DDB,IMPDDB-1(AC3)	; IS THERE A DDB THERE?
	JRST NODDB		; NO
	PUSHJ P,UNBLOK		; YES, PICK UP IOS AND UNBLOCK LINK
	ORI IOS,IODERR
	MOVEM IOS,DEVIOS(DDB)	; NOTE THAT AN ERROR HAS HAPPENED AND THAT WE MIGHT RECEIVE A RFNM LATER
	JRST PSCAN

L0EWMI:	PUSHJ P,CLRBL0		; UNBLOCK LINK
	PUSHJ P,CWL0		; WAKE UP ANYBODY WAITING FOR LINK 0
	JFCL
	SKIPE L0WAIT		; IS THERE ANYBODY AT USER-LEVEL WAITING?
	SKIPN AC3,FFLNK		; YES, IS THERE A LINK TABLE TO SEARCH
	JRST PSCAN		; NO, FLUSH TRANSFER AND LEAVE
	LDB AC2,ELINKP		; PICK UP HOST-LINK NUMBER
L0EWL:	MOVEI TAC,(AC2)		; SAVE HOST-LINK NUMBER
	XOR TAC,LNKTAB-1(AC3)	; COMPARE IT WITH TABLE
	TRNN TAC,177400		; DO HOST NUMBERS MATCH?
	JRST L0MRKE		; YES
L0EWIN:	SOJG AC3,L0EWL		; NO, LOOP AROUND
	JRST PSCAN

L0MRKE:	MOVE TEM,IMPSTB-1(AC3)
	TLNE TEM,RFCR!RFCS
	SKIPN DDB,IMPDDB-1(AC3)	; PICK UP DEVICE DATA BLOCK ADDRESS
	JRST L0EWIN		; NONE THERE, LOOP AROUND
	MOVE IOS,DEVIOS(DDB)
	TLZN IOS,LNK0W		; WAITING FOR LINK 0?
	JRST L0EWIN		; NO, FORGET IT
	PUSHJ P,QRUN		; YES, PUT HIM IN RUN QUEUE
	ORI IOS,IODERR		; AND GIVE HIM ERROR MESSAGE
	MOVEM IOS,DEVIOS(DDB)
	SKIPE L0WAIT		; ARE THERE ANY MORE WAITERS?
	JRST L0EWIN		; YES, GO LOOK FOR THEM
	JRST PSCAN
;UNL UNLMER NODDB

; UNKNOWN LINK AND NO DDB ERROR TYPEOUTS

UNL:	TELCTR(UNKLNK,<UNKNOWN LINK>)
	PUSHJ P,UNLMER
	JRST PSCAN

UNLMER:	PUSH P,AC1		; SAVE INPUT MESSAGE ADDRESS
	PUSHJ P,MAKERB		; MAKE UP AN ERROR BLOCK
	PUSHJ P,CLKWAIT		; IF NONE, WAIT FOR IT (SIGH)
	PUSHJ P,EFILL		; SEND HIM BACK HIS COMMAND
	MOVEI AC3,LNC		; GIVE HIM LINK-NOT-CONNECTED ERROR
	DPB AC3,BYTE2P
	PUSHJ P,CLKOUT		; SEND IT OUT
	POP P,AC1		; GET BACK HIS MESSAGE
	POPJ P,

NODDB:	TELCTR(NODDBS,<NO DDB>)
	JRST PSCAN
;L0PTR CLRBL0

; ROUTINE TO MAKE UP A POINTER INTO THE HOST TABLES
; CALL WITH POINTER TO INCOMMING MESSAGE IN AC1
; RETURNS INDEX IN AC2 AND SINGLE BIT IN AC3

L0PTR:	LDB AC2,[POINT 5,TDATA(AC1),15]
	MOVEI AC3,1
	LSH AC3,(AC2)
	LDB AC2,[POINT 3,TDATA(AC1),10]
	POPJ P,

; ROUTINE TO UNBLOCK LINK ZERO
; CALL WITH POINTER TO INCOMMING MESSAGE IN AC1

CLRBL0:	PUSHJ P,L0PTR
	TDNN AC3,L0BLOK(AC2)	; FIRST, IS IT BLOCKED?
	JRST ILLUNB
	ANDCAM AC3,L0BLOK(AC2)	; YES, CLEAR IT
	POPJ P,
;UNBL0 L0FL L0INCR L0TRY NOLNKS

; ROUTINE TO UNBLOCK LINK ZERO AND WAKE UP ANYBODY WAITING FOR IT

UNBL0:	PUSHJ P,CLRBL0		; CLEAR BLOCK ON LINK ZERO
	PUSHJ P,CWL0		; WAKE UP ANY CLOCK LEVEL WAITERS
	SKIPN L0WAIT		; ANY UUO LEVEL WAITERS?
	POPJ P,			; LEAVE IF A CLOCK LEVEL WAITER WAS AWOKEN OR IF NO UUO WAITERS
	SKIPN AC3,FFLNK		; SCAN LINK TABLE
	JRST NOLNKS		; NONE THERE, ERROR
	LDB AC2,ELINKP		; PICK UP HOST-LINK NUMBER
L0FL:	MOVE TAC,AC2
	XOR TAC,LNKTAB-1(AC3)
	TRNN TAC,177400		; HOST NUMBERS MATCH?
	JRST L0TRY		; YES, SEE IF HE IS WAITING FOR LINK 0
L0INCR:	SOJG AC3,L0FL
	POPJ P,

L0TRY:	SKIPN DDB,IMPDDB-1(AC3)
	JRST L0INCR
	MOVE IOS,DEVIOS(DDB)
	TLZN IOS,LNK0W
	JRST L0INCR
	SOS L0WAIT		; NOTE ONE LESS UUO-LEVEL WAITER
	PUSHJ P,QRUN
	MOVEM IOS,DEVIOS(DDB)
	SKIPE L0WAIT
	JRST L0INCR
	POPJ P,

NOLNKS:	TELCTR(NRFNL,<RFNM WITH NO LINK>)
	POPJ P,
;CWL0 CWL0A CWL0G UNLCW CWL0NN

; ROUTINE TO TRANSMIT ANY MESSAGES IN CLOCK WAIT ON LINK 0
; CALL WITH INCOMMING MESSAGE CAUSING UNBLOCKING IN AC1
; SKIPS IF ANY WAITING MESSAGES WERE FOUND

CWL0:	SETZ TAC1,		; NOTE NO PREVIOUS WAITER
	LDB AC3,SRCP		; PICK UP HOST NUMBER
	SKIPN AC2,L0CWTL	; PICK UP WAIT LIST
	POPJ P,			; NONE THERE
CWL0A:	LDB TAC,[POINT 8,TDATA(AC2),15]
	CAMN TAC,AC3		; SAME HOST?
	JRST CWL0G		; YES, SERVE HIM
	MOVE TAC1,AC2		; PUT THIS BLOCK IN LAST BLOCK POSITION
	HLRZ AC2,TLINK(AC2)	; PICK UP NEXT BLOCK ADDRESS
	JUMPN AC2,CWL0A		; IF THERE IS ONE, LOOP AROUND AND SERVE IT
	POPJ P,

CWL0G:	PUSHJ P,UNLCW		; UNLINK IT
	PUSH P,AC1
	MOVE AC1,AC2
	PUSHJ P,QOUT		; SEND IT OUT
	POP P,AC1
	PUSHJ P,L0PTR
	ORM AC3,L0BLOK(AC2)	; NOTE LINK 0 BLOCKED
	JRST CPOPJ1		; GIVE SKIP RETURN

; ROUTINE TO UNLINK A BLOCK FROM THE CLOCK WAIT LIST
; CALL WITH BLOCK ADDRESS IN AC2 AND ACCRESS OF PREVIOUS BLOCK IN TAC1

UNLCW:	JUMPN TAC1,CWL0NN
	HLRZ AC3,TLINK(AC2)	; PICK UP ADDRESS OF NEXT BLOCK
	HRRM AC3,L0CWTL
	SKIPN AC3
	SETZM L0CWTL
	POPJ P,

CWL0NN:	HLRZ AC3,TLINK(AC2)
	HRLM AC3,TLINK(TAC1)
	SKIPN AC3
	HRLM TAC1,L0CWTL
	POPJ P,
;FLCWL0 FLCWA FLCG

; ROUTINE TO FLUSH ALL CLOCK-LEVEL OUTPUTS TO A PARTICULAR HOST
; CALL WITH INCOMMING MESSAGE IN AC1

FLCWL0:	SETZ TAC1,
	LDB AC3,SRCP
	SKIPN AC2,L0CWTL
	POPJ P,
FLCWA:	LDB TAC,[POINT 8,TDATA(AC2),15]
	CAMN TAC,AC3
	JRST FLCG
	MOVE TAC1,AC2
	HLRZ AC2,TLINK(AC2)
	JUMPN AC2,FLCWA
	POPJ P,

FLCG:	HLRZ DAT,TLINK(AC2)
	PUSH P,AC3		; SAVE STATE OF SCAN
	PUSH P,DAT
	PUSH P,AC1
	PUSH P,TAC1
	PUSHJ P,UNLCW		; UNLINK LIST FROM WAIT LIST
	MOVE AC1,AC2
	PUSHJ P,RELLST		; RELEASE STORAGE IN LIST
	POP P,TAC1
	POP P,AC1
	POP P,AC2
	POP P,AC3
	JUMPN AC2,FLCWA
	POPJ P,
;UNBLOK UNBLK1 ILLUNB FNDLNK FNDL1 FNDL3 FNDL2

; UNBLOCKING ROUTINE FOR NON-ZERO LINK
; DDB MUST BE SET UP

UNBLOK:	MOVE IOS,DEVIOS(DDB)
	TRZN IOS,BLOK		; IS IT BLOCKED?
	JRST ILLUNB
	TLZE IOS,BLOKW		; IS HE WAITING FOR IT TO BECOME UNBLOCKED?
	PUSHJ P,QRUN		; YES, WAKE HIM UP
UNBLK1:	MOVEM IOS,DEVIOS(DDB)
	POPJ P,

ILLUNB:	PUSH P,DDB
	SKIPN RECOVER
	SETOM RECOVER
	TELCTR(BDRFNM,<UNBLOCKING AN ALREADY UNBLOCKED LINE>)
	POP P,DDB
	POPJ P,

; ROUTINE TO FIND THE INDEX OF A GIVEN HOST-LINK NUMBER
; FINDS SEND-SIDE INDEX ONLY
; ENTER WITH HOST-LINK NUMBER IN AC2
; RETURNS INDEX INTO LNKTAB AND IMPDDB IN AC3
; SKIPS ON SUCCESS

FNDLNK:	SKIPN AC3,FFLNK		; PICK UP NUMBER OF FIRST FREE LINK
	POPJ P,
FNDL1:	CAMN AC2,LNKTAB-1(AC3)	; IS THIS IT?
	JRST FNDL2		; YES, CHECK FOR SEND-SIDE
FNDL3:	SOJG AC3,FNDL1
	POPJ P,

FNDL2:	MOVE TEM,IMPLS-1(AC3)
	TRNN TEM,1
	JRST FNDL3
	JRST CPOPJ1