Google
 

Trailing-Edge - PDP-10 Archives - tops10_703_distr_bb-x140b-sb - 10,7/703anf/dndte.p11
There are 3 other files named dndte.p11 in the archive. Click here to see a list.
.SBTTL	DNDTE - KL10/PDP-11 INTERFACE  20 NOV 84

;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,1979,1980,1981,1984 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.

VRDTE=034			;FILE EDIT NUMBER

;THE BULK OF THIS MODULE COMES FROM RSX-20F, SPECIFICALLY
;DMDTE.MAC,QPRDTE.MAC, AND SCOMM.MAC. THE FIRST PART OF THE FILE
;CONTAINS SUBROUTINES THAT DUPLICATE THE SUBROUTINES IN DNDL10.MAC
;
;DTE INTERRUPTS NO LONGER USED

.IIF NE DEBUG,$DBDTE=-1		;ENABLE DTE DEBUG CODE IF WILLING TO DIE
DTE.LVL	=6			;PI LEVEL FOR DTE20



	.MACRO	.CRASH	CODE
	TRAP	S..DTE
	.ENDM
.SBTTL		TO ELEVEN BLOCKS


	BLOCK	TE		;TO ELEVEN  *** DO NOT CHANGE ORDER ***
	X	LNK,1		;ADDRESS OF NEXT CHUNK IN MESSAGE
	X	QPR,1		;# OF BYTES LEFT TO XFER IN QPR MESSAGE
	X	LEN,1		;TOTAL LENGTH OF MESSAGE
	XX	FFW,1		;COPY OF FIRST WORD FOR CURRENT QPR MSG
		FW.MOR	=1*400	;SET WHEN THERE WILL BE ANOTHER QPR
				;  MESSAGE IN THIS NCL MESSAGE
	XX	LIN,1		;HIGH BYTE IS LINE NUMBER, FLAGS FOR NCL
	X	CNK,1		;SPACE LEFT IN CURRENT CHUNK
	X	QHD,1		;QPR MESSAGE HEADER - LENGTH OF 1ST MESSAGE
	X	QFN,1		;FUNCTION
	X	QDV,1		;DEVICE (BETTER BE NCL)
	X	CMP,0		;START OF USER DATA FOR COMPRESSION
	X	QSP,1		;SPARE WORD
	X	ADR,1		;ADDRESS OF WHERE TO PUT DATA OF NEXT FRAGMENT
	X	.SZ,0		;SIZE OF THE TO-11 BLOCK

.IIF NE TE..SZ-CN.NCT,.PRINT; Phase error in TO-11 blocks.

.SBTTL		TO TEN BLOCKS


	BLOCK	TT		;TO TEN  *** DO NOT CHANGE ORDER ***
	X	FLK,1		;FORWARD LINK
	X	RLK,1		;REVERSE LINK
	X	ALC,1		;*OBS* SPACE ALLOCATED FOR THIS BLOCK
	X	HDL,1		;LENGTH OF HEADER
	X	QHD,1		;FIRST QPR WORD, LENGTH OF HEADER
	X	QFN,1		;FUNCTION
	X	QDV,1		;DEVICE (NCL)
	X	QSP,1		;SPARE
	X	QFW,1		;FIRST WORD (LINE#, IND MSG LENGTH)
	X	ADR,1		;ADDRESS OF REAL DATA
	X	USR,1		;USER SUPPLIED DATA
	X	EFN,1		;*OBS* EVENT FLAG NUMBER (OR SOMETHING LIKE THAT)
;ROUTINE CALLED AT STARTUP TO INITIALIZE THE DTE SOFTWARE INTERFACE
;(THE HARDWARE NEEDS NO INITIALIZATION). IT WAITS FOR THE -10 TO EXIT
;PRIMARY PROTOCOL BECAUSE THERE IS NO PRESENT MECHANISM FOR RESTARTING
;THE QUEUED PROTOCOL. IT MUST BE RESTARTED BECAUSE OTHERWISE WE WOULD
;NOT KNOW WHAT STATE WE WERE IN WHEN WE GOT RESTARTED AND THEREFORE
;CANNOT CONTINUE USING THE PRESENT INCARNATION. NOTE THAT THIS SOME
;UNPLEASANT SIDE EFFECTS - NORMALLY DTELDR RUNNING ON THE -10 WILL
;BE CALLED WHEN THE KEEP ALIVE TIMER EXPIRES AND WILL RELOAD THE-11,
;WHEN THERE REALLY IS NO NEED TO SINCE ALL THE -11 WANTED TO DO WAS
;RESTART. (THIS WILL BE A PROBLEM MAINLY WITH POWER FAULTS THAT AFFECT
;ONLY THE 87S, PRESUMABLY A RARE OCCURANCE). SYSTEM PROGRAMMERS
;TRYING TO RESTART THE -11 BY TYPING BEGIN$G TO DDT-11 WILL FIND IT
;CAUSES THE -11 TO BE RELOADED IF DTELDR IS RUNNING IN AUTOMATIC
;MODE. THE ONLY WAY TO RESTART IT IS TO GET DTELDR IN MANUAL MODE, SAY
;BEGIN$G TO DDT11 THEN /TERMINATE:N AND /INITIALIZE:N TO DTELDR. THIS IS
;KNOWN IN THE BUSINESS AS PROGRESS.

DTEINI:	CLR	T10QUE		;PUNT OLD MESSAGES TO THE -10
	MOV	#TO10Q,TO10Q	;RESET QUEUED PROTOCOL LIST
	MOV	#TO10Q,TO10Q+2	;BOTH FORWARD AND BACKWARD LINKS
	CLR	ACKFLG		;WAIT FOR ACK BEFORE SENDING MSG
	CLR	TO11Q		;AND CLEAR MESSAGES SENT TO -11 BUT NOT READ
	MOV	.PRDTE,R0	;GET ADDRESS OF OUR DTE
	BEQ	20$		;IF NONE (?) DON'T BOTHER
	JSR	R0,TRPST	;INTERCEPT NON-EX DTE
		.WORD	30$	;(JUST RETURN IF NOT THERE)
10$:	CLR	TNAD1(R0)	;TRY TO EXAMINE START OF COMM REGION
	CLR	TNAD2(R0)	; TO SEE IF QUEUED PROTOCOL IS RUNNING
	JSR	PC,WFED		;WAIT FOR EXAMINE
	BCS	20$		;FAILED, MUST NOT BE IN PRIMARY PROTOCOL
	TST	DXWD2(R0)	;NON-ZERO IF WINDOW ENABLED
	BNE	10$		;PRIMARY PROTOCOL STILL RUNNING. WAIT LONGER
20$:	RTS	PC		;OUT OF PRIMARY PROTOCOL, SAFE TO RESTART NOW

30$:	CLR	.PRDTE		;NO DTE IF IT'S NOT THERE
				; TENSEC WILL SCAN FOR DTES APPEARING OUT OF
				; THE DARK SO IF IT COMES BACK (MAYBE WE
				; POWER FAIL RESTARTED BEFORE THE KL COULD
				; GET ITS DTES GOING AGAIN) WE WILL EVEN-
				; TUALLY NOTICE IT.
	RTS	PC		;RETURN IN ANY CASE


;ROUTINE TO REQUEST -10 TO RELOAD US. DONE SO BY SETTING THE RELOAD
;FLAG IN OUR STATUS WORD IN THE COMM AREA.

DTERLD:	TST	TENSCB		;ARE WE TALKING TO THE -10?
	BEQ	10$		;NO, FORGET IT
	BIS	#LOAD11,STSTT	;SET RELOAD REQUEST FLAG
	MOV	.PRADR,R3	;GET ADDRESS OF COMM AREA DATA BLOCK
	JSR	R0,TRPST	;IN CASE NO -10
		.WORD	10$	; (JUST IGNORE DTE)
	JSR	PC,STTOIP	;CHEAT A BIT. THIS ROUTINE ONLY SENDS STSTT TO -10
	MOV	#TO10DB,@.PRSTA	;TELL -10 ABOUT CATASTROPHE
10$:	RTS	PC		;-10 SHOULD RELOAD US IMMEDIATELY
.SBTTL		LOOPDT - LOOP LEVEL MESSAGE SHUFFLER

;THIS SUBROUTINE IS CALLED AT LOOP LEVEL TO DO ALL BACKGROUND TASKS:

;1) TELL NCL WHICH MESSAGES HAVE BEEN SENT TO THE -10 AND THEREFORE
;   MAY NEED TO BE TIMED.

;2) PROCESS TO-11 QPR MESSAGES. ACKS MEAN THE -10 IS READY TO RECIEVE
;   ANOTHER MESSAGE AND STRING DATA MESSAGES ARE TO-11 NCL MESSAGES
;   IN NEED OF POSSIBLE COMPRESSION BEFORE BEING PASSED TO NCLIN0.

LOOPDT:	TST	TENSCB		;PRIMARY PROTOCOL RUNNING?
	BEQ	99$		;NO, CAN'T ACCESS DTE20 RETURN QUICK
	JSR	PC,INTLPS	;CALL "INTERRUPT" CODE

20$:	MOV	TO11Q,R0	;SEE IF ANYTHING SENT FROM -10
	BEQ	99$		;NOTHING ON LIST
	MOV	CN.MLK(R0),TO11Q ;DELINK MSG
	MOVB	TE.QFN(R0),R1	;GET MESSAGE TYPE
	CMP	R1,#BC.SAK	;ACKNOWLEDGE?
	BEQ	40$		;THAT MEANS WE CAN SEND ANOTHER MESSAGE
	CMP	R1,#BC.STR	;STRING DATA?
	BEQ	35$		;YEP, SEND IT TO NCL
	TWIDDLE	R1		;SHOULDN'T GET HERE. NOTE THE OCCURANCE
	JSR	PC,FRECKS	;AND FORGET THE MESSAGE
	BR	20$		;LOOP ON OTHER MESSAGES
;HERE WHEN WE HAVE A DATA MESSAGE TO COMPRESS

35$:	MOV	TE.CMP(R0),R3	;GET ADDRESS WHERE USER DATA STARTS
	MOVB	TE.LIN(R0),R4	;GET LINE NUMBER (FLAGS) FOR THIS MESSAGE
	BIC	#^C6,R4		;ISOLATE THE COMPRESSION CODE
	BEQ	37$		;NOTHING SPECIAL IF NO COMPRESSION
	CLR	R2		;NOTHING WRITTEN YET
	MOV	R0,R1		;CALC LENGTH OF PROTOCOL HEADER AND DATA
	ADD	#CN.NCT,R1	;R1_ADDRESS OF START OF NCL
	SUB	R3,R1		;R1_NEGATIVE PROTOCOL LENGTH (NCL+DAP HEADER)
	ADD	CN.LEN(R0),R1	;R1_DATA LENGTH (USED IN LOOP BELOW)
	SUB	R1,CN.LEN(R0)	;CN.LEN_POSITIVE HEADER LENGTH (FIXED UP LATER)
	MOV	R0,-(P)		;SAVE POINTER TO 1ST CHUNK
	MOV	R3,R0		;SETUP GETTER ADDRESS
	JSR	PC,@CMPDSP-2(R4) ;CALL APPROPRIATE COMPRESSER
	MOV	(SP)+,R0	;GET MESSAGE ADDRESS BACK
	ADD	R2,CN.LEN(R0)	;ADD LENGTH OF COMPRESSED DATA TO HEADER FOR TOTAL
37$:	MOV	TENSCB,SNA	;THIS MESSAGE CAME FROM OUR TEN
	JSR	PC,NCLIN0	;TELL NCL WE HAVE A MESSAGE FOR IT
	BR	20$		;LOOP FOR ANY MORE MESSAGES


;HERE WHEN WE GET A QPR ACK - SEND A MESSAGE TO -10

40$:	JSR	PC,FRECKS	;FREE THE ACK MESSAGE
	TST	T10QUE		;CAN WE SEND A MESSAGE RIGHT NOW?
	BNE	50$		;YES, DO SO
	INC	ACKFLG		;NOPE, REMEMBER WE HAVE AN OUTSTANDING REQUEST
	BR	20$		;AND SEE WHAT ELSE HAS TO BE DONE

50$:	MOV	T10QUE,R0	;GET MESSAGE ADDRESS
	MOV	CN.MLK(R0),T10QUE ;DELINK THIS MESSAGE
	JSR	PC,DTEQUE	;SEND TO -10
	BCC	20$		;DO MORE
	MOV	R0,T10QUE	;DTEQUE FAILED (DTE KROAKED OFF)
	BR	20$		;DO SOME MORE

99$:	RTS	PC		;ALL FINISHED, RETURN
.SBTTL		TO-11 DATA COMPRESSION ROUTINES

;THIS CODE LARGELY STOLEN FROM DNDL10 AND BEAT UPON FOR OUR PURPOSES
;WHICH ARE DIFFERENT ENOUGH TO WARRANT NOT TURNING IT INTO COMMON
;CODE. CMPDSP IS CALLED WITH R0-R3 SETUP:

;R0	ADDRESS OF NEXT DATA BYTE TO READ
;R1	# OF CHARACTERS LEFT TO COMPRESS
;R2	0 (SEE RETURNED INFO)
;R3	LIKE R0, ONLY FOR WRITING. IT CHASES R0 BUT NEVER PASSES IT

;RETURNS:
;R2	LENGTH (BYTES) OF COMPRESSED DATA.

CMPDSP:	CMPRSL			;(1) LPT COMPRESSION
.IIF NE FT.ANF,	COPBIN		;(2) 36 BIT MODE
.IIF EQ FT.ANF,	DTERTS		;(2) BUT ONLY IF INTELLIGENCE REQUESTED
	DTERTS			;(3) UNDEFINED - DO NOTHING

;ROUTINE TO PACK DATA FOR LPT. THE GENERAL SCHEME IS TO PACK THE DATA IN
;PLACE WHICH IS POSSIBLE SINCE THE COMPRESSION ALGORITHM GUARANTEES
;THAT NO MESSAGE WILL EVER BE LARGER THAN THE UNCOMPRESSED FORM.
;REGISTER USAGE

;R4	# OF OCCURANCES FOR THE PRESENT CHARACTER WE'RE COMPRESSING
;R5	THE CHARACTER WE'RE TRYING TO COMPRESS

;FORMAT OF COMPRESSED DATA:
;SINGLE OCCURANCE OF A CHARACTER		200!CHAR
;MULTIPLE SPACES (2 TO 77)			100!COUNT
;MULTIPLE ANYTHING ELSE (2 TO 37)		40!COUNT,200!CHAR

CMPRSL:	MOV	R3,-(P)		;SAVE POINTER TO DATA
	CLR	R4		;NOTHING COMPRESSED YET
	;..
	;..
30$:	JSR	PC,AVCKR0	;ENSURE WE'RE STILL POINTING TO DATA
	TST	R4		;ANY COMPRESSED YET ?
	BEQ	35$		;IF NOT THIS IS FIRST
	CMPB	@R0,R5		;IS THIS CHAR SAME AS LAST ?
	BEQ	35$		;YES SO JUST COUNT IT
	JSR	PC,PAKCHR	;PUT OLD CHAR INTO MSG
35$:	MOVB	(R0)+,R5	;REMEMBER WHAT WE ARE COMPRRESSING
	INC	R4		;COUNT IT
	CMP	R4,#37		;CHECK FOR TOO MANY
	BMI	39$
	CMP	R5,#40		;IS CHAR A BLANK ?
	BNE	38$		;IF NOT THIS IS IT
	CMP	R4,#77		;THIS IS LIMIT FOR BLANKS
	BMI	39$
38$:	JSR	PC,PAKCHR	;MUST GO INTO MESSAGE NOW
39$:	SOB	R1,30$		;LOOP FOR REST OF DATA
	TST	R4		;ANY DATA COMPRESSED ?
	BEQ	26$
	JSR	PC,PAKCHR	;PUT INTO MESSAGE
26$:	MOV	(P)+,R3		;GET POINTER TO DATA OFF STACK
	MOV	R2,R4		;WE HAVE TO RETURN R2
	INC	R4		;COUNT FOR DAP MESSAGE TYPE BYTE FOR TOTAL
	SUB	#2,R3		;POINT TO COUNT
27$:	TSTB	-(R3)		;GET MESSAGE TYPE
	BMI	27$		;LOOK FOR DLA
	INC	R3		;BACK TO COUNT FIELD
	TSTB	@R3		;CHECK FOR EXTENSIBLE
	BPL	29$
	MOV	R4,R5		;COPY MESSAGE LENGTH
	BIS	#200,R5		;PUT EXTENSIBLE BIT ON
	MOVB	R5,(R3)+	;PUT INTO MESSAGE
	ASL	R4
	SWAB	R4
29$:	MOVB	R4,@R3		;PUT LENGTH INTO MESSAGE
DTERTS:	RTS	PC		;NOW AT LAST PASS OFF MESSAGE
;HERE TO PUT COMPRESSED LPT CHAR INTO MESSAGE
PAKCHR:	CMP	R4,#1		;SINGLE OCCURANCE ?
	BEQ	46$		;IF SO JUST PUT IN AS IS
	CMP	#40,R5		;IS CHARACTER A BLANK ?
	BNE	44$		;NO
	BIS	#100,R4		;FLAG THIS IS BLANK COUNT
	JSR	PC,AVCKR3	;ENSURE WE POINT TO DATA
	MOVB	R4,(R3)+	;PUT INTO THE MESSAGE
	BR	47$		;INC LENGTH AND DONE

44$:	BIS	#40,R4		;FLAG THIS IS REPITION COUNT
	JSR	PC,AVCKR3
	MOVB	R4,(R3)+	;PUT COUNT INTO MESSAGE
	INC	R2		;COUNT CHAR
46$:	BIS	#200,R5		;FLAG THIS IS CHAR
	JSR	PC,AVCKR3
	MOVB	R5,(R3)+	;PUT INTO MSG
47$:	INC	R2		;COUNT CHAR INTO MESSAGE
48$:	CLR	R4		;CLEAR COMPRESSION COUNT
	RTS	PC
;ROUTINE TO PACK BINARY DATA (36 BITS) FROM THE -10. THE UNCOMPRESSED
;FORM IS 12 BIT BYTES, 1 PER -11 WORD (3 MAKE AN ENTIRE -10 WORD).
;THIS ROUTINE TAKES PAIRS OF THESE AND PACKS THEM INTO 3 BYTES ON THE
;-11 WITH NO BYTES WASTED. THE RESULT IS A BYTE STREAM OF THE DATA
;FROM THE -10 WITH ALL THE BITS IN ORDER.

.IF NE FT.ANF
COPBIN:	ASR	R1		;CONVERT # OF BYTES TO # OF WORDS
	INC	R0		;MAKE SURE GETTER STARTS ON WORD BOUNDARY
	BIC	#1,R0		;SINCE THAT'S WHERE THE WORD DATA WENT
32$:	JSR	PC,AVCKR0	;MAKE SURE WE STILL POINT TO DATA
	MOV	(R0)+,R5	;GET NEXT 12 BITS
	ASL	R5		;WANT TO GET HIGH ORDER 8 BITS
	ASL	R5
	ASL	R5
	ASL	R5
	JSR	PC,40$		;PUT HIGH ORDER BITS INTO MSG
	BIC	#^C170000,R5	;STRIP EXTRA BITS
	DEC	R1		;COUNT LAST 12-BITS OUT OF 10
	BEQ	40$		;IF LAST WORD, STORE LEFTOVER BITS
	JSR	PC,AVCKR0	;ENSURE WE POINT TO DATA
	ADD	(R0)+,R5	;GET NEXT 12 BITS
	JSR	PC,40$		;PUT NEXT BYTE INTO MSG
	JSR	PC,40$		;PUT NEXT BYTE INTO MSG
	DEC	R1		;COUNT LAST 12 BITS OUT OF 10
	BNE	32$
	RTS	PC

;HERE TO PUT NEXT BYTE INTO MSG
40$:	SWAB	R5
	JSR	PC,AVCKR3	;POINT TO DATA
	MOVB	R5,(R3)+	;PUT NEXT BYTE INTO MSG
	INC	R2		;THAT'S ANOTHER BYTE IN FINAL MESSAGE
42$:	RTS	PC		;RETURN
.ENDC ; .IF NE FT.ANF
.SBTTL		TENSEC - CLOCK LEVEL ROUTINE

;THE CLOCK SUPPORT FOR THE DTE INCLUDES DETERMINATION OF WHETHER OR
;NOT THE -10 IS UP. UP IS WHEN BOTH THE HEADER WORD IS NONZERO
;AND VALID EXAMINE IS SET ($DTEON DOES THE VALID EXAMINE CHECK). THE
;-10 IS DECLARED DOWN ONLY WHEN THE HEADER IS NO LONGER ACCESSIBLE (0),
;WHICH ALLOWS THE -10 TO ENTER SECONDARY PROTOCOL (E.G. EDDT) WITHOUT
;LOOSING ALL THE CONNECTIONS. WARNING:
;THIS REQUIRES THAT THIS 11 NOT BE PROCESSOR 0. SINCE TOPS-10 AND
;TOPS-20 BOTH CALL THEMSELVES PROCESSOR 0, THIS SHOULD NOT BE A PROBLEM.)
;THE SBF.IU BIT IS USED TO RECORD THE STATE OF THE -10 (IN FACT, THIS
;IS EXACTLY THE SAME WAY ANY OTHER NODE'S SBF.IU IS USED.) WHEN THE -10
;GOES OFFLINE, WE BREAK ANY OPEN CONNECTIONS AND TELL THE REST
;OF THE NETWORK IT HAPPENED. WHEN IT COMES ONLINE, WE SET UP THE
;QUEUED PROTOCOL DATA BASE AND SEND A NODEID AS THE FIRST MESSAGE.
;WHENEVER THE -10 IS FOUND TO BE UP, WE UPDATE THE KEEP ALIVE COUNTER.
;WHILE THIS MAY NOT BE THE BEST LOCATION TO DO IT, IT WILL CATCH PROBLEMS
;LIKE LOOPS, CONTINUAL INTERRUPTS, AND A KW11 THAT HAS LOST ITS
;INTERRUPT ENABLE BIT. WE ALSO MAKE SURE THE -10 SAW LAST DOORBELL.

TENSEC:	MOV	.PRDTE,R0	;GET START ADDRESS OF OUR DTE20
	BEQ	TENSE5		;NO DTE, MUST GO SEARCHING FOR ONE
	JSR	R0,TRPST	;IN CASE NO DTE (I.E., IT WENT AWAY)
		.WORD	TENDWD	; (NOTE -10 DOWN, REQUEUE ANY MESSAGES)
	CLR	TNAD1(R0)	;LOOK AT OUR HEADER WORD WHICH IS AT
	CLR	TNAD2(R0)	; OFFSET 0. IT WILL BE NON ZERO IF THE
	JSR	PC,WFED		; 10 IS TALKING TO US
	BCS	10$		;IF WE CAN'T DO IT, -10 IS DOWN
	TST	DXWD2(R0)	;DID WE GET OUR PROCESSOR #?
	BNE	TENUP		;YEP, MAKE SURE WE'RE TALKING TO -10
10$:	JSR	PC,TRPCL	;NO, TEN IS DOWN, CLEAR TRAP INTERCEPT
	BR	TENDWN		;AND FLAG NO -10
;HERE WHEN WE HAVE NO KNOWN DTE-20 (BUT WERE ASSEMBLED FOR ONE). ASSUME
;THE KL WAS POWERED OFF, OR MAYBE EVEN THAT WE WE BOOTED FROM A ROM AND
;HAVE NEVER SEEN A DTE-20 YET. WE MUST SCAN FOR ONE WHICH EXISTS
;(AND WHICH IS NOT NECESSARILY THE DTE WHICH BOOTED US).

TENSE5:	MOV	#TE.NNN,R0	;NUMBER OF DTES TO TRY
	MOV	#TE.BAS,R1	;BASE ADDRESS OF FIRST ONE TO TRY

;LOOP, SNIFFING AT THE DTE TO SEE IF IT IS THERE

10$:	JSR	R0,TRPST	;SET UP NXM INTERCEPT
		.WORD	20$	; (JUST IGNORE IT)
	TST	(R1)		;HELLO - ANYONE THERE?
	BR	100$		;YES!!! WE HAVE A DTE!!!
20$:	ADD	#TE.BNX,R1	;NO, BUMP POINTER TO NEXT POSSIBLE DTE
	SOB	R0,10$		;AND TRY AGAIN
	RTS	PC		;NO DTE-20 ANYWHERE

;WE NOW HAVE A DTE-20 (WHERE BEFORE WE DIDN'T)

100$:	TWIDDLE			;COUNT DTE [RE]INCARNATIONS
	MOV	R1,.PRDTE	;SET WONDERFUL NEW DTE-20 BASE ADDRESS
	ADD	#TE.STW,R1	;POINT TO DTE-20 STATUS REGISTER
	MOV	R1,.PRSTA	;AND SAVE ITS ADDRESS TOO
	JSR	PC,TRPCL	;CLEAR OUT THE TENSE5 TRAP
	JSR	R0,TRPST	;AND SET THE USUAL TENSEC TRAP
		.WORD	TENDWD	; (ZAP THE DTE AND MARK THE -10 DOWN)
	BR	TENUP		;NOW GO HANDLE THE -10'S COMING UP
;HERE ON NXM FROM DTE (WHICH PRESUMABLY IS NOW POWERED OFF OR THE LIKE)

TENDWD:	TWIDDLE			;COUNT DTE DISAPPEARING ACTS
	CLR	.PRDTE		;NOTE NO MORE DTE (TENSEC MUST SCAN FOR
				; ONE APPEARING OUT OF THE MISTS)
	MOV	#TE.BAS-1,.PRSTA  ;CATCH ANYONE LOOKING AT STATUS SANS DTE
				; (THIS WILL CATCH 'EM EVEN IF DTE COMES
				;  BACK BEFORE WE OFFICIALLY NOTICE IT)
TENDWN:	MOV	TENSCB,SB	;THE TEN IS DOWN, DID WE KNOW THAT?
	BEQ	99$		;YES, NOTHING MORE TO DO.
	SAVE	<SB>		;SAVE POINTER WHILE WE FIX UP THE QUEUES
	CLR	ACKFLG		;PREVENT NEW MESSAGES FROM ENTERING TO10Q
				; (THEY'LL GO ON T10QUE AND TIMEOUT)
	CLR	TENSCB		;SAY THAT WE KNOW THE DTE IS DOWN
;	CLR	SB.LBA(SB)	;CLEAR ROUTING (ROUTE REALLY DOES IT)
	BIS	#SBF.NK,(SB)	;FORCE A NAK
	BIT	#SF.HID,(SB)	;DID I KNOW WHO HE WAS?
	BNE	10$		;IF SO, MAYBE THERE'S ANOTHER PATH TO HIM
	CLR	(SB)		;IF NOT, THEN FREE UP USLESS SCB

10$:	MOV	T10QUE,R0	;NOW QUEUE ALL UNSENT MSGS ON MSGRSQ
	BEQ	20$		;  THEY WILL BE RE-ROUTED NEXT JIFFY
	MOV	CN.MLK(R0),T10QUE ;  IFF THERE IS A PATH TO THE NODE
	JSR	PC,MSGREQ	;REQUEUE THE MESSAGE
	BR	10$		;LOOP UNTIL ALL MSGS REQUEUED


20$:	MOV	TO10Q,R4	;DISCARD MESSAGES ALREADY QUEUED
	CMP	R4,#TO10Q	;EMPTY RING?
	BEQ	30$		;YES, ALL DONE
	JSR	PC,T10DON	;PRETEND -10 GOT IT
	JSR	PC,..NDEL	;REMOVE CONTROL BLOCK FROM TO10Q
	MOV	R4,R0		;AND DEALLOCATE IT
	JSR	PC,FRECNK
	BR	20$		;DO REST

30$:	RESTORE	<SB>		;GET THE SCB POINTER BACK AGAIN
	JSR	PC,ROUTE	;REMOVE UNREACHABLE NODES
	JSR	PC,SNDNGH	;TELL ANYONE WHO MIGHT BE INTERESTED
99$:	RTS	PC		;DON'T NEED TO CALL TIMDTE SINCE NO MSGS
				;  ARE QUEUED ANY MORE
;HERE ONCE A SECOND IF WE THINK THE DTE IS RUNNING
;STILL IN TRPST (TO TENDWD) FROM TENSEC (OR TENSE5)

TENUP:	MOV	TENSCB,SB	;DID WE KNOW TEN WAS UP? (GET SCB IF WE DID)
	BNE	20$		;YES, JUST UPDATE KEEP ALIVE
	JSR	PC,$DTEON	;NO, INITIALIZE QUEUED PROTOCOL DATA BASE
	BCS	30$		;VALID EXAMINE IS STILL OFF, LEAVE -10 DOWN
	JSR	PC,MAKSCB	;GET AN SCB FOR THE TEN
	BCS	30$		;NO SCB'S?
	MOV	SB,TENSCB	;MARK THE TEN AS UP, AND THIS SCB AS THE 10'S
	MOV	SB,SB.LBA(SB)	;SET UP IT'S INCESTOUS ROUTING TABLE
	MOV	#SBF.IU,@SB	;FLAG THAT THE DTE IS UP (WELL SORT OF...)
	CLR	CURMSG		;NOT BUILDING A MESSAGE

;***	DNDL10 TESTS DL10 HERE - CAN WE TEST DTE?

	JSR	PC,NCLRS9	;SEND A NODEID TO -10 TO START THINGS UP
20$:	INCB	KPAL1		;ALL THE KEEP ALIVE COUNTER HAS TO DO IS CHANGE
	MOV	.PRDTE,R0	;SO THE -10 WILL KNOW WE'RE ALRIGHT
	MOV	KPAL1,DXWD3(R0)	;DON'T BOTHER WITH HIGH BITS OF WORD
	MOV	#DEP,TNAD1(R0)	; JUST TRANSFER IT TO THE -10
	MOV	#PSWW1,TNAD2(R0) ;START TRANSFER
	TST	DBLCNT		;HAS -10 RESPONDED TO LAST DOORBELL?
	BEQ	25$		;YEP
	DEC	DBLCNT		;NOT YET, COUNT DOWN TIMER
	BNE	25$		;STILL COUNTING
	JSR	PC,RINGDB	;TIMED OUT, TRY AGAIN
	TWIDDLE			;THAT SHOULDN'T HAVE HAPPENED
25$:	JSR	PC,WFED		;WAIT FOR IT TO COMPLETE
30$:

TIMDTE:	MOV	#T10QUE-CN.MLK,R0 ;PREVENT OLD MESSAGES FROM BUILDING UP
	JSR	PC,TIMQUE	;  IN THE QUEUE TO THE -10
	.WORD	10$		;CALL THIS FOR DISCARD OLD MESSAGES
 	RTS	PC

10$:	TWIDDLE			;COUNT THE NUMBER MESSAGES NOT SENT
	JSR	PC,MSGREQ	;REQUEUE THE MESSAGE NEXT TICK
	RTS	PC		;ALL DONE, JIFFY CODE WILL RESEND
.SBTTL		MEMORY ALLOCATION

;MEMORY ALLOCATION. RSX ALLOWS FOR ALLOCATING A VARIABLE AMOUNT OF
;MEMORY PER CALL, WHEREAS THE DN87 ONLY ALLOCATES A FIXED "CHUNK"
;PER CALL. THE ROUTINE COMPROMISES AND ALLOCATES AN ENTIRE CHUNK
;NO MATTER HOW MUCH WAS REQUESTED AS LONG AS IT IS LESS THAN
;THE USABLE SPACE IN THE CHUNK.

;SUBROUTINE TO REQUEST A BLOCK OF MEMORY:
;CALL:
;R1/	LENGTH OF MEMORY REQUIRED
;RETURN:
;R0/	ADDRESS OF MEMORY
;PS/	C SET ON ERROR
;ALL OTHER REGISTERS UNMODIFIED

..ALCB:	ASSERT	R1 LE #CNKSIZ	;CRASH IF REQUEST IS TOO BIG
	JSR	PC,ERSGET	;GET A CHUNK FROM FREELIST, GOING FOR BROKE
	BEQ	10$		;NONE LEFT, RETURN ERROR
	RTS	PC		;RETURN CARRY CLEAR

10$:	TRAP			;NO ROOM, DIE



;ROUTINE TO DEALLOCATE MEMORY ALLOCATED BY ..ALCB. SINCE WE
;ALLOCATED A SINGLE BLOCK, THE STANDARD CHUNK FREER WILL DO JUST
;FINE.

..DECB	=FRECNK			;EASY DOES IT
.SBTTL		QUEUED PROTOCOL INTERFACE
;ROUTINE TO SEND A MESSAGE TO QPRDTE TO SEND TO THE -10. SINCE
;THE PROTOCOL ROUTINES EXPECT THAT THE FIRST WORD OF THE DATA
;INCLUDE THE SIZE AND THE LINE NUMBER, WE HAVE TO USE
;WHAT MAY HAVE BEEN A DDCMP BCC WORD. NOWHERE ELSE IN DN87 IS
;THAT WORD USED, SO WE ARE SAFE IF USING IT.
;CALL:
;R0/	CHUNK ADDRESS
;RETURNS:
;R3,R4,R5 PRESERVED

.IIF EQ NTLINE,DDQDAT:		;NEED FOR ASYNC ONLY FRONT ENDS
DLQDAT:	ASSERT	NE TENSCB	;WE SHOULDN'T ROUTE HERE IF THE DTE IS DEAD
	TST	ACKFLG		;DID -10 REQUEST A MESSAGE?
	BEQ	10$		;NO, PUT IT ON QUEUE
	JSR	PC,DTEQUE	;YES, SEND IT OUT NOW
	BCC	99$		;IF SUCCEEDED JUST RETURN
				; THE DTE KROAKED OFF WHILST WE WERE TRYING
				; TO USE IT, QUEUE UP THE MESSAGE AND
				; LET TENSEC RECOVER IT
10$:	MOV	#15,CN.TIM(R0)	;GIVE HIM ONLY 15 SECONDS ON THE QUEUE BEFORE
				;  HE TIMES OUT (SHORT, BUT DTE IS VERY FAST)
	MOV	#T10QUE-CN.MLK,R1  ;PUT MESSAGE ON END OF QUEUE
20$:	MOV	R1,R2		;SAVE POSSIBLE LAST CHUNK
	MOV	CN.MLK(R1),R1	;GET NEXT CHUNK
	BNE	20$		;THAT WASN'T LAST, TRY THIS ONE
	MOV	R0,CN.MLK(R2)	;EXTEND QUEUE
99$:	RTS	PC
;THIS ROUTINE TAKES A MULTI CHUNK MESSAGE AND SENDS IT TO THE -10.
;SINCE QPR AND THE DTE DON'T SUPPORT GATHER READ, THE DATA IN EACH
;CHUNK HAS TO BE SENT AS A SEPARATE MESSAGE AND D8SINT IN THE -10
;HAS TO PACK THEM ALL INTO A SINGLE NCL MESSAGE.
;CALL:
;R0	ADDRESS OF FIRST CHUNK OF MESSAGE

DTEQUE:	CLR	ACKFLG		;CAN'T SEND NEXT MESSAGE YET
	MOV	R0,.STUSR	;SAVE REGISTERS WE PLAN ON MANGLING
	JSR	R0,TRPST	;IN CASE THE DTE DOES A DISAPPEARING ACT
		.WORD	100$	; (WE WILL FLAG AN ERROR)
	TST	@.PRSTA		;HELLO? ANYONE THERE?
				; IF -10 POWERED DOWN SUDDENLY THIS WILL TRAP
				; BEFORE WE START MUNGING ON MEMORY/QUEUES/ETC.
	MOV	R3,-(SP)	; .STUSR REFFED BY ..STIN
	MOV	SB,-(SP)
	MOV	#100000+BC.STR,R1 ;GET STRING DATA MSG TYPE (PLUS INDIRECT BIT)
	MOV	#D.CNCL,R3	;AND QPR DEVICE TYPE (NCL)
	MOV	CN.LEN(R0),-(SP) ;THIS WILL BE # BYTES LEFT TO SEND
	MOV	R0,-(SP)	;THIS WILL BE CHUNK ADDRESS CURRENTLY BEING SENT
	MOV	#CNKLN1,-(SP)	;FIRST CHUNK HAS UP TO THIS MUCH DATA
	MOV	#CN.NCT-2,-(SP)	;AND THE ACTUAL DATA STARTS HERE
10$:	ADD	(SP)+,R0	;POINT TO FIRST WORD LOCATION
	MOV	@R0,SB		;SAVE POSSIBLE LINK WORD (IF 2ND CHUNK)
	CMP	4(SP),@SP	;IS THERE MORE DATA TO SEND THAN IN CHUNK?
	BLE	20$		;NO, SEND LAST PART AND EXIT
	SUB	@SP,4(SP)	;THIS MUCH LESS FOR NEXT FRAGMENT
	MOV	(SP)+,@R0	;AND TRANSFER THAT MUCH
	BIS	#FW.MOR,@R0	;TELL -10 THERE WILL BE MORE
	JSR	PC,..STIN	;QUEUE UP THE MESSAGE
	MOV	SB,@R0		;RESTORE POSSIBLE LINK WORD
	MOV	@(SP)+,R0	;GET ADDRESS OF NEXT CHUNK IN MESSAGE
	CHK	NE		;THERE'D BETTER BE ONE....
	MOV	R0,-(SP)	;MAKE IT CURRENT
	MOV	#CNKLN2,-(SP)	;NOW THERE'S THIS MUCH DATA/CHUNK
	MOV	#CN.DT2-2,-(SP)	;SO FIRST WORD STARTS HERE
	BR	10$		;SEND MORE

20$:	CMP	(SP)+,(SP)+	;RID OURSELVES OF TRASH
	MOV	(SP)+,@R0	;NUMBER OF BYTES LEFT TO TRANSFER
	JSR	PC,..STIN	;SEND LAST FRAGMENT
	MOV	SB,@R0		;FIX POSSIBLE LINK WORD
	MOV	(SP)+,SB	;RESTORE ALL ACS USED
	MOV	(SP)+,R3
	CLC			;FLAG SUCCESSFUL
98$:	MOV	.STUSR,R0	;RESTORE R0 (MESSAGE ADDRESS)
	RTS	PC		;DONE

100$:	SEC			;DTE NXM'ED US, FLAG ERROR
	BR	98$		;AND RETURN NOW
;ROUTINE CALLED WHEN EACH CHUNK OF A TO-10 NCL MESSAGE REACHES THE -10.
;ONLY WHEN THE LAST CHUNK HAS BEEN SENT WILL THE MESSAGE BE 
;  GIVEN TO NCLODN.
;CALL:
;R4	ADDRESS OF TO-10 CONTROL BLOCK

T10DON:	BIT	#FW.MOR,TT.QFW(R4) ;ANYTHING MORE IN THIS NCL MESSAGE?
	BNE	99$		;YES, CAN'T GIVE IT BACK TO NCL YET
	MOV	R0,-(SP)	;SAVE ACS NEEDED BY TOTNDN
	MOV	R4,-(SP)
	MOV	TT.USR(R4),R0	;GET ADDRESS OF INITIAL CHUNK
	TST	TENSCB		;IS THE DTE STILL UP, OR ARE WE CLEARING UNSENT
	BEQ	10$		;  MSGS.  IF SO, THEN REQUE THE MSG
	JSR	PC,NCLODN	;HAVE NCL GET RID OF IT
	BR	20$		;CLEAN STACK AND EXIT
10$:	JSR	PC,MSGREQ	;REQUEUE THE MESSAGE NEXT TICK
20$:	MOV	(SP)+,R4
	MOV	(SP)+,R0
99$:	RTS	PC


;ROUTINE CALLED WHEN QPR DOORBELL FINDS IT HAS DATA FOR NCL.
;THIS ALLOCS SPACE ALA DN87 AND SETS UP ITS INTERNAL DATA BASE.
;
;CALL:
;R0/	# OF BYTES IN MESSAGE
;RETURN:
;R0/	# OF BYTES TO XFER
;R1/	ADDRESS OF WHERE TO PUT DATA

T11DBL:	MOV	R0,-(SP)	;SAVE LENGTH OF QPR MESSAGE
	MOV	CURMSG,R5	;ARE WE TRYING TO ADD TO ONE?
	BNE	10$		;YEP, WE HAVE ALREADY INITIALIZED STUFF
	JSR	PC,ERSGET	;GET FIRST CHUNK OF MESSAGE
	MOV	R0,R5		;SAVE IT FOR FUTURE REFERENCING
	MOV	R5,CURMSG	;AND REMEMBER OVER SUBROUTINE CALLS
	CLR	(R0)+		;TE.LNK SAY NOT LINKED TO ANYONE YET (ERSGET SHOULD HAVE CLEARED IT)
	MOV	@SP,(R0)+	;TE.QPR SAVE LENGTH REMAINING IN FRAGMENT
	MOV	(SP)+,(R0)+	;TE.LEN START COUNT LENGTH OF NCL MESSAGE
	MOV	TO11FW,(R0)+	;TE.FFW REMEMBER LINE # (STATUS) FOR THIS FRAGMENT
	MOV	#CNKLN1,(R0)+	;TE.CNK # BYTES LEFT IN PRESENT CHUNK
	MOV	#TO11HD,R1	;COPY MESSAGE HEADER INTO CHUNK
	MOV	(R1)+,(R0)+	;TE.QHD
	MOV	(R1)+,(R0)+	;TE.QFN
	MOV	(R1)+,(R0)+	;TE.QDV
	MOV	(R1)+,@R0	;TE.QSP
	ADD	#CN.NCT-TE.QSP,R0 ;POINT TO FIRST DATA BYTE
	MOV	R0,TE.ADR(R5)	;REMEMBER NEXT BYTE TO FILL
	BR	CONT11		;APPEND TO THIS CHUNK

10$:	ADD	@SP,TE.LEN(R5)	;THE MESSAGE IS THIS MUCH LONGER
	MOV	(SP)+,TE.QPR(R5) ;REMEMBER HOW MUCH WE HAVE TO TRANSFER
	MOV	TO11FW,TE.FFW(R5) ;REMEMBER FLAGS (LINE #) FOR THIS FRAGMENT
	MOV	TE.ADR(R5),TE.CMP(R5) ;HACK: WE KNOW THIS MESSAGE IS LAST AND IS USER DATA
	BIT	#TOBM,STATI+2	;WILL THIS BE WORD MODE? (BINARY DATA)
	BEQ	EXTMSG		;NO, THAT'S A RELIEF
	INC	TE.ADR(R5)	;THIS WILL ROUND UP TO NEXT WORD ADDRESS
	BIC	#1,TE.ADR(R5)
	BIC	#1,TE.CNK(R5)	;AND THIS WILL ROUND DOWN TO # OF USABLE BYTES
	BR	EXTMSG		;TACK THIS ON AT END OF LAST ONE
;ROUTINE CALLED FROM TO-11 DONE INTERRUPT ROUTINE TO ADD NEW CHUNK
;OR PROCESS END OF FRAGMENT
;
;CALL - NO REGISTERS NEEDED
;RETURN:
;R0/	LENGTH OF NEXT FRAGMENT TO TRANSFER
;R1/	ADDRESS TO STORE DATA
;PS/	Z BIT SET IF EVERYTHING IN

T11DON:	MOV	CURMSG,R5	;GET ADDRESS FOR FIRST CHUNK OF THIS MESSAGE
	ASSERT	NE		;T11DBL GUARANTEES IT TO BE SETUP
	TST	TE.QPR(R5)	;ANYTHING LEFT IN QPR MESSAGE?
	BNE	EXTMSG		;YES, MUST BE AT END OF CHUNK, ADD A NEW ONE
	BIT	#FW.MOR,TE.FFW(R5) ;IS THERE AT LEAST ANOTHER FRAGMENT?
	BNE	20$		;YES, DON'T QUEUE WHAT WE HAVE
	MOV	#TO11Q-CN.MLK,R0 ;PUT COMPLETED MESSAGE AT END OF LIST
10$:	MOV	R0,R1		;SAVE POSSIBLE LIST END
	MOV	CN.MLK(R0),R0	;GET NEXT ITEM
	BNE	10$		;THERE WAS ONE, SEE IF ANOTHER
	MOV	R5,CN.MLK(R1)	;PUT ON END OF LIST
	CLR	CN.MLK(R5)	;MARK END OF LIST
	CLR	CURMSG		;NO LONGER BUILDING AN NCL MESSAGE
20$:	CLR	R0		;TO TELL QPR TO STOP TRANSFER
	RTS	PC		;BACK TO IT, Z BIT SET


EXTMSG:	TST	TE.CNK(R5)	;ANY SPACE LEFT IN THIS CHUNK?
	BNE	CONT11		;YES, CONTINUE WITH IT
	JSR	PC,ERSGET	;GET ANOTHER CHUNK
	MOV	TE.ADR(R5),R1	;SINCE WE'RE AT END, THIS IS START OF
	MOV	R0,-CNKSIZ(R1)	; NEXT CHUNK, CORRECT TO EXTEND LIST
	MOV	#CNKLN2,TE.CNK(R5) ;WE HAVE THIS MANY BYTES TO FILL IN THIS CHUNK
	ADD	#CN.DT2,R0	;MAKE ADDRESS TO START AT
	MOV	R0,TE.ADR(R5)	;REMEMBER FOR AWHILE
CONT11:	MOV	TE.CNK(R5),R0	;CALC NUMBER OF BYTES WE CAN TRANSFER NOW
	CMP	R0,TE.QPR(R5)	;WHICH IS MIN OF SPACE IN CHUNK AND QPR MESSAGE
	BLE	10$		;SPACE LEFT IN CHUNK IS SMALLER
	MOV	TE.QPR(R5),R0	;SPACE IN QPR MESSAGE IS SMALLER
10$:	MOV	TE.ADR(R5),R1	;WHERE TO PUT DATA
	SUB	R0,TE.QPR(R5)	;THIS MUCH LESS IN QPR MESSAGE
	SUB	R0,TE.CNK(R5)	;AND CHUNK
	ADD	R0,TE.ADR(R5)	;NEXT TRANSFER MAY START AT THIS ADDRESS
	RTS	PC		;BACK TO QPR
.SBTTL		DTE20 REGISTER DEFINITIONS

;	THESE LABELS ARE THOSE USED IN THE FRONT END INTERFACE SPEC
;	EXCEPT STATUS WHICH CONFLICTS WITH PROTOCOL SPEC
;
;	PDM# 200-200-012-00

;DTE-11 REGISTER ADDRESSES (FOR FIRST UNIT)

DLYCNT=174400	;DELAY COUNT WORD
DEXWD3=174402	;DEPOSIT OR EXAMINE WORD 3
DEXWD2=174404	;DEPOSIT OR EXAMINE WORD 2
DEXWD1=174406	;DEPOSIT OR EXAMINE WORD 1
TENAD1=174410	;TEN ADDRESS WORD 1
TENAD2=174412	;TEN ADDRESS WORD 2
TO10BC=174414	;TO-10 PDP-11 MEMORY ADDRESS
TO11BC=174416	;TO-11 BYTE COUNT
TO10AD=174420	;TO-10 PDP-11 MEMORY ADDRESS
TO11AD=174422	;TO-11 PDP-11 MEMORY ADDRESS
TO10DT=174424	;TO-10 PDP-11 DATA WORD
TO11DT=174426	;TO-11 PDP-11 DATA WORD
DIAG1=174430	;DIAGNOSTIC WORD 1
DIAG2=174432	;DIAGNOSTIC WORD 2
STAT=174434	;STATUS WORD
DIAG3=174436	;DIAGNOSTIC WORD 3
;TENAD1 DEFINITIONS

DEP=010000	;DEPOSIT (BIT 12)
PRTOFF=004000	;EXAMINE/DEPOSIT PROTECT OFF 
PHYS=100000	;PHYSICAL EXAMINE



;TO11BC DEFINITIONS

IFLOP=100000	;I FLIPFLOP BIT
ZSTOP=040000	;ZSTOP
TO11BM=020000	;TO 11 BYTE MODE



;	DIAG1 DEFINITIONS

DS04=004000	;KL CLOCK ERROR STOP
DS05=002000	;RUN
DS06=001000	;HALT
DEX=000400	;DEPOSIT OR EXAMINE MAJOR STATE
TO10=000200	;TO 10
DFUNC=000200
TO11=000100	;TO-11 TRANSFER MAJOR STATE
D1011=000040	;DIAGNOSE 10/11 INTERFACE
PULSE=000020	;SINGLE CLOCK CYCLE
DIKL10=00010	;DIAGNOSTIC MODE SWITCH
DSEND=000004	;SEND DATA
DCOMST=000001	;DIAGNOSTIC COMMAND START

TO10BM=000001	;NEED BYTE MODE IN DIAG3
;STAT DEFINITIONS (READ)

TO10DN=100000	;TO-10 NORMAL TERMINATION
TO10ER=020000	;TO-10 ERROR TERMINATION
RAMIS0=010000	;RAM IS ZEROS
TO11DB=004000	;-10 REQUESTED -11 INTERRUPT
DXWRD1=002000	;DEXWORD 1
MPE11=001000	;-11 MEMORY PARITY ERROR
TO10DB=000400	;-11 REQUEST -10 INTERRUPT
TO11DN=000200	;TO-11 TRANSFER DONE
EBSEL=000100	;E BUFFER SELECT
NULSTP=000040	;NULL STOP
BPARER=000020	;EBUS PARITY ERROR 
RM=000010	;RESTRICTED MODE
DEXDON=000004	;DEPOSIT/EXAMINE DONE
TO11ER=000002	;TO-11 BYTE ERROR TERMINATION
INTSON=000001	;INTERRUPTS ON


;STAT DEFINITIONS (WRITE)

DON10S=100000	;SET TO-10 NORMAL TERMINATION (DONE)
DON10C=040000	;CLEAR TO-10 NORMAL TERMINATION
ERR10S=020000	;SET TO-10 ERROR TERMINATION
ERR10C=010000	;CLEAR TO-10 ERROR TERMINATION
INT11S=004000	;SET TO-11 DOORBELL INTERRUPT REQUEST
INT11C=002000	;CLEAR TO-11 DOORBELL INTERRUPT REQUEST
PERCLR=001000	;CLEAR -11 MEMORY PARITY ERROR FLAG
INT10S=000400	;SET TO-10 DOORBELL INTERRUPT REQUEST
DON11S=000200	;SET TO-11 NORMAL TERMINATION FLAG
DON11C=000100	;CLEAR TO-11 NORMAL TERMINATION FLAG
INTRON=000040	;ENABLE -11 INTERRUPT
EBUSPC=000020	;CLEAR EBUS PARITY ERROR
INTROF=000010	;DISABLE -11 INTERRUPT
EBUSPS=000004	;SET EBUS PARITY ERROR
ERR11S=000002	;SET TO-11 ERROR TERMINATION FLAG
ERR11C=000001	;CLEAR TO-11 ERROR TERMINATION FLAG

;STATUS TO CLEAR DTE-11

DTE11C=ERR10C+PERCLR+EBUSPC+INTROF+ERR11C
;DTE20 COMMUNICATION AREA OFFSETS (WORD NAMES)

PIDENT=0	;PROCESSOR IDENTIFICATION WORD
CHNPNT=1	;POINTER TO COMM AREA OF NEXT PROCESSOR (CIRC LIST)
CYCLS=2		;CLOCK CPS COUNT
TOD=3		;TIME OF DAY
DATE=4		;DATE
PSWW1=5		;PROCESSOR STATUS WORD1
PSWW2=6		;PROCESSOR STATUS WORD2
PSWW3=7		;PROCESSOR STATUS WORD3
PSWW4=10	;PROCESSOR STATUS WORD4
PSWW5=11	;PROCESSOR STATUS WORD5
PSWW6=12	;PROCESSOR STATUS WORD6
PSWW7=13	;PROCESSOR STATUS WORD7
PSWW10=14	;PROCESSOR STATUS WORD10
PSWW11=15	;PROCESSOR STATUS WORD11
PSWW12=16	;PROCESSOR STATUS WORD12
PSWW13=17	;PROCESSOR STATUS WORD13
FORPRO=20	;FOR PROCESSOR IDENTIFICATON WORD
PROPNT=21	;POINTER TO COMM AREA OF THE PROCESSOR ASSOC WITH THIS BLOCK
STATUS=22	;COMMUNICATION STATUS WORD
QSIZE=23	;QUEUE SIZE WORD
;CTY0CW=24	;CTY #0 COMMAND WORD
;CTY0RW=25	;CTY #0 RESPONSE WORD
;CTY1CW=26	;CTY #1 COMMAND WORD
;CTY1RW=27	;CTY #1 RESPONSE WORD
;MISCW=30	;MISCELLANEOUS COMMAND WORD FOR NON-QUEUE PROTOCOL
;MISRW=31	;MISCELLANEOUS RESPONSE WORD
UNASG1=32	;UNASSIGNED WORD1
UNASG2=33	;UNASSIGNED WORD2
UNASG3=34	;UNASSIGNED WORD3
UNASG4=35	;UNASSIGNED WORD4
UNASG5=36	;UNASSIGNED WORD5
UNASG6=37	;UNASSIGNED WORD6



;EPT ADDRESSES AS DEFINED IN BOOTS FOR USE IN THE SECONDARY PROTOCOL

DTEFLG=444	;OPERATION COMPLETE FLAG
DTEF11=450	;PDP-10 FROM PDP-11 ARGUMENT
DTECMD=451	;PDP-10 TO PDP-11 COMMAND WORD
DTEMTD=455	;MONITOR TTY OUTPUT COMPLETE FLAG
DTEMTI=456	;MONITOR TTY INPUT FLAG



;STATUS DEFINITONS

TOIT=1		;IN PROGRESS OF PROCESSING QUEUE
TOIP=2		;TO HIM INDIRECT IN PROGRESS
TOBM=4		;TO HIM WORD MODE REQUESTED
LOAD11=4	;LOAD ELEVEN
	.SBTTL	$DTEON -- TURN THE DTE20 ON
;
;+
;
;	$DTEON -- TURN ON THE DTE20
;	THIS ROUTINE WILL SET UP THE TABLES NECESSARY TO
;	INITALIZE THE COMMUNICATION BETWEEN THE PDP10 AND PDP11'S
;
;
;	ENTRY CONDITIONS:
;
;
;	JSR	PC,$DTEON
;
;	EXIT CONDITIONS:
;
;	R0 --1 TO INDICATE SUCCESS
;	CC-C CLEAR TO INDICATE SUCCESS
;
;
;	ERROR CONDITIONS: 
;
;	R0 -2 -- E BOX STOPPED
;	CC-C SET
;
;
;	REGISTERS SAVED AND RESTORED BY EMT SERVICE
;
;-
;
$DTEON:	MOV	R5,-(SP)
	CLR	DBLCNT		;NO LONGER TRYING TO SEND A MESSAGE TO THE -10
	MOV	.PRDTE,R0	;FIND THE COMMON DTE20
	MOV	#DTE11C,STATD(R0) ;RESET DTE
	CLR	R1		;SET UP TO FIND PROCESSOR NUMBER
	CLR	R2		;START TRANSFER OF ABS WORD 0 OF EPT (MY PROCESSOR NUMBER
	MOV	#DEXTM3,R3	;SET UP ADDRESS TO STORE WORDS
	CLR	R4
	JSR	PC,SWFED	;WAIT FOR EXAMINE/DEPOSIT
	BCS	1$		;E BOX STOP
	MOV	@R3,R4		;YES --FIND OFFSET TO MY R/W AREA
	MOVB	@#DEXTM2+1,R2	;FIND THE PROCESSOR NUMBER
				; PROCESSOR NUMBER TO LOW ORDER BITS
	BIC	#177760,R2	;MASK OFF JUNK(0.-15. LEGAL)
	MOV	R2,PRMEMN	;SAVE PROCESSOR NUMBER
	INC	R2		;FIND COMMUNICATIONS VIRTUAL 2
	MOV	R2,COMBSE	;SAVE BASE OF COMMUNICATIONS AREA
	ADD	R4,R2		;ADD OFFSET TO BASE OF COMM AREA
	MOV	R2,DEPOF	;SET CORRECT OFFSET
	JSR	PC,SWFED	;WAIT FOR TRANSFER
1$:	BCS	80$		;
2$:	MOV	@#DEXTM2,R5	;PICK UP THE NUMBER OF 8 TM BLOCKS
	BIC	#177770,R5	;FIND THE NUMBER OF 8 WORD BLOCKS IN MY AREA
	SUB	#2,R5		;ACCOUNT FOR MY GENERAL SECTION
	MOV	R2,-(SP)
	MOV	R5,-(SP)	;SAVE COUNT OF BLOCKS
15$:	ADD	#FORPRO,2(SP)	;LOOK AT A COMMUNICATIONS AREA TO ANOTHER PROCESSOR
	MOV	2(SP),R2
	CLR	R4
	JSR	PC,SWFED	;WAIT FOR TRANSFER
	BCS	70$		; E BOX STOPPED
	MOV	@R3,R4		;FIND PROCESSOR NUMBER
	MOV	#PROTBL,R5	;SET INITIAL POINTER
	BIC	#177770,R4	;MASK OFF JUNK
	BEQ	19$		;YES -- CONTINUE
37$:	ADD	#5*2,R5		;NO -- LOOK AT NEXT ENTRY
	SOB	R4,37$		;TRY UNTIL ALL DONE
19$:	MOV	@#DEXTM2,R4	;FIND NUMBER OF 8 WORD BLOCS
	BIC	#177770,R4	;MASK OFF POSSIBLE GARBAGE
	SUB	R4,@SP		;UPDATE COUNT OF BLOCKS
	CLR	@R5		;SET UP TO CLEAR TABLE IF NO DTE
	MOV	@#DEXTM1,R4	;PICK UP DTE NUMBER
	BIT	#4,R4		;DTE HERE?
	BEQ	20$		;NO -- DON'T ENTER IN TABLE
	SWAB	R4		;MAKE MOD 40 (8)
	ROR	R4
	ROR	R4
	ROR	R4
	BIC	#177637,R4	;MASKOFF JUNK
	ADD	#174400,R4	;POINT TO FIRST BLOCK OF DTE'S
	CMP	R4,.PRDTE	;PRIMARY DTE?
	BNE	40$		;NO -- DON'T SET TABLE POINTER
	MOV	R5,.PRADR	;SAVE TABLE OFFSET
40$:	MOV	R4,@R5		;SET DTE ADDRESS IN TABLE
	MOV	#37777,@R4	;SET UP DELAY COUNTER
20$:	MOV	R2,EMYN(R5) 	;SET THE ADDRESS OF EXAMINE MY AREA FOR N
				;MAKE ADDRESS OF THE ADDRESS OF DEPOSIT MY AREA FOR N
	MOV	R2,DMYN(R5) 	;STORE IT
	SUB	DEPOF,DMYN(R5) 	;RESTORE SUPRESS FOR EXAMINE OF THIS BLOCK
	ADD	#PROPNT-FORPRO,R2 ;READ POINTER TO HIS COMM AREA
	CLR	R4
	JSR	PC,SWFED	;WAIT FOR EXAMINE/DEPOSIT
	BCS	70$		;E BOX STOPPED
	MOV	@R3,R2		;FIND THE EXAMINE ADDRESS
	ADD	COMBSE,R2	;ADD OFFSET TO COMMON AREA
	MOV	R2,EHSG(R5) 	;SET EHSG ADDRESS IN TABLE
	ADD	#FORPRO,R2	;POINT TO HIS FIRST TABLE FOR OTHER PROCESSORS
50$:	CLR	R4
	JSR	PC,SWFED	;WAIT FOR EXAMINE/DEPOSIT
	BCS	70$
	CMPB	PRMEMN,@R3 	;SAME PROCESSOR NUMBER?
	BEQ	60$		;YES -- FOUND MY ENTRY
	MOV	@#DEXTM2,R4	;NO -- FIND NEXT ENTRY IN LIST
	BIC	#177770,R4	;IT IS IN 8 WORD INCREMENTS
	ASL	R4		;SO IT MUST BE SHIFTED LEFT 3 BITS
	ASL	R4		;
	ASL	R4		;
	ADD	R4,R2		;READ NEXT BLOCK
	BR	50$		;AND TRY AGAIN

60$:	MOV	R2,EHSM(R5)	;STORE EHSM ADDRESS
	MOV	@SP,R5		;DONE ALL BLOCKS??
	BHI	15$		;NO -- TRY NEXT BLOCK
	CLR	QCOUNT		;RESET PROTOCOL COUNTERS
	CLR	QSTATE		;INIT STATE MECHANISM, CLEAR CARRY
70$:	BIT	(SP)+,(SP)+	;CLEANUP STACK, PRESERVE C BIT
80$:	MOV	(SP)+,R5
	RTS	PC
	.SBTTL	SWFED -- INTERNAL SUBROUTINE START AND WAIT FOR EX/DEP
;
;	SWFED -- STARTS A DEPOSIT/EXAMINE SEQUENCE AND WAITS FOR
;	ITS COMPLETION.  IT CHECKS TO SEE IF THE BOOTSTRAP
;	PROTOCOL IS NECESSARY BY CHECKING THE EXAMINE VALID BIT
;	AFTER EVERY EXAMINE/DEPOSIT.  IT IS NOT NECESSARY TO
;	CHECK MORE THAN ANY ONE RANDOM EXAMINE VAILD BIT
;	BECAUSE IF ONE IS 0 THEN THE PROCESSOR HAS
;	TO REVERT TO THE BOOTSTRAP PROTOCOL.
;	IF THE EXAMINE VALID BIT IS NOT SET THEN A CALL
;	TO .BTPRO MUST BE MADE TO START THE USE OF THE BOOTSTRAP
;	PROTOCOL -- THIS PROTOCOL IS USED PRIMARLY IN CASES
;	WHEN THE SYSTEM IS BEING BOOTSTRAPPED OR EDDT IS RUNNING.
;
;	NOTE: **** THIS ROUTINE MUST BE ENTERED AT PRI6 ****
;
;
;	CALLING SEQUENCE:
;
;	R0 -- ADDRESS OF DTE20
;	R1-- HIGH ORDER EXAMINE/DEPOSIT ADDRESS WORD (FOR TENAD1)
;	R2 -- LOW ORDER EXAMINE/DEPOSIT ADDRESS WORD (FOR TENAD2)
;	R3 -- ADDRESS TO XFER 3 WORD BLOCK TO OR FROM
;
;	JSR	PC,SWFED
;
;	EXIT CONDITIONS:
;
;	SUCCESS NO REGISTERS ALTERED CC-C CLEAR
;
;	ERROR CONDITIONS:
;
;	CC-C SET
;
;
SWFED:	MOV	R3,-(SP)	;SAVE REGISTERS
	BIT	#DEP,R1		;CHECK FOR DEPOSIT
	BNE	20$		;YES -- GO TO DEPOSIT PART OF SUB
	MOV	R1,TNAD1(R0)	;SET UP ADDRESS OF XFER IN DTE
	MOV	R2,TNAD2(R0)	;START XFER
	JSR	PC,WFED		;WAIT FOR EXAMINE/DEPOSIT
	BCS	40$		;COMPLAIN ABOUT E BOX STOPPED
	MOV	DXWD3(R0),(R3)+	;STORE THE WORD XFERED
	MOV	DXWD2(R0),(R3)+
	MOV	DXWD1(R0),(R3)+
10$:	TST	R4		;PRIV EXAMINE/DEP?
	BNE	40$		;YES -- DON'T DO CHECKS
	CLR	TNAD1(R0)	;SEE IF WE CAN READ ANYTHING
	CLR	TNAD2(R0)	;START TRANSFER
	JSR	PC,WFED		;WAIT FOR XFER
	BCS	40$		;E BOX STOPPED
	TST	DXWD3(R0)	;VALID?
	BNE	40$		;YES -- PROCEED
	BR	30$		;DN87S - JUST SET CARRY AND RETURN

20$:	MOV	(R3)+,DXWD3(R0) ;TRANSFER TO 10
	MOV	(R3)+,DXWD2(R0) ;SET UP WORD IN DTE
	MOV	(R3)+,DXWD1(R0)
	MOV	R1,TNAD1(R0)	;SET HIGH ORDER ADDRESS
	MOV	R2,TNAD2(R0)
	JSR	PC,WFED		;WAIT FOR EXAMINE/DEPOSIT
	BCC	10$		;GO TO COMMON EXAMINE VALID BIT CHECK
;
30$:	SEC			;SET CARRY TO SAY VALID EXAMINE IS OFF
40$:	MOV	(SP)+,R3	;RESTORE R3
	RTS	PC		;RETURN TO CALLER
	.SBTTL	WFED -- INTERNAL SUBROUTINE  WAIT FOR EXAMINE/DEPOSIT
;
;	WFED -- WAITS FOR EXAMINE/DEPOSIT TRANSFERS AND
;	CHECKS TO SEE THAT E BOX HAS NOT STOPPED
;
;	NOTE: **** THIS ROUTINE MUST BE ENTERED AT PRI6 ****
;
;
;	CALLING SEQUENCE:
;	ENTRY CONDITIONS:
;	R0 -- ADDRESS OF DTE20
;
;	JSR	PC,WFED
;
;	EXIT CONDITIONS:
;
;	SUCCESS NO REGISTERS ALTERED CC-C CLEAR
;
;	ERROR CONDITIONS:
;
;	CC-C SET
;	R0 -2 -- E BOX STOPPED
;
WFED:	MOV	#3000,DEXST	;SET UP TIMEOUT FOR DEXDONE
10$:	BIT	#DEXDON,STATD(R0) ;WAIT FOR TRANSFER TO COMPLETE
	BEQ	30$		;WAIT IF NOT YET DONE
	BIT	#BPARER,STATD(R0) ;DONE, CHECK FOR E BUS PARITY ERROR
	BNE	40$		;LOOKS BAD
.IF NE FTKLKR			;IF PARANOID ABOUT THE KL KROAKING OFF,
	BIT	#DS04!DS06,DAG1(R0)  ;KL IN HALT-LOOP OR CLOCK-ERROR-STOP?
	BNE	39$		;YES, THEN THE KL IS NOT RUNNING
	BIT	#DS05,DAG1(R0)	;IS THE KL RUN FLOP STILL SET?
	BEQ	39$		;NO, THEN THE KL IS NOT RUNNING
.ENDC;.IF NE FTKLKR
	CLC			;CLEAR CC-C FOR SUCCESSFUL OPERATION
	RTS	PC		;RETURN TO CALLER

30$:	DEC	DEXST		;TIMEOUT?
	BNE	10$		;NO -- CONTINUE WAITING
39$:	TWIDDLE			;COUNT THE NUMBER OF TIMES THIS HAPPENS
	TWIDDLE	STATD(R0)	;REMEMBER STATUS REGISTER
	TWIDDLE	DAG1(R0)	;REMEMBER SOME OTHER STATUS
	SEC			;SET CC-C TO INDICATE FAILURE
	RTS	PC		;AND RETURN WITH BAD NEWS

40$:	BIS	#ERR11C,STATD(R0) ;CLEAR THE ERROR STATUS
	BR	39$		;AND CLAIM FAILURE
.SBTTL		QUEUED PROTOCOL DATA AND SYMBOLS

TO11NP:	.WORD	0	;NODE POINTER FOR NDOE
TO11HD:	.WORD	0	;COUNT OF BYTES IN THIS QUEUE
TO11FN:	.WORD	0	;TO ELEVEN FUNCTION CODE
TO11DV:	.WORD	0	;TO ELEVEN DEVICE NUMBER
TO11SP:	.WORD	0	;SPACE
TO11FW:	.WORD	0	;FIRST WORD OF FUNCTION
	.IF	DF,$DBDTE
TO11GW:	.WORD	-1	;GUARD WORD FOR DTE20
TO11QP:	.WORD	0
TO11AS:	.WORD	0	;ADDRESS SAVE
TO11BS:	.WORD	0	;BYTE COUNT SAVE
TO10SZ:	.WORD	0	;BYTE COUNT OF XFER
TO10AS:	.WORD	0
	.ENDC
;
STSTT:	.WORD	1,0,0	;TO 10 STATUS
;
QCOUNT	=STSTT+4	;BOTH OF BELOW
TO10QC	=STSTT+4	;TO 10 QUEUE COUNT
TO11QC	=STSTT+5	;TO 11 QUEUE COUNT
;
BUFOV:	.WORD	0	;BUFFER OVERFLOW FLAG (NO NODES AVAILABLE
;
;
TO10Q:	 .WORD	.	;LISTHEAD FOR TO 10 QUEUE
	.WORD	.-2	
;
EQSZ:	.WORD	0	;ELEVEN Q SIZE
;
QSTATE:			;ZEROED AT STARTUP
TO11ST:	.BLKB	1	;STATE OF TO-11 MECHANISM
TO10ST:	.BLKB	1	;AND OF TO-10
CURMSG:	.BLKW	1	;CHUNK ADDR OF NCL MESSAGE BEING BUILT
T10QUE:	.BLKW	1	;QUEUE OF MESSAGES WAITING FOR ACKS
ACKFLG:	.BLKW	1	;NON-ZERO WHEN WE CAN SEND A MESSAGE TO -10
.STUSR:	.BLKW	1	;TEMP, SAVED BY ..STIN ON A PER MESSAGE BASIS
DBLCNT:	.WORD	0	;TIMER FOR CASES WHEN -10 MISSES DOORBELL
TO11Q:	.WORD	0	;TO 11 QUEUE
STATI:	.BLKW	3	;STATUS/SCRATCH WORD FOR EXAMINES/DEPOSITS
;	DEVICE QUEUE POINTERS
;
D.CCTY	=1	;DEVICE CODE FOR CTY
D.CDL1	=2	;DEVICE CODE FOR DL11
D.CDH1	=3	;DEVICE CODE FOR DH11 (1)
D.CDLS	=4	;DEVICE CODE FOR DATA LINE SCANNER (1)
D.CLPT	=5	;DEVICE CODE FOR LPT
D.CCDR	=6	;DEVICE CODE FOR CDR
D.CCLK	=7	;DEVICE CODE FOR CLOCK
D.FEPD	=10	;PSEUDO DEVICE FOR FE
D.CNCL	=11	;NCL NETWORK DEVICE
;
D.CCPU	=200	;PSEUDO DEVICE PDP10 CPU
D.CKLE	=201	;KL ERROR PSEUDO DEVICE
;
;
;
; TO ELEVEN QUEUE ENTRY
;
E.FP	=0	;FORWARD POINTER
E.LS	=2	;LIST SIZE
E.FN	=4	;FUNCTION CODE
E.DV	=6	;DEVICE CODE
E.FW	=10	;FUNCTION FIRST WORD
;
;	FUNCTION CODE DEFINITIONS
;
BC.RQD	=1	;REQUEST DEVICES
BC.HAD	=2	;HERE ARE DEVICES
BC.STR	=3	;STRING DATA
BC.LNC	=4	;LINE/CHARACTER DATA
BC.RDS	=5	;RETURN DEVICE STATUS
BC.SDS	=6	;SET DEVICE STATUS
BC.HDS	=7	;HERE IS DEVICE STATUS
BC.DES	=10	;DEVICE ERROR STATUS
BC.RTD	=11	;RETURN TIME OF DAY
BC.HTD	=12	;HERE IS TIME OF DAY
BC.FOD	=13	;FLUSH OUTPUT DEVICE QUEUE
BC.SNA	=14	;SEND ALL 
BC.TDU	=15	;DEVICE DIAL UP
BC.THU	=16	;DEVICE HANG UP
BC.SAK	=17	;ACKNOWLEDGE DEVICE DONE
BC.XOF	=20	;X-OFF (TTY ONLY)
BC.XON	=21	;X-ON (TTY ONLY)
BC.STS	=22	;SET TTY SPEED
BC.SLA	=23	;SET LINE ALLOCATION
BC.BTP	=24	;11 REBOOT WORD
BC.AKA	=25	;ACK ALL
BC.SPT	=26	;START/STOP LINE
BC.EDR	=27	;ENABLE/DISABLE REMOTES
BC.LDR	=30	;LOAD LP RAM
BC.LDV	=31	;LOAD LP VFU
BC.D6D	=32	;DAS 60 DATA
BC.KPS	=33	;KLINIK PARAMETER STATUS
BC.FNM	=34	;1 GREATER THAN MAX FUNCTION
;DTE20 REGISTER DEFINITIONS

DAG3	=36
STATD	=34
DAG2	=32
DAG1	=30
T11AD	=22
T10AD	=20
T11BC	=16
TNAD1	=10
TNAD2	=12
DXWD1	=6
DXWD2	=4
DXWD3	=2


;QUEUED PROTOCOL STATE DEFINITIONS:
;TO-11:
TES.DB	=0			;IDLE, WAITING FOR DIRECT DOORBELL
TES.HD	=2			;WAITING FOR TO11 DONE FOR HEADER
TES.DD	=4			;WAITING FOR TO11 DONE FOR DIRECT PORTION
TES.IB	=6			;WAITING FOR INDIRECT DOORBELL
TES.ID	=10			;WAITING FOR TO11 DONE FOR INDIRECT PORTION
.IIF NDF,DBLTIM,DBLTIM=5	;GIVE -10 5 SECONDS TO RESPOND TO A DOORBELL
.SBTTL		DTE20 INTERRUPT SERVICE ROUTINES

DTEVA0:				;CHK11 USES THIS SYMBOL
.DTINT:	.CRASH	INT		;WE DON'T USE INTERRUPTS ANYMORE

;INTLPS - ROUTINE TO SEE IF ANY "EVENTS" HAPPENED WHILE WE WEREN'T
;  LOOKING.  MAIN THINGS CHECKED FOR ARE DOORBELLS AND ERRORS.


INTLPS:	JSR	R0,TRPST	;PREPARE FOR DTE DEATH
		.WORD	TENDWD	; (FLAG TEN DOWN, RE-ROUTE IF NECESSARY)
INTLP0:	MOV	.PRDTE,R0	;SET UP POINTER TO THIS PROCESSOR'S DTE-20
	ASSERT	NE		;HAD BETTER NOT BE 0!
	MOV	@.PRSTA,R1	;GET ALL OF DTE-20'S STATUS BITS
	MOV	.PRADR,R3	;ADDRESS OF COMM TABLE OFFSETS
	BIT	#TO10DN!TO10ER!MPE11,R1 ;TO 10 DONE OR ERROR?
	BNE	TOTNDN		;YES -- GO CHECK IT OUT
	BITB	#TO11DN!TO11ER,R1 ;TO 11 DONE OR ERROR?
	BEQ	4$		;NO -- GO ON
	JMP	TOELDN		;YES -- SEE WHAT IS NEXT FOR 11
4$:	BIT	#TO11DB,R1	;NO -- CHECK FOR DOORBELL INTERRUPT
	BEQ	INTLP9		;NO -- SKIP DOORBELL STUFF
	JMP	DBLRNG		;YES -- GO DO DOORBELL STUFF

INTLP9:	RTS	PC
;THIS INTERRUPT ROUTINE DECIDES WHAT TO DO WHEN A DIRECT
;MESSAGE OR EITHER PIECE OF AN INDIRECT MESSAGE REACH THE -10. THE
;STATE  VARIABLE USED IS THE FUNCTION WORD OF THE MESSAGE BEING SENT.
;ON DIRECT MESSAGES IT WILL BE POSITIVE AND AFTER THE DIRECT PORTION
;OF INDIRECT MESSAGES IT WILL BE NEGATIVE. IN THE LATTER CASE THE INDIRECT
;PORTION WILL BE SENT TO THE -10 AND THE STATE VARIABLE IS CLEARED TO
;ENTER THE STATE WHERE THE NEXT INTERRUPT MARKS THE END OF THE INDIRECT
;MESSAGE. WHEN IT OCCURS, WE CALL T10DON TO ALLOW THE NCL INTERFACE TO
;RETURN THE MESSAGE BACK TO NCL FOR DISCARD OR SAVING.

TOTNDN:	BMI	10$		;DONE?
	.CRASH	TET		;NO -- MUST BE EITHER MEMORY PARITY OR TO10ER
;
10$:
	.IF	DF,$DBDTE
	MOV	TO10SZ,R4
	ADD	TO10AS,R4
	CMP	R4,T10AD(R0)
	BEQ	13$
	MOV	T10AD(R0),#0	;SAVE THE WRONG COUNT
	TRAP			;TELL SOMEONE END POINTS OF XFER DON'T MATCH
13$:
	MOV	#1,TO10AS	;SET NO XFER EXPECTED
	.ENDC
	MOV	#DON10C,@.PRSTA	;CLEAR DONE FLAGS
	CLR	DBLCNT		;GETTING HERE MEANS THE -10 SAW THE DOORBELL
	MOV	TO10Q,R4	;START NEXT ENTRY IF THERE IS ONE
	TST	12(R4)		;CHECK FOR INDIRECT FUNCTION
	BMI	INDTTF		;YES -- START THE FUNCTION
	BNE	15$		;NO -- IF NE THEN NORMAL FUNCTION
	BIC	#TOIP!TOBM,STSTT+2 ;CLEAR INDIRECT IN PROGRESS
	JSR	PC,T10DON	;LET NCL INTERFACE KNOW ABOUT IT
15$:	JSR	PC,..NDEL
	MOV	R0,-(SP)	;SAVE R0 -- CPU NUMBER
	MOV	4(R4),R1	;FIND THE SIZE OF THIS ENTRY
	MOV	R4,R0		;SET THE NODE ADDRESS
	JSR	PC,..DECB		;DEALLOCATE
	MOV	(SP)+,R0	;RESTORE THE CPU NUMBER
	MOV	TO10Q,R4	;FIND THE LISTHEAD AGAIN
	CMP	#TO10Q,R4	;IS THERE ANOTHER ONE TO DO
	BEQ	INTLP0
	JSR	PC,STNTQ		;START NEXT TEN QUEUE
20$:	BR	INTLP0		;CHECK THE OTHER CONDITIONS NOW
INDTTF:	CLR	12(R4)		;SET INDICATOR TO INDICATE THAT THIS WAS INDIRECT
	CLR	DXWD1(R0)	;DEPOSIT THE WORD COUNT
	CLR	DXWD2(R0)
	CLR	R5
	BISB	20(R4),R5	;SET THE COUNT
	MOV	R5,DXWD3(R0)
	.IF	DF,$DBDTE
	MOV	22(R4),TO10AS
	MOV	R5,TO10SZ
	.ENDC
	MOV	22(R4),T10AD(R0) ;SET THE TO 10 ADDRESS
	MOV	#QSIZE-FORPRO,R5 ;DEPOSIT THE SIZE IN 10 MEMORY
	ADD	DMYN(R3),R5	;GET OFFSET
	MOV	#DEP,TNAD1(R0)	;SET DEPOSIT
	MOV	R5,TNAD2(R0)	;START XFER
	JSR	PC,WFED		;WAIT FOR DEPOSIT
	BIS	#TOIP,STSTT+2	;SAY WE'RE DOING INDIRECT
	MOV	#TO10BM,DAG3(R0) ;AND TELL HARDWARE THAT WE'RE DOING
				; IT IN BYTE MODE
	MOV	STSTT,DXWD1(R0)	;SET IN 10 MEMORY
	MOV	STSTT+2,DXWD2(R0)
	MOV	STSTT+4,DXWD3(R0)
	ADD	#STATUS-QSIZE,TNAD2(R0)	;DEPOSIT IN 10 MEMORY
	JSR	PC,WFED		;WAIT FOR DEPOSIT
	JSR	PC,RINGDB	;TELL -10
	JMP	INTLP0
;TO-11 TRANSFERS ARE CONTROLLED BY BOTH THE DONE AND DOORBELL
;INTERRUPT ROUTINES AND EVERYTHING IS SYNCHRONIZED BY THE TO11ST
;STATE VARIABLE. (SEE THE TES.?? SYMBOL DEFINITIONS FOR THE MEANINGS.)

TOELDN:	BMI	10$		;ERROR?
5$:	.CRASH	ETE		;YES -- TO ELEVEN ERROR FLAG UP
;
10$:
	.IF	DF,$DBDTE
	MOV	TO11BS,R1
	BIS	#170000,R1
	NEG	R1
	BIT	#TO11BM,TO11BS
	BNE	6$
	ASL	R1
6$:	ADD	TO11AS,R1
	CMP	R1,T11AD(R0)
	BEQ	7$
	MOV	T11AD(R0),#0
	.CRASH	DTB
7$:
	.ENDC
	MOV	#DON11C,@.PRSTA	;CLEAR DONE FLAGS
	MOVB	TO11ST,R1	;GET PRESENT TO11 STATE
	JSR	PC,@20$(R1)	;CALL APPROPRIATE ROUTINE
	MOVB	R1,TO11ST	;ENTER NEW STATE
	JMP	INTLP0		;SEE WHAT ELSE TO DO

20$:	DEAD11			;IDLE
	TEHDIN			;GO BRING IN THE HEADER
	TEDONE			;DIRECT MESSAGE IS IN
	DEAD11			;INDIRECT DOORBELL EXPECTED
	TEDONE			;INDIRECT DATA DONE


DEAD11:	.CRASH	PT4		;PROTOCOL BROKEN
;
;
;	DOOR BELL INTERRUPT SERVICE
;
DBLRNG:	CLR	TNAD1(R0)	;READ STATUS WORD
	MOV	#STATUS-FORPRO,R2 ;FIND THE ADDRESS OF HIS STATUS-TO ME
	ADD	EHSM(R3),R2
	MOV	R2,TNAD2(R0)	;READ THAT STATUS WORD
	MOV	#INT11C,@.PRSTA
	JSR	PC,WFED		;WAIT FOR EXAMINE
	BCS	35$		;IGNORE INTERRUPT IF NOT STARTED
	MOV	DXWD1(R0),STATI	;SAVE STATUS
	MOV	DXWD2(R0),STATI+2
	MOV	DXWD3(R0),STATI+4
	TST	STATI		;VALID EXAMINE?
	BEQ	35$		;IGNORE WHEN NOT IN PRIMARY PROTOCOL
10$:	BIT	#TOIP,STATI+2	;INDIRECT IN PROGRESS
	BEQ	30$		;NO -- MUST BE NORMAL
	CMPB	TO11ST,#TES.IB	;WAITING FOR IND. DOORBELL?
	ASSERT	EQ		;BETTER BE!
	JSR	PC,TEINST	;YEP, START TRANSFER
	BR	40$		;SAVE NEW STATE AND CLEAN UP
;
30$:	CMPB	STATI+4,TO10QC	;IS THIS THE CORRECT COUNT
	BEQ	35$		;YES -- CONTINUE PROCESSING
	CMPB	TO11ST,#TES.DB	;WAITING FOR DIRECT DOORBELL?
	ASSERT	EQ
	JSR	PC,TEHDST	;START TRANSFER OF HEADER
40$:	MOVB	R1,TO11ST	;ENTER NEW STATE (TO11 DONE EXPECTED)
35$:	JMP	INTLP0		;SEE IF ANYTHING NEW TO DO
;CALLED TO START THE TRANSFER OF A TO-11 MESSAGE WHICH IT DOES BY
;TRANSFERRING THE HEADER AND FIRST WORD OF DATA (ALLWAY PART OF THE
;DIRECT PACKET). WHEN THAT IS IN, MESSAGE PROCESSING CONTINUES
;AT TEHDIN.

TEHDST:	BIS	#TOIT,STSTT+2	;SET QUEUE IN PROGRESS
	INCB	TO10QC		;INDICATE Q UPDATED
	CMPB	STATI+4,TO10QC	;COUNT CORRECT?
	BEQ	40$		;YES -- PROCEED
	.CRASH	ILQ		;NO -- DISASTER
;
40$:	MOV	#DEP,TNAD1(R0)	;SET UP TO DEPOSIT
	MOV	STSTT,DXWD1(R0)	;THE STATUS
	MOV	STSTT+2,DXWD2(R0)
	MOV	STSTT+4,DXWD3(R0)
	MOV	#STATUS-FORPRO,R2
	ADD	DMYN(R3),R2
	MOV	R2,TNAD2(R0)
	JSR	PC,WFED		;START DEPOSIT
	MOV	#INT11C,@.PRSTA
	MOV	#QSIZE-FORPRO,R2 ;FIND THE QUEUE SIZE
	ADD	EHSM(R3),R2	;EXAMINE HIS FOR ME
	CLR	TNAD1(R0)	;CLEAR DEPOSIT BIT
	MOV	R2,TNAD2(R0)
	JSR	PC,WFED		;WAIT FOR EXAMINE/DEPOSIT
	BCS	77$
	MOV	DXWD3(R0),EQSZ	;SET UP Q SIZE
	CMP	EQSZ,#100.	;LEGAL SIZE
	BLO	77$		;YES -- ALL OK
	.CRASH	PT4
				;THIS AUTOMATICALLY SETS UP EQSZ
77$:	MOV	R0,R2		;MOVE DTE ADDR TO RIGHT PLACE
	MOV	#12,R0		;JUST TRANSFER THE HEADER
	MOV	#TO11HD,R1	;INTO THE HEADER AREA
	JSR	PC,TESTRT	;START TRANSFER
30$:	MOV	#TES.HD,R1	;RETURN HEADER WAIT STATE
	RTS	PC
;CALLED AFTER THE HEADER OF THE TO-11 MESSAGE IS SAFELY IN. THE
;REST OF THE DIRECT PORTION (IF ANY) IS TRANSFERRED INTO MEMORY SET
;UP BY THE NCL INTERFACE (T11DBL). IF THIS IS AN INDIRECT MESSAGE,
;WE WILL WAIT FOR ITS DOORBELL; IF AN ACK, IT'S ENTIRELY IN AND
;CONTROL GOES TO TEDONE TO CALL T11DON TO START PROCESSING BY LOOPDT.

TEHDIN:	SWAB	TO11HD		;SWAP BYTES TO CORRECT DIRECTION
	SWAB	TO11FN
	SWAB	TO11DV
	SWAB	TO11FW
	MOV	R0,R2		;SAVE THE CPU NIMBER -ALSO RESTART HERE IF ALL FAIL
	CMP	#D.CNCL,TO11DV	;LEGAL DEVICE?
	BEQ	42$		;YES -- ALL OK
	.CRASH	PT1		;NO -- PROTOCOL BROKEN
42$:	TST	TO11FN		;INDIRECT FUNCTION?
	BMI	44$		;YES -- GET OUT AND WAIT FOR REST
	CMPB	TO11FN,#BC.FNM	;FUNCTION MAX?
	BLO	46$		;YES -- ALL OK HERE
	.CRASH	PT2		;NO -- PROTOCOL BROKEN
46$:	MOV	EQSZ,R0		;GET LENGTH OF MESSAGE MINUS HEADER
	JSR	PC,T11DBL	;TELL NCL STUFF TO TRANSFER DIRECT MESSAGE
	TST	R0		;ANYTHING TO DO?
	BEQ	TEDONE		;NOPE, CALL THE DONE ROUTINE
	JSR	PC,TESTRT	;TRANSFER THE DATA
44$:	MOV	R2,R0
	TST	TO11FN		;IS IT INDIRECT?
	BPL	70$
	MOV	#TES.IB,R1	;RETURN IND. DOORBELL WAIT STATE
	JMP	TOITDN

70$:	MOV	#TES.DD,R1	;RETURN DIRECT DOORBELL WAIT STATE
	RTS	PC
;CALLED WHEN THE DOORBELL REQUESTING THE START OF THE INDIRECT
;DATA RINGS. T11DBL IS NOTIFIED AND RETURNS WHERE THE DATA SHOULD BE
;SENT. NOTE THAT IT NEED NOT ALLOCATE SPACE FOR THE ENTIRE MESSAGE.

TEINST:	BIS	#TOIT,STSTT+2	;TELL -10 WE SHOULD BE XFERRING DATA
	ADD	#QSIZE-STATUS,TNAD2(R0) ;READ THE STATUS WORD
	JSR	PC,WFED		;WAIT FOR EXAMINE
	BCS	SETDNE
	MOV	R0,R2		;WE NEED R0
	MOV	DXWD3(R2),R0	;GET MESSAGE LENGTH
	MOV	R0,EQSZ		;SAVE LENGTH OF MESSAGE
	JSR	PC,T11DBL	;TELL NCL INTERFACE THE GOOD NEWS
	JSR	PC,TESTRT	;START UP THE TRANSFER
	MOV	R2,R0
	MOV	#TES.ID,R1	;RETURN IND. DONE WAIT STATE
	BR	STTOIP		;STORE STATUS WORD IN COMM REGION AND DISMISS INTERRUPT
;CALLED WHEN WE FILL A CHUNK OR REACH THE END OF THE TO-11 MESSAGE.
;T11DON IS QUERIED TO DETERMINE WHETHER OR NOT IT IS TIME TO
;STOP (IT WILL PUT THE MESSAGE ON A QUEUE FOR LOOPDT TO SEE.)

TEDONE:	MOV	TO11NP,R1	;ENTER THE NODE IN THE QUEUE
	MOV	R0,R2		;SAVE DTE ADDRESS
	JSR	PC,T11DON	;TELL NCL ROUTINES DATA CAME IN
	BEQ	10$		;QUEUE IT IF THAT'S ALL THERE IS
	JSR	PC,TESTRT	;MORE TO RECEIVE, START IT
	MOVB	TO11ST,R1	;DON'T CHANGE STATE
	RTS	PC

10$:	MOV	#TES.DB,R1	;BACK TO INITIAL STATE
	TST	EQSZ		;ANY MORE TO XFER?
	BEQ	TOITDN		;NO -- SET DONE TO -10
	TRAP			;I DON'T THINK WE CAN GET HERE!


;SERVICE ROUTINES FOR INTERRUPT CODE

TOITDN:	BIC	#TOIT,STSTT+2	;CLEAR PROCESSING QUEUE STATUS
STTOIP:	MOV	.PRDTE,R0	;MAKE SURE THIS IS SETUP
	MOV	#STATUS-FORPRO,R2 ;YES -- BETTER INDICATE THAT 11 IS FINISHED
	ADD	DMYN(R3),R2	;POINT TO STATUS WORD
	MOV	#DEP,TNAD1(R0)	;INDICATE WRITE
	MOV	STSTT,DXWD1(R0)	;SET UP TO DEPOSIT
	MOV	STSTT+2,DXWD2(R0)
	MOV	STSTT+4,DXWD3(R0)
	MOV	R2,TNAD2(R0)	;START XFER
	JSR	PC,WFED		;WAIT FOR DEPOSIT
SETDNE:	RTS	PC		;RETURN TO TOELDN OR DBLRNG
;ROUTINE TO START A TO-11 BYTE MODE TRANSFER.
;CALL:
;R0/	# OF BYTES TO TRANSFER
;R1/	WHERE TO START DATA

TESTRT:	SUB	R0,EQSZ		;THIS MUCH LESS TO DO
	NEG	R0		;MAKE COUNT NEGITIVE
	BIC	#170000,R0	;MASK OFF COUNT
	RORB	R0		;!!!WARNING THIS ASSUMES C BIT IS SET BY NEG R0!!!!^^
	BIT	#TOBM,STATI+2	;WORD MODE?
	BNE	25$		;YES -- DON'T SET BYTE FLAG
	ROLB	R0		;!!^^SEE ABOVE -- RESTORE TO BYTE COUNT!!
	BIS	#TO11BM,R0	;SET BYTE MODE
25$:	TST	EQSZ		;WILL THIS FINISH MESSAGE?
	BNE	30$		;NO, DON'T INTERRUPT -10
	BIS	#IFLOP,R0 	;SET INTERRUPT BOTH
30$:	MOV	R1,T11AD(R2)	;AND START XFER
	MOV	R0,T11BC(R2)	;SET BYTE COUNT
	.IF	DF,$DBDTE
	MOV	R1,TO11AS
	MOV	R0,TO11BS
	.ENDC
	RTS	PC
;
;	STNTQ -- SUBROUTINE TO START NEXT TO TEN QUEUE
;
STNTQ:	MOV	R5,-(SP)	;SAVE REGISTERS
	MOV	R0,-(SP)
	MOV	.PRDTE,R0	;SET UP ADDRESS OF DTE20
	CLR	DXWD1(R0)
	CLR	DXWD2(R0)
	MOV	R4,R5		;SAVE THE NODE ADDRESS
	ADD	#6,R5		;MOVE OVER LISTHEAD AND NODE SIZE
	.IF	DF,$DBDTE
	MOV	@R5,TO10SZ
	.ENDC
	MOV	(R5)+,DXWD3(R0)	;SET THE QUEUE SIZE IN MY AREA TO HIM
	MOV	R5,T10AD(R0)	;SET UP THE TO10 ADDRESS
	MOV	#1,DAG3(R0)	;SET BYTE MODE
	.IF	DF,$DBDTE
	MOV	R5,TO10AS
	.ENDC
	MOV	.PRADR,R5	;FIND THE CORRECT DTE
	MOV	DMYN(R5),R5	;FIND THE OFFSET INTO MY AREA
	ADD	#QSIZE-FORPRO,R5 ; FIND Q SIZE
	MOV	#DEP,TNAD1(R0)	;SET UP TO DO DEPOSIT
	MOV	R5,TNAD2(R0)
	JSR	PC,WFED
	INCB	TO11QC		;INCREMENT THE COUNT
	MOV	STSTT,DXWD1(R0)
	MOV	STSTT+2,DXWD2(R0)
	MOV	STSTT+4,DXWD3(R0)
	ADD	#STATUS-QSIZE,TNAD2(R0)
	JSR	PC,WFED		;EXAMINE/DEPOSIT
	MOV	(SP)+,R0
	MOV	(SP)+,R5	;RESTORE REGISTERS
	BR	RINGDB		;DING THE -10
;RINIDB  --  RING THE -10 DOORBELL
;RINGDB  --  RING THE -10 DOORBELL
;
;BOTH ROUTINES RING THE -10'S DOORBELL BUT RINIDB ASSUMES THAT NXM
;TRAPPING IS NOT IN EFFECT (CALLED FROM SYSTEM STARTUP).

RINIDB:	TST	.PRDTE		;DO WE HAVE ANY DTE?
	BEQ	99$		;NO, THEN DON'T RING ITS DOORBELL
	JSR	R0,TRPST	;YES (IN THEORY), ENABLE NXM TRAPPING
		.WORD	10$	; (JUST IGNORE IT AND GO AWAY)
	BR	RINGDB		;GO DO IT

10$:	CLR	.PRDTE		;NO DTE ANYMORE
	MOV	#TE.BAS-1,.PRSTA;NXM ANY TURKEYS
99$:	RTS	PC		;SO MUCH FOR THAT IDEA



RINGDB:	MOV	#TO10DB,@.PRSTA	;TELL -10 TO GO
	MOV	#DBLTIM,DBLCNT	;START TIMER
	RTS	PC
	.SBTTL	COMMON ROUTINES AND DATA STORAGE

.PRADR:	.WORD	0		;ADDRESS OF PRIV OFFSET TABLE ENTRY
.PRSTA:	.WORD	0		;OUR DTE20 STATUS WORD ADDRESS AND
.PRDTE:	.WORD	0		;DTE20 REGISTER(S) BASE ADDRESS
				; IF 0 THEN AS NEAR AS WE CAN TELL THERE
				; IS NO DTE, EVEN THOUGH WE WERE ASSEMBLED
				; FOR ONE (E.G., KL IS POWERED OFF)
DEXST:	.WORD	0		;DEXDONE TIMEOUT
.CRQZ:	.WORD	0		;CURRENT QUEUE SIZE
.CPFN:	.WORD	0		;CURRENT FUNCTION IN TO 10 Q
.CPDV:	.WORD	0		;CURRENT DEVICE IN TO 10 QUEUE
.CRSZ:	.WORD	0		;CURRENT SIZE OF TO10 Q
.CRPB:	.WORD	0		;CURRENT BUFFER POINTER IN TO10 Q
.CRHD:	.WORD	0		;HEAD OF CURRENT TO10Q
.CRSB:	.WORD	0		;POINTER TO CURRENT FUNCTION SIZE
;
;	POINTERS TO COMMUNICATIONS AREA
;
COMBSE:	.WORD	0	;BASE OF COMMUNICATION AREA
PRMEMN:	.WORD	0	;MY PROCESSOR NUMBER
DEPOF:	.WORD	0	;DEPOSIT OFFSET FROM EXAMINE
;
;
;	PROCESSOR IDENTIFICATION TABLE
;
;	PROTBL FORMAT:
;
;	5 WORDS/ENTRY
;	16 ENTRYS IN THE TABLE ONE FOR EACH PROCESSOR IN COMMUNICATION 
;	COMMUNICATION NUMBERS ARE LIMITED TO THE RANGE 0-15.
;
;	(PROCESSOR 0) PROTBL:	ADDRESS OF DTE20 TO ACCESS THIS PROCESSOR
DTENM=0
;	(PROCESOR 0)		ADDRESS TO COMMUNICATE TO PROCESSOR 0
EMYN	=2
;	(PROCESSOR 0)		ADDRESS TO COMMUNICATE TO PROCESSOR 0 (WRITE)
DMYN	=4
;	(PROCESSOR 0)		ADDRESS FROM GENERAL 
EHSG	=6
;	(PROCESSOR 0)		ADDRESS FROM SPECIFIC
EHSM	=10
;
;	(PROCESSOR 1)	ADDRESS OF DTE20 TO USE TO ACCESS THIS PROCESSOR
;	...........
;
PROTBL:	.BLKW	16.*5.
;
DEXTM3:	.WORD	0		;EXAMINE WORD 3 (TEMP STORAGE) TO BE
DEXTM2:	.WORD	0		;EXAMINE WORD 2 -USED ONLY BECAUSE EXAMINE
DEXTM1:	.WORD	0		;EXAMINE WORD 1 - OR DEPOSIT MAY FAIL AND MUST BE REDONE
;
KPAL1:	.WORD	0,0,0		;11 KEEP ALIVE
.SBTTL	SCOM MODULE -- ..NDEL	(NODE DELETE)
;+
;
;	..NDEL -- ROUTINE TO DELETE A NODE FROM A LIST
;		THIS IS A BASIC SUBROUTINE TO DELETE
;		NODES FROM A LIST.  IT DOES NOT DO
;		ANY ACCOUNTING OR LOOKING THE NODE
;		IT ASSUMES THAT THERE IS A NODE TO BE PICKED
;		AND INHIBITS INTERRUPTS TO PREVENT CONFLICTS WITH
;		NODES BEING ADDED TO A DEQUE.
;
;
;	CALLING SEQUENCE:
;		R4 -- POINTER TO NODE TO BE DELETED
;		JSR	PC,..NDEL
;-
;
..NDEL:	MOV	R1,-(SP)	;SAVE R1
	MOV	@R4,R1		;PICK THE NODE
	MOV	R1,@2(R4)	;
	MOV	2(R4),2(R1)	;
	MOV	(SP)+,R1	;RESTORE R1
	RTS	PC		;RETURN TO CALLER
.SBTTL	SCOM MODULE -- ..NADD	(NODE ADD)
;+
;
;
;	..NADD -- ROUTINE TO ADD A NODE TO A DEQUEUE
;		..NADD IS THE GENERAL PICK A NODE ROUTINE
;		THE ADDITION OF A NODE IS DONE WITH INTERRUPTS
;		INHIBITED TO PREVENT A CONFLICT WITH
;		NODE DELETION.
;
;
;	CALLING SEQUENCE:
;		R1 -- NODE ADDRESS
;		R4 -- ADDRESS OF LISTHEAD OR PREVIOUS NODE
;		JSR	PC,..NADD
;-
;
;
..NADD:	MOV	R2,-(SP)	;SAVE R2
	MOV	R4,2(R1)	;SET UP BACKWARD POINTER IN NODE
	MOV	@R4,@R1		;SET UP FORWARD POINTER
	MOV	R1,@R4		;FORWARD POINTER FROM LIST HEAD
	MOV	@R1,R2		;
	MOV	R1,2(R2)	;
	MOV	(SP)+,R2	;RESTORE R2
	RTS	PC		;RETURN TO CALLER
.SBTTL	SCOM MODULE -- ..STIN	(START INDIRECT FUNCTION)
;
;+
;
;	..STIN -- SUBROUTINE TO START AN INDIRECT DTE20 FUNCTION
;	TO THE 10
;
;  ENTRY CONDITIONS:
;
;	R0 -- BUFFER ADDRESS
;	R1 -- FUNCTION +100000
;	R2 -- EFN/BUFFER SIZE
;	R3 -- DEVICE ID
;
;	NOTE :  THE FIRST WORD OF THE BUFFER MUST CONTAIN THE
;	LINE NUMBER AND BUFFER SIZE
;
;	MAY NOT BE CALLED FROM ISR
;
;
;	JSR	PC,..STIN
;
;  EXIT CONDITIONS:
;	CC-C CLEAR SUCCESS
;	CC-C SET FAILURE -- PRIMARY PROTOCOL IN USE
;
;-
;
..STIN:	MOV	R5,-(SP)	;SAVE REGISTERS
	MOV	R0,-(SP)
	MOV	R1,-(SP)
	MOV	#30,R1		;SET UP TO ALLOCATE A BUFFER
10$:	JSR	PC,..ALCB	;ALLOCATE BUFFER

20$:	MOV	R0,R5		;MOVE BUFFER ADDRESS TO R5
	CMP	(R5)+,(R5)+	;MOVE OVER THE LISTHEAD
	MOV	R1,(R5)+	;STORE THE BUFFER SIZE
	MOV	#12,@R5		;PUT IN THE SIZE OF THIS HEADER PACKET
	MOV	(R5)+,(R5)+	;ALSO PUT IT IN FIRST WORD TO 10
	MOV	@SP,(R5)+	;STORE FUNCTION CODE
	MOV	R3,(R5)+	;STORE THE DEVICE I/D
	CLR	(R5)+		;CLEAR THE SPARE WORD
	MOV	2(SP),R1	;RESTORE BUFFER ADDRESS
	MOV	(R1)+,(R5)+	;SET BYTE COUNT/LINE NUMBER
	MOV	R1,(R5)+	;SET UP BUFFER ADDRESS
	MOV	.STUSR,(R5)+	;SAVE USER DATA
	MOV	R2,(R5)+	;SET ADDRESS
	MOV	R4,-(SP)	;SAVE R4
	MOV	R0,R1		;SET UP TO ENTER NODE
	MOV	#TO10Q,R4	;START TO 10 Q IF NECESSARY
	CMP	@R4,R4		;CHECK TO SEE IF ALREADY GOING
	BNE	30$		;YES -- JUST ENTER IN Q
	MOV	R1,R4		;NO -- SET NODE ADDRESS
	JSR	PC,STNTQ	;START QUEUE
30$:	MOV	TO10Q+2,R4	;ENTER Q
	JSR	PC,..NADD	;ADD NODE
	MOV	(SP)+,R4	;RESTORE REGISTERS
	MOV	(SP)+,R1
	MOV	(SP)+,R0
	MOV	(SP)+,R5
	CLC			;CLEAR C
	RTS	PC		;RETURN TO CALLER