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>