Google
 

Trailing-Edge - PDP-10 Archives - BB-X116A-BB_1984 - nrtser.mac
There are 3 other files named nrtser.mac in the archive. Click here to see a list.
	TITLE NRTSER - DECnet Network Remote Terminal Service V027
	SUBTTL W. G. Nichols, 19 JULY 83

	SALL

	SEARCH D36PAR,SCPAR,NETPRM,F,S,MACSYM

	D36SYM			;Fix problems with MACSYM in DECnet-36

	$RELOC
	$HIGH


;This software is furnished under a license and may be only used
;  or copied in accordance with the terms of such license.
;
.CPYRT<
COPYRIGHT (C) 1982,1984 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
>



;DATE		LOAD	EDIT
;----		----	----
;9-FEB-82	70132	001
;16-FEB-82	70133	002
;23-FEB-82	70134	003
;10111
;02-MAR-82	70135	004
;09-MAR-82	70136	005
;30-MAR-82	70141	006
;13-APR-82	70142	007
;27-APR-82	70144	010
;25-MAY-82	70145	011
;08-JUN-82	70152	012
;22-JUN-82	70154	013
;29-JUN-82	70155	014
;13-JUL-82	70157	015
;10-AUG-82	70163	016
;17-AUG-82	70164	017
;21-SEP-82	70171	020
;5-OCT-82	70173	021
;12-OCT-82	70174	022
;09-NOV-82	70111	023
;10476
;18-APR-83	70136	024
;14-JUN-83	70145	025
;12-JUL-83	70151	026
;10836
;19-JUL-83	70152	027
;10857
;
VNRTSER==:027


	NRTOBJ==^D23		;NRTSRV OBJECT TYPE
	NRTINT==3		;JIFFIES BETWEEN NRT SERVICE CHECKS
	INACTIVITY==^D120	;SECS 'TIL INACTIVE LINK IS DISCONNECTED


; The length of the record and the max record we will send are separately
; defined so that the compiled-in record buffer can be larger than the
; actual record we send so that we can poke the max to a larger value for
; performance tests to systems we know can handle the size.

	NRTROL==^D500		;BYTES IN OUTPUT NRT RECORD
	NRTMXC==^D500		;MAX LENGTH OF RECORD WE WILL SEND
	NRTRIL==^D50		;BYTES IN INPUT NRT RECORD

IFG NRTMXC-NRTROL,NRTMXC==NRTROL ;ASSURE WE DON'T GET CARRIED AWAY
	SUBTTL	Table of contents
COMMENT @

                         Theory of Operation

Except for NRTINI, called by SYSINI, NRTSER runs only at clock level,
and then only on one CPU, so it needs little more interlocking.

Every jiffy, NRTSTO gets called along with all the other queued
drivers in the system via a call in CLOCK1 through .CPSTO.  NRTSTO
checks that it is on the boot CPU and then counts down an interval
timer.  The timer is reinitialized to some small number, say 3, every
time it expires.

NRTSTO only runs after its interval counter expires for two reasons:
it imposes less overhead if it runs less often, and it lets more input
& output build up and thus fills the DECnet messages better than it
would if it ran more frequently.  It is important that it run often
enough that the user not see any delay, the optimum setting seems to
be around 3 to 5 jiffies.

When the interval timer expires, NRTSTO checks two queues for service
requests:

1)	NRTSTO calls TOTAKE to dequeue any LDBs which may have output
	pending.  NRTSTO loops over these LDBs, calling NRTLKS
	(NRT Link Service) on each.  If an LDB has output available
	and the associated DECnet link cannot take any output, NRTLKS
	just forgets about it:  it will get a DECnet 'interrupt' from
	that link when output is again OK.

2)	NRTSTO then calls SCTPSQ to see if there has been any DECnet
	activity.  This activity could be: a) input available, b)
	output newly OK on this link, or c) the link has changed
	state.

@
	SUBTTL	Definitions -- External References

;ENTRY declarations for LINK

	ENTRY NRTSTO		;CALLED VIA .CPSTO EVERY JIFFY

;These are the external references to the D36COM library of routines.

	EXT DNSWDS		;SMEAR SOME WORDS

;Here are the references to SCLINK.

	EXT SCTNSF		;NSP. FUNCTION PROCESSING (Section 1)
	EXT MAKSJB		;MAKE AN SJB
	EXT SCTWKQ		;ENQUEUE THIS SLB FOR SCTPSQ CALL
	EXT SCTPSQ		;DEQUEUE NEXT SLB FOR PSI INTERRUPT

;Here are some external references to TOPS-10 things.

	EXT CPOPJ		;RETURN
	EXT CPOPJ1		;SKIP RETURN
	SUBTTL Register & Macro Definitions

;NRTSER uses standard TOPS-10 register definitions with the exception
;that R is redefined as CX, the super-temp for macros.
;
;The register defintions from D36PAR are ignored herein.

	CX==R		;SUPER-TEMP AC FOR MACROS
	.SAC==CX	;SOME USE THIS NAME INSTEAD


;Register Conventions in NRTSER
;
;	M usually points to an SAB, SCLINK arg block
;	W usually points to a NRB, NRT data block
	SUBTTL NRT Data Base Definitions

;The NRB is the NRT Data Block.  One is allocated for each active
;link to hold data associating the DECnet link with an LDB.

BEGSTR NR			;USUALLY INDEXED BY W
	WORD LDB		;PTR TO ASSOCIATED LDB
	FIELD FLG,6		;FLAGS
	  BIT CFG		;SET IF CONFIG MSG HAS BEEN SENT
	  BIT REL		;THIS NRB IS BEING RELEASED
	FIELD CHN,12		;DECnet CHANNEL NUMBER
	HWORD STS		;CURRENT STATUS OF DECnet LINK
	HWORD SIZ		;MAX CHARS IN A SEGMENT ON THIS LINK
	HWORD INA		;INACTIVITY TIMER
ENDSTR
	SUBTTL	Impure Storage

	$LOW			;IMPURE STUFF

NRTDFT::EXP <FLD(^D9,PDGOL) ! FLD(^D16,PDDQT) ! FLD(^D50,PDIPR)>
NRTINA:	EXP	INACTIVITY	;NUMBER OF SECONDS INACTIVITY ALLOWED
NRTINL:	EXP	NRTINT		;NUMBER OF JIFFIES BETWEEN NRT SERVICES
NRTINC:	BLOCK	1		;NRT INTERVAL COUNTER, SEE NRTSTO
NRTMAX::EXP	NRTMXC		;MAX SIZED RECORD WE'LL SEND (POKABLE)
NRTRTQ:	BLOCK	1		;QUEUE HEADER FOR LDBQUE
NRTPSQ:	BLOCK	1		;NON-ZERO IF DECnet NEEDS SERVICE
NRTCWL::BLOCK	1		;NUMBER OF LINKS IN CW STATE
NRTCHP::BLOCK	1		;POINTER TO NRT CHANNEL TABLE
NRTCHL:	BLOCK	1		; AND ITS LENGTH (WORDS)
NRTSJP::BLOCK	1		;PTR TO NRT'S SJB (ACCESS FROM SEC 1)
NRTSAP:	BLOCK	1		;PTR TO NRT'S SAB (SEC 0/1 ADDR)
NRTBLW:	BLOCK	1		;SAVED NRB PTR FOR BLOCKED LINK
NRTBLP:	BLOCK	2		;SAVED BYTE PTR "    "      "
NRTBLC:	BLOCK	1		;SAVED BYTE COUNT "  "      "
NRTRCO:	BLOCK	<<NRTROL+3>/4>	;PLACE TO BUILD OUTPUT RECORD
NRTRCI:	BLOCK	<<NRTRIL+3>/4>	;PLACE TO BUILD INPUT RECORD

	$HIGH
	SUBTTL LDBISR Dispatch Table

NRTDSP::JRST	CPOPJ##		;( 0)ILLEGAL NOW.  DON'T USE!!
	JRST	CPOPJ##		;( 1)MODEM CONTROL
	JRST	NRTSEC		;( 2)ONCE A SECOND CALL (NOT PER TTY)
	JRST	CPOPJ##		;( 3)INITIALIZE
	JRST	CPOPJ##		;( 4)CHANGE HARDWARE PARMS
	JRST	CPOPJ##		;( 5)LINE PARM CONTROL
	JRST	CPOPJ##		;( 6)SET TERMINAL ELEMENT
	JRST	CPOPJ##		;( 7)STUFF FOR REMOTE TERMINALS
	JRST	CPOPJ1##	;(10)IS LINE DEFINED ON STATION (YES)


;Codes passed to Remote Terminal routine (code 7)

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

;Here to set up NRT host object for DECnet
;
;Call:
;	RET			;ALWAYS
;
;Here to initialize the NRT data base

NRTINI::SAVEAC <M,W>		;CALLED FROM SYSINI
	SEC1			;NRTSER RUNS IN SECTION 1
	HLRE T1,NETRTY##	;GET LENGTH OF AOBJN PTR TO NET LDBS
	MOVMS T1		;MAKE POSITIVE
	AOJ T1,			;LEAVE ROOM FOR RELEASE TIMING
	MOVEM T1,NRTCHL		;SAVE CHANNEL TABLE LENGTH
	CALL NRTGWD		;GET WORDS FOR OUR CHANNEL TABLE
	  BUG. HLT,NRTSJM,NRTSER,SOFT,<No memory for NRT's SJB>,,<

Cause:	This BUG is not documented yet.

>,NRTINI
	MOVEM T1,NRTCHP		;STORE POINTER TO CHANNEL TABLE

	MOVX T1,SA.LEN		;LENGTH OF AN SAB
	CALL NRTGWD		;GET WORDS FOR OUR SA BLOCK
	  BUG. HLT,NRTSAB,NRTSER,SOFT,<No memory for NRT's SAB>,,<

Cause:	This BUG is not documented yet.

>,NRTINI
	MOVEM T1,NRTSAP		;STORE POINTER TO SCLINK ARG BLK
	MOVEM T1,M		;NORMALLY USE M TO POINT TO SAB

;We will elect No Flow Control on incoming links.
;		Default Goal		Quota		Input %
	MOVE T1,NRTDFT		;GET DEFAULT GOAL,QUOTAS
	SETZM NRTSJP		;IN CASE WE FAIL, SIGNAL TO OTHERS
	CALL MAKSJB##		;GO MAKE AN SJB
	  BUG. HLT,NRTSJB,NRTSER,SOFT,<No memory for NRT's SJB>,,<

Cause:	This BUG is not documented yet.

>,NRTINI
	SETONE SJPRV,(T1)	;TURN ON PRIVED BIT IN SJB
	MOVEM T1,NRTSJP		;SAVE POINTER TO OUR SJB

	STOR M,SJSAB,(T1)	;SAVE SAB PTR FOR SCLINK
	RET			;RETURN
	SUBTTL NRTSTO - Called every Jiffy via .CPSTO

;Called every jiffy to handle DECnet Network Remote Terminals
;
;Call:
;	RET			;ALWAYS
;
;Changes M,W,U and T1 through T4

NRTSTO::
IFN FTMP,<XCT .CPSK0##		;SKIP IF WE'RE ON POLICY CPU
	  RET			;NO, ONLY RUN ONCE A JIFFY!
	 >
	SEC1			;NRTSER RUNS IN SECTION 1
	SOSG NRTINC		;HAS INTERVAL COUNTER EXPIRED YET?
	SKIPN NRTSJP		;YES, HAS NRTINI BEEN CALLED?
	RET			;NO
	MOVE T1,NRTINL		;YES, GET INTERVAL LENGTH
	MOVEM T1,NRTINC		;REINITIALIZE THE INTERVAL COUNTER

	SKIPE NRTBLW		;IS THERE A BLOCKED LINK?
	JRST [	CALL NRTUNB	;  YES, UNBLOCK IT
		  JRST NRTST3	;  STILL BLK'D, SEE IF WE CAN FREE ANY
		JRST .+1]	;ALL CLEAR NOW, TRY FOR MORE OUTPUT
	SKIPN NRTCWL		;ANY CONNECT WAITERS?
	CALL NRTNEP		;NO, MAKE ANOTHER IF WE CAN

;We know that we can safely take at least one link with TOTAKE, since
;there is now no other blocked link, so the worst that can happen
;is that this link will become blocked and we'll have to try it again.

NRTST1:	MOVEI T1,NRTRTQ		;GET THE QUEUE HEADER
	S0CALL TOTAKE##		;GET U := TERMINAL NEEDING SERVICE
	  JRST NRTST2		;IF NONE, THEN ALL DONE
	SKIPE W,LDBNRT##(U)	;GET POINTER TO ITS NRB
	CALL NRTLKS		;SERVICE THE LINK, IF ITS STILL THERE
	JRST NRTST1		;GO SEE IF ANY MORE TERMINALS TO START

;Loop over lines DECnet wants to service

NRTST2:	SETZ T1,		;LOAD UP A ZERO
	EXCH T1,NRTPSQ		;CLEAR FLAG SAYING DECnet WANTS US
	JUMPE T1,NRTST4		;LEAVE IF DECnet DIDN'T WANT SERVICE

NRTST3:	MOVE T1,NRTSJP		;POINTER TO NRT'S SJB (EXTENDED ADDR)
	CALL SCTPSQ##		;ANY SERVICE NEEDED? (EXTENDED CALL)
NRTST4:	  RET			;NO, ALL DONE FOR THIS INTERVAL
	HRRZ T1,T2		;YES, GET CHANNEL NUMBER
	MOVE T3,T1		;COPY CHANNEL NUMBER
	ADD T3,NRTCHP		;ADD IN BASE ADDR OF CHANNEL TABLE
	SKIPG W,(T3)		;GET PTR TO NRB, ANYTHING THERE?
	JRST NRTST3		;NO, NO LONGER INTERESTED
	OPSTR <CAME T1,>,NRCHN,(W) ;CHECK CHANNEL NUMBER
	  BUG. CHK,NRTSET,NRTSER,SOFT,<SCTPSQ returned wrong channel info>,,<

Cause:	This BUG is not documented yet.

>,NRTST3
	CALL NRTLKS		;SERVICE THE LINK
	JRST NRTST3		;LOOP OVER LINKS NEEDING SERVICE
	SUBTTL NRTSEC - Called every second via .CPSTO

;Called every second to handle DECnet Network Remote Terminals
;
;Call:
;	U/ Pointer to LDB
;	RET			;ALWAYS
;
;Changes M,W,U and T1 through T4
;
;This routine is called at clock level (as are all NRTSER routines
;except NRTWAK) so it does not need an interlock from NRTSTO.

NRTSEC::SAVEAC <W,U,P1,P2>
IFN FTMP,<
	XCT .CPSK0##		;SKIP IF WE'RE ON POLICY CPU
	RET			;NO, ONLY RUN ONCE A SECOND!
>
	SEC1			;NRTSER RUNS IN SECTION 1
	SKIPN NRTBLW		;ANY BLOCKED LINK?
	JRST NRTSE1		;NO
	CALL NRTUNB		;YES, TRY TO UNBLOCK IT
	  RET			;CAN'T, DECnet IS BLOCKED
NRTSE1:

;The channel table may be in an extended section.

	MOVE P1,NRTCHL		;GET LENGTH OF CHANNEL TABLE
	MOVE P2,NRTCHP		;GET ADDRESS OF CHANNEL TABLE
NRTSE2:	SKIPE W,(P2)		;ANY NRB ON THIS CHANNEL?
	CALL INACHK		;YES, CHECK FOR INACTIVITY
	AOJ P2,			;POINT TO NEXT NRB
	SOJG P1,NRTSE2		;LOOP OVER ALL CHANNELS
	RET
	SUBTTL INACHK - Check an NRB for Inactivity

;Called every second to handle DECnet Network Remote Terminals
;
;Call:
;	W/ Pointer to NRB
;	RET			;ALWAYS
;
;Changes M,W,U and T1 through T4

INACHK:	LOAD U,NRLDB,(W)	;GET POINTER TO ASSOCIATED LDB
	JUMPE U,CPOPJ		;NO PROBLEMS IF NO LDB
	HRRZ T1,LDBDDB##(U)	;YES, IS THIS LDB ASSIGNED?
	JUMPN T1,CPOPJ		;LEAVE IT ALONE IF SO
IFN FTNET,<
	MOVE T1,LDBREM##(U)	;GET THE REMOTE STATUS WORD
	TLNE T1,LRLVTM##	;IS IT SET HOSTED AWAY?
	RET			;YES, LEAVE IT ALONE
>;END OF IFN FTNET

;Now we've decided link is eligible for forced disconnect

	OPSTRM <AOS T1,>,NRINA,(W) ;INCREMENT SECONDS OF INACTIVITY
	CAMG T1,NRTINA		;ABOVE INACTIVITY THRESHOLD?
	RET			;NO

;Here to close an inactive link

	MOVE M,NRTSAP		;POINT TO NRT'S SAB
	MOVEI T1,DSCLEN		;LENGTH OF MESSAGE TO SEND
	STOR T1,SAAA1,(M)	;STORE AS FIRST ARG
	MOVE T1,[POINT 7,DSCMSG] ;BYTE POINTER TO DISCONNECT MSG
	STOR T1,SAAA2,(M)	;STORE BYTE POINTER
	SETONE SAEOM,(M)	;SEND THIS MESSAGE NOW

	MOVX T1,.NSFDS		;DATA SEND FUNCTION
	MOVEI T2,4		;NUMBER OF ARG WORDS
	CALL NRTNSF		;SEND CONFIG MESSAGE
	  JFCL			;IGNORE ERROR RETURN, DISCON ANYWAY

	MOVE M,NRTSAP		;POINT TO NRT'S SAB
	MOVX T1,.NSFSD		;SYNCHRONOUS DISCONNECT FUNCTION
	MOVEI T2,2		;NUMBER OF ARGS PASSED
	CALL NRTNSF		;INITIATE THE DISCONNECT PROCESS
	  JFCL			;IGNORE ERROR RETURN
	RET

DSCMSG:	ASCII "
[ Idle line disconnected by host ]
"
DSCLEN==<.-DSCMSG>*5		;LENGTH INCLUDES SOME NULLS, SO WHAT?
	SUBTTL NJFRxx - Routines to handle each DECnet link state

;Routine to service a link according to its DECnet state
;Call
;	W/ Pointer to NRB
;	U/ Pointer to LDB
;
;Return:
;	RET			;ONLY RETURN

NRTLKS:	SETZRO NRINA,(W)	;ZERO THE INACTIVITY TIME
	TMNE NRREL,(W)		;IS THIS NRB BEING RELEASED?
	CALLRET NRTREL		;YES, COMPLETE THE PROCESS

	MOVE M,NRTSAP		;POINT TO NRT'S SAB
	MOVX T1,.NSFRS		;READ STATUS FUNCTION CODE
	MOVEI T2,3		;NUMBER OF ARGS PASSED
	CALL NRTNSF		;READ LINK STATUS, STORE IT IN NRB
	  CALLRET NRTREL	;ERROR, CLEAN UP
	LOAD T1,NRSTS,(W)	;GET LINK'S STATUS WORD
	LOAD T1,NSSTA,+T1	;GET THE STATE FIELD FROM STATUS
	CAILE T1,NJFTLN		;A STATE WE UNDERSTAND?
	SETZ T1,		;NO, CALL ILLEGAL STATE BUG.
	CALLRET @NJFTBL(T1)	;CALL ROUTINE APPROPRIATE TO LINK STATE


DEFINE LNKSTA(code),<
	IFN .-NJFTBL-.NSS'code,<PRINTX NJFTBL is in wrong order>
	IFIW NJFR'code		;;ADDRESS OF NJF ROUTINE
>

NJFTBL:	IFIW NJFRIL		;ILLEGAL STATE
	LNKSTA CW		;CONNECT WAIT
	LNKSTA CR		;CONNECT RECEIVED
	LNKSTA CS		;CONNECT SENT
	LNKSTA RJ		;REMOTE REJECTED CONNECT INIT
	LNKSTA RN		;LINK IS UP AND RUNNING
	LNKSTA DR		;DISCONNECT RECEIVED
	LNKSTA DS		;DISCONNECT SENT
	LNKSTA DC		;DISCONNECT CONFIRMED
	LNKSTA CF		;NO CONFIDENCE
	LNKSTA LK		;NO LINK
	LNKSTA CM		;NO COMMUNICATION
	LNKSTA NR		;NO RESOURCES
NJFTLN==.-1-NJFTBL		;LENGTH OF TABLE

	PURGE LNKSTA

NJFRCS:				;CONNECT SENT
NJFRIL:	BUG. CHK,NRTILS,NRTSER,SOFT,<NRT link in unexpected state>,,<

Cause:	This BUG is not documented yet.

>,NRTREL

NJFRRJ:				;REJECTED, WAITING FOR DC
NJFRDS:				;DISCONNECT SENT, WAITING FOR DC
NJFRCW:	RET			;CONNECT WAIT, WAITING FOR A CONNECT
;NJFRCR - Jiffy Service Routine for a link in CONNECT RECEIVED state
;
;Call:
;	W/ Pointer to Link's NRB
;	RET			;ALWAYS
;
;Now we have someone interested in this link, try to get a LDB for
;it.  If that succeeds, accept the link.

NJFRCR:				;CONNECT RECEIVED STATE PROCESSOR
	SOS NRTCWL		;ONE LESS LINK IN CW STATE
	MOVX T1,RSNRNS		;REMOTE NODE SHUT DOWN REASON CODE
	MOVE T2,STATES##	;GET THE SCHEDULE BITS
	TRNE T2,ST.NRT		;NO REMOTE TERMINALS?
	JRST NJRCRF		;YES, GO ANNOUNCE THE FAILURE

;Get a TTY for this link

	CALL NGTLDB		;GET A NRT LDB
	  JRST NJRCRF		;FAILED, REASON CODE IN T1

;Accept the Connect

	MOVE M,NRTSAP		;POINT TO NRT'S SAB
	SETZRO SAAA1,(M)	;NO USER DATA
	MOVEI T1,NRTROL		;GET MAX BYTES IN OUR RECORD
	STOR T1,SAAA2,(M)	;USE A MSG SEGMENT NO BIGGER THAN THAT
	MOVX T1,NSF.C0		;ELECT NO FLOW CONTROL FOR INPUT
	STOR T1,SAAA3,(M)	;ARG #3
	MOVX T1,.NSFAC		;ACCEPT FUNCTION CODE
	MOVEI T2,5		;NUMBER OF ARGS PASSED
	CALL NRTNSF		;ACCEPT THE CONNECT
	  CALLRET NRTREL	;ERROR, CLEAN UP

;Read link status to find out segment size

	MOVE M,NRTSAP		;POINT TO NRT'S SAB
	MOVX T1,.NSFRS		;READ STATUS FUNCTION CODE
	MOVEI T2,3		;NUMBER OF ARGS PASSED
	CALL NRTNSF		;READ LINK STATUS
	  CALLRET NRTREL	;ERROR, CLEAN UP
	LOAD T1,SAAA1,(M)	;GET LINK'S SEGMENT SIZE
	CAMLE T1,NRTMAX		;IS THAT TOO BIG FOR US?
	MOVE  T1,NRTMAX		;YES, LOAD UP OUR MAX
	CAILE T1,NRTROL		;HAS SOMEONE POKED THAT TOO BIG?
	MOVEI T1,NRTROL		;YES, LIMIT TO SIZE OF RECORD
	STOR T1,NRSIZ,(W)	;STORE FOR NRTOUT

	CALLRET NRTNEP		;HANG OUT A NEW CONNECT WAIT LINK

;We'll send a configuration message when we get a data request.
;Here on failure in Connect Received state processing

NJRCRF:	MOVE M,NRTSAP		;POINT TO NRT'S SAB
	MOVX T1,.NSFRJ		;REJECT FUNCTION CODE
	MOVEI T2,2		;NUMBER OF ARGS PASSED
	CALL NRTNSF		;REJECT THE CONNECT
	  CALLRET NRTREL	;RELEASE THE LINK
	RET			;WE'LL RELEASE LINK WHEN DC COMES IN


;The configuration message sent out when we accept a connect

CFGLEN==10			;BYTES IN CONFIG MESSAGE
CFGMSG:	BYTE(8) 1,1,0,0,11,0,10,0
;	Config--' ^ ^ ^  ^ ^  ^ ^
;		  ? ? ?  | ?  | ?
;	System=TOPS10----'    |
;	Protocol=TOPS20-------'
;NJFRRN - Jiffy Service Routine for a link in RUN state
;
;Call:
;	W/ Pointer to Link's NRB
;	RET			;ALWAYS
;
;The link is running, see if any traffic needs to be transferred.

NJFRRN:				;LINK IS UP AND RUNNING
	LOAD U,NRLDB,(W)	;GET PTR TO LDB

;First, try some input, may free up some DECnet buffers for output

	LOAD T1,NRSTS,(W)	;GET DECnet STATUS LAST TIME WE HEARD
NJFRR1:	TXNN T1,NSNDA		;NORMAL DATA AVAILABLE?
	JRST NJFRR2		;NO, TRY OUTPUT
	CALL NRTIN		;YES, TRY TO READ SOME
	  JFCL			;IGNORE ERROR HERE

;See if there is any output requested and allowed now

NJFRR2:	LOAD T1,NRSTS,(W)	;GET DECnet STATUS LAST TIME WE HEARD
	TXNN T1,NSNDR		;NORMAL DATA REQUESTED?
	RET			;NO, ALL DONE WITH THIS LINK

	TMNN NRCFG,(W)		;HAVE WE SENT A CONFIG MSG YET?
	JRST [	CALL SNDCFG	;NO, DO SO NOW
		  RET		;ERROR, DON'T LOOP FOREVER
		JRST NJFRR2]	;SEE IF WE CAN STILL SEND MORE

	CALL NRTOUT		;YES, TRY TO SEND SOME
	  JFCL			;BLOCKED, CAN'T DO ANY OUTPUT
	RET			;RETURN
;SNDCFG - Send a configuration message
;
;Call:
;	W/ Pointer to Link's NRB
;	U/ Pointer to LDB
;
;Return:
;	RET			;ERROR
;	RETSKP			;SUCCESS
;
;Send a configuration message

SNDCFG:	MOVE M,NRTSAP		;POINT TO NRT'S SAB
	MOVEI T1,CFGLEN		;LENGTH OF MESSAGE TO SEND
	STOR T1,SAAA1,(M)	;STORE AS FIRST ARG
	MOVE T1,[POINT 8,CFGMSG] ;BYTE POINTER TO CONFIG MSG
	STOR T1,SAAA2,(M)	;STORE BYTE POINTER
	SETONE SAEOM,(M)	;SEND THIS MESSAGE NOW

	MOVX T1,.NSFDS		;DATA SEND FUNCTION
	MOVEI T2,5		;NUMBER OF ARG WORDS
	CALL NRTNSF		;SEND CONFIG MESSAGE
	  RET			;ERROR, MAYBE TRY AGAIN LATER
	TMNE SAAA1,(M)		;DID DECnet SEND THE WHOLE THING?
	BUG. CHK,NRTPCL,NRTSER,SOFT,<Partial Configuration Msg Loss>,,<

Cause:	This BUG is not documented yet.

>,CPOPJ

	SETONE NRCFG,(W)	;CONFIGURATION MSG HAS BEEN SENT
	RETSKP
;NRTOUT - Try to do some output from SCNSER to DECnet
;
;Call, when DECnet is ready to receive from us:
;	W/ Pointer to Link's NRB
;	U/ Points to LDB
;Return:
;	RET			;IF FATAL ERROR
;	RETSKP			;SUCCESS

NRTOUT:	SAVEAC <P1,P2>
NRTOT1:	LOAD P1,NRSIZ,(W)	;GET MAX BYTES IN A SEGMENT ON LINK
	MOVE P2,[POINT 8,NRTRCO] ;BYTE POINTER TO RECORD WE'LL SEND
NRTOT2:	S0CALL XMTCHR##		;GET A CHAR IN T3
	  JRST NRTOT3		;NO MORE, SEND WHAT WE COLLECTED
	IDPB T3,P2		;STORE BYTE
	SOJG P1,NRTOT2		;GET MORE WHILE THERE'S ROOM

	LOAD P2,NRSIZ,(W)	;GET MAX AGAIN
	CALL NRTOTS		;SEND THAT MUCH
	  RET			;BLOCKED, TRY AGAIN LATER
	LOAD T1,NRSTS,(W)	;GET DECnet STATUS AFTER LAST SEND
	TXNN T1,NSNDR		;NORMAL DATA STILL REQUESTED?
	RETSKP			;NO, SUCCESS RETURN NOW
	JRST NRTOT1		;SUCCESS, TRY FOR MORE

NRTOT3:	LOAD P2,NRSIZ,(W)	;GET MAX AGAIN
	SUB P2,P1		;CALC NUMBER WE COPIED
	JUMPLE P2,CPOPJ1	;SUCCESS RETURN NOW IF NONE
				;FALL THROUGH TO NRTOTS TO SEND

;Subroutine to send data for NRTOUT

NRTOTS:	MOVE M,NRTSAP		;POINT TO NRT'S SAB
	STOR P2,SAAA1,(M)	;STORE LENGTH OF DATA TO SEND
	MOVX T1,<<POINT 8,>!1B12> ;MAKE A 2-WORD BYTE POINTER
	STOR T1,SAAA2,(M)	;STORE AS FIRST WORD OF BYTE POINTER
	XMOVEI T1,NRTRCO	;GET EXTENDED ADDR OF RECORD
	STOR T1,SAAA3,(M)	;STORE AS 2ND WORD OF BYTE POINTER
	SETONE SAEOM,(M)	;SET THE END-OF-MESSAGE FLAG

	MOVX T1,.NSFDS		;DATA SEND FUNCTION
	MOVEI T2,5		;NUMBER ARGS WE'RE PASSING
	CALL NRTNSF		;SEND THE DATA TO DECnet
	  JRST NRTOTE		;ERROR, GO DEAL WITH IT
	LOAD T1,SAAA1,(M)	;GET COUNT OF BYTES LEFT TO SEND
	JUMPE T1,CPOPJ1		;SUCCESS RETURN NOW IF ALL SENT

;Here when the link is blocked (DECnet is out of buffers)

	MOVEM W,NRTBLW		;SAVE PTR TO BLOCKED LINK
	MOVEM T1,NRTBLC		;SAVE COUNT OF BYTES STILL TO SEND
	LOAD T1,SAAA2,(M)	;GET BYTE POINTER
	LOAD T2,SAAA3,(M)	;GET SECOND WORD OF BYTE POINTER
	DMOVEM T1,NRTBLP	;SAVE BYTE PNTR FROM WHICH TO SEND
	RET			;FAIL RETURN

NRTOTE:	LOAD T1,SAAST,(M)	;GET NEW STATUS
	LOAD T1,NSSTA,+T1	;GET THE STATE FIELD FROM STATUS
	CAIN T1,.NSSRN		;IN RUN STATE?
	BUG. CHK,NRTOUD,NRTSER,SOFT,<NRT output to DECnet failed>,,<

Cause:	This BUG is not documented yet.

>,NRTREL
	RETSKP			;DON'T COMPLAIN NOW, ITS CLOSING
;NRTUNB - Unblock a link which is blocked trying to output
;
;Call:	NRTBLW/ Pointer to NRB of blocked link
;	NRTBLC/ Count of bytes still to send
;	NRTBLP/ Two-word byte pointer from which to send
;
;Return:
;	RET		;If link still blocked, NRTBLx updated
;	RETSKP		;If link is now free, NRTBLW zeroed
;
;Uses T1-T4, M and the SAB

NRTUNB:	SAVEAC W
	MOVE M,NRTSAP		;POINT TO NRT'S SAB
	SKIPN W,NRTBLW		;GET POINTER TO BLOCKED NRB
	RETSKP			;NONE?  LEAVE SUCCESSFULLY
	MOVE T1,NRTBLC		;GET COUNT OF BYTES TO SEND
	STOR T1,SAAA1,(M)	;STORE IN SAB
	DMOVE T1,NRTBLP		;GET DOUBLE-WORD BYTE PTR
	STOR T1,SAAA2,(M)	;PASS IN SAB
	STOR T2,SAAA3,(M)	;PASS SECOND WORD OF BYTE PTR
	SETONE SAEOM,(M)	;SET THE END-OF-MESSAGE FLAG

	MOVX T1,.NSFDS		;DATA SEND FUNCTION
	MOVEI T2,5		;NUMBER ARGS WE'RE PASSING
	CALL NRTNSF		;SEND THE DATA TO DECnet
	  JRST NRTOTE		;ERROR, GO DEAL WITH IT
	LOAD T1,SAAA1,(M)	;GET COUNT OF BYTES LEFT TO SEND
	JUMPE T1,NRTUN1		;SUCCESS RETURN NOW IF ALL SENT

;Here when the link is still blocked (DECnet is out of buffers)

	MOVEM T1,NRTBLC		;SAVE NEW COUNT OF BYTES STILL TO SEND
	LOAD T1,SAAA2,(M)	;GET NEW BYTE POINTER
	LOAD T2,SAAA3,(M)	;GET NEW BYTE POINTER (2ND WORD)
	DMOVEM T1,NRTBLP	;SAVE BYTE PNTR FROM WHICH TO SEND
	RET			;FAIL RETURN

;Here when the link is unblocked

NRTUN1:	SETZM NRTBLW		;NO LINK IS NOW BLOCKED
	RETSKP			;SUCCESS RETURN
;NRTIN - Try to do some input from DECnet to SCNSER
;
;Call, when DECnet has something for us to read:
;	W/ Pointer to Link's NRB
;	U/ Points to LDB
;Return:
;	RET			;IF FATAL ERROR
;	RETSKP			;SUCCESS

NRTIN:	SAVEAC <P1,P2,P3>
NRTIN1:	MOVE M,NRTSAP		;POINT TO NRT'S SAB
	MOVEI T1,NRTRIL		;GET MAX CHARS WE'LL ALLOW AT ONCE
	STOR T1,SAAA1,(M)	;STORE LENGTH OF DATA TO SEND
	MOVX T1,<<POINT 8,>!1B12> ;MAKE A 2-WORD BYTE POINTER
	STOR T1,SAAA2,(M)	;STORE AS FIRST WORD OF BYTE POINTER
	XMOVEI T1,NRTRCI	;GET EXTENDED ADDR OF INPUT RECORD
	STOR T1,SAAA3,(M)	;STORE AS 2ND WORD OF BYTE POINTER
	SETZRO SAEOM,(M)	;DON'T INSIST ON A WHOLE RECORD

	MOVX T1,.NSFDR		;DATA RECEIVE FUNCTION
	MOVEI T2,5		;NUMBER ARGS WE'RE PASSING
	CALL NRTNSF		;GET DATA FROM DECnet
	  JRST NRTINE		;ERROR, GO DEAL WITH IT

;Now we have some data, give it to SCNSER

	MOVE P1,[POINT 8,NRTRCI] ;GET BYTE POINTER TO NRT'S RECORD
	MOVEI P2,NRTRIL		;GET MAX WE SAID WE'D READ
	OPSTR <SUB P2,>,SAAA1,(M) ;CALC # OF CHARS WE GOT
	JUMPE P2,NRTIN3		;NONE?
	LDB P3,LDPLNO##		;GET LINE NUMBER FROM LDB
NRTIN2:	ILDB T3,P1		;GET NEXT CHARACTER FROM DECnet
	MOVE U,P3		;GET LINE NUMBER WE'RE FEEDING
	S0CALL RECINT##		;GIVE THE CHAR TO SCNSER
	SOJG P2,NRTIN2		;LOOP UNTIL ALL PASSED TO SCNSER

NRTIN3:	LOAD U,NRLDB,(W)	;RESTORE LDB POINTER TO U
	LOAD T1,NRSTS,(W)	;GET DECnet STATUS AFTER LAST SEND
	TXNE T1,NSNDA		;NORMAL DATA STILL AVAILABLE?
	JRST NRTIN1		;YES, GO GET IT
	RETSKP			;NO, SUCCESS RETURN NOW


;Here on DECnet error

NRTINE:	LOAD T1,SAAST,(M)	;GET NEW STATUS
	LOAD T1,NSSTA,+T1	;GET THE STATE FIELD FROM STATUS
	CAIN T1,.NSSRN		;IN RUN STATE?
	BUG. CHK,NRTINP,NRTSER,SOFT,<NRT Input to DECnet failed>,,<

Cause:	This BUG is not documented yet.

>,NRTREL
	RET			;DON'T COMPLAIN NOW, ITS CLOSING
;NJFRRN - Jiffy Service Routine for a link in DISCONNECT RECEIVED state
;
;Call:
;	W/ Pointer to Link's NRB
;	RET			;ALWAYS
;
;The link is in one of the "gone sour" states.  Close the link
;and free the TTY LDB.

NJFRDC:				;DISCONNECT CONFIRMED
NJFRDR:				;DISCONNECT RECEIVED
NJFRCF:				;NO CONFIDENCE
NJFRLK:				;NO LINK
NJFRCM:				;NO COMMUNICATION
NJFRNR:				;NO RESOURCES
	CALLRET NRTREL		;RELEASE THE LINK ALTOGETHER
;NRTNEP - Do an Enter Passive to hang out a new DECnet link
;
;Call:
;	NRTSAP/ Pointer to NRT's SAB
;	NRTSJP/ Pointer to NRT's SJB
;
;Return:
;	RET			;ALWAYS

NRTNEP:	SKIPE NRTCWL		;ANY LINKS ALREADY WAITING?
	RET			;YES, DON'T HANG OUT ANY MORE

	SAVEAC <M,W,P1>		;SAVE FOR SAB,NRB,CBLK POINTERS
	MOVE M,NRTSAP		;POINT TO NRT'S SAB
	MOVEI T1,NR.LEN		;LENGTH OF A NRB BLOCK
	CALL NRTGWD		;GET A NEW NRB
	  RET			;COULDN'T
	MOVE W,T1		;POINTER TO NRB

;Get and set up a connect block

	MOVEI T1,CB.LEN		;GET PLACE TO PUT CONNECT BLK
	CALL NRTGWD
	  JRST [MOVE T1,W	;CAN'T, DEALLOCATE NRB AS WELL
		CALLRET NRTFWD]	; FREE NRB
	MOVE P1,T1		;P1 POINTS TO CONNECT BLOCK
	MOVEI T1,PB.LEN		;LENGTH OF PDB
	STOR T1,PBSIZ,+CB.SRC(P1) ;STORE SIZE OF SOURCE PDB
	STOR T1,PBSIZ,+CB.DST(P1) ;STORE SIZE OF DEST PDB
	MOVEI T1,0		;GET FORMAT TYPE 0
	STOR T1,PBFOR,+CB.SRC(P1) ;STORE FORMAT OF SOURCE PDB
	STOR T1,PBFOR,+CB.DST(P1) ;STORE FORMAT OF DEST PDB
	MOVX T1,NRTOBJ		;GET NRTSRV'S OBJECT TYPE
	STOR T1,PBOBJ,+CB.SRC(P1) ;STORE OBJECT TYPE OF SOURCE PDB
	STOR T1,PBOBJ,+CB.DST(P1) ;STORE OBJECT TYPE OF DEST PDB

;Now set up the SAB for an Enter Passive

	STOR P1,SAAA1,(M)	;CONNECT BLK IS FIRST ARG
	STOR P1,SACBP,(M)	;STORE POINTER TO CONNECT BLOCK HERE TOO

	MOVX T1,.NSFEP		;ENTER PASSIVE FUNCTION CODE
	MOVEI T2,3		;NUMBER OF ARGS
	CALL NRTNSF		;ENTER PASSIVE
	  JRST NRTNEE		;CAN'T, RETURN MEMORY & LEAVE
	CAMLE T1,NRTCHL		;CAN WE HANDLE THIS CHANNEL NUMBER?
	JRST [	MOVX T1,.NSFRL	;NO, RELEASE THE CHANNEL & TRY
		MOVEI T2,2	; FOR ANOTHER LATER, WHEN DECnet
		CALL NRTNSF	; HAS FREED UP SOME LOWER NUMBERS
		JRST NRTNEE]	;RETURN MEMORY & LEAVE

;Now collect returned info not already stored by NRTNSF

	LOAD T1,SAACH,(M)	;GET NEW CHANNEL NUMBER
	STOR T1,NRCHN,(W)	;STORE CHANNEL NUMBER IN NRB
	ADD T1,NRTCHP		;CALC PTR TO CHANNEL TABLE ENTRY
	MOVEM W,(T1)		;STORE NEW NRB PTR IN CHANNEL TABLE
	AOS NRTCWL		;ONE MORE LINK IN CONNECT WAIT STATE
NRTNEX:	MOVE T1,P1		;GET POINTER TO CONNECT BLOCK
	CALLRET NRTFWD		;FREE IT

;Here on error when we have to deallocate an NRB

NRTNEE:	MOVE T1,W		;DEALLOCATE NRB AS WELL
	CALL NRTFWD		;FREE NRB
	JRST NRTNEX		;FREE CONNECT BLOCK AS WELL

	SUBTTL Subroutines -- NRTNSF - Call SCLINK's SCTNSF

;NRTNSF - Call SCLINK's SCTNSF and handle the return
;
; Call:
;	T1/ Function code
;	T2/ Number of Args not defaulted in SAB
;	M/ Extended pointer to filled-in SAB
;	W/ Pointer to NRB
;
; Return:
;	RET			;FAILED, CODE IN T1
;	RETSKP			;SUCCESS

NRTNSF:	STOR T1,SAAFN,(M)	;FUNCTION CODE
	STOR T2,SANAG,(M)	;STORE NUMBER OF ARGS

	SETONE SAEVA,(M)	;BUFFERS WE PASS WILL BE IN EVA
	MOVE T1,NRTSJP		;GET POINTER TO OUR SJB
	STOR T1,SASJB,(M)	;STORE THE ADDRESS OF THE SJB
	XMOVEI T1,NRTHBR	;POINT TO THE HIBER ROUTINE (BUG.)
	STOR T1,SAHBA,(M)	;STORE IN THE HIBER ADDRESS ARGUMENT
	XMOVEI T1,NRTWAK	;GET ADDRESS OF WAKE HANDLER
	STOR T1,SAWKA,(M)	; AND TELL SCLINK ABOUT IT

	LOAD T1,NRCHN,(W)	;GET CHANNEL NUMBER
	STOR T1,SAACH,(M)	;STORE IN SAB
	MOVE T1,M		;PASS SAB TO SCLINK
	CALL SCTNSF		;DO THE DECnet FUNCTION

	LOAD T1,SAERR,(M)	;GET THE ERROR CODE
	JUMPN T1,CPOPJ		;ERROR RETURN IF NON-ZERO
	LOAD T1,SAAST,(M)	;GET NEW LINK STATUS
	STOR T1,NRSTS,(W)	;STORE IN NRB
	RETSKP			;SUCCESS RETURN
	SUBTTL Subroutines -- NRTREL - Release a Link

;NRTREL - Release a link and all that goes with it.
;
; Call:	W/ Pointer to the NRB to release
;
; Return:
;	RET			;ALWAYS, NRB IS DEALLOCATED
;
; Uses: W

NRTREL:	SAVEAC <U,M>
	SETONE NRREL,(W)	;TELL NRTLKS THIS NRB IS DOOMED

	OPSTR <SKIPN U,>,NRLDB,(W) ;ANY LDB HERE?
	JRST NRTRL1		;NO

;Here when there is an LDB to be freed

IFN FTNET,<
	MOVE T1,LDBREM##(U)	;GET THE REMOTE STATUS WORD
	TLNE T1,LRLVTM##	;IS IT SET HOSTED AWAY?
	JRST [	SEC0		;YES, NETSER RUNS IN SECTION 0
		CALLRET VTMPRL##] ;TELL NETVTM TO RELEASE THIS
				; LINE.  WE'LL GET CALLED AGAIN LATER
				; AND FIND LDBREM(U) IS ZERO
				; BY WHICH TIME WE HOPE ITS BEEN
>;END OF IFN FTNET		; DISCONNECTED BY NETVTM

	S0CALL RMVTTY##		;DETACH AND CLEAN THE TTY DDB
	CALL NGVLDB		;THEN GIVE IT BACK TO GETLDB

;Here to free the associated DECnet link

NRTRL1:	MOVE M,NRTSAP		;POINT TO NRT'S SAB
	MOVX T1,.NSFRL		;RELEASE FUNCTION CODE
	MOVEI T2,2		;NUMBER OF ARGS PASSED
	CALL NRTNSF		;RELEASE THE CONNECT
	  JFCL			;IGNORE ERROR RETURN

	LOAD T1,NRCHN,(W)	;GET DECnet CHANNEL NUMBER
	ADD T1,NRTCHP		;INDEX INTO CHANNEL TABLE
	SETZM (T1)		;WE NO LONGER HAVE THIS CHANNEL OPEN

	MOVE T1,W		;ADDRESS OF NRB
	CALL NRTFWD		;FREE IT
	SETZ W,			;DON'T LET CALLERS USE W
	RET			;LINK IS RELEASED NOW
	SUBTTL Subroutines -- NGTLDB - Get an LDB for NRTSER

;NGTLDB - Get a remote LDB and make it mine
;
; Call:	W/ Pointer to NRB
;
; Return:
;	RET			;FAILED, REASON CODE IN T1
;	RETSKP			;SUCCESS, POINTER IN U
;
; Uses: W

NGTLDB:	SAVEAC <P1,W>		;P1 WILL POINT TO NRB
	MOVE P1,W		;PTR TO NRB

;Allocate an LDB

	SETZ W,			; TELL GETLDB WE HAVE NO ANF NDB
	NETOFF			;#LETS HAVE NO CONFLICT WITH ANF
	S0CALL GETLDB##		;#GET A REMOTE TTY LDB, POINTER IN U
	  JRST [NETON		;#CAN'T, ALLOW ANF AGAIN
		MOVX T1,RSNOTB	; OBJECT TOO BUSY REASON CODE
		RET]		; GO ANNOUNCE THE FAILURE
	HRRZS U			;#REMOVE FLAGS FROM LH SO INDEX
				;# WILL WORK IN EXTENDED SECTION
	MOVEI T1,LDRREM##	;#GET THE ANF-REMOTE FLAG
	ANDCAM T1,LDBDCH##(U)	;# AND CLEAR IT IN THIS LDB
	NETON			;#ALLOW ANF AGAIN

;Finish making this a NRT LDB

	MOVEI T1,NRTDSP		;NRT'S ISR DISPATCH TABLE
	HRRM T1,LDBISR##(U)	;STORE IN LDB FOR SCNSER
	MOVEI T1,NRTRTQ		;GET POINTER TO OUTPUT Q HEADER
	HRLZM T1,LDBQUE##(U)	;STORE FOR SCNSER (TOPOKE/TOTAKE)
	STOR U,NRLDB,(P1)	;REMEMBER OUR LDB
	MOVEM P1,LDBNRT##(U)	;STORE NRB PTR IN LDB TOO
	S0CALL LDBCLR##		;THIS MUST BE OUTSIDE OF NETOFF
	MOVSI T1,LDLNRT##	;BIT INDICATING NRT LINE
	IORM T1,LDBTTW##(U)	;STORE IN LDB FOR SCNSER TO LOOK AT
	MOVEI T1,APCNRT##	;GET NRTSER CODE
	DPB T1,LDPAPC##		;SET ASYNC PORT CHARACTERISTIC

;Initialize the TTY with .HELLO force command

	LDB T2,LDPLNO##		;SINCE THIS GUY SET-HOST'ED HERE,
	MOVE T2,LINTAB##(T2)	;  LET'S GREET HIM.  GET WORD WITH
	MOVEI T1,TTFCXR##	;  INITIA BIT SET, AND IF MONGEN WANTS
	TLNE T2,TTVINI##	;  INITIA RUN,
	MOVEI T1,TTFCXH##	;  THEN .HELLO ELSE .RESTART
	S0CALL TTFORC##		;GO FORCE .HELLO/.RESTART
	RETSKP 			;SUCCESS RETURN
	SUBTTL Subroutines -- NGVLDB - Give an LDB back to ANF

;NGVLDB - Give an LDB back to ANF
;
; Call:	U/ Pointer to LDB
;
; Return:
;	RET			;ALWAYS

NGVLDB:
	MOVEI T1,APCUNK##	;GET UNKNOWN STATUS CODE
	DPB T1,LDPAPC##		;SET ASYNC PORT CHARACTERISTICS
	MOVEI T1,REMDSP##	; GET ANF'S DISPATCH AGAIN
	MOVEI T2,NETRTQ##  	; GET ANF'S QUEUE HEADER
	MOVX  T4,LDRREM##	; GET ANF-REMOTE FLAG
	SCNOFF			; DON'T LET SCNSER GET CONFUSED
	SETZM   LDBNRT##(U)	;#DISENGAGE LDB FROM NRB
	HRRM T1,LDBISR##(U)	;#RESTORE ANF'S DISPATCH ADDR
	HRLM T2,LDBQUE##(U)	;#RESTORE ANF'S QUEUE HEADER

;LDRREM must be last here so that ANF will not get a half-deallocated
;LDB from GETLDB, which will not allocate an LDB whose @LDRREM is
;zero.

	IORM T4,LDBDCH##(U)	;#RETURN THIS LDB TO ANF
	SCNON			; LET SCNSER IN AGAIN
	RET			; ONLY RETURN
	SUBTTL Subroutines -- NRTWAK - Subroutine to do the WAKEs.

;NRTWAK - Called when SCLINK thinks we might want to wake the user
;
; Call:	T1/ Old Status,,PSI Mask
;	T2/ New Status,,Channel Number
;	T3/ Pointer to Session Control Job Block
;	T4/ Link identifier to pass to SCTWKQ
;
; Return:
;	RET			;Tells SCLINK not to queue SLB
;	RETSKP			;Tells SCLINK to queue SLB for SCTPSQ
;
; Uses: T1,T2,T3,T4
;
;SCLINK calls this routine (via SAWKA) when either the link
;state has changed or one of the status bits has changed from a
;zero to a one.
;
;This routine is called from extended section (on extended machine)
;so be careful not to change that.

NRTWAK:				;NRTNSF PASSES THIS ADDR TO SCLINK
	MOVE T1,T4		;PASS LINK IDENTIFIER TO SCTWKQ
	CALL SCTWKQ		;ASK SCLINK TO QUEUE THIS LINK FOR SCTPSQ
	SETOM NRTPSQ		;TELL NRTSTO DECnet IS INTERESTING NOW
	RET			;ONLY RETURN
	SUBTTL Subroutines -- NRTHBR - Subroutine to do the HIBERs.

;NRTHBR - Called by SCLINK to hibernate
;
; Call:
;	T1/ Pointer to SJB
;
; Return:
;	RET			;ONLY RETURN
;
; Uses: T1

NRTHBR:	BUG. CHK,NRTHBC,NRTSER,SOFT,<NRTHBR should never be called>,,<

Cause:	This BUG is not documented yet.

>,CPOPJ
	SUBTTL Subroutine -- NRTLFC - Get a NRT Line number from channel

;NRTLFC - Gets a Line number given a NRT channel.
;
; Call:
;	U/ Channel number
;
; Return: U/ Line number or 0 if none found
;	RET			;Always return
; It is expected when this subroutine is called, that the calling
; routine has checked to be sure that the channel is in range of the
; channels that NRTSER has open.
;
; Used: T1,U


NRTLFC::MOVE T1,NRTCHP		;GET THE POINTER TO THE NRB
	ADD T1,U		;ADD IN THE CHANNEL NUMBER
	SKIPN T1,(T1)		;ANYTHING THERE?
	 JRST NRTRZR		;NONE, THEN RETURN ZERO
	LOAD U,NRLDB,(T1)	;AND THEN THE POINTER TO THE LDB
	SKIPN U			;ANYTHING THERE?
NRTRZR: TDZA U,U		;CLEAR OUT U
	LDB U,LDPLNO##		;GET THE LINE NUMBER
	POPJ P,			;AND RETURN

	SUBTTL	NRTGWD - Get Some Words

;NRTGWD - Get some zeroed words
;
; Call:
;	T1/ Count of words we want
;
; Return:
;	RET			;ON ALLOCATION FAILURE
;	RETSKP			;WITH T1 POINTING TO WORDS
;
; Uses: T1-T4
;
;Note: The count of words allocated is stored in the word before the
;returned pointer.

NRTGWD:	SAVEAC	<P1,W,M>	;W & M ARE DECnet'S T5 & T6
	MOVE P1,T1		;SAVE THE COUNT
	MOVEI T2,1(T1)		;T2 GETS NUMBER OF WORDS.
	S0CALL GETWDS##		;GO GET SOME FREE CORE
	  RET			;TELL CALLER WE LOST
	XMOVEI T1,(T1)		;MAKE EXTENDED ADDR IN SECTION 1
	HRLI P1,'NRT'		;MAKE A TEST THINGY
	MOVEM P1,(T1)		;STORE COUNT IN RH OF OVERHEAD WORD
	AOJ T1,			;RETURN POINTER TO USER PART OF BLOCK

;Zero the words.
	PUSH P,T1		;SAVE USER ADDRESS OF NEW BLOCK
	HRRZ T2,P1		;GET THE LENGTH OF THE BLOCK
	ADD T2,T1		;AND POINT TO THE LAST WORD IN THE BLOCK
	SOJ T2,			;POINT TO LAST WORD
	MOVEI T3,0		;VALUE TO SMEAR INTO BLOCK
	CALL DNSWDS		;SMEAR ZEROES INTO BLOCK
	POP P,T1		;RESTORE ADDRESS OF BLOCK FOR CALLER
	RETSKP			; AND GIVE GOOD RETURN
	SUBTTL	NRTFWD - Free Some Words

;NRTFWD - Free what NRTGWD took away
;
; Call:
;	T1/ Pointer to some words
;
; Return:
;	RET			;ALWAYS
;
; Uses: T1,T2

NRTFWD:	SOJLE T1,[BUG.(CHK,NRTFW0,NRTSER,SOFT,<Tried to free words at zero>,,<

Cause:	This BUG is not documented yet.

>,CPOPJ)]
				;POINT TO HEADER WORD
	HLRZ T3,(T1)		;GET THINGY TO CHECK AGAINST.
	CAIE T3,'NRT'		;IS IT WHAT WE PUT THERE?
	  BUG. CHK,NRTBPM,NRTSER,SOFT,<Bad pointer passed to memory manager>,,<

Cause:	This BUG is not documented yet.

>,CPOPJ

	HRRZ T2,(T1)		;GET THE WORD COUNT FOR GIVWDS
	AOJ T2,			;ADD IN WORD OF OVERHEAD
	EXCH T1,T2		;CORE1 WANTS THESE IN OTHER ORDER
	HRRZS T2		;RESTORE ADDRESS TO SECTION 0
	S0CALL GIVWDS##		;LET GO OF OUR CORE.
	RET			;RETURN, BACK IN SECTION 1
	SUBTTL End of Program

	.XCMSY			;XCREF MACSYM TEMPS

				;PUT A LABEL ON THE LITERAL POOL
NRTLIT:	XLIST			;DON'T LIST THE LITERALS
	LIT
	LIST

	END