Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-09 - decus/20-181/rmtque.mac
There are no other files named rmtque.mac in the archive.
TITLE	RMTQUE	 -- REMOTE PRINTER QUEUE ACTIVE TASK
SUBTTL	Scott McClure/ESI	20-AUG-84

	SEARCH	GLXMAC			    ;SEARCH GALAXY PARAMETERS
IFE DEBUG,<				    ;[10]
	PROLOG	(RMTQUE)
>
IFN DEBUG,<				    ;[10]
	PROLOG	(TSTQUE)
>
	SEARCH	QSRMAC			    ;SEARCH QUASAR PARAMETERS
	SEARCH	ORNMAC			    ;GET OPERATOR SYMBOLS


COMMENT $

Abstract:	RMTQUE is the run in conjunction with RMTSPL, the
	first on a source machine and the second on a target machine.
	This program is the active portion.  It reads the primary
	master queue file looking for any queue entry with a
	/destination that is remote.  This queue entry is then
	transfered, the file referenced is transfered, the queue entry
	is removed from the local queue and the file is handled as it
	would have been had LPTSPL done the printing locally.  Each of
	these tasks is dependent upon a positive acknowledgement from
	RMTSPL.  Any non-fatal failure simply leaves the queue alone
	causing the system to attempt the transmition on the next
	pass. 

Limitations:	This system is limited to the DECSYSTEM-20 line by
	currently sending the 20 External Queue Entry record as a
	message format between machines and send essentially 36 bit
	data.  Seperate spoolers (RMTSPL) could be created to decode
	this for other machines or this active portion could be made
	to use DAPLIB or some other system which knows more machines.
	There are no current plans to change this.

	The system will only transfer a single page queue entry. This is
	not a major problem since about 22 average sized file specs will
	fit in a single page. The system will only work with queue entry
	files of less than 513 pages. This is also not a practical problem
	but should be fixed to maintain consistency with other DEC software.
$

;VERSION AND EDIT INFORMATION

	QUEMAJ==1			    ;MAJOR VERSION
	QUEMIN==0			    ;MINOR VERSION
	QUEEDT==16			    ;EDIT LEVEL
	QUEWHO==2			    ;WHO LAST EDITED - CUST

;ENTRY VECTOR DEFINITION

QUEVEC:	JRST	RMTQUE			    ;ENTER HERE
	JRST	RMTQUE			    ;REENTER SAME
QUEVER:	BYTE	(3)QUEWHO(9)QUEMAJ(6)QUEMIN(18)QUEEDT
	EVECL==.-QUEVEC
;DEBUG SWITCH[10]
	DEBUG==0
SUBTTL	Table of Contents

;                     TABLE OF CONTENTS FOR RMTQUE
;
;			SECTION					PAGE
;			-------					----
;	1.  Table of Contents..................................    2
;	2.  Revision History...................................    3
;	3.  Accumulators and Constants.........................    4
;	4.  Quasar storage.....................................    5
;	5.  RMTQUE  Main entry and initilization...............    6
;	6.  CHKQUE  Check the queue files for remote request...    7
;	7.  GETIDX  Read MQF index page(s).....................	   8
;	8.  NXTSEC  Process the next section of MQF............    9
;	9.  ISNODE  Check if entry goes to remote node.........   10
;      10.  MOVEIT  Move queue entry to another node...........   11
;      11.  LLGJFN  Routine to get logical link JFN............   12
;      12.  LLOPEN  Open logical link to remote................   13
;      13.  SENDQE  Send queue entry to remote node............   14
;      14.  OPENIT  Open file for moving to target node........   15
;      15.  SNDPAG  Send a single (full) page to remote JFN....   16
;      16.  PUTBCT  Store image bit stream in 8 bit message....   17
;      17.  CANQUE  Cancel queue entry.........................   17
;      18.  FILDIS  Keep/Delete printed spool files............   18
;      19.  LLCLOS  Routine to close or abort a logical link...   19
;      20.  SNDINT  Send interrupt message to server (RMTSPL)..   20
;      21.  RELJFN  Routine to release all non-open JFNS.......   20
;      22.  STRMNT  Mount the structure for the current file...   21
;      23.  Interrupt tables...................................   22
;      24.  INTCDN  Connect/Disconnect interrupt...............   22
;      25.  INTINA  Interrupt message handler..................   22
;      26.  INTDAV  Data available from network................   22
;      27.  Table of NSP disconnect reasons....................   23
;      28.  Inpure storage.....................................   24
SUBTTL	Revision History

COMMENT $

EDIT 	DATE		WHO		WHY
====	====		===		=====================================

1	08/20/84	SDM		First installed for development area
					use.
2	08/21/84	SDM		Handle unreachable nodes.  Store them
					and ignore queue entry. Don't die!
3	08/28/84	SDM		Get paranoid about index page changing
					after I read it.  Set a max of 1 page.
4	08/29/84	SDM		If we can't access the input file, tell
					server not to save file.  Let LPTSPL
					tell user.
5	09/03/84	SDM		More paranoia - trap Illegal memory
					reads and die only if there have been
					10 on this pass.
6	09/13/84	SDM		Release all unopened JFNS at end of
					queue scan.
7	09/28/84	SDM		One more on IMR trap.  Add delay before
					we try again to allow QUASAR to finish.
8	03/21/85	SDM		Clear FILJFN if it can't be opened
					so we don't try to close it.
9	05/06/85	DLP		Change the transfer protocol to send
					the # of bytes in the file and the file
					byte size. This will then be used to
					update the FDB of the remote file so
					the file will not end in nulls. This
					is necessary to support the 6.0 LPTSPL
					which tests for non-printable chars.
					Also change SNDPAG to support variable
					sizes of send data to support this.
10	05/06/85	DLP		Add debug switch to setup active and
					passive programs to run independently
					of production versions. Change the
					node test to look for /Node:TEST and
					convert the node to MISB if true.
					These features setup for conditional
					assembly.
11	06/04/85	DLP		Implement multiple file transfer
					according to # of files in queue entry.
12	06/05/85	DLP		Put user name in /NOTE field if there
					isn't already something there
13	06/10/85	DLP		Fix 'page table does not exist' error.
					Change the MQF index page to be shared
					so as to let it change with the queue.
					Then trap the error at the PMAP% for
					the queue entry if the index page has
					changed.
14	06/11/85	DLP		Fix 'string exceeds 16 bytes' message.
					See LLCLOS. Also remove SNDINT and
					CLSJFN sections (never called).
15	06/12/85	DLP		Add a routine to mount a structure
					if the open fails and try again.
16	06/13/85	DLP		Files are not being deleted properly
					on the source machine if the user
					is not privilaged. Fix argblk for
					CHKAC call in FILDIS.
$
SUBTTL	Accumulators and Constants


;ACCUMULATOR DEFINITIONS

	E==14				    ;POINT TO THIS FILE
	J==15				    ;JOB CONTEXT - BEGINING ADDRESS

;INTERRUPT CHANNEL ASSIGNMENTS

	XP	.ICCDN,0		    ;CONNECT/DISCONNECT
	XP	.ICINA,1		    ;INTERRUPT MESSAGE
	XP	.ICDAV,2		    ;DATA AVAILABLE

;OTHER CONSTANTS

	XP	PDLEN,^D200		    ;STACK SIZE
	XP	TRNSIZ,1100		    ;SIZE OF TRANSFER BUFFER
	XP	MAXNOD,20		    ;MAX LENGTH OF BAD NODE TABLE
	XP	MYNODE,[SIXBIT/MISB /]	    ;NODE TO CHANGE TO FOR TEST[10]

;INTERRUPT MESSAGE NUMBERS - FIRST 8 BITS ONLY
	
	.QEPAG==FLD(1,7B7)		    ;QUEUE ENTRY PAGE
	.FIDAT==FLD(2,77B7)		    ;DATA PAGE
	.FIEOF==FLD(3,77B7)		    ;END OF FILE FLAG

;AND THE ANSWERS WE WANT

	.QEACK==1			    ;ACKNOWLEDGE QUEUE ENTRY
	.FIACK==2			    ;ACKNOWLEDGE FILE TRANSFER
	.FINAK==3		   	    ;HAD PROBLEM IN TRANMIT
SUBTTL	Local macros

DEFINE	MQFNAM,<ASCIZ\PS:<SPOOL>PRIMARY-MASTER-QUEUE-FILE.QUASAR\>

DEFINE	TXT(TEXT),<POINT 7,[ASCIZ\TEXT\]>

DEFINE	$FATAL	(MSG,ITXT,%L1) <
	HRRZ	P1,(P)
	SUBI	P1,2
	$CALL	[$TEXT (,<?^W/.SPRGM## /^A>)
		 $TEXT (,<^Q/ %L1/ITXT ^A>)
		 $TEXT (,<at ^O/P1/>)
		 HALTF%
		 PJRST .-1
	%L1:!	 TXT<MSG>]
	SUPPRESS %L1
> ;End of $FATAL
SUBTTL	Quasar storage


MYIB:	$BUILD IB.SZ
	    $SET(IB.PRG,,%%.MOD)	    ;SET PROGRAM NAME
	    $SET(IB.FLG,IB.DPM,1)	    ;USE JOB # FOR PID
	    $SET(IB.OUT,,T%TTY)		    ;DEFAULT TO TTY FOR TEXT
	    $SET(IB.INT,,<LEVTAB,,CHNTAB>)  ;TURN ON PSI STUFF
	    $SET(IB.PIB,,PIBBLK)	    ;ADDRESS OF PIB BLOCK
	$EOB

PIBBLK:	$BUILD PB.MNS			    ;MINIMUM SIZE
	    $SET(PB.HDR,PB.LEN,PB.MNS)	    ;LENTH
	$EOB

QUESAB:	$BUILD	(SAB.SZ)		    ;IPCF SEND ARG BLOCK
	  $SET	(SAB.LN,,KIL.SZ)	    ;KILL IS ALL WE SEND
	  $SET	(SAB.MS,,KIL.MS)	    ;POINT TO KILL MESSAGE
	  $SET	(SAB.SI,SI.FLG,1)	    ;USE SI.IDX
	  $SET	(SAB.SI,SI.IDX,SP.QSR)	    ;USE QUASAR INDEX
	$EOB

KIL.MS:	$BUILD (KIL.SZ)
	    $SET(.MSTYP,MS.CNT,KIL.SZ)	    ;MESSAGE LENGTH
	    $SET(.MSTYP,MS.TYP,.QOKIL)	    ;KILL FUNCTION
	    $SET(.MSFLG,MF.ACK,1)	    ;ASK FOR ACKNOWLEGE
	    $SET(.MSCOD,,4)		    ;ACK CODE
	    $SET(KIL.OT,,.OTLPT)	    ;OBJ TYPE IS LPT
	$EOB

CKAARG:	$BUILD (6)			    ;ARG BLOCK FOR CHKAC
	  $SET(.CKAAC,,1)		    ;WANT WRITE ACCESS
	  $SET(.CKAEC,,0)		    ;USER HAS NO CAPABILITIES
	$EOB
SUBTTL	RMTQUE	Main entry and initilization

RMTQUE:	RESET				    ;CLEAR THE WORLD
	MOVE	P,[IOWD PDLEN,PDL]	    ;BUILD A STACK
	MOVEI	S1,IB.SZ		    ;SIZE OF THE IB
	MOVEI	S2,MYIB			    ;WHERE IT IS
	$CALL	I%INIT			    ;INIT GLXLIB
	MOVEI	S1,.FHSLF		    ;INIT PSI FOR ME
	MOVE	S2,[LEVTAB,,CHNTAB]	    ;TABLE ADDRESSES
	SIR%				    ;SET 'EM
	EIR%				    ;AND ENABLE THE PSI
	MOVEI	S1,.FHSLF		    ;ME AGAIN
	MOVX	S2,1B<.ICCDN>!1B<.ICINA>!1B<.ICDAV>!1B<.ICIRD>
	AIC%				    ;ACTIVATE CHANNELS
	MOVX	S1,<GJ%SHT!GJ%OLD!GJ%NS>    ;SHORT, MUST BE THERE
	HRROI	S2,[MQFNAM]		    ;MASTER QUEUE FILE NAME    
	GTJFN%				    ;GO GET IT
	 ERCAL	DIE			    ;OOPS, CAN'T GET IT
	HRRZM	S1,MQFJFN		    ;SAVE IT
	HRRZS	S1			    ;CLEAR RIGHT FOR OPEN
	MOVX	S2,<OF%RD!OF%PDT>	    ;READ ONLY - QUIETLY
	OPENF%
	 ERCAL	DIE			    ;GOT TO HAVE IT!
	MOVEI	S1,.NDGLN		    ;GET LOCAL NODE NAME
	MOVEI	S2,T1			    ;T1 IS ARG BLOCK
	MOVE	T1,[POINT 7, LOCNOD]	    ;POINT TO NAME STORAGE
	MOVE	T2,T1			    ;COPY POINTER
	NODE%				    ;GET IT!
	 ERCAL	DIE			    ;OR DIE - NEED IT TOO.
	MOVE	T1,T2			    ;RESTORE POINTER
	MOVE	T2,[POINT 6, LOCNOD]	    ;AND MAKE A SIXBIT COPY
RMTQ1:	ILDB	S1,T1			    ;GET CHAR
	CAIG	S1,0			    ;DONE?
	JRST	RMTQ2			    ;CLEAN UP
	SUBI	S1,40			    ;MAKE IT SIXBIT
	IDPB	S1,T2			    ;STORE IT AWAY
	JRST	RMTQ1			    ;DO SOME MORE
RMTQ2:	IDPB	S1,T2			    ;STORE THE ZERO
	$CALL	M%ACQP			    ;GET PAGE FOR
	MOVEM	S1,INPAGE		    ;THE INPUT BUFFER
	PG2ADR	S1			    ;MAKE IT AN ADDRESS
	MOVEM	S1,INADDR		    ;AND STORE THAT TOO
					    ;FALL THROUGH INTO MAIN LOOP
SUBTTL	CHKQUE	Check the queue files for remote request

;MAIN PROCESSING LOOP - READ QUEUE LOOKING FOR /NODE:NOTHERE.  MOVE FILE IF
;FOUND AND CANCEL REQUEST HERE DUPING ON OTHER MACHINE

CHKQUE:	SKIPE	FOUND			    ;DID WE MOVE SOMETHING?
	 JRST	CHKQ1			    ;YES - LOOK FOR MORE
	MOVEI	S1,^D60			    ;SLEEP A MINUTE
	$CALL	I%SLP			    ;TO LET QUEUE CHANGE
CHKQ1:	SETZM	FOUND			    ;START OVER
	AOSGE	CHKCNT			    ;STILL IN BIG LOOP?
	JRST	CHKQ2			    ;YES, DON'T CLEAR BAD TABLE
	HRREI	S1,-12			    ;DONE, GET NEG COUNTER
	MOVEM	S1,CHKCNT		    ;AND PUT IT AWAY
	MOVEI	S1,MAXNOD		    ;GET LENGTH OF NODE TABLE
	MOVEI	S2,NODTBL		    ;POINT TO TABLE
	$CALL	.ZCHNK			    ;CLEAR IT TO START AGAIN
	SETZM	NODTLN			    ;AND CLEAR THE TABLE COUNTER
CHKQ2:	$CALL	GETIDX			    ;GET THE INDEX PAGE
	CLEARM	P1			    ;CLEAR OUT INDEX REGISTER
CKLOOP:	MOVE	S1,P1			    ;GET CURRENT INDEX REG
	SKIPN	INDTAB(S1)		    ;IS THERE AN INDEX PAGE HERE?
	 JRST	CKLOP1			    ;NOTHING THERE - GO AROUND
	$CALL	NXTSEC			    ;PROCESS THE NEXT SECTION
	HRLI	S2,.FHSLF		    ;NEED TO CLEAR THIS PAGE
	HRR	S2,INDTAB(P1)		    ;SO NEXT PASS CAN USE IT
	SETOM	S1			    ;TELL PMAP TO UNMAP
	MOVX	T1,PM%CNT		    ;ONE
	HRRI	T1,1			    ;PAGE
	PMAP%
	  ERCAL	DIE			    ;OOPS, PMAP FAILED
	MOVE	S1,INDTAB(P1)		    ;AND NOW RELEASE THIS PAGE
	$CALL	M%RELP			    ;IN MY MEMORY TABLE
CKLOP1:	CAIGE	P1,FSSMNS-1		    ;ANY LEFT
	AOJA	P1,CKLOOP		    ;INCREMENT AND DO NEXT
	$CALL	RELJFN			    ;RELEASE ANY UNOPENED JFNS[6]
	JRST	CHKQUE			    ;DONE - NEXT PASS
SUBTTL	GETIDX	Read MQF index page(s)

GETIDX:	CLEARM	INDTAB			    ;CLEAR FIRST WORD
	MOVE	S1,[INDTAB,,INDTAB+1]	    ;MAKE BLT POINTER
	BLT	S1,INDTAB+FSSMNS-1	    ;CLEAR INDEX TABLE
	MOVE	S1,MQFJFN		    ;GET MY JFN BACK
	MOVX	S2,<1,,.FBUSW>		    ;GET USER ARE FROM FDB
	MOVE	T1,BLKCNT		    ;IT GIVES FILE SIZE
	GTFDB%				    ;FOR THE MQF
	 ERCAL	DIE
	MOVE	T2,BLKCNT		    ;GET IT BACK
	ADDI	T2,FSSBPS-1		    ;ROUND IT UP
	IDIVI	T2,FSSBPS		    ;CONVERT TO # SECTIONS
	MOVEM	T2,SECCNT		    ;AND REMEMBER IT
	CLEAR	T3,			    ;CLEAR A COUNTER
GETID1:	$CALL	M%ACQP			    ;GET A PAGE
	MOVEM	S1,INDTAB(T3)		    ;AND SAVE THE #
	HRLI	S1,.FHSLF		    ;<MY-HANDLE,,DEST-PAGE>
	MOVE	S2,S1			    ;IN S2 FOR PMAP
	MOVEI	S1,FSSBPS		    ;GET BLOCKS/SECTION
	IMULI	S1,(T2)			    ;WHICH SECTION?
	ADDI	S1,FSSFIB		    ;+FIRST BLOCK = DPA
	HRL	S1,MQFJFN		    ;<JFN,,SOURCE-PAGE #>
	MOVX	T1,(PM%RD)		    ;READ-LET PAGE CHANGE W/QUEUE[13]
	PMAP%				    ;GET THE PAGE IN
	 ERCAL	.RETF			    ;GOT TO GET IT
	SOJLE	T2,.RETT		    ;RETURN IF DONE
	AOJA	T3,GETID1		    ;OR GET THE NEXT INDEX PAGE
SUBTTL	NXTSEC	Process the next section of MQF

NXTSEC:	$CALL	.SAVE1			    ;SAVE INDEX REG
	MOVE	S2,INDTAB(S1)		    ;GET PAGE # OF SECTION INDEX
	PG2ADR	S2			    ;CONVERT IT TO AN ADDRESS
	MOVEM	S2,INDEX		    ;MAKE IT THE CURRENT INDEX
	IMULI	S1,FSSBPS		    ;GET BASE DATA PAGE ADD(DPA)
	MOVEM	S1,BASE			    ;AND SAVE IT
	HRRZ	P1,@INDEX		    ;HOW MANY ENTRIES
	JUMPE	P1,.RETT		    ;GO HOME IF EMPTY
	MOVEM	P1,QERCNT		    ;AND SAVE THAT IF THERE
	MOVE	P2,INDEX		    ;GET ADDRESS OF INDEX
	ADDI	P2,FSSFDB		    ;POINT TO FIRST DATA BLOCK
NXTSE1:	SKIPN	S2,0(P2)		    ;GET NEXT ENTRY IF THERE
	JRST	NXTSE2			    ;EMPTY, GO TO NEXT ONE
	AOJE	S2,NXTSE2		    ;-1 IS CONTINUATION, IGNORE
	$CALL	M%ACQP			    ;OK, GET OPEN PAGE
	MOVEM	S1,MQPAGE		    ;SAVE THE DEST PAGE #
	HRLI	S1,.FHSLF		    ;<MY-HANDLE,,DEST-PAGE #>
	MOVEM	S1,S2			    ;INTO S2 FOR PMAP
	MOVE	S1,P2			    ;GET THE SOURCE ADDRESS
	SUB	S1,INDEX		    ;TAKE OUT INDEX
	ADD	S1,BASE			    ;PUT IN THE RIGHT SECTION
	HRL	S1,MQFJFN		    ;<MFQ,,SOURCE-PAGE #>
 	MOVX	T1,PM%RD!PM%CPY		    ;READ AND MAKE IT PRIVATE[12]
	PMAP%				    ;GET IT
	 ERCAL	IDXERR			    ;INDEX PAGE CHANGED, SKIP ENTRY[13]
	$CALL	ISNODE			    ;IS IT REMOTE?
	SKIPF				    ;IF NOT THEN
	$CALL	MOVEIT			    ;DON'T DO THIS
	MOVE	S1,MQPAGE		    ;DONE WITH THIS ONE SO,
	$CALL	M%RELP			    ;GIVE THE PAGE BACK
IDXERR:	SOSG	P1,QERCNT		    ;DECREMENT AND LOAD COUNT
	$RETT				    ;NO MORE - DONE
NXTSE2:	AOS	P2			    ;GET NEXT PAGE
	MOVE	S1,INDEX		    ;GET INDEX ADDRESS[3]
	ADDI	S1,1000			    ;POINT TO END OF INDEX PAGE[3]
	CAMLE	P2,S1			    ;ARE WE PAST THAT?[3]
	 $RETT				    ;YES, SOMETHING CHANGED[3]
	JRST	NXTSE1			    ;NO, GET NEXT POINTER
SUBTTL	ISNODE	 Check if entry goes to remote node

;CALL WITH PAGE # OF CURRENT REQUEST IN MQPAGE, RETURN FALSE IF DESTINATION
;NODE IS LOCAL, TRUE IF NOT

ISNODE:	MOVE	J,MQPAGE		    ;COLLECT PAGE #
	PG2ADR	J			    ;MAKE AN ADDRESS
	LOAD	S1,.EQROB(J)		    ;GET REQUESTED OBJECT FOR TYPE
	CAIE	S1,.OTLPT		    ;IS THIS FOR THE LPT?
	$RETF				    ;NO - RETURN FALSE
	LOAD	S1,.EQROB+.ROBND(J)	    ;POINT TO NODE NAME AND GET
	CAMN	S1,LOCNOD		    ;IS IT REMOTE?
	$RETF				    ;NO - SAY SO
IFN DEBUG,<
	CAMN	S1,[SIXBIT/TEST /]	    ;IS IT A TEST FILE?[10]
	MOVE	S1,MYNODE		    ;YES, CHANGE IT FOR TEST[10]
>
	MOVN	S2,NODTLN		    ;GET NEG LENGTH OF BAD NODES TABLE 
	HRLZS	S2			    ;SET IT UP FOR AOBJN
ISNOD1:	CAMN	S1,NODTBL(S2)		    ;IS THIS A BAD NODE?
	$RETF				    ;YES, TELL CALLER TO IGNORE
	AOBJN	S2,ISNOD1		    ;NO MATCH - TRY MORE
	MOVEM	S1,TONODE		    ;OK, SAVE FOR GTJFN
	$RETT			 	    ;DONE HERE
SUBTTL	MOVEIT	Move queue entry to another node


;HERE HAVING DECIDED THAT WE NEED TO MOVE A QUEUE ENTRY BETWEEN MACHINES.
;THIS BECOMES THE MAINLINE FOR THE REST OF THE WORK.

MOVEIT:	AOS	FOUND			    ;SAY WE FOUND ONE TO MOVE
	SETZM	SNDERR			    ;CLEAR THE SEND ERROR FLAG
	$CALL	LLGJFN			    ;GET THE NODE JFN
	$CALL	LLOPEN			    ;OPEN THE LOGICAL LINK
	 JUMPF	.POPJ			    ;FAILURE HERE JUST RETURNS
	$CALL	SENDQE			    ;SEND QUEUE ENTRY TO REMOTE
	 JUMPF	MOVE3			    ;ON FAILURE JUST GO TO NEXT
	LOAD	T1,.EQSPC(J),EQ.NUM         ;GET # OF FILES[11]
	MOVEM	T1,FILES		    ;SAVE IT[11]
	LOAD	E,.EQLEN+(J),EQ.LOH	    ;GET HEADER LENGTH[11]
	ADD	E,J			    ;POINT TO FIRST FP[11]
	MOVEM	E,FPPNT			    ;SAVE THE FP POINTER[11]
MOVE0:	$CALL	OPENIT			    ;OPEN THE SOURCE FILE
	 JUMPF	MOVE2			    ;ON FAILURE SEND BAD EOF[4]
	MOVN	T2,FILSIZ		    ;HOW MANY TIMES?
	HRLZS	T2			    ;<PAGES TO DO,,NEXT PAGE>
MOVE1:	MOVX	T1,.FIDAT		    ;THIS IS A FILE DATA PAGE
	MOVEM	T1,MSGWRD		    ;SAY SO
	MOVE	S2,INPAGE		    ;S2 GETS <ME,,PAGE#>
	HRLI	S2,.FHSLF		    ;PUT SELF WITH SOURCE PAGE #
	HRL	S1,FILJFN		    ;JFN FOR <JFN,,PAGE #>
	MOVX	T1,PM%RD		    ;READ ACCESS ONLY
	HRR	S1,T2			    ;GET NEXT PAGE #
	PMAP%
	 ERCAL	DIE
	MOVEI	S1,1000			    ;# OF BYTES TO SEND[9]
	MOVEM	S1,SBYTS		    ;SAVE IT[9]
	MOVE	S1,INADDR		    ;SET UP FOR TRANSFER
	$CALL	SNDPAG			    ;SEND A PAGE TO REMOTE
	AOBJN	T2,MOVE1		    ;DO 'TIL DONE
MOVE2:	MOVE	T1,[POINT 8,MSGWRD]	    ;EOF INFO 
	MOVX	S1,.FIEOF		    ;THE EOF MESSAGE NUMBER
	MOVEM	S1,MSGWRD		    ;STORE IT
	MOVE	T1,FILSIZ		    ;# OF PAGES IN FILE[9]
	MOVEM	T1,TRNBUF		    ;SAVE IT[9]
	MOVE	T1,FILBYT		    ;# OF BYTES IN FILE[9]
	MOVEM	T1,TRNBUF+1		    ;SAVE IT[9]
	MOVE	T1,FILBSZ		    ;BYTE SIZE[9]
	MOVEM	T1,TRNBUF+2		    ;SAVE IT[9]
	MOVEI	S1,3			    ;# BYTES TO SEND[9]
	MOVEM	S1,SBYTS		    ;SAVE IT[9]
	MOVEI	S1,TRNBUF		    ;SETUP FOR TRANSFER[9]
	$CALL	SNDPAG			    ;SEND IT[9]
	SETZM	S1			    ;WILL WAIT FOREVER
	$CALL	I%SLP			    ;FOR THE ACKNOWLEDGMENT
	MOVE	T1,[POINT 8,MESAGE]	    ;POINTER TO MESSAGE
	ILDB	S1,T1			    ;GET MESSAGE BYTE
	CAIE	S1,.FIACK		    ;IS THIS AN ACK?
	 AOS	SNDERR			    ;NO - SET ERROR[11]
	$CALL	FILDIS			     ;FINISH THE FILE[11]
	SKIPE	SNDERR			     ;FILE OK?[11]
	 JRST	MOVE3			     ;NO - START QUEUE ENTRY OVER[11]
	SOSE	FILES			     ;ANOTHER FILE?[11]
	 JRST	MOVE0			     ;YES[11]
	$CALL	CANQUE			     ;CANCEL THE QUEUE ENTRY
MOVE3:	$CALL	LLCLOS			     ;CLOSE THE LINK
	$RETT				    ;AND DONE
SUBTTL	LLGJFN	Routine to get logical link JFN

;ACCEPTS	TONODE/ POINTER TO NODE NAME
;RETURNS	TRUE - JFN IN LLJFN
;		FALSE - ON FAILURE

LLGJFN:	HRROI	S1,LLNAME		    ;DESTINATION AREA
	MOVE	S2,DCNOBJ		    ;START WITH "DCN:"
	SETZM	T1
	SOUT%
LLGJF2:	MOVE	S2,[POINT 6,TONODE]	    ;NODE IS SIXBIT
	HRLOI	T2,-6			    ;MAX NODE NAME LENGTH
LLGJF3:	ILDB	T1,S2
	CAIG	T1,0			    ;DONE ON NULL (SPACE)
	JRST	LLGJF4
	ADDI	T1,40			    ;MAKE IT ASCIZ
	IDPB	T1,S1			    ;STORE INTO DESTINATION
	AOJL	T2,LLGJF3		    ;MORE IF MORE WORD
LLGJF4:	MOVE	S2,DCNOBJ+1		    ;FINISH IT WITH TASK
	SETZM	T1
	SOUT%
LLGJF6:	MOVEI	T1,0			    ;FINISH OFF
	IDPB	T1,S1			    ;WITH NULL
	MOVX	S1,<GJ%NEW!GJ%SHT>	    ;NEW - SHORT
	HRROI	S2,LLNAME		    ;POINT TO FULL NAME
	GTJFN%				    ;AND GET THE JFN
	 JRST	.+1			    ;LET LLOPEN TAKE CARE OF ERRORS
	MOVEM	S1,LLJFN		    ;SAVE THE NEW JFN
	$RETT

DCNOBJ:	TXT(DCN:)
IFE DEBUG,<TXT(-TASK-RMTSPL.RMTQUE)>	    ;[10]
IFN DEBUG,<TXT(-TASK-TSTSPL.TSTQUE)>	    ;[10]
SUBTTL	LLOPEN	Open logical link to remote

;LLOPEN		OPENS  NETWORK JFN ON DCN:
;ACCEPTS	LLJFN JFN OF NETWORK

;RETURNS	TRUE - LINK OPEN AND ATTACHED

LLOPEN:	MOVE	S1,LLJFN		    ;GET JFN OF LINK
	MOVE	S2,[FLD(^D8,OF%BSZ)+OF%RD+OF%WR]
	OPENF%				    ;DO IT
	 JRST	LLOPN2			    ;OOPS, RELEASE AND RETURN
LLOPN1:	MOVE	S1,LLJFN		    ;GET JFN BACK
	MOVEI	S2,.MOACN		    ;ENABLE FOR CONNECT INTERRUPTS 
	MOVX	T1,<FLD(0,MO%CDN)+FLD(1,MO%INA)+FLD(2,MO%DAV)>
	MTOPR%				    ;DO IT.
	 ERJMP	LLOPN2			    ;GIVE UP
	MOVX	S1,^D10			    ;GIVE SERVER LOTS OF TIME
	$CALL	I%SLP			    ;WAIT FOR THE INTERRUPT
	MOVE	S1,LLJFN		    ;GET JFN AGAIN
	MOVEI	S2,.MORLS		    ;GET THE CURRENT LOGICAL LINK
	MTOPR%				    ;STATUS 
	 ERJMP	LLOPN2			    ;DAMN, CLOSE IT UP
	MOVEM	T1,LLSTAT		    ;SAVE STATUS
	TXNN	T1,MO%CON		    ;ARE WE CONNECTED?
	 JRST	LLOPN2			    ;NO, BETTER DIE
	$RETT				    ;LOOKS OK
LLOPN2:	MOVE	S1,LLJFN		    ;GET THE JFN AND
	TXO	S1,CZ%ABT		    ;ABORT IT
	CLOSF%				    ;CLOSE IT
	 ERJMP	.+1			    ;IGNORING ERRORS
	MOVE	S1,TONODE		    ;GET BAD NODE NAME[2]
	MOVE	S2,NODTLN		    ;GET NODE TABLE COUNT[2]
	CAIG	S2,MAXNOD		    ;JUST SKIP IT IF TABLE FULL[2]
	MOVEM	S1,NODTBL(S2)		    ;PUT THIS BAD NODE IN TABLE[2]
	AOS	NODTLN			    ;INCREMENT NODE TABLE COUNT[2]
	$RETF				    ;AND FLAG AN ERROR[2]
SUBTTL	SENDQE	Send queue entry to remote node

SENDQE:	GETLIM	S1,.EQLIM(J),NOT1	    ;GET /NOTE:[12]
	JUMPN	S1,SENDIT		    ;IF NOT BLANK LEAVE IT ALONE[12]
	MOVE	S1,[POINT 6,.EQLIM+2(J)]    ;POINT TO /NOTE:[12]
	MOVEI	T2,-14			    ;MAX 12 CHARS[12]
	HRLZS	T2			    ;<CHARS TO DO,,LAST CHAR>[12]
	MOVE	T1,[POINT 7,.EQOWN(J)]	    ;POINT TO USER NAME[12]
INOTE:	ILDB	S2,T1			    ;GET A CHAR[12]
	JUMPE	S2,SENDIT		    ;NO MORE CHARS IN USER NAME[12]
	SUBI	S2,40			    ;CONVERT TO SIXBIT[12]
	IDPB	S2,S1			    ;PUT IT IN /NOTE:[12]
	AOBJN	T2,INOTE		    ;DO TILL DONE[12]
SENDIT:	MOVX	T1,.QEPAG		    ;SAY IT'S A QUEUE ENTRY
	MOVEM	T1,MSGWRD		    ;IN THE MESSAGE WORD
	MOVEI	S1,1000			    ;#BYTES TO SEND[9]
	MOVEM	S1,SBYTS		    ;SAVE IT[9]
	MOVE	S1,MQPAGE		    ;GET PAGE # OF QE
	PG2ADR	S1			    ;MAKE IT AN ADDRESS FOR BP
	$CALL	SNDPAG			    ;SEND IT OUT
	SETZM	MESAGE			    ;CLEAR MESSAGE WORD
	MOVE	S1,60			    ;ONE MINUTE WAIT
	$CALL	I%SLP			    ;BACK HERE WHEN DONE
	MOVE	T1,[POINT 8,MESAGE]	    ;GET POINTER BACK
	ILDB	S1,T1			    ;RETURN THE BYTE
ACK:	CAIN	S1,.QEACK		    ;IS IT THE RIGHT INDEX?
	$RET				    ;YES, 
	AOS	SNDERR			    ;NO, SET SEND ERROR
	$RETF				    ;AND RETURN FAILURE
SUBTTL	OPENIT	Open file for moving to target node

;ACCEPTS	J/ ADDRESS OF THIS JOB
;		FPPNT/ CURRENT FILE PARAMETER POINTER

OPENIT:	MOVE	E,FPPNT			    ;GET POINTER[11]
	LOAD	S2,.FPLEN(E),FP.LEN    	    ;GET FP LENGTH
	ADD	E,S2			    ;POINT TO FD[11]
OPEN0:	HRROI	S2,.FDFIL(E)		    ;POINTER TO FILE SPEC[11]
	MOVX	S1,<GJ%SHT!GJ%OLD>	    ;HAS TO BE THERE
	GTJFN%				    ;GET IT
	 JRST	JFNERR			    ;FAILURE[15]
	MOVEM	S1,FILJFN		    ;SAVE THE FILE JFN
	HRRZ	S1,S1			    ;KEEP RIGHT HALF
	MOVE	S2,[FLD(36,OF%BSZ)+OF%RD]   ;READ IS ALL I NEED
	OPENF%				    ;OPEN IT UP
	 JRST	OPEN1			    ;FLAG AS NOT THERE[4]
	MOVE	S1,FILJFN		    ;GET FILE JFN[9]
	MOVSI	S2,2			    ;GET 2 WORDS <2,,0>[9]
	HRRI	S2,.FBBYV		    ;WORD 11 <2,,11>[9]
	MOVEI	T1,FDB11		    ;ADDR TO STORE IT[9]
	GTFDB%				    ;GET FDB DATA[9]
	 ERJMP	OPEN2			    ;FLAG AS NOT THERE[4]
	LDB	T1,[POINT 6,FDB11,11]	    ;GET BYTE SIZE[9]
	MOVEM	T1,FILBSZ		    ;SAVE IT[9]
	HRRZ	T1,FDB11		    ;GET # OF PAGES[9]
	MOVEM	T1,FILSIZ		    ;SAVE
	LOAD	S2,.FDLEN(E),FD.LEN	    ;GET FD LENGTH[11]
	ADD	E,S2			    ;POINT TO NEXT FP[11]
	MOVEM	E,FPPNT			    ;SAVE UPDATED POINTER[11]
	$RETT
JFNERR:	$CALL	STRMNT			    ;TRY MOUNTING THE STRUCTURE[15]
	JUMPT	OPEN0			    ;SUCCESS! - GET THE JFN AGAIN[15]
					    ;ON FAIL FALL THRU[15]
OPEN1:	SETZM	FILJFN			    ;Clear JFN for close operation[8]
OPEN2:	SETOM	FILSIZ			    ;FLAG AS NON-EXISTENT[4]
	$RETF
SUBTTL	SNDPAG	Send a single (full) page to remote JFN

;Accepts	S1/ page address
;		SBYTS/ # of 36-bit bytes to send (octal,use 1000 for full page)
;Returns	+1 always

	
SNDPAG:	$SAVE	<P1,P2>			    ;SAVE THESE, IDIVI REM. IN P2[9]
	MOVE	P1,SBYTS		    ;# OF BYTES[9]
	IMULI	P1,44			    ;CALC # OF...[9]
	IDIVI	P1,10			    ;8-BIT WORDS[9]
	ADDI	P1,4			    ;ADD MSGWRD[9]
	MOVEM	P1,SNDCNT		    ;SAVE IT[9]
	MOVN	P1,SBYTS		    ;GET NEG # OF BYTES[9]
	MOVEM	P1,SBYTS		    ;SAVE IT[9]
	MOVS	P1,SBYTS		    ;GET # OF BYTES[9]
	HRR	P1,S1			    ;GET ADDRESS ARG PAGE
	MOVE	S2,[POINT 8, TRNBUF]	    ;POINTER IN 8 BIT BYTES
	MOVEM	S2,TRNPNT		    ;STORE FOR PUTBCT
	MOVEI	S1,0			    ;GET A ZERO
	MOVEM	S1,BITCNT		    ;STORE FOR PUTBCT
SNDPA1:	MOVE	S1,0(P1)		    ;PICK UP WORD
	MOVEI	S2,^D36			    ;36 BIT WORDS
	$CALL	PUTBCT			    ;TRANSFER THE WORD
	AOBJN	P1,SNDPA1		    ;AND THE NEXT
SNDPA2:	MOVE	S1,LLJFN		    ;GET TARGET NODE
	MOVE	S2,[POINT 8,MSGWRD]	    ;POINT TO WHOLE MESSAGE
	MOVN	T1,SNDCNT 		    ;SEND 1001 WORDS
	SOUTR%				    ;SEND IT
	 ERCAL	DIE
	MOVEI	S1,TRNSIZ+1		    ;SIZE OF TRANSFER BUFFER
	MOVEI	S2,MSGWRD		    ;LOCATION
	$CALL	.ZCHNK			    ;DONE WITH IT FOR NOW
;	MOVE	S1,INPAGE		    ;DONE WITH THIS ONE SO,
;	$CALL	M%RELP			    ;GIVE THE PAGE BACK
;	$CALL	M%ACQP			    ;GET PAGE FOR
;	MOVEM	S1,INPAGE		    ;THE INPUT BUFFER
;	PG2ADR	S1			    ;MAKE IT AN ADDRESS
;	MOVEM	S1,INADDR		    ;AND STORE THAT TOO
	$RETT				    ;GO BACK


	
SUBTTL	PUTBCT	Store image bit stream in 8 bit message

;Accepts	S1/ right justified byte
;		S2/ byte size - ^d36

PUTBCT:	$SAVE	<T1,T2>			;Need these for later.
	SKIPN	T1,BITCNT		;Any residual bitcount?
	JRST	PUTBC1			;No..start at byte boundry
	HLLZ	T2,BCTADJ		;Yes..get pointer adjustment
	ADD	T2,TRNPNT		;Point to residual bits
	DPB	S1,T2			;Store them
	SUB	S2,T1			;Get bits remaining in S1
	JUMPLE	S2,PUTBC4		;All done?
	MOVN	T1,T1			;No..get shift right value
	LSH	S1,0(T1)		;Right justify remaining bits
PUTBC1:	IDIVI	S2,^D8			;Get S2 bytecount T1 bitcount
	JUMPE	S2,PUTBC3		;Any full bytes to send?
PUTBC2:	IDPB	S1,TRNPNT		;Yes..store a byte
	LSH	S1,-^D8			;Get next byte
	SOJG	S2,PUTBC2		;Do them all
PUTBC3:	JUMPE	T1,PUTBC4		;Any odd bits?
	IDPB	S1,TRNPNT		;Yes..store them
	HRRE	S2,BCTADJ		;Get negitive bitcount
PUTBC4:	MOVNM	S2,BITCNT		;Save the bitcount
	$RETT				;All finished

BCTADJ:	037400,,-4			;Pointer adjust,,-bitcount

SUBTTL	CANQUE	Cancel queue entry

;SEND MESSAGE TO QUASAR TO CANCEL A MASTER QUEUE ENTRY

CANQUE:	MOVE	S1,.EQRID(J)		    ;GET THE REQUEST ID
	MOVEM	S1,KIL.MS+KIL.RQ+.RDBRQ     ;SAVE IN KILL MESSAGE
	MOVEI	S1,SAB.SZ		    ;LENGTH OF ARG BLOCK
	MOVEI	S2,QUESAB		    ;LOCATION OF ARGS
	$CALL	C%SEND			    ;SEND TO QUASAR
	 JUMPF	[$FATAL ( Can't send KILL to QUASAR - ,^E[-1]/)]
	$CALL	C%BRCV			    ;WAIT FOR RESPONSE
	$RET
SUBTTL	FILDIS	Keep/Delete printed spool files


FILDIS:	$SAVE	<T1,T2>			    ;SAVE THE TEMPS
	SKIPN	FILJFN			    ;IF THERE'S NO FILE
	 $RETT				    ;JUST RETURN
	MOVE	S2,INPAGE		    ;PAGE OF FILE
	HRLI	S2,.FHSLF		    ;FORK HANDLE OF SELF
	SETOM	S1			    ;SAY TO UNMAP
	MOVX	T1,PM%CNT		    ;WITH A COUNT OF
	HRRI	T1,1			    ;ONE
	PMAP%				    ;UNMAP IT
	LOAD	E,.EQLEN(J),EQ.LOH	    ;GET THE HEADER LENGTH.
	ADD	E,J			    ;POINT TO FIRST FILE.
	MOVE	S1,FILJFN		    ;GET JFN
	TXO	S1,CO%NRJ		    ;SAY TO KEEP IT ON CLOSE
	CLOSF%				    ;CLOSE NO MATTER WHAT
	 ERCAL	DIE			    ;FATAL OUT IF ERROR
FILD.1:	SKIPE	SNDERR			    ;ERROR IN SENDING?
	 JRST	FILD.4			    ;YES - JUST RELEASE IT
	MOVE	T2,.FPINF(E)		    ;GET THE FILE INFO BITS.
	LOAD	S2,.FPLEN(E),FP.LEN	    ;GET THE FILE INFO LENGTH.
	LOAD	S1,.EQSEQ(J),EQ.PRV	    ;GET THE USERS PRIVILGE BITS
	JUMPN	S1,FILD.2		    ;IF SET, AVOID ACCESS CHECK
	TXNE	T2,FP.SPL		    ;WAS IT A SPOOLED FILE ???
	JRST	FILD.3			    ;YES,,THEN NO ACCESS CHECK
	HRROI	S1,.EQOWN(J)		    ;GET THE OWNERS NAME
	MOVEM	S1,CKAARG+.CKALD	    ;AND SAVE IT[16]
	HRROI	S1,.EQCON(J)		    ;GET CONNECTED DIRECTORY
	MOVEM	S1,CKAARG+.CKACD	    ;SAVE IT[16]
	MOVE	S1,FILJFN		    ;GET JFN FOR CHKAC
	MOVEM	S1,CKAARG+.CKAUD	    ;SAVE IT[16]
	MOVEI	S1,6			    ;LENGTH OF CKAARG
	TXO	S1,CK%JFN		    ;SAY WE HAVE JFN IN .CKAUD
	MOVEI	S2,CKAARG		    ;POINT TO CHKAC ARG BLOCK
	CHKAC%				    ;CHECK RIGHTS
	 JRST	FILD.4			    ;NO RIGHTS - RELEASE AND RETURN
FILD.2:	TXNN	T2,FP.DEL		    ;/delete?
	JRST	FILD.4			    ;NO - RELEASE AND RETURN
FILD.3:	MOVE	S1,FILJFN		    ;JFN FOR THE DELETE
	DELF%				    ;DO THE DELETE
	 JRST	FILD.4			    ;ERR - JUST RELEASE JFN
	SETZM	FILJFN			    ;CLEAR JFN WORD
FILD.4:	SKIPN	FILJFN			    ;STILL HAVE A JFN?
	 $RET				    ;NO - ALL DONE
	MOVE	S1,FILJFN		    ;STIL HAVE JFN - RETREIVE IT
	RLJFN%				    ;AND RELEASE IT
	 JRST	.+1			    ;IGNORE ERRORS
	$RET				    ;RETURN.
SUBTTL	LLCLOS	Routine to close or abort a logical link


LLCLOS:	SKIPN	LLJFN			    ;Is link open?
	$CALL	[$FATAL	(Logical link is not open in LLCLOS)]
	HRLI	S2,0			    ;NO ERRORS
	HRRI	S2,.MOCLZ		    ;Get the close function
	MOVE	S1,LLJFN		    ;Get the JFN
	SETZB	T1,T2			    ;No additional data[14]
	MTOPR%
	 ERJMP	LLCLS3			    ;Abort if MTOPR fails
	JRST	LLCLS4			    ;OTHERWISE GO CLOSE NORMALLY
LLCLS3:	MOVE	S1,LLJFN		    ;GET THE JFN
	TXO	S1,CZ%ABT		    ;Set bit for close
	CLOSF%				    ;and be sure.
	 ERCAL	[$FATAL (Can't abort close logical link in LLCLOS - ,^E/[-2]/)]
	SETZM	LLJFN			    ;clear the JFN
	$RETT				    ;done.
LLCLS4:	MOVE	S1,LLJFN		    ;Pick up JFN
	CLOSF%
	 JRST	LLCLS3			    ;keep trying
	SETZM	LLJFN			    ;Clear JFN word
	$RETT
SUBTTL	SNDINT	Send interrupt message to server (RMTSPL)

;ACCEPTS - T1/MESSAGE NUMBER RIGHT JUSTIFIED IN FIRST 8 BITS
;	      WITH ANY ADDITIONAL DATA IN NEXT 3 BYTES

;SNDINT:	$SAVE	<T2>			    ;NEED ABOVE - BETTER KEEP
;	MOVEI	T2,4			    ;ONLY ONE WORD ALWAYS
;	MOVE	S1,LLJFN		    ;THE NETWORK LINE
;	MOVEI	S2,.MOSIM		    ;SENDING A MESSAGE
;	MTOPR%				    ;SEND IT
;	 ERCAL	DIE			    ;MUST GO
;	$RETT

SUBTTL	RELJFN	Routine to release all non-open JFNS


;CLSJFN::SKIPA	S1,[EXP CZ%ABT!.FHSLF]	    ;ABORT ALL FILE OPERATIONS
RELJFN::MOVX	S1,CZ%NCL!.FHSLF	    ;RELEASE ALL NON-OPEN JFNS
	CLZFF%
	 ERJMP	.+1			    ;Ignore any errors
	$RETT				    ;RETURN
SUBTTL STRMNT Routine to mount the structure of the current file[15]

;ACCEPTS	E/ address of FD of current file

STRMNT:	MOVE	S1,[POINT 7,.FDSTG(E)]	    ;POINT TO THE STRUCTURE
	MOVE	S2,[POINT 7,STRBLK+1]	    ;WHERE TO PUT IT
STRMOV:	ILDB	T1,S1			    ;GET A CHAR
	IDPB	T1,S2			    ;STORE IT
	CAIE	T1,":"			    ;DONE?
	JRST	STRMOV			    ;NOPE - LOOP
STRARG:	HRLI	S1,1			    ;LENGTH OF ARGBLK
	HRRI	S1,.MSIMC		    ;INCR THE MOUNT COUNT FOR THIS JOB
	HRROI	S2,STRBLK+1		    ;GET -1,,ADDRRESS OF STRING
	MOVEM	S2,STRBLK		    ;SAVE IT
	MOVEI	S2,STRBLK		    ;POINT TO STR STRING
	MSTR%				    ;MOUNT IT
	 ERJMP	MNTERR			    ;FAILURE
	$RETT				    ;RETURN SUCCESS
MNTERR:	$RETF				    ;RETURN FAILURE
SUBTTL	Interrupt tables

LEVTAB:	LEV1PC				    ;ONLY NEED ONE LEVEL
	EXP	0
	EXP	0


CHNTAB:					    ;CHANNEL TABLE
ICHCND:	1,,INTCDN			    ;CONNECT/DISCONNECT
ICHINA:	1,,INTINA			    ;INTERRUPT MESSAGE
ICHDAV:	1,,INTDAV			    ;DATA AVAILABLE
BLANK:	BLOCK 15
ICHIMR:	1,,INTIMR			    ;ILLEGAL MEMORY READ[5]
ICHRST:	BLOCK	CHNTAB+^D36-.		    ;FILL IT OUT

SUBTTL	INTCDN	Connect/Disconnect interrupt

INTCDN:	$BGINT	(1)
	$DEBRK

SUBTTL	INTINA	Interrupt message handler

INTINA:	$BGINT	(1)
	MOVE	S1,LLJFN		    ;GET JFN OF CURRENT REMOTE NODE
	MOVEI	S2,.MORIM		    ;READ INTERRPT MESSAGE
	MOVE	T1,[POINT 8,MESAGE]	    ;STORE MESSAGE HERE
	MTOPR%				    ;GET IT
	 ERCAL	DIE			    ;OH NO...
	$DEBRK

SUBTTL	INTDAV	Data available from network

INTDAV:	$BGINT	(1)
	$DEBRK

SUBTTL	INTIMR	Illegal memory read[5]

INTIMR:	$BGINT	(1)
	AOS	TRPCNT			    ;COUNT THE ERROR
	MOVE	S1,TRPCNT		    ;RETRIEVE THAT COUNT
	CAIL	S1,^D10			    ;TRY TEN TIMES
	$STOP (MRE, Memory Read Error ^O/LEV1PC/) ;TOO MANY TIMES, STOP
	MOVEI	S1,^D1000		    ;WAIT 1 SECOND[7]
	DISMS%				    ;FOR USE OF MEMORY
	SETZM	S1			    ;CLEAR IN CASE...
	$DEBRK
SUBTTL	Table of NSP disconnect reasons

DEFINE DISCR <
	ER	(0,No error)
	ER	(1,Resource allocation failure)
	ER	(2,Target node does not exist)
	ER	(3,Node shutting down)
	ER	(4,Target task does not exist)
	ER	(5,Invalid name field)
	ER	(6,Target task queue overflow)
	ER	(7,Unspecified error condition)
	ER	(8,Third party aborted the logical link)
	ER	(9,<User abort (asynchronous disconnect)>)
	ER	(24,Flow control failure)
	ER	(32,Too many connections to node)
	ER	(33,Too many connections to target task)
	ER	(34,Access not permitted)
	ER	(35,Logical link Services mismatch)
	ER	(36,Invalid account)
	ER	(37,Segment size too small)
	ER	(38,<User aborted, timed out, or canceled link>)
	ER	(39,No path to target node)
	ER	(40,Flow control violation)
	ER	(41,No current link to target node)
	ER	(42,Confirmation of Disconnect Initiate)
	ER	(43,Image data field too long)
>					    ;END DISCR DEFINITION

DEFINE ER (VALUE,TXT) <
	.DCX'VALUE==^D'VALUE
	IFDEF %%CUR,<%%DIF==^D'VALUE-%%CUR-1>
	IFNDEF %%CUR,<
		%%CUR==0
		%%DIF==^D'VALUE>
	IFG %%DIF,<REPEAT %%DIF,<[ASCIZ\Unknown\]>>
	[ASCIZ\TXT\]
	%%CUR==^D'VALUE
>					    ;END OF ER DEFINITION

DSCTBL:	DISCR				    ;GENERATE TABLE OF REASONS
	DSCMAX==.-DSCTBL-1
	PURGE	%%CUR,%%DIF
SUBTTL	Inpure storage


;STORAGE AREAS


	$DATA	INPAGE			    ;PAGE # OF INPUT BUFFER
	$DATA	INADDR			    ;MAKE PAGE # INTO ADDRESS
	$DATA	MSGWRD			    ;MESSAGE STATUS/TYPE WORD
	$DATA	TRNBUF,TRNSIZ		    ;TRANSFER AREA
	$DATA	NODTBL,MAXNOD		    ;TABLE BAD NODE NAMES
	$DATA	NODTLN			    ;CURRENT COUNT OF BAD NODES
	$DATA	CHKCNT			    ;COUNT OF TIMES THROUGH LOOP
	$DATA	PDL,PDLEN		    ;OUR STACK
	$DATA	LEV1PC,1		    ;AND INTERRUPT STACK POINTER
	$DATA	MQFJFN			    ;JFN OF MASTER QUEUE FILE
	$DATA	FOUND			    ;DID WE FIND ENTRY TO MOVE?
	$DATA	SNDERR			    ;WAS THERE AND ERROR IN SENDING QE
	$DATA	INDTAB,FSSMNS		    ;INDEX LOC FOR EACH SECTION
	$DATA	SECCNT			    ;NUMBER OF SECTIONS IN THIS MQF
	$DATA	BLKCNT			    ;COUNT THE BLOCKS IN THIS FILE
	$DATA	QERCNT			    ;COUNT OF QUEUE ENTRY REQUESTS
	$DATA	INDEX			    ;ADDRESS OF CURRENT INDEX
	$DATA	BASE			    ;ADJUST FOR LARGE MQFILE
	$DATA	MQPAGE			    ;PAGE # OF CURRENT REQUEST 
	$DATA	LOCNOD			    ;LOCAL ASCIZ NODE NAME
	$DATA	TONODE			    ;ASCIZ NAME OF REMOTE NODE
	$DATA	LLNAME,^D45		    ;STRING FOR LINK NAME
	$DATA	LLJFN			    ;JFN OF LOGICAL LINK
	$DATA	LLSTAT			    ;STATUS OF LOGICAL LINK
	$DATA	LLDISC,20		    ;Disconnect cause stored here
	$DATA	FILJFN			    ;JFN OF PRINT FILE
	$DATA	FDB11			    ;FDB WORD 11 STORAGE[9]
	$DATA	FILBYT			    ;FDB WORD 12, # BYTES IN FILE[9]
	$DATA	FILSIZ			    ;SIZE OF INPUT FILE
	$DATA	FILBSZ			    ;FILE BYTE SIZE[9]
	$DATA	TRNPNT			    ;BYTE POINTER TO TRANSFER AREA
	$DATA	BITCNT			    ;COUNT OF LEFTOVER BITS
	$DATA	MESAGE			    ;INCOMING MESSAGE BUFFER
	$DATA	INTMSG			    ;OUTGOING MESSAGE BUFFER
	$DATA	TRPCNT			    ;COUNT OF PROBLEMS
	$DATA	SBYTS			    ;# OF BYTES FOR SNDPAG[9]
	$DATA	SNDCNT			    ;CALC # OF 8-BIT WORDS IN SNDPAG[9]
	$DATA	FILES			    ;# OF FILES TO SEND[11]
	$DATA	FPPNT			    ;FILE PARAMETER POINTER[11]
	$DATA	STRBLK,2		    ;STORE STRUCTURE FOR MOUNTING[15]



DIE:	$FATAL ( Unknown error - ,^E/[-2]/)	    ;LAST TOPS-20




	END	<EVECL,,QUEVEC>