mirror of
https://github.com/PDP-10/stacken.git
synced 2026-03-01 09:21:15 +00:00
885 lines
26 KiB
Plaintext
885 lines
26 KiB
Plaintext
TITLE DTR - DECnet Test Receiver
|
||
SUBTTL W. Nichols May, 1981
|
||
|
||
SEARCH DTSPRM,JOBDAT,MACTEN,UUOSYM,SWIL
|
||
|
||
IFN FTUSRMOD,< SEARCH D36PAR
|
||
D36SYM
|
||
>
|
||
SALL
|
||
.DIRECTIVE FLBLST ;DON'T GIVE ME CODE FOR ASCIZ
|
||
$RELOC
|
||
|
||
|
||
COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1984,1986. ALL RIGHTS RESERVED.\
|
||
|
||
; This program conforms to the DTR specification version 1.1
|
||
; published on 22 April 1981.
|
||
|
||
PRGID=:'DTR ' ;NAME OF THIS PROGRAM
|
||
PRGABR=:'DTR' ;3 CHR ABBREVIATION USED FOR PROG.
|
||
|
||
DTRWHO==0
|
||
DTRVER==1 ;MAJOR VERSION
|
||
DTRMIN==0 ;MINOR VERSION
|
||
DTREDT==10 ;EDIT NUMBER
|
||
|
||
DEFINE VRSN. (PROG),<
|
||
BYTE (3) PROG'WHO (9) PROG'VER (6) PROG'MIN (18) PROG'EDT
|
||
>
|
||
LOC .JBVER
|
||
VRSN. DTR
|
||
RELOC
|
||
LOC .JBREN
|
||
EXP REENTER
|
||
RELOC
|
||
|
||
|
||
;Expand the INTERNAL/EXTERNAL macro from DTSPRM
|
||
|
||
GLOBAL EXTERNAL,INTERNAL
|
||
|
||
|
||
SUBTTL Revision History
|
||
|
||
|
||
COMMENT &
|
||
|
||
Edit Description
|
||
|
||
4 17-Jan-84 by Bill Davenport.
|
||
|
||
Fix the INTERRUPT SEQUENCE test to correctly check the
|
||
expected sequence number.
|
||
|
||
5 18-Jan-84 by Bill Davenport.
|
||
|
||
Fix the interrupt test to store the interrupt message size
|
||
from the received interrupt messages. This fixes the report-
|
||
ing of bogus interrupt message sizes.
|
||
|
||
6 19-Jan-84 by Tarl Neustaedter.
|
||
|
||
Sleep for a second on a disconnect test, so that we don't do a .NSFDS
|
||
before the ack for the CC arrives. Crock, but who'll notice?
|
||
|
||
7 25-Jan-84 by Bill Davenport.
|
||
|
||
Zero count of receive and send errors at start of interrupt tests.
|
||
Ignore "Abort by Object" returns during DATA and INTERRUPT tests
|
||
as this seems the normal thing that VAXen do.
|
||
|
||
10 26-Jan-84 by Bill Davenport.
|
||
|
||
More of edit 7.
|
||
|
||
&; End Revision History
|
||
SUBTTL Standard Test Strings
|
||
|
||
;The "standard" user data string
|
||
|
||
STDUSR: XWD ^D16,<^D16/4>+1 ;USER DATA IS MAX 16 BYTES
|
||
BYTE8 ABCDEFGHIJKLMNOP ;STRING OF 8-BIT BYTES
|
||
$HIGH
|
||
|
||
;The Enter Passive Connect Block
|
||
|
||
EPCONB: EXP EPCONL ;LENGTH OF BLK IN WORDS
|
||
EXP 0 ;STRING PTR TO NODE NAME (.NSCND)
|
||
EXP EPSPRC ;PTR TO SOURCE PRC BLK (.NSCSD)
|
||
EXP EPDPRC ;PTR TO DEST PRC BLK (.NSCDD)
|
||
EXP 0 ;PTR TO UID STRING BLK (.NSCUS)
|
||
EXP 0 ;PTR TO PASSWORD STR BLK (.NSCPW)
|
||
EXP 0 ;PTR TO ACCOUNT STR BLK (.NSCAC)
|
||
EXP 0 ;PTR TO USER DATA STR BLK (.NSCUD)
|
||
EPCONL==.-EPCONB
|
||
|
||
|
||
;The Source Process Descriptor
|
||
|
||
EPSPRC: EXP 5 ;LENGTH OF BLK IN WORDS
|
||
EXP 0 ;FORMAT ZERO
|
||
EXP OBJDTR ;THE OBJECT TYPE OF A DTR
|
||
EXP 0 ;PPN MUST BE ZERO FOR FORMAT ZERO
|
||
EXP 0 ;DITTO PROCESS NAME STRING PTR
|
||
|
||
;The Destination Process Descriptor
|
||
|
||
EPDPRC: EXP 5 ;LENGTH OF BLK IN WORDS
|
||
EXP 0 ;FORMAT ZERO
|
||
EXP OBJDTR ;THE OBJECT TYPE OF A DTR
|
||
EXP 0 ;PPN MUST BE ZERO FOR FORMAT ZERO
|
||
EXP 0 ;DITTO PROCESS NAME STRING PTR
|
||
$LOW
|
||
|
||
;The Enter Active Connect Block
|
||
|
||
RICONB: EXP RICONL ;LENGTH OF BLOCK IN WORDS
|
||
EXP NODNAM ;STRING PTR TO NODE NAME (.NSCND)
|
||
EXP RISPRC ;PTR TO SOURCE PRC BLK (.NSCSD)
|
||
EXP RIDPRC ;PTR TO DEST PRC BLK (.NSCDD)
|
||
EXP UID ;PTR TO UID STRING BLK (.NSCUS)
|
||
EXP PASSWORD ;PTR TO PASSWORD STR BLK (.NSCPW)
|
||
EXP ACCOUNT ;PTR TO ACCOUNT STR BLK (.NSCAC)
|
||
EXP CNTUSR ;PTR TO USER DATA STR BLK (.NSCUD)
|
||
RICONL==.-RICONB
|
||
|
||
NODNAM: STRBLK STRLNW ;NODE NAME
|
||
UID: STRBLK STRLNW ;UID STRING BLK
|
||
PASSWORD:STRBLK STRLNW ;PASSWORD STR BLK
|
||
ACCOUNT:STRBLK STRLNW ;ACCOUNT STR BLK
|
||
|
||
;The Source Process Descriptor
|
||
|
||
RISPRC: EXP 5 ;LENGHT OF BLK
|
||
EXP 0 ;FORMAT ZERO
|
||
EXP 0 ;THE OBJECT TYPE OF A DTR
|
||
EXP 0 ;PPN MUST BE ZERO FOR FORMAT ZERO
|
||
EXP 0 ;DITTO PROCESS NAME STRING PTR
|
||
|
||
;The Destination Process Descriptor
|
||
|
||
RIDPRC: EXP 5 ;LENGTH OF BLK IN WORDS
|
||
EXP 0 ;FORMAT ZERO
|
||
EXP 0 ;THE OBJECT TYPE OF A DTR
|
||
EXP 0 ;PPN MUST BE ZERO FOR FORMAT ZERO
|
||
EXP 0 ;DITTO PROCESS NAME STRING PTR
|
||
|
||
$HIGH
|
||
SUBTTL General Impure Storage
|
||
|
||
$LOW
|
||
|
||
PRINT:: BLOCK 1 ;HOLDS THE PRINT FLAG (ALL,NONE,ERROR)
|
||
LOGFLG::BLOCK 1 ;NON-ZERO IF WE'RE LOGGING
|
||
|
||
TYPE: BLOCK 1 ;TEST TYPE
|
||
RFLTYP: BLOCK 1 ;RECEIVE (FROM DTS VIEW) FLOW CONTROL
|
||
RQUEUE: BLOCK 1 ;RECEIVE (FROM DTS VIEW) QUEUE GOAL
|
||
MSGSIZ: BLOCK 1 ;MESSAGE SIZE (FOR EITHER DATA OR INT)
|
||
SNDCNT: BLOCK 1 ;NUMBER OF MESSAGES SENT TO DTR
|
||
BAUD: BLOCK 1
|
||
ELPTIM: BLOCK 1 ;ELAPSED TIME FOR STATS
|
||
STRTIM: BLOCK 1 ;STARTING TIME
|
||
RCVCNT: BLOCK 1
|
||
RERRCNT:BLOCK 1
|
||
SERRCNT:BLOCK 1
|
||
|
||
$HIGH
|
||
SUBTTL Start the Program Here
|
||
|
||
REENTER:EXIT ;WAIT FOR RESET TO WORK PROPERLY
|
||
|
||
DTR:: TDZA T1,T1 ;NON-CCL ENTRY
|
||
MOVEI T1,1 ;CCL ENTRY
|
||
MOVEM T1,CCLF1 ;STORE FOR LATER
|
||
MOVE P,PDLIOW ;SET UP STACK
|
||
DTRRES::RESET ;LABEL IS FOR DDT PATCHING
|
||
HRRZ T1,.JBREL ;GET FIRST-TIME CORE SIZE
|
||
MOVEM T1,INICOR
|
||
HRRZ T1,.JBFF ;GET INITIAL .JBFF
|
||
MOVEM T1,INIFF ;SAVE FOR LATER
|
||
|
||
MOVX T1,PRI.AL ;START OUT WITH /PRINT:ALL
|
||
MOVEM T1,PRINT ;DTS WILL CHANGE THIS WITH TESTTYPE
|
||
|
||
;Fall through to next page for .ISCAN
|
||
SUBTTL Call .ISCAN
|
||
|
||
;From previous page
|
||
|
||
;.ISCAN--SUBROUTINE TO INITIALIZE COMMAND SCANNER
|
||
;CALL AC1=XWD LENGTH,BLOCK
|
||
;
|
||
; BLOCK+0=PROTOCOL VERSION WORD: <MAJOR>,,<MINOR>
|
||
; BLOCK+1=0 OR IOWD PTR TO A LIST OF LEGAL MONITOR COMMANDS
|
||
; IF 0, NO RESCAN IS DONE
|
||
; BLOCK+2=RH 0 OR SIXBIT CCL NAME
|
||
; IF 0, NO CCL MODE
|
||
; LH 0 OR ADDRESS OF STARTING OFFSET
|
||
; BLOCK+3=RH 0 OR ADDRESS OF CHARACTER TYPEOUT ROUTINE
|
||
; IF 0, OUTCHR WILL BE DONE FROM T1
|
||
; LH 0 OR ADDRESS OF CHARACTER INPUT ROUTINE
|
||
; MUST SAVE ALL ACS, CHAR IN P4
|
||
; BLOCK+4=0 OR POINTER (XWD LEN,BLOCK) TO INDIRECT FILE BLOCK
|
||
; .FXDEV NE 0 TO USE BLOCK
|
||
; BLOCK+5=RH 0 OR ADDRESS OF MONRET ROUTINE
|
||
; LH 0 OR ADDRESS OF PROMPT ROUTINE
|
||
; CALLED WITH CHAR IN RH(T1), LH(T1) HAS
|
||
; 0 FOR FIRST LINE, -1 FOR CONTINUATION LINES
|
||
; BLOCK+6=LH FLAGS
|
||
; RH (FUTURE)
|
||
;VALUE AC1=INDEX IN TABLE OF COMMANDS IF FOUND(0,1,...), ELSE -1
|
||
|
||
|
||
MOVE T1,[6,,[12,,%%FXVE ;MAJOR,,MINOR SCAN VERSION
|
||
IOWD 1,[PRGID] ;CCL ENTRY NAME
|
||
CCLF1,,PRGABR ;CCL FLAG,,PROGRAM NAME ABBREVIATION
|
||
0,,STYPOU ;NO SPECIAL TYPEIN,,TYPEOUT ROUTINE
|
||
0,,0 ;NO USER INDIRECT
|
||
0,,.EXIT]] ;MONRET ROUTINE
|
||
CALLSCAN .ISCAN## ;INITIALIZE SCAN
|
||
|
||
;Fall through to Main Loop
|
||
;Fall through from previous page at startup
|
||
|
||
|
||
;Main Loop
|
||
|
||
DTRPAS: INFO <Waiting for a connect from DTS>,CRLF
|
||
CALL ENTPAS ;ENTER PASSIVE
|
||
EXIT ;ERROR, DECNET PROBABLY NOT LOADED
|
||
|
||
INFO <Connect from DTS on node >
|
||
|
||
PUSH P,P1
|
||
PUSH P,P2
|
||
HLRZ P1,NODNAM ;GET LENGTH OF NAME IN BYTES
|
||
JUMPE P1,DTRPS2 ;SHOULD NOT JUMP
|
||
MOVE P2,[POINT 8,NODNAM+1]
|
||
DTRPS1: ILDB T1,P2 ;GET NEXT BYTE OF NODE'S NAME
|
||
CALLSCAN .TCHAR## ;TYPE IT OUT
|
||
SOJG P1,DTRPS1 ;LOOP UNTIL ALL OUT
|
||
DTRPS2:
|
||
CALLSCAN .TRBRK## ;A RIGHT SQUARE BRACKET FOR INFO
|
||
CALLSCAN .TCRLF##
|
||
POP P,P2
|
||
POP P,P1
|
||
|
||
CALL DO.TEST ;WE HAVE A COMMAND, GO DO THE TEST
|
||
JRST DTRPAS
|
||
|
||
DTRNSE: ERROR <Error trying to Reject a Connect:>,CRLF
|
||
CALL NSPERR
|
||
JRST DTRPAS
|
||
SUBTTL DO.TEST - We have a command from DTS, do it
|
||
|
||
;Called only from the main loop
|
||
|
||
DO.TEST:SAVEAC P1
|
||
MOVEI T1,0 ;GET THE FIRST (TESTTYPE) FIELD
|
||
MOVEI T2,CNTUSR ; FROM CNTUSR (CONNECT USER DATA)
|
||
CALL GET1BY ;GET 1 BYTE INTO T1
|
||
PJRST UNSUP0 ;FIELD ZERO UNSUPPORTED
|
||
MOVE P1,T1 ;SAVE THE TESTTYPE CODE
|
||
|
||
;Get the PRINT:xxx option from the high-order bits of TESTTYPE
|
||
|
||
MOVX T2,PRI.NO ;ASSUME PRINT:NONE
|
||
TXNE P1,.TCERR ;WANT ERROR PRINTING?
|
||
MOVX T2,PRI.ER ;YES, LOAD UP PRINT:ERROR
|
||
TXNE P1,.TCPRI ;WANT ALL PRINTING?
|
||
MOVX T2,PRI.AL ;YES, LOAD UP PRINT:ALL
|
||
MOVEM T2,PRINT ;STORE FOR STYPOUT ROUTINES
|
||
|
||
;Now that we know how to print, offer some user info
|
||
|
||
TRACE <Got a Connect>,CRLF
|
||
; CALL TYPSTA ;TELL USER ABOUT THE LINK STATUS
|
||
|
||
;Now go off to the requested test
|
||
|
||
ANDI P1,77 ;ONLY THE TEST TYPE LEFT
|
||
CAILE P1,.TCMAX ;SUPPORTED TEST?
|
||
PJRST UNSUP0 ;NO, SEND BACK AN ERROR FOR FIELD 0
|
||
|
||
;Note that we have not yet accepted the connection. This is so we
|
||
;can reject it if we find any unsupported tests being requested.
|
||
;It is the responsibility of each test to accept the connect when
|
||
;it has checked the entire request.
|
||
|
||
CALL @[EXP DO.CONNECT
|
||
EXP DO.DATA
|
||
EXP DO.DISCONNECT
|
||
EXP DO.INTERRUPT](P1)
|
||
|
||
SKIPGE CHANEL ;CHANNEL NUMBER
|
||
RET ;-1 MEANS THAT THE CHANNEL IS CLOSED
|
||
CALNSP .NSFRS ;READ STATUS TO SEE IF CHN STILL OPEN
|
||
RET ;NOPE, ALL IS DONE
|
||
PJRST NSPREL ;YES, TEST MUST HAVE LEFT IT OPEN
|
||
;ABORT OR RELEASE IT.
|
||
|
||
;Now we return to main loop for another test
|
||
SUBTTL The CONNECT Test
|
||
|
||
;Call: CALL DO.CONNECT
|
||
; Normal Return
|
||
|
||
DO.CONNECT:
|
||
|
||
;Here we check the entire request string first, then see if
|
||
;we should accept or reject the connect according to the test option.
|
||
|
||
MOVEI T1,1 ;GET THE SECOND FIELD
|
||
MOVEI T2,CNTUSR ;FROM CONNECT USER DATA
|
||
CALL GET1BY ;GET 1 BYTE INTO T1
|
||
PJRST UNSUP1 ;UNSUPPORTED IF NON-EXISTENT
|
||
CAILE T1,5 ;MAX OFFSET THIS CODE KNOWS ABOUT
|
||
PJRST UNSUP1 ;OOPS, UNSUPPORTED CMD IN FIELD 1
|
||
|
||
PJRST @[EXP DOCO.0 ;(0) REJECT, NO DATA
|
||
EXP DOCO.1 ;(1) ACCEPT, NO DATA
|
||
EXP DOCO.2 ;(2) REJECT, STANDARD DATA
|
||
EXP DOCO.3 ;(3) ACCEPT, STANDARD DATA
|
||
EXP DOCO.4 ;(4) REJECT, RETURN DATA
|
||
EXP DOCO.5](T1) ;(5) ACCEPT, RETURN DATA
|
||
|
||
DOCO.0: MOVEI NSAA1,0 ;(0) REJECT, NO DATA
|
||
PJRST DOCO.R ;GO TO COMMON EXIT
|
||
|
||
DOCO.1: MOVEI NSAA1,0 ;(1) ACCEPT, NO DATA
|
||
PJRST DOCO.A ;GO TO COMMON EXIT
|
||
|
||
DOCO.2: MOVEI NSAA1,STDUSR ;(2) REJECT, STANDARD DATA
|
||
PJRST DOCO.R ;GO TO COMMON EXIT
|
||
|
||
DOCO.3: MOVEI NSAA1,STDUSR ;(3) ACCEPT, STANDARD DATA
|
||
PJRST DOCO.A ;GO TO COMMON EXIT
|
||
|
||
DOCO.4: MOVEI NSAA1,CNTUSR ;(4) REJECT, RETURN DATA
|
||
PJRST DOCO.R ;GO TO COMMON EXIT
|
||
|
||
DOCO.5: MOVEI NSAA1,CNTUSR ;(5) ACCEPT, RETURN DATA
|
||
PJRST DOCO.A ;GO TO COMMON EXIT
|
||
;Here to Reject the connect for the CONNECT test
|
||
|
||
DOCO.R: INFO <Connect Reject Test>,CRLF
|
||
;NSAA1 FILLED IN BY CALLER
|
||
CALNSP .NSFRJ,NSAA1,NS.WAI ;REJECT FUNCTION
|
||
PJRST NSPERR
|
||
RET
|
||
|
||
|
||
;Here to Accept the connect for the CONNECT test
|
||
|
||
DOCO.A: INFO <Connect Accept Test>,CRLF
|
||
;NSAA1 FILLED IN BY CALLER
|
||
CALNSP .NSFAC,NSAA1 ;ACCEPT FUNCTION
|
||
PJRST NSPERR
|
||
|
||
DOCA.1: MOVEI NSAA1,0 ;WE'RE NOT EXPECTING ANY DATA
|
||
MOVE NSAA2,PRCVMSG ;POINTER TO LEGAL BUFFER
|
||
CALNSP .NSFDR,NSAA2,NS.WAIT ;WAIT FOR ABORT FROM DTS
|
||
PJRST NSPREL ;ERROR, HOPE IT IS THE ABORT
|
||
JRST DOCA.1 ;IGNORE ANY DATA RECEIVED
|
||
SUBTTL The DISCONNECT Test
|
||
|
||
;Call: CALL DO.DISCONNECT
|
||
; Normal Return
|
||
|
||
DO.DISCONNECT:
|
||
SAVEAC P1
|
||
MOVEI T1,1 ;GET THE SECOND FIELD
|
||
MOVEI T2,CNTUSR ;FROM CONNECT USER DATA
|
||
CALL GET1BY ;GET 1 BYTE INTO T1
|
||
PJRST UNSUP1 ;UNSUPPORTED IF NON-EXISTENT
|
||
CAILE T1,5 ;MAX OFFSET THIS CODE KNOWS ABOUT
|
||
PJRST UNSUP1 ;OOPS, UNSUPPORTED CMD IN FIELD 1
|
||
MOVE P1,T1 ;SAVE FOR PJRST BELOW
|
||
CALNSP .NSFAC ;WE'RE HAPPY, ACCEPT THE CONNECT
|
||
PJRST NSPERR
|
||
MOVEI T1,1 ;ONE SECOND
|
||
SLEEP T1, ;WAIT FOR US TO GET OUT OF CC STATE
|
||
PJRST @[EXP DODI.0 ;(0) SYNCHRONOUS, NO DATA
|
||
EXP DODI.1 ;(1) ABORT, NO DATA
|
||
EXP DODI.2 ;(2) SYNCHRONOUS, STANDARD DATA
|
||
EXP DODI.3 ;(3) ABORT, STANDARD DATA
|
||
EXP DODI.4 ;(4) SYNCHRONOUS, RETURN DATA
|
||
EXP DODI.5](P1) ;(5) ABORT, RETURN DATA
|
||
|
||
DODI.0: ;(0) SYNCHRONOUS, NO DATA
|
||
MOVEI NSAA1,0 ;NO USER DATA
|
||
PJRST DODI.S ;GO TO COMMON EXIT
|
||
|
||
DODI.1: ;(1) ABORT, NO DATA
|
||
MOVEI NSAA1,0 ;NO USER DATA
|
||
PJRST DODI.A ;GO TO COMMON EXIT
|
||
|
||
DODI.2: ;(2) SYNCHRONOUS, STANDARD DATA
|
||
MOVEI NSAA1,STDUSR ;STANDARD USER DATA
|
||
PJRST DODI.S ;GO TO COMMON EXIT
|
||
|
||
DODI.3: ;(3) ABORT, STANDARD DATA
|
||
MOVEI NSAA1,STDUSR ;STANDARD USER DATA
|
||
PJRST DODI.A ;GO TO COMMON EXIT
|
||
|
||
DODI.4: ;(4) SYNCHRONOUS, RETURN DATA
|
||
MOVEI NSAA1,CNTUSR ;RECEIVED USER DATA
|
||
PJRST DODI.S ;GO TO COMMON EXIT
|
||
|
||
DODI.5: ;(5) ABORT, RETURN DATA
|
||
MOVEI NSAA1,CNTUSR ;RECEIVED USER DATA
|
||
PJRST DODI.A ;GO TO COMMON EXIT
|
||
;The common exit for DO.DISCONNECT
|
||
|
||
DODI.S: INFO <Synchronous Disconnect Test>,CRLF
|
||
CALNSP .NSFSD,NSAA1,NS.WAI ;SYNCH DISCONNECT
|
||
PJRST NSPERR
|
||
JRST DODI.X
|
||
|
||
DODI.A: INFO <Abort Disconnect Test>,CRLF
|
||
CALNSP .NSFAB,NSAA1,NS.WAI ;ABORT AND RELEASE
|
||
PJRST NSPERR
|
||
|
||
DODI.X:
|
||
|
||
;If this is a synchronous disconnect, lets wait for the confirm
|
||
;before we release the channel: that's playing the game right.
|
||
|
||
CAXE NSAFN,.NSFSD ;IS THIS IS A SYNCH DISCONNECT?
|
||
RET ;NO, ITS ABORT-AND-RELEASE
|
||
|
||
DODX.1: MOVEI NSAA1,0 ;WE'RE NOT EXPECTING ANY DATA
|
||
MOVE NSAA2,[POINT 8,T2] ;DUMMY BYTE POINTER
|
||
CALNSP .NSFDR,NSAA2,NS.WAIT ;WAIT FOR DISCON CONFIRM
|
||
TRNA ;ERROR, LET'S HOPE ITS THE DC
|
||
JRST DODX.1 ;IGNORE ANY READS RECEIVED
|
||
CALL NSPREL ;RELEASE THE CHANNEL
|
||
RET
|
||
SUBTTL The DATA Test
|
||
|
||
;Call: CALL DO.DATA
|
||
; Normal Return
|
||
|
||
DO.DATA:
|
||
MOVEI T2,CNTUSR ;THIS IS KEPT THROUGH CALLS TO GETxBY
|
||
|
||
MOVEI T1,1 ;FIELD NUMBER 1 NEXT
|
||
CALL GET1BY ;READ DATTYPE FIELD
|
||
PJRST UNSUP1 ;IF ERROR, UNSUPPORTED TEST IN FIELD 1
|
||
CAILE T1,.DCMAX ;SUPPORTED VALUE?
|
||
PJRST UNSUP1 ;NO, COMPLAIN
|
||
MOVEM T1,TYPE ;PUT THE DATA TEST'S /TYPE: VALUE
|
||
|
||
MOVEI T1,2 ;FIELD NUMBER 2 NEXT
|
||
CALL GET1BY ;READ RFLOW FIELD
|
||
PJRST UNSUP2 ;IF ERROR, UNSUPPORTED TEST IN FIELD 2
|
||
CAILE T1,.FCMAX ;SUPPORTED VALUE?
|
||
PJRST UNSUP2 ;NO, COMPLAIN
|
||
MOVEM T1,RFLTYP ;PUT /RFLOW VALUE
|
||
|
||
MOVEI T1,3 ;FIELD NUMBER 3 NEXT
|
||
CALL GET1BY ;READ /RQUEUE FIELD
|
||
PJRST UNSUP3 ;IF ERROR, UNSUPPORTED TEST IN FIELD 3
|
||
MOVEM T1,RQUEUE ;PUT /RQUEUE FIELD
|
||
|
||
MOVEI T1,4 ;FIELD NUMBER 4 NEXT
|
||
CALL GET2BY ;NOW A 2-BYTE RESERVED FIELD
|
||
PJRST UNSUP4 ;IF ERROR, UNSUPPORTED TEST IN FIELD 4
|
||
|
||
MOVEI T1,6 ;FIELD NUMBER 5 NEXT
|
||
CALL GET2BY ;READ THE MSGLEN FIELD
|
||
PJRST UNSUP5 ;IF ERROR, UNSUPPORTED TEST IN FIELD 5
|
||
CAXLE T1,MAXMSG ;SUPPORTED MESSAGE SIZE?
|
||
PJRST UNSUP5 ;IF ERROR, UNSUPPORTED TEST IN FIELD 5
|
||
MOVEM T1,MSGSIZ ;PUT THE /MSGSIZ VALUE
|
||
|
||
;Finished reading the Connect message,
|
||
;fall through to next page to accept the connect
|
||
;From Previous Page
|
||
|
||
DEFINE DTYPMC(text),<
|
||
[INFO <text Test>,CRLF
|
||
RET]
|
||
>
|
||
|
||
MOVE T1,TYPE ;GET TYPE CODE FOR DATA TEST
|
||
CALL @[DTYPMC Data Sink
|
||
DTYPMC Data Sequence
|
||
DTYPMC Data Pattern
|
||
DTYPMC Data Echo](T1)
|
||
|
||
SETZB NSAA1,NSAA2 ;NO USER DATA OR SEGSIZE OFFERED
|
||
MOVE NSAA3,RFLTYP ;GET FLOW CONTROL MODE TO USE
|
||
CALNSP .NSFAC,NSAA3 ;WE'RE HAPPY, ACCEPT THE CONNECT
|
||
PJRST NSPERR
|
||
|
||
CALNSP .NSFRS,NSAA2 ;READ STATUS TO GET SEGMENT SIZE USED
|
||
RET ;NOPE, ALL IS DONE
|
||
INFO <Seg: >
|
||
MOVE T1,NSAA1 ;GET SEGSIZE FROM READ STATUS
|
||
CALLSCAN .TDECW##
|
||
MOVEI T1,[ASCIZ /, Msg: /]
|
||
CALLSCAN .TSTRG##
|
||
MOVE T1,MSGSIZ ;GET MESSAGE SIZE FROM PROTOCOL HEADER
|
||
CALLSCAN .TDECW##
|
||
MOVEI T1,[ASCIZ /, RQUEUE: /]
|
||
CALLSCAN .TSTRG##
|
||
MOVE T1,RQUEUE ;GET BUFFERING DTR IS TO USE
|
||
CALLSCAN .TDECW##
|
||
MOVEI T1,[ASCIZ /, RFLOW: /] ;DTR'S FLOW CONTROL ELECTION
|
||
CALLSCAN .TSTRG##
|
||
HRRZ T1,NSAA2 ;LOCAL FLOW CONTROL IN RH
|
||
CALL TYPFLO
|
||
MOVEI T1,[ASCIZ /, SFLOW: /] ;DTS'S FLOW CONTROL ELECTION
|
||
CALLSCAN .TSTRG##
|
||
HLRZ T1,NSAA2 ;REMOTE FLOW CONTROL IN LH
|
||
CALL TYPFLO
|
||
MOVEI T1,[ASCIZ /]/]
|
||
CALLSCAN .TSTRG##
|
||
CALLSCAN .TCRLF##
|
||
|
||
;Set the link quota from the RQUEUE value received in the
|
||
;Connect Initiate message
|
||
|
||
MOVE T1,RQUEUE ;SET TO VALUE USER WANTED
|
||
CALL SETQTA
|
||
RET ;MESSAGE ALREADY GIVEN
|
||
|
||
;We have accepted the connect, now loop on data message receives
|
||
|
||
SETZM RCVCNT ;START WITH MESSAGE #1
|
||
SETZM SNDCNT ;AND NO MSGS SENT FOR STATS
|
||
SETZM RERRCNT ;NO RECEIVE ERRORS YET
|
||
SETZM SERRCNT ;NO SEND ERRORS YET
|
||
|
||
CALL GETTIME
|
||
MOVEM T1,STRTIME ;STORE STARTING TIME
|
||
|
||
CALL DATLOP ;TO THE DATA TEST
|
||
JFCL ;FAILED
|
||
|
||
CALL GETTIM ;GET CURRENT TIME
|
||
SUB T1,STRTIME ;SUBTRACT OFF STARTING TIME
|
||
MOVEM T1,ELPTIME ;STORE AS ELAPSED TIME
|
||
CALL PSTATS ;TYPE OUT STATS FOR USER
|
||
|
||
PJRST NSPREL ;RELEASE THE LINK
|
||
|
||
;The DTS will close the link in all success cases, we may abort
|
||
;if there is an error.
|
||
;DATLOP - Loop to do the actual data test
|
||
;
|
||
;Call: CALL DATLOP
|
||
; Error Return
|
||
; Normal Return
|
||
;
|
||
;Called only from DO.DATA
|
||
|
||
DATLOP: MOVE T1,TYPE ;GET TEST TYPE
|
||
CAIN T1,.DCECH ;IS IT AN ECHO TEST?
|
||
JRST DATECH ;YES, SPECIAL LOOP FOR ECHO TEST
|
||
;NO, USE STANDARD LOOP
|
||
DATLP1: MOVE NSAA1,MSGSIZ ;BYTES IN A MAX MESSAGE
|
||
MOVE NSAA2,PRCVMSG ;BYTE POINTER TO RECEIVED MESSAGE
|
||
CALNSP .NSFDR,NSAA2,<NS.WAIT ! NS.EOM> ;READ WHOLE MESAGE
|
||
JRST DATL.E ;ABORT ON NETWORK ERROR (ERROR RETURN)
|
||
TXNN NSAFN,NS.EOM ;DID WE GET THE WHOLE MESSAGE?
|
||
JRST DATL.M ;NO, COMPLAIN
|
||
|
||
AOS RCVCNT ;UPDATE FOR SEQ TEST AND FOR STATS
|
||
|
||
;Since NS.WAI and NS.EOM are lit in the arg block,
|
||
;we will only return from the NSP. UUO when we have a full message.
|
||
|
||
MOVE T1,TYPE ;TYPE OF THIS DATA TEST
|
||
CALL @[EXP DATL.1 ;SINK
|
||
EXP DATL.2 ;SEQUENCE
|
||
EXP DATL.3 ;PATTERN
|
||
EXP DATL.3](T1) ;ECHO (SHOULD BE IN DATECH LOOP)
|
||
RET ;ERROR RETURN: ABORT THE LINK
|
||
JRST DATLOP ;SUCCESS RETURN, GET NEXT MESSAGE
|
||
|
||
|
||
;Here on a network error. Spec says abort the link.
|
||
|
||
DATL.E: CAXE T1,NSABO% ;[7] IGNORE "ABORT BY OBJECT" ERROR
|
||
CAXN T1,NSDBO% ;IGNORE "DISCONNECTED BY OBJECT" ERROR
|
||
RET ;CALLER WILL ABORT THE LINK
|
||
AOS RERRCNT ;COUNT OTHER ERRORS FOR STATS
|
||
PJRST NSPERR ;TELL USER ABOUT THE ERROR
|
||
|
||
;Here if we received a message with no End of Message flag
|
||
|
||
DATL.M: WARN <No EOM flag on received message>,CRLF
|
||
RET ;ERROR RETURN
|
||
;The SINK test
|
||
|
||
DATL.1: RETSKP ;SINK, JUST TOSS THE MESSAGE
|
||
|
||
;The SEQUENCE test
|
||
|
||
DATL.2: MOVE T1,MSGSIZ ;GET MAX SIZE THIS MSG COULD BE
|
||
HRLM T1,RCVMSG ;STORE AS STRING BLK LENGTH FOR GETNBY
|
||
MOVEI T1,0 ;OFFSET OF BYTES TO GET
|
||
MOVEI T2,RCVMSG ;POINTER TO STRING BLOCK
|
||
MOVEI T3,SEQLEN ;NUMBER OF BYTES IN A SEQUENCE NUMBER
|
||
CALL GETNBY ;GET N BYTES INTO T1
|
||
HALT ;INTERNAL ERROR
|
||
MOVE T2,RCVCNT ;SEQUENCE, CHECK THE SEQUENCE NUMBER
|
||
ANDX T2,MASK.(SEQLEN*^D8,35) ;MAKE IT WRAP AROUND PROPERLY
|
||
MOVEM T2,RCVCNT ;SAVE WRAPPED VALUE
|
||
CAME T1,T2 ;IS THIS THE EXPECTED MESSAGE?
|
||
TRNA ;NO, ABORT THE LINK
|
||
RETSKP ;YES, SUCCESS
|
||
|
||
WARN <Comparison of sequence numbers failed>,CRLF
|
||
RET
|
||
|
||
;The PATTERN test
|
||
|
||
DATL.3: CALL DATL.2 ;FIRST, CHECK THE SEQUENCE NUMBER
|
||
RET ;PROPOGATE ERROR RETURN
|
||
MOVEI T1,SEQLEN ;ADVANCE BY SEQLEN TO SKIP MSG NUMBER
|
||
ADJBP T1,PRCVMSG ;BYTE PTR TO RECEIVED MSG
|
||
MOVE T2,MSGSIZ ;LENGTH OF CORRECT MESSAGE
|
||
SUBI T2,SEQLEN ;DECREMENT BY LENGTH OF MESSAGE NUMBER
|
||
CALL CMPSTD ;COMPARE WITH STANDARD DATA
|
||
TRNA ;COMPARE FAILED, ABORT THE TEST
|
||
RETSKP ;YES, SUCCESS
|
||
|
||
WARN <Comparison of standard data failed>,CRLF
|
||
RET
|
||
;The ECHO test
|
||
|
||
DATECH: MOVE NSAA1,MSGSIZ ;BYTES IN A MAX MESSAGE
|
||
MOVE NSAA2,PRCVMSG ;BYTE POINTER TO RECEIVED MESSAGE
|
||
CALNSP .NSFDR,NSAA2,<NS.WAIT> ;READ WHOLE MESAGE
|
||
JRST DATL.E ;ABORT ON NETWORK ERROR (ERROR RETURN)
|
||
|
||
AOS RCVCNT ;TELL STATS ABOUT THE RECEIVE
|
||
AOS SNDCNT ;TELL STATS ABOUT THE SEND
|
||
|
||
SUB NSAA1,MSGSIZ ;GET NUMBER OF BYTES WE ACTUALLY RECEIVED
|
||
MOVMS NSAA1 ;MAKE THAT POSITIVE
|
||
MOVE NSAA2,PRCVMSG ;SEND THE SAME MESSAGE BACK AGAIN
|
||
TXNN NSAFN,NS.EOM ;DID WE HAVE EOM ON THAT READ?
|
||
JRST DATEC1 ;NO
|
||
CALNSP .NSFDS,NSAA2,<NS.WAIT!NS.EOM> ;YES, SEND MESSAGE BACK
|
||
JRST DATECE ;NETWORK ERROR, ABORT THE LINK
|
||
JRST DATECH ;SUCCESS, DO IT AGAIN
|
||
|
||
DATEC1: CALNSP .NSFDS,NSAA2,<NS.WAIT> ;YES, SEND SEGMENT BACK
|
||
JRST DATECE ;NETWORK ERROR, ABORT THE LINK
|
||
JRST DATECH ;SUCCESS, DO IT AGAIN
|
||
|
||
;Here on a network error, spec says abort the link
|
||
|
||
DATECE: AOS SERRCNT ;COUNT A SEND ERROR
|
||
RET ;CALLER WILL ABORT THE LINK
|
||
SUBTTL The INTERRUPT Test
|
||
|
||
;Call: CALL DO.INTERRUPT
|
||
; Normal Return
|
||
|
||
DO.INTERRUPT:
|
||
MOVEI T2,CNTUSR ;T2 IS KEPT THROUGH CALLS TO GETxBY
|
||
|
||
MOVEI T1,1 ;FIELD NUMBER 1 NEXT
|
||
CALL GET1BY ;READ INTTYPE FIELD
|
||
PJRST UNSUP1 ;IF ERROR, UNSUPPORTED TEST IN FIELD 1
|
||
CAILE T1,.ICMAX ;SUPPORTED VALUE?
|
||
PJRST UNSUP1 ;NO, COMPLAIN
|
||
MOVEM T1,TYPE ;PUT THE INTERRUPT TEST'S /TYPE: VALUE
|
||
|
||
MOVEI T1,2 ;FIELD NUMBER 2 NEXT
|
||
CALL GET1BY ;READ RQUEUE FIELD
|
||
PJRST UNSUP2 ;IF ERROR, UNSUPPORTED TEST IN FIELD 2
|
||
MOVEM T1,RQUEUE ;PUT /RQUEUE FIELD
|
||
|
||
MOVEI T1,3 ;FIELD NUMBER 3 NEXT
|
||
;[3] CALL GET2BY ;READ THE MSGLEN FIELD
|
||
;[3] PJRST UNSUP3 ;IF ERROR, UNSUPPORTED TEST IN FIELD 3
|
||
;[3] CAXLE T1,MAXMSG ;SUPPORTED MESSAGE SIZE?
|
||
;[3] PJRST UNSUP3 ;IF ERROR, UNSUPPORTED TEST IN FIELD 3
|
||
;[3] MOVEM T1,MSGSIZ ;PUT THE /MSGSIZ VALUE
|
||
SETZM MSGSIZ ;[10] CLEAR MESSAGE SIZE
|
||
|
||
;Finished reading the Connect message,
|
||
;fall through to next page to accept the connect
|
||
;From Previous Page
|
||
|
||
DEFINE ITYPMC(text),<
|
||
[INFO <text Test>,CRLF
|
||
RET]
|
||
>
|
||
|
||
MOVE T1,TYPE ;GET TYPE CODE FOR INTERRUPT TEST
|
||
CALL @[ITYPMC Interrupt Sink
|
||
ITYPMC Interrupt Sequence
|
||
ITYPMC Interrupt Pattern
|
||
ITYPMC Interrupt Echo](T1)
|
||
|
||
SETZB NSAA1,NSAA2 ;NO USER DATA OR SEGSIZE OFFERED
|
||
SETZM NSAA3 ;DEFAULT FLOW CONTROL MODE
|
||
CALNSP .NSFAC,NSAA3 ;WE'RE HAPPY, ACCEPT THE CONNECT
|
||
PJRST NSPERR
|
||
|
||
;We have accepted the connect, now loop on data message receives
|
||
|
||
SETZM RCVCNT ;START WITH MESSAGE #1
|
||
SETZM SNDCNT ;AND NO MSGS SENT FOR STATS
|
||
SETZM RERRCNT ;[7] NO RECEIVE ERRORS YET
|
||
SETZM SERRCNT ;[7] OR SEND ERRORS
|
||
|
||
CALL GETTIME
|
||
MOVEM T1,STRTIME ;STORE STARTING TIME
|
||
|
||
CALL INTLOP ;TO THE INTERRUPT TEST
|
||
JFCL ;FAILED
|
||
|
||
CALL GETTIM ;GET CURRENT TIME
|
||
SUB T1,STRTIME ;SUBTRACT OFF STARTING TIME
|
||
MOVEM T1,ELPTIME ;STORE AS ELAPSED TIME
|
||
CALL PSTATS ;TYPE OUT STATS FOR USER
|
||
|
||
PJRST NSPREL ;RELEASE THE LINK
|
||
|
||
;The DTS will close the link in all success cases, we may abort
|
||
;if there is an error.
|
||
;INTLOP - Loop to do the actual INTERRUPT test
|
||
;
|
||
;Call: CALL INTLOP
|
||
; Error Return
|
||
; Normal Return
|
||
;
|
||
;Called only from DO.INTERRUPT
|
||
|
||
INTLOP: MOVEI NSAA1,RCVMSG ;POINTER TO A STRING BLOCK
|
||
CALNSP .NSFIR,NSAA1,NS.WAIT ;INTERRUPT READ
|
||
PJRST NSPREL ;ABORT ON NETWORK ERROR (ERROR RETURN)
|
||
|
||
AOS RCVCNT ;UPDATE FOR SEQ TEST AND FOR STATS
|
||
HLRZ T1,RCVMSG ;[5] GET SIZE OF INTERRUPT MESSAGE
|
||
MOVEM T1,MSGSIZ ;[5] SAVE FOR STATISTICS
|
||
|
||
;Since NS.WAI is lit in the arg block, we will only return from
|
||
;the NSP. UUO when we have a full RCVMSG.
|
||
|
||
MOVE T1,TYPE ;TYPE OF THIS INTERRUPT TEST
|
||
CALL @[EXP INTL.1 ;SINK
|
||
EXP INTL.2 ;SEQUENCE
|
||
EXP INTL.3 ;PATTERN
|
||
EXP INTL.4](T1) ;ECHO
|
||
RET ;ERROR RETURN: ABORT THE LINK
|
||
JRST INTLOP ;SUCCESS RETURN, GET NEXT RCVMSG
|
||
;The SINK test
|
||
|
||
INTL.1: RETSKP ;SINK, JUST TOSS THE MESSAGE
|
||
|
||
;The SEQUENCE test
|
||
|
||
INTL.2: MOVEI T1,0 ;OFFSET OF BYTES TO GET
|
||
MOVEI T2,RCVMSG ;POINTER TO STRING BLOCK
|
||
MOVEI T3,SEQLEN ;NUMBER OF BYTES IN A SEQUENCE NUMBER
|
||
CALL GETNBY ;GET N BYTES INTO T1
|
||
HALT ;INTERNAL ERROR
|
||
MOVE T2,RCVCNT ;[4] GET EXPECTED SEQUENCE NUMBER
|
||
ANDX T2,MASK.(SEQLEN*^D8,35) ;MAKE IT WRAP AROUND PROPERLY
|
||
CAME T1,T2 ;IS THIS THE EXPECTED MESSAGE?
|
||
TRNA ;NO, ABORT THE LINK
|
||
RETSKP ;YES, SUCCESS
|
||
|
||
WARN <Comparison of sequence numbers failed>,CRLF
|
||
RET
|
||
|
||
;The PATTERN test
|
||
|
||
INTL.3: CALL INTL.2 ;FIRST, CHECK THE SEQUENCE NUMBER
|
||
RET ;PROPOGATE ERROR RETURN
|
||
MOVEI T1,SEQLEN ;ADVANCE BY SEQLEN TO SKIP MSG NUMBER
|
||
ADJBP T1,PRCVMSG ;BYTE PTR TO RECEIVED MSG
|
||
HLRZ T2,RCVMSG ;LENGTH OF OUR MESSAGE ;[3]
|
||
SUBI T2,SEQLEN ;DECREMENT BY LENGTH OF MESSAGE NUMBER
|
||
CALL CMPSTD ;COMPARE WITH STANDARD DATA
|
||
TRNA ;COMPARE FAILED, ABORT THE TEST
|
||
RETSKP ;YES, SUCCESS
|
||
|
||
WARN <Comparison of standard data failed>,CRLF
|
||
RET
|
||
|
||
;The ECHO test
|
||
|
||
INTL.4: AOS SNDCNT ;COUNT FOR STATS
|
||
MOVEI NSAA1,RCVMSG ;POINTER TO STRING BLOCK
|
||
CALNSP .NSFIS,NSAA1,NS.WAIT ;SEND THE INTERRUPT BACK
|
||
TRNA ;[10] SEND FAILED, COUNT ERROR AND ABORT LINK
|
||
RETSKP ;SUCCESS, THE ECHO IS NOW COMPLETE
|
||
AOS SERRCNT ;[10] COUNT SEND ERROR
|
||
RET ;[10] NON-SKIP RETURN TO ABORT LINK
|
||
SUBTTL ENTPAS - Subroutine to Enter Passive
|
||
|
||
;ENTPAS - Subroutine to Enter Passive
|
||
;
|
||
;Call: CALL ENTPAS
|
||
; Error Return, message put out
|
||
; Normal Return with DECnet state in T1, status word in NSAA1
|
||
;
|
||
;Uses T1,T2,T3,T4
|
||
|
||
ENTPAS: SETOM CHANEL ;NO CHANNEL NUMBER YET
|
||
MOVEI NSAA1,EPCONB ;POINTER TO CONNECT BLOCK
|
||
CALNSP .NSFEP,NSAA1,NS.WAIT ;WAIT ON ENTER PASSIVE
|
||
PJRST NSPERR ;COMPLAIN ABOUT NSP. ERROR
|
||
|
||
MOVEM NSACH,CHANEL ;STORE CHANNEL NUMBER RETURNED
|
||
|
||
LDB T1,[POINTR(NSACH,NS.STA)];GET THE STATE FIELD
|
||
CAIE T1,.NSSRN ;NOW IN RUN STATE?
|
||
CAIN T1,.NSSCR ;OR CONNECT RECEIVED?
|
||
JRST ENTP.1 ;YES, GET THE USER DATA
|
||
|
||
ERROR <Unexpected state after Enter Passive, see next message>,CRLF
|
||
CALL TYPSTA ;TELL USER CURRENT STATE INFO
|
||
PJRST NSPREL ;RELEASE THE CHANNEL
|
||
|
||
|
||
;Here when we have a connect, get the user data
|
||
|
||
ENTP.1: MOVEI NSAA1,RICONB ;CONNECT BLK PTR
|
||
SETZB NSAA2,NSAA3 ;SEG SIZE, FLOW CONTROL
|
||
CALNSP .NSFRI,NSAA3 ;READ CONNECT INIT DATA
|
||
PJRST NSPERL
|
||
RETSKP ;USER DATA IN CNTUSR
|
||
SUBTTL UNSUPn - Unsupported Test Routine
|
||
|
||
;Here we sent the error code back to DTS, saying that we don't
|
||
;support the particular test or option requested.
|
||
|
||
;The number at the end of the routine name is the number of the
|
||
;field which contains the unsupported request.
|
||
|
||
;Call: T1/ Number of field in error
|
||
; CALL UNSUPT
|
||
; Normal Return
|
||
|
||
UNSUP0: JSP T1,UNSU.1 ;THE TESTTYPE FIELD
|
||
UNSUP1: JSP T1,UNSU.1 ;THE TESTDESC FIELD
|
||
UNSUP2: JSP T1,UNSU.1
|
||
UNSUP3: JSP T1,UNSU.1
|
||
UNSUP4: JSP T1,UNSU.1
|
||
UNSUP5: JSP T1,UNSU.1
|
||
|
||
UNSU.1: MOVEI T1,-UNSUP0-1(T1);MAKE T1 A SMALL INTEGER
|
||
UNSUPT: SAVEAC P1
|
||
MOVE P1,T1 ;THE FIELD NUMBER
|
||
MOVEI T1,STRLNW ;LENGTH OF A STR BLK IN WORDS
|
||
MOVEM T1,CNTUSR ;START WITH FRESH STR BLK
|
||
MOVEI T1,.ECUKT ;UNKNOWN TEST (^D15)
|
||
MOVEI T2,CNTUSR ;PTR TO STR BLK
|
||
CALL PUT1BY ;PUT ONE BYTE IN STRING BLOCK
|
||
MOVE T1,P1 ;NUMBER OF FIELD IN ERROR
|
||
MOVEI T2,CNTUSR
|
||
CALL PUT1BY ;STORE THE SECOND BYTE
|
||
|
||
ERROR <Rejecting unsupported test request in field >
|
||
MOVE T1,P1 ;GET FIELD NUMBER
|
||
CALLSCAN .TDECW##
|
||
CALLSCAN .TCRLF##
|
||
|
||
MOVEI NSAA1,CNTUSR ;POINTER TO USER DATA
|
||
CALNSP .NSFRJ,NSAA1,NS.WAI ;REJECT FUNCTION CODE
|
||
PJRST NSPERL
|
||
CPOPJ: RET
|
||
SUBTTL .EXIT - Called by SCAN's MONRET Routine
|
||
|
||
;Called by the EXIT command and by SCAN's monret routine
|
||
|
||
|
||
.EXIT: CALL CLSLOG ;IN CASE IT WAS OPEN
|
||
PJRST .MNRET## ;SCAN'S MONRET HANDLER
|
||
SUBTTL End of Program
|
||
|
||
END DTR
|