Google
 

Trailing-Edge - PDP-10 Archives - tops10_tools_bb-fp64a-sb - 10,7/decnet/dts/dtr.mac
There are 6 other files named dtr.mac in the archive. Click here to see a list.
	TITLE DTR - DECnet Test Receiver
	SUBTTL W. Nichols	May, 1981

	SEARCH	DTSPRM,JOBDAT,MACTEN,UUOSYM,SWIL

IFN FTUSRMOD,<	SEARCH D36PAR
		D36SYM
>
	SALL
	.DIRECTIVE FLBLST	;DON'T GIVE ME CODE FOR ASCIZ
	$RELOC


COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1984,1986. ALL RIGHTS RESERVED.\

;	This program conforms to the DTR specification version 1.1
;	published on 22 April 1981.

	PRGID=:'DTR   '		;NAME OF THIS PROGRAM
	PRGABR=:'DTR'		;3 CHR ABBREVIATION USED FOR PROG.

	DTRWHO==0
	DTRVER==1		;MAJOR VERSION
	DTRMIN==0		;MINOR VERSION
	DTREDT==10		;EDIT NUMBER

DEFINE	VRSN. (PROG),<
	BYTE  (3) PROG'WHO (9) PROG'VER (6) PROG'MIN (18) PROG'EDT
>
	LOC	.JBVER
	VRSN.	DTR
	RELOC
	LOC	.JBREN
	EXP	REENTER
	RELOC


;Expand the INTERNAL/EXTERNAL macro from DTSPRM

	GLOBAL	EXTERNAL,INTERNAL


	SUBTTL	Revision History


COMMENT	&

Edit	Description

4	17-Jan-84 by Bill Davenport.

	Fix the INTERRUPT SEQUENCE test to correctly check the
	expected sequence number.

5	18-Jan-84 by Bill Davenport.

	Fix the interrupt test to store the interrupt message size
	from the received interrupt messages.  This fixes the report-
	ing of bogus interrupt message sizes.

6	19-Jan-84 by Tarl Neustaedter.

	Sleep for a second on a disconnect test, so that we don't do a .NSFDS
	before the ack for the CC arrives. Crock, but who'll notice?

7	25-Jan-84 by Bill Davenport.

	Zero count of receive and send errors at start of interrupt tests.
	Ignore "Abort by Object" returns during DATA and INTERRUPT tests
	as this seems the normal thing that VAXen do.

10	26-Jan-84 by Bill Davenport.

	More of edit 7.

&; End Revision History
	SUBTTL	Standard Test Strings

;The "standard" user data string

STDUSR:	XWD ^D16,<^D16/4>+1	;USER DATA IS MAX 16 BYTES
	BYTE8	ABCDEFGHIJKLMNOP ;STRING OF 8-BIT BYTES
	$HIGH

;The Enter Passive Connect Block

EPCONB:	EXP	EPCONL		;LENGTH OF BLK IN WORDS
	EXP	0		;STRING PTR TO NODE NAME (.NSCND)
	EXP	EPSPRC		;PTR TO SOURCE PRC BLK (.NSCSD)
	EXP	EPDPRC		;PTR TO DEST PRC BLK (.NSCDD)
	EXP	0		;PTR TO UID STRING BLK (.NSCUS)
	EXP	0		;PTR TO PASSWORD STR BLK (.NSCPW)
	EXP	0		;PTR TO ACCOUNT STR BLK (.NSCAC)
	EXP	0		;PTR TO USER DATA STR BLK (.NSCUD)
EPCONL==.-EPCONB


;The Source Process Descriptor

EPSPRC:	EXP	5		;LENGTH OF BLK IN WORDS
	EXP	0		;FORMAT ZERO
	EXP	OBJDTR		;THE OBJECT TYPE OF A DTR
	EXP	0		;PPN MUST BE ZERO FOR FORMAT ZERO
	EXP	0		;DITTO PROCESS NAME STRING PTR

;The Destination Process Descriptor

EPDPRC:	EXP	5		;LENGTH OF BLK IN WORDS
	EXP	0		;FORMAT ZERO
	EXP	OBJDTR		;THE OBJECT TYPE OF A DTR
	EXP	0		;PPN MUST BE ZERO FOR FORMAT ZERO
	EXP	0		;DITTO PROCESS NAME STRING PTR
	$LOW

;The Enter Active Connect Block

RICONB:	EXP	RICONL		;LENGTH OF BLOCK IN WORDS
	EXP	NODNAM		;STRING PTR TO NODE NAME (.NSCND)
	EXP	RISPRC		;PTR TO SOURCE PRC BLK (.NSCSD)
	EXP	RIDPRC		;PTR TO DEST PRC BLK (.NSCDD)
	EXP	UID		;PTR TO UID STRING BLK (.NSCUS)
	EXP	PASSWORD	;PTR TO PASSWORD STR BLK (.NSCPW)
	EXP	ACCOUNT		;PTR TO ACCOUNT STR BLK (.NSCAC)
	EXP	CNTUSR		;PTR TO USER DATA STR BLK (.NSCUD)
RICONL==.-RICONB

NODNAM:	STRBLK	STRLNW		;NODE NAME
UID:	STRBLK	STRLNW		;UID STRING BLK
PASSWORD:STRBLK	STRLNW		;PASSWORD STR BLK
ACCOUNT:STRBLK	STRLNW		;ACCOUNT STR BLK

;The Source Process Descriptor

RISPRC:	EXP	5		;LENGHT OF BLK
	EXP	0		;FORMAT ZERO
	EXP	0		;THE OBJECT TYPE OF A DTR
	EXP	0		;PPN MUST BE ZERO FOR FORMAT ZERO
	EXP	0		;DITTO PROCESS NAME STRING PTR

;The Destination Process Descriptor

RIDPRC:	EXP	5		;LENGTH OF BLK IN WORDS
	EXP	0		;FORMAT ZERO
	EXP	0		;THE OBJECT TYPE OF A DTR
	EXP	0		;PPN MUST BE ZERO FOR FORMAT ZERO
	EXP	0		;DITTO PROCESS NAME STRING PTR

	$HIGH
	SUBTTL	General Impure Storage

	$LOW

PRINT::	BLOCK	1		;HOLDS THE PRINT FLAG (ALL,NONE,ERROR)
LOGFLG::BLOCK	1		;NON-ZERO IF WE'RE LOGGING

TYPE:	BLOCK	1		;TEST TYPE
RFLTYP:	BLOCK	1		;RECEIVE (FROM DTS VIEW) FLOW CONTROL
RQUEUE:	BLOCK	1		;RECEIVE (FROM DTS VIEW) QUEUE GOAL
MSGSIZ:	BLOCK	1		;MESSAGE SIZE (FOR EITHER DATA OR INT)
SNDCNT:	BLOCK	1		;NUMBER OF MESSAGES SENT TO DTR
BAUD:	BLOCK	1
ELPTIM:	BLOCK	1		;ELAPSED TIME FOR STATS
STRTIM:	BLOCK	1		;STARTING TIME
RCVCNT:	BLOCK	1
RERRCNT:BLOCK	1
SERRCNT:BLOCK	1

	$HIGH
	SUBTTL	Start the Program Here

REENTER:EXIT			;WAIT FOR RESET TO WORK PROPERLY

DTR::	TDZA	T1,T1		;NON-CCL ENTRY
	  MOVEI	T1,1		;CCL ENTRY
	MOVEM	T1,CCLF1	;STORE FOR LATER
	MOVE	P,PDLIOW	;SET UP STACK
DTRRES::RESET			;LABEL IS FOR DDT PATCHING
	HRRZ	T1,.JBREL	;GET FIRST-TIME CORE SIZE
	MOVEM	T1,INICOR
	HRRZ	T1,.JBFF	;GET INITIAL .JBFF
	MOVEM	T1,INIFF	;SAVE FOR LATER

	MOVX	T1,PRI.AL	;START OUT WITH /PRINT:ALL
	MOVEM	T1,PRINT	;DTS WILL CHANGE THIS WITH TESTTYPE

;Fall through to next page for .ISCAN
	SUBTTL	Call .ISCAN

;From previous page

;.ISCAN--SUBROUTINE TO INITIALIZE COMMAND SCANNER
;CALL	AC1=XWD LENGTH,BLOCK
;
;	BLOCK+0=PROTOCOL VERSION WORD: <MAJOR>,,<MINOR>
;	BLOCK+1=0 OR IOWD PTR TO A LIST OF LEGAL MONITOR COMMANDS
;		IF 0, NO RESCAN IS DONE
;	BLOCK+2=RH 0 OR SIXBIT CCL NAME
;		  IF 0, NO CCL MODE
;		LH 0 OR ADDRESS OF STARTING OFFSET
;	BLOCK+3=RH 0 OR ADDRESS OF CHARACTER TYPEOUT ROUTINE
;		  IF 0, OUTCHR WILL BE DONE FROM T1
;		LH 0 OR ADDRESS OF CHARACTER INPUT ROUTINE
;			MUST SAVE ALL ACS, CHAR IN P4
;	BLOCK+4=0 OR POINTER (XWD LEN,BLOCK) TO INDIRECT FILE BLOCK
;		  .FXDEV NE 0 TO USE BLOCK
;	BLOCK+5=RH 0 OR ADDRESS OF MONRET ROUTINE
;		LH 0 OR ADDRESS OF PROMPT ROUTINE
;			CALLED WITH CHAR IN RH(T1), LH(T1) HAS
;			    0 FOR FIRST LINE, -1 FOR CONTINUATION LINES
;	BLOCK+6=LH FLAGS
;		RH (FUTURE)
;VALUE	AC1=INDEX IN TABLE OF COMMANDS IF FOUND(0,1,...), ELSE -1


	MOVE	T1,[6,,[12,,%%FXVE	;MAJOR,,MINOR SCAN VERSION
			IOWD 1,[PRGID]	;CCL ENTRY NAME
			CCLF1,,PRGABR	;CCL FLAG,,PROGRAM NAME ABBREVIATION
			0,,STYPOU	;NO SPECIAL TYPEIN,,TYPEOUT ROUTINE
			0,,0		;NO USER INDIRECT
			0,,.EXIT]]	;MONRET ROUTINE
	CALLSCAN .ISCAN##		;INITIALIZE SCAN

;Fall through to Main Loop
;Fall through from previous page at startup


;Main Loop

DTRPAS:	INFO	<Waiting for a connect from DTS>,CRLF
	CALL	ENTPAS		;ENTER PASSIVE
	  EXIT			;ERROR, DECNET PROBABLY NOT LOADED

	INFO	<Connect from DTS on node >

	PUSH	P,P1
	PUSH	P,P2
	HLRZ	P1,NODNAM	;GET LENGTH OF NAME IN BYTES
	JUMPE	P1,DTRPS2	;SHOULD NOT JUMP
	MOVE	P2,[POINT 8,NODNAM+1]
DTRPS1:	ILDB	T1,P2		;GET NEXT BYTE OF NODE'S NAME
	CALLSCAN .TCHAR##	;TYPE IT OUT
	SOJG	P1,DTRPS1	;LOOP UNTIL ALL OUT
DTRPS2:
	CALLSCAN .TRBRK##	;A RIGHT SQUARE BRACKET FOR INFO
	CALLSCAN .TCRLF##
	POP	P,P2
	POP	P,P1

	CALL	DO.TEST		;WE HAVE A COMMAND, GO DO THE TEST
	JRST	DTRPAS

DTRNSE:	ERROR	<Error trying to Reject a Connect:>,CRLF
	CALL	NSPERR
	JRST	DTRPAS
	SUBTTL	DO.TEST - We have a command from DTS, do it

;Called only from the main loop

DO.TEST:SAVEAC	P1
	MOVEI	T1,0		;GET THE FIRST (TESTTYPE) FIELD
	MOVEI	T2,CNTUSR	; FROM CNTUSR (CONNECT USER DATA)
	CALL	GET1BY		;GET 1 BYTE INTO T1
	  PJRST	UNSUP0		;FIELD ZERO UNSUPPORTED
	MOVE	P1,T1		;SAVE THE TESTTYPE CODE

;Get the PRINT:xxx option from the high-order bits of TESTTYPE

	MOVX	T2,PRI.NO	;ASSUME PRINT:NONE
	TXNE	P1,.TCERR	;WANT ERROR PRINTING?
	MOVX	T2,PRI.ER	;YES, LOAD UP PRINT:ERROR
	TXNE	P1,.TCPRI	;WANT ALL PRINTING?
	MOVX	T2,PRI.AL	;YES, LOAD UP PRINT:ALL
	MOVEM	T2,PRINT	;STORE FOR STYPOUT ROUTINES

;Now that we know how to print, offer some user info

	TRACE	<Got a Connect>,CRLF
;	CALL	TYPSTA		;TELL USER ABOUT THE LINK STATUS

;Now go off to the requested test

	ANDI	P1,77		;ONLY THE TEST TYPE LEFT
	CAILE	P1,.TCMAX	;SUPPORTED TEST?
	PJRST	UNSUP0		;NO, SEND BACK AN ERROR FOR FIELD 0

;Note that we have not yet accepted the connection.  This is so we
;can reject it if we find any unsupported tests being requested.
;It is the responsibility of each test to accept the connect when
;it has checked the entire request.

	CALL	@[EXP DO.CONNECT
		  EXP DO.DATA
		  EXP DO.DISCONNECT
		  EXP DO.INTERRUPT](P1)

	SKIPGE	CHANEL		;CHANNEL NUMBER
	RET			;-1 MEANS THAT THE CHANNEL IS CLOSED
	CALNSP	.NSFRS		;READ STATUS TO SEE IF CHN STILL OPEN
	  RET			;NOPE, ALL IS DONE
	PJRST	NSPREL		;YES, TEST MUST HAVE LEFT IT OPEN
				;ABORT OR RELEASE IT.

;Now we return to main loop for another test
	SUBTTL	The CONNECT Test

;Call:	CALL DO.CONNECT
;	Normal Return

DO.CONNECT:

;Here we check the entire request string first, then see if
;we should accept or reject the connect according to the test option.

	MOVEI	T1,1		;GET THE SECOND FIELD
	MOVEI	T2,CNTUSR	;FROM CONNECT USER DATA
	CALL	GET1BY		;GET 1 BYTE INTO T1
	  PJRST	UNSUP1		;UNSUPPORTED IF NON-EXISTENT
	CAILE	T1,5		;MAX OFFSET THIS CODE KNOWS ABOUT
	PJRST	UNSUP1		;OOPS, UNSUPPORTED CMD IN FIELD 1

	PJRST	@[EXP DOCO.0	  ;(0) REJECT, NO DATA
		  EXP DOCO.1	  ;(1) ACCEPT, NO DATA
		  EXP DOCO.2	  ;(2) REJECT, STANDARD DATA
		  EXP DOCO.3	  ;(3) ACCEPT, STANDARD DATA
		  EXP DOCO.4	  ;(4) REJECT, RETURN DATA
		  EXP DOCO.5](T1) ;(5) ACCEPT, RETURN DATA

DOCO.0:	MOVEI	NSAA1,0		;(0) REJECT, NO DATA
	PJRST	DOCO.R		;GO TO COMMON EXIT

DOCO.1:	MOVEI	NSAA1,0		;(1) ACCEPT, NO DATA
	PJRST	DOCO.A		;GO TO COMMON EXIT

DOCO.2:	MOVEI	NSAA1,STDUSR	;(2) REJECT, STANDARD DATA
	PJRST	DOCO.R		;GO TO COMMON EXIT

DOCO.3:	MOVEI	NSAA1,STDUSR	;(3) ACCEPT, STANDARD DATA
	PJRST	DOCO.A		;GO TO COMMON EXIT

DOCO.4:	MOVEI	NSAA1,CNTUSR	;(4) REJECT, RETURN DATA
	PJRST	DOCO.R		;GO TO COMMON EXIT

DOCO.5:	MOVEI	NSAA1,CNTUSR	;(5) ACCEPT, RETURN DATA
	PJRST	DOCO.A		;GO TO COMMON EXIT
;Here to Reject the connect for the CONNECT test

DOCO.R:	INFO	<Connect Reject Test>,CRLF
				;NSAA1 FILLED IN BY CALLER
	CALNSP	.NSFRJ,NSAA1,NS.WAI ;REJECT FUNCTION
	  PJRST	NSPERR
	RET


;Here to Accept the connect for the CONNECT test

DOCO.A:	INFO	<Connect Accept Test>,CRLF
					;NSAA1 FILLED IN BY CALLER
	CALNSP	.NSFAC,NSAA1		;ACCEPT FUNCTION
	  PJRST	NSPERR

DOCA.1:	MOVEI	NSAA1,0			;WE'RE NOT EXPECTING ANY DATA
	MOVE	NSAA2,PRCVMSG		;POINTER TO LEGAL BUFFER
	CALNSP	.NSFDR,NSAA2,NS.WAIT	;WAIT FOR ABORT FROM DTS
	  PJRST	NSPREL			;ERROR, HOPE IT IS THE ABORT
	JRST	DOCA.1			;IGNORE ANY DATA RECEIVED
	SUBTTL	The DISCONNECT Test

;Call:	CALL DO.DISCONNECT
;	Normal Return

DO.DISCONNECT:
	SAVEAC	P1
	MOVEI	T1,1		;GET THE SECOND FIELD
	MOVEI	T2,CNTUSR	;FROM CONNECT USER DATA
	CALL	GET1BY		;GET 1 BYTE INTO T1
	  PJRST	UNSUP1		;UNSUPPORTED IF NON-EXISTENT
	CAILE	T1,5		;MAX OFFSET THIS CODE KNOWS ABOUT
	PJRST	UNSUP1		;OOPS, UNSUPPORTED CMD IN FIELD 1
	MOVE	P1,T1		;SAVE FOR PJRST BELOW
	CALNSP	.NSFAC		;WE'RE HAPPY, ACCEPT THE CONNECT
	  PJRST	NSPERR
	MOVEI	T1,1		;ONE SECOND
	SLEEP	T1,		;WAIT FOR US TO GET OUT OF CC STATE
	PJRST	@[EXP DODI.0	  ;(0) SYNCHRONOUS, NO DATA
		  EXP DODI.1	  ;(1) ABORT, NO DATA
		  EXP DODI.2	  ;(2) SYNCHRONOUS, STANDARD DATA
		  EXP DODI.3	  ;(3) ABORT, STANDARD DATA
		  EXP DODI.4	  ;(4) SYNCHRONOUS, RETURN DATA
		  EXP DODI.5](P1) ;(5) ABORT, RETURN DATA

DODI.0:				;(0) SYNCHRONOUS, NO DATA
	MOVEI	NSAA1,0		;NO USER DATA
	PJRST	DODI.S		;GO TO COMMON EXIT

DODI.1:				;(1) ABORT, NO DATA
	MOVEI	NSAA1,0		;NO USER DATA
	PJRST	DODI.A		;GO TO COMMON EXIT

DODI.2:				;(2) SYNCHRONOUS, STANDARD DATA
	MOVEI	NSAA1,STDUSR	;STANDARD USER DATA
	PJRST	DODI.S		;GO TO COMMON EXIT

DODI.3:				;(3) ABORT, STANDARD DATA
	MOVEI	NSAA1,STDUSR	;STANDARD USER DATA
	PJRST	DODI.A		;GO TO COMMON EXIT

DODI.4:				;(4) SYNCHRONOUS, RETURN DATA
	MOVEI	NSAA1,CNTUSR	;RECEIVED USER DATA
	PJRST	DODI.S		;GO TO COMMON EXIT

DODI.5:				;(5) ABORT, RETURN DATA
	MOVEI	NSAA1,CNTUSR	;RECEIVED USER DATA
	PJRST	DODI.A		;GO TO COMMON EXIT
;The common exit for DO.DISCONNECT

DODI.S:	INFO	<Synchronous Disconnect Test>,CRLF
	CALNSP	.NSFSD,NSAA1,NS.WAI ;SYNCH DISCONNECT
	  PJRST	NSPERR
	JRST	DODI.X

DODI.A:	INFO	<Abort Disconnect Test>,CRLF
	CALNSP	.NSFAB,NSAA1,NS.WAI ;ABORT AND RELEASE
	  PJRST	NSPERR

DODI.X:

;If this is a synchronous disconnect, lets wait for the confirm
;before we release the channel: that's playing the game right.

	CAXE	NSAFN,.NSFSD	;IS THIS IS A SYNCH DISCONNECT?
	RET			;NO, ITS ABORT-AND-RELEASE

DODX.1:	MOVEI	NSAA1,0			;WE'RE NOT EXPECTING ANY DATA
	MOVE	NSAA2,[POINT 8,T2]	;DUMMY BYTE POINTER
	CALNSP	.NSFDR,NSAA2,NS.WAIT	;WAIT FOR DISCON CONFIRM
	  TRNA			;ERROR, LET'S HOPE ITS THE DC
	JRST	DODX.1		;IGNORE ANY READS RECEIVED
	CALL	NSPREL		;RELEASE THE CHANNEL
	RET
	SUBTTL	The DATA Test

;Call:	CALL DO.DATA
;	Normal Return

DO.DATA:
	MOVEI	T2,CNTUSR	;THIS IS KEPT THROUGH CALLS TO GETxBY

	MOVEI	T1,1		;FIELD NUMBER 1 NEXT
	CALL	GET1BY		;READ DATTYPE FIELD
	  PJRST	UNSUP1		;IF ERROR, UNSUPPORTED TEST IN FIELD 1
	CAILE	T1,.DCMAX	;SUPPORTED VALUE?
	PJRST	UNSUP1		;NO, COMPLAIN
	MOVEM	T1,TYPE		;PUT THE DATA TEST'S /TYPE: VALUE

	MOVEI	T1,2		;FIELD NUMBER 2 NEXT
	CALL	GET1BY		;READ RFLOW FIELD
	  PJRST	UNSUP2		;IF ERROR, UNSUPPORTED TEST IN FIELD 2
	CAILE	T1,.FCMAX	;SUPPORTED VALUE?
	PJRST	UNSUP2		;NO, COMPLAIN
	MOVEM	T1,RFLTYP	;PUT /RFLOW VALUE

	MOVEI	T1,3		;FIELD NUMBER 3 NEXT
	CALL	GET1BY		;READ /RQUEUE FIELD
	  PJRST	UNSUP3		;IF ERROR, UNSUPPORTED TEST IN FIELD 3
	MOVEM	T1,RQUEUE	;PUT /RQUEUE FIELD

	MOVEI	T1,4		;FIELD NUMBER 4 NEXT
	CALL	GET2BY		;NOW A 2-BYTE RESERVED FIELD
	  PJRST	UNSUP4		;IF ERROR, UNSUPPORTED TEST IN FIELD 4

	MOVEI	T1,6		;FIELD NUMBER 5 NEXT
	CALL	GET2BY		;READ THE MSGLEN FIELD
	  PJRST	UNSUP5		;IF ERROR, UNSUPPORTED TEST IN FIELD 5
	CAXLE	T1,MAXMSG	;SUPPORTED MESSAGE SIZE?
	  PJRST	UNSUP5		;IF ERROR, UNSUPPORTED TEST IN FIELD 5
	MOVEM	T1,MSGSIZ	;PUT THE /MSGSIZ VALUE

;Finished reading the Connect message,
;fall through to next page to accept the connect
;From Previous Page

DEFINE DTYPMC(text),<
	[INFO <text Test>,CRLF
	 RET]
>

	MOVE	T1,TYPE		;GET TYPE CODE FOR DATA TEST
	CALL	@[DTYPMC Data Sink
		  DTYPMC Data Sequence
		  DTYPMC Data Pattern
		  DTYPMC Data Echo](T1)

	SETZB	NSAA1,NSAA2	;NO USER DATA OR SEGSIZE OFFERED
	MOVE	NSAA3,RFLTYP	;GET FLOW CONTROL MODE TO USE
	CALNSP	.NSFAC,NSAA3	;WE'RE HAPPY, ACCEPT THE CONNECT
	  PJRST	NSPERR

	CALNSP	.NSFRS,NSAA2	;READ STATUS TO GET SEGMENT SIZE USED
	  RET			;NOPE, ALL IS DONE
	INFO <Seg: >
	MOVE	T1,NSAA1	;GET SEGSIZE FROM READ STATUS
	CALLSCAN .TDECW##
	MOVEI	T1,[ASCIZ /, Msg: /]
	CALLSCAN .TSTRG##
	MOVE	T1,MSGSIZ	;GET MESSAGE SIZE FROM PROTOCOL HEADER
	CALLSCAN .TDECW##
	MOVEI	T1,[ASCIZ /, RQUEUE: /]
	CALLSCAN .TSTRG##
	MOVE	T1,RQUEUE	;GET BUFFERING DTR IS TO USE
	CALLSCAN .TDECW##
	MOVEI	T1,[ASCIZ /, RFLOW: /] ;DTR'S FLOW CONTROL ELECTION
	CALLSCAN .TSTRG##
	HRRZ	T1,NSAA2	;LOCAL FLOW CONTROL IN RH
	CALL	TYPFLO
	MOVEI	T1,[ASCIZ /, SFLOW: /] ;DTS'S FLOW CONTROL ELECTION
	CALLSCAN .TSTRG##
	HLRZ	T1,NSAA2	;REMOTE FLOW CONTROL IN LH
	CALL	TYPFLO
	MOVEI	T1,[ASCIZ /]/]
	CALLSCAN .TSTRG##
	CALLSCAN .TCRLF##

;Set the link quota from the RQUEUE value received in the
;Connect Initiate message

	MOVE	T1,RQUEUE	;SET TO VALUE USER WANTED
	CALL	SETQTA
	  RET			;MESSAGE ALREADY GIVEN

;We have accepted the connect, now loop on data message receives

	SETZM	RCVCNT		;START WITH MESSAGE #1
	SETZM	SNDCNT		;AND NO MSGS SENT FOR STATS
	SETZM	RERRCNT		;NO RECEIVE ERRORS YET
	SETZM	SERRCNT		;NO SEND ERRORS YET

	CALL	GETTIME
	MOVEM	T1,STRTIME	;STORE STARTING TIME

	CALL	DATLOP		;TO THE DATA TEST
	  JFCL			;FAILED

	CALL	GETTIM		;GET CURRENT TIME
	SUB	T1,STRTIME	;SUBTRACT OFF STARTING TIME
	MOVEM	T1,ELPTIME	;STORE AS ELAPSED TIME
	CALL	PSTATS		;TYPE OUT STATS FOR USER

	PJRST	NSPREL		;RELEASE THE LINK

;The DTS will close the link in all success cases, we may abort
;if there is an error.
;DATLOP - Loop to do the actual data test
;
;Call:	CALL DATLOP
;	  Error Return
;	Normal Return
;
;Called only from DO.DATA

DATLOP:	MOVE	T1,TYPE		;GET TEST TYPE
	CAIN	T1,.DCECH	;IS IT AN ECHO TEST?
	JRST	DATECH		;YES, SPECIAL LOOP FOR ECHO TEST
				;NO, USE STANDARD LOOP
DATLP1:	MOVE	NSAA1,MSGSIZ	;BYTES IN A MAX MESSAGE
	MOVE	NSAA2,PRCVMSG	;BYTE POINTER TO RECEIVED MESSAGE
	CALNSP	.NSFDR,NSAA2,<NS.WAIT ! NS.EOM> ;READ WHOLE MESAGE
	  JRST	DATL.E		;ABORT ON NETWORK ERROR (ERROR RETURN)
	TXNN	NSAFN,NS.EOM	;DID WE GET THE WHOLE MESSAGE?
	JRST	DATL.M		;NO, COMPLAIN

	AOS	RCVCNT		;UPDATE FOR SEQ TEST AND FOR STATS

;Since NS.WAI and NS.EOM are lit in the arg block,
;we will only return from the NSP. UUO when we have a full message.

	MOVE	T1,TYPE		;TYPE OF THIS DATA TEST
	CALL	@[EXP DATL.1	  ;SINK
		  EXP DATL.2	  ;SEQUENCE
		  EXP DATL.3	  ;PATTERN
		  EXP DATL.3](T1) ;ECHO (SHOULD BE IN DATECH LOOP)
	  RET			;ERROR RETURN: ABORT THE LINK
	JRST	DATLOP		;SUCCESS RETURN, GET NEXT MESSAGE


;Here on a network error.  Spec says abort the link.

DATL.E:	CAXE	T1,NSABO%	;[7] IGNORE "ABORT BY OBJECT" ERROR
	CAXN	T1,NSDBO%	;IGNORE "DISCONNECTED BY OBJECT" ERROR
	RET			;CALLER WILL ABORT THE LINK
	AOS	RERRCNT		;COUNT OTHER ERRORS FOR STATS
	PJRST	NSPERR		;TELL USER ABOUT THE ERROR

;Here if we received a message with no End of Message flag

DATL.M:	WARN	<No EOM flag on received message>,CRLF
	RET			;ERROR RETURN
;The SINK test

DATL.1:	RETSKP			;SINK, JUST TOSS THE MESSAGE

;The SEQUENCE test

DATL.2:	MOVE	T1,MSGSIZ	;GET MAX SIZE THIS MSG COULD BE
	HRLM	T1,RCVMSG	;STORE AS STRING BLK LENGTH FOR GETNBY
	MOVEI	T1,0		;OFFSET OF BYTES TO GET
	MOVEI	T2,RCVMSG	;POINTER TO STRING BLOCK
	MOVEI	T3,SEQLEN	;NUMBER OF BYTES IN A SEQUENCE NUMBER
	CALL	GETNBY		;GET N BYTES INTO T1
	  HALT			;INTERNAL ERROR
	MOVE	T2,RCVCNT	;SEQUENCE, CHECK THE SEQUENCE NUMBER
	ANDX	T2,MASK.(SEQLEN*^D8,35) ;MAKE IT WRAP AROUND PROPERLY
	MOVEM	T2,RCVCNT	;SAVE WRAPPED VALUE
	CAME	T1,T2		;IS THIS THE EXPECTED MESSAGE?
	  TRNA			;NO, ABORT THE LINK
	RETSKP			;YES, SUCCESS

	WARN	<Comparison of sequence numbers failed>,CRLF
	RET

;The PATTERN test

DATL.3:	CALL	DATL.2		;FIRST, CHECK THE SEQUENCE NUMBER
	  RET			;PROPOGATE ERROR RETURN
	MOVEI	T1,SEQLEN	;ADVANCE BY SEQLEN TO SKIP MSG NUMBER
	ADJBP	T1,PRCVMSG	;BYTE PTR TO RECEIVED MSG
	MOVE	T2,MSGSIZ	;LENGTH OF CORRECT MESSAGE
	SUBI	T2,SEQLEN	;DECREMENT BY LENGTH OF MESSAGE NUMBER
	CALL	CMPSTD		;COMPARE WITH STANDARD DATA
	  TRNA			;COMPARE FAILED, ABORT THE TEST
	RETSKP			;YES, SUCCESS

	WARN	<Comparison of standard data failed>,CRLF
	RET
;The ECHO test

DATECH:	MOVE	NSAA1,MSGSIZ	;BYTES IN A MAX MESSAGE
	MOVE	NSAA2,PRCVMSG	;BYTE POINTER TO RECEIVED MESSAGE
	CALNSP	.NSFDR,NSAA2,<NS.WAIT> ;READ WHOLE MESAGE
	  JRST	DATL.E		;ABORT ON NETWORK ERROR (ERROR RETURN)

	AOS	RCVCNT		;TELL STATS ABOUT THE RECEIVE
	AOS	SNDCNT		;TELL STATS ABOUT THE SEND

	SUB	NSAA1,MSGSIZ	;GET NUMBER OF BYTES WE ACTUALLY RECEIVED
	MOVMS	NSAA1		;MAKE THAT POSITIVE
	MOVE	NSAA2,PRCVMSG	;SEND THE SAME MESSAGE BACK AGAIN
	TXNN	NSAFN,NS.EOM	;DID WE HAVE EOM ON THAT READ?
	JRST	DATEC1		;NO
	CALNSP	.NSFDS,NSAA2,<NS.WAIT!NS.EOM> ;YES, SEND MESSAGE BACK
	  JRST	DATECE		;NETWORK ERROR, ABORT THE LINK
	JRST	DATECH		;SUCCESS, DO IT AGAIN

DATEC1:	CALNSP	.NSFDS,NSAA2,<NS.WAIT> ;YES, SEND SEGMENT BACK
	  JRST	DATECE		;NETWORK ERROR, ABORT THE LINK
	JRST	DATECH		;SUCCESS, DO IT AGAIN

;Here on a network error, spec says abort the link

DATECE:	AOS	SERRCNT		;COUNT A SEND ERROR
	RET			;CALLER WILL ABORT THE LINK
	SUBTTL	The INTERRUPT Test

;Call:	CALL DO.INTERRUPT
;	Normal Return

DO.INTERRUPT:
	MOVEI	T2,CNTUSR	;T2 IS KEPT THROUGH CALLS TO GETxBY

	MOVEI	T1,1		;FIELD NUMBER 1 NEXT
	CALL	GET1BY		;READ INTTYPE FIELD
	  PJRST	UNSUP1		;IF ERROR, UNSUPPORTED TEST IN FIELD 1
	CAILE	T1,.ICMAX	;SUPPORTED VALUE?
	PJRST	UNSUP1		;NO, COMPLAIN
	MOVEM	T1,TYPE		;PUT THE INTERRUPT TEST'S /TYPE: VALUE

	MOVEI	T1,2		;FIELD NUMBER 2 NEXT
	CALL	GET1BY		;READ RQUEUE FIELD
	  PJRST	UNSUP2		;IF ERROR, UNSUPPORTED TEST IN FIELD 2
	MOVEM	T1,RQUEUE	;PUT /RQUEUE FIELD

	MOVEI	T1,3		;FIELD NUMBER 3 NEXT
;[3]	CALL	GET2BY		;READ THE MSGLEN FIELD
;[3]	  PJRST	UNSUP3		;IF ERROR, UNSUPPORTED TEST IN FIELD 3
;[3]	CAXLE	T1,MAXMSG	;SUPPORTED MESSAGE SIZE?
;[3]	  PJRST	UNSUP3		;IF ERROR, UNSUPPORTED TEST IN FIELD 3
;[3]	MOVEM	T1,MSGSIZ	;PUT THE /MSGSIZ VALUE
	SETZM	MSGSIZ		;[10] CLEAR MESSAGE SIZE

;Finished reading the Connect message,
;fall through to next page to accept the connect
;From Previous Page

DEFINE ITYPMC(text),<
	[INFO <text Test>,CRLF
	 RET]
>

	MOVE	T1,TYPE		;GET TYPE CODE FOR INTERRUPT TEST
	CALL	@[ITYPMC Interrupt Sink
		  ITYPMC Interrupt Sequence
		  ITYPMC Interrupt Pattern
		  ITYPMC Interrupt Echo](T1)

	SETZB	NSAA1,NSAA2	;NO USER DATA OR SEGSIZE OFFERED
	SETZM	NSAA3		;DEFAULT FLOW CONTROL MODE
	CALNSP	.NSFAC,NSAA3	;WE'RE HAPPY, ACCEPT THE CONNECT
	  PJRST	NSPERR

;We have accepted the connect, now loop on data message receives

	SETZM	RCVCNT		;START WITH MESSAGE #1
	SETZM	SNDCNT		;AND NO MSGS SENT FOR STATS
	SETZM	RERRCNT		;[7] NO RECEIVE ERRORS YET
	SETZM	SERRCNT		;[7] OR SEND ERRORS

	CALL	GETTIME
	MOVEM	T1,STRTIME	;STORE STARTING TIME

	CALL	INTLOP		;TO THE INTERRUPT TEST
	  JFCL			;FAILED

	CALL	GETTIM		;GET CURRENT TIME
	SUB	T1,STRTIME	;SUBTRACT OFF STARTING TIME
	MOVEM	T1,ELPTIME	;STORE AS ELAPSED TIME
	CALL	PSTATS		;TYPE OUT STATS FOR USER

	PJRST	NSPREL		;RELEASE THE LINK

;The DTS will close the link in all success cases, we may abort
;if there is an error.
;INTLOP - Loop to do the actual INTERRUPT test
;
;Call:	CALL INTLOP
;	  Error Return
;	Normal Return
;
;Called only from DO.INTERRUPT

INTLOP:	MOVEI	NSAA1,RCVMSG	;POINTER TO A STRING BLOCK
	CALNSP	.NSFIR,NSAA1,NS.WAIT ;INTERRUPT READ
	  PJRST	NSPREL		;ABORT ON NETWORK ERROR (ERROR RETURN)

	AOS	RCVCNT		;UPDATE FOR SEQ TEST AND FOR STATS
	HLRZ	T1,RCVMSG	;[5] GET SIZE OF INTERRUPT MESSAGE
	MOVEM	T1,MSGSIZ	;[5] SAVE FOR STATISTICS

;Since NS.WAI is lit in the arg block, we will only return from
;the NSP. UUO when we have a full RCVMSG.

	MOVE	T1,TYPE		;TYPE OF THIS INTERRUPT TEST
	CALL	@[EXP INTL.1	  ;SINK
		  EXP INTL.2	  ;SEQUENCE
		  EXP INTL.3	  ;PATTERN
		  EXP INTL.4](T1) ;ECHO
	  RET			;ERROR RETURN: ABORT THE LINK
	JRST	INTLOP		;SUCCESS RETURN, GET NEXT RCVMSG
;The SINK test

INTL.1:	RETSKP			;SINK, JUST TOSS THE MESSAGE

;The SEQUENCE test

INTL.2:	MOVEI	T1,0		;OFFSET OF BYTES TO GET
	MOVEI	T2,RCVMSG	;POINTER TO STRING BLOCK
	MOVEI	T3,SEQLEN	;NUMBER OF BYTES IN A SEQUENCE NUMBER
	CALL	GETNBY		;GET N BYTES INTO T1
	  HALT			;INTERNAL ERROR
	MOVE	T2,RCVCNT	;[4] GET EXPECTED SEQUENCE NUMBER
	ANDX	T2,MASK.(SEQLEN*^D8,35) ;MAKE IT WRAP AROUND PROPERLY
	CAME	T1,T2		;IS THIS THE EXPECTED MESSAGE?
	  TRNA			;NO, ABORT THE LINK
	RETSKP			;YES, SUCCESS

	WARN	<Comparison of sequence numbers failed>,CRLF
	RET

;The PATTERN test

INTL.3:	CALL	INTL.2		;FIRST, CHECK THE SEQUENCE NUMBER
	  RET			;PROPOGATE ERROR RETURN
	MOVEI	T1,SEQLEN	;ADVANCE BY SEQLEN TO SKIP MSG NUMBER
	ADJBP	T1,PRCVMSG	;BYTE PTR TO RECEIVED MSG
	HLRZ	T2,RCVMSG	;LENGTH OF OUR MESSAGE ;[3]
	SUBI	T2,SEQLEN	;DECREMENT BY LENGTH OF MESSAGE NUMBER
	CALL	CMPSTD		;COMPARE WITH STANDARD DATA
	  TRNA			;COMPARE FAILED, ABORT THE TEST
	RETSKP			;YES, SUCCESS

	WARN	<Comparison of standard data failed>,CRLF
	RET

;The ECHO test

INTL.4:	AOS	SNDCNT		;COUNT FOR STATS
	MOVEI	NSAA1,RCVMSG	;POINTER TO STRING BLOCK
	CALNSP	.NSFIS,NSAA1,NS.WAIT ;SEND THE INTERRUPT BACK
	  TRNA			;[10] SEND FAILED, COUNT ERROR AND ABORT LINK
	RETSKP			;SUCCESS, THE ECHO IS NOW COMPLETE
	AOS	SERRCNT		;[10] COUNT SEND ERROR
	RET			;[10] NON-SKIP RETURN TO ABORT LINK
	SUBTTL	ENTPAS - Subroutine to Enter Passive

;ENTPAS - Subroutine to Enter Passive
;
;Call:	CALL	ENTPAS
;	  Error Return, message put out
;	Normal Return with DECnet state in T1, status word in NSAA1
;
;Uses T1,T2,T3,T4

ENTPAS:	SETOM	CHANEL		;NO CHANNEL NUMBER YET
	MOVEI	NSAA1,EPCONB	;POINTER TO CONNECT BLOCK
	CALNSP	.NSFEP,NSAA1,NS.WAIT ;WAIT ON ENTER PASSIVE
	  PJRST	NSPERR		;COMPLAIN ABOUT NSP. ERROR

	MOVEM	NSACH,CHANEL	;STORE CHANNEL NUMBER RETURNED

	LDB	T1,[POINTR(NSACH,NS.STA)];GET THE STATE FIELD
	CAIE	T1,.NSSRN	;NOW IN RUN STATE?
	CAIN	T1,.NSSCR	;OR CONNECT RECEIVED?
	JRST	ENTP.1		;YES, GET THE USER DATA

	ERROR <Unexpected state after Enter Passive, see next message>,CRLF
	CALL	TYPSTA		;TELL USER CURRENT STATE INFO
	PJRST	NSPREL		;RELEASE THE CHANNEL


;Here when we have a connect, get the user data

ENTP.1:	MOVEI	NSAA1,RICONB	;CONNECT BLK PTR
	SETZB	NSAA2,NSAA3	;SEG SIZE, FLOW CONTROL
	CALNSP	.NSFRI,NSAA3	;READ CONNECT INIT DATA
	  PJRST	NSPERL
	RETSKP			;USER DATA IN CNTUSR
	SUBTTL	UNSUPn - Unsupported Test Routine

;Here we sent the error code back to DTS, saying that we don't
;support the particular test or option requested.

;The number at the end of the routine name is the number of the
;field which contains the unsupported request.

;Call:	T1/	Number of field in error
;	CALL	UNSUPT
;	Normal Return

UNSUP0:	JSP	T1,UNSU.1	;THE TESTTYPE FIELD
UNSUP1:	JSP	T1,UNSU.1	;THE TESTDESC FIELD
UNSUP2:	JSP	T1,UNSU.1
UNSUP3:	JSP	T1,UNSU.1
UNSUP4:	JSP	T1,UNSU.1
UNSUP5:	JSP	T1,UNSU.1

UNSU.1:	MOVEI	T1,-UNSUP0-1(T1);MAKE T1 A SMALL INTEGER
UNSUPT:	SAVEAC	P1
	MOVE	P1,T1		;THE FIELD NUMBER
	MOVEI	T1,STRLNW	;LENGTH OF A STR BLK IN WORDS
	MOVEM	T1,CNTUSR	;START WITH FRESH STR BLK
	MOVEI	T1,.ECUKT	;UNKNOWN TEST (^D15)
	MOVEI	T2,CNTUSR	;PTR TO STR BLK
	CALL	PUT1BY		;PUT ONE BYTE IN STRING BLOCK
	MOVE	T1,P1		;NUMBER OF FIELD IN ERROR
	MOVEI	T2,CNTUSR
	CALL	PUT1BY		;STORE THE SECOND BYTE

	ERROR	<Rejecting unsupported test request in field >
	MOVE	T1,P1		;GET FIELD NUMBER
	CALLSCAN .TDECW##
	CALLSCAN .TCRLF##

	MOVEI	NSAA1,CNTUSR	;POINTER TO USER DATA
	CALNSP	.NSFRJ,NSAA1,NS.WAI ;REJECT FUNCTION CODE
	  PJRST	NSPERL
CPOPJ:	RET
	SUBTTL	.EXIT - Called by SCAN's MONRET Routine

;Called by the EXIT command and by SCAN's monret routine


.EXIT:	CALL	CLSLOG		;IN CASE IT WAS OPEN
	PJRST	.MNRET##	;SCAN'S MONRET HANDLER
	SUBTTL	End of Program

	END	DTR