Google
 

Trailing-Edge - PDP-10 Archives - SRI_NIC_PERM_SRC_1_19910112 - 6-sources/scstst.mac
There is 1 other file named scstst.mac in the archive. Click here to see a list.
; UPD ID= 563, SNARK:<6.UTILITIES>SCSTST.MAC.29,  12-Jul-84 15:40:16 by LOMARTIRE
;Fix FNDNOD not cycle through nodes since SBI and node number are the same now
; UPD ID= 541, SNARK:<6.UTILITIES>SCSTST.MAC.28,   1-Jun-84 12:38:52 by LOMARTIRE
;Use .SSGLN not .SSRCD to obtain local node number at startup
; UPD ID= 512, SNARK:<6.UTILITIES>SCSTST.MAC.27,  28-Mar-84 01:25:38 by CDUNN
;Temporarily remove code to handle maintainace data function since they are
;now performed by DIAG and not SCS%. Fixes referances to removed symbols.
; UPD ID= 459, SNARK:<6.UTILITIES>SCSTST.MAC.26,  30-Jan-84 08:01:11 by LOMARTIRE
;Increase LOGBUF size again and interlock logging buffer at FRKER1
; Also adjust timing of trace logging to prevent overflows
; UPD ID= 457, SNARK:<6.UTILITIES>SCSTST.MAC.25,  25-Jan-84 10:41:08 by LOMARTIRE
;Log buffer counts before sending disconnect and make LOGCNT non-interruptable
; UPD ID= 451, SNARK:<6.UTILITIES>SCSTST.MAC.24,  24-Jan-84 12:47:03 by LOMARTIRE
;Rework handling of SCS% failures - do not die on SCSNEB or SCSNBA errors
; Also, implement nesting of PION and PIOFF
; UPD ID= 434, SNARK:<6.UTILITIES>SCSTST.MAC.23,  17-Jan-84 15:38:36 by LOMARTIRE
;Do not queue receive buffers before sends in DATAGRAM and MESSAGE tests
; Instead, fix bug in SCSJSY to allow the buffers to be queued upon connect
; UPD ID= 433, SNARK:<6.UTILITIES>SCSTST.MAC.22,  16-Jan-84 15:01:38 by LOMARTIRE
;Implement new scheme for SCSNEC error - retry after credit available interrupt
; Also, go PIOFF in DOSXG so that correct error code is obtained race-free
; UPD ID= 423, SNARK:<6.UTILITIES>SCSTST.MAC.21,   9-Jan-84 11:03:40 by LOMARTIRE
;Get correct level table address in STRTST and STRSRV routines
; UPD ID= 422, SNARK:<6.UTILITIES>SCSTST.MAC.20,   9-Jan-84 08:41:34 by LOMARTIRE
;Remove releasing of buffer from send done interrupt routine
; Also, only increment buffers sent count in the SNDDON interrupt routine
; UPD ID= 421, SNARK:<6.UTILITIES>SCSTST.MAC.19,   9-Jan-84 08:29:26 by LOMARTIRE
;Add maintenance function test
; UPD ID= 418, SNARK:<6.UTILITIES>SCSTST.MAC.18,   3-Jan-84 14:56:13 by LOMARTIRE
;Fix byte count in logical shifts when placing counts in optional data
; UPD ID= 417, SNARK:<6.UTILITIES>SCSTST.MAC.17,  27-Dec-83 09:42:02 by LOMARTIRE
;Rewrite segment handling in DMA and add .SSGDE to DMA interrupt routine
; UPD ID= 411, SNARK:<6.UTILITIES>SCSTST.MAC.15,  19-Dec-83 13:21:06 by LOMARTIRE
;Replace P6 with BUFFLG in DMAMAP to avoid clobbering TRVAR index
; UPD ID= 409, SNARK:<6.UTILITIES>SCSTST.MAC.14,  19-Dec-83 11:11:17 by LOMARTIRE
;Complete coding of DMA test
; UPD ID= 388, SNARK:<6.UTILITIES>SCSTST.MAC.12,  29-Nov-83 12:55:30 by LOMARTIRE
;Add some needed ERJMPs in FRKINT routine
; UPD ID= 387, SNARK:<6.UTILITIES>SCSTST.MAC.11,  29-Nov-83 12:33:57 by LOMARTIRE
;Loop and retry message send when SCSNEC is encountered
; UPD ID= 386, SNARK:<6.UTILITIES>SCSTST.MAC.10,  29-Nov-83 12:05:53 by LOMARTIRE
;Clear the link pointer of the requeued buffer when reflected
; UPD ID= 385, SNARK:<6.UTILITIES>SCSTST.MAC.9,  29-Nov-83 11:55:01 by LOMARTIRE
;Increase log buffer size so that it doesn't write over LEVTAB
; UPD ID= 384, SNARK:<6.UTILITIES>SCSTST.MAC.8,  29-Nov-83 11:36:20 by LOMARTIRE
;Don't halt during incoming DATAGRAM or MESSAGE routines due to SCSQIE
; UPD ID= 383, SNARK:<6.UTILITIES>SCSTST.MAC.7,  29-Nov-83 10:12:11 by LOMARTIRE
;Make sure STOP writes out correct test number
; UPD ID= 373, SNARK:<6.UTILITIES>SCSTST.MAC.6,  15-Nov-83 14:55:57 by LOMARTIRE
;Queue up receive buffers before starting sends in DATAGRAM and MESSAGE tests
; UPD ID= 372, SNARK:<6.UTILITIES>SCSTST.MAC.5,  15-Nov-83 14:45:36 by LOMARTIRE
;Add error handling after EXTENDs in DATAGRAM and MESSAGE interrupt routines
; UPD ID= 371, SNARK:<6.UTILITIES>SCSTST.MAC.4,  15-Nov-83 14:31:08 by LOMARTIRE
;Fix incorrect AC setup for BLTs in routines RETDAT and RETMSG
; UPD ID= 363, SNARK:<6.UTILITIES>SCSTST.MAC.3,  31-Oct-83 12:52:56 by LOMARTIRE
;Use Q2 instead of Q1 as AOBJN counter in SEND MESSAGE and DATAGRAM routines
; UPD ID= 362, SNARK:<6.UTILITIES>SCSTST.MAC.2,  31-Oct-83 12:46:56 by LOMARTIRE
;Change T1 to P1 at OK2DS - caused DISCONNECT NO-REASON-CODE test to fail

;DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY  OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE  SOFTWARE  IS  HEREBY
;TRANSFERRED.
;
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT  NOTICE
;AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY  OF  ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.


	TITLE SCSTST - TOPS-20 Systems Communications Service Tester
	SALL
	SEARCH	MONSYM,MACSYM,CMD
	.REQUIRE SYS:MACREL.REL,SYS:CMD

COMMENT #



***** description of SCSTST


#
	SUBTTL Symbol Definitions

	VMAJOR=1		;MAJOR VERSION NUMBER
	VMINOR=0		;MINOR VERSION NUMBER
	VEDIT=^D20		;EDIT NUMBER
	VWHO==0			;LAST EDITOR (0 = DEC DEVELOPMENT)

	VSCSTST==<VWHO>B2+<VMAJOR>B11+<VMINOR>B17+VEDIT

	T1=1			;ACS
	T2=2
	T3=3
	T4=4
	Q1=5
	Q2=6
	TST=7			;TEST STREAM NUMBER
	P1=10
	P2=11
	P3=12
	P4=13
	LP=14			;BP TO STRING TO BE LOGGED
	P6=15
	CX=16
	P=17

	NPDL==600		;SIZE OF PUSH DOWN LIST
	PAGSIZ==1000		;WORDS/PAGE
	MAXNOD==^D15		;MAX CI NODE NUMBER
	MAXTST==10		;MAXIMUM NUMBER OF TEST STREAMS (FORKS)
	NDATBF==10		;# OF DATGRAM BUFFERS PER CONNECTION
	DATBFL==^D152		;# OF WORDS IN A DATAGRAM BUFFER
	MXDWRD==^D152		;MAX WORDS IN A DATAGRAM
	MXDBYT==^D152*4		;MAX BYTES IN A DATAGRAM
	MXMWRD==^D38		;MAX WORDS IN A MESSAGE
	MXMBYT==^D38*4		;MAX BYTES IN A MESSAGE
	MXDMAW==PAGSIZ		;MAX WORDS IN A DMA SEGMENT
	MXDMAB==PAGSIZ*4	;MAX BYTES IN A DMA SEGMENT
	DGRAMS==NDATBF*DATBFL	;TOTAL # OF DATAGRAM BUFFERS
	NMSGBF==10		;# OF MESSAGE BUFFERS PER CONNECTION
	MSGBFL==^D38		;MESSAGE BUFFER LENGTH
	MSGS==NMSGBF*MSGBFL	;TOTAL # OF MESSAGE BUFFERS
	NDMAIN==4		;NUMBER OF INCOMING DMA BUFFERS
	NDMAOU==4		;NUMBER OF OUTGOING DMA BUFFERS
				; (NDMAOU MUST BE >= NDMAIN)
	NDMASG==5		;NUMBER OF SEGMENTS PER DMA BUFFER
	MAPLEN==^D13		;LENGTH OF .SSMAP ARG BLOCK
	OPTCHR==377		;FILL CHARACTER FOR CONNECT OPTIONAL DATA
	TIMCHN==4		;PSI CHANNEL FOR TIMER%
	LISCHN==5		;PSI CHANNEL FOR IIC% - START A NEW LISTENER
;SCSTST DISCONNECT/REJECT REASON CODES

	R.CON==101		;CONNECT TEST (NO OPTIONAL DATA) COMPLETE
	R.CONO==102		;CONNECT TEST (WITH OPTIONAL DATA) COMPLETE
	R.REJ==103		;REJECT TEST (NO REASON CODE) COMPLEETE
	R.REJR==104		;REJECT TEST (WITH REASON CODE) COMPLETE
	R.DIS==105		;DISCONNECT TEST (NO REASON CODE) COMPLETE
	R.DISR==106		;DISCONNECT TEST (WITH REASON CODE) COMPLETE
	R.IDL==107		;IDLE TEST COMPLETE
	R.DAT==110		;DATA TEST COMPLETE
	R.MSG==111		;MESSAGE TEST COMPLETE
	R.DMA==112		;DMA TEST COMPLETE
	R.MAIN==113		;MAINTENANCE TEST COMPLETE
	R.WOPD==120		;WRONG OPTIONAL DATA
	R.SNAC==121		;SHOULD NOT ACCEPT CONNECTION
	R.IVTN==122		;INVALID TEST NUMBER
	R.WDAT==123		;WRONG DATA
	SUBTTL Storage

;GLOBAL INFORMATION

	LOC 100000
DATOUB:	Z			;OUTBOUND DATAGRAM BUFFER POOL

	LOC 200000
MSGOUB:	Z			;OUTBOUND MESSAGE BUFFER POOL

	LOC 300000
DMABFS:	Z			;DMA BUFFER POOL

	LOC 500000
	CMDSTG			;COMND STORAGE
DBUGSW:	0			;DEBUGGING SWITCH
ONECOM:	0			;ONE-MORE-COMND FLAG
PDL:	BLOCK NPDL		;PDL FOR USER INTERFACE FORK
OURNUM:	0			;LOCAL CI NODE NUMBER
PMODE:	0			;SCSTST PROGRAM MODE
	INIMOD==1		;INITIATOR
	SRVMOD==2		;SERVER
LOGJFN:	0			;LOG FILE'S JFN
LOGFRK:	0			;LOGGING FORK'S FORK HANDLE
LOGLOK:	-1			;LOCK ON LOG BUFFER
LSTLGR:	0			;PC OF FORK OWNING THE LOGGING LOCK
LOGPTR:	POINT 7,LOGBUF		;CURRENT BP INTO LOG BUFFER
LOGDAT:	0			;DATA-TO-BE-LOGGED FLAG
LOGBUF:	BLOCK 15000		;THE LOGGING BUFFER
TAKJFN:	0			;TAKE FILE'S JFN
TRACEF:	0			;TRACE FLAG (0=TRACING, -1=NOT TRACING)

LEVTAB:	0,,L1PC
	0,,L2PC
	0,,L3PC
L1PC:	0
L2PC:	0
L3PC:	0

CHNTAB:	2,,DATINT		;DATAGRAM ARRIVED
	2,,MSGINT		;MESSAGE ARRIVED
	2,,DMAINT		;DMA TRANSFER COMPLETED
	2,,EVTINT		;SPECIAL EVENT OCCURRED
	2,,TIMINT		;TIMER JSYS INTERRUPT
	2,,LISINT		;START A NEW LISTENER
   REPEAT ^D13,<0>
	2,,FRKINT		;CHN 19, FORK HAS TERMINATED
   REPEAT ^D16,<0>		;THAT'S ALL

CHNMSK:	77B5!1B<19>

DGBUFR:	REPEAT ^D151,<BYTE (8)"A","B","C","D">
DMATXT:	BLOCK MXDMAW		   ;DMA TEXT FOR SEGMENTS
DATINB:	BLOCK MAXTST*NDATBF*DATBFL ;INBOUND DATAGRAM BUFFER POOL
MSGINB:	BLOCK MAXTST*NMSGBF*MSGBFL ;INBOUND MESSAGE BUFFER POOL
;PER TEST INFORMATION

TSTPDL:	BLOCK NPDL*MAXTST	;TEST PDLS
TSTPDP:	BLOCK MAXTST		;TEST PDL POINTERS
TSTLVP:	BLOCK MAXTST		;TEST LEVTAB POINTERS
TSTLEV:	BLOCK 3*MAXTST		;TEST LEVTABS
TSTIPC:	BLOCK 3*MAXTST		;INTERRUPT PC STORAGE


	DEFINE DEFTST(MAXTST),<	;;MACRO TO DEFINE ALL TESTS
	TSTIDX==0		;;INITIALIZE THE INDEX
	REPEAT MAXTST,<.DETST>>	;;LOOP FOR EACH TEST

	DEFINE .DETST,< 	;;MACRO TO DEFINE A TEST
	LOC TSTPDP+TSTIDX	;;GO TO STACK POINTER AREA
	IOWD NPDL,<TSTPDL+<TSTIDX*NPDL>> ;;DEFINE INITIAL STACK POINTER
	LOC TSTLVP+TSTIDX	;;GO TO LEVTAB POINT TABLE
	TSTLEV+3*TSTIDX 	;;LEVTAB POINTER
	LOC TSTLEV+3*TSTIDX	;;GO TO LEVTAB AREA
	TSTIPC+3*TSTIDX 	;;LEVEL 1 PC POINTER
	TSTIPC+3*TSTIDX+1	;;LEVEL 2 PC POINTER
	TSTIPC+3*TSTIDX+2	;;LEVEL 3 PC POINTER
	TSTIDX==TSTIDX+1	;;BUMP THE FORK INDEX
	LOC TSTEND
	>

	TSTEND==.

	DEFTST MAXTST		;DEFINE ALL THE FORK DATA
STATUS:	BLOCK MAXTST		;TEST STATUS, INDEXED BY TEST #
	MSKSTR TEST,STATUS,17B3	;CURRENT TEST
	  T.CON==0		;CONNECT - NO OTIONAL DATA
	  T.CONO==1		;CONNECT - OPTIONAL DATA
	  T.REJ==2		;REJECT - NO REASON
	  T.REJR==3		;REJECT - REASON
	  T.DIS==4		;DISCONNECT - NO REASON
	  T.DISR==5		;DISCONNECT - REASON
	  T.IDL==6		;IDLE CONNECTION
	  T.DAT==7		;DATAGRAM
	  T.MSG==10		;MESSAGE
	  T.DMA==11		;DMA
	  T.MAIN==12		;MAINTENANCE
	MSKSTR NAMES,STATUS,1B4	;DMA BUFFER NAMES HAVE BEEN RECEIVED
	MSKSTR NODE,STATUS,37B11 ;REMOTE NODE
	MSKSTR DONE,STATUS,1B12	;TEST IS DONE
	MSKSTR STATE,STATUS,7B15 ;STATE OF THE TEST
	  S.STRT==1		;STARTING
	  S.RUN==2		;RUNNNING
	  S.STOP==3		;STOPPING
	  S.HALT==4		;HALTED
	  S.LIS==5		;LISTENING
	MSKSTR TMODE,STATUS,3B17 ;TRANSFER MODE
	  M.INDC==1		;INDUSTRY COMPATIBLE
	  M.HIGH==2		;HIGH DENSITY
	MSKSTR FORKH,STATUS,777777B35 ;FORK HANDLE

COUNT:	BLOCK MAXTST		;BYTE OR WORD COUNT
TTIME:	BLOCK MAXTST		;TEST DURATION (IN SECONDS)
ITIME:	BLOCK MAXTST		;INTERNAL TIME FORMAT FOR TEST DURATION
STIME:	BLOCK MAXTST		;BEGIN TIME
ETIME:	BLOCK MAXTST		;END TIME
PSISYS:	BLOCK MAXTST		;STATE OF PI SYSTEM - 0=ON, >0 = NESTING LEVEL
BUFNUM:	BLOCK MAXTST		;NUMBER OF DMA BUFFERS FOR TEST
SEGSIZ:	BLOCK MAXTST		;SEGMENT SIZE
SEGNUM:	BLOCK MAXTST		;NUMBER OF SEGMENTS PER BUFFER
CONID:	BLOCK MAXTST		;CONNECT ID
SBI:	BLOCK MAXTST		;SBI
DATGIN:	BLOCK MAXTST		;ADDR OF TEST'S FIRST INCOMING DATAGRAM BUFFER
DATGOU:	BLOCK MAXTST*NDATBF	;ADDRS OF TEST'S OUTGOING DATAGRAM BUFFERS
MSGIN:	BLOCK MAXTST		;ADDR OF TEST'S FIRST INCOMING MESSAGE BUFFER
MSGOU:	BLOCK MAXTST*NMSGBF	;ADDRS OF TEST'S OUTGOING MESSAGE BUFFERS
LSTERR:	BLOCK MAXTST		;TEST'S LAST ERROR
CREDIT:	BLOCK MAXTST		;CREDIT AVAILABLE FLAG
BUFSNT:	BLOCK MAXTST		;# OF BUFFERS SENT
BUFRCV:	BLOCK MAXTST		;# OF BUFFERS RECEIVED
DMASND:	BLOCK MAXTST		;NUMBER OF DMA SENDS COMPLETED
DMAREQ:	BLOCK MAXTST		;NUMBER OF DMA READS COMPLETED
DMAINB:	BLOCK MAXTST*NDMAIN	;LIST OF INCOMING BUFFER ADDRS
DMAISG:	BLOCK MAXTST*NDMASG*NDMAIN  ;LIST OF INCOMING BUFFER SEGMENTS
DMAOSG:	BLOCK MAXTST*NDMASG*NDMAOU  ;LIST OF OUTGOING BUFFER SEGMENTS
DMAOUB:	BLOCK MAXTST*NDMAOU	;LIST OF OUTGOING BUFFER ADDRS
DMAMIN:	BLOCK MAXTST*NDMAIN	;LIST OF INCOMING BUFFER NAMES
DMAMOU:	BLOCK MAXTST*NDMAOU	;LIST OF OUTGOING BUFFER NAMES
DMAREM:	BLOCK MAXTST*NDMAIN	;LIST OF REMOTE'S DMA BUFFER NAMES
	MAP.OI==-1		;MAP INCOMING AND OUTGOING BUFFERS
	MAP.IN==0		;MAP ONLY INCOMING BUFFERS
	UMP.OI==-1		;UNMAP INCOMING AND OUTGOING BUFFERS
	UMP.IN==0		;UNMAP ONLY INCOMING BUFFERS
MNTFLG:	BLOCK MAXTST		;MAINTENANCE TEST FLAG
;PROTOTYPE ARGUMENT BLOCKS

SSAIC:	0,,5			;SCS% (.SSAIC) ARG BLOCK
	.SIDGA,,0
	.SIMSA,,1
	.SIDMA,,2
	.SIPAN,,3

SSCON:	0,,.LBCON		;SCS% (.SSCON) ARG BLOCK
	-1,,SCSNAMO		;BP TO SOURCE PROCESS NAME
	-1,,SCSNAM		;BP TO DESTINATION PROCESS NAME
	0
	0
	0
	0
	0

SCSNAM:	ASCIZ/SCS$TESTER/

SSACC:	0,,.LBACC		;SCS% (.SSACC) ARG BLOCK
	0
	0

SSLIS:	0,,.LBLIS		;SCS% (.SSLIS) ARG BLOCK
	-1,,SCSNAM
	-1,,SCSNAM
	0
	0
	0
	0


SSEVT:	0,,.LBEVT
	-1
	0
	0
	0
	0
	0
	0


;ENTRY VECTOR

EVEC:	JRST START		;INITIAL START
	JRST START		;REENTER START
	EXP VSCSTST		;VERSION

	RELOC 0
	SUBTTL Macros

;TYPE OUT A STRING

DEFINE TYPE (S),<
	HRROI T1,[ASCIZ/S/]
	PSOUT>

;TYPE OUT A STRING FOLLOWED BY A CRLF

DEFINE TYPEN (S),<
	HRROI T1,[ASCIZ/S
/]
	PSOUT>

;TYPE OUT A CRLF

DEFINE TCRLF,<
	HRROI T1,[ASCIZ/
/]
	PSOUT>

;SAVE THE ACS ON THE STACK

DEFINE SAVACS,<CALL .SAVAC>

;TURN PI SYSTEM OFF

DEFINE PIOFF,<CALL .PIOFF>

;TURN PI SYSTEM ON

DEFINE PION,<CALL .PION>
;OUTPUT A STRING TO THE LOG FILE

DEFINE LOG (S),<
	HRROI T2,[ASCIZ/S/]
	CALL LOGASZ>

;OUTPUT A STRING, FOLLOWED BY A CRLF, TO THE LOG FILE

DEFINE LOGN (S),<
	HRROI T2,[ASCIZ/S
/]
	CALL LOGASZ>

;OUTPUT A CRLF TO THE LOG FILE

DEFINE LCRLF,<
	HRROI T2,[ASCIZ/
/]
	CALL LOGASZ>

 ;LOG A TEST IDENTIFIER (PRECEDED BY A "#")

DEFINE LOGIDG,<
	LOG (
# Test #)
	MOVE T2,TST
	CALL LOGDEC>

;LOG A TEST IDENTIFIER (PRECEDED BY A "?")

DEFINE LOGIDE,<
	LOG (
? Test #)
	MOVE T2,TST
	CALL LOGDEC>

;LOG A TEST IDENTIFIER (PRECEDED BY A "%")

DEFINE LOGIDW,<
	LOG (
% Test #)
	MOVE T2,TST
	CALL LOGDEC>
	SUBTTL Initialization

START:	RESET			;INITIALIZE ALL
	MOVE T1,[BYTE (8) "1","2","3","4"]  ;GET DMA TEXT
	MOVEM T1,DMATXT		;PLACE IN FIRST WORD OF TEXT BUFFER
	MOVEI T1,DMATXT+1	;INITIALIZE THE
	HRLI T1,DMATXT		; REST OF
	BLT T1,DMATXT+MXDMAW-1	; THE DMA TEXT BUFFER
	MOVX T1,GJ%SHT
	HRROI T2,[ASCIZ/TTY:/]
	GTJFN
	 ERJMP FATAL
	MOVEM T1,LOGJFN		;SAVE LOG FILE JFN
	MOVE P,[IOWD NPDL,PDL]	;SET UP PUSH DOWN LIST
START1:	MOVX T1,.SSAIC		;SET UP SCS% PSI
	MOVEI T2,SSAIC		;ADDR OF ARG BLOCK
	PIOFF			;NO INTERRUPTS
	SCS%
	IFJER.			;FAILED
	  CALL SCSERR		;PROCESS SCS ERROR
	  JRST START1		;CONTINUE
	  JRST FATAL		;IT WAS A FATAL ONE
	ENDIF.
	PION			;ALLOW INTERRUPTS
	MOVX T1,.FHSLF		;THIS PROCESS
	MOVE T2,[LEVTAB,,CHNTAB] ;GET PSI TABLES
	SIR			;SET PSI TABLES
	 ERJMP FATAL
	EIR			;ENABLE PSI
	 ERJMP FATAL
	MOVE T2,CHNMSK		;GET CHANNEL MASK
	AIC			;ACTIVATE INTERRUPTS
	 ERJMP FATAL

;SCS% argument blocks and a sub-fork's ACs are on the stack

	TRVAR <<TSTACS,20>,<EVTBLK,.LBEVT>,<RCDBLK,.LBRCD>,<CONBLK,.LBCON>,<OPTDAT,SQ%CDT>,<LISBLK,.LBLIS>,<ACCBLK,.LBACC>,<REJBLK,.LBREJ>,<DISBLK,.LBDIS>,<CSPBLK,.LBCSP>,<STSBLK,.LBSTS>,<GLNBLK,.LBGLN>,<QRXBLK,.LBQRD>,<SXGBLK,.LBSDG>,<RXGBLK,.LBRDG>,<GDEBLK,.LBGDE>,<MAPBLK,MAPLEN>,<UMPBLK,.LBUMP>,<SNDBLK,.LBSND>,<REQBLK,.LBREQ>,TSTNOD,TSTTYP,TSTCOU,TSTITM,TSTTTM,TSTMOD,TSTBNM,TSTSCT>

	CALL DOGLN		;(/T1) GET LOCAL NODE NUMBER
	IFNSK.
	  TYPEN (
% No CI nodes currently available)
	  SETOM OURNUM		;NO NODE NUMBER YET
	ELSE.
	  MOVEM T1,OURNUM	;SAVE NODE NUMBER RETURNED
	ENDIF.

	CALL LOGINI		;() START THE LOGGING FORK
	CALL CMDINI		;() INITIALIZE COMND JSYS

;.....
	SUBTTL Main Command Loop

COMAND:	STKVAR <FLAGS,ERR>
	PROMPT (SCSTST>)	;PROMPT FOR COMND
	MOVEI T1,[FLDDB. .CMKEY,,CMDTAB]  ;WANT A KEYWORD
	CALL RFLDE		;(T1) READ THE COMMAND
	IFNSK.
	  MOVEM T1,FLAGS	;SAVE FLAGS FROM COMND
	  MOVEI T1,.FHSLF	;GET THE
	  GETER			; ERROR
	   ERJMP CMDER1		;MOVE TO NEXT COMMAND
	  MOVEM T2,ERR		;PRESERVE ERROR
	  MOVE T1,FLAGS		;RETRIEVE COMND FLAGS
	  TXNN T1,CM%NOP	;NO PARSE?
	  IFSKP.
	    TYPE (
? )				;YES
	    MOVEI T1,.PRIOU	;PUT
	    MOVE T2,[.FHSLF,,-1] ; THE
	    SETZ T3,		; ERROR
	    ERSTR		; ON THE TTY
	     NOP
	     NOP
	    JRST CMDER1		;CLEAN UP COMND
	  ENDIF.
	  SKIPN TAKJFN		;NO, DOING A TAKE FILE?
	  JRST CMDER1		;NO, TOO BAD
	  HRRZ T2,ERR		;DON'T NEED THE FORK HANDLE, ONLY THE ERROR
	  CAIE T2,IOX4		;WAS IT END OF FILE?
	  JRST CMDER1		;NO, CLEAN UP COMND AND GO TO NEXT COMMAND
	  HRRZ T1,TAKJFN	;GET THE TAKE FILE
	  CLOSF			;CLOSE IT
	   ERJMP FATAL		;KILL EVERYTHING
	  TYPE (
[End of command file])
	  SETZM TAKJFN		;NO MORE TAKE FILE
	  MOVE T1,[.PRIIN,,.PRIOU] ;POINT COMND
	  MOVEM T1,SBK+.CMIOJ	; AT TTY AGAIN
	ELSE.
	  MOVE T1,(T2)		;GET DISPATCH ADDR FOR COMMAND
	  CALL (T1)		;GO DO IT
	ENDIF.
;...
	SKIPN ONECOM		;ARE WE IN ONE MORE COMND MODE?
	JRST COMAND		;NO, NOTHING SPECIAL
	SKIPG ONECOM		;YES, WAS THIS THE LAST ONE?
	IFSKP.
	  SKIPE ONECOM		;YES, WAIT FOR
	  JRST .-1		; FLAG TO CLEAR
	ELSE.
	  MOVEI T1,1		;NO, THE NEXT ONE IS
	  MOVEM T1,ONECOM	;SET THE FLAG
	ENDIF.
	JRST COMAND

	ENDSV.



CMDTAB:	CMD,,CMD
	T COMND-IS-OUT-TO-LUNCH,DBUG
	T DECLARE,DCLARE
	T DISABLE,DABLE
	T ENABLE,ENABL
	T EXIT
	T HELP
	T ONE-MORE-COMND-BEFORE-LUNCH,ONEMOR
	T SHOW
	T STOP
	T TAKE
	T TEST
	T WAIT
	CMD==.-CMDTAB-1
	SUBTTL The Logging Fork

;CREATE AND START THE LOGGING FORK
;RETURNS:	+1

LOGINI:	MOVEI T2,1+TSTACS	;INIT
	HRLI T2,TSTACS		; THE
	SETZM TSTACS		; ACS
	BLT T2,17+TSTACS
	MOVE T1,[CR%MAP!CR%CAP!CR%ACS] ;SAME MAP AND CAPABILITIES, SET THE ACS
	MOVEI T2,TSTACS		;SET THE AC BASE
	CFORK			;CREATE AND START THE FORK
	IFJER.
	  TYPEN (
? Fatal error - unable to create logging fork)
	  JRST FATAL
	ENDIF.
	MOVEM T1,LOGFRK		;SAVE FORK HANDLE
	MOVEI T2,LOGST		;GET FORK'S STARTING ADDR
	SFORK			;START THE FORK
	IFJER.
	  TYPEN (
? Fatal error - unable to start logging fork)
	  JRST FATAL
	ENDIF.
	RET


LOGST:	SKIPE LOGJFN		;ARE WE LOGGING?
	SKIPN LOGDAT		;YES, ANYTHING TO LOG?
	JRST LOGST1		;NO
	AOSE LOGLOK		;YES, LOCK AVAILABLE?
	IFSKP.
	  MOVEI T1,.		;YES, GET PC
	  MOVEM T1,LSTLGR	;STASH IT
	  HRRZ T1,LOGJFN	;GET LOG FILE
	  MOVE T2,[7B5+OF%APP]	;APPEND
	  OPENF
	   JSERR
	  MOVE T2,[POINT 7,LOGBUF] ;GET BP
	  SETZB T3,T4		;NOTHING SPECIAL
	  SOUT
	   ERJMP FATAL
	  MOVE T1,[POINT 7,LOGBUF] ;RESET
	  MOVEM T1,LOGPTR	; BP
	  MOVX T1,CO%NRJ	;DON'T RELEASE JFN
	  HRR T1,LOGJFN		; WHEN CLOSING LOG FILE
	  CLOSF
	   ERJMP FATAL
	  SETZM LOGDAT		;RESET THE DATA-TO-BE-LOGGED FLAG
	  SETOM LOGLOK		;DONE WITH THE LOCK
	  SETZM LSTLGR		;NO ONE LOGGING NOW
	ENDIF.
LOGST1:	MOVEI T1,^D1000		;WAIT
	DISMS			; HERE
	JRST LOGST		;TRY AGAIN
	SUBTTL DEBUG Command

;DEBUG IS USED WHEN YOU EXPECT TO HIT BREAKPOINTS AND YOU
;DON'T WANT COMND TO BE WAITING FOR INPUT

DBUG:	CONFRM
	SKIPN DBUGSW		;STILL DEBUGGING?
	JRST .-1		;YES
	MOVEI T1,^D3000		;NO, WAIT
	DISMS			; A BIT

;Waiting allows you to deposit something in DBUGSW and type $P

	RET			;GO BACK TO ACCEPTING COMMANDS

;SET THE FLAG WHICH TELLS THE COMMAND PROCESSOR TO PROCESS ON MORE COMMAND
;THEN WAIT FOR THE FLAG TO CLEAR BEFORE GOING BACK FOR THE NEXT COMMAND

ONEMOR:	CONFRM
	SETOM ONECOM
	RET
;DECLARE COMMAND

DCLARE:	NOISE (SCSTST TO BE THE)
	MOVEI T1,[FLDDB. .CMKEY,,DECTAB]
	CALL RFIELD
	MOVE T1,(T2)
	CALL (T1)
	RET

DECTAB:	DECTBL,,DECTBL
	T INITIATOR,INITIA
	T SERVER,SERVER
	DECTBL=.-DECTAB-1


;DECLARE AN INITIATOR

INITIA:	CONFRM
	MOVE T1,PMODE		;GET CURRENT MODE
	CAIE T1,SRVMOD		;SERVER?
	IFSKP.
	  TYPE (
? Must restart SCSTST to change program modes)
	ELSE.
	  MOVEI T1,INIMOD	;NO, GET INITIATOR INDICATOR
	  MOVEM T1,PMODE	;SET IT
	ENDIF.
	RET
;DECLARE A SERVER

SERVER:	CONFRM
	MOVE T1,PMODE		;GET CURRENT MODE
	CAIE T1,INIMOD		;INITIATOR?
	IFSKP.
	  TYPE (
? Must restart SCSTST to change program modes)
	  RET
	ELSE.
	  CAIE T1,SRVMOD	;NO, ALREADY IN SERVER MODE?
	  IFSKP.
	    MOVSI T1,-MAXTST	;YES, AOBJN WORD FOR ALL TEST STREAMS
SERVR1:	    SKIPE STATUS(T1)	;THIS ONE IN USE?
	    RET			;YES, WE'RE ALL SET
	    AOBJN T1,SERVR1	;NO, TRY NEXT STREAM
	    SETZ T4,		;NONE IN USE, ASSIGN STREAM 0
	    JRST SERVR2		;MOVE ON
	  ENDIF.
	  MOVEI T1,SRVMOD	;NO, GET SERVER INDICATOR
	  MOVEM T1,PMODE	;SET IT
	ENDIF.
	CALL GETTST		;(/T4) GET A TEST STREAM
	IFNSK.
	  TYPE (
? SCSTST internal error - impossible to continue)
	  JRST FATAL
	ENDIF.
SERVR2:	MOVE P1,T4		;PRESERVE STREAM #
	MOVX P2,S.LIS		;INITIAL STATE IS LISTENING
	MOVEI P3,STRSRV		;START THE FORK HERE
	CALL STRFRK		;(P1,P2,P3) START A SERVER FORK
	IFNSK.
	  TYPEN (
? Failure in creating initial listener:  )
	  JSERR
	ENDIF.
	RET
	SUBTTL Start a Server Stream

STRSRV:	MOVE P,TSTPDP(TST)	;LOAD PDL WORD
	MOVX T1,.SSAIC		;SET UP SCS% PSI
	MOVEI T2,SSAIC		;ADDR OF ARG BLOCK
	PIOFF			;NO INTERRUPTS
	SCS%
	IFJER.			;FAILED
	  CALL SCSERR		;PROCESS SCS ERROR
	  JRST STRSRV		;CONTINUE
	  JRST FATAL		;THIS ONE WAS FATAL
	ENDIF.
	PION 			;ALLOW INTERRUPTS
	MOVEI T1,.FHSLF		;THIS FORK
	MOVEI T2,CHNTAB		;CHANNEL TABLE ADDR
	HRL T2,TSTLVP(TST)	;LEVEL TABLE ADDR
	SIR			;SET PSI INFO
	 ERJMP FATAL		;FAILED
	SETZM PSISYS(TST)	;SYSTEM WILL BE ON
	EIR			;ENABLE PSI SYSTEM
	 ERJMP FATAL		;FAILED
	MOVE T2,CHNMSK		;GET CHANNEL MASK
	AIC			;ACTIVATE INTERRUPTS
	 ERJMP FATAL		;FAILED
	SETOM P1		;ACCEPT FROM ANY NODE
	MOVEM TST,P2		;USE CONNECTION # AS MY PART OF CID
	CALL DOLIS		;(P1,P2) GO SET UP A LISTENER
	 JRST FATAL		;FAILED
	HRROI LP,[ASCIZ/listening
	CALL TRACE		;LOG IT
	WAIT			;PSI WILL TELL US WHEN SOMETHING HAPPENS
	SUBTTL DISABLE Command

DABLE:	NOISE (TEST FEATURE)
	MOVEI T1,[FLDDB. .CMKEY,,DISTAB]
	CALL RFIELD
	MOVE T1,(T2)
	CALL (T1)
	RET

DISTAB:	DISTBL,,DISTBL
	T LOGGING,DISLOG
	T TRACING,DITRAC
	DISTBL=.-DISTAB-1

;DISABLE LOGGING

DISLOG:	CONFRM
	SKIPN T1,LOGJFN		;GET CURRENT LOG FILE
	RET			;NOT LOGGING
	RLJFN			;RELEASE THE JFN
	 ERJMP FATAL
	SETZM LOGJFN		;NO MORE LOG FILE
	RET


;DISABLE TRACING

DITRAC:	CONFRM
	SETZM TRACEF		;SET FLAG WORD OFF
	RET
	SUBTTL ENABLE Command

ENABL:	NOISE (TEST FEATURE)
	MOVEI T1,[FLDDB. .CMKEY,,ENATAB]
	CALL RFIELD
	MOVE T1,(T2)
	CALL (T1)
	RET

ENATAB:	ENATBL,,ENATBL
	T LOGGING,ENLOG
	T TRACING,ENTRAC
	ENATBL=.-ENATAB-1


;ENABLE LOGGING

ENLOG:	NOISE (OUTPUT TO)
	MOVEI T1,[FLDDB. .CMOFI] ;WANT AN OUTPUT FILE
	CALL CFIELD		;(T1) GET IT
	SKIPN T1,LOGJFN		;CURRENTLY LOGGING?
	IFSKP.
	  RLJFN			;YES, RELEASE IT
	   ERJMP FATAL
	ENDIF.
	MOVEM T2,LOGJFN		;SAVE NEW FILE
	RET


;ENABLE TRACING

ENTRAC:	CONFRM
	SETOM TRACEF		;SET FLAG WORD ON
	RET


;EXIT COMMAND

.EXIT:	NOISE (TO TOPS-20 COMMAND LEVEL)
	CONFRM
	HALTF
	RET			;CONTINUABLE
	SUBTTL HELP Command

.HELP:	NOISE (WITH SCSTST)
	CONFRM
	HRROI T1,HLPTXT		;BP TO TEXT
	PSOUT
	 ERJMP .+1
	RET


HLPTXT:	ASCIZ\
SCSTST is used to test TOPS-20's implementation of Digital's Systems
Communication Architecture.  SCSTST runs on TOPS-20 systems only;  it runs
in either "server" or "initiator" mode, but not both simultaneously.
Use the DECLARE command to select the desired mode.

TTY: is the default log file;  logging can be directed to any file by using
the ENABLE command or logging can be turned off by using the DISABLE command.

Tracing provides the results of each SCS% JSYS executed, the output going
to the log file.  It is if off by default and is controlled by ENABLE/DISABLE.

Use the SHOW command to obtain the current status of SCSTST's test streams.
The output of SHOW always goes to TTY:.

The TAKE command causes SCSTST to execute commands from a file.  Note:  TAKE
is ignored if it is encountered in a file being TAKEn.

Use the STOP command to abort a currently running test stream.

The WAIT command causes SCSTST not to execute the next command until the
supplied time period has elapsed;  WAIT is intended for use in command files.

SCSTST is continuable after an EXIT to TOPS-20 command level.

\
	SUBTTL SHOW Command

.SHOW:	NOISE (CURRENT TEST PARAMETERS)
	CONFRM
	TCRLF
	TYPEN ( TEST ENVIRONMENT)
	TCRLF

;SCSTST MODE

.SHOPM:	TYPE (  TEST MODE:		)
	MOVE T1,PMODE		;GET PROGRAM MODE
	CAIE T1,SRVMOD		;ARE WE THE SRVER?
	IFSKP.
	  TYPEN (Server)	;YES
	ELSE.
	  CAIE T1,INIMOD	;NO, ARE WE THE INITATOR?
	  IFSKP.
	    TYPEN (Initiator)	;YES
	  ELSE.
	    TYPEN (none specified)
	  ENDIF.
	ENDIF.

;LOCAL NODE NUMBER

.SHOLN:	TYPE (  LOCAL NODE:		)
	SKIPGE T2,OURNUM	;GET OUR CI NODE NUMBER
	IFSKP.
	  CALL TYPNUM		;(T2) OUTPUT IT
	  TCRLF
	ELSE.
	  TYPEN (unknown)	;don't know it
	ENDIF.

;LOG FILE

.SHOLG:	TYPE (  LOG FILE:		)
	SKIPE LOGJFN		;ARE WE LOGGING?
	IFSKP.
	  TYPEN (logging disabled)
	ELSE.
	  MOVEI T1,.PRIOU		;OUTPUT TO TTY
	  MOVE T2,LOGJFN		;GET LOG FILE
	  SETZ T3,		;NO SPECIAL FORMAT
	  JFNS			;OUTPUT THE STRING
	   ERJMP [JSERR
		  JRST .+1]
	  TCRLF
	ENDIF.

;TRACE

.SHOTR:	TYPE (  TRACING:		)
	SKIPN TRACEF		;TRACE FLAG ON?
	IFSKP.
	  TYPEN (On)		;YES
	ELSE.
	  TYPEN (Off)		;NO
	ENDIF.
	TCRLF
	TYPEN ( TEST PARAMETERS)

	MOVSI Q1,-MAXTST	;AOBJN WORD FOR ALL TEST STREAMS
.SHOLP:	SKIPN T1,STATUS(Q1)	;STREAM IN USE?
	JRST .SHONX		;NO, MOVE ON
	TCRLF
	TYPE (  Test #)
	HRRZ T2,Q1		;GET STREAM #
	CALL TYPNUM		;(T2) OUTPUT IT
	TCRLF

;STATE

.SHOST:	TYPE ( STATE:			)
	MOVEI T1,.PRIOU		;OUTPUT TO TTY
	LOAD T2,STATE,(Q1)	;GET STATE OF THIS TEST
	SOS T2			;THERE IS NO "0" STATE
	HRRO T2,[EXP[ASCIZ/Starting/]
		 EXP[ASCIZ/Running/]
		 EXP[ASCIZ/Stopping/]
		 EXP[ASCIZ/Halted/]
		EXP[ASCIZ/Listening/]](T2)
	SETZ T3,		;ASCIZ STRING
	SOUT
	 ERJMP [JSERR
		JRST .+1]
	TCRLF
	LOAD T2,STATE,(Q1)	;GET BACK STATE
	CAIN T2,S.LIS		;WAS IT LISTENING?
	JRST .SHODN		;YES, NOTHING MORE TO SAY

;NODE

.SHOND:	TYPE (  NODE:			)
	LOAD T2,NODE,(Q1)	;GET REMOTE NODE #
	CALL TYPNUM		;(T2) OUTPUT IT
	TCRLF

;TEST

.SHOTS:	TYPE (  TEST:			)
	MOVEI T1,.PRIOU		;TO THE TTY
	LOAD T2,TEST,(Q1)	;GET CURRENT TEST
	HRRO T2,[EXP[ASCIZ/Connect (no optional data)/]
		 EXP[ASCIZ/Connect (optional data)/]
	  	 EXP[ASCIZ/Reject (no reason code)/]
	  	 EXP[ASCIZ/Reject (reason code)/]
		 EXP[ASCIZ/Disconnect (no reason code)/]
		 EXP[ASCIZ/Disconnect (reason code)/]
		 EXP[ASCIZ/Idle/]
		 EXP[ASCIZ/Datagram/]
		 EXP[ASCIZ/Message/]
		 EXP[ASCIZ/DMA/]
		 EXP[ASCIZ/Maintenance/]](T2)
	SETZ T3,
	SOUT
	 ERJMP [JSERR
		JRST .+1]
	TCRLF

	LOAD T2,TEST,(Q1)	;RETRIEVE TEST TYPE
	CAIG T2,T.IDL		;IS IT A DATA MOVER?
	JRST .SHONX		;NO

;TIME

	CALL SHOTIM		;YES, OUTPUT THE TEST DURATION

;TRANSFER MODE

.SHOTM:	TYPE (  MODE:			)
	LOAD T2,TMODE,(Q1)	;GET TRANSFER MODE
	CAIE T2,M.INDC		;IS IT I.C.?
	IFSKP.
	  TYPEN (Industry Compatible) ;YES
	ELSE.
	  TYPEN (High Density) ;NO
	ENDIF.

;COUNT

.SHOBC:	LOAD T1,TMODE,(Q1)	;GET TRANSFER MODE
	CAIE T1,M.INDC		;INDUSTRY COMPATIBLE?
	IFSKP.
	  TYPE (  BYTE COUNT:		) ;YES
	ELSE.
	  TYPE (  WORD COUNT:		) ;NO
	ENDIF.
	MOVE T2,COUNT(Q1)	;GET BYTE COUNT
	CALL TYPNUM		;(T2) OUTPUT IN DECIMAL
	TCRLF

;BUFFER NUMBER

.SHOBN:	TYPE (  BUFFERS:		)
	MOVE T2,BUFNUM(Q1)	;GET BUFFER SIZE
	CALL TYPNUM		;(T2) OUTPUT IN DECIMAL
	TCRLF

;SEGMENT SIZE

.SHOSS:	TYPE (  SEGMENT SIZE:		)
	MOVE T2,SEGSIZ(Q1)	;GET BUFFER POOL
	CALL TYPNUM		;(T2) OUTPUT IN DECIMAL
	TCRLF

;SEGMENT COUNT

.SHOSC:	TYPE (  SEGMENTS:		) 
	MOVE T2,SEGNUM(Q1)	;GET BUFFER POOL
	CALL TYPNUM		;(T2) OUTPUT IN DECIMAL
	TCRLF			

.SHONX:	AOBJN Q1,.SHOLP		;DO ALL TEST STREAMS
.SHODN:	TCRLF
	RET


;SHOW TEST DURATION
;ACCEPTS:	Q1/ TEST #
;RETURNS:	+1

SHOTIM:	MOVE T1,PMODE		;GET SCSTST MODE
	CAIE T1,INIMOD		;INITIATOR?
	RET			;NO, DONE
	TYPE (  TIME:			) ;YES
	MOVEI T1,.PRIOU		;GET OUTPUT FILE
	MOVE T2,ITIME(Q1)	;RETRIEVE INTERNAL TIME
	MOVX T3,OT%NDA		;DON'T OUTPUT THE DATE
	ODTIM
	 ERJMP [JSERR
	 	JRST .+1]
	TCRLF
	RET
	SUBTTL STOP Command

.STOP:	NOISE (TEST #)
	MOVEI T1,[FLDDB. .CMNUM,,12]
	CALL CFIELD
	CALL CKTNUM		;(T2) VALIDATE TEST NUMBER
	 RET			;FAILED
	MOVE T4,T2		;PRESERVE TEST NUMBER
 	MOVE TST,T2		;PLACE IN TST FOR LOGGER
        SKIPE STATUS(T4)	;THIS TEST STREAM IN USE?
	IFSKP.
	  HRROI LP,[ASCIZ/No such test/]
	  CALL LOGW		;LOG WARNING
	  RET
	ENDIF.
	LOAD T1,FORKH,(T4)	;GET THE FORK HANDLE FOR THIS TEST
	KFORK			;KILL THE TEST
	 ERJMP [JSERR
		JRST .+1]
	SETZM STATUS(T4)	;NO MORE TEST STREAM
	HRROI LP,[ASCIZ/stopped/]
	CALL TRACE
	RET
	SUBTTL TAKE Command

.TAKE:	NOISE (COMMANDS FROM)
	MOVEI T1,[FLDDB. .CMIFI,,,,<SCSTST.CMD>]
	CALL CFIELD
	SKIPN TAKJFN		;ALREADY DOING A FILE?
	IFSKP.
	  TYPE (
% TAKE within a file is not allowed - command ignored)
	  RET
	ENDIF.
	MOVEM T2,TAKJFN		;STORE TAKE FILE JFN
	HRRI T1,.NULIO		;OUTPUT TO OZONE
	HRL T1,T2		;POINT COMND
	MOVEM T1,SBK+.CMIOJ	; AT THE FILE
	HRRZ T1,T2		;GET JUST JFN
	MOVE T2,[7B5+OF%RD]	;OPEN FILE FOR READ
	OPENF
	 ERJMP [JSERR
		JRST .+1]
	RET
	SUBTTL TEST Command

.TEST:	NOISE (TO NODE)
	MOVEI T1,[FLDDB. .CMNUM,CM%SDH,12,<CI node number>]
	CALL RFIELD
	CALL CKINIT		;() MUST BE INITIATOR
	 RET			;WE'RE NOT
	CAIL T2,0		;MUST BE
	CAILE T2,MAXNOD		; LEGAL CI NODE NUMBER
	IFSKP.
	  MOVEM T2,TSTNOD	;OK, STORE IT AWAY
	ELSE.
	  TYPEN (
? Illegal CI node number)
	  RET
	ENDIF.
	NOISE (FEATURE)
	MOVEI T1,[FLDDB. .CMKEY,,TSTTAB]
	CALL RFIELD
	MOVE T1,(T2)
	CALL (T1)
	RET


TSTTAB:	TSTTBL,,TSTTBL
	T CONNECT,CONECT
	T DATAGRAMS,DATAG
	T DISCONNECT,DISCON
	T DMA-TRANSFERS,DMAT
	T IDLE-CONNECTION,IDLE
	T MAINTENANCE,MAINT
	T MESSAGES,MESSAG
	T REJECT,RJECT
	TSTTBL=.-TSTTAB-1
;CONNECT

CONECT:	NOISE (WITH)
	MOVEI T1,[FLDDB. .CMKEY,,CONTAB]
	CALL RFIELD
	MOVE T1,(T2)
	CALL (T1)
	RET


CONTAB:	CONTBL,,CONTBL
	T NO-OPTIONAL-DATA,CONNOP
	T OPTIONAL-DATA,CONOP
	CONTBL==.-CONTAB-1


;CONNECT WITH NO OPTIONAL DATA

CONOP:	CONFRM
	MOVEI T1,T.CONO
	CALL CDRFIN		;(T1)
	RET


;CONNECT WITH OPTIONLA DATA

CONNOP:	CONFRM
	MOVEI T1,T.CON
	CALL CDRFIN		;(T1)
	RET
;DISCONNECT

DISCON:	NOISE (WITH)
	MOVEI T1,[FLDDB. .CMKEY,,DSCTAB]
	CALL RFIELD
	MOVE T1,(T2)
	CALL (T1)
	RET


DSCTAB:	DSCTBL,,DSCTBL
	T NO-REASON-CODE,DISNR
	T REASON-CODE,DISR
	DSCTBL==.-DSCTAB-1


;DISCONNECT WITH NO REASON CODE

DISNR:	CONFRM
	MOVEI T1,T.DIS
	CALL CDRFIN		;(T1)
	RET


;DISCONNECT WITH REASON CODE

DISR:	CONFRM
	MOVEI T1,T.DISR
	CALL CDRFIN		;(T1)
	RET



;FINISH UP A NON-DATA MOVING TEST
;ACCEPTS:	T1/ TEST TYPE
;RETURNS:	+1

CDRFIN:	MOVEM T1,TSTTYP		;STASH THE TEST TYPE
	CALL .TESTF		;FINISH TEST SET UP
	RET
;REJECT

RJECT:	NOISE (WITH)
	MOVEI T1,[FLDDB. .CMKEY,,REJTAB]
	CALL RFIELD
	MOVE T1,(T2)
	CALL (T1)
	RET


REJTAB:	REJTBL,,REJTBL
	T NO-REASON-CODE,REJNR
	T REASON-CODE,REJWR
	REJTBL==.-REJTAB-1


;REJECT WITH NO REASON CODE

REJNR:	CONFRM
	MOVEI T1,T.REJ
	CALL CDRFIN		;(T1)
	RET


;REJECT WITH REASON CODE

REJWR:	CONFRM
	MOVEI T1,T.REJR
	CALL CDRFIN		;(T1)
	RET


IDLE:	NOISE (FOR TIME PERIOD)
	MOVEI T1,[FLDDB. .CMTAD,CM%SDH,CM%ITM,<hr:min:sec>,<00:02:00>]
	CALL CFIELD
	MOVEM T2,TSTITM		;PRESERVE INTERNAL TIME
	SETZ T4,		;NORMAL CONVERSION
	ODCNV
	 ERJMP [JSERR
		RET]
	HRRZM T4,TSTTTM		;PRESERVE THE TIME (IN SECONDS)
	MOVEI T1,T.IDL		;GET TEST TYPE
	CALL CDRFIN		;(T1)
	RET
;DATAGRAMS AND MESSAGES 

MESSAG:	MOVX T1,T.MSG		;GET MESSAGE INDICATOR
	SKIPA
DATAG:	MOVX T1,T.DAT		;GET DATAGRAM INDICATOR
	MOVEM T1,TSTTYP		;PRESERVE TEST TYPE
	NOISE (FOR TIME PERIOD)
	MOVEI T1,[FLDDB. .CMTAD,CM%SDH,CM%ITM,<hr:min:sec>,<00:02:00>]
	CALL RFIELD
	MOVEM T2,TSTITM		;PRESERVE INTERNAL TIME
	SETZ T4,		;NORMAL CONVERSION
	ODCNV
	 ERJMP [JSERR
		RET]
	HRRZM T4,TSTTTM		;PRESERVE THE TIME (IN SECONDS)
	NOISE (IN MODE)
	MOVEI T1,[FLDDB. .CMKEY,,DATDSP,,<INDUSTRY-COMPATIBLE>]
	CALL RFIELD
	MOVE T1,(T2)
	CALL (T1)
	RET

DATDSP:	DATDSL,,DATDSL
	T HIGH-DENSITY,DATHID
	T INDUSTRY-COMPATIBLE,DATIND
	DATDSL=.-DATDSP-1

DATIND:	NOISE (OF BYTE COUNT)
	MOVEI T1,[FLDDB. .CMNUM,,12,,100]
	CALL CFIELD
	SKIPL T2		;CAN'T BE NEGATIVE
	IFSKP.
DATID1:	  TYPE (
? Invalid byte count)
	  RET
	ENDIF.
	MOVE T1,TSTTYP		;RETRIEVE TEST TYPE
	CAIE T1,T.DAT		;DATAGRAM?
	IFSKP.
	  CAILE T2,MXDBYT	;YES, OVER THE LIMIT?
	  JRST DATID1		;YES
	ELSE.
	  CAIE T1,T.DMA		;NO, DMA TEST?
	  IFSKP.		
	    CAILE T2,MXDMAB	;YES, OVER THE LIMIT?
    	    JRST DATID1		;YES
	  ELSE.			
	    CAIE T1,T.MAIN	;NO, MAINTENANCE TEST?
	    IFSKP.
	      CAILE T2,MXDMAB	;YES, OVER THE LIMIT?
	      JRST DATID1	;YES
	    ELSE.
	      CAILE T2,MXMBYT	;NO, MESSAGE - OVER THE LIMIT?
	      JRST DATID1	;YES
	    ENDIF.
	  ENDIF.		
	ENDIF.
	MOVEM T2,TSTCOU		;PRESERVE THE COUNT
	MOVX T1,M.INDC		;GET INDUSTRY COMPATIBLE INDICATOR
	MOVEM T1,TSTMOD		;PRESERVE TRANSFER MODE
	CALLRET .TESTF		;GO FINISH THE PARSING
DATHID:	NOISE (OF WORD COUNT)
	MOVEI T1,[FLDDB. .CMNUM,,12,,20]
	CALL CFIELD
	SKIPL T2		;CAN'T BE NEGATIVE
	IFSKP.
DATHI1:	  TYPE (
? Invalid word count)
	  RET
	ENDIF.
	MOVE T1,TSTTYP		;RETRIEVE TEST TYPE
	CAIE T1,T.DAT		;DATAGRAM?
	IFSKP.
	  CAILE T2,MXDWRD	;YES, OVER THE LIMIT?
	  JRST DATHI1		;YES
	ELSE.
	  CAIE T1,T.DMA		;NO, DMA TEST?
	  IFSKP.		
	    CAILE T2,MXDMAW	;YES, OVER THE LIMIT?
    	    JRST DATHI1		;YES
	  ELSE.			
	    CAIE T1,T.MAIN	;NO, MAINTENANCE TEST?
	    IFSKP.
	      CAILE T2,MXDMAW	;YES, OVER THE LIMIT?
	      JRST DATHI1	;YES
	    ELSE.
	      CAILE T2,MXMWRD	;NO, MESSAGE - OVER THE LIMIT?
	      JRST DATHI1	;YES
	    ENDIF.
	  ENDIF.		
	ENDIF.
	MOVEM T2,TSTCOU		;PRESERVE THE COUNT
	MOVX T1,M.HIGH		;GET HIGH DENSITY INDICATOR
	MOVEM T1,TSTMOD		;PRESERVE TRANSFER MODE
	CALLRET .TESTF		;GO FINISH THE PARSING
;DMA-TRANSFERS

DMAT:	MOVX T1,T.DMA		;TEST IS NOW DMA-TRANSFERS
	MOVEM T1,TSTTYP		;PRESERVE TEST TYPE
	NOISE (FOR TIME PERIOD) 
	MOVEI T1,[FLDDB. .CMTAD,CM%SDH,CM%ITM,<hr:min:sec>,<00:02:00>]  
	CALL RFIELD		
	MOVEM T2,TSTITM		;PRESERVE INTERNAL TIME
	SETZ T4,		;NORMAL CONVERSION
	ODCNV			
	 ERJMP [JSERR		
		RET]		
        HRRZM T4,TSTTTM		;PRESERVE THE TIME (IN SECONDS) 
	NOISE (OF BUFFER NUMBER)
	MOVEI T1,[FLDDB. .CMNUM,,12,,1]  
	CALL RFIELD
	JUMPLE T2,DMAT1		;CAN'T BE NEGATIVE, ZERO
	CAIG T2,NDMAIN		; OR GREATER THAN MAX # INPUT BUFFERS
	IFSKP.
DMAT1:	  TYPE (
? Invalid number of buffers)	
	  RET			
 	ENDIF.
	MOVEM T2,TSTBNM		;PRESERVE IT
	NOISE (OF SEGMENT COUNT)
	MOVEI T1,[FLDDB. .CMNUM,,12,,1]  
	CALL RFIELD		
	JUMPLE T2,DMAT3		;CAN'T BE NEGATIVE, ZERO
	CAIG T2,NDMASG		; OR GREATER THAN MAX SEGEMENT / BUFFER
	IFSKP.			
DMAT3:	  TYPE (
? Invalid segment count)	
	  RET			
 	ENDIF.
	MOVEM T2,TSTSCT		;PRESERVE IT
	NOISE (IN MODE)		
	MOVEI T1,[FLDDB. .CMKEY,,DATDSP,,<INDUSTRY-COMPATIBLE>]  
	CALL RFIELD		
	MOVE T1,(T2)		
	CALL (T1)		
	RET			
;MAINTENANCE

MAINT:	MOVX T1,T.MAIN		;TEST IS NOW MAINTENANCE
	MOVEM T1,TSTTYP		;PRESERVE TEST TYPE
	NOISE (FOR TIME PERIOD) 
	MOVEI T1,[FLDDB. .CMTAD,CM%SDH,CM%ITM,<hr:min:sec>,<00:02:00>]  
	CALL RFIELD		
	MOVEM T2,TSTITM		;PRESERVE INTERNAL TIME
	SETZ T4,		;NORMAL CONVERSION
	ODCNV			
	 ERJMP [JSERR		
		RET]		
        HRRZM T4,TSTTTM		;PRESERVE THE TIME (IN SECONDS) 
	NOISE (OF BUFFER NUMBER)
	MOVEI T1,[FLDDB. .CMNUM,,12,,1]  
	CALL RFIELD
	JUMPLE T2,MAINT1	;CAN'T BE NEGATIVE, ZERO
	CAIG T2,NDMAIN		; OR GREATER THAN MAX # INPUT BUFFERS
	IFSKP.
MAINT1:	  TYPE (
? Invalid number of buffers)	
	  RET			
 	ENDIF.
	MOVEM T2,TSTBNM		;PRESERVE IT
	NOISE (OF SEGMENT COUNT)
	MOVEI T1,[FLDDB. .CMNUM,,12,,1]  
	CALL RFIELD		
	JUMPLE T2,MAINT2	;CAN'T BE NEGATIVE, ZERO
	CAIG T2,NDMASG		; OR GREATER THAN MAX SEGEMENT / BUFFER
	IFSKP.			
MAINT2:	  TYPE (
? Invalid segment count)	
	  RET			
 	ENDIF.
	MOVEM T2,TSTSCT		;PRESERVE IT
	NOISE (IN MODE)		
	MOVEI T1,[FLDDB. .CMKEY,,DATDSP,,<INDUSTRY-COMPATIBLE>]  
	CALL RFIELD		
	MOVE T1,(T2)		
	CALL (T1)		
	RET			
;PARSING IS FINISHED.  SET UP THE TEST STREAM PARAMETERS

;SET UP THE TEST PARAMETERS
;RETURNS:	+1

.TESTF:	CALL GETTST		;(/T4) GET A TEST STREAM
	IFNSK.
	  TYPE (
? All test streams currently in use)
	  RET
	  SETZM STATUS(TST)	;INIT STREAM
	ENDIF.

;Store TEST data

.TESTD:	MOVE T3,TSTNOD		;GET NODE #
	STOR T3,NODE,(T4)	;SET IT
	MOVE T3,TSTTYP		;GET TEST TYPE
	STOR T3,TEST,(T4)	;SET IT
	CAIG T3,T.DISR		;MORE PARAMETERS TO DO?
	JRST .TESTS		;NO, GO START TEST FORK
	MOVE T2,TSTITM		;YES, GET INTERNAL TEST TIME
	MOVEM T2,ITIME(T4)	;SET IT
	MOVE T2,TSTTTM		;GET TEST TIME
	MOVEM T2,TTIME(T4)	;SET IT
	SETZM MNTFLG(T4)	;ASSUME NOT A MAINTENANCE TEST
	CAIE T3,T.DMA		;IS IT A DMA TEST?
	CAIN T3,T.MAIN		;OR A MAINTENANCE TEST?
	JRST TESTD1		;YES
	MOVE T2,TSTCOU		;NO, GET COUNT
	MOVEM T2,COUNT(T4)	;SET IT
	MOVE T2,TSTMOD		;GET TRANSFER MODE
	STOR T2,TMODE,(T4)	;SET IT
	JRST .TESTS
TESTD1:	MOVE T2,TSTBNM		;GET NUMBER OF BUFFERS
	MOVEM T2,BUFNUM(T4)	;SET IT
	MOVE T2,TSTSCT		;GET SEGMENT COUNT
	MOVEM T2,SEGNUM(T4)	;SET IT
	MOVE T2,TSTCOU		;GET COUNT
	MOVEM T2,SEGSIZ(T4)	;SET IT
	MOVE T2,TSTMOD		;GET TRANSFER MODE
	STOR T2,TMODE,(T4)	;SET IT
	CAIE T3,T.DMA
	SETOM MNTFLG(T4)	;IT IS A MAINTENANCE TEST

;Start a test fork

.TESTS:	MOVE P1,T4		;GET CONNECTION #
	MOVX P2,S.STRT		;INITIAL STATE IS STARTING
	MOVEI P3,STRTST		;FORK'S BEGINNING ADDR
	CALL STRFRK		;(P1,P2,P3) START THE FORK
	IFNSK.
	  TYPEN (
? Failure in creating test stream:  )
	  JSERR
	  SETZM STATUS(TST)	;INIT STREAM
	ENDIF.
	RET
	SUBTTL WAIT Command

.WAIT:	NOISE (FOR ALL TESTS TO COMPLETE)
	CONFRM
	MOVE T1,PMODE		;GET PROGRAM MODE
	CAIN T1,INIMOD		;INITIATOR MODE?
	IFSKP.
	  LOGN (% Not in initiator mode)
	  RET
	ENDIF.
WAITL:	MOVSI T1,-MAXTST	;AOBJN WORD FOR ALL TEST FORKS
WAIT1:	SKIPN STATUS(T1)	;THIS TEST IN USE?
	IFSKP.
	  MOVEI T1,^D1000	;YES, WAIT FOR
	  DISMS			; A BIT
	  JRST WAITL		;TRY IT AGAIN
	ENDIF.
	AOBJN T1,WAIT1		;NO, TRY NEXT TEST
	RET			;ALL TESTS ARE FINISHED
	SUBTTL Test Fork Startup

;A CFORKed test initiator starts here

STRTST:	MOVE P,TSTPDP(TST)	;LOAD PDL WORD
	MOVX T1,.SSAIC		;SET UP SCS% PSI
	MOVEI T2,SSAIC		;ADDR OF ARG BLOCK
	PIOFF			;NO INTERRUPTS
	SCS%
	IFJER.			;FAILED
	  CALL SCSERR		;PROCESS SCS ERROR
	  JRST STRTST		;CONTINUE
	  JRST FATAL		;THIS WAS A BAD ONE
	ENDIF.
	PION			;ALLOW INTERRUPTS
	MOVEI T1,.FHSLF		;THIS FORK
	MOVEI T2,CHNTAB		;CHANNEL TABLE ADDR
	HRL T2,TSTLVP(TST)	;LEVEL TABLE ADDR
	SIR			;SET PSI INFO
	 ERJMP FATAL		;FAILED
	SETZM PSISYS(TST)	;SYSTEM WILL BE ON
	EIR			;ENABLE PSI SYSTEM
	 ERJMP FATAL		;FAILED
	MOVE T2,CHNMSK		;GET CHANNEL MASK
	AIC			;ACTIVATE INTERRUPTS
	 ERJMP FATAL		;FAILED
	LOAD T3,NODE,(TST)	;GET REMOTE NODE
	MOVE Q1,T3		;PRESERVE NODE #
	CALL FNDNOD		;(T3) SEE IF IT'S UP
	IFNSK.
	  LOGIDE
	  LOG ( - node )
	  MOVE T2,Q1		;GET NODE NUMBER
	  CALL LOGDEC		;(T2)
	  LOGN ( not available)
	  JRST STPTST		;ALL DONE
	ENDIF.
	MOVEM Q1,SBI(TST)	;SAVE SBI (THIS IS THE SAME AS THE NODE NUMBER)
	LOAD T1,TEST,(TST)	;GET TEST TYPE
	CAIL T1,0		;IS IT
	CAILE T1,TSTDPL		; LEGIT?
	JRST STPTST 		;NO, CLEAN UP AND RETURN
	CALL @TSTDSP(T1)	;YES, DO THE WORK
	JRST STPTST		;TEST IS DONE

TSTDSP:	CONTST
	CONTST
	REJTST
	REJTST
	DISTST
	DISTST
	IDLTST
	DATTST
	MSGTST
	DMATST
	MNTTST			;MAINTENANCE
	TSTDPL=.-TSTDSP-1
	SUBTTL CONNECT/REJECT/DISCONNECT Test

CONTST:	CAIE T1,T.CONO		;OPTIONAL DATA?
	IFSKP.
	  MOVE T2,[POINT 8,OPTDAT] ;YES, MAKE BP TO OPTIONAL DATA
	  MOVEI T4,OPTCHR	;GET FILL CHARACTER
	  MOVSI T3,-<SQ%CDT*4>	;AOBJN WORD FOR ALL OF DATA AREA
	  IDPB T4,T2		;PUT IN CHAR
	  AOBJN T3,.-1		;DO ALL OF OPTIONAL DATA AREA
	  CALL DOTST1		;(T1) DO THE CONNECT
	ELSE.
	  CALL DOTST		;(T1) DO THE CONNECT
	ENDIF.
	HRROI LP,[ASCIZ/CONNECT test started/]
	CALL LOGG		;LOG IT
	MOVEI T1,^D30000	;WAIT FOR 30 SECONDS
	DISMS			;THE TEST SHOULD COMPLETE BEFORE WE WAKE UP
	HRROI LP,[ASCIZ/CONNECT test failed - timed out waiting for disconnect
/]
	CALL LOGE		;LOG ERROR
	JRST STPTST

REJTST:	CALL DOTST		;(T1) DO THE CONNECT
	HRROI LP,[ASCIZ/REJECT test started/]
	CALL LOGG		;LOG IT
	MOVEI T1,^D30000	;WAIT FOR 30 SECONDS
	DISMS			;THE TEST SHOULD COMPLETE BEFORE WE WAKE UP
	HRROI LP,[ASCIZ/REJECT test failed - timed out waiting for reject
/]
	CALL LOGE		;LOG ERROR
	JRST STPTST

DISTST:	CALL DOTST		;(T1) DO THE CONNECT
	HRROI LP,[ASCIZ/DISCONNECT test started/]
	CALL LOGG		;LOG IT
	MOVEI T1,^D30000	;WAIT FOR 30 SECONDS
	DISMS			;THE TEST SHOULD COMPLETE BEFORE WE WAKE UP
	HRROI LP,[ASCIZ/DISCONNECT test failed - timed out waiting for disconnect
/]
	CALL LOGE		;LOG ERROR
	JRST STPTST
	SUBTTL IDLE Test

IDLTST:	CALL DOTST		;(T1) DO THE CONNECT
	HRROI LP,[ASCIZ/IDLE test started/]
	CALL LOGG		;LOG IT

	MOVSI T2,-30
IDLTS1:	MOVEI T1,^D1000		;WAIT
	DISMS			; FOR A BIT
	LOAD T1,STATE,(TST)	;GET CONNECTION STATE
	CAIN T1,S.RUN		;RUNNING YET?
	JRST IDLTS2		;YES
	AOBJN T2,IDLTS1		;WAIT SOME MORE
	HRROI LP,[ASCIZ/IDLE test failed - timed out waiting for accept
/]
	CALL LOGE		;LOG ERROR
	JRST STPTST		;WE'RE DEAD

IDLTS2:	SETO T2,		;GET CURRENT TIME
	SETZ T4,		;REGULAR OPTIONS
	ODCNV			;
	 ERJMP FATAL		;CAN'T CONTINUE
	ADD T4,TTIME(TST)	;ADD TEST DURATION
	IDCNV			;CONVERT TIME TO INTERNAL FORMAT
	 JRST FATAL
	HRLI T1,.FHSLF		;THIS PROCESS
	HRRI T1,.TIMDT		;FUNCTION IS EXACT TIME INTERRUPT
	MOVEI T3,TIMCHN		;PSI CHANNEL
	TIMER			;SET IT
	 JRST FATAL

;PERIODICALLY CHECK TO SEE IF CONNECTION IS STILL THERE

IDLTS3:	MOVEI T1,^D10000	;AT TEN SECOND INTERVALS
	DISMS
	CALL DOSTS		;GET CONNECTION STATUS
	 JRST FATAL		;JSYS FAILED
	HRRZ T1,.SQFST+STSBLK	;JUST THE STATE
	CAIN T1,SQ%OPN		;IS IT OPEN?
	JRST IDLTS3		;YES
	HRROI LP,[ASCIZ/IDLE test failed - connection no longer open
/]
	CALL LOGE		;LOG ERROR
	JRST STPTST		;WE'RE DEAD
	SUBTTL DATAGRAM Test

DATTST:	CALL INIOPT		;INIT OPTIONAL DATA
	MOVE T2,[POINT 8,OPTDAT] ;GET BP TO OPTIONAL DATA
	IDPB T1,T2		;PUT IN TEST TYPE
	LOAD T1,TMODE,(TST)	;GET XFER MODE
	IDPB T1,T2		;PUT IT IN
	MOVE T3,COUNT(TST)	;GET COUNT
	LSHC T3,-^D8		;GET 1ST BYTE OF COUNT
	IDPB T3,T2		;PUT IT IN
	SETZ T3,		;INIT THE PLACE HOLDER
	LSHC T3,^D8		;GET 2ND BYTE OF COUNT
	IDPB T3,T2		;PUT IT IN
	SETZ P1,		;NO MESSAGE BUFFERS
	CALL DATINI		;INITIALIZE DATAGRAM BUFFERS
	MOVE P2,DATGIN(TST)	;GET ADDR OF DATAGRAM BUFFER CHAIN
	CALL DOCON		;(P1,P2) DO CONNECT
	 JRST FATAL		;JSYS FAILED
	HRROI LP,[ASCIZ/DATAGRAM test started/]
	CALL LOGG		;LOG IT

	MOVSI T2,-30
DATTS1:	MOVEI T1,^D1000		;WAIT
	DISMS			; FOR A BIT
	LOAD T1,STATE,(TST)	;GET CONNECTION STATE
	CAIN T1,S.RUN		;RUNNING YET?
	JRST DATTS2		;YES
	AOBJN T2,DATTS1		;NO, WAIT SOME MORE
	HRROI LP,[ASCIZ/DATAGRAM test failed - timed out waiting for accept
/]
	CALL LOGE		;LOG ERROR
	JRST STPTST		;WE'RE DEAD

DATTS2:	SETO T2,		;GET CURRENT TIME
	SETZ T4,		;REGULAR OPTIONS
	ODCNV			;
	 ERJMP FATAL		;CAN'T CONTINUE
	ADD T4,TTIME(TST)	;ADD TEST DURATION
	IDCNV			;CONVERT TIME TO INTERNAL FORMAT
	 JRST FATAL
	HRLI T1,.FHSLF		;THIS PROCESS
	HRRI T1,.TIMDT		;FUNCTION IS EXACT TIME INTERRUPT
	MOVEI T3,TIMCHN		;PSI CHANNEL
	TIMER			;SET IT
	 JRST FATAL
	GTAD			;GET CURRENT TIME
	MOVEM T1,STIME(TST)	;SAVE IT AS TEST BEGINNING

;.....
;SEND DATAGRAMS

DATTS4:	MOVSI Q2,-50		;DO 50 SENDS AT A TIME
DATTS3:	PIOFF
	CALL GETDAT		;(/T1) GET A DATAGRAM BUFFER
	IFNSK.
	  PION
	  HRROI LP,[ASCIZ/no available datagram buffers/]
	  CALL LOGW
	  MOVEI T1,^D500	;NONE AVAILABLE
	  DISMS			;WAIT A BIT
	  JRST DATTS3		; AND TRY AGAIN
	ENDIF.
	PION
	MOVE P1,T1		;GET BUFFER ADDRESS
	SETZM (P1)		;BUFFER IS IN USE
	LOAD T2,TMODE,(TST)	;GET XFER MODE
	CAIE T2,M.HIGH		;HIGH DENSITY?
	IFSKP.
	  MOVE T2,T1		;YES, SAVE BUFFER ADDR
	  HRLI T1,DGBUFR	;CREATE
	  ADD T2,COUNT(TST)	; THE
	  SOS T2		; DATAGRAM
	  BLT T1,(T2)		; IN WORDS
	ELSE.
	  MOVE T1,COUNT(TST)	;NO, GET SOURCE BYTE COUNT
	  MOVE T2,[POINT 8,DGBUFR] ;GET SOURCE BP
	  MOVE T4,COUNT(TST)	;GET DESTINATION BYTE COUNT
	  MOVE Q1,P1		;MAKE DESTINATION
	  HRLI Q1,441000	; BP
	  EXTEND T1,[MOVSLJ]	;MAKE THE DATAGRAM IN BYTES
	  IFJER.
	    HRROI LP,[ASCIZ/EXTEND failed
/]
	    CALL LOGE
	    JRST STPTST		;WE'RE DEAD
	  ENDIF.
	ENDIF.
	MOVEI P2,.SSSDG		;IT'S A DATAGRAM
	CALL DOSXG		;(P1,P2) SEND THE DATAGRAM
	 JRST FATAL		;FAILED
	MOVE T1,P1		;RETRIEVE BUFFER ADDR
	PIOFF
	CALL RETDAT		;RETURN BUFFER TO FREE POOL
	PION
	AOBJN Q2,DATTS3		;DO SOME MORE
	TMNN DONE,(TST)		;HAS TIME RUN OUT?
	JRST DATTS4		;NO
	GTAD			;GET CURRENT TIME
	MOVEM T1,ETIME(TST)	;SAVE IT AS TEST ENDING TIME
	HRROI LP,[ASCIZ/DATAGRAM test complete
/]
	CALL LOGG
	CALL LOGCNT		;LOG THE BUFFER COUNT
	MOVEI P1,R.DAT		;GET DISCONNECT CODE
	CALL DODIS		;SEND THE DISCONNECT
	 JRST FATAL		;FAILED
	JRST STPTST		;WE'RE DONE
	SUBTTL MESSAGE Test

MSGTST:	CALL INIOPT		;INIT OPTIONAL DATA
	MOVE T2,[POINT 8,OPTDAT] ;GET BP TO OPTIONAL DATA
	IDPB T1,T2		;PUT IN TEST TYPE
	LOAD T1,TMODE,(TST)	;GET XFER MODE
	IDPB T1,T2		;PUT IT IN
	MOVE T3,COUNT(TST)	;GET COUNT
	LSHC T3,-^D8		;GET 1ST BYTE OF COUNT
	IDPB T3,T2		;PUT IT IN
	SETZ T3,		;INIT THE PLACE HOLDER
	LSHC T3,^D8		;GET 2ND BYTE OF COUNT
	IDPB T3,T2		;PUT IT IN
	CALL MSGINI		;INITIALIZE MESSAGE BUFFERS
	MOVE P1,MSGIN(TST)	;GET ADDR OF MESSAGE BUFFER CHAIN
	SETZ P2,		;NO DATAGRAM BUFFERS
	CALL DOCON		;(P1,P2) DO CONNECT
	 JRST FATAL		;JSYS FAILED
	HRROI LP,[ASCIZ/MESSAGE test started/]
	CALL LOGG		;LOG IT

	MOVSI T2,-30
MSGTS1:	MOVEI T1,^D1000		;WAIT
	DISMS			; FOR A BIT
	LOAD T1,STATE,(TST)	;GET CONNECTION STATE
	CAIN T1,S.RUN		;RUNNING YET?
	JRST MSGTS2		;YES
	AOBJN T2,MSGTS1		;NO, WAIT SOME MORE
	HRROI LP,[ASCIZ/MESSAGE test failed - timed out waiting for accept
/]
	CALL LOGE		;LOG ERROR
	JRST STPTST		;WE'RE DEAD

MSGTS2:	SETO T2,		;GET CURRENT TIME
	SETZ T4,		;REGULAR OPTIONS
	ODCNV			;
	 ERJMP FATAL		;CAN'T CONTINUE
	ADD T4,TTIME(TST)	;ADD TEST DURATION
	IDCNV			;CONVERT TIME TO INTERNAL FORMAT
	 JRST FATAL
	HRLI T1,.FHSLF		;THIS PROCESS
	HRRI T1,.TIMDT		;FUNCTION IS EXACT TIME INTERRUPT
	MOVEI T3,TIMCHN		;PSI CHANNEL
	TIMER			;SET IT
	 JRST FATAL
	GTAD			;GET CURRENT TIME
	MOVEM T1,STIME(TST)	;SAVE IT AS TEST BEGINNING

;.....
;SEND MESSAGES

MSGTS4:	MOVSI Q2,-50		;DO A BUNCH OF MESSAGES
MSGTS3:	PIOFF
	CALL GETMSG		;(/T1) GET A MESSAGE BUFFER
	IFNSK.
	  PION
	  HRROI LP,[ASCIZ/no available message buffers/]
	  CALL LOGW
	  MOVEI T1,^D500	;NONE AVAILABLE
	  DISMS			;WAIT A BIT
	  JRST MSGTS3		; AND TRY AGAIN
	ENDIF.
	PION
	MOVE P1,T1		;GET BUFFER ADDRESS
	SETZM (P1)		;BUFFER IS IN USE
	LOAD T2,TMODE,(TST)	;GET XFER MODE
	CAIE T2,M.HIGH		;HIGH DENSITY?
	IFSKP.
	  MOVE T2,T1		;YES, SAVE BUFFER ADDR
	  HRLI T1,DGBUFR	;CREATE
	  ADD T2,COUNT(TST)	; THE
	  SOS T2		; MESSAGE
	  BLT T1,(T2)		; IN WORDS
	ELSE.
	  MOVE T1,COUNT(TST)	;NO, GET SOURCE BYTE COUNT
	  MOVE T2,[POINT 8,DGBUFR] ;GET SOURCE BP
	  MOVE T4,COUNT(TST)	;GET DESTINATION BYTE COUNT
	  MOVE Q1,P1		;MAKE DESTINATION
	  HRLI Q1,441000	; BP
	  EXTEND T1,[MOVSLJ]	;MAKE THE MESSAGE IN BYTES
	  IFJER.
	    HRROI LP,[ASCIZ/EXTEND failed
/]
	    CALL LOGE
	    JRST STPTST		;WE'RE DEAD
	  ENDIF.
	ENDIF.
MSGTS6:	MOVEI P2,.SSSMG		;IT'S A MESSAGE
	CALL DOSXG		;(P1,P2) SEND THE MESSAGE
        IFNSK.		
          MOVE T2,LSTERR(TST)	;GET THE ERROR CODE - LSTERR SET BY DOSXG
          CAIN T2,SCSNEC	;NOT ENOUGH CREDIT?
          IFSKP.
            HRROI LP,[ASCIZ/.SSSMG failed
/]
            CALL TRACE
            JRST FATAL		;NO, CAN'T CONTINUE
          ENDIF.
          HRROI LP,[ASCIZ/.SSSMG not enough credit/] ;YES
          CALL TRACE
	  CALL CHKCRD		;WAIT FOR CREDIT
	  IFNSK.
	    HRROI LP,[ASCIZ/MESSAGE test failed - timed out waiting for credit
/]
	    CALL LOGE		;REPORT ERROR
	    JRST STPTST		;DIE
	  ENDIF.
	  SETZM CREDIT(TST)	;RESET CREDIT AVAILABLE FLAG
          JRST MSGTS6		;THEN TRY TO SEND AGAIN
        ENDIF.
	MOVE T1,P1		;RETRIEVE BUFFER ADDR
	PIOFF
	CALL RETMSG		;RETURN MESSAGE BUFFER TO FREE POOL
	PION
	AOBJN Q2,MSGTS3		;DO A BUNCH
	TMNN DONE,(TST)		;HAS TIME RUN OUT?
	JRST MSGTS4		;NO
	GTAD			;GET CURRENT TIME
	MOVEM T1,ETIME(TST)	;SAVE IT AS TEST ENDING TIME
	HRROI LP,[ASCIZ/MESSAGE test complete
/]
	CALL LOGG
	CALL LOGCNT		;LOG THE BUFFER COUNT
	MOVEI P1,R.MSG		;GET DISCONNECT CODE
	CALL DODIS		;SEND THE DISCONNECT
	 JRST FATAL		;FAILED
	JRST STPTST		;WE'RE DONE
	SUBTTL DMA-TRANSFERS Test

;NOTE:  THIS ROUTINE IS ALSO IS USED TO PERFORM A MAINTENANCE TEST

MNTTST:				;MAINTENANCE TEST ENTRY ALSO
DMATST:	STKVAR <TTMODE,TCOUNT>  
	CALL INIOPT		;INIT OPTIONAL DATA
	MOVE T2,[POINT 8,OPTDAT] ;MAKE BP TO IT
	IDPB T1,T2		;PUT IN TEST TYPE
	LOAD T1,TMODE,(TST)	;GET XFER MODE
	IDPB T1,T2		;PUT IT IN
	MOVE T3,SEGSIZ(TST)	;GET SEGMENT SIZE
	LSHC T3,-^D8		;GET 1ST BYTE OF COUNT
	IDPB T3,T2		;PUT IT IN
	SETZ T3,		;INIT THE PLACE HOLDER
	LSHC T3,^D8		;GET 2ND BYTE OF COUNT
	IDPB T3,T2		;PUT IT IN
	MOVE T1,BUFNUM(TST)	;GET NUMBER OF DMA BUFFERS
	IDPB T1,T2		;PUT IT IN
	MOVE T1,SEGNUM(TST)	;GET NUMBER OF SEGMENTS PER BUFFER
	IDPB T1,T2		;PUT IT IN
	CALL MSGINI		;INIT MESSAGE BUFFERS
 	MOVE P1,MSGIN(TST)	;GET BEGINNING MESSAGE BUFFER ADDR
	SETZ P2,		;NO DATAGRAM BUFFERS
	CALL DOCON		;MAKE THE CONNECITON
	 JRST FATAL
	CALL DMAINI		;INIT THE BUFFERS
	HRROI LP,[ASCIZ/DMA test started/]
	SKIPE MNTFLG		;REALLY A MAINTENANCE TEST?
	HRROI LP,[ASCIZ/MAINTENANCE test started/]
	CALL LOGG		;LOG IT

	MOVSI T2,-30
	DO.			
	  MOVEI T1,^D1000	;WAIT
	  DISMS			; FOR A BIT
	  LOAD T1,STATE,(TST)	;GET CONNECTION STATE
	  CAIN T1,S.RUN		;RUNNING YET?
	  EXIT.			;YES
	  AOBJN T2,TOP.		;NO, WAIT SOME MORE
	  HRROI LP,[ASCIZ/DMA test failed - timed out waiting for accept
/]	  
	  SKIPE MNTFLG		;REALLY A MAINTENANCE TEST?
	  HRROI LP,[ASCIZ/MAINTENANCE test failed - timed out waiting for accept
/]				;YES
	  CALL LOGE		;LOG ERROR
	  JRST STPTST		;WE'RE DEAD
	ENDDO.			

	SETO T2,		;GET CURRENT TIME
	SETZ T4,		;REGULAR OPTIONS
	ODCNV			;
	 ERJMP FATAL		;CAN'T CONTINUE
	ADD T4,TTIME(TST)	;ADD TEST DURATION
	IDCNV			;CONVERT TIME TO INTERNAL FORMAT
	 JRST FATAL
	HRLI T1,.FHSLF		;THIS PROCESS
	HRRI T1,.TIMDT		;FUNCTION IS EXACT TIME INTERRUPT
	MOVEI T3,TIMCHN		;PSI CHANNEL
	TIMER			;SET IT
	 JRST FATAL
	GTAD			;GET THE TIME
	MOVEM T1,STIME(TST)	;SAVE AS TEST'S START TIME
;GET BUFFER NAMES

DMATS4:	MOVX T1,MAP.OI		;MAP BOTH INCOMING AND OUTGOING
	CALL DMAMAP		;(T1) GET BUFFER NAMES
	 JRST FATAL		;FAILED

;SEND BUFFER NAMES TO SERVER AND WAIT FOR SERVER BUFFER NAMES

	SETZRO NAMES,(TST)	;NO NAMES HAVE BEEN RECEIVED
DMATS1:	PIOFF			
	CALL GETMSG		;(/T1) GET A MESSAGE BUFFER
	IFNSK.			
	  PION			
	  HRROI LP,[ASCIZ/no available message buffers for DMA/]  
	  SKIPE MNTFLG		;REALLY MAINTENANCE?
	  HRROI LP,[ASCIZ/no available message buffers for MAINTENANCE/]  
	  CALL LOGW		
	  MOVEI T1,^D500	;NONE AVAILABLE
	  DISMS			;WAIT A BIT
	  JRST DMATS1		; AND TRY AGAIN
	ENDIF.			
	PION			
	MOVE P1,T1		;GET BUFFER ADDRESS
	MOVE T2,BUFNUM(TST)	;GET NUMBER OF NAMED BUFFERS
	AOS T2			;INCREMENT TO REFLECT MESSAGE LENGTH
	MOVEM T2,(T1)		;PLACE IN MESSAGE BUFFER
	AOS T1			;MOVE TO NEXT BUFFER SLOT
	MOVE T3,TST		;GET TEST NUMBER
	IMULI T3,NDMAIN		;OFFSET BY MAX NUMBER OF DMA BUFFERS
	ADDI T3,DMAMIN		;OFFSET INTO BUFFER NAMES
	DO.			
	  MOVE T4,(T3)		;GET BUFFER NAME
	  MOVEM T4,(T1)		;PLACE IN MESSAGE BLOCK
	  AOS T1		;MOVE TO NEXT MESSAGE BLOCK SLOT
	  AOS T3		;MOVE TO NEXT BUFFER NAME
	  SOJN T2,TOP.		;DECREMENT BUFFER COUNT AND CONTINUE
	ENDDO.			
	LOAD T1,TMODE,(TST)	;GET TEST MODE FOR DMA
	MOVEM T1,TTMODE		;PRESERVE IT
	MOVEI T1,M.HIGH		;THIS MESSAGE IS IN HIGH DENSITY
	STOR T1,TMODE,(TST)	;PLACE AS MODE FOR THIS MESSAGE
	MOVE T1,COUNT(TST)	;GET COUNT FOR DMA TEST
	MOVEM T1,TCOUNT		;PRESERVE IT
	MOVE T1,(P1)		;GET MESSAGE COUNT SIZE
	MOVEM T1,COUNT(TST)	;PLACE AS COUNT FOR THIS MESSAGE
DMATS2:	MOVEI P2,.SSSMG		;IT'S A MESSAGE
	CALL DOSXG		;(P1,P2) SEND THE MESSAGE
        IFNSK.			
          MOVE T2,LSTERR(TST)	;GET THE ERROR CODE - LSTERR SET BY DOSXG
          CAIN T2,SCSNEC	;NOT ENOUGH CREDIT?
          IFSKP.		
            HRROI LP,[ASCIZ/.SSSMG failed
/]				
            CALL TRACE		
            JRST FATAL		;NO, CAN'T CONTINUE
          ENDIF.		
          HRROI LP,[ASCIZ/.SSSMG not enough credit for DMA/] ;YES
	  SKIPE MNTFLG		;MAINTENANCE?
          HRROI LP,[ASCIZ/.SSSMG not enough credit for MAINTENANCE/] ;YES
          CALL TRACE		
	  CALL CHKCRD		;WAIT FOR CREDIT
	  IFNSK.
	    HRROI LP,[ASCIZ/DMA test failed - timed out waiting for credit
/]
	    SKIPE MNTFLG	;MAINTENANCE?
	    HRROI LP,[ASCIZ/MAINTENANCE test failed - timed out waiting for credit
/]
	    CALL LOGE		;REPORT ERROR
	    JRST STPTST		;DIE
	  ENDIF.
	  SETZM CREDIT(TST)	;RESET CREDIT AVAILABLE FLAG
          JRST DMATS2		;THEN TRY TO SEND AGAIN
        ENDIF.			
	MOVE T1,P1		;RETRIEVE BUFFER ADDR
	PIOFF			
	CALL RETMSG		;RETURN MESSAGE BUFFER TO FREE POOL
	PION			
	MOVE T1,TTMODE		;GET SAVED DMA MODE
	STOR T1,TMODE,(TST)	;RESTORE AS DMA MODE
	MOVE T1,TCOUNT		;GET SAVED DMA COUNT
	MOVEM T1,COUNT(TST)	;RESTORE AS DMA COUNT

	MOVSI T2,-30		;WAIT FOR 30 SECONDS MAXIMUM
	DO.			
	  MOVEI T1,^D1000	;WAIT
	  DISMS			; FOR A BIT
	  LOAD T1,NAMES,(TST)	;GET REMOTE NAMES STATUS
	  JUMPN T1,ENDLP.	;HAVE THEM YET?
	  AOBJN T2,TOP.		;NO, WAIT SOME MORE
	  HRROI LP,[ASCIZ/DMA test failed - timed out waiting for names
/]	          		
	  SKIPE MNTFLG		;MAINTENANCE?
	  HRROI LP,[ASCIZ/MAINTENANCE test failed - timed out waiting for names
/]
	  CALL LOGE		;LOG ERROR
	  JRST STPTST		;WE'RE DEAD
	ENDDO.			
;HAVE BUFFER NAMES NOW - FILL DMA MESSAGE BUFFERS

	MOVE Q2,BUFNUM(TST)	;GET NUMBER OF BUFFERS
	DO.			
DMATS3:	  PIOFF			
	  CALL GTDMAO		;(/T1,T3) GET A OUTGOING DMA BUFFER
	  IFNSK.		
	    PION		
	    HRROI LP,[ASCIZ/no available outgoing DMA buffers/]  
	    SKIPE MNTFLG	;MAINTENANCE?
	    HRROI LP,[ASCIZ/no available outgoing MAINTENANCE buffers/]  
	    CALL LOGW		
	    MOVEI T1,^D500	;NONE AVAILABLE
	    DISMS		;WAIT A BIT
	    JRST DMATS3		; AND TRY AGAIN
	  ENDIF.		
	  PION			
	  MOVE P1,TST		;CALCULATE OFFSET
	  IMULI P1,NDMAOU	; INTO SEGMENT
	  IMULI P1,NDMASG	; ADDRESSES FOR THIS
	  ADDI P1,DMAOSG	; TEST AND
	  IMULI T3,NDMASG	; THIS
	  ADD P1,T3		; BUFFER
	  LOAD T2,TMODE,(TST)	;GET XFER MODE
	  CAIE T2,M.HIGH	;HIGH DENSITY?
	  IFSKP.		
	    MOVE P2,SEGNUM(TST)	;YES, GET NUMBER OF SEGMENTS
	    DO.	     
	      MOVE T1,(P1)	;GET SECOND WORD OF SEGMENT
	      AOS T1
	      SETZM @(P1)	;CLEAR FIRST WORD OF SEGMENT
	      HRL T1,(P1)	;START OF SEGMENT
	      MOVE P3,(P1)	;CALCULATE END OF SEGMENT
	      ADDI P3,MXDMAW-1
	      BLT T1,(P3)  	;CLEAR ENTIRE SEGMENT
	      MOVE T1,(P1)	;GET SEGMENT ADDRESS
	      MOVE T2,T1
	      HRLI T1,DMATXT	;START OF DMA TEXT
	      ADD T2,SEGSIZ(TST)
	      SOS T2		;END OF DMA TEXT
	      BLT T1,(T2)	;CREATE DMA BUFFER IN WORDS
	      AOS P1		;NEXT SEGMENT
	      SOJN P2,TOP.	;DO NEXT ONE
	    ENDDO.
	  ELSE.			
	    MOVE P2,SEGNUM(TST)	;NO, GET NUMBER OF SEGMENTS
	    DO.	     
	      MOVE T1,(P1)	;GET SECOND WORD OF SEGMENT
	      AOS T1
	      SETZM @(P1)	;CLEAR FIRST WORD OF SEGMENT
	      HRL T1,(P1)	;START OF SEGMENT
	      MOVE P3,(P1)	;CALCULATE END OF SEGMENT
	      ADDI P3,MXDMAW-1
	      BLT T1,(P3)  	;CLEAR ENTIRE SEGMENT
	      MOVE T1,SEGSIZ(TST)	;GET SOURCE BYTE COUNT
	      MOVE T2,[POINT 8,DMATXT]  ;GET SOURCE BP
	      MOVE T4,SEGSIZ(TST)  ;GET DESTINATION BYTE COUNT
	      MOVE Q1,(P1)	;MAKE DESTINATION
	      HRLI Q1,441000	; BP
	      EXTEND T1,[MOVSLJ]  ;MAKE THE DMA BUFFER IN BYTES
	      IFJER.		
	        HRROI LP,[ASCIZ/EXTEND failed
/]				
	        CALL LOGE		
	        JRST STPTST	;WE'RE DEAD
	      ENDIF.		
	      AOS P1		;NEXT SEGMENT
	      SOJN P2,TOP.	;DO ALL SEGMENTS
	    ENDDO.
	  ENDIF.		
	SOJN Q2,TOP.		;DO ALL THE BUFFERS
	ENDDO.			
;SEND DATA, WAIT FOR DMA DONE

	SETZM DMASND(TST)	;CLEAR NUMBER OF BUFFERS SENT
	SETZM DMAREQ(TST)	;CLEAR NUMBER OF BUFFERS READ
	MOVE P1,TST		;GET TEST NUMBER
	IMULI P1,NDMAOU		;CALCULATE OFFSET
	ADDI P1,DMAMOU		;OFFSET INTO BUFFER NAMES
	MOVE P2,TST		;GET TEST NUMBER
	IMULI P2,NDMAIN		;CALCULATE OFFSET
	ADDI P2,DMAREM		;OFFSET INTO REMOTE NAMES
	MOVE Q1,BUFNUM(TST)	;GET NUMBER OF BUFFERS TO SEND
	DO.			
DMATS6:
;	  SKIPN MNTFLG		;MAINTENANCE?
;	  IFSKP.
;	    MOVEI T1,.LBMDS	;GET ARG BLOCK LENGTH
;	    MOVEM T1,.SQLEN+SNDBLK  ;PLACE IN ARG BLOCK
;	    LOAD T1,NODE,(TST)	;GET NODE NUMBER
;	    MOVEM T1,.SQMDT+SNDBLK  ;PLACE IN ARG BLOCK
;	    MOVE T1,(P1)	;GET NAME OF SEND BUFFER
;	    MOVEM T1,.SQMSS+SNDBLK  ;PLACE IN ARG BLOCK
;	    MOVE T1,(P2)	;GET NAME OF REMOTE RECEIVE BUFFER
;	    MOVEM T1,.SQMSR+SNDBLK  ;PLACE IN ARG BLOCK
;	    SETZM .SQMOF+SNDBLK	;NO OFFSETS
;	    MOVEI T1,.SSMDS	;FUNCTION CODE
;	  ELSE.			;NO, DMA
	    MOVEI T1,.LBSND	;GET ARG BLOCK LENGTH
	    MOVEM T1,.SQLEN+SNDBLK  ;PLACE IN ARG BLOCK
	    MOVE T1,CONID(TST)	;GET CONNECT ID
	    MOVEM T1,.SQCID+SNDBLK  ;PLACE IN ARG BLOCK
	    MOVE T1,(P1)	;GET NAME OF SEND BUFFER
	    MOVEM T1,.SQSNM+SNDBLK  ;PLACE IN ARG BLOCK
	    MOVE T1,(P2)	;GET NAME OF REMOTE RECEIVE BUFFER
	    MOVEM T1,.SQRNM+SNDBLK  ;PLACE IN ARG BLOCK
	    SETZM .SQOFS+SNDBLK	;NO OFFSETS
	    MOVEI T1,.SSSND	;FUNCTION CODE
;	  ENDIF.
	  MOVEI T2,SNDBLK	;ARG BLOCK ADDRESS
	  PIOFF			;NO INTERRUPTS
	  SCS%			;SEND DMA BUFFER
	  IFJER.		
	    HRROI LP,[ASCIZ/.SSSND failed/]
	    CALL TRACE 		;SEND FAILED
	    CALL SCSERR		;PROCESS SCS ERROR
	    JRST DMATS6		;TRY AGAIN
	    JRST FATAL		;A BAD ERROR
	  ENDIF.		
	  PION			;ALLOW INTERRUPTS
	  HRROI LP,[ASCIZ/.SSSND ok/]  
	  CALL TRACE		;SEND SUCCEEDED
	  AOS P1		;MOVE TO NEXT BUFFER NAME
	  AOS P2		;MOVE TO NEXT REMOVE BUFFER NAME
	  SOJN Q1,TOP.		;ONE LESS BUFFER TO SEND AND CONTINUE
	ENDDO.			

	MOVSI T2,-30		;WAIT FOR 30 SECONDS MAXIMUM
	DO.
	  MOVEI T1,^D1000	;WAIT
	  DISMS			; FOR A BIT
	  MOVE T1,DMASND(TST)	;GET NUMBER OF SEND DONES
	  CAMN T1,BUFNUM(TST)	;DONE THEM ALL YET?
	  EXIT.			;YES
	  AOBJN T2,TOP.		;NO, WAIT SOME MORE
	  HRROI LP,[ASCIZ/DMA test failed - timed out waiting for SEND dones
/]	          		
	  SKIPE MNTFLG		;REALLY MAINTENANCE?
	  HRROI LP,[ASCIZ/MAINTENANCE test failed - timed out waiting for SEND dones
/]				;YES
	  CALL LOGE		;LOG ERROR
	  JRST STPTST		;WE'RE DEAD
	ENDDO.
;REQUEST DATA, WAIT FOR DMA DONE

	MOVE P1,TST		;GET TEST NUMBER
	IMULI P1,NDMAIN		;CALCULATE OFFSET
	MOVE P2,P1		
	ADDI P2,DMAMIN		;OFFSET INTO BUFFER NAMES
	ADDI P1,DMAREM		;OFFSET INTO REMOTE NAMES
	MOVE Q1,BUFNUM(TST)	;GET NUMBER OF BUFFERS TO REQUEST
	DO.			
DMATS7:
;	  SKIPN MNTFLG		;MAINTENANCE TEST?
;	  IFSKP.		;YES
;           MOVEI T1,.LBMDR	;GET ARG BLOCK LENGTH
;	    MOVEM T1,.SQLEN+SNDBLK  ;PLACE IN ARG BLOCK
;	    LOAD T1,NODE,(TST)	;GET NODE NUMBER
;	    MOVEM T1,.SQMDT+SNDBLK  ;PLACE IN ARG BLOCK
;	    MOVE T1,(P1)	;GET NAME OF REMOTE SEND BUFFER
;	    MOVEM T1,.SQMSS+SNDBLK  ;PLACE IN ARG BLOCK
;	    MOVE T1,(P2)	;GET NAME OF RECEIVE BUFFER
;	    MOVEM T1,.SQMSR+SNDBLK  ;PLACE IN ARG BLOCK
;	    SETZM .SQMOF+SNDBLK	;NO OFFSETS
;	    MOVEI T1,.SSMDR	;FUNCTION CODE
;	  ELSE.			;NO, DMA
            MOVEI T1,.LBSND	;GET ARG BLOCK LENGTH
	    MOVEM T1,.SQLEN+SNDBLK  ;PLACE IN ARG BLOCK
	    MOVE T1,CONID(TST)	;GET CONNECT ID
	    MOVEM T1,.SQCID+SNDBLK  ;PLACE IN ARG BLOCK
	    MOVE T1,(P1)	;GET NAME OF REMOTE SEND BUFFER
	    MOVEM T1,.SQSNM+SNDBLK  ;PLACE IN ARG BLOCK
	    MOVE T1,(P2)	;GET NAME OF RECEIVE BUFFER
	    MOVEM T1,.SQRNM+SNDBLK  ;PLACE IN ARG BLOCK
	    SETZM .SQOFS+SNDBLK	;NO OFFSETS
	    MOVEI T1,.SSREQ	;FUNCTION CODE
;	  ENDIF.
	  MOVEI T2,SNDBLK	;ARG BLOCK ADDRESS
	  PIOFF			;NO INTERRUPTS
	  SCS%			;GET DMA BUFFER
	  IFJER.		
	    HRROI LP,[ASCIZ/.SSREQ failed/]
	    CALL TRACE 		;SEND FAILED
	    CALL SCSERR		;PROCESS SCS ERROR
	    JRST DMATS7		;TRY AGAIN
	    JRST FATAL		;A FATAL ERROR
	  ENDIF.		
	  PION			;ALLOW INTERRUPTS
	  HRROI LP,[ASCIZ/.SSREQ ok/]  
	  CALL TRACE		;REQUEST SUCCEEDED
	  AOS P1		;MOVE TO NEXT BUFFER NAME
	  AOS P2		;MOVE TO NEXT REMOVE BUFFER NAME
	  SOJN Q1,TOP.		;ONE LESS BUFFER TO SEND AND CONTINUE
	ENDDO.			

	MOVSI T2,-30		;WAIT FOR 30 SECONDS MAXIMUM
	DO.
	  MOVEI T1,^D1000	;WAIT
	  DISMS			; FOR A BIT
	  MOVE T1,DMAREQ(TST)	;GET NUMBER OF RECEIVE DONES
	  CAMN T1,BUFNUM(TST)	;DONE THEM ALL YET?
	  EXIT.			;YES
	  AOBJN T2,TOP.		;NO, WAIT SOME MORE
	  HRROI LP,[ASCIZ/DMA test failed - timed out waiting for REQUEST dones
/]	          		
	  SKIPE MNTFLG		;MAINTENANCE?
	  HRROI LP,[ASCIZ/MAINTENANCE test failed - timed out waiting for REQUEST dones
/]				;YES
	  CALL LOGE		;LOG ERROR
	  JRST STPTST		;WE'RE DEAD
	ENDDO.
;VERIFY RECEIVED DATA

	MOVE P4,TST		;GET TEST NUMBER
	IMULI P4,NDMAOU		;CALCULATE OFFSET
	ADDI P4,DMAOUB		;OFFSET INTO OUTGOING BUFFER ADDRESSES
	MOVEI Q1,0		;START WITH FIRST BUFFER OFFSET
	DO.			
	  MOVE P1,TST		;CALCULATE OFFSET
	  IMULI P1,NDMAIN	; INTO INCOMING SEGMENT
	  IMULI P1,NDMASG	; ADDRESSES FOR THIS
	  ADDI P1,DMAISG	; TEST AND
	  MOVE T3,Q1		; FOR
	  IMULI T3,NDMASG	; THIS
	  ADD P1,T3		; BUFFER
	  MOVE P2,TST		;CALCULATE OFFSET
	  IMULI P2,NDMAOU	; INTO OUTGOING SEGMENT
	  IMULI P2,NDMASG	; ADDRESSES FOR THIS
	  ADDI P2,DMAOSG	; TEST AND
	  MOVE T3,Q1		; FOR
	  IMULI T3,NDMASG	; THIS
	  ADD P2,T3		; BUFFER
	  MOVE P3,SEGNUM(TST)	;GET NUMBER OF SEGMENTS
	  DO.
	    MOVE Q2,SEGSIZ(TST)	;GET SEGMENT SIZE
	    MOVE T1,(P1)	;GET ADDRESS OF INCOMING SEGMENT
	    MOVE T2,(P2)	;GET ADDRESS OF OUTGOING SEGMENT
	    LOAD T3,TMODE,(TST)	;GET TEST MODE
	    CAIE T3,M.HIGH	;IS IT HIGH DENSITY?
	    IFSKP.
	      DO.			
	        MOVE T3,(T1)	;GET A WORD FROM INCOMING BUFFER
	        CAMN T3,(T2)	;IS IT WHAT IS EXPECTED?
	        IFSKP.		;NO
DMATS5:	          HRROI LP,[ASCIZ/DMA test failed - invalid data
/]	              		
	          SKIPE MNTFLG	;MAINTENANCE?
	          HRROI LP,[ASCIZ/MAINTENANCE test failed - invalid data
/]	          		;YES
	          CALL LOGE		
	          MOVEI P1,R.WDAT  ;GET "WRONG DATA" REASON CODE
	          CALL DODIS	;DISCONNECT
	           JRST FATAL	;JSYS FAILED
	          JRST STPTST	;WE'RE DEAD
	        ENDIF.		
	        AOS T1		;NEXT INCOMING LOCATION
	        AOS T2		;NEXT OUTGOING LOCATION
	        SOJN Q2,TOP.	;DO ENTIRE BUFFER
	      ENDDO.		
	    ELSE.
	      HRLI T1,441000	;MAKE BYTE POINTER TO INCOMING SEGMENT
	      HRLI T2,441000	;MAKE BYTE POINTER TO OUTGOING SEGMENT
	      DO.
	        ILDB T3,T1	;GET INCOMING BYTE
	        ILDB T4,T2	;GET OUTGOING BYTE
	        CAME T3,T4	;ARE THEY EQUAL?
	        JRST DMATS5	;NO - ERROR
	        SOJN Q2,TOP.	;DO ENTIRE SEGMENT
	      ENDDO.
	    ENDIF.
	    AOS P1		;NEXT INCOMING SEGMENT
	    AOS P2		;NEXT OUTGOING SEGMENT
	    SOJN P3,TOP.	;DO NEXT SEGMENT IF NEEDED
	  ENDDO.
	  HRROI LP,[ASCIZ\DMA SEND/REQUEST verified\]  
	  SKIPE MNTFLG		;MAINTENANCE TEST?
	  HRROI LP,[ASCIZ\MAINTENANCE SEND/REQUEST verified\]  
	  CALL TRACE		;REPORT SUCCESS
	  SETOM @(P4)		;FREE OUTGOING BUFFER
	  AOS P4		;NEXT OUTGOING BUFFER
	  AOS Q1		;NEXT BUFFER OFFSET
	  CAME Q1,BUFNUM(TST)	;ANOTHER BUFFER TO DO?
	  JRST TOP.		;YES, DO IT
	ENDDO.
;UNMAP DMA BUFFERS

	MOVX T1,UMP.OI		;UNMAP BOTH OUTGOING AND INCOMING
	CALL DMAUMP		;(T1) UNMAP BUFFER NAMES
	 JRST FATAL		;FAILED

	TMNN DONE,(TST)		;HAS TIME RUN OUT?
	JRST DMATS4		;NO
	GTAD			;GET CURRENT TIME
	MOVEM T1,ETIME(TST)	;SAVE IT AS TEST ENDING TIME
	HRROI LP,[ASCIZ/DMA test complete
/]				
	SKIPE MNTFLG		;REALLY MAINTENANCE?
	HRROI LP,[ASCIZ/MAINTENANCE test complete
/]				;YES
	CALL LOGG		
	CALL LOGCNT		;LOG BUFFER COUNTS
	MOVEI P1,R.DMA		;GET DISCONNECT CODE
	SKIPE MNTFLG		;REALLY MAINTENANCE TEST?
	MOVEI P1,R.MAIN		;YES, USE CORRECT CODE
	CALL DODIS		;SEND THE DISCONNECT
	 JRST FATAL		;FAILED
	JRST STPTST		;TEST IS DONE
	SUBTTL Do A Vanilla Connect 

;DO A TEST'S CONNECT (NO BUFFERS ALLOCATED)
;ACCEPTS:	T1/ TEST TYPE
;RETURNS:	+1

DOTST:	CALL INIOPT		;() ZERO OPTIONAL DATA BLOCK
DOTST1:	MOVE T2,[POINT 8,OPTDAT] ;MAKE BP TO OPTIONAL DATA
	IDPB T1,T2		;PUT IN TEST TYPE
	SETZB P1,P2		;NO BUFFERS
	CALL DOCON		;(P1,P2) SEND THE CONNECT
	 JRST FATAL		;JSYS FAILED
	RET
	SUBTTL Incoming Datagram Interrupt Routine

DATINT:	CALL DATPRO		;DO THE WORK
	DEBRK

DATPRO:	SAVACS
DATPR1:	MOVEI P1,.SSRDG		;GET FUNCTION CODE
	CALL DORXG		;GET THE DATAGRAM
	IFNSK.
	  MOVEI T1,.FHSLF	;ERROR, GET
	  GETER			; THE ERROR CODE
	   ERJMP FATAL		;CAN'T HAVE THAT
	  HRRZS T2		;JUST THE ERROR CODE
	  CAIN T2,SCSQIE	;QUEUE EMPTY?
	  IFSKP.
	    HRROI LP,[ASCIZ/.SSRDG failed
/]
	    CALL TRACE
	   JRST FATAL		;NO, CAN'T CONTINUE
	  ENDIF.
	  HRROI LP,[ASCIZ/.SSRDG queue empty/] ;YES
	  CALL TRACE
	  RET			;NOTHING MORE TO DO
	ENDIF.
	SKIPN T2,.SQARB+RXGBLK	;GET BUFFER ADDRESS
	RET			;NO MORE BUFFERS AVAILABLE
	AOS BUFRCV(TST)		;ANOTHER BUFFER RECEIVED

;VERIFY THE DATAGRAM

	MOVN Q1,COUNT(TST)	;GET COUNT
	HRLZS Q1		;MAKE AN AOBJN WORD
	LOAD T1,TMODE,(TST)	;GET XFER MODE
	CAIE T1,M.HIGH		;IS IT HIGH DENSITY?
	IFSKP.
DATPR2:	  MOVE T3,(T2)		;YES, GET A WORD
	  CAMN T3,DGBUFR(Q1)	;IS IT OK?
	  IFSKP.
DATPR4:	    HRROI LP,[ASCIZ/DATAGRAM test failed - invalid data
/]
	    CALL LOGE
	    MOVEI P1,R.WDAT	;GET "WRONG DATA" REASON CODE
	    CALL DODIS		;DISCONNECT
	     JRST FATAL		;JSYS FAILED
	    JRST STPTST		;WE'RE DEAD
	  ENDIF.
	  AOS T2		;YES, NEXT WORD
	  AOBJN Q1,DATPR2	;DO ALL WORDS
  	ELSE.
	  HRLI T2,441000	;MAKE BP TO INCOMING DATAGRAM
	  MOVE T3,[POINT 8,DGBUFR] ;MAKE BP TO PROTOTYPE DATAGRAM
DATPR3:	  ILDB T1,T3		;GET A BYTE FROM PROTOTYPE
	  ILDB T4,T2		;GET A BYTE FROM DATAGRAM
	  CAME T1,T4		;MATCH?
	  JRST DATPR4		;NO
	  AOBJN Q1,DATPR3	;YES, DO ALL BYTES
	ENDIF.
	HRROI LP,[ASCIZ/Received datagram/]
	CALL TRACE
;.....
;REFLECT THE DATAGRAM

	MOVE T1,PMODE		;GET SCSTST MODE
	CAIE T1,SRVMOD		;ARE WE THE SERVER?
	IFSKP.
DATPR5:	  CALL GETDAT		;(/T1) YES, GET A DATAGRAM BUFFER
	  IFNSK.
	    MOVEI T1,^D500	;NONE AVAILABLE
	    DISMS		;WAIT A BIT
	    JRST DATPR5		; AND TRY AGAIN
	  ENDIF.
	  MOVE P1,T1		;PRESERVE BUFFER ADDR
	  SETZM (P1)		;BUFFER IS IN USE
	  LOAD T2,TMODE,(TST)	;YES, GET XFER MODE
	  CAIE T2,M.HIGH	;HIGH DENSITY?
	  IFSKP.
	    MOVE T2,T1		;YES, SAVE BUFFER ADDR
	    HRL T1,.SQARB+RXGBLK ;GET BEGINNING OF INCOMING DATAGRAM
	    ADD T2,COUNT(TST)	;GET WORD COUNT
	    SOS T2		;ADJUST
	    BLT T1,(T2)		;MOVE TO OUTGOING BUFFER
	  ELSE.
	    MOVE T1,COUNT(TST)	;GET BYTE COUNT
	    MOVE T2,.SQARB+RXGBLK ;GET BEGINNING OF INCOMING DATAGRAM
	    HRLI T2,441000	;MAKE A BP TO IT
	    MOVE T4,T1		;GET BYTE COUNT FOR DESTINATION
	    MOVE Q1,P1		;GET DESTINATION ADDR
	    HRLI Q1,441000	;MAKE A BP
	    EXTEND T1,[MOVSLJ]	;MOVE IT
   	    IFJER.
	      HRROI LP,[ASCIZ/EXTEND failed
/]
	      CALL LOGE
	      JRST STPTST	;WE'RE DEAD
	    ENDIF.
	  ENDIF.
	  MOVEI P2,.SSSDG	;IT'S A DATAGRAM
	  CALL DOSXG		;SEND IT
	   JRST FATAL
	  MOVE T1,P1		;RETRIEVE BUFFER ADDR
	  CALL RETDAT		;RETURN BUFFER TO FREE POOL
	ENDIF.

;MAKE THE BUFFER AVAILABLE FOR ANOTHER INCOMING DATAGRAM

	MOVEI P1,.SSQRD		;GET FUNCTION CODE
	MOVE P2,.SQARB+RXGBLK	;RETRIEVE BUFFER ADDR
	SETZM (P2)		;CLEAR THE LINK POINTER
	CALL DOQRX		;REQUEUE THE BUFFER
	 JRST FATAL
	JRST DATPR1		;GO FOR MORE
	SUBTTL Incoming Message Interrupt Routine

MSGINT:	CALL MSGPRO		;DO THE WORK
	DEBRK

MSGPRO:	SAVACS
	LOAD T1,TEST,(TST)	;GET TEST TYPE
	CAIE T1,T.DMA		;DMA?
	CAIN T1,T.MAIN		; OR MAINTENANCE?
	JRST DMAMSG		;YES
MSGPR1:	MOVEI P1,.SSRMG		;GET FUNCTION CODE
	CALL DORXG		;GET THE MESSAGE
	IFNSK.
	  MOVEI T1,.FHSLF	;ERROR, GET
	  GETER			; THE ERROR CODE
	   ERJMP FATAL		;CAN'T HAVE THAT
	  HRRZS T2		;JUST THE ERROR CODE
	  CAIN T2,SCSQIE	;QUEUE EMPTY?
	  IFSKP.
	    HRROI LP,[ASCIZ/.SSRMG failed
/]
	    CALL TRACE
	   JRST FATAL		;NO, CAN'T CONTINUE
	  ENDIF.
	  HRROI LP,[ASCIZ/.SSRMG queue empty/] ;YES
	  CALL TRACE
	  RET			;NOTHING MORE TO DO
	ENDIF.
	SKIPN T2,.SQARB+RXGBLK	;GET BUFFER ADDRESS
	RET			;NO MORE BUFFERS AVAILABLE
	AOS BUFRCV(TST)		;ANOTHER BUFFER RECEIVED

;VERIFY THE MESSAGE

	MOVN Q1,COUNT(TST)	;GET COUNT
	HRLZS Q1		;MAKE AN AOBJN WORD
	LOAD T1,TMODE,(TST)	;GET XFER MODE
	CAIE T1,M.HIGH		;IS IT HIGH DENSITY?
	IFSKP.
MSGPR2:	  MOVE T3,(T2)		;YES, GET A WORD
	  CAMN T3,DGBUFR(Q1)	;IS IT OK?
	  IFSKP.
MSGPR4:	    HRROI LP,[ASCIZ/MESSAGE test failed - invalid data
/]
	    CALL LOGE
	    MOVEI P1,R.WDAT	;GET "WRONG DATA" REASON CODE
	    CALL DODIS		;DISCONNECT
	     JRST FATAL		;JSYS FAILED
	    JRST STPTST		;WE'RE DEAD
	  ENDIF.
	  AOS T2		;YES, NEXT WORD
	  AOBJN Q1,MSGPR2	;DO ALL WORDS
  	ELSE.
	  HRLI T2,441000	;MAKE BP TO INCOMING MESSAGE
	  MOVE T3,[POINT 8,DGBUFR] ;MAKE BP TO PROTOTYPE MESSAGE
MSGPR3:	  ILDB T1,T3		;GET A BYTE FROM PROTOTYPE
	  ILDB T4,T2		;GET A BYTE FROM MESSAGE
	  CAME T1,T4		;MATCH?
	  JRST MSGPR4		;NO
	  AOBJN Q1,MSGPR3	;YES, DO ALL BYTES
	ENDIF.
	HRROI LP,[ASCIZ/Received message/]
	CALL TRACE
;.....
;REFLECT THE MESSAGE

	MOVE T1,PMODE		;GET SCSTST MODE
	CAIE T1,SRVMOD		;ARE WE THE SERVER?
	IFSKP.
MSGPR5:	  CALL GETMSG		;(/T1) YES, GET A MESSAGE BUFFER
	  IFNSK.
	    MOVEI T1,^D500	;NONE AVAILABLE
	    DISMS		;WAIT A BIT
	    JRST MSGPR5		; AND TRY AGAIN
	  ENDIF.
	  MOVE P1,T1		;PRESERVE BUFFER ADDR
	  SETZM (P1)		;BUFFER IS IN USE
	  LOAD T2,TMODE,(TST)	;YES, GET XFER MODE
	  CAIE T2,M.HIGH	;HIGH DENSITY?
	  IFSKP.
	    MOVE T2,T1		;YES, SAVE BUFFER ADDR
	    HRL T1,.SQARB+RXGBLK ;GET BEGINNING OF INCOMING MESSAGE
	    ADD T2,COUNT(TST)	;GET WORD COUNT
	    SOS T2		;ADJUST
	    BLT T1,(T2)		;MOVE TO OUTGOING BUFFER
	  ELSE.
	    MOVE T1,COUNT(TST)	;GET BYTE COUNT
	    MOVE T2,.SQARB+RXGBLK ;GET BEGINNING OF INCOMING MESSAGE
	    HRLI T2,441000	;MAKE A BP TO IT
	    MOVE T4,T1		;GET BYTE COUNT FOR DESTINATION
	    MOVE Q1,P1		;GET DESTINATION ADDR
	    HRLI Q1,441000	;MAKE A BP
	    EXTEND T1,[MOVSLJ]	;MOVE IT
	    IFJER.
	      HRROI LP,[ASCIZ/EXTEND failed
/]
	      CALL LOGE
	      JRST STPTST	;WE'RE DEAD
	    ENDIF.
	  ENDIF.
MSGPR6:	  MOVEI P2,.SSSMG	;IT'S A MESSAGE
	  CALL DOSXG		;SEND IT
	  IFNSK.		
	    MOVE T2,LSTERR(TST)	;GET THE ERROR CODE - LSTERR SET BY DOSXG
	    CAIN T2,SCSNEC	;NOT ENOUGH CREDIT?
	    IFSKP.
	      HRROI LP,[ASCIZ/.SSSMG failed
/]
	      CALL TRACE
	      JRST FATAL	;NO, CAN'T CONTINUE
	    ENDIF.
	    HRROI LP,[ASCIZ/.SSSMG not enough credit to reflect/] ;YES
	    CALL TRACE
	    CALL CHKCRD		;WAIT FOR CREDIT
	    IFNSK.
	      HRROI LP,[ASCIZ/MESSAGE test failed - timed out waiting for credit
/]
	      CALL LOGE		;REPORT ERROR
	      JRST STPTST	;DIE
	    ENDIF.
	    SETZM CREDIT(TST)	;RESET CREDIT AVAILABLE FLAG
	    JRST MSGPR6		;THEN TRY TO SEND AGAIN
	  ENDIF.
	  MOVE T1,P1		;RETRIEVE BUFFER ADDR
	  CALL RETMSG		;RETURN BUFFER TO FREE POOL
	ENDIF.

;MAKE THE BUFFER AVAILABLE FOR ANOTHER INCOMING MESSAGE

	MOVEI P1,.SSQRM		;GET FUNCTION CODE
	MOVE P2,.SQARB+RXGBLK	;RETRIEVE BUFFER ADDR
	SETZM (P2)		;CLEAR THE LINK POINTER
	CALL DOQRX		;REQUEUE THE BUFFER
	 JRST FATAL
	JRST MSGPR1		;GO FOR MORE
;MESSAGE RECEIVED WAS FOR DMA TEST - CONTAINS DMA BUFFER NAMES

DMAMSG:	STKVAR <ITTMODE,ITCOUNT>  
	MOVEI P1,.SSRMG		;GET FUNCTION CODE
	CALL DORXG		;GET THE MESSAGE
	IFNSK.			
	  MOVEI T1,.FHSLF	;ERROR, GET
	  GETER			; THE ERROR CODE
	   ERJMP FATAL		;CAN'T HAVE THAT
	  HRRZS T2		;JUST THE ERROR CODE
	  CAIN T2,SCSQIE	;QUEUE EMPTY?
	  IFSKP.		
	    HRROI LP,[ASCIZ/.SSRMG failed
/]				
	    CALL TRACE		
	   JRST FATAL		;NO, CAN'T CONTINUE
	  ENDIF.		
	  HRROI LP,[ASCIZ/.SSRMG queue empty for DMA/] ;YES
	  SKIPE MNTFLG		;REALLY A MAINTENANCE TEST?
	  HRROI LP,[ASCIZ/.SSRMG queue empty for MAINTENANCE/] ;YES
	  CALL TRACE		
	  RET			;NOTHING MORE TO DO
	ENDIF.			
	SKIPN T2,.SQARB+RXGBLK	;GET BUFFER ADDRESS
	RET			;NO MORE BUFFERS AVAILABLE
	MOVE Q1,(T2)		;GET MESSAGE LENGTH
	SOS Q1			;ADJUST TO REFLECT NUMBER OF BUFFERS
	CAME Q1,BUFNUM(TST)	;IS IT WHAT WE EXPECTED?
	IFNSK.			
	  HRROI LP,[ASCIZ/incorrect number of buffer names received/]  
	  CALL LOGW		;LOG THE WARNING
	ENDIF.			
	AOS T2			;MOVE TO NEXT MESSAGE WORD
	MOVE Q2,TST		;CALCULATE OFFSET
	IMULI Q2,NDMAIN		; INTO THE 
	ADDI Q2,DMAREM		; BUFFER NAME TABLE
	DO.			
	  MOVE T1,(T2)		;GET BUFFER NAME
	  MOVEM T1,(Q2)		;PLACE IN BUFFER NAME TABLE
	  AOS Q2		;MOVE TO NEXT NAME TABLE ENTRY
	  AOS T2		;MOVE TO NEXT MESSAGE BUFFER SLOT
	  SOJN Q1,TOP.		;MORE TO GET?
	ENDDO.			
	MOVE T1,PMODE		;GET PROGRAM MODE
	CAIE T1,SRVMOD		;ARE WE THE SERVER?
	IFSKP.			;YES - MAP BUFFER NAMES
	  CALL DMAINI		;INIT THE DMA BUFFERS
	  MOVX T1,MAP.IN	;ONLY WANT TO MAP INCOMING BUFFERS
	  CALL DMAMAP		;(T1) GET BUFFER NAMES
	   JRST FATAL		;FAILED
;SEND BUFFER NAMES TO INITIATOR

DMAMS1:	  PIOFF			
	  CALL GETMSG		;(/T1) GET A MESSAGE BUFFER
	  IFNSK.		
	    PION		
	    HRROI LP,[ASCIZ/no available message buffers for DMA/]  
	    SKIPE MNTFLG	;REALLY MAINTENANCE?
	    HRROI LP,[ASCIZ/no available message buffers for MAINTENANCE/]  
	    CALL LOGW		
	    MOVEI T1,^D500	;NONE AVAILABLE
	    DISMS		;WAIT A BIT
	    JRST DMAMS1		; AND TRY AGAIN
	  ENDIF.		
	  PION			
	  MOVE P1,T1		;GET BUFFER ADDRESS
	  MOVE T2,BUFNUM(TST)	;GET NUMBER OF NAMED BUFFERS
	  AOS T2		;ADJUST TO REFLECT MESSAGE SIZE
	  MOVEM T2,(T1)		;PLACE IN MESSAGE BUFFER
	  AOS T1		;MOVE TO NEXT BUFFER SLOT
	  MOVE T3,TST		;GET TEST NUMBER
	  IMULI T3,NDMAIN	;OFFSET BY MAX NUMBER OF DMA BUFFERS
	  ADDI T3,DMAMIN	;OFFSET INTO BUFFER NAMES
	  DO.			
	    MOVE T4,(T3)	;GET BUFFER NAME
	    MOVEM T4,(T1)	;PLACE IN MESSAGE BLOCK
	    AOS T1		;MOVE TO NEXT MESSAGE BLOCK SLOT
	    AOS T3		;MOVE TO NEXT BUFFER NAME
	    SOJN T2,TOP.	;DECREMENT BUFFER COUNT AND CONTINUE
	  ENDDO.		
	  LOAD T1,TMODE,(TST)	;GET TEST MODE FOR DMA
	  MOVEM T1,ITTMODE	;PRESERVE IT
	  MOVEI T1,M.HIGH	;THIS MESSAGE IS IN HIGH DENSITY
	  STOR T1,TMODE,(TST)	;PLACE AS MODE FOR THIS MESSAGE
	  MOVE T1,COUNT(TST)	;GET COUNT FOR DMA TEST
	  MOVEM T1,ITCOUNT	;PRESERVE IT
	  MOVE T1,(P1)		;GET MESSAGE COUNT SIZE
	  MOVEM T1,COUNT(TST)	;PLACE AS COUNT FOR THIS MESSAGE
DMAMS2:	  MOVEI P2,.SSSMG	;IT'S A MESSAGE
	  CALL DOSXG		;(P1,P2) SEND THE MESSAGE
          IFNSK.		
            MOVE T2,LSTERR(TST)	;GET THE ERROR CODE - LSTERR SET BY DOSXG
            CAIN T2,SCSNEC	;NOT ENOUGH CREDIT?
            IFSKP.		
              HRROI LP,[ASCIZ/.SSSMG failed
/]	          		
              CALL TRACE	
              JRST FATAL	;NO, CAN'T CONTINUE
            ENDIF.		
            HRROI LP,[ASCIZ/.SSSMG not enough credit for DMA/] ;YES
	    SKIPE MNTFLG	;MAINTENANCE?
            HRROI LP,[ASCIZ/.SSSMG not enough credit for MAINTENANCE/] ;YES
            CALL TRACE		
	    CALL CHKCRD		;WAIT FOR CREDIT
	    IFNSK.
	      HRROI LP,[ASCIZ/DMA test failed - timed out waiting for credit
/]
	      SKIPE MNTFLG	;MAINTENANCE?
	      HRROI LP,[ASCIZ/MAINTENANCE test failed - timed out waiting for credit
/]
	      CALL LOGE		;REPORT ERROR
	      JRST STPTST	;DIE
	    ENDIF.
	    SETZM CREDIT(TST)	;RESET CREDIT AVAILABLE FLAG
            JRST DMAMS2		;THEN TRY TO SEND AGAIN
          ENDIF.		
	  MOVE T1,P1		;RETRIEVE BUFFER ADDR
	  PIOFF			
	  CALL RETMSG		;RETURN MESSAGE BUFFER TO FREE POOL
	  PION			
	  MOVE T1,ITTMODE	;GET SAVED DMA MODE
	  STOR T1,TMODE,(TST)	;RESTORE AS DMA MODE
	  MOVE T1,ITCOUNT	;GET SAVED DMA COUNT
	  MOVEM T1,COUNT(TST)	;RESTORE AS DMA COUNT
	ELSE.			;NOT THE SERVER
	  SETONE NAMES,(TST)	;RECORD THAT THE INITIATOR GOT THE NAMES
	ENDIF.			
	RET			;DONE
       SUBTTL Incoming DMA-Transfer Interrupt Routine

DMAINT:	CALL DMAPRO		;() DO THE WORK
	DEBRK

DMAPRO:	SAVACS			;SAVE ACS
DMAPR1:	HRRI T1,1+GDEBLK	;INIT
	HRLI T1,GDEBLK		; THE
	SETZM GDEBLK		; ARG
	BLT T1,.LBGDE-1+GDEBLK	; BLOCK
	MOVEI T1,.LBGDE		;GET ARG BLOCK LENGTH
	MOVEM T1,.SQLEN+GDEBLK	;PLACE IN ARG BLOCK
	SETOM .SQCID+GDEBLK	;WANT NEXT BLOCK FOR THIS FORK
	MOVEI T1,.SSGDE		;FUNCTION CODE
	MOVEI T2,GDEBLK		;ADDRESS OF FUNCTION BLOCK
	PIOFF			;NO INTERRUPTS
	SCS%			;GET ENTRY FROM DATA QUEUE
	IFJER.
	  MOVEI T1,.FHSLF	;ERROR, GET
	  GETER			; THE ERROR CODE
	   ERJMP FATAL		;CAN'T HAVE THAT
	  HRRZS T2		;JUST THE ERROR CODE
	  CAIN T2,SCSQIE	;QUEUE EMPTY?
	  IFSKP.
	    HRROI LP,[ASCIZ/.SSGDE failed
/]
	    CALL TRACE
	    CALL SCSERR		;PROCESS SCS ERROR
	    JRST DMAPR1		;ONE MORE TIME
	    JRST FATAL		;THIS WAS A FATAL ONE
	  ENDIF.
	  PION			;ALLOW INTERRUPTS
	  HRROI LP,[ASCIZ/.SSGDE queue empty/] ;YES
	  CALL TRACE
	  RET			;NOTHING MORE TO DO
	ENDIF.
	PION			;ALLOW INTERRUPTS
	HRROI LP,[ASCIZ/.SSGDE ok/]
	CALL TRACE		;REPORT SUCCESS
	MOVE P1,.SQBID+GDEBLK	;GET BUFFER NAME
	MOVE P2,BUFNUM(TST)	;GET NUMBER OF BUFFERS
	MOVE Q1,TST		;GET TEST NUMBER
	IMULI Q1,NDMAOU		;CALCULATE OFFSET
	ADDI Q1,DMAMOU		;OFFSET INTO OUTGOING BUFFER NAMES
	MOVE Q2,TST		;GET TEST NUMBER
	IMULI Q2,NDMAIN		;CALCULATE OFFSET
	ADDI Q2,DMAMIN		;OFFSET INTO INCOMING BUFFER NAMES
	DO.
	  MOVE T1,(Q1)		;GET OUTGOING BUFFER NAME
	  CAME T1,P1		;IS THIS THE BUFFER?
	  IFSKP.			
	    AOS DMASND(TST)	;MUST BE A .SSSND DONE
	    AOS BUFSNT(TST)	;ONE MORE SEND DONE
	    MOVE T1,DMASND(TST)	;GET NUMBER OF SENDS DONE
	    EXIT.
	  ENDIF.		
	  MOVE T1,(Q2)		;GET INCOMING BUFFER NAME
	  CAME T1,P1		;IS THIS THE BUFFER?
	  IFSKP.
	    AOS DMAREQ(TST)	;IT IS A .SSREQ DONE
	    AOS BUFRCV(TST)	;ONE MORE RECEIVE DONE
	    MOVE T1,DMAREQ(TST)	;GET NUMBER OF REQUESTS DONE
	    EXIT.
	  ENDIF.			
	  AOS Q1		;NEXT OUTGOING ENTRY
	  AOS Q2		;NEXT INCOMING ENTRY
	  SOJN P2,TOP.		;CHECK MORE BUFFERS
	  HRROI LP,[ASCIZ/Invalid buffer name in .SSGDE interrupt/]
	  CALL LOGE		;LOG ERROR
	  JRST STPTST		;WE'RE DEAD
	ENDDO.
	CAMG T1,BUFNUM(TST)	;TOO MANY INTERRUPTS?
	IFSKP.			
	  HRROI LP,[ASCIZ/extra DMA transfer done interrupt/]  
	  SKIPE MNTFLG(TST)	;REALLY A MAINTENANCE TEST?
	  HRROI LP,[ASCIZ/extra MAINTENANCE transfer done interrupt/]  
	  CALL LOGW		;REPORT ERROR
	ENDIF.			
	JRST DMAPR1		;GET NEXT EVENT
	SUBTTL TIMER% Interrupt

TIMINT:	CALL TIMPRO		;() DO THE WORK
	DEBRK

TIMPRO:	SAVACS
	LOAD T1,TEST,(TST)	;GET TEST TYPE
	CAIL T1,0		;IS IT
	CAILE T1,TIMDPL		; LEGIT?
	JRST STPTST
	CALL @TIMDSP(T1)	;DO THE WORK
	RET


TIMDSP:	TIMWRN			;CONNECT
	TIMWRN			;CONNECT OPTIONAL DATA
	TIMWRN			;REJECT
	TIMWRN			;REJECT REASON CODE
	TIMWRN			;DISCONNECT
	TIMWRN			;DISCONNECT REASON CODE
	TIMIDL			;IDLE
	TIMDAT			;DATAGRAM
	TIMMSG			;MESSAGE
	TIMDMA			;DMA
	TIMMNT			;MAINTENANCE
	TIMDPL==.-TIMDSP-1

TIMWRN:	HRROI LP,[ASCIZ/Invalid TIMER% interrupt/]
	CALL LOGW		;LOG WARNING
	RET
;TIMER% INTERRUPT FOR AN IDLE TEST

TIMIDL:	HRROI LP,[ASCIZ/IDLE TIMER% interrupt/]
	CALL TRACE
	CALL DOSTS		;() GET CONNECTION STATUS
	 JRST FATAL		;FAILED
	HRRZ T1,.SQFST+STSBLK	;GET CONNECTION STATE
	CAIN T1,SQ%OPN		;RUNNING?
	IFSKP.
	  HRROI LP,[ASCIZ/IDLE test failed
/] ;NO
	CALL LOGE		;LOG ERROR
	ELSE.
	  MOVEI P1,R.IDL	;YES
	  CALL DODIS		;(T1) DO A DISCONNECT
	   JRST FATAL		;JSYS FAILED
	  HRROI LP,[ASCIZ/IDLE test complete
/]
	  CALL LOGG		;LOG IT
	ENDIF.
	JRST STPTST		;WE'RE DONE


;TIMER% INTERRUPT FOR A MESSAGE TEST

TIMDAT:	SETONE DONE,(TST)	;TEST TIME IS UP
	RET


;TIMER% INTERRUPT FOR A MESSAGE TEST

TIMMSG:	SETONE DONE,(TST)	;TEST TIME IS UP
	RET


;TIMER% INTERRUPT FOR A DMA TEST

TIMDMA:	SETONE DONE,(TST)	;TEST TIME IS UP
	RET

;TIMER% INTERRUPT FOR A MAINTENANCE TEST

TIMMNT:	SETONE DONE,(TST)	;TEST TIME IS UP
	RET
	SUBTTL Event Interrupt Routine

EVTINT:	CALL EVTPRO		;() GO PROCESS THE EVENT
	DEBRK

EVTPRO:	SAVACS
EVTPR1:	MOVEI T1,EVTBLK		;INIT
	HRLI T1,SSEVT		; THE ARG
	BLT T1,.LBEVT-1+EVTBLK	; BLOCK
	MOVEI T1,.SSEVT		;GET FUNCTION CODE
	MOVEI T2,EVTBLK		;GET ARG BLOCK ADDR
	PIOFF			;NO INTERRUPTS
	SCS%			;GET THE NEXT EVENT FOR THIS FORK
	IFJER.
	  MOVEI T1,.FHSLF	;ERROR, GET
	  GETER			; THE ERROR CODE
	   ERJMP FATAL		;CAN'T HAVE THAT
	  HRRZS T2		;JUST THE ERROR CODE
	  CAIN T2,SCSQIE	;QUEUE EMPTY?
	  IFSKP.
	    HRROI LP,[ASCIZ/.SSEVT failed
/]
	    CALL TRACE
	    CALL SCSERR		;PROCESS SCS ERROR
	    JRST EVTPR1		;ONCE AGAIN
	    JRST FATAL		;A BAD ERROR
	  ENDIF.
	  PION			;ALLOW INTERRUPTS
	  HRROI LP,[ASCIZ/.SSEVT queue empty/] ;YES
	  CALL TRACE
	  RET			;NOTHING MORE TO DO
	ENDIF.
	PION			;ALLOW INTERRUPTS
	HRROI LP,[ASCIZ/.SSEVT ok/]
	CALL TRACE
	MOVE T2,.SQCID+EVTBLK	;GET CONNECT ID
	CAMN T2,CONID(TST)	;IS IT US?
	IFSKP.
	  HRROI LP,[ASCIZ/wrong CID in event/]	;NO!
	  CALL LOGE		;LOG ERROR
	  JRST STPTST		;WE'RE DEAD
	ENDIF.
	MOVE T1,.SQEVT+EVTBLK	;YES, GET EVENT CODE
	SOS T1			;THERE'S NO EVENT CODE 0
	CAIL T1,0		;IS IT 
	CAILE T1,EVTDSP		; LEGIT?
	IFNSK.
	  HRROI LP,[ASCIZ/bad event code/] ;NO!
	  CALL LOGE		;LOG ERROR
	  JRST STPTST		;WE'RE DEAD
	ENDIF.
	CALL @EVTDSP(T1)	;YES, GO DO THE WORK
	JRST EVTPR1		;GO GET NEXT EVENT


EVTDSP:	VCBROK			;VC BROKEN
	INCONN			;INCOMING CONNECT
	ACCEPT			;OUTGOING CONNECT WAS ACCEPTED
	REJECT			;OUTGOING CONNECT WAS REJECTED
	SNDDON			;MESSAGE/DATAGRAM SEND DONE
	LTLCRD			;LITTLE CREDIT LEFT
	NODOFF			;NODE WENT OFF LINE
	NODON			;NODE CAME ON LINE
	OK2SND			;OK TO SEND
	RMDISC			;REMOTE SYSTEM INITIATED A DISCONNECT
	PRTBRK			;OUR PORT BROKE THE CONNECTION
	CRDAVL			;CREDIT NOW AVAILABLE
	EVTDPT=.-EVTDSP-1
VCBROK:	HRROI LP,[ASCIZ/circuit broken/]
	CALL TRACE
	JRST STPTST		
	SUBTTL Process an Incoming Connect 

;PROCESS AN INCOMING CONNECT
;RETURNS:	+1

INCONN:	HRROI LP,[ASCIZ/receiving connect/]
	CALL TRACE
	SAVEAC <Q1>		;FOR BYTE POINTER
	MOVX T1,.FHSUP		;INTERRUPT THE SUPERIOR FORK
	MOVE T2,[1B<LISCHN>]	; ON THE "NEW LISTENER" CHANNEL
	IIC
	IFJER.
	  LOGN (? SCSTST internal error - IIC% failed)
	  JRST FATAL
	ENDIF.
	LOAD T1,STATE,(TST)	;GET STATE OF CONNECTION
	CAIN T1,S.LIS		;LISTENING?
	IFSKP.
	  HRROI LP,[ASCIZ/test not listening/] ;NO!
	  CALL LOGE		;LOG ERROR
	  JRST STPTST		;WE'RE DEAD
	ENDIF.
   REPEAT 0,<
	LOGIDG
	LOG ( - Optional data:  )
	MOVE T1,[POINT 8,.SQDTA+EVTBLK] ;GET BP TO OPTOINAL DATA
	CALL LOGOPT		;(T1)
	LCRLF
   >
	MOVE Q1,[POINT 8,.SQDTA+EVTBLK] ;GET BP TO OPTOINAL DATA
	ILDB T1,Q1		;GET TEST TYPE
	CAIL T1,0		;IS IT
	CAILE T1,INCDPL		;LEGIT?
	JRST [	HRROI LP,[ASCIZ/bad test type byte/]
		CALL LOGE		;LOG ERROR
		MOVEI T1,S.STOP		;STATE IS
		STOR T1,STATE,(TST)	; STOPPING
		MOVEI P1,R.IVTN		;INVALID TEST NUMBER
		CALL DOREJ		;(T1) REJECT THE CONNECTION
		  JRST FATAL		;JSYS FAILED, STOP EVERYTHING
		MOVEI T1,S.LIS		;BACK TO A LISTENER
		STOR T1,STATE,(TST)	;SET IT
		SETZRO TEST,(TST)	;NO TEST
		JRST STPTST]		;WE'RE DEAD
	STOR T1,TEST,(TST)	;SAVE TEST TYPE
	CALL @INCDSP(T1)	;DO THE WORK
	RET
;INCOMING CONNECT DISPATCH TABLE

INCDSP:	INCCNN			;
	INCCNO			;
	INCRJ			;
	INCRJR			;
	INCDS			;
	INCDSR			;
	INCIDL			;
	INCDAT			;
	INCMSG			;
	INCDMA			;
	INCMNT			;MAINTENANCE
INCDPL=.-INCDSP-1
;HAVE AN INCOMING CONNECT FOR A CONNECT (NO OPTIONAL DATA) TEST
;ACCEPTS:	Q1/ BP TO OPTONAL DATA
;RETURNS:	+1

INCCNN:	HRROI LP,[ASCIZ/CONNECT NO-OPTIONAL-DATA/]
	CALL LOGG		;LOG IT
	MOVSI T1,-<<SQ%CDT*4>-1> ;AOBJN WORD FOR ALL BYTES
INCCN1:	ILDB T2,Q1		;GET NEXT BYTE
	SKIPE T2		;IS IT NULL?
	JRST BADOPT		;NO, REJECT CONNECTION AND KILL TEST
	AOBJN T1,INCCN1		;YES, DO ALL BYTES
	JRST INCCO3		;MOVE ON


;HAVE AN INCOMING CONNECT FOR A CONNECT (WITH OPTIONAL DATA) TEST
;ACCEPTS:	Q1/ BP TO OPTONAL DATA
;RETURNS:	+1

INCCNO:	HRROI LP,[ASCIZ/CONNECT OPTIONAL-DATA/]
	CALL LOGG		;LOG IT
	MOVSI T1,-<<SQ%CDT*4>-1> ;AOBJN WORD FOR ALL BYTES
INCCO1:	ILDB T2,Q1		;GET NEXT BYTE
	CAIE T2,OPTCHR		;THE RIGHT STUFF?
	JRST BADOPT		;NO, REJECT CONNECTION AND KILL TEST
	AOBJN T1,INCCO1		;YES, DO ALL BYTES
INCCO3:	CALL MOVOPT		;() POSITION OPTIONAL DATA
	CALL DOACC		;() ACCEPT THE CONNECTION
	 JRST FATAL		;FAILED
	RET
;HAVE AN INCOMING CONNECT FOR A REJECT (WITH NO REASON CODE) TEST
;ACCEPTS:	Q1/ BP TO OPTIONAL DATA
;RETURNS:	+1

INCRJ:	HRROI LP,[ASCIZ/REJECT - NO-REASON-CODE/]
	CALL LOGG		;LOG IT
	MOVSI T1,-<<SQ%CDT*4>-1> ;AOBJN WORD FOR ALL BYTES
INCRJ1:	ILDB T2,Q1		;GET NEXT BYTE
	SKIPE T2		;IS IT NULL?
	JRST BADOPT		;NO, REJECT CONNECTION AND KILL TEST
	AOBJN T1,INCRJ1		;YES, DO ALL BYTES
	SETZ P1,		;NO REASON CODE
	JRST INCRR2		;FINISH UP


;HAVE AN INCOMING CONNECT FOR A REJECT (WITH REASON CODE) TEST
;ACCEPTS:	Q1/ BP TO OPTIONAL DATA
;RETURNS:	+1

INCRJR:	HRROI LP,[ASCIZ/REJECT - REASON-CODE/]
	CALL LOGG		;LOG IT
	MOVSI T1,-<<SQ%CDT*4>-1> ;AOBJN WORD FOR ALL BYTES
INCRR1:	ILDB T2,Q1		;GET NEXT BYTE
	SKIPE T2		;IS IT NULL?
	JRST BADOPT		;NO, REJECT CONNECTION AND KILL TEST
	AOBJN T1,INCRR1		;YES, DO ALL BYTES
	MOVEI P1,R.REJR		;GET REASON CODE
INCRR2:	CALL DOREJ		;(T1) REJECT
	 JRST FATAL		;JSYS FAILED
	HRROI LP,[ASCIZ/REJECT test complete
/]
	CALL LOGG		;LOG IT
	JRST STPTST		;WE'RE DONE
;HAVE AN INCOMING CONNECT FOR A DISCONNECT (WITH NO REASON CODE) TEST
;ACCEPTS:	Q1/ BP TO OPTONAL DATA
;RETURNS:	+1

INCDS:	HRROI LP,[ASCIZ/DISCONNECT - NO-REASON-CODE/]
	CALL LOGG		;LOG IT
	JRST INCDR0		;DO THE ACCEPT


;HAVE AN INCOMING CONNECT FOR A DISCONNECT (WITH REASON CODE) TEST
;ACCEPTS:	Q1/ BP TO OPTONAL DATA
;RETURNS:	+1

INCDSR:	HRROI LP,[ASCIZ/DISCONNECT - REASON-CODE/]
	CALL LOGG		;LOG IT
INCDR0:	MOVSI T1,-<<SQ%CDT*4>-1> ;AOBJN WORD FOR ALL BYTES
INCDR1:	ILDB T2,Q1		;GET NEXT BYTE
	SKIPE T2		;NULL?
	JRST BADOPT		;NO, REJECT CONNECTION AND KILL TEST
	AOBJN T1,INCDR1		;YES, DO ALL BYTES
INCDR3:	CALL MOVOPT		;() POSITION OPTIONAL DATA
	CALL DOACC		;() ACCEPT THE CONNECTION
	 JRST FATAL		;FAILED
	RET
;HAVE AN INCOMING CONNECT FOR AN IDLE TEST
;ACCEPTS:	Q1/ BP TO OPTIONAL DATA
;RETURNS:	+1

INCIDL:	HRROI LP,[ASCIZ/IDLE/]
	CALL LOGG		;LOG IT
	JRST INCDR0		;DO THE ACCEPT


;HAVE AN INCOMING CONNECT FOR A DATAGRAM TEST
;ACCEPTS:	Q1/ BP TO OPTONAL DATA
;RETURNS:	+1

INCDAT:	HRROI LP,[ASCIZ/DATAGRAM/]
INCDA1:	CALL LOGG		;LOG IT
	ILDB T1,Q1		;GET XFER MODE
	STOR T1,TMODE,(TST)	;SAVE IT
	ILDB T2,Q1		;GET 1ST BYTE OF COUNT
	LSH T2,^D8		;POSITION IT
	ILDB T1,Q1		;GET 2ND BYTE OF COUNT
	IORM T2,T1		;MAKE 2-BYTE COUNT
	MOVEM T1,COUNT(TST)	;SAVE IT
	MOVSI T1,-<<SQ%CDT*4>-4> ;AOBJN WORD FOR REMAINING BYTES
	JRST INCDR1		;DO THE ACCEPT

;HAVE AN INCOMING CONNECT FOR A MESSAGE TEST
;ACCEPTS:	Q1/ BP TO OPTONAL DATA
;RETURNS:	+1

INCMSG:	HRROI LP,[ASCIZ/MESSAGE/]
	JRST INCDA1		;DO THE REST

;HAVE AN INCOMING CONNECT FOR A DMA TEST
;ACCEPTS:	Q1/ BP TO OPTONAL DATA
;RETURNS:	+1

INCDMA:	SETZM MNTFLG(TST)	;NOT A MAINTENANCE TEST
	HRROI LP,[ASCIZ/DMA/]
INCDM1:	CALL LOGG		;LOG IT
	ILDB T1,Q1		;GET XFER MODE
	STOR T1,TMODE,(TST)	;SAVE IT
	ILDB T2,Q1		;GET 1ST BYTE OF COUNT
	LSH T2,^D8		;POSITION IT
	ILDB T1,Q1		;GET 2ND BYTE OF COUNT
	IORM T2,T1		;MAKE 2-BYTE COUNT
	MOVEM T1,SEGSIZ(TST)	;SAVE IT
	ILDB T1,Q1		;GET NUMBER OF DMA BUFFERS
	MOVEM T1,BUFNUM(TST)	;SAVE IT
	ILDB T1,Q1		;GET NUMBER OF SEGMENTS PER BUFFER
	MOVEM T1,SEGNUM(TST)	;SAVE IT
	MOVSI T1,-<<SQ%CDT*4>-6>;AOBJN WORD FOR REMAINING BYTES
	JRST INCDR1		;DO THE ACCEPT

;HAVE AN INCOMING CONNECT FOR A MAINTENANCE TEST
;ACCEPTS:	Q1/ BP TO OPTONAL DATA
;RETURNS:	+1

INCMNT:	SETOM MNTFLG(TST)	;A MAINTENANCE TEST
	HRROI LP,[ASCIZ/MAINTENANCE/]
	JRST INCDM1		;DO THE REST
;BAD OPTITONAL DATA WAS FOUND IN AN INCOMING CONNECTION

BADOPT:	HRROI LP,[ASCIZ/wrong optional data in incoming connect/]
	CALL LOGE		;LOG ERROR
	MOVEI T1,S.STOP		;NO, STATE IS
	STOR T1,STATE,(TST)	; STOPPING
	MOVEI P1,R.WOPD		;NO, WRONG OPTIONAL DATA
	CALL DOREJ		;(T1) REJECT THE CONNECTION
	 JRST FATAL		;FAILED
	JRST STPTST		;WE'RE DEAD


;MOVE OPTIONAL DATA FROM INCOMING CONNECT TO OUTGOING ACCEPT
;RETURNS:	+1

MOVOPT:	HRRI T1,OPTDAT		;RETURN
	HRLI T1,.SQDTA+EVTBLK	; THE
	BLT T1,SQ%CDT-1+OPTDAT	; OPTIONAL DATA
	RET
	SUBTTL Connection Attempt Accepted

ACCEPT:	SAVEAC <Q1>
	HRROI LP,[ASCIZ/connection was accepted/]
	CALL TRACE
	LOAD T1,STATE,(TST)	;GET TEST STATE
	CAIE T1,S.STRT		;STARTING?
	RET			;SCA IS MESSED UP
   REPEAT 0,<
	LOGIDG
	LOG ( - Optional data:  )
	MOVE T1,[POINT 8,.SQDTA+EVTBLK] ;GET BP TO OPTOINAL DATA
	CALL LOGOPT		;(T1)
	LCRLF
   >
	MOVE Q1,[POINT 8,.SQDTA+EVTBLK] ;MAKE BP TO OPTIONAL DATA
	ILDB T1,Q1		;GET TEST TYPE FROM OPTIONAL DATA IN ACCEPT
	CAIL T1,0		;IS IT
	CAILE T1,ACCDPL		; POSSIBLE?
	JRST [	MOVEI T1,S.STOP		;NO, STATE IS
		STOR T1,STATE,(TST)	; STOPPING
		HRROI LP,[ASCIZ/invalid optional data on incoming accept/]
		CALL LOGE		;LOG ERROR
		MOVEI P1,R.WOPD		;WRONG OPTIONAL DATA
		CALL DODIS		;(T1) DISCONNECT
		 JRST FATAL		;JSYS FAILED
		JRST STPTST]		;WE'RE DEAD
	CALL @ACCDSP(T1)	;DO THE WORK
	RET


ACCDSP:	ACCCN
	ACCCNO
	ACCREJ
	ACCREJ
	ACCDIS
	ACCDIS
	ACCIDL
	ACCDAT
	ACCMSG
	ACCDMA
	ACCDMA			;MAINTENANCE TEST
	ACCDPL==.-ACCDSP-1
;OUR CONNECT TEST (NO OPTIONAL DATA) CONNECTION HAS BEEN ACCEPTED
;ACCEPTS:	Q1/ BP TO OPTIONAL DATA
;RETURNS:	+1

ACCCN:	CALL ACCCHK		;() CHECK TEST TYPE
	JRST ACCCO2		;WRONG
	MOVSI T1,-<<SQ%CDT*4>-1> ;AOBJN WORD FOR REMAINING OPTIONAL DATA BYTES
ACCCN1:	ILDB T2,T4		;GET A BYTE
	SKIPE T2		;IS IT NULL?
	JRST ACCCO2		;NO, WRONG
	AOBJN T1,ACCCN1		;YES, DO ALL OF OPTIONAL DATA
	JRST ACCCO3		;MOVE ON

;OUR CONNECT TEST (WITH OPTIONAL DATA) CONNECTION HAS BEEN ACCEPTED
;ACCEPTS:	Q1/ BP TO OPTIONAL DATA
;RETURNS:	+1

ACCCNO:	CALL ACCCHK		;() CHECK TEST TYPE
	JRST ACCCO2		;WRONG
	MOVSI T1,-<<SQ%CDT*4>-1> ;AOBJN WORD FOR REMAINING OPTIONAL DATA BYTES
ACCCO1:	ILDB T2,T4		;GET A BYTE
	CAIN T2,OPTCHR		;IS IT GOOD?
	IFSKP.
ACCCO2:	  MOVEI T1,S.STOP	;STATE IS
	  STOR T1,STATE,(TST)	; STOPPING
	  HRROI LP,[ASCIZ/CONNECT test failed - wrong optional data in accept
/]
	  CALL LOGE		;LOG ERROR
	  MOVEI P1,R.WOPD	;WRONG OPTIONAL DATA
	  CALL DODIS		;(T1) DISCONNECT
	   JRST FATAL		;JSYS FAILED
	  JRST STPTST		;WE'RE DEAD
	ENDIF.
	AOBJN T1,ACCCO1		;YES, DO ALL OF OPTIONAL DATA
ACCCO3:	MOVEI T1,S.RUN		;STATE IS
	STOR T1,STATE,(TST)	; RUNNING
	HRROI LP,[ASCIZ/CONNECT test running/]
	CALL LOGG		;LOG IT
	RET
;OUR DISCONNECT TEST CONNECTION HAS BEEN ACCEPTED
;ACCEPTS:	Q1/ BP TO OPTIONAL DATA
;RETURNS:	+1

ACCDIS:	CALL ACCCHK		;() CHECK TEST TYPE
	JRST ACCDI2		;WRONG
	MOVSI T1,-<<SQ%CDT*4>-1> ;YES, MAKE AOBJN WORD FOR REMAINING BYTES
ACCDI1:	ILDB T2,T4		;GET NEXT BYTE
	SKIPN T2		;IS IT NULL?
	IFSKP.
ACCDI2:	  MOVEI T1,S.STOP	;NO, STATE IS
	  STOR T1,STATE,(TST)	; STOPPING
	  HRROI LP,[ASCIZ/DISCONNECT test failed - wrong optional data in accept
/]
	  CALL LOGE		;LOG ERROR
	  MOVEI P1,R.WOPD	;NO, WRONG OPTIONAL DATA
	  CALL DODIS		;(T1) DISCONNECT
	   JRST FATAL		;FAILED
	  JRST STPTST		;WE'RE DEAD
	ENDIF.
	AOBJN T1,ACCDI1		;YES, DO ALL BYTES
	MOVEI T1,S.RUN		;STATE IS
	STOR T1,STATE,(TST)	; NOW RUNNING
	HRROI LP,[ASCIZ/DISCONNECT test running/]
	CALL LOGG		;LOG IT
	RET


;OUR REJCT TEST CONNECTION HAS BEEN ACCEPTED
;ACCEPTS:	Q1/ BP TO OPTIONAL DATA
;RETURNS:	+1

ACCREJ:	HRROI LP,[ASCIZ/REJECT test failed - connect was accepted
/]
	CALL LOGE		;LOG THE EREOR
	MOVEI P1,R.SNAC		;GET DISCONNECT CODE
	CALL DODIS		;DISCONNECT
	RET
;OUR IDLE TEST CONNECTION WAS ACCEPTED
;RETURNS:	+1

ACCIDL:	CALL ACCCHK		;() CHECK TEST TYPE
	JRST ACCID2		;WRONG
	MOVSI T1,-<<SQ%CDT*4>-1> ;YES, MAKE AOBJN WORD FOR REMAINING BYTES
ACCID1:	ILDB T2,T4		;GET NEXT BYTE
	SKIPN T2		;IS IT NULL?
	IFSKP.
ACCID2:	  MOVEI T1,S.STOP	;NO, STATE IS
	  STOR T1,STATE,(TST)	; STOPPING
	  HRROI LP,[ASCIZ/IDLE test failed - wrong optional data in accept
/]
	  CALL LOGE		;LOG ERROR
	  MOVEI P1,R.WOPD	;NO, WRONG OPTIONAL DATA
	  CALL DODIS		;(T1) DISCONNECT
	   JRST FATAL		;FAILED
	  JRST STPTST		;WE'RE DEAD
	ENDIF.
	AOBJN T1,ACCID1		;YES, DO ALL BYTES
	MOVEI T1,S.RUN		;STATE IS
	STOR T1,STATE,(TST)	; NOW RUNNING
	HRROI LP,[ASCIZ/IDLE test running/]
	CALL LOGG		;LOG IT
	RET
;OUR DATA TEST CONNECTION WAS ACCEPTED
;RETURNS:	+1

ACCDAT:	CALL ACCCHK		;(/T4) CHECK TEST TYPE
	JRST ACCDA2		;WRONG
	ILDB T1,T4		;GET XFER MODE
	LOAD T2,TMODE,(TST)	;GET WHAT WE THINK IT IS
	CAME T1,T2		;DOES IT MATCH?
	JRST ACCDA2		;NO
	ILDB T2,T4		;GET 1ST BYTE OF COUNT
	LSH T2,^D8		;POSITION IT
	ILDB T1,T4		;GET 2ND BYTE OF COUNT
	IORM T2,T1		;MAKE 2-BYTE COUNT
	CAME T1,COUNT(TST)	;DOES IT MATCH OUR COUNT?
	JRST ACCDA2		;NO
	MOVSI T1,-<<SQ%CDT*4>-4> ;YES, MAKE AOBJN WORD FOR REMAINING BYTES
ACCDA1:	ILDB T2,T4		;GET NEXT BYTE
	SKIPN T2		;IS IT NULL?
	IFSKP.
ACCDA2:	  MOVEI T1,S.STOP	;NO, STATE IS
	  STOR T1,STATE,(TST)	; STOPPING
	  HRROI LP,[ASCIZ/DATAGRAM test failed - wrong optional data in accept
/]
	  CALL LOGE		;LOG ERROR
	  MOVEI P1,R.WOPD	;NO, WRONG OPTIONAL DATA
	  CALL DODIS		;(T1) DISCONNECT
	   JRST FATAL		;FAILED
	  JRST STPTST		;WE'RE DEAD
	ENDIF.
	AOBJN T1,ACCDA1		;YES, DO ALL BYTES
	MOVEI T1,S.RUN		;STATE IS
	STOR T1,STATE,(TST)	; NOW RUNNING
	HRROI LP,[ASCIZ/DATAGRAM test running/]
	CALL LOGG		;LOG IT
	RET
;OUR MESSAGE TEST CONNECTION WAS ACCEPTED
;RETURNS:	+1

ACCMSG:	CALL ACCCHK		;(/T4) CHECK TEST TYPE
	JRST ACCMS2		;WRONG
	ILDB T1,T4		;GET XFER MODE
	LOAD T2,TMODE,(TST)	;GET WHAT WE THINK IT IS
	CAME T1,T2		;DOES IT MATCH?
	JRST ACCDA2		;NO
	ILDB T2,T4		;GET 1ST BYTE OF COUNT
	LSH T2,^D8		;POSITION IT
	ILDB T1,T4		;GET 2ND BYTE OF COUNT
	IORM T2,T1		;MAKE 2-BYTE COUNT
	CAME T1,COUNT(TST)	;DOES IT MATCH OUR COUNT?
	JRST ACCDA2		;NO
	MOVSI T1,-<<SQ%CDT*4>-4> ;YES, MAKE AOBJN WORD FOR REMAINING BYTES
ACCMS1:	ILDB T2,T4		;GET NEXT BYTE
	SKIPN T2		;IS IT NULL?
	IFSKP.
ACCMS2:	  MOVEI T1,S.STOP	;NO, STATE IS
	  STOR T1,STATE,(TST)	; STOPPING
	  HRROI LP,[ASCIZ/MESSAGE test failed - wrong optional data in accept
/]
	  CALL LOGE		;LOG ERROR
	  MOVEI P1,R.WOPD	;NO, WRONG OPTIONAL DATA
	  CALL DODIS		;(T1) DISCONNECT
	   JRST FATAL		;FAILED
	  JRST STPTST		;WE'RE DEAD
	ENDIF.
	AOBJN T1,ACCMS1		;YES, DO ALL BYTES
	MOVEI T1,S.RUN		;STATE IS
	STOR T1,STATE,(TST)	; NOW RUNNING
	HRROI LP,[ASCIZ/MESSAGE test running/]
	CALL LOGG		;LOG IT
	RET
;OUR DMA TEST CONNECTION WAS ACCEPTED
;RETURNS:	+1

;NOTE:  THIS ROUTINE IS ALSO IS USED WHEN A
;	MAINTENANCE TEST CONNECTION WAS ACCEPTED

ACCDMA:	CALL ACCCHK		;() CHECK TEST TYPE
	JRST ACCDM2		;WRONG
	ILDB T1,T4		;GET XFER MODE
	LOAD T2,TMODE,(TST)	;GET WHAT WE THINK IT IS
	CAME T1,T2		;DOES IT MATCH?
	JRST ACCDM2		;NO
	ILDB T2,T4		;GET 1ST BYTE OF COUNT
	LSH T2,^D8		;POSITION IT
	ILDB T1,T4		;GET 2ND BYTE OF COUNT
	IORM T2,T1		;MAKE 2-BYTE COUNT
	CAME T1,SEGSIZ(TST)	;DOES IT MATCH OUR SIZE?
	JRST ACCDM2		;NO
	ILDB T1,T4		;GET NUMBER OF DMA BUFFERS
	CAME T1,BUFNUM(TST)	;DOES IT MATCH OUR NUMBER?
	JRST ACCDM2		;NO
	ILDB T1,T4		;GET NUMBER OF SEGMENTS PER BUFFER
	CAME T1,SEGNUM(TST)	;DOES IT MATCH OUR NUMBER?
	JRST ACCDM2		;NO
	MOVSI T1,-<<SQ%CDT*4>-6> ;YES, MAKE AOBJN WORD FOR REMAINING BYTES
ACCDM1:	ILDB T2,T4		;GET NEXT BYTE
	SKIPN T2		;IS IT NULL?
	IFSKP.
ACCDM2:	  MOVEI T1,S.STOP	;NO, STATE IS
	  STOR T1,STATE,(TST)	; STOPPING
	  HRROI LP,[ASCIZ/DMA test failed - wrong optional data in accept
/]
	  SKIPE MNTFLG(TST)	;REALLY A MAINTENANCE TEST?
	  HRROI LP,[ASCIZ/MAINTENANCE test failed - wrong optional data in accept
/]				;YES, PRINT CORRECT ERROR
	  CALL LOGE		;LOG ERROR
	  MOVEI P1,R.WOPD	;NO, WRONG OPTIONAL DATA
	  CALL DODIS		;(T1) DISCONNECT
	   JRST FATAL		;FAILED
	  JRST STPTST		;WE'RE DEAD
	ENDIF.
	AOBJN T1,ACCDM1		;YES, DO ALL BYTES
	MOVEI T1,S.RUN		;STATE IS
	STOR T1,STATE,(TST)	; NOW RUNNING
	HRROI LP,[ASCIZ/DMA test running/]
	SKIPE MNTFLG(TST)	;REALLY A MAINTENANCE TEST?
	HRROI LP,[ASCIZ/MAINTENANCE test running/]  ;YES
	CALL LOGG		;LOG IT
	RET

;ACCEPT TEST CHECK
;RETURNS:	+1 FAILED
;		+2 ACCEPT DATA MATCHES OUR TEST TYPE

ACCCHK:	MOVE T4,[POINT 8,.SQDTA+EVTBLK] ;GET BP TO OPTIONAL DATA
	ILDB T3,T4		;GET TEST TYPE FROM ACCEPT'S OPTIONAL DATA
	LOAD T2,TEST,(TST)	;GET WHAT WE THINK IT IS
	CAME T2,T3		;DO WE AGREE?
	RET			;NO
	RETSKP			;YES
	SUBTTL Connection Rejected
REJECT:	HRROI LP,[ASCIZ/connection was rejected/]
	CALL TRACE
	LOAD T1,STATE,(TST)	;GET TEST STATE
	CAIE T1,S.STRT		;STARTING?
	RET			;SCA IS MESSED UP
	CALL DOCSP		;() GET CONNECTION STATUS
	 JRST FATAL		;FAILED
	HRRZ T2,.SQREA+CSPBLK	;GET REASON CODE
	LOAD T1,TEST,(TST)	;GET TEST TYPE
	CAIN T1,T.REJ		;REJECT?
	JRST REJEC1		;YES
	CAIN T1,T.REJR		;OR REJECT WITH REASON CODE?
	JRST REJEC2		;YES
	HRROI LP,[ASCIZ/connection rejected/] ;NO
	CALL LOGE		;LOG ERROR
	JRST STPTST		;WE'RE DEAD

;TEST IS REJECT WITHOUT REASON CODE

REJEC1:	SKIPE T2		;IS THERE A REASON CODE?
	JRST REJEC4		;YES, THAT'S BAD
	JRST REJEC3		;NO, GOOD

;TEST IS REJECT WITH REASON CODE

REJEC2:	CAIE T2,R.REJR		;THE RIGHT ONE?
	IFSKP.
REJEC3:	  HRROI LP,[ASCIZ/REJECT test complete
/] ;YES
	CALL LOGG		;LOG IT
	ELSE.
REJEC4:	  HRROI LP,[ASCIZ/REJECT test failed
/]
	  CALL LOGE		;LOG ERROR
	ENDIF.
	JRST STPTST
	SUBTTL Send Done

SNDDON:	HRROI LP,[ASCIZ/send done/]
	CALL TRACE
	MOVE T1,.SQDTA+EVTBLK	;GET BUFFER ADDR
	AOS BUFSNT(TST)		;ANOTHER BUFFER SENT
	RET


LTLCRD:	HRROI LP,[ASCIZ/little credit left/]  
	CALL TRACE		
	RET			

NODOFF:	HRROI LP,[ASCIZ/node off line/]  
	CALL TRACE		
	RET			

NODON:	HRROI LP,[ASCIZ/node on line/]  
	CALL TRACE		
	RET			
	SUBTTL OK to Send

;IT'S OK TO SEND ON THIS CONNECTION
;RETURNS:	+1

OK2SND:	HRROI LP,[ASCIZ/ok to send/]
	CALL TRACE
	LOAD T1,TEST,(TST)	;GET TEST TYPE
	CAIL T1,0		;JUST
	CAILE T1,OK2DPL		; CHECKING
	JRST SCSER		;WE MESSED UP
	MOVEI T2,S.RUN		;CONNECTION
	STOR T2,STATE,(TST)	; NOW RUNNING
	CALL @OK2DSP(T1)	;DO THE WORK
	RET

OK2DSP:	OK2CN
	OK2CNO
	SCSER
	SCSER
	OK2DS
	OK2DSR
	OK2IDL
	OK2DAT
	OK2MSG
	OK2MSG
	OK2MSG			;MAINTENANCE TEST
	OK2DPL==.-OK2DSP-1
;OK TO SEND ON OUR CONNECT TEST CONNECTION

OK2CN:	MOVEI P1,R.CON		;GOOD TEST
	SKIPA
OK2CNO:	MOVEI P1,R.CONO		;GOOD TEST
	CALL DODIS		;(T1) DISCONNECT
	 JRST FATAL		;JSYS FAILED
	HRROI LP,[ASCIZ/CONNECT test complete
/]
	CALL LOGG		;LOG IT
	JRST STPTST		;WE'RE DONE

;OK TO SEND ON OUR DISCONNECT TEST CONNECTION

OK2DS:	SETZ P1,		;NO REASON CODE
	SKIPA
OK2DSR:	MOVEI P1,R.DISR		;GOOD TEST
	CALL DODIS		;(T1) DISCONNECT
	 JRST FATAL		;JSYS FAILED
	HRROI LP,[ASCIZ/DISCONNECT test complete
/]
	CALL LOGG		;LOG IT
	JRST STPTST		;WE'RE DONE

;OK TO SEND

OK2MSG:	CALL MSGINI		;INIT MESSAGE BUFFERS
	MOVEI P1,.SSQRM		;GET FUNCTION CODE
	MOVE P2,MSGIN(TST)	;GET FIRST MESSAGE BUFFER
	JRST OK2DA1		;MOVE ON
OK2DAT:	CALL DATINI		;INIT DATAGRAM BUFFERS
	MOVEI P1,.SSQRD		;GET FUNCTION CODE
	MOVE P2,DATGIN(TST)	;GET FIRST DATAGRAM BUFFER
OK2DA1:	CALL DOQRX		;QUEUE THE BUFFER CHAIN
	 JRST FATAL		;FAILED
OK2IDL:	MOVEI T1,S.RUN		;TEST IS
	STOR T1,STATE,(TST)	; RUNNING
	RET
	SUBTTL Disconnect from remote system

RMDISC:	HRROI LP,[ASCIZ/receiving disconnect/]
	CALL TRACE
	LOAD Q1,TEST,(TST)	;GET TEST TYPE
	CAIL Q1,0		;JUST
	CAILE Q1,RMDDPL		; CHECKING
	JRST SCSER		;WE MESSED UP
	CALL DOCSP		;GET CONNECTION STATUS INFO
	 JRST FATAL		;JSYS FAILED
	HRRZ T2,.SQREA+CSPBLK	;GET REASON CODE
	CALL @RMDDSP(Q1)	;DO THE WORK
	RET

RMDDSP:	RMDCN
	RMDCNO
	SCSER
	SCSER
	RMDDS
	RMDDSR
	RMDIDL
	RMDDAT
	RMDMSG
	RMDDMA
	RMDMNT			;MAINTENANCE
	RMDDPL==.-RMDDSP-1
;REMOTE DISCONNECTED OUR CONNECT (WITH NO OPTIONAL DATA) TEST

RMDCN:	CAIE T2,R.CON		;THE RIGHT ONE?
	JRST RMDCN1		;NO
	JRST RMDCN2		;YES


;REMOTE DISCONNECTED OUR CONNECT (WITH OPTIONAL DATA) TEST

RMDCNO:	CAIN T2,R.CONO		;THE RIGHT ONE?
	IFSKP.
RMDCN1:	  HRROI LP,[ASCIZ/CONNECT test failed - wrong disconnect code
/]
	  CALL LOGE		;LOG ERROR
	ELSE.
RMDCN2:	  HRROI LP,[ASCIZ/CONNECT test complete
/]
	CALL LOGG		;LOG IT
	ENDIF.
	JRST STPTST


;REMOTE DISCONNECTED OUR DISCONNECT (WITH NO REASON CODE) TEST

RMDDS:	SKIPE T2		;THE RIGHT ONE?
	JRST RMDDS1		;NO
	JRST RMDDS2		;YES

;REMOTE DISCONNECTED OUR DISCONNECT (WITH REASON CODE) TEST

RMDDSR:	CAIN T2,R.DISR		;THE RIGHT ONE?
	IFSKP.
RMDDS1:	  HRROI LP,[ASCIZ/DISCONNECT test failed - wrong reason code
/]
	  CALL LOGE		;LOG ERROR
	ELSE.
RMDDS2:	  HRROI LP,[ASCIZ/DISCONNECT test complete
/]
	CALL LOGG		;LOG IT
	ENDIF.
	JRST STPTST


;REMOTE DISCONNECTED OUR IDLE TEST

RMDIDL:	MOVE T1,PMODE		;GET TEST MODE
	CAIN T1,SRVMOD		;ARE WE THE SERVER?
	IFSKP.
	  HRROI LP,[ASCIZ/IDLE test failed
/] ;NO
	  CALL LOGE		;LOG ERROR
	ELSE.
	  CAIN T2,R.IDL		;CORRECT REASON CODE?
	  IFSKP.
	    HRROI LP,[ASCIZ/IDLE test failed - wrong reason code
/] ;NO
	    CALL LOGE		;LOG IT
	  ENDIF.
	  HRROI LP,[ASCIZ/IDLE test complete
/] ;YES
	  CALL LOGG		;LOG IT
	ENDIF.
	JRST STPTST
;REMOTE DISCONNECTED OUR DATAGRAM TEST

RMDDAT:	MOVE T1,PMODE		;GET TEST MODE
	CAIN T1,SRVMOD		;ARE WE THE SERVER?
	IFSKP.
	  HRROI LP,[ASCIZ/DATAGRAM test failed
/] ;NO
	  CALL LOGE		;LOG ERROR
	ELSE.
	  HRROI LP,[ASCIZ/DATAGRAM test complete
/] ;YES
	  CALL LOGG		;LOG IT
	ENDIF.
	JRST STPTST


;REMOTE DISCONNECTED OUR MESSAGE TEST

RMDMSG:	MOVE T1,PMODE		;GET TEST MODE
	CAIN T1,SRVMOD		;ARE WE THE SERVER?
	IFSKP.
	  HRROI LP,[ASCIZ/MESSAGE test failed
/] ;NO
	  CALL LOGE		;LOG ERROR
	ELSE.
	  HRROI LP,[ASCIZ/MESSAGE test complete
/] ;YES
	  CALL LOGG		;LOG IT
	ENDIF.
	JRST STPTST


;REMOTE DISCONNECTED OUR DMA TEST

RMDDMA:	MOVE T1,PMODE		;GET TEST MODE
	CAIN T1,SRVMOD		;ARE WE THE SERVER?
	IFSKP.
	  HRROI LP,[ASCIZ/DMA test failed
/] ;NO
	  CALL LOGE		;LOG ERROR
	ELSE.
	  MOVX T1,UMP.IN	;UNMAP INCOMING BUFFERS ONLY
	  CALL DMAUMP		;CLEAR MAPPINGS
	   JRST FATAL		;FAILED
	  HRROI LP,[ASCIZ/DMA test complete
/] ;YES
	  CALL LOGG		;LOG IT
	ENDIF.
	JRST STPTST

;REMOTE DISCONNECTED OUR MAINTENANCE TEST

RMDMNT:	MOVE T1,PMODE		;GET TEST MODE
	CAIN T1,SRVMOD		;ARE WE THE SERVER?
	IFSKP.
	  HRROI LP,[ASCIZ/MAINTENANCE test failed
/] ;NO
	  CALL LOGE		;LOG ERROR
	ELSE.
	  MOVX T1,UMP.IN	;UNMAP INCOMING BUFFERS ONLY
	  CALL DMAUMP		;CLEAR MAPPINGS
	   JRST FATAL		;FAILED
	  HRROI LP,[ASCIZ/MAINTENANCE test complete
/] ;YES
	  CALL LOGG		;LOG IT
	ENDIF.
	JRST STPTST
	SUBTTL  Port Broke Connection and Credit Available Events

PRTBRK:	HRROI LP,[ASCIZ/our port broken connection/]
	CALL TRACE
	JRST STPTST

CRDAVL:	HRROI LP,[ASCIZ/credit available/]  
	CALL TRACE		
	SETOM CREDIT(TST)
	RET			
	SUBTTL Create a New Listener Interrupt Routine

LISINT:	CALL LISPRO		;() DO THE WORK
	DEBRK

LISPRO:	SAVACS
	CALL GETTST		;(/T4) GET A TEST STREAM
	IFNSK.
	  LOGN (% No available test streams)
	  RET
	ENDIF.
	MOVE P1,T4		;PRESERVE STREAM #
	MOVX P2,S.LIS		;INITIAL STATE IS LISTENING
	MOVEI P3,STRSRV		;START THE FORK HERE
	CALL STRFRK		;(P1,P2,P3) START A SERVER FORK
	IFNSK.
	  LOGN (% Failure while creating new listener)
	ENDIF.
	RET
	SUBTTL Fork Termination Interrupt Routine

FRKINT:	CALL FRKPRO		;() GO DO THE WORK
	DEBRK

FRKPRO:	SAVACS
	MOVSI Q1,-MAXTST	;AOBJN WORD TO SEARCH ALL TESTS
FRKPR1:	LOAD T1,FORKH,(Q1)	;GET FORK HANDLE
	SKIPN T1		;THIS ONE IN USE?
	IFSKP.
	  RFSTS			;YES, GET ITS STATUS
	   ERJMP FATAL		;ERROR - CAN'T CONTINUE
	  LOAD T2,RF%STS,T1	;JUST THE GOOD STUFF
	  CAIE T2,.RFHLT	;HALTED?
	  CAIN T2,.RFFPT	;OR TERMINATED?
	  JRST [SKIPGE LSTERR(Q1)	;YES, SELF INFLICTED?
	        JRST FRKPR2		;YES
	        LOAD T1,FORKH,(Q1)	;GET FORK HANDLE
	        GETER			;NO, GET THE ERROR
		 ERJMP FATAL		;CAN'T CONTINUE
	        HRRZM T2,LSTERR(Q1) 	;SAVE THE ERROR CODE
FRKPR2:	        CALL FRKERR		;REPORT THE DEATH
	        JRST .+1]
	ENDIF.
	AOBJN Q1,FRKPR1		;DO THEM ALL
	RET


;LOG AN ERROR
;ACCEPTS:	Q1/ TEST (FORK) #
;RETURNS:	+1
;PRESERVES Q1

FRKERR:	SKIPL LSTERR(Q1)	;SELF INFLICTED?
	JRST FRKER1		;NO
	HRROI LP,[ASCIZ/stopped/] ;YES
	HRRZ TST,Q1		;SET UP TEST # FOR LOGGER
	CALL TRACE
	JRST FRKER2

FRKER1:	HRROI LP,[ASCIZ/halted:  /]
	HRRZ TST,Q1		;SET UP TEST # FOR LOGGER
	CALL LOGE		;LOG ERROR
FRKER3:	AOSN LOGLOK		;LOCK AVAILABLE?
	IFSKP.
	  MOVEI T1,^D500	;NO, WAIT
	  DISMS			; HERE
	  JRST FRKER3		;TRY AGAIN
	ENDIF.
	MOVEI T1,.		;GET PC
	MOVEM T1,LSTLGR		;STASH IT PC
	MOVE T1,LOGPTR		;GET LOG BUFFER POINTER
	LOAD T2,FORKH,(Q1)	;GET FORK HANDLE
	HRLS T2			;POSITION IT
	HRR T2,LSTERR(Q1)	;GET ERROR CODE
	SETZB T3,T4		;NO SPECIAL FORMAT
	ERSTR
	 JFCL
	 JFCL
	MOVEM T1,LOGPTR		;UPDATE THE BP
	SETOM LOGDAT		;SAY THE LOG BUFFER HAS DATA
	SETOM LOGLOK		;DONE WITH THE LOCK
	SETZM LSTLGR
	LCRLF

FRKER2:	LOAD T1,FORKH,(Q1)	;GET FORK HANDLE
	KFORK			;KILL IT
	 ERJMP .+1
	MOVE T2,Q1		;GET TEST #
	CALL INITST		;(T2) INIT TEST PARAMETERS
	RET
	SUBTTL SCS% Error Handling 

;PROCESS AN SCS% ERROR
;RETURNS:	+1 A NON-FATAL ERROR TO SCSTST OCCURRED
;		   T2/ LAST ERROR
;		+2 A FATAL ERROR TO SCSTST OCCURRED
;		   T2/ LAST ERROR

;NOTE:	THIS ROUTINE SHOULD BE CALLED PIOFF SO THAT THE ERROR
;	CODE CAN BE OBTAINED RELIABLY.  THE ROUTINE WILL ISSUE
;	A PION AS SOON AS THE ERROR CODE IS OBTAINED.

SCSERR:	MOVEI T1,.FHSLF		;THIS PROCESS
	GETER			;GET LAST ERROR CODE
	 ERJMP FATAL		;ERROR
	HRRZS T2		;ISOLATE ERROR CODE
	PION			;ALLOW INTERRUPTS AGAIN
	CAIE T2,SCSNBA		;IS THIS A BUFFER SPACE FAILURE?
	CAIN T2,SCSNEB
	JRST SCSER1		;NON-FATAL BUFFER FAILURE
	RETSKP			;OTHERWISE - THIS WAS FATAL

SCSER1:	HRROI LP,[ASCIZ/Resources exhausted....waiting.../]
	CALL LOGW		;REPORT CONDITION
	MOVEI T1,^D15000	;WAIT 15 SECONDS
	DISMS			; FOR RESOURCES TO RETURN
	RET			;RETURN NON-FATAL


;A FATAL ERROR HAS OCCURRED AND THE PROGRAM CAN'T BE CONTINUED

FATAL:	SETZM LSTERR(TST)	;FATAL ERROR
	HALTF
	JRST .-1
	SUBTTL Utility Routines

;PUT A STRING IN THE LOG BUFFER
;ACCEPTS:	T2/ BP TO STRING
;		T3/ SOUT #, IF ENTERING AT LOGASC
;RETURNS:	+1
;
;ENTRY POINTS:  LOGASC IF ASCII
;		LOGASZ IF ASCIZ

LOGASC:	SKIPA T4,[-1]		;ASCII
LOGASZ:	SETZ T4,		;ASCIZ
	PIOFF			;DISABLE INTERRUPTS
LOGAS1:	SKIPN LOGJFN		;ARE WE LOGGING?
	JRST LOGAS2		;NO, DONE
	AOSN LOGLOK		;YES, LOCK AVAILABLE?
	IFSKP.
	  MOVEI T1,^D500	;NO, WAIT
	  DISMS			; HERE
	  JRST LOGAS1		;TRY AGAIN
	ENDIF.
	MOVEI T1,.		;GET PC
	MOVEM T1,LSTLGR		;STASH IT PC
	MOVE T1,LOGPTR		;GET BP TO LOG BUFFER
	SKIPN T4		;ASCIZ?
	SETZ T3,		;YES
	SOUT
	 ERJMP .+1
	MOVEM T1,LOGPTR		;UPDATE THE BP
	SETOM LOGDAT		;SAY THE LOG BUFFER HAS DATA
	SETOM LOGLOK		;DONE WITH THE LOCK
	SETZM LSTLGR
LOGAS2:	PION			;ENABLE INTERRUPTS NOW
	RET


;OUTPUT OPTIONAL DATA TO THE LOG BUFFER
;ACCEPTS:	T1/ BP TO OPTINAL DATA
;RETURNS:	+1

LOGOPT:	SAVEAC <Q1,Q2>
	MOVE Q2,T1		;PRESERVE BP
	MOVSI Q1,-<SQ%CDT*4>	;AOBJN WORD FOR ALL BYTES
LOGOP1:	ILDB T2,Q2		;GET A BYTE
	CALL LOGOCT		;(T2) LOG IT
	LOG (-)
	AOBJN Q1,LOGOP1		;DO THEM ALL
	RET
;PUT A NUMBER INTO THE LOG BUFFER
;ACCEPTS:	T2/ NUMBER
;RETURNS:	+1
;
;ENTRY POINTS:	LOGOCT - FOR OCTAL OUTPUT
;		LOGDEC - FOR DECIMAL OUTPUT

LOGOCT:	SKIPA T4,[-1]		;OCTAL
LOGDEC:	SETZ T4,		;DECIMAL
	PIOFF			;DISABLE INTERRUPTS
LOGDE1:	SKIPN LOGJFN		;ARE WE LOGGING?
	JRST LOGDE2		;NO, DONE
	AOSN LOGLOK		;YES, LOCK AVAILABLE?
	IFSKP.
	  MOVEI T1,^D500	;NO, WAIT HERE
	  DISMS			; FOR 1/2 SECOND
	  JRST LOGDE1		;TRY AGAIN
	ENDIF.
	MOVEI T1,.		;GET PC
	MOVEM T1,LSTLGR		;STASH IT PC
	MOVE T1,LOGPTR		;GET BP TO LOG BUFFER
	SKIPE T4		;DECIMAL?
	IFSKP.
	  MOVEI T3,^D10		;YES
	ELSE.
	  MOVEI T3,^D8		;NO
	ENDIF.
	NOUT
	 JRST FATAL		;FAILED
	MOVEM T1,LOGPTR		;UPDATE THE BP
	SETOM LOGDAT		;SAY THE LOG BUFFER HAS DATA
	SETOM LOGLOK		;DONE WITH THE LOCK
	SETZM LSTLGR
LOGDE2:	PION			;ENABLE INTERRUPTS NOW
	RET


;TRACE
;ACCEPTS:	LP/ BP TO STRING TO BE LOGGED
;RETURNS:	+1

TRACE:	SKIPE TRACEF		;TRACING ENABLED?
	SKIPN LOGJFN		;YES, HOW ABOUT LOGGING?
	RET			;NO
	CALL LOGT		;YES, LOG IT
	MOVSI T1,-750		;WAIT AWHILE TO 
	DISMS			;ALLOW LOGGER TO CATCH UP
	RET
;OUTPUT A NUMBER (IN DECIMAL) TO THE TTY
;ACCEPTS:	T2/ NUMBER
;RETURNS:	+1

TYPNUM:	MOVEI T1,.PRIOU		;TO THE TTY
	MOVEI T3,^D10		;DECIMAL
	NOUT
	 ERJMP [JSERR		;SOMETHING WRONG
		RET]
	RET


;LOG COUNTERS
;RETURNS:	+1

LOGCNT:	PIOFF			;NO INTERRUPTS
	HRROI LP,[ASCIZ/Buffers sent:  /]
	CALL LOGG
	MOVE T2,BUFSNT(TST)	;GET BUFFERS SENT
	CALL LOGDEC		;LOG AS DECIMAL
	LOG (	Buffers received:  )
	MOVE T2,BUFRCV(TST)	;GET BUFFERS RECEIVED
	CALL LOGDEC		;OUT PUT AS DECIMAL
	HRROI LP,[ASCIZ/Test duration:  /]
	  CALL LOGG		;YES
	MOVE T2,ETIME(TST)	;GET ENDING TIME
	SUB T2,STIME(TST)	;CALC TEST DURATION
	CALL LOGDEC		;OUTPUT NUMBER OF SECONDS
	RET
	PION			;ALLOW INTERRUPTS AGAIN
;LOG AN EVENT
;ACCEPTS:	LP/ BP TO STRING
;RETURNS:	+1

LOGG:	MOVEI T2,"#"		;GET GOOD INDICATOR
	JRST LOG2
LOGW:	MOVEI T2,"%"		;GET WARNING INDICATOR
	JRST LOG2
LOGE:	MOVEI T2,"?"		;GET ERROR INDICATOR
	JRST LOG2
LOGT:	MOVEI T2,"t"		;GET TRACE INDICATOR
LOG2:	PIOFF			;DISABLE INTERRUPTS
	STKVAR <IND>
	MOVEM T2,IND		;PRESERVE INDICATOR
LOG1:	SKIPN LOGJFN		;ARE WE LOGGING?
	JRST LOG3		;NO, DONE
	AOSN LOGLOK		;YES, LOCK AVAILABLE?
	IFSKP.
	  MOVEI T1,^D500	;NO, WAIT
	  DISMS			; HERE
	  JRST LOG1		;TRY AGAIN
	ENDIF.
	MOVEI T1,.		;GET PC
	MOVEM T1,LSTLGR		;STASH IT PC
	MOVE T1,LOGPTR		;GET BP TO LOG BUFFER
	HRROI T2,[ASCIZ/
/]
	SETZ T3,
	SOUT
	 ERJMP .+1
	SETO T2,		;OUTPUT
	MOVX T3,OT%NDA		; CURRENT
	ODTIM			; TIME
	 ERJMP .+1
	MOVEI T2," "		;GET A SPACE
	BOUT			;OUTPUT IT
	 ERJMP .+1
	MOVE T2,IND		;GET LOGGING TYPE INDICATOR
	BOUT			;OUTPUT IT
	 ERJMP .+1
	HRROI T2,[ASCIZ/ Test #/]
	SETZ T3,
	SOUT
	 ERJMP FATAL		;DON'T CONTINUE
	MOVE T2,TST		;GET TEST NUMBER
	MOVEI T3,^D10		;IN DECIMAL
	NOUT
	 JRST FATAL		;DON'T CONTINUE
	HRROI T2,[ASCIZ/ - /]
	SETZ T3,
	SOUT
	 ERJMP FATAL
	MOVE T2,LP		;GET BP TO STRING TO BE LOGGED
	SETZ T3,
	SOUT
	 ERJMP FATAL
	MOVEM T1,LOGPTR		;UPDATE THE BP
	SETOM LOGDAT		;SAY THE LOG BUFFER HAS DATA
	SETOM LOGLOK		;DONE WITH THE LOCK
	SETZM LSTLGR
LOG3:	PION			;ENABLE INTERRUPTS NOW 
	RET
;CHECK PROGRAM FOR INITIATOR MODE
;RETURNS:	+1  NOT INITIATOR
;		+2  INITIATOR

CKINIT:	MOVE T1,PMODE		;GET PROGRAM MODE
	CAIN T1,INIMOD		;INITIATOR?
	RETSKP			;YES
	TYPE (
? SCSTST must be in INITIATOR mode)
	RET


;CHECK FOR LEGAL TEST #
;ACCEPTS:	T2/ TEST NUMBER
;RETURNS:	+1  ILLEGAL
;		+2  LEGAL

CKTNUM:	CAIL T2,0		;MUST BE
	CAIGE T2,MAXTST		; LEGAL TEST #
	RETSKP			;GOOD
	TYPEN (
? Illegal test number)
	RET


;CHECK TO SEE IF ALL BUFFERS WERE ECHOED
;RETURNS:	+1 ALL BUFFERS NOT ECHOED
;		+2 ALL BUFFERS ECHOED

CHKECK:	MOVSI Q1,-^D60
CHKEC1:	MOVEI T1,^D500		;WAIT 1/2 A SECOND
	DISMS
	MOVE T1,BUFSNT(TST)	;GET BUFFERS SENT
	CAMN T1,BUFRCV(TST)	;SAME AS RECEIVED?
	RETSKP			;YES
	AOBJN Q1,CHKEC1		;NO, WAIT A BIT AND TRY AGAIN
	RET			;TOO LATE NOW


;WAIT FOR CREDIT AVAILABLE
;RETURNS:	+1 TIME OUT WAITING FOR CREDIT AVAILABLE
;		+2 CREDIT IS AVAILABLE

CHKCRD:	SKIPE CREDIT(TST)	;IS CREDIT AVAILABLE?
       	RETSKP			;YES, RETURN SUCCESS
	MOVSI T2,-30		;WAIT FOR 30 SECONDS
	DO.
	  MOVEI T1,^D1000	;ONE SECOND AT A TIME
	  DISMS
	  SKIPE CREDIT(TST)	;CREDIT AVAILABLE YET?
	  RETSKP		;YES
	  AOBJN T2,TOP.		;CONTINUE TO WAIT
	ENDDO.
	RET			;NEVER GOT CREDIT
;INITIALIZE A TEST STREAM'S DATA BASE
;ACCEPTS:	T2/ STREAM #
;RETURNS:	+1

INITST:	SETZM STATUS(T2)	;STATUS
	SETZM COUNT(T2)		;BYTE COUNT
	SETZM TTIME(T2)		;TEST TIME
	SETZM ITIME(T2)		;INTERNAL TIME
	SETZM BUFNUM(T2)	;NUMBER OF BUFFERS
	SETZM SEGSIZ(T2)	;SEGMENT SIZE
	SETZM SEGNUM(T2)	;NUMBER OF SEGMENTS PER BUFFER
	SETZM CONID(T2)		;CONNECT ID
	SETZM SBI(T2)		;SBI
	SETZM DATGIN(T2)	;DATAGRAM CHAIN
	SETZM MSGIN(T2)		;MESSAGE CHAIN
	SETZM LSTERR(T2)	;LAST ERROR
	SETZM CREDIT(T2)	;CREDIT IS NOT AVAILABLE
	SETZM BUFSNT(T2)	;# BUFFERS SENT
	SETZM BUFRCV(T2)	;# BUFFERS RECEIVED
	SETZM MNTFLG(T2)	;ASSUME NOT A MAINTENANCE TEST
	RET


;SEE IF A GIVEN CI NODE IS ALIVE
;ACCEPTS:	T3/ CI NODE NUMBER
;RETURNS:	+1  NOT UP
;		+2  UP

FNDNOD:	SAVEAC <Q1>
	MOVEM T3,Q1		;SAVE NODE NUMBER
       	SETZ P1,		;NO CONNECT ID
	HRRZ P2,T3		;JUST THE NODE NUMBER
	CALL DORCD		;(P1,P2) GET CONFIGURATION DATA
	 RET			;NO MORE TO LOOK AT
	HRRZ T3,.SQVCS+RCDBLK	;GET NODE NUMBER
	CAME T3,Q1		;THE ONE WE'RE LOOKING FOR?
        RET			;DIDN'T FIND IT
	RETSKP
    

;GET A TEST STREAM
;RETURNS:	+1  NONE AVAILABLE
;		+2  T4/ TEST STREAM #

GETTST:	MOVSI T4,-MAXTST	;AOBJN WORD FOR ALL TEST STREAMS
GETTSL:	SKIPE STATUS(T4)	;THIS STREAMS IN USE?
	IFSKP.
	  HRRZS T4		;YES, GET JUST THE STREAM #
	  RETSKP
	ENDIF.
	AOBJN T4,GETTSL		;NO, TRY THE NEXT ONE
	RET			;ALL STREAMS IN USE

;TURN PI SYSTEM OFF
;RETURNS:	+1 ALWAYS

.PIOFF:	SKIPE PSISYS(TST)	;PSI SYSTEM ON?
	IFSKP.			;DON'T REALLY TURN IT OFF IF ALREADY OFF
	  PUSH P,T1
	  MOVX T1,.FHSLF
	  DIR
	   ERJMP FATAL
	  POP P,T1
	ENDIF.
	AOS PSISYS(TST)		;SYSTEM IS OFF AGAIN
	RET

;TURN PI SYSTEM ON
;RETURNS:	+1 ALWAYS

.PION:	SOSE PSISYS(TST)	;ADJUST PSI STATUS COUNT
	IFSKP.			;IF NESTED, ONLY TURN PI
	  PUSH P,T1		; ON WHEN REALLY DESIRED
	  MOVX T1,.FHSLF
	  EIR
	   ERJMP FATAL
	  POP P,T1
	ENDIF.
	SKIPL PSISYS(TST)	;TOO MANY PIONS?
	IFSKP.
	  HRROI LP,[ASCIZ/Too many PION requests/]
	  CALL LOGE		;REPORT ERROR
	  JRST STPTST		;STOP TEST
	ENDIF.
	RET
	SUBTTL Start Lower Fork

;START A LOWER FORK
;ACCEPTS:	P1/ STREAM #
;		P2/ INITIAL STATE
;		P3/ START ADDRESS
;RETURNS:	+1 FAILED
;		+2 SUCCESS

STRFRK:	MOVEI T2,1+TSTACS	;INIT
	HRLI T2,TSTACS		; THE
	SETZM TSTACS		; ACS
	BLT T2,17+TSTACS
	MOVEM P1,TST+TSTACS	;TELL FORK
	MOVE T1,[CR%MAP!CR%CAP!CR%ACS] ;SAME MAP AND CAPABILITIES, SET THE ACS
	MOVEI T2,TSTACS		;SET THE AC BASE
	CFORK			;CREATE AND START THE FORK
	 ERJMP [RET]
	STOR T1,FORKH,(P1)	;SET FORK HANDLE
	STOR P2,STATE,(P1)	;SET IT
	MOVE T2,P3		;GET FORK'S STARTING ADDR
	SFORK			;START THE FORK
	 ERJMP [RET]		;FAILED
	RETSKP


;INITIALIZE OPTIONAL DATA AREA
;RETURNS:	+1
;PRESERVES T1

INIOPT:	SAVEAC <T1>
	MOVEI T1,1+OPTDAT	;INIT
	HRLI T1,OPTDAT		; THE
	SETZM OPTDAT		; OPTIONAL DATA
	BLT T1,SQ%CDT-1+OPTDAT	; BLOCK
	RET
	SUBTTL AC Save/Restore Facility

.SAVAC:				;ROUTINE TO SAVE ACS ON STACK
	ADJSP P,^D14		;GET ROOM ON THE STACK
	MOVEM CX,0(P) 		;SAVE AC 16
	MOVEI CX,-^D13(P)	;GET RIGHT HALF OF BLT AC
	HRLI CX,T1		;GET LEFT HALF OF BLT AC
	BLT CX,-1(P)		;SAVE ACS 1-15
	MOVE CX,0(P)		;RESTORE AC 16
	CALL @-^D14(P)		;GO BACK TO CALLER
.RSTAC:				;HERE TO RESTORE ACS VIA ORIGINAL CALLERS RET
	SKIPA			;NON-SKIP RETURN
	AOS -^D15(P)		;SKIP RETURN...BUMP RETURN PC
	HRLI CX,-^D13(P)	;GET BLT AC LEFT
	HRRI CX,T1		;GET BLT AC RIGHT
	BLT CX,CX		;RESTORE ACS
	ADJSP P,-^D15		;FIX UP THE STACK
	RET			;RETURN TO ORIGINAL



SCSER:	TYPEN (
? SCSTST internal error)

STPTST:	MOVEI T1,S.HALT		;WE'RE
	STOR T1,STATE,(TST)	; DEAD
	SETOM LSTERR(TST)	;SELF INFLICTED HALT
	HALTF
	JRST .-1		;DO NOT CONTINUE
	SUBTTL Initialize Buffers

;INITALIZE DATAGRAM BUFFERS FOR A TEST STREAM
;RETURNS:	+1

DATINI:	MOVE T2,TST		;GET TEST #
	IMULI T2,NDATBF*DATBFL	;OFFSET INTO
	ADDI T2,DATINB		; BUFFER POOL
	MOVEM T2,DATGIN(TST)	;SAVE TEST'S FIRST DATAGRAM ADDRESS
	MOVSI T4,-NDATBF	;AOBJN WORD FOR DATAGRAM BUFFERS PER TEST
DATIN1:	MOVE T3,T2		;PRESERVE ADDR
	ADDI T2,DATBFL		;MOVE TO NEXT BUFFER
	MOVEM T2,(T3)		;PUT NEXT BUFFER ADDRESS IN THIS BUFFER
	AOBJN T4,DATIN1		;DO ALL BUFFERS FOR THIS TEST STREAM
	SETZM (T3)		;TIE OFF LAST BUFFER

	MOVE T3,TST		;GET TEST #
	IMULI T3,NDATBF		;OFFSET INTO
	ADDI T3,DATGOU		; LIST 
	MOVE T2,TST		;GET TEST #
	IMULI T2,NDATBF*PAGSIZ	;OFFSET INTO
	ADDI T2,DATOUB+.SQTXT	; INTO BUFFER POOL
	MOVSI T4,-NDATBF	;AOBJN WORD FOR DATAGRAM BUFFERS PER TEST
DATIN2:	MOVEM T2,(T3)		;SAVE BUFFER ADDRESS
	SETOM (T2)		;INIT FIRST WORD IN BUFFER
	AOS T3			;NEXT LOC
	ADDI T2,PAGSIZ		;NEXT BUFFER
	AOBJN T4,DATIN2		;DO ALL BUFFERS FOR THIS TEST STREAM
	RET

;INITIALIZE MESSAGE BUFFERS FOR A TEST STREAM
;RETURNS:	+1

MSGINI:	MOVE T2,TST		;GET TEST #
	IMULI T2,NMSGBF*MSGBFL	;OFFSET INTO
	ADDI T2,MSGINB		; BUFFER POOL
	MOVEM T2,MSGIN(TST)	;SAVE TEST'S FIRST MESSAGE ADDRESS
	MOVSI T4,-NMSGBF	;AOBJN WORD FOR MESSAGE BUFFERS PER TEST
MSGIN1:	MOVE T3,T2		;PRESERVE ADDR
	ADDI T2,MSGBFL		;MOVE TO NEXT BUFFER
	MOVEM T2,(T3)		;PUT NEXT BUFFER ADDRESS IN THIS BUFFER
	AOBJN T4,MSGIN1		;DO ALL BUFFERS FOR THIS TEST STREAM
	SETZM (T3)		;TIE OFF LAST BUFFER

	MOVE T3,TST		;GET TEST #
	IMULI T3,NMSGBF		;OFFSET INTO
	ADDI T3,MSGOU		; LIST
	MOVE T2,TST		;GET TEST #
	IMULI T2,NMSGBF*PAGSIZ	;OFFSET INTO
	ADDI T2,MSGOUB+.SQTXT	; BUFFER POOL
	MOVSI T4,-NMSGBF	;AOBJN WORD FOR MESSAGE BUFFERS PER TEST
MSGIN2:	MOVEM T2,(T3)		;SAVE BUFFER ADDRESS
	SETOM (T2)		;INIT FIRST WORD IN BUFFER
	AOS T3			;NEXT LOC
	ADDI T2,PAGSIZ		;NEXT BUFFER
	AOBJN T4,MSGIN2		;DO ALL BUFFERS FOR THIS TEST STREAM
	RET


;INITIALIZE DMA BUFFERS FOR A TEST STREAM
;RETURNS:	+1

;DO THE INCOMING BUFFERS

DMAINI:	MOVE T1,TST		;GET TEST #
	IMULI T1,MXDMAW*NDMASG*2;OFFSET
	ADDI T1,DMABFS		; TO ITS BUFFER AREA
	MOVE T2,TST		;GET TEST #
	IMULI T2,NDMAIN		;OFFSET
	ADDI T2,DMAINB		; TO ITS INCOMG BUFFER LIST
	MOVSI T3,-NDMAIN	;AOBJN WORD FOR INCOMING BUFFERS
DMAIN1:	SETOM (T1)		;THIS BUFFER IS NOT IN USE
	MOVEM T1,(T2)		;STASH THE BUFFER ADDR
	ADDI T1,MXDMAW*NDMASG	;MOVE TO NEXT BUFFER
	AOS T2			;MOVE TO NEXT LIST ENTRY
	AOBJN T3,DMAIN1		;DO ALL OF THEM

;DO THE OUTGOING BUFFERS

	MOVE T2,TST		;GET TEST #
	IMULI T2,NDMAOU		;OFFSET
	ADDI T2,DMAOUB		; TO ITS OUTBOUND BUFFER LIST
	MOVSI T3,-NDMAOU	;AOBJN WORD FOR OUTGOING BUFFERS
DMAIN2:	SETOM (T1)		;THIS BUFFER IS NOT IN USE
	MOVEM T1,(T2)		;SAVE THE BUFFER ADDR
	ADDI T1,MXDMAW*NDMASG	;MOVE TO NEXT BUFFER
	AOS T2			;MOVE TO NEXT LIST ENTRY
	AOBJN T3,DMAIN2		;DO THEM ALL
	RET
	SUBTTL Get/Return an available buffer

;GET A FREE DATAGRAM BUFFER FOR A STREAM
;RETURNS:	+1 FAILED
;		+2 SUCCESS  T1/ BUFFER ADDRESS

GETDAT:	MOVE T3,TST		;GET TEST STREAM
	IMULI T3,NDATBF		;OFFSET INTO THE BUFFER LIST
	HRLI T3,-NDATBF		;MAKE AOBJN WORD FOR THIS TEST'S BUFFERS
GETDA1:	MOVE T1,@DATGOU(T3)	;GET FIRST WORD OF BUFFER
	CAME T1,[-1]		;IN USE?
	IFSKP.
	  MOVE T1,DATGOU(T3)	;NO, FOUND ONE
	  RETSKP
	ENDIF.
	AOBJN T3,GETDA1		;YES, TRY THE NEXT ONE
	RET


;RETURN A DATAGRAM BUFFER TO THE FREE POOL
;ACCEPTS:	T1/ BUFFER ADDRESS
;RETURNS:	+1

RETDAT:	SETZM (T1)		;WE'LL ZERO THE BUFFER
	MOVEI T3,DATBFL-1	;CALC THE END
	ADD T3,T1		; OF THE BUFFER
	HRL T2,T1		;MAKE THE
	HRRI T2,1(T1)		; BLT WORD
	BLT T2,(T3)		;ZERO THE BUFFER
	SETOM (T1)		;SAY IT'S AVAILABLE FOR USE
	RET
;GET A FREE MESSAGE BUFFER FOR A STREAM
;RETURNS:	+1 FAILED
;		+2 SUCCESS  T1/ BUFFER ADDRESS

GETMSG:	MOVE T3,TST		;GET TEST STREAM
	IMULI T3,NMSGBF		;OFFSET INTO THE BUFFER LIST
	HRLI T3,-NMSGBF		;MAKE AOBJN WORD FOR THIS TEST'S BUFFERS
GETMS1:	MOVE T1,@MSGOU(T3)	;GET FIRST WORD OF BUFFER
	CAME T1,[-1]		;IN USE?
	IFSKP.
	  MOVE T1,MSGOU(T3)	;NO, FOUND ONE
	  RETSKP
	ENDIF.
	AOBJN T3,GETMS1		;YES, TRY THE NEXT ONE
	RET

;RETURN A MESSAGE BUFFER TO THE FREE POOL
;ACCEPTS:	T1/ BUFFER ADDRESS
;RETURNS:	+1

RETMSG:	SETZM (T1)		;WE'LL ZERO THE BUFFER
	MOVEI T3,MSGBFL-1	;CALC THE END
	ADD T3,T1		; OF THE BUFFER
	HRL T2,T1		;MAKE THE
	HRRI T2,1(T1)		; BLT WORD
	BLT T2,(T3)		;ZERO THE BUFFER
	SETOM (T1)		;SAY IT'S AVAILABLE FOR USE
	RET
;GET A FREE OUTGOING DMA BUFFER
;RETURNS:	+1 FAILED
;		+2 SUCCESS, WITH: T1 = BUFFER ADDRESS
;			          T3 = BUFFER NUMBER-1

GTDMAO:	MOVE T1,TST		;GET TEST #
	IMULI T1,NDMAOU		;OFFSET
	ADDI T1,DMAOUB		; TO TEST'S BUFFER LIST
	MOVSI T3,-NDMAOU	;AOBJN WORD TO CHECK ALL BUFFERS
GTDMO1:	MOVE T2,@(T1)		;GET BUFFER
	CAME T2,[-1]		;IN USE?
	IFSKP.
	  MOVE T1,(T1)		;NO
	  HRRZS T3		;RECORD BUFFER OFFSET
	  RETSKP		;FOUND ONE
	ENDIF.
	AOS T1			;MOVE TO NEXT LIST ENTRY
	AOBJN T3,GTDMO1		;CHECK ALL BUFFERS
	RET			;DIDN'T FIND A FREE ONE
	SUBTTL Send a connect request

;SEND A CONNECT REQUEST
;ACCEPTS:	P1/ ADDRESS OF MESSAGE BUFFER CHAIN
;		P2/ ADDRESS OF DATAGRAM BUFFER CHAIN
;RETURNS:	+1 FAILED
;		+2 SUCCESS

DOCON:	MOVEI T1,CONBLK		;INIT
	HRLI T1,SSCON		; THE
	BLT T1,.LBCON-1+CONBLK	; ARG BLOCK
	HRRM TST,.SQSYS+CONBLK	;SET CONNECTION #
	MOVE T1,SBI(TST)	;GET SBI
	HRLM T1,.SQSYS+CONBLK	;SET IT
	MOVEI T1,OPTDAT		;GET OPTIONAL DATA ADDR
	MOVEM T1,.SQCDT+CONBLK	;PUT IT IN
	MOVEM P1,.SQAMC+CONBLK	;PUT IN MESSAGE BUFFER CHAIN ADDR
	MOVEM P2,.SQADC+CONBLK	;PUT IN DATAGRAM BUFFER CHAIN ADDR
   REPEAT 0,<
	LOGIDG
	LOG ( - Optional data:  )
	MOVE T1,[POINT 8,OPTDAT]
	CALL LOGOPT		;(T1)
	LCRLF
   >
	MOVEI T1,.SSCON		;GET FUNCTION CODE
	MOVEI T2,CONBLK		;GET ARG BLOCK ADDR
	PIOFF			;NO INTERRUPTS
	SCS%
	IFJER.
	  HRROI LP,[ASCIZ/.SSCON failed/]
	  CALL TRACE
	  CALL SCSERR		;PROCESS SCS ERROR
	  JRST DOCON		;TRY ONCE AGAIN
	  RET			;FATAL ERROR
	ENDIF.
	PION			;ALLOW INTERRUPTS
	HRROI LP,[ASCIZ/.SSCON ok/]
	CALL TRACE
	MOVE T1,.SQRCI+CONBLK	;GET THE CONNECT ID
	MOVEM T1,CONID(TST)	;SAVE IT
	MOVEI T1,S.STRT		;TEST IS
	STOR T1,STATE,(TST)	; STARTING
	RETSKP
	SUBTTL Send a Reject/Disconnect

;SEND A REJECT
;ACCEPTS:	P1/ REASON CODE
;RETURNS:	+1 FAILED
;		+2 SUCCESS

DOREJ:	MOVEM P1,.SQREJ+REJBLK	;PUT IN REASON CODE
	MOVEI T1,.LBREJ		;GET ARG BLOCK LENGTH
	MOVEM T1,.SQLEN+REJBLK	;PUT IT IN ARG BLOCK
	MOVE T1,CONID(TST)	;GET CONNECT ID
	MOVEM T1,.SQCID+REJBLK	;PUT IN CONNECT ID
	MOVEI T1,.SSREJ		;GET FUNCTION CODE
	MOVEI T2,REJBLK		;GET ARG BLOCK ADDR
	PIOFF			;NO INTERRUPTS
	SCS%
	IFJER.
	  HRROI LP,[ASCIZ/.SSREJ failed/]
	  CALL TRACE
	  CALL SCSERR		;PROCESS SCS ERROR
	  JRST DOREJ		;TRY ONCE AGAIN
	  RET			;FATAL ERROR OCCURRED
	ENDIF.
	PION			;ALLOW INTERRUPTS
	HRROI LP,[ASCIZ/.SSREJ ok/]
	CALL TRACE
	MOVEI T1,S.STOP		;TEST IS
	STOR T1,STATE,(TST)	; STOPPING
	RETSKP


;SEND A DISCONNECT
;ACCEPTS:	P1/ REASON CODE
;RETURNS:	+1 FAILED
;		+2 SUCCESS

DODIS:	MOVEM P1,.SQDIS+DISBLK	;PUT IN REASON CODE
	MOVEI T1,.LBDIS		;GET ARG BLOCK LENGTH
	MOVEM T1,.SQLEN+DISBLK	;PUT IT IN ARG BLOCK
	MOVE T1,CONID(TST)	;GET CONNECT ID
	MOVEM T1,.SQCID+DISBLK	;PUT IT IN
	MOVEI T1,.SSDIS		;GET DISCONNECT FUNCTION CODE
	MOVEI T2,DISBLK		;GET ARG BLOCK ADDR
	PIOFF			;NO INTERRUPTS
	SCS%
	IFJER.
	  HRROI LP,[ASCIZ/.SSDIS failed/]
	  CALL TRACE
	  CALL SCSERR		;PROCESS SCS ERROR
	  JRST DODIS		;CONTINUE
	  RET			;THIS WAS A FATAL ERROR
	ENDIF.
	PION			;ALLOW INTERRUPTS
	HRROI LP,[ASCIZ/.SSDIS ok/]
	CALL TRACE
	MOVEI T1,S.STOP		;TEST NOW
	STOR T1,TEST,(TST)	; STOPPING
	RETSKP
	SUBTTL Set up a listener

;SET UP A LISTNER
;ACCEPTS:	P1/ SBI
;		P2/ CONNECTION #
;RETURNS:	+1 FAILED
;		+2 SUCCESS

DOLIS:	MOVEI T1,LISBLK		;INIT
	HRLI T1,SSLIS		; THE
	BLT T1,.LBLIS-1+LISBLK	; ARG BLOCK
	HRRM P2,.SQSYS+LISBLK	;SET CONNECTION #
	HRLM P1,.SQSYS+LISBLK	;SET SBI
	MOVEI T1,.SSLIS		;GET FUNCTION CODE
	MOVEI T2,LISBLK		;GET ARG BLOCK ADDR
	PIOFF			;NO INTERRUPTS
	SCS%
	IFJER.
	  HRROI LP,[ASCIZ/.SSLIS failed/]
	  CALL TRACE
	  CALL SCSERR		;PROCESS SCS ERROR
	  JRST DOLIS		;CONTINUE
	  RET			;FATAL ERROR
	ENDIF.
	PION			;ALLOW INTERRUPTS
	HRROI LP,[ASCIZ/.SSLIS ok/]
	CALL TRACE
	MOVE T1,.SQLCI+LISBLK	;GET THE CONNECT ID
	MOVEM T1,CONID(TST)	;SAVE IT
	MOVEI T1,S.LIS		;TEST NOW
	STOR T1,STATE,(TST)	; LISTENING
	RETSKP
	SUBTTL Accept a Connection

;ACCEPT A CONNECTION
;RETURNS:	+1 FAILED
;		+2 SUCCESS

DOACC:	MOVEI T1,.LBACC		;GEWT LENGTH OF ARG BLOCK
	MOVEM T1,.SQLEN+ACCBLK	;PUT IT IN
	MOVE T1,CONID(TST)	;GET CONNECT ID
	MOVEM T1,.SQCID+ACCBLK	;PUT IT IN
	MOVEI T1,OPTDAT		;GET OPTIONAL DATA ADDR
	MOVEM T1,.SQCDA+ACCBLK	;PUT IT IN
   REPEAT 0,<
	LOGIDG
	LOG ( - Optional data:  )
	MOVE T1,[POINT 8,OPTDAT]
	CALL LOGOPT		;(T1)
	LCRLF
   >
	MOVEI T1,.SSACC		;GET FUNCTION CODE
	MOVEI T2,ACCBLK		;GET ARG BLOCK ADDR
	PIOFF			;NO INTERRUPTS
	SCS%
	IFJER.
	  HRROI LP,[ASCIZ/.SSACC failed/]
	  CALL TRACE
	  CALL SCSERR		;PROCESS SCS ERROR
	  JRST DOACC		;CONTINUE
	  RET			;FATAL ERROR
	ENDIF.
	PION			;ALLOW INTERRUPTS
	HRROI LP,[ASCIZ/.SSACC ok/]
	CALL TRACE
	MOVEI T1,S.STRT		;TEST IS
	STOR T1,STATE,(TST)	; STARTING
	RETSKP
	SUBTTL Get CI Configuration Data

;GET CI CONFIGURATION DATA
;ACCEPTS:	P1/ CONNECT ID
;		P2/ SBI
;RETURNS:	+1 FAILED
;		+2 SUCCESS

DORCD:	MOVEI T1,1+RCDBLK	;INIT
	HRLI T1,RCDBLK		; THE
	SETZM RCDBLK		; ARG
	BLT T1,.LBRCD-1+RCDBLK	; BLOCK
	MOVEI T1,.LBRCD		;GET ARG BLOCK LENGTH
	MOVEM T1,.SQLEN+RCDBLK	;SET IT
	MOVEM P2,.SQOSB+RCDBLK	;SET SBI
	MOVEM P1,.SQCID+RCDBLK	;SET IT
	MOVEI T1,.SSRCD		;GET FUNCTION CODE
	MOVEI T2,RCDBLK		;GET ARG BLOCK ADDR
	PIOFF			;NO INTERRUPTS
	SCS%			;RETURN CONFIGURATION DATA
	IFJER.
	  HRROI LP,[ASCIZ/.SSRCD failed/]
	  CALL TRACE
	  CALL SCSERR		;PROCESS SCS ERROR
	  JRST DORCD		;CONTINUE
	  RET			;FATAL ERROR
	ENDIF.
	PION			;ALLOW INTERRUPTS
	HRROI LP,[ASCIZ/.SSRCD ok/]
	CALL TRACE
	RETSKP
	SUBTTL Get Connection Status

;GET CONNECTION STATUS (SHORT FORM)
;RETURNS:	+1 FAILED
;		+2 SUCCESS

DOSTS:	MOVEI T1,1+STSBLK	;INIT
	HRLI T1,STSBLK		; THE
	SETZM STSBLK		; ARG
	BLT T1,.LBSTS-1+STSBLK	; BLOCK
	MOVEI T1,.LBSTS		;GET ARG BLOCK LENGTH
	MOVEM T1,.SQLEN+STSBLK	;SET IT
	MOVE T1,CONID(TST)	;GET CONNECT ID
	MOVEM T1,.SQCID+STSBLK	;SET IT
	MOVEI T1,.SSSTS		;GET FUNCTION CODE
	MOVEI T2,STSBLK		;GET ARG BLOCK ADDR
	PIOFF			;NO INTERRUPTS
	SCS%			;GET CONNECTION STATUS
	IFJER.
	  HRROI LP,[ASCIZ/.SSSTS failed/]
	  CALL TRACE
	  CALL SCSERR		;PROCESS SCS ERROR
	  JRST DOSTS		;CONTINUE
	  RET			;FATAL ERROR
	ENDIF.
	PION			;ALLOW INTERRUPTS
	HRROI LP,[ASCIZ/.SSSTS ok/]
	CALL TRACE
	RETSKP


;GET CONNECTION STATUS (LONG FORM)
;RETURNS:	+1 FAILED
;		+2 SUCCESS

DOCSP:	MOVEI T1,1+CSPBLK	;INIT
	HRLI T1,CSPBLK		; THE
	SETZM CSPBLK		; ARG
	BLT T1,.LBCSP-1+CSPBLK	; BLOCK
	MOVEI T1,.LBCSP		;GET ARG BLOCK LENGTH
	MOVEM T1,.SQLEN+CSPBLK	;SET IT
	MOVE T1,CONID(TST)	;GET CONNECT ID
	MOVEM T1,.SQCID+CSPBLK	;SET IT
	HRROI T1,SCSNAM		;GET BP TO DESTINATION PROCESS NAME
	MOVEM T1,.SQBDN+CSPBLK	;PUT IT IN
	MOVEI T1,.SSCSP		;GET FUNCTION CODE
	MOVEI T2,CSPBLK		;GET ARG BLOCK ADDR
	PIOFF			;NO INTERRUPTS
	SCS%			;GET CONNECTION STATUS
	IFJER.
	  HRROI LP,[ASCIZ/.SSCSP failed/]
	  CALL TRACE
	  CALL SCSERR		;PROCESS SCS ERROR
	  JRST DOCSP		;CONTINUE
	  RET			;FATAL ERROR
	ENDIF.
	PION			;ALLOW INTERRUPTS
	HRROI LP,[ASCIZ/.SSCSP ok/]
	CALL TRACE
	RETSKP
	SUBTTL Get CI Local Node Number

;GET CI LOCAL NODE NUMBER
;RETURNS:	+1 FAILED
;		+2 SUCCESS - NODE NUMBER IN T1

DOGLN:	MOVEI T1,1+GLNBLK	;INIT
	HRLI T1,GLNBLK		; THE
	SETZM GLNBLK		; ARG
	BLT T1,.LBGLN-1+GLNBLK	; BLOCK
	MOVEI T1,.LBGLN		;GET ARG BLOCK LENGTH
	MOVEM T1,.SQLEN+GLNBLK	;SET IT
	MOVEI T1,.SSGLN		;GET FUNCTION CODE
	MOVEI T2,GLNBLK		;GET ARG BLOCK ADDR
	PIOFF			;NO INTERRUPTS
	SCS%			;RETURN LOCAL NODE NUMBER
	IFJER.
	  HRROI LP,[ASCIZ/.SSGLN failed/]
	  CALL TRACE
	  CALL SCSERR		;PROCESS SCS ERROR
	  JRST DOGLN		;CONTINUE
	  RET			;FATAL ERROR
	ENDIF.
	PION			;ALLOW INTERRUPTS
	HRROI LP,[ASCIZ/.SSGLN ok/]
	CALL TRACE
	MOVE T1,.SQLNN+GLNBLK	;RETURN LOCAL NODE NUMBER
	RETSKP
	SUBTTL Queue a Receive Buffer

;QUEUE RECEIVE DATAGRAM BUFFERS
;ACCEPTS:	P1/ FUNCTION CODE
;		P2/ ADDRESS OF 1ST BUFFER
;RETURNS:	+1 FAILED
;		+2 SUCCESS

DOQRX:	MOVEI T1,1+QRXBLK	;INIT
	HRLI T1,QRXBLK		; THE
	SETZM QRXBLK		; ARG
	BLT T1,.LBQRD-1+QRXBLK	; BLOCK
	MOVEI T1,.LBQRD		;GET ARG BLOCK LENGTH
	MOVEM T1,.SQLEN+QRXBLK	;SET IT
	MOVE T1,CONID(TST)	;GET CONNECT ID
	MOVEM T1,.SQCID+QRXBLK	;SET IT
	MOVEM P2,.SQAFB+QRXBLK	;PUT IN BUFFER ADDRESS
	MOVE T1,P1		;GET FUNCTION CODE
	MOVEI T2,QRXBLK		;GET ARG BLOCK ADDR
	PIOFF			;NO INTERRUPTS
	SCS%			;GET CONNECTION STATUS
	IFJER.
	  HRROI LP,[ASCIZ/.SSQRX failed/]
	  CALL TRACE
	  CALL SCSERR		;PROCESS SCS ERROR
	  JRST DOQRX		;CONTINUE
	  RET			;FATAL ERROR
	ENDIF.
	PION			;ALLOW INTERRUPTS
	HRROI LP,[ASCIZ/.SSQRX ok/]
	CALL TRACE
	RETSKP
	SUBTTL Send/Receive a Buffer

;SEND A DATAGRAM OR MESSAGE
;ACCEPTS:	P1/ ADDRESS OF BUFFER
;		P2/ .SSSDG OR .SSSMG
;RETURNS:	+1 FAILED
;		+2 SUCCESS

DOSXG:	MOVEI T1,1+SXGBLK	;INIT
	HRLI T1,SXGBLK		; THE
	SETZM SXGBLK		; ARG
	BLT T1,.LBSDG-1+SXGBLK	; BLOCK
	MOVEI T1,.LBSDG		;GET ARG BLOCK LENGTH
	MOVEM T1,.SQLEN+SXGBLK	;SET IT
	MOVE T1,CONID(TST)	;GET CONNECT ID
	MOVEM T1,.SQCID+SXGBLK	;SET IT
	MOVEM P1,.SQAPT+SXGBLK	;PUT IN BUFFER ADDRESS
	MOVE T1,COUNT(TST)	;GET COUNT
	MOVEM T1,.SQLPT+SXGBLK	;PUT IN COUNT
	LOAD T1,TMODE,(TST)	;GET TRANSFER MODE
	SOS T1			;MAKE THE CONVERSION
	STOR T1,SC%MOD,.SQFLG+SXGBLK ;PUT IT IN
	MOVE T1,P2		;GET FUNCTION CODE
	MOVEI T2,SXGBLK		;GET ARG BLOCK ADDR
	PIOFF			;NO INTERRUPTS
	SCS%			;GET CONNECTION STATUS
	IFJER.
	  HRROI LP,[ASCIZ/.SSSXG failed/]
	  CALL TRACE
	  CALL SCSERR		;PROCESS SCS ERROR
	  JRST DOSXG		;TRY ONE MORE TIME
	  HRRZM T2,LSTERR(TST)  ;SAVE AS LAST ERROR OF TEST
	  RET			;BAD FAILURE
	ENDIF.
	PION			;ALLOW INTERRUPTS AGAIN
	HRROI LP,[ASCIZ/.SSSXG ok/]
	CALL TRACE
	RETSKP


;RECEIVE A DATAGRAM OR MESSAGE
;ACCEPTS:	P1/ FUNCTION CODE
;RETURNS:	+1 FAILED
;		+2 SUCCESS

DORXG:	HRRI T1,1+RXGBLK	;INIT
	HRLI T1,RXGBLK		; THE
	SETZM RXGBLK		; ARG
	BLT T1,.LBRDG-1+RXGBLK	; BLOCK
	MOVEI T1,.LBRDG		;GET LENGTH OF ARG BLOCK
	MOVEM T1,.SQLEN+RXGBLK	;PUT IT IN
	SETOM .SQCID+RXGBLK	;WANT NEXT BUFFER FOR THIS FORK
	MOVE T1,P1
	MOVEI T2,RXGBLK		;GET ARG BLOCK ADDR
	PIOFF			;NO INTERRUPTS
	SCS%
	IFJER.
	  HRROI LP,[ASCIZ/.SSRXG failed/]
	  CALL TRACE
	  CALL SCSERR		;PROCESS SCS ERROR
	  JRST DORXG		;CONTINUE
	  RET			;FATAL ERROR
	ENDIF.
	PION			;ALLOW INTERRUPTS
	HRROI LP,[ASCIZ/.SSRXG ok/]
	CALL TRACE
	RETSKP
	SUBTTL Map DMA Buffers and Store Names

;MAP DMA BUFFERS
;ACCEPTS:	T1/ FLAG VALUE INDICATING WHICH BUFFERS TO MAP
;		    MAP.OI = MAP BOTH OUTGOING AND INCOMING
;		    MAP.IN = MAP ONLY INCOMING
;
;RETURNS:	+1 FAILURE
;		+2 SUCCESS - BUFFER NAMES AND SEGMENT ADDRESSES STORED

DMAMAP:	STKVAR <BUFFLG,SEGBAS>
	MOVEM T1,BUFFLG		;SAVE BUFFER FLAG
	DO.			
	  MOVE P2,TST		;GET TEST #
	  SKIPE BUFFLG		;DOING INPUT BUFFERS?
	  IFSKP.		
	    IMULI P2,NDMAIN	;YES, FIND TABLE OFFSET
	    MOVE P1,P2		;PRESERVE OFFSET
	    MOVE P4,P2
	    ADDI P2,DMAINB	;GET INPUT BUFFER ADDR LIST
	    MOVE P3,P2		;PRESERVE OFFSET
	    MOVE P2,(P2)	;GET ADDR OF BUFFER'S FIRST SEGMENT
	    ADDI P1,DMAMIN	;GET BUFFER NAME LIST
	    IMULI P4,NDMASG	;CALCULATE OFFSET INTO
	    ADDI P4,DMAISG	; SEGMENT ADDRESS TABLE
	    MOVEM P4,SEGBAS	;REMEMBER BASE ADDRESS
	  ELSE.			
	    IMULI P2,NDMAOU	;NO, FIND TABLE OFFSET
	    MOVE P1,P2		;PRESERVE OFFSET
	    MOVE P4,P2
	    ADDI P2,DMAOUB	;GET INPUT BUFFER ADDR LIST
	    MOVE P3,P2		;PRESERVE OFFSET
	    MOVE P2,(P2)	;GET ADDR OF BUFFER'S FIRST SEGMENT
	    ADDI P1,DMAMOU	;GET BUFFER NAME LIST
	    IMULI P4,NDMASG	;CALCULATE OFFSET INTO
	    ADDI P4,DMAOSG	; SEGMENT ADDRESS TABLE
	    MOVEM P4,SEGBAS	;REMEMBER BASE ADDRESS
	  ENDIF.		
	  MOVN Q2,BUFNUM(TST)	;AOBJN WORD TO DO ALL BUFFERS
	  HRLZS Q2		
	  DO.			
	    MOVE P4,SEGBAS	;GET SEGMENT ADDRESS TABLE BASE
	    HRRZ T1,Q2		;GET NUMBER OF BUFFERS DONE
	    IMULI T1,NDMASG	;CALCULATE OFFSET
	    ADD P4,T1		; INTO SEGMENT TABLE
	    MOVEI T1,1+MAPBLK	;INIT
	    HRLI T1,MAPBLK	; THE
	    SETZM MAPBLK	; ARG
	    BLT T1,MAPLEN-1+MAPBLK; BLOCK
	    MOVE T1,SEGNUM(TST)	;CALCULATE 
	    IMULI T1,2		; TRUE ARG
	    ADDI T1,.SQBNA+1	; BLOCK LENGTH
	    MOVEM T1,MAPBLK	;PUT IT IN
 	    LOAD T1,TMODE,(TST)	;GET TRANSFER MODE
 	    CAIN T1,M.HIGH	;IS IT HIGH DENSITY?
	    IFSKP.
	      MOVEI T1,SQ%DIC	;NO, USE INDUSTRY COMPATABLE VALUE
	    ELSE.
 	      MOVEI T1,SQ%DHD	;YES, STORE CORRECT VALUE
	    ENDIF.
 	    STOR T1,SQ%DMD,.SQXFL+MAPBLK  ;PLACE IN ARG BLOCK
	    MOVEI T1,MAPBLK	;GET ARG BLOCK ADDR
	    ADDI T1,.SQBNA+1	;SKIP ARG BLOCK LOC WHERE NAME WILL BE RETURNED
	    MOVN Q1,SEGNUM(TST)	;AOBJN WORD TO DO ALL SEGMENTS PER BUFFER
	    HRLZS Q1		
	    MOVEI T2,MXDMAW	;GET MAX SEGMENT SIZE
	    MOVE T3,SEGSIZ(TST)	;GET SEGMENT SIZE FOR TEST
	    DO.			
	      MOVEM T3,(T1)	;PUT IN SEGMENT LENGTH
	      AOS T1		;MOVE TO NEXT SLOT IN ARG BLOCK
	      MOVEM P2,(T1)	;PUT SEGMENT ADDR IN ARG BLOCK
	      MOVEM P2,(P4)	; AND IN SEGMENT ADDRESS TABLE
	      AOS T1		;MOVE TO NEXT SLOT IN ARG BLOCK
	      ADD P2,T2		;GET ADDR OF BUFFER'S NEXT SEGMENT
	      AOS P4		;NEXT SEGMENT TABLE ENTRY
	      AOBJN Q1,TOP.	;DO ALL SEGMENTS FOR THIS BUFFER
	    ENDDO.		
DMAMA1:	    MOVEI T1,.SSMAP	;GET FUNCTION CODE
	    MOVEI T2,MAPBLK	;GET ARG BLOCK ADDR
	    PIOFF		;NO INTERRUPTS
	    SCS%		;MAP THE BUFFER
	    IFJER.		
	      HRROI LP,[ASCIZ/.SSMAP failed/]
	      CALL TRACE	
	      CALL SCSERR	;PROCESS SCS ERROR
	      JRST DMAMA1	;CONTINUE
	      RET		;FAILED
	    ENDIF.		
	    PION		;ALLOW INTERRUPTS
	    HRROI LP,[ASCIZ/.SSMAP ok/]  
	    CALL TRACE		;MAPPING SUCCEEDED
	    MOVE T1,.SQBNA+MAPBLK  ;GET THE BUFFER NAME
	    MOVEM T1,(P1)	;SAVE IT
	    AOS P3		;NEXT BUFFER ADDRESS
	    MOVE P2,(P3)	;FIRST SEGMENT ADDRESS FOR BUFFER
	    AOS P1		;MOVE TO NEXT BUFFER NAME SLOT
	    AOBJN Q2,TOP.	;DO ALL BUFFERS FOR THIS TEST
	  ENDDO.		
	  AOSG BUFFLG		;ONE SET OF BUFFERS DONE
	  JRST TOP.		;DO INCOMING BUFFERS IF NEEDED
	ENDDO.			
	RETSKP			;MAPPING SUCCEEDED
	SUBTTL Unmap DMA Buffers and Remove Names

;UNMAP DMA BUFFERS
;ACCEPTS:	T1/ FLAG VALUE INDICATING WHICH BUFFERS TO MAP
;		    UMP.OI = UNMAP BOTH OUTGOING AND INCOMING
;		    UMP.IN = UNMAP ONLY INCOMING
;
;RETURNS:	+1 FAILURE
;		+2 SUCCESS - BUFFER NAMES CLEARED

DMAUMP:	MOVE P4,T1		;GET BUFFER FLAG
	DO.			
	  MOVE P1,TST		;GET TEST #
	  SKIPE P4		;DOING INPUT BUFFERS?
	  IFSKP.		
	    IMULI P1,NDMAIN	;YES, FIND TABLE OFFSET
	    ADDI P1,DMAMIN	;GET BUFFER NAME LIST
	  ELSE.			
	    IMULI P1,NDMAOU	;NO, FIND TABLE OFFSET
	    ADDI P1,DMAMOU	;GET BUFFER NAME LIST
	  ENDIF.		
	  MOVE Q1,BUFNUM(TST)	;GET NUMBER OF BUFFER TO UNMAP
	  DO.			
	    MOVEI T1,.LBUMP	;GET ARG BLOCK LENGTH
	    MOVEM T1,.SQLEN+UMPBLK  ;PLACE IN ARG BLOCK
	    MOVE T1,(P1)	;GET BUFFER NAME
	    MOVEM T1,.SQNAM+UMPBLK  ;PLACE IN ARG BLOCK
DMAUM1:	    MOVEI T1,.SSUMP	;FUNCTION CODE
	    MOVEI T2,UMPBLK	;ADDRESS OF ARG BLOCK
	    PIOFF		;NO INTERRUPTS
	    SCS%		;UNMAP BUFFER
	    IFJER.		
	      HRROI LP,[ASCIZ/.SSUMP failed/]
	      CALL TRACE	;REPORT FAILURE
	      CALL SCSERR	;PROCESS SCS ERROR
	      JRST DMAUM1	;TRY AGAIN
	      RET		;FAILED
	    ENDIF.		
	    PION		;ALLOW INTERRUPTS
	    HRROI LP,[ASCIZ/.SSUMP ok/]  
	    CALL TRACE		;UNMAP SUCCEEDED
	    SETZM (P1)		;CLEAR BUFFER NAME
	    AOS P1		;NEXT BUFFER NAME
	    SOJN Q1,TOP.	;CONTINUE IF NEEDED
	  ENDDO.		
	  AOJE P4,TOP.		;DO INCOMING BUFFERS IF REQUIRED
	ENDDO.			
	RETSKP			;UNMAPPING SUCCEEDED

	END 3,,EVEC		;ENTRY VECTOR