Trailing-Edge
-
PDP-10 Archives
-
tops10_703a_sys_atpch16_bb-fr67f-bb
-
glxipc.x16
There are 2 other files named glxipc.x16 in the archive. Click here to see a list.
TITLE GLXIPC -- IPCF INTERFACE FOR GALAXY PROGRAMS
SUBTTL Cliff Romash & Irwin L. Goverman/CER/PJT/DC/MLB/RCB 25-Aug-84
;
;
; COPYRIGHT (c) 1975,1976,1977,1978,1979,1980,1981,1982,
; 1983,1984,1985,1986,1987
; DIGITAL EQUIPMENT CORPORATION
; ALL RIGHTS RESERVED.
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE
; AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS
; SOFTWARE OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR
; OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO
; AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE
; WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT
; BY DIGITAL EQUIPMENT CORPORATION.
;
; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
; OF ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY
; DIGITAL.
SEARCH GLXMAC ;SEARCH SUBSYSTEMS SYMBOLS
PROLOG(GLXIPC,IPC) ;PRODUCE PROLOG CODE
;THE PURPOSE OF THIS MODULE IS TO PROVIDE AN OPERATING SYSTEM INDEPENDENT
; IPCF INTERFACE TO GALAXY PROGRAMS (OR ANY OTHER PROGRAM WHICH
; WANTS TO USE IT).
;ALL SUBROUTINES IN THIS MODULE USE ACS S1 AND S2 (1 AND 2) AND GUARANTEE
; THAT ALL OTHER ACS WILL BE PRESERVED.
IPCEDT==76 ;VERSION NUMBER
SUBTTL Table of contents
; TABLE OF CONTENTS FOR GLXIPC
;
;
; SECTION PAGE
; 1. Table of contents......................................... 2
; 2. Revision History.......................................... 3
; 3. Entry Points found in GLXIPC.............................. 4
; 4. Global Storage............................................ 5
; 5. C%INIT - Initialize the IPCF interface.................... 6
; 6. C%CPID - Create a PID..................................... 6
; 7. CHKNAM - See if PIB has a name attached................... 10
; 8. CHKAND - Check PIB to see if account and node pointers specified 10
; 9. C%KPID, C%SPID............................................ 11
; 10. C%SEND Routine to send an IPCF Message.................... 12
; 11. SNDMSG - Work routine to do actual IPCF send.............. 14
; 12. C%INTR - Interrupt level routine to flag message available 16
; 13. C%RECV - Non-blocking IPCF receive........................ 16
; 14. C%BRCV - Blocking IPCF Receive............................ 16
; 15. RCVMSG - Work routine to do an actual IPCF receive........ 17
; 16. C%REL - Release the last message received................ 20
; 17. C%RPRM Routine to read IPCF Parameters................... 20
; 18. GETPID - Acquire a PID for this job....................... 21
; 19. KILPID Routine to delete a pid........................... 22
; 20. SPID - Set a system PID................................. 23
; 21. RSPIDS Routine to read System Pid tables................. 24
; 22. RSPID Routine to return a system pid...................... 25
; 23. C%MAXP - Read maximum short packet size.................. 27
; 24. CPIDI - Connect PID to specified interrupt channel....... 28
; 25. IPRM Read/Write IPCF parameters........................... 29
; 26. MNPRED/MNPWRT - Read/Write maximum number of PIDS......... 30
; 27. QTARED/QTAWRT - Read/Write the Send and Receive Quotas.... 31
; 28. SETNAM - Routine to declare our name to INFO.............. 32
; 29. SNDSYS - Routine to converse with [SYSTEM]INFO & IPCC..... 33
; 30. STAC - Routine to build INFO messages................... 35
; 31. C%PIDJ Returb PID owners job number...................... 36
SUBTTL Revision History
COMMENT \
Edit GCO Reason
---- ------- -------------------------------------------------------
0001 Initial version of GLXIPC
0002 Make sending to PID 0 illegal
0003 Convert to new OTS format
0004 Add better send failure recovery code
Also, receive packets .GT. short packet size if they come
0005 G012 Change the definition of the 'capabilties' word in the MDB
to contain a canonical set of capabilities rather than the
operating-system specific capabilities. It also contains
the senders job number.
0006 G016 On the -10, don't try to determine the length of the System
PID table before doing the GETTABs. Just do SZ.PID GETTABs.
0007 Change the debugging system so that 'alternates' are used
only if DEBUGW is set.
0010 G025 Change the DEBUGW so that a non-zero value enables
the DEBUGGING System while a negative value will
declare a private component to SYSTEM[INFO].
Also fix C%RECV so that MD%PWH is only turned on with
JACCT on the -10.
0011 G026 FIX RSEFLG ACTION TO RETURN ON ERRORS AND LOOP THE
PROPER NUMBER OF TIMES IF NOT SET
0012 G027 MAKE C%RECV USE THE ASSOCIATED VARIABLE NAD DO PAGE
CHECK FIRST
0013 G052 Fix C%RECV to Destroy non-existent page if failed on
page mode due to wrong mode
0014 Remove DEBUGW test to set quotas and job wide pid
Also -- convert some$STOP messages to $FATAL and
some $TEXT to $WARN
0015 Made extensive changes to Debugging code and initializtion
code. Added error code ERICA$ to use in range checks.
Modified RSPIDS to do alternate search based on DEBUGW
and a special name table.
Modified C%SEND to clear the internal pid table entry
if a send to a system pid fails.
0016 Fixed TOPS20 code in KILPID and SNDSYS to work properly
0017 Fixed SNDSYS to save SNDFLG
0020 Cosmetic cleanup. Changed ERICA$ to ERARG$ for
errors which are caused by bad calling args.
Corrected spelling.
Added "PULSAR" name for SP.TLP
0021 Use SPIDS macro to make up SPDNAM
0022 Change C%INIT to setup debugging names based on SPIDS,
Not on contents of the IB
The degugging flag DEBUGW (135) now has 2, not 3 meanings
0== off, -1 == on. If it is ON, and the IB says to become
a system PID, then C%INIT uses the name in the SPIDS table
to declare [p,pn]NAME to system info
0023 Install PIB and multiple PID support
0024 Print Becomming PID message only if Debugging. Make getting
of maximum packet size a Library entry Point (C%MAXP)
0025 Make getting maximum packet size a part of C%INIT
even if no PIB is specified in IB
0026 Preserve RCVMDB+MDB.MS durring SNDSYS so C%REL will
always work after sending to a system component in
in DEBUG mode
0027 Make C%PIDJ entry to return Pid's job number
0030 Make C%KPID work for -10. Kill named PIDs via INFO only,
and unnamed PIDs via IPCC, then INFO if that fails.
0031 Fix setting of Maximum number of Pids to first
Read the number then increment and write it out
0032 Change SAVE to $SAVE
0033 Fix Maximum PID setting Bug
0034 Make MAXPAK a global variable
0035 Return ARG if sending a 0 length message
0036 Return ARG if attempting to SNDMSG with a 0 PID
0037 TOPS10 - Set job # as PID when conversing with
INFO or IPCC to get a PID.
0040 Write system PID table after setting MYPID
0041 Fix a bug in wait logic if debugging and the component
does not yet exist.
0042 -10, Set Job number as PID
while asking INFO for PIDs of debugging
system components
0043 CHANGE THE SEND QUOTA SETTINGS TO READ THE CURRENT
SETTING AND THEN ADD TO IT
0044 Add support for sending to any arbitrary process
by name.
Never send pages to the system gopher, send them
as large (510 wd max) packets.
0045 Just a recompile to pick up new value for SZ.PAK
0046 Return the located node if requested in PIB block for
TOPS10.
0047 Zero out out own $DATA space and comment out instructions
that used to zero out particular locations.
0050 If no IPCF privs and SYSINF not running then $FATAL error
0051 Set OPR priv in C%RECV if message received from a special
pid while debugging.
0052 Add support for using job numbers as PIDs.
0053 Fix a problem with SNDSYS flushing the IPCF queue looking
for the response from [SYSTEM]IPCC.
0054 Only type out "% GLXIPC alternate..." when debugging.
0055 Prevent IFN, BPN, and ILM stopcodes. Routine STAC IDPBs 1
byte too far.
0056 Fix bug in SNDSYS which caused MDA's pid to not be defined.
0057 FIX IPRM.1 TO DO THE CORRECT THING FOR BOTH TOPS10
AND TOPS20.
0060 3/7/81 Change reference to .JBOPS to the general symbol DEBUGW
0061 9/14/81 Fix FNDNAM bug and make sure we always return the PID in S1
0062 12/15/81 Handle error return from M%IPRM.
0063 1372 Prevent unprived user from becoming godly by clearing junk in
AC before setting up priv bits in MDB.PV
0064 G1394 Insure all messages get received by setting MSGFLG early.
0065 8-Feb-84 /DPM
Increased monitor free core usage could be attributed to
the fact that GLXIPC always sends 510 word packets to the
GOPHER. Make it send exact length packets instead.
0066 10055 26-Mar-84 /DPM
Add support for flag word in the SAB and return useful
priv bits.
0067 10079 14-Aug-84 /RCB
Include new IPCFM. code for efficient use under 7.03.
0070 10084 28-Aug-84 /RCB
Include fallback code for 7.02, and finish the IPCFM. code
for talking to [SYSTEM]INFO.
0071 10095 11-Sep-84 /RCB
Fix the fallback code.
0072 10261 23-Jul-85 /RCB
Fix more fallback code (GETTAB of .GTPID).
0073 10267 30-Jul-85 /RCB
More of above (%IPCPM).
0074 10307 22-Oct-85 /RCB
Fix some FTFLBK problems.
0076 10462 14-Nov-86 /BAH
Change $STOP to STOPCD.
\ ;END OF REVISION HISTORY
SUBTTL Entry Points found in GLXIPC
ENTRY C%INIT ;INITIALIZE THE MODULE
ENTRY C%CPID ;CREATE A PID
ENTRY C%SPID ;SET DEFAULT SENDER PID
ENTRY C%KPID ;KILL A PID
ENTRY C%RPRM ;READ IPCF PARAMETERS
ENTRY C%INTR ;POST AN IPCF INTERRUPT
ENTRY C%SEND ;SEND AN IPCF MESSAGE
ENTRY C%RECV ;NON-BLOCKING IPCF RECEIVE
ENTRY C%BRCV ;BLOCKING IPCF RECEIVE
ENTRY C%REL ;RELEASE LAST IPCF MESSAGE
ENTRY C%MAXP ;MAX PACKET SIZE ENTRY POINT
ENTRY C%PIDJ ;RETURN PID OWNERS JOB NUMBER
ENTRY C%PIDH ;RETURN PID OWNER'S JCH
ENTRY C%SIDX ;RETURN SYSTEM INDEX FOR PID
SUBTTL Global Storage
$DATA IPCBEG,0 ;START OF ZEROABLE $DATA SPACE
$GDATA MYPID ;PROCESS IDENTIFIER
$DATA DEFPID ;Default (ie first) PID
$DATA FSTPFG ;Set after we define first PID
$GDATA IMOPR ;Set if we are ORION
$DATA PSIFLG ;FLAG SET IF IPCF IS CONNECT TO PSI SYSTEM
$DATA SNDFLG ;FLAGS TO USE FOR SEND
$DATA RCVFLG ;FLAGS TO USE FOR RECIEVE
$DATA RCVPAG ;PAGSIZ,,PAGADR RESERVED FOR RECV
$DATA MSGFLG ;SET AT INTERRUPT LEVEL (IF PSI USED)
$GDATA RSEFLG ;RETURN SEND ERROR FLAG
$DATA IPCINT ;INTERRUPT ADDRESS FOR IPCF STATUS
$DATA IPCSTS ;IPCF STATUS..ASSOCIATED VARIABLE
$DATA PIDTAB,SZ.PID ;TABLE OF SYSTEM PIDS
$DATA ALTNAM,SZ.PID ;Table of alternate names for system
;components. Debuggers can poke
;a slot to -1 to force a debugging library
;to talk to that system component.
;Or, the address of an ASCIZ string can
;be poked in to force a debugging
;library to talk to that named component
;instead of the standard library
;debugging conventions.
$DATA STACP ;BYTE POINTER FOR NAME CREATION
$DATA STACL ;MAX CHARACTER LIMIT FOR NAMED PIDS
MTLSIZ==SZ.INF/5+3 ;MAXIMUM PACKET SIZE FOR INFO NAMES
$DATA MTLBLK,MTLSIZ ;IPCFM BLOCK
SYSPRM (IPCSLN,4,.IPCFP+1) ;Length of a send block
SYSPRM (IPCRLN,.IPCFC+1,.IPCLL+1) ;Length of a receive block
$DATA SNDBLK,IPCSLN ;IPCF SEND PACKET DESCRIPTOR BLOCK
$DATA RCVBLK,IPCRLN ;IPCF RECEIVE PDB
$DATA SNDSAB,SAB.SZ ;PLACE TO BUILD A SAB INTO
$DATA RCVMDB,MDB.SZ ;PLACE TO BUILD MDB INTO
$DATA ACTPTR ;POINTER TO USER AREA FOR ACCT STRING
$DATA NODPTR ;POINTER TO USER AREA FOR NODE STRING
$DATA PACKET,SZ.PAK ;PLACE TO RECEIVE SHORT MESSAGE INTO
IFN FTFLBK,<
$DATA QUELOK ;LOCK FOR THE INTERNAL IPCF QUEUE
$DATA IPCQUE ;LINK LIST ID OF THE INTERNAL IPCF QUEUE
$DATA OLDMON ;MONITOR WITHOUT IPCFM. UUO
$DATA NEWSID ;NEW SYSTEM PID UNDER OLD MONITOR
$DATA MAXSID ;MAXIMUM SYSTEM PID KNOWN TO MONITOR
>
$DATA OPRPPN ;PPN OF THE OPERATOR
$DATA MNTPPN ;PPN FOR MAINT PRIVS
$DATA IPCEND,0 ;END OF ZEROABLE $DATA SPACE
;SPDNAM TABLE TO SETUP SEARCH FOR SPECIAL SYSTEM PIDS BY NAME
DEFINE .SPID(CANNAM,T10IDX,T20IDX,SYMNAM),<
IFNB <SYMNAM>,<
$SET (CANNAM,,<-1,,[ASCIZ/SYMNAM/]>)
>;;END IFNB SYMNAM
>;End DEFINE .SPID
SPDNAM: $BUILD (SZ.PID)
SPIDS ;Generate the Special names
$EOB
; INDIRECT TEXT STRINGS TO USE FOR BUILDING INFO NAME
NAMTXT: ITEXT(<^U/DEBUGW/^Q/S1/>) ;OUR NAME+CUSP
SYSTXT: ITEXT(<[SYSTEM]^Q/S1/>) ;SYSTEM NAME+CUSP
DEFINE $SLEEP(TIME),<
XLIST
MOVEI S1,TIME ;;GET THE TIME TO SLEEP IN SECONDS
SLEEP S1, ;;GO TO SLEEP
LIST>
SUBTTL C%INIT - Initialize the IPCF interface
; Initializes IPCF interface, acquires PID and does alternate search.
;CALL IS: IIB setup by I%INI1 in GLXINT
;TRUE RETURN: Always, PID stored in the IIB
C%INIT: MOVE S1,[IPCBEG,,IPCBEG+1] ;BLT PTR TO ZEROABLE $DATA SPACE
SETZM IPCBEG ;ZERO THE FIRST LOC
BLT S1,IPCEND-1 ;AND DO THE REST WITH A BLT
IFN FTFLBK,<
MOVE S1,[%CNDAE] ;MONITOR VERSION GETTAB
GETTAB S1, ;FIND IT
SETZ S1, ;NOT THERE?!?
HRRZS S1 ;ISOLATE BINARY VERSION
CAIGE S1,703 ;DOES THIS MONITOR HAVE IPCFM.?
SETOM OLDMON ;NO, REMEMBER THAT IT'S OLD
MOVE S1,[.GTSID,,.GTIDX] ;INDEXING INFO FOR SYSTEM PID TABLE
GETTAB S1, ;FETCH IT
SETZ S1, ;SHOULDN'T GET HERE
HRREM S1,MAXSID ;SAVE FOR SYSINF CHECKING
>
SETOM ALTNAM+SP.IPC ;ALWAYS USE REAL IPCC
SETOM ALTNAM+SP.GFR ;AND THE REAL GOPHER
IFN FTFLBK,<
SKIPE OLDMON ;IS IT AN OLD MONITOR?
SETOM ALTNAM+SP.INF ;YES, ALWAYS USE REAL SYSTEM INFO
>
SKIPN S2,IIB##+IB.PIB ;Does the caller want to use IPCF?
$RETT ;No, nothing to do here!
LOAD S1,PB.HDR(S2),PB.LEN ;Yes, get length of block in S1
PUSHJ P,C%CPID ;Get the PID
$RETIT ;OK
STOPCD (CGP,HALT,,<Can't Get a PID>)
SUBTTL C%CPID - Create a PID
;This routine will create a PID, give it a name, connect it to
; the interrupt system, set its quotas, etc, etc, based on the PIB passed.
;Arguments:
; S1-Length of block
; S2-Addr of PIB
;Returns:
; True, all set
; False, ERARG$ or ERCGP$
C%CPID: CAIL S1,PB.MNS ;Small PIB?
CAILE S1,PB.MXS ;.. or big PIB
$RETE (ARG) ;No good
$SAVE <P1,P2> ;Save some work regs
DMOVE P1,S1 ;Copy the input args
SKIPE FSTPFG ;Has our data base been intialized?
JRST CPID.3 ;Yes, charge on!
SKIPN S2,DEBUGW ;SEE IF DEBUGGING
JRST CPID.2 ;NOPE
JUMPL S2,CPID.1 ;DO THE GETPPN IF NEGATIVE
TLNE S2,377777 ;IF SET ASSUME WE GOT A PPN IN THERE
TRNN S2,-1 ;IF RH, THEN IS OK
CPID.1: GETPPN S2, ;GET THE PPN
JFCL ;INFAMOUS SKIP RETURN
MOVEM S2,DEBUGW ;SAVE UPDATED COPY
CPID.2: SETOM MSGFLG ;SET MESSAGE AVAILABLE FLAG
SETZM SNDFLG ;INIT SEND FLAGS
MOVX S1,IP.TTL ;GET TRUNCATE LONG MESSAGE FLAG
MOVEM S1,RCVFLG ;INIT RECIEVE FLAGS
PUSHJ P,RSPIDS ;READ THE SYSTEM PIDS
MOVX S1,%LDFFA ;WE NEED OPR PPN FOR PRIV CHECK
GETTAB S1, ;SO GET IT
MOVX S1,<1,,2> ;USE A SUITABLE DEFAULT
MOVEM S1,OPRPPN ;SAVE IT
MOVX S1,%LDUMD ;GET MAINTANANCE PPN
GETTAB S1,
MOVX S1,<6,,6>
MOVEM S1,MNTPPN
;C%INIT CONTINUED ON NEXT PAGE
;C%INIT CONTINUED FROM PREVIOUS PAGE
CPID.3: LOAD S2,PB.INT(P2),IP.SPI ;GET REQUESTED INDEX
JUMPE S2,CPID.5 ;JUMP IF WE ARE NOT SYSTEM TO JUST GET A PID
CAXN S2,SP.OPR ;Becoming ORION?
SETOM IMOPR ;Set flag for .STOP
SKIPN S1,PIDTAB(S2) ;IS THERE A PID THERE?
JRST CPID.4 ;NAME NOT THERE -- MUST GET A PID
MOVEM S1,PB.PID(P2) ;Save as ours
PUSHJ P,C%PIDJ ;GET PID'S JOB NUMBER
JUMPF CPID.4 ;NO OWNER -- MUST GET A PID
CAME S1,MYJOB## ;IS IT MINE?
$FATAL (Requested PID belongs to job ^D/S1/) ;NOPE
JRST CPID.8 ;NO NEED TO GET A PID
;We already own that PID
CPID.4: PUSHJ P,SYSPID ;SET UP TO GET A SYSTEM PID
$RETIF ;PROPAGATE FAILURE
JRST CPID.7 ;GOT IT
;Here if we're not becoming a system PID
CPID.5: PUSHJ P,CHKNAM ;Set up name pointers
JUMPT CPID.7 ;All set, use callers name
;otherwise, use noname
CPID.6: SETZ S2, ;Indicate no name desired
CPID.7: PUSHJ P,SETNAM ;Set name in message to IPCC or INFO
LOAD S1,PB.FLG(P2),IP.JWP ;Get desired job-wide flag
PUSHJ P,GETPID ;GET A PID FOR MY JOB
JUMPF [$RETE(CGP)] ;PROPAGATE FAILURE
MOVEM S1,PB.PID(P2) ;SAVE ACQUIRED PID
;C%INIT CONTINUED ON NEXT PAGE
;C%INIT CONTINUED FROM PREVIOUS PAGE
;Here when the PID and requisite name have been set up.
CPID.8: LOAD S2,PB.PID(P2) ;Get back pid
SKIPE FSTPFG ;First time 'round?
JRST CPID.9 ;No, the defaults were set last time
MOVEM S2,DEFPID ;Save as default for -1 to C%SPID
MOVEM S2,MYPID ;That's mine!
SETOM FSTPFG ;Note that we've been here
CPID.9: LOAD S1,PB.INT(P2),IP.SPI ;GET SPECIAL INDEX FIELD
SKIPE S1 ;WANT TO BE SYSTEM PID?
PUSHJ P,SPID ;YES -- GO SET IT
JUMPF [LOAD S1,PB.PID(P2) ;GET PID AGAIN
PUSHJ P,KILPID ;GET RID OF IT
$RETE(CGP)] ;CAN'T GET PID ERROR
SETO S1, ;SET TO WRITE IPCF PARAMETERS
SKIPE S2,PB.SYS(P2) ;GET IPCF PARAMETER WORD
PUSHJ P,IPRM ;MAKE CHANGES
LOAD S1,PB.FLG(P2),IP.RSE ;WANT SEND FAILURES RETURNED?
MOVNM S1,RSEFLG ;SET OR CLEAR THE FLAG
LOAD S1,PB.FLG(P2),IP.SPB ;GET SENDER'S PRIV FLAG
CPID.D:! SKIPN DEBUGW ;DEBUGGING?
STORE S1,RCVFLG,IP.CFP ;NO -- STORE IN RECIEVE FLAGS
LOAD S1,PB.INT(P2),IP.CHN ;GET CHANNEL OR OFFSET FOR PSI
LOAD S2,PB.FLG(P2),IP.PSI ;SEE WHETHER PSI IS TO BE USED
MOVNM S2,PSIFLG ;SET OR CLEAR THE FLAG
LOAD S2,PB.PID(P2) ;Get desired PID
SKIPE PSIFLG ;IS IPCF CONNECTION WANTED?
PUSHJ P,CPIDI ;YES, CONNECT PID TO INTERRUPT SYSTEM
PUSHJ P,CHKAND ;Check out account and node pointers
$RETT ;All done
SUBTTL SYSPID - Helper for C%CPID to set up to acquire a system PID
;Call with no obvious args
;
;Return set up for CPID.7
SYSPID: SKIPN DEBUGW ;Are we debugging?
JRST SYSP.1 ;No, never bother INFO in production
PUSHJ P,CHKNAM ;Set up the name pointer
$RETIT ;All set, caller has special debug name
;Otherwise, set up library convention
LOAD S2,PB.INT(P2),IP.SPI ;Get back special index
SKIPN S1,SPDNAM(S2) ;Get debugging name from table
$FATAL (No debugging name for special index ^O/S2/) ;None there
MOVEI S2,NAMTXT ;Aim at ITEXT to convert debug name
$RETT ;Go setup the name, get the PID
SYSP.1: SETZ S2, ;ASSUME NO NAME DESIRED
IFN FTFLBK,<
SETZM NEWSID ;ALSO ASSUME AN OK SYSTEM PID
LOAD S1,PB.INT(P2),IP.SPI ;GET BACK SPECIAL INDEX
SKIPE OLDMON ;IF GOOD MONITOR,
CAMG S1,MAXSID ;OR IN 7.02 RANGE,
>
$RETT ;RETURN TO SET UP FOR NULL PID
IFN FTFLBK,<
SETOM NEWSID ;NOT AN OK SYSTEM PID
SKIPN S1,SPDNAM(S1) ;DOES IT HAVE A NAME?
$RETE(CGP) ;NO, CAN'T DO IT
MOVEI S2,SYSTXT ;YES, POINT AT ITEXT FOR SYSTEM NAME
$RETT ;RETURN TO SET UP PID
>
SUBTTL CHKNAM - See if PIB has a name attached
;Call - P1/ length of PIB
; P2/ addr of PIB
;Returns - FALSE if PIB is too short or no name pointer in PIB
; TRUE - S1 has pointer, S2 has ITEXT to it (suitable for SETNAM)
CHKNAM: CAILE P1,PB.NAM ;Was a name supplied?
SKIPN S1,PB.NAM(P2) ;Was one?
$RETF ;No, Tell caller there's none
TLCE S1,-1 ;0 left half
TLCN S1,-1 ; or -1 left half?
HRLI S1,(POINT 7,) ;Yes, make a pointer
MOVEI S2,[ITEXT (<^Q/S1/>)] ;Aim at the pointer just built
$RETT ;Return S1,S2 setup
SUBTTL CHKAND - Check PIB to see if account and node pointers specified
;Call - P1/ length of PIB
; P2/ addr of PIB
;Returns - TRUE (always)
CHKAND: CAIG P1,PB.ACT ;Is there an act ptr on the block?
$RETT ;No, quit
SKIPE S1,PB.ACT(P2) ;Get ptr, if any
MOVEM S1,ACTPTR ;Save it if there is one
CAIG P1,PB.LOC ;Is there a logical location pointer
$RETT ;No
SKIPE S1,PB.LOC(P2) ;Maybe, get it
MOVEM S1,NODPTR ;Yes there is, save it
$RETT ;All done
SUBTTL C%KPID, C%SPID
;C%KPID - Kill a PID
; Call - S1/addr of PIB describing PID to be killed
; Return, TRUE - PID has been killed, and removed from system tables
; (if applicable)
; FALSE - PID wasn't killed,perhaps because
; insufficient privs, or no such PID
C%KPID: $SAVE <P1> ;Save work reg
MOVE P1,S1 ;Copy input arg
SKIPN S1,PB.PID(P1) ;Get PID, if any
$RETT ;None there, all done!
LOAD S2,PB.INT(P1),IP.SPI ;Get special PID index
SKIPE S2 ;If special index
SKIPN DEBUGW ; ... and we're debugging,
SKIPA ;(Not special, or not debug) skipa
JRST KPID.N ; ... must be named, kill via INFO
$SAVE <P2> ;Preserve another AC
PUSH P,S1 ;Save PID to be killed
MOVE P2,P1 ;Setup addr of PIB
LOAD P1,PB.HDR(P2),PB.LEN ;Get length of the PIB
PUSHJ P,CHKNAM ;See if this PIB is named
JUMPF [POP P,S1 ;No name, Get back PID
JRST KPID.U] ;And kill it either way
POP P,S1 ;There is a name, must kill via INFO
KPID.N: PUSHJ P,KILPDN ;Kill via INFO
SKIPA ;Reenter common flow
KPID.U: PUSHJ P,KILPID ;Give it the gong
$RETIF ;Couldn't do it
MOVE S2,PB.PID(P1) ;Get back PID just killed
MOVSI S1,-SZ.PID ;Get AOBJN ptr for PIDTAB
KPID.1: CAMN S2,PIDTAB(S1) ;Does this one match?
SETZM PIDTAB(S1) ;Yes, kill it
AOBJN S1,KPID.1 ;Check all the pids in our table
$RETT ;Back to caller
;C%SPID - A routine to set the default send PID
;Call S1/addr of PIB describing new default or -1 to set original default
;Return - TRUE always
C%SPID: SKIPGE S1 ;Skip if a PIB is there, otherwise...
SKIPA S2,DEFPID ;Get original default PID
SKIPE S2,PB.PID(S1) ;Get PID to be set
MOVEM S2,MYPID ;Set as our sender default
$RETT
SUBTTL C%SEND Routine to send an IPCF Message
;CALL S1/ Length of SAB
; S2/ Address of SAB
;TRUE Return if message is sent Successfully
;FALSE Return if message cannot be sent for any reason
;POSSIBLE ERRORS
; ERARG$ Invalid Calling Argument
; ERNSP$ No Such Pid
; ERRQF$ Recievers Quota Full
; ERSQF$ Senders Quota Full
; ERSLE$ System Limits Exceeded
; ERUSE$ Unexpected System Error
; ERPWA$ System PID went away
C%SEND: CAXGE S1,SAB.MZ ;PROPER SAB?
$RETE(ARG) ;NO -- RETURN ERROR
$SAVE <T1> ;SAVE T1
MOVE T1,S1 ;COPY SAB LENGTH
PUSHJ P,.SAVE2 ;PRESERVE P1-P2
LOAD P1,SAB.LN(S2) ;P1 IS MESSAGE LENGTH
MOVE P2,S2 ;P2 IS SAB ADDRESS
CAIL P1,0 ;MESSAGE LENGTH OK?
CAILE P1,PAGSIZ
$RETE(ARG) ;NO -- RETURN ERROR
LOAD S2,SAB.MS(P2) ;GET MESSAGE ADDRESS
PUSHJ P,C%MAXP ;GET MAX. PACKET SIZE
CAMG P1,S1 ;LARGER THAN A PACKET?
JRST SEND.4 ;NO -- SEND A PACKET
CAIN P1,PAGSIZ ;EXACTLY ONE PAGE?
JRST SEND.2 ;YES -- GO SEND IT
$CALL M%GPAG ;NO -- CREATE A PAGE AND COPY MESSAGE
HRL S1,SAB.MS(P2) ;FORM BLT POINTER
HRRZ S2,S1 ;GET NEW PAGE ADDRESS
ADDI S2,0(P1) ;ADDRESS + MESSAGE SIZE
BLT S1,-1(S2) ;MOVE ENTIRE MESSAGE TO NEW PAGE
SUBI S2,0(P1) ;RECLAIM NEW MESSAGE ADDRESS
;HERE TO SEND A PAGE
SEND.2: TRNE S2,PAGSIZ-1 ;IS PAGE ON PAGE BOUNDRY?
$RETE(ARG) ;NO -- RETURN ERROR
ADR2PG S2 ;YES -- CONVERT TO PAGE NUMBER
HRLI S2,PAGSIZ ;SEND A FULL PAGE
MOVX S1,IP.CFV ;GET THE PAGE MODE FLAG
IORM S1,SNDFLG ;AND SET IT
MOVE S1,P2 ;POINT TO SAB
MOVEI P2,(S2) ;REMEMBER THE PAGE NUMBER
PUSHJ P,SNDMSG ;GO SEND THE MESSAGE
JUMPT .POPJ ;ANY ERRORS? NO, RETURN
CAIN P1,PAGSIZ ;YES, DID WE SUPPLY THIS PAGE?
$RET ;NO, USER GAVE US THE PAGE, RETURN F
$SAVE <TF,S1> ;SAVE FOR FINAL RETURN
MOVE S1,P2 ;RECLAIM PAGE NUMBER
$CALL M%RELP ;RELEASE THE PAGE WE GOT FOR THE BIG PACKET
$RET ;RETURN TF AND S1 FROM SNDMSG
;HERE TO SEND A PACKET
SEND.4: HRL S2,P1 ;FORM LENGTH,,ADDRESS
MOVX S1,IP.CFV ;GET PAGE MODE FLAG
ANDCAM S1,SNDFLG ;AND CLEAR IT
MOVE S1,P2 ;POINT TO SAB
$FALL SNDMSG ;FALL INTO COMMON CODE AND RETURN
SUBTTL SNDMSG - Work routine to do actual IPCF send
;CALL S1/ SAB Address
; S2/ Message Length,,Message Address
; T1/ SAB LENGTH
;If the message is paged, then a true return will
; leave the page unaddressable, and a false return will leave it addressable
SNDMSG: $SAVE <P1,P2,P3,P4>
DMOVE P1,S1 ;PRESERVE CALLING ARGS
SKIPN P3,RSEFLG ;RETURN SEND ERRORS?
MOVX P3,RT.SFL ;NO -- LOAD RETRY LIMIT
MOVE S1,MYPID ;GET MY PID
SKIPE S2,SAB.PB(P1) ;WANT TO SEND FOR A DIFFERENT PID?
MOVE S1,PB.PID(S2) ;YES, GET PID FROM PIB ATTACHED TO SAB
SKIPN S1 ;IS THERE REALLY A PID?
$RETE (ARG) ;NO, COMPLAIN
MOVEM S1,SNDBLK+.IPCFS ;I AM SENDER
LOAD S1,SAB.PD(P1) ;GET RECIEVERS PID OR ADDR OF PID'S NAME
SETO P4, ;SYSTEM INDEX OR -1 IF SEND BY PID
LOAD S2,SAB.SI(P1),SI.FLG ;GET SPECIAL INDEX FLAG
JUMPE S2,SNDM.2 ;SEND BY PID? NO, TRY OTHER FEATURES
LOAD S1,SAB.SI(P1),SI.IDX ;NO -- SEND BY INDEX
MOVE P4,S1 ;REMEMBER WHO IT IS
SKIPN P3,RSEFLG ;RETURN SEND ERRORS?
MOVX P3,RT.SCL ;NO -- GET SYSTEM RETRY LIMIT
SNDM.1: PUSHJ P,RSPID ;GET THE RECIEVERS PID
JUMPT SNDM.3 ;GOT IT, SO SEND TO IT
CAIE S1,ERNSP$ ;UNKNOWN PID FOR SYSTEM COMPONENT?
$RET ;NO -- RETURN THE ERROR
CAXN P3,RT.SCL ;YES -- FIRST RETRY?
SKIPN SPDNAM(P4) ;YES -- DOES PID HAVE A NAME?
CAIA ;NO -- DON'T PRINT THE MSG
SKIPN DEBUGW ;YES -- DEBUGGING?
CAIA ;NO -- DON'T PRINT THE MESSAGE
$WARN (Waiting for ^Q/SPDNAM(P4)/ to start)
SOJL P3,.POPJ ;RETURN ERROR IF RETRY LIMIT EXAUSTED
$SLEEP RT.SLP ;SLEEP FOR A WHILE
MOVE S1,P4 ;RETORE DESIRED INDEX
JRST SNDM.1 ;AND TRY AGAIN
SNDM.2: LOAD S2,SAB.SI(P1),SI.NAM ;WANT TO SEND TO A NAMED PID?
JUMPE S2,SNDM.3 ;NO, JUST USE THE PID
MOVEI S2,[ITEXT(^Q/S1/)] ;YES, AIM AT THE TEXT (SAB.PD HAS ADDR)
PUSHJ P,FNDNAM ;GET THE NAME'S PID FROM INFO
JUMPF .POPJ ;QUIT IF INFO CAN'T MAP THE NAME
SNDM.3: MOVEM S1,SNDBLK+.IPCFR ;SAVE RECIEVERS PID
MOVEM P2,SNDBLK+.IPCFP ;SAVE PAGE/PACKET POINTER
MOVE S2,SNDFLG ;GET SEND FLAGS
CAIG T1,SAB.FL ;SAB INCLUDE A FLAG WORD?
TDZA T1,T1 ;NO
MOVE T1,SAB.FL(P1) ;GET THE FLAGS
LOAD TF,T1,SF.ECD ;GET ERROR CODE TO RETURN
STORE TF,S2,IP.CFE ;SET
LOAD TF,T1,SF.PRV ;GET SENDER'S PRIVILEGE BIT
STORE TF,S2,IP.CFP ;STORE IN SEND FLAGS
CAME S1,PIDTAB+SP.GFR ;SENDING TO SYSTEM GOPHER?
CAMN S1,PIDTAB+SP.IPC ;SENDING TO IPCC?
IORX S2,IP.CFP ;YES -- ENABLE PRIVS
SETZ P1, ;CLEAR PAGE MODE TO GOPHER FLAG
CAMN S1,PIDTAB+SP.GFR ;SENDING TO GOPHER?
TXZN S2,IP.CFV ;SENDING A PAGE TO THE GOPHER?
JRST SNDM.4 ;NO, NOTHING SPECIAL
;**;[65] Replace 6 lines after SNDM.3+10L. /DPM
IORX S2,IP.CFL ;[65] YES, SET LARGE PACKET BIT
HRRZ P1,P2 ;[65] GOPHER DOESN'T LIKE PAGES
PG2ADR P1 ;[65] SO MAKE IT A LARGE PACKET
LOAD TF,.MSTYP(P1),MS.CNT ;[65] GET MESSAGE LENGTH
HRL P1,TF ;[65] MAKE IT LEN,,ADDR
MOVEM P1,SNDBLK+.IPCFP ;[65] SAVE IT AWAY
MOVNI P1,1 ;[65] NOTE THAT WE FAKED A PAGE TO GOPHER
SNDM.4: MOVEM S2,SNDBLK+.IPCFL ;STORE SEND FLAGS
SNDM.5: MOVE S1,[IPCSLN,,SNDBLK] ;ARG FOR UUO
IPCFS. S1, ;SEND THE MESSAGE
JRST SNDERR ;SEE WHY WE LOST
;Here if the send wins
HLRZ S1,P2 ;GET DESIRED MESSAGE SIZE
CAIE S1,PAGSIZ ;WAS THE MESSAGE A PAGE?
$RETT ;NO, ALL DONE!
HRRZ S1,P2 ;GET THE ADRS OF THE PAGE
SKIPN P1 ;WAS PAGE SENT AS A PACKET TO GOPHER?
PUSHJ P,M%IPSN## ;NO, NOTIFY MEMORY MANAGER OF PAGE SENT
HRRZ S1,P2 ;GET PAGE NUMBER AGAIN
PJRST M%RELP## ;AND NOW SAY ITS OUT OF OUR ADRS SPACE
;SNDMSG CONTINUED ON NEXT PAGE
;SNDMSG CONTINUED FROM PREVIOUS PAGE
;HERE TO HANDLE SEND FAILURES WITH ERROR CODE IN S1
SNDERR: CAXE S1,IPE.SQ ;SENDER'S QUOTA FULL?
CAXN S1,IPE.RQ ;OR RECIEVER'S QUOTA FULL?
JRST SNDE.1 ;YES -- THEN TRY AGAIN
CAXE S1,IPE.SF ;FREE SPACE EXAUSTED?
JRST SNDE.3 ;NO -- THEN FAIL
;HERE TO HANDLE TRANSIENT SEND FAILURES
SNDE.1: SOJL P3,SNDE.2 ;TIME TO GIVE UP?
$SLEEP RT.SLP ;WAIT FOR CONDITION TO CLEAR
JRST SNDM.5 ;THEN TRY THE SEND AGAIN
SNDE.2: CAXN S1,IPE.SF ;NO SYSTEM FREE SPACE?
$RETE(SLE) ;YES -- SYSTEM LIMIT EXCEEDED
CAXN S1,IPE.RQ ;IS RECEIVER'S QUOTA FULL?
$RETE(RQF) ;YES -- RETURN ERROR
CAXN S1,IPE.SQ ;IS SENDER'S QUOTA FULL?
$RETE(SQF) ;YES -- RETURN ERROR
SNDE.3: CAXE S1,IPE.DU ;UNKNOWN DESTINATION?
$RETE(USE) ;NO -- UNEXPECTED SYSTEM ERROR
SKIPL P4 ;YES -- WAS THERE A SYSTEM INDEX?
SKIPN PIDTAB(P4) ;YES -- WAS IT EVER THERE?
$RETE(NSP) ;NO -- RETURN NO SUCH PID
SETZM PIDTAB(P4) ;YES -- REMEMBER IT'S GONE AWAY
$RETE(PWA) ;RETURN PID-WENT-AWAY ERROR
SUBTTL C%INTR - Interrupt level routine to flag message available
;Called to note the fact that an IPCF interrupt has occured
;CALL IS: No arguments
;
;TRUE RETURN: Always
C%INTR: SETOM MSGFLG ;FLAG THAT INTERRUPT HAS OCCURED
MOVE S1,@IPCINT ;GET ASSOCIATED VARIABLE
SKIPN IPCSTS ;ALREADY SETUP
MOVEM S1,IPCSTS ;NO..SET IT UP
$RETT ;TAKE A GOOD RETURN
SUBTTL C%RECV - Non-blocking IPCF receive
;C%RECV returns the next message from the IPCF queue or error ERNMA$
; indicating that no messages are outstanding.
;
;CALL IS: No arguments
;
;TRUE RETURN: S1/ CONTAINS POINTER TO MDB (SEE GLXMAC)
; OR
;FALSE RETURN: S1/ CONTAINS ERROR CODE FOR FAILURE
C%RECV: AOSE MSGFLG ;IF FLAG SAYS THERE IS MESSAGE
SKIPN PSIFLG ; OR NO PSI CONNECTION
SKIPA S1,[IP.CFB] ;OK -- GET NON-BLOCKING FLAG
$RETE(NMA) ;OTHERWISE, NO MESSAGE AVAILABLE
IORM S1,RCVFLG ;SET THE FLAG
PJRST RCVMSG ;AND GO DO THE WORK
SUBTTL C%BRCV - Blocking IPCF Receive
;C%BRCV differs from C%RECV in that it never returns with the error
; condition ERNMA$. If no message is available, C%BRCV will block,
; waiting for the next IPCF message.
;
;CALL IS: No arguments
;
;TRUE RETURN: S1/ CONTAINS POINTER TO MDB (SEE GLXMAC)
; OR
;FALSE RETURN: S1/ CONTAINS ERROR CODE (SEE GLXMAC)
C%BRCV: MOVX S1,IP.CFB ;GET NON BLOCKING FLAG
ANDCAM S1,RCVFLG ;CLEAR IT AND GO DO RECIEVE
SUBTTL RCVMSG - Work routine to do an actual IPCF receive
RCVMSG:
IFN FTFLBK,<
SKIPN QUELOK ;IS THE IPCF QUEUE LOCKED ???
SKIPN S1,IPCQUE ;NO,,ANY INTERNAL QUEUE ???
JRST RCVM.A ;LOCKED OR NO QUEUE,,GET REAL MSG
;Here to pick up an IPCF message off the internal queue
PUSHJ P,L%FIRST ;GET THE FIRST MSG ON THE QUEUE
JUMPF [MOVE S1,IPCQUE ;NO MSGS,,GET THE ID BACK
SETZM IPCQUE ;CLEAR THE QUEUE ID
PUSHJ P,L%DLST ;DELETE THE QUEUE
JRST RCVM.A ] ;AND GET A REAL MESSAGE
SETOM MSGFLG ;REMEMBER WE HAVE A PACKET
MOVSS S2 ;GET MDB ADDRESS,,0
HRRI S2,RCVMDB ;GET MDB ADDRESS,,DESTINATION
BLT S2,RCVMDB+MDB.SZ-1 ;COPY OVER TO PERMANENT MDB
PUSHJ P,L%DENT ;DELETE THE QUEUED MDB
LOAD S1,RCVMDB+MDB.MS,MD.CNT ;GET THE MESSAGE LENGTH
CAXN S1,PAGSIZ ;IS IT A PAGE ???
JRST RCVM.7 ;YES,,RETURN TO THE USER
LOAD S2,RCVMDB+MDB.MS,MD.ADR ;GET THE PACKET ADDRESS
PUSH P,S2 ;SAVE ITS ADDRESS
MOVSS S2 ;GET PACKET ADDRESS,,0
HRRI S2,PACKET ;GET PACKET ADDRESS,,NEW ADDRESS
BLT S2,PACKET-1(S1) ;COPY IT OVER
POP P,S2 ;GET THE ADDRESS BACK
PUSHJ P,M%RMEM ;DELETE THE QUEUED PACKET
MOVEI S1,PACKET ;GET THE NEW PACKET ADDRESS
STORE S1,RCVMDB+MDB.MS,MD.ADR ;AND SAVE IT
JRST RCVM.7 ;RETURN TO THE USER
> ;END IFN FTFLBK
;Here to recieve a real IPCF message
RCVM.A: PUSHJ P,.SAVE3 ;GET SOME AC'S
SETZ S1, ;SETUP TO TEST/CLEAR IPCSTS
EXCH S1,IPCSTS ;GET STATUS WORD AND RESET
SKIPN S1 ;ANYTHING SET?
TXOA S1,1 ;NO -- SET A BIT FOR PAGE MODE
LOAD S1,S1,IP.CFV ;YES -- GET ACTUAL MODE
STORE S1,RCVFLG,IP.CFV ;STORE MODE FLAG
JUMPE S1,RCVM.1 ;PACKET?
RCVM.0: SKIPE S1,RCVPAG ;NO -- DO WE HAVE A RECIVE PAGE?
JRST RCVM.1 ;YES -- NO NEED TO GET ONE
PUSHJ P,M%NXPG ;NO --GET A NON-EXISTENT PAGE
JUMPF [SETOM MSGFLG ;OOPS -- CAN'T GET ONE
$RETE (SLE)] ;RETURN ERROR
HRLI S1,PAGSIZ ;PLACE PAGE SIZE IN LEFT HALF
MOVEM S1,RCVPAG ;AND SAVE IT
RCVM.1: MOVE S1,RCVFLG ;GET FLAGS TO USE
MOVEM S1,RCVBLK+.IPCFL ;INIT RECIEVE BLOCK
TXNE S1,IP.CFV ;PAGE MODE?
SKIPA S2,RCVPAG ;YES -- GET PAGE TO USE
IFN FTFLBK,<
JRST [SKIPE QUELOK ;NO -- CALL FROM SNDSYS?
SKIPA S2,[MTLSIZ,,MTLBLK] ;YES -- POINT TO ITS BLOCK
>
MOVE S2,[SZ.PAK,,PACKET] ;NO -- POINT TO PACKET
IFN FTFLBK,<
JRST .+1] ;MERGE BACK INLINE
>
MOVEM S2,RCVBLK+.IPCFP ;SAVE PROPER POINTER
MOVE S1,MYPID ;RECIEVE ON MY BEHALF
MOVEM S1,RCVBLK+.IPCFR
SETZM RCVBLK+.IPCFS ;UNKNOWN SENDER -- UNTIL RECIEVE
RCVM.2: MOVE S1,[IPCRLN,,RCVBLK] ;UUO ARGUMENT
IPCFR. S1, ;DO THE RECEIVE
JRST RCVM.3 ;WE HAVE AN ERROR, GO ANALYZE IT
SKIPE S1 ;ANY ASSOCIATED VARIABLE
MOVEM S1,IPCSTS ;YES..UPDATE THE STATUS
LOAD S2,RCVBLK+.IPCFU ;GET LOGGED IN PPN OF USER
STORE S2,RCVMDB+MDB.SD ;STORE IT
STORE S2,RCVMDB+MDB.CD ;ALSO USE IT AS CONNECTED DIRECTORY
MOVE S2,RCVBLK+.IPCFC ;GET CAPABILTIES WORD
LOAD P1,S2,IP.SJC ;GET SENDERS JCH
STORE P1,P1,MD.PJH ;STORE IT
TXNE S2,IP.JAC ;JACCT ON?
TXO P1,MD.PWH ;YES, TURN ON WHEEL
TXNE S2,IP.IPC ;IPCF PRIVS?
TXO P1,MD.PIP ;YES
TXNE S2,IP.POK ;POKE PRIVS?
TXO P1,MD.POK ;YES
TXNE S2,IP.JLG ;LOGGED IN?
TXO P1,MD.PLG ;YES
TXNE S2,IP.SXO ;SENDER EXECUTE-ONLY?
TXO P1,MD.PXO ;YES
MOVE S2,RCVBLK+.IPCFU ;GET PPN WORD
CAMN S2,OPRPPN ;IS HE THE OPERATOR?
TXO P1,MD.POP ;YES, SET OPERATOR
CAMN S2,MNTPPN ;HAVE MAINTANANCE PRIVS?
TXO P1,MD.PMT ;YES, SET THE PRIV
LOAD S1,P1,MD.PJB ;GET THE JOB NUMBER
STORE P1,RCVMDB+MDB.PV ;SAVE SENDERS PRIVILEGES
SKIPN NODPTR ;WANT THE LOCATED NODE RETURNED?
PJRST RCVM.5 ;NO..PROCEED
MOVX S2,JI.LOC ;YES..GET THE INFO
$CALL I%JINF
JUMPF RCVM.5 ;SORRY ABOUT THAT
MOVE S1,NODPTR ;GET THE POINTER
$CALL SIXASC ;STORE SIXBIT AS ASCIZ
JRST RCVM.5 ;GO FINISH UP
; HERE TO WHEN IPCF RECIEVE FAILS
RCVM.3: CAXN S1,IPE.NM ;IS THIS "NO MESSAGE"?
$RETE (NMA) ;YES -- RETURN
CAXE S1,IPE.WM ;CHECK FOR "WRONG MODE" ERROR
JRST RCVM.4 ;NOPE -- MUST BE REAL ERROR
MOVX S1,IP.CFV ;YES --GET PAGE MODE BIT
XORB S1,RCVFLG ;SWITCH MODES
TXNE S1,IP.CFV ;PAGE MODE
JRST RCVM.0 ;YES -- GO GET IT RIGHT
JRST RCVM.1 ;NO -- GO GET A PACKET
RCVM.4: CAXE S1,IPE.NR ;CHECK FOR "NO ROOM" (TOPS-10)
STOPCD (IRF,HALT,,<IPCF Reception failure>)
PUSHJ P,M%IPRM ;TRY TO MAKE SOME ROOM
JUMPT RCVM.1 ;TRY AGAIN
$RETE (NPI) ;?NO FREE PAGES FOR IPCF RECEPTION
;HERE ON A SUCCESSFUL RECEIVE
RCVM.5: SKIPE IPCSTS ;MORE MESSAGES IN QUEUE?
SETOM MSGFLG ;YES -- SET MSG AVAILABLE FLAG
LOAD S1,RCVBLK+.IPCFL ;GET FLAGS
STORE S1,RCVMDB+MDB.FG ;STORE INTO MDB
TXNE S1,IP.CFV ;DID WE RECIVE A PAGE?
SETZM RCVPAG ;YES -- CLEAR OUR PAGE
LOAD S1,RCVBLK+.IPCFP ;GET LENGTH AND ADDRESS OF DATA
STORE S1,RCVMDB+MDB.MS ;STORE INTO MDB
LOAD S1,RCVBLK+.IPCFR ;GET RECEIVER'S PID
STORE S1,RCVMDB+MDB.RP ;STORE IT TOO
LOAD S1,RCVBLK+.IPCFS ;GET PID OF SENDER
STORE S1,RCVMDB+MDB.SP ;STORE AS SENDER'S PID
SETZM RCVMDB+MDB.SI ;ASSUME NOT A SYSTEM PID
PUSHJ P,C%SIDX ;SEE IF A SYSTEM PID
JUMPF RCVM.6 ;NO -- GIVE UP
TXO S1,SI.FLG ;YES -- SET SPECIAL INDEX FLAG
MOVEM S1,RCVMDB+MDB.SI ;STORE INTO INDEX WORD
MOVX S1,MD.POP ;SET OPERATOR CAPABILITY
SKIPE DEBUGW ;DEBUGGING?
IORM S1,RCVMDB+MDB.PV ;YES..SET THE CAPABILITY
RCVM.6: LOAD S1,RCVMDB+MDB.MS,MD.CNT ;GET SIZE OF MESSAGE
CAXE S1,PAGSIZ ;IF NOT A PAGE
JRST RCVM.7 ;RETURN NOW
LOAD S1,RCVMDB+MDB.MS,MD.ADR ;GET PAGE NUMBER
PUSHJ P,M%IPRC ;NOTIFY THAT IT IS IN NOW
LOAD S1,RCVMDB+MDB.MS,MD.ADR ;GET PAGE NUMBER FROM MDB
PG2ADR S1 ;CONVERT IT TO AN ADDRESS
STORE S1,RCVMDB+MDB.MS,MD.ADR ;STORE IT BACK INTO MDB
RCVM.7: MOVEI S1,RCVMDB ;GET POINTER TO MDB AND TAKE
$RETT ;GENERATE A GOOD RETURN
SUBTTL C%SIDX - See if PID in S1 is a system PID
;CALL: S1/ A PID
; PUSHJ P,C%SIDX
;
;RETURN FALSE IF NO SYSTEM INDEX FOUND TO MATCH
;RETURN TRUE WITH S1/ SYSTEM INDEX THAT MATCHED
C%SIDX: SKIPN DEBUGW ;IF NOT DEBUGGING,
IFN FTFLBK,<
SKIPE OLDMON ;AND THE IPCFM. UUO IS PRESENT,
TRNA ;NO, FLUNK
>
JRST SIDX.4 ;YES, JUST ASK IPCC
PUSHJ P,.SAVE2## ;NO, SAVE WORK ACS
MOVE P2,S1 ;PRESERVE THE PID IN QUESTION
MOVSI P1,-SZ.PID ;AOBJN WORD
SIDX.1:
IFE FTFLBK,<
SKIPE S1,PIDTAB(P1) ;DO WE KNOW A PID FOR THIS INDEX?
>
IFN FTFLBK,<
SKIPN S1,PIDTAB(P1) ;DO WE KNOW A PID FOR THIS INDEX?
SKIPE QUELOK ;NO -- CAN WE ASK ABOUT IT?
>
JRST SIDX.2 ;NO OR KNOWN -- DON'T ASK AGAIN
HRRZ S1,P1 ;UNKNOWN -- GET INDEX WHERE WE NEED IT
PUSHJ P,RSPID ;TRY TO FIND IT
JUMPF SIDX.3 ;CAN'T TELL ABOUT THIS ONE
SIDX.2: CAME S1,P2 ;DOES IT MATCH OURS?
SIDX.3: AOBJN P1,SIDX.1 ;NO -- LOOK SOME MORE
JUMPGE P1,.RETF ;NO MATCH AT ALL, FAIL
HRRZ S1,P1 ;ISOLATE INDEX IN RETURN AC
$RETT ;RETURN GOODNESS
SIDX.4: MOVEM S1,MTLBLK+.IPCS1 ;SAVE ARGUMENT TO IPCC FUNCTION
MOVE S1,[3,,.IPCLP] ;LENGTH,,FUNCTION TO LOCATE SYSTEM PID
PUSHJ P,SNDIPC ;HAVE IPCC LOCATE IT
MOVE S1,MTLBLK+.IPCS2 ;GET THE PID INDEX RETURNED
POPJ P, ;PROPAGATE TF VALUE
SUBTTL C%REL - Release the last message received
; C%REL is used to release the last message received via C%RECV or C%BRCV.
;If this message is a packet, then this is a null operation, and if its
;a page, the page is released.
;CALL IS: No arguments
;
;TRUE RETURN: Always
C%REL: SKIPN S2,RCVMDB+MDB.MS ;GET SIZE AND ADDRESS OF MESSAGE
STOPCD (RAR,HALT,,<Releasing already released IPCF message>) ;ALREADY RELEASED
SETZM RCVMDB+MDB.MS ;MARK MESSAGE AS RELEASED
LOAD S1,S2,MD.CNT ;GET SIZE OF MESSAGE
CAXE S1,PAGSIZ ;IS THIS MESSAGE A PAGE?
$RETT ;NO, SO RETURN NOW
LOAD S1,S2,MD.ADR ;GET ADDRESS OF MESSAGE
ADR2PG S1 ;GET THE PAGE NUMBER
PJRST M%RELP ;RETURN AFTER RELEASING THE PAGE
SUBTTL C%RPRM Routine to read IPCF Parameters
;C%RPRM IS USED TO EXAMINE THE MOST COMMONLY NEEDED
;IPCF PARAMETERS. THESE INCLUDE THE TOTAL NUMBER OF PIDS AND THE
;IPCF RECEPTION / SEND QUOTAS.
;CALL IS: S1/ -1 TO READ PARAMETERS OF PID QUOTA, SND,RCV QUOTAS
; OR ELSE AN SP.??? SYMBOL TO RETURN THAT ENTRY FROM
; THE PID TABLE
;
;TRUE RETURN: IF THE INFORMATION IS AVAILABLE
; S1/<MAX PIDS>B17+<SND QUOTA>B26+<RCV QUOTA>B35 ;IF S1=-1
; S1/ PID TABLE ENTRY ; IF S1=0 OR +
C%RPRM: JUMPGE S1,RSPID ;IF NON-ZERO, WANT SYSTEM PID
SETZ S1, ;SET TO READ IPCF PARAMETERS
PJRST IPRM ;GO READ PARAMS AND RETURN
SUBTTL GETPID - Acquire a PID for this job
;CALL IS: First, Call SETNAM to setup name (if any)
; S1 - 1 means set JWP
;
;TRUE RETURN: S1/ PID acquired for this job
GETPID: $SAVE <P1,P2,MYPID> ;Save some regs
PJOB S2, ;Get our job number
MOVX TF,IB.DPM ;GET A BIT
TDNE TF,IIB##+IB.FLG ;USE JOB NUMBER AS PID ?
JRST GETP.1 ;YES - THIS MAKES LIFE EASY FOR US
MOVEM S2,MYPID ;Save as our (temporary) PID
SKIPN P2,S1 ;Want JWP?
TXO S2,1B0 ;NO -- MAKE PID TEMPORARY
MOVEM S2,MTLBLK+.IPCI1 ;ARGUMENT
SETO P1, ;Set 'named PID flag'
SKIPE MTLBLK+.IPCI2 ;Is a name desired?
JRST GETP.3 ;Yes, must go thru INFO
SETZ P1, ;Clear 'named PID flag'
MOVE S1,[XWD 3,.IPCSC] ;FUNCTION IS MAKE PID
PUSHJ P,SNDIPC ;ASK IPCC TO DO IT
JUMPF GETP.2 ;Failed, maybe no privs, try INFO
MOVE S1,MTLBLK+.IPCS2 ;GET PID RETURNED BY IPCC
$RETT ;RETURN
; Here to use our job number for a PID
GETP.1: MOVE S1,S2 ;GET JOB NUMBER
$RETT ;RETURN
;Here to ask INFO for a PID (perhaps named)
GETP.2: SETZ S2, ;Indicate no name desired
PUSHJ P,SETNAM ;Set up the PACKET
GETP.3: MOVE S1,[XWD C%INIT,.IPCII] ;Function to make a named PID, till RESET
SKIPE P2 ;Want to be job-wide?
MOVE S1,[XWD C%INIT,.IPCIJ] ;Function to make a named PID, job wide
PUSHJ P,SNDINF ;ASK INFO TO DO IT
$RETIF ;PROPAGATE FAILURE
MOVE S1,MTLBLK+.IPCI1 ;Get the PID returned by INFO
SKIPN P1 ;Did we get a name?
$RETT ;Give that back
SKIPE DEBUGW ;ARE WE DEBUGGING?
$WARN <^I/NAMMSG/> ;Type the name we're getting
$RETT ;AND RETURN
;An ITEXT to print out the debugging name
NAMMSG: ITEXT <Becoming ^T20/MTLBLK+.IPCI2/ (PID = ^O/S1/)>
SUBTTL KILPID Routine to delete a pid
;KILL PID IS CALLED DURING INITIALIZATION TO RETURN ANY PID ACQUIRED
;THAT WE NO LONGER NEED.
;Tops10 Alternate entry at KILPDN, to kill a PID via INFO, since
; the PID to be killed is known to be named
;CALL S1/ Pid to be killed
;TRUE RETURN: Pid has been killed
;FALSE RETURN: Pid wasn't killed
KILPID: MOVEM S1,MTLBLK+.IPCI1 ;SAVE PID TO BE KILLED
MOVE S1,[2,,.IPCSZ] ;CODE,,DELETE PID FUNCTION
PUSHJ P,SNDIPC ;ASK IPCC TO DO IT
$RETIT ;RETURN IF ALL SET
MOVE S1,MTLBLK+.IPCI1 ;Get back PID which should have gone
KILPDN: MOVEM S1,MTLBLK+.IPCI2 ;Save PID in message to INFO
SETZM STACL ;'NAME' FIT JUST FINE, THANK YOU
MOVE S1,[KILPID,,.IPCID] ;IPCC won't listen, probably no privs
PJRST SNDINF ;TRY INFO, PROPAGATE RETURN
SUBTTL SPID - Set a system PID
;SPID sets a system wide pid in the internal pid table and in the
;monitor pid table if not debugging.
;CALL IS: S1/ Index into the system pid table
; S2/ Pid to store in system Pid Table
;
;TRUE RETURN: Pid stored in internal and system pid table
; (if Debugging -- pid is stored in internal table only)
SPID: CAIL S1,1 ;MUST BE 1 THRU SZ.PID
CAXL S1,SZ.PID ;INDEX IN RANGE?
STOPCD (PIR,HALT,,<PID Index out of range>)
CAMN S2,PIDTAB(S1) ;IS REQUESTED INDEX ALREADY SET?
$RETT ;YES, NO NEED TO SET IT AGAIN
MOVEM S2,PIDTAB(S1) ;STORE MYPID IN INTERNAL TABLE
IFN FTFLBK,<
SKIPN NEWSID ;FAKING A SYSTEM PID?
>
SKIPE DEBUGW ;DEBUGGING?
$RETT ;YES -- DON'T TELL THE MONITOR
MOVEM S1,MTLBLK+.IPCS1 ;STORE FIRST WORD, THE INDEX
MOVEM S2,MTLBLK+.IPCS2 ;STORE PID TO SET
MOVE S1,[XWD 3,.IPCWP] ;FUNCTION IS SET SYSTEM PID
PUSHJ P,SNDIPC ;ASK IPCC TO DO IT
$RETIT ;RETURN ALL OK IF WE ARE IN GOOD SHAPE
$FATAL <Can't write System PID table>
SUBTTL RSPIDS Routine to read System Pid tables
;RSPIDS is called from initialization to set up our internal System
;pid table. It requests all system pids from the monitor or from
;INFO if the pid has a name. If a Pid exists, it's entry in PIDTAB
;will be non-zero.
;RSPIDS is usually called only during intialization. It gets a PID for us,
;reads all the PIDS, then destroys the PID
;For hacking around, the ALTNAM table can be twiddled, and
;a debugger can do PUSHJ P,RSPIDS to set up some different PIDs
;CALL No Arguments
;TRUE RETURN PIDTAB Contains all valid system pids
RSPIDS: $SAVE <P1> ;PRESERVE P1
MOVE S1,[XWD PIDTAB,PIDTAB+1] ;Make BLT pointer
SETZM PIDTAB ;To clear all the PIDs
BLT S1,PIDTAB+MX.PID ;Clear it
IFN FTFLBK,<
MOVX S2,SP.INF ;GET SYSINF INDEX
SKIPE OLDMON ;OLD MONITOR?
PUSHJ P,RSPI.1 ;YES, FIND AND SAVE INFO'S PID
>
PJOB S1, ;-10, just use job # as PID
PUSH P,MYPID ;Save whatever is there now
MOVEM S1,MYPID ;Save as ours, for now
MOVSI P1,-SZ.PID ;DO ALL ENTRIES
RSPD.1: HRRZ S1,P1 ;LOAD THE INDEX
PUSHJ P,RSPID ;GET THE PID
JUMPF [CAIE S1,ERARG$ ;INVALID INDEX?
TDZA S1,S1 ;NO -- MUST BE NO SUCH PID
SETO S1, ;YES -- MARK INVALID ENTRY
JRST .+1] ;RETURN IN LINE
MOVEM S1,PIDTAB(P1) ;STORE THE ENTRY
RSPD.2: AOBJN P1,RSPD.1 ;LOOP THRU ALL ENTRIES
POP P,MYPID ;Put back the old one
$RETT ;AND RETURN
SUBTTL RSPID Routine to return a system pid
;RSPID is called to return system PID when sending by special index.
;If the Pid is not found in our internal table, we request the Pid
;from the monitor (or from INFO if we are debugging and the System
;index has a name.)
;The PID is obtained from the system table unless
; 1) - the DEBUGW is set
; and ALTNAM(index) contains an address of a string
;or
; 2) - the DEBUGW is set
; and ALTNAM(index) = 0 (no fooling around), and SPDNAM has a SIXBIT
; library convention debug name.
;Under normal debug, ALTNAM is 0.
;To fool around, put a -1 in an entry to talk to system component, or
; put the address of a string which is the name of the PID you want to talk to.
;CALL IS: S1/ Index into System PID table
;
;TRUE RETURN: S1/ PID for that index
;FALSE RETURN: ERARG$ Invalid index
; ERNSP$ No Such Pid
; ERPWA$ PID went away
RSPID: MOVE S2,S1 ;GET THE INDEX
SKIPN DEBUGW ;Are we debugging?
JRST RSPI.1 ;No, never use names
RSPI.0: CAIL S2,0 ;INDEX VALID?
CAIL S2,SZ.PID
$RETE(ARG) ;NO -- FAIL
SKIPE S1,PIDTAB(S2) ;DO WE KNOW THIS PID?
$RETT ;YES, RETURN IT
SKIPGE S1,ALTNAM(S2) ;Force use of system for this component?
JRST RSPI.1 ;Yes, go thru system table
JUMPN S1,RSPI.3 ;If an addr was in there, use that name
SKIPE S1,SPDNAM(S2) ;0 in ALTNAM, is there a library entry?
JRST RSPI.3 ;Yes, use library convention
IFN FTFLBK,<
SKIPN DEBUGW ;ARE WE HERE FOR FALLBACK REASONS?
JRST RSPI.2 ;YES, ASSUME NO SUCH PID
>
;Here to get PID from system table
RSPI.1: MOVEI S1,.GTSID ;NO -- ASK THE MONITOR
HRL S1,S2 ;LOAD THE INDEX
GETTAB S1, ;GET THE ENTRY
JRST RSPI.8 ;INVALID INDEX
JUMPE S1,RSPI.2 ;IS IT THERE?
SKIPL S2 ;RANGE CHECK
CAILE S2,MX.PID ;AGAINST OUR TABLE
$RETT ;DON'T STORE OUTSIDE OF TABLE
MOVEM S1,PIDTAB(S2) ;YES, REMEMBER THAT IT EXISTED ONCE
$RETT ;RETURN GOODNESS
;Here to see if it went away after we had known it once
RSPI.2: SKIPN PIDTAB(S2) ;DID WE EVER KNOW IT?
$RETE(NSP) ;NO -- RETURN NO SUCH PID
$RETE(PWA) ;YES -- RETURN PID WENT AWAY
;Here to check invalid index
RSPI.8:
IFN FTFLBK,<
CAILE S2,SP.GFR ;IN 7.02 RANGE?
SKIPN OLDMON ;OR NOT 7.02?
>
$RETE(ARG) ;YES, GIVE INVALID ARGUMENT ERROR
IFN FTFLBK,<
JRST RSPI.0 ;NO, CHECK WITH INFO
>
;RSPIDS is continued on the next page
;RSPIDS continued from previous page
;Here to find a system component thru INFO
;Enter with S1/addr of ASCIZ name (LH of S1 = 0)
; or S1/SIXBIT debug name (LH of S1 .NE. 0)
; S2/ special system index
RSPI.3: $SAVE <P1> ;PRESERVE P1
MOVE P1,S2 ;SAVE THE INDEX
MOVEI S2,NAMTXT ;Assume library convention
IFN FTFLBK,<
SKIPN DEBUGW ;ARE WE HERE FOR FALLBACK REASONS?
MOVEI S2,SYSTXT ;YES, ASSUME SYSTEM CONVENTION
>
TLNN S1,-1 ;Is S1 SIXBIT?
MOVEI S2,[ITEXT (<^T/(S1)/>)] ;No, use different arg
PUSHJ P,FNDNAM ;ASK INFO FOR THE PID
MOVE S2,P1 ;RESTORE THE INDEX
JUMPF .POPJ ;RETURN ERROR FROM FNDNAM
RSPI.4: MOVEM S1,PIDTAB(S2) ;STORE THE PID
$RETT
SUBTTL C%MAXP - Read maximum short packet size
;CALL IS: No arguments
;
;TRUE RETURN: S1/ Largest size of short IPCF message
C%MAXP: MOVX S1,%IPCML ;ASK MONITOR FOR IT
GETTAB S1, ;
MOVEI S1,-1 ;WILL TAKE "TOO LARGE" FAILURE
$RETT ;RETURN
SUBTTL CPIDI - Connect PID to specified interrupt channel
;This routine connects the PID acquired
;to the specified interrupt channel.
;CALL IS: S1/ Channel to connect PID to
; S2 / PID to connect
; TOPS10, IIB is used to setup internal intrpt connection
;TRUE RETURN: Always
CPIDI: HRLZM S1,MTLBLK+1 ;STORE OFFSET,,0
PUSH P,S1 ;Save offset
MOVX S1,.PCIPC ;REASON IS IPCF RECEPTION
MOVEM S1,MTLBLK+0 ;STORE IT
SETZM MTLBLK+2 ;CLEAR PRIORITY LEVEL
MOVE S1,[PS.FAC+MTLBLK] ;ADD THE CONDITION
PISYS. S1, ;ADD IT
STOPCD (IIF,HALT,,<IPCF to interrupt system connect failed>)
LOAD S1,IIB##+IB.INT ;ADDRESS OF INTERRUPT VECTOR
POP P,S2 ;GET VECTOR OFFSET FOR IPCF
ADDI S1,.PSVIS(S2) ;GET ADDRESS OF ASSOCIATED VARIABLE
MOVEM S1,IPCINT ;SAVE ADDRESS FOR C%INTR
$RETT ;RETURN
SUBTTL IPRM Read/Write IPCF parameters
;CALL IS: S1 / -1 TO WRITE, 0 TO READ PARAMETERS
; S2 / PARAMETERS TO WRITE (IF S1=-1)
;
;TRUE RETURN: S1 / <MAX PIDS>B17+<SND QUOTA>B26+<RCV QUOTA>B35 ;IF S1=0
IPRM: PUSHJ P,.SAVE1 ;GET ONE AC
MOVE P1,S2 ;REMEMBER 2ND ARG
JUMPE S1,IPRM.2 ;IF READING, SKIP THIS
HLRZ S1,S2 ;GET THE PID MAX WANTED
JUMPE S1,IPRM.1 ;IF DEFAULTED, SKIP THIS
PUSHJ P,MNPRED ;GET THE CURRENT MAXIMUM
HLRZ S2,P1 ;GET THE REQUESTED NUMBER
ADD S1,S2 ;ADD TO CURRENT AMOUNT
CAIL S1,1000 ;MAXIMUM IN RANGE
MOVEI S1,777 ;NO..SET TO MAXIMUM
PUSHJ P,MNPWRT ;WRITE MAXIMUM NUMBER OF PIDS
SKIPT ;OK?
$FATAL <IPCF privileges required to set maximum number of pids>
IPRM.1: HRRZ S1,P1 ;GET THE QUOTAS
JUMPE S1,.RETT ;IF DEFAULTING, LEAVE IT ALONE
LOAD S1,P1,IP.SQT ;GET THE QUOTAS
CAIL S1,1000 ;MAXIMUM IN RANGE
MOVEI S1,777 ;NO..SET TO MAXIMUM
STORE S1,P1,IP.SQT ;SAVE THE VALUES
HRRZ S1,P1 ;GET THE QUOTAS AGAIN
PUSHJ P,QTAWRT ;WRITE QUOTAS OUT
JUMPT .RETT ;IF ALL OK, RETURN NOW
$FATAL <IPCF privileges required to set IPCF quotas>
IPRM.2: PUSHJ P,MNPRED ;READ MAXIMUM NUMBER OF PIDS
MOVE P1,S1 ;REMEMBER THE ANSWER
PUSHJ P,QTARED ;AND THE QUOTA'S
SKIPT ;DID WE GET IT?
$FATAL <Can't read IPCF quotas>
HRLM P1,S1 ;MAKE UP THE TWO HALVES
$RETT ;AND RETURN
SUBTTL MNPRED/MNPWRT - Read/Write maximum number of PIDS
;THESE ROUTINES DO THE SYSTEM DEPENDENT WORK FOR SETTING THE MAXIMUM
;NUMBER OF PIDS FOR A JOB.
;
; CALL IS: READ/NO ARGUMENTS WRITE/S1 MAXIMUM NUMBER OF PIDS
;TRUE RETURN: READ/S1 MAX NR. OF PIDS WRITE/NO RETURNED VALUE
;FALSE RETURN: FAILURE OF SOME SORT
MNPRED: SKIPA S2,[3,,.IPCQR] ;READ QUOTA
MNPWRT: MOVE S2,[3,,.IPCQS] ;WRITE QUOTA
IFN FTFLBK,<
SKIPN OLDMON ;DOES THIS MONITOR HAVE PID QUOTAS?
>
PJRST QTARWT ;JOIN COMMON QUOTA READ/WRITE CODE
IFN FTFLBK,<
MOVEI S1,777 ;NO, RETURN A LARGE NUMBER FOR READS
$RETT ;PRETEND IT WORKS
>
SUBTTL QTARED/QTAWRT - Read/Write the Send and Receive Quotas
;CALL IS: S1/ 0,,<SND QUOTA>B26+<RCV QUOTA>B35 IF WRITING
;TRUE RETURN: S1/ 0,,<SND QUOTA>B26+<RCV QUOTA>B35 IF READING
;FALSE RETURN: ON ANY FAILURE OF TASK
QTARED: SKIPA S2,[3,,.IPCSR] ;READ QUOTAS
QTAWRT: MOVE S2,[3,,.IPCSQ] ;WRITE QUOTAS
;JOIN HERE FROM MNPRED/MNPWRT, ABOVE
QTARWT: MOVEM S1,MTLBLK+.IPCS2 ;STORE QUOTA FOR WRITE
MOVE S1,MYJOB## ;GET OUR JOB NUMBER
MOVEM S1,MTLBLK+.IPCS1 ;STORE IT AWAY
MOVE S1,S2 ;GET XWD CODE,FUNCTION IN RIGHT AC
PUSHJ P,SNDIPC ;ASK IPCC TO DO IT
MOVE S1,MTLBLK+.IPCS2 ;GET RESPONSE
POPJ P, ;PROPAGATE TF VALUE
SUBTTL SETNAM - Routine to declare our name to INFO
;SETNAM is used to setup the name in the packet about to go to INFO or IPCC
;This allows programs to communicate
; by other means than the system PID table. This is useful for debugging
; purposes when multiple components are going to be used.
;SETNAM should always be called just before calling GETPID
;CALL: S2/ Addr of ITEXT of name to write
; or 0, to set up no name
;
;TRUE RETURN: Always, name has been established
; 2 nd word of PACKET has 0 or name,
; STACP has incremented pointer
SETNAM: SETZM MTLBLK+.IPCI2 ;CLEAR NAME FROM MESSAGE
SETZM MTLBLK+MTLSIZ-1 ;MAKE SURE IS ALWAYS ASCIZ
PUSH P,S2 ;SAVE NAME POINTER A MOMENT
MOVE S2,[POINT 7,MTLBLK+.IPCI2] ;GET POINTER TO MESSAGE AREA
MOVEM S2,STACP ;STORE THAT POINTER
MOVEI S2,SZ.INF ;GET MAXIMUM NAME LENGTH
MOVEM S2,STACL ;STORE IN LIMIT WORD
POP P,S2 ;RESTORE NAME POINTER
JUMPE S2,.RETT ;IF NO NAME DESIRED, WE'RE DONE
$TEXT(STAC,<^I/(S2)/^0>) ;CREATE THE NAME
$RETT ;RETURN SUCCESS
;FNDNAM is used to ask INFO for the pid of a specified name
; It is called by GETPID to look for our name and by RSPIDX
; to check for Private Quasar and Private Orion
;CALL: S2/ addr of ITEXT to build name
;TRUE RETURN: S1/ Pid of Specified Name
FNDNAM: PUSHJ P,SETNAM ;Set up name in message
MOVE S1,[XWD FNDNAM,.IPCIW] ;FUNCTION IS FIND PID FOR NAME
PUSHJ P,SNDINF ;ASK INFO
JUMPF [$RETE(NSP)] ;RETURN NO SUCH PID
MOVE S1,MTLBLK+.IPCI1 ;GET THE PID
SKIPE DEBUGW ;DEBUGGING ?
$WARN <Alternate ^T20/MTLBLK+.IPCI2/ (PID = ^O/S1/)> ;SHOW THE NAME
$RETT ;RETURN SUCCESS
SUBTTL SNDINF/SNDIPC - Routines to converse with [SYSTEM]INFO & IPCC
;SNDINF is used to carry on an IPCFM. dialog with [SYSTEM]INFO
;CALL IS: S1/ CODE WORD TO USER, I.E., ID,,FUNCTION CODE
;
;TRUE RETURN: If UUO succeeds
;
;FALSE RETURN: If it fails
;
;SNDSYS will be used instead if IPCFM. UUO support is missing
SNDINF: SKIPGE STACL ;DID THE NAME FIT?
$RETF ;NO, GIVE UP NOW
MOVEM S1,MTLBLK+.IPCI0 ;SAVE FUNCTION WORD IN ARG BLOCK
SETZM MTLBLK+.IPCI1 ;NO ONE IS TO BE COPIED
IFN FTFLBK,<
SKIPE OLDMON ;IS THE IPCFM. UUO PRESENT?
JRST [MOVEI S2,SP.INF ;NO, TELL SNDSYS TO USE INFO
PJRST SNDSYS] ;AND LET IT DO THE WORK
>
HRRZ S1,STACP ;LAST WORD USED BY SETNAM
SUBI S1,MTLBLK-1 ;FORM LENGTH OF BLOCK
HRLM S1,MTLBLK ;SAVE FOR UUO
$SAVE <P1> ;SAVE A REG
MOVEI P1,RT.SCL ;LOAD RETRY LIMIT
SINF.1: XMOVEI S1,[IP.CMP!<0,,2> ;INVOKING PRIVS, TALK TO INFO
IFIW MTLBLK] ;POINT TO UUO ARG BLOCK
IPCFM. S1, ;TALK TO [SYSTEM]INFO
JRST SINF.2 ;ANALYZE FAILURE
$RETT ;PROPAGATE SUCCESS
SINF.2: CAIE S1,IPCDU% ;UNKNOWN DESTINATION?
$RETF ;NO, JUST FAIL
SKIPE DEBUGW ;IF DEBUGGING,
CAIE P1,RT.SCL ;AND FIRST TIME TO WAIT,
JRST SINF.3 ; (NO, SKIP IT)
MOVE S1,SPDNAM+SP.INF ;GET POINTER WHERE REQUIRED
$WARN <Waiting for ^I/SYSTXT/ to start> ;SAY WHY WE PAUSED
SINF.3: SOJL P1,.RETF ;FAIL IF RETRIES DONE
$SLEEP RT.SLP ;ELSE WAIT A LITTLE FOR IT
JRST SINF.1 ;AND TRY AGAIN
;SNDIPC is used to carry on an IPCFM. dialog with [SYSTEM]IPCC
;CALL IS: S1/ CODE WORD TO USE, I.E., LEN,,FUNCTION CODE
;
;TRUE RETURN: If UUO succeeds
;
;FALSE RETURN: If it fails
;
;SNDSYS will be used instead if IPCFM. UUO support is missing
SNDIPC:
IFN FTFLBK,<
SKIPN OLDMON ;IS THE IPCFM. UUO PRESENT?
JRST SNDI.1 ;YES, USE IT
HLRZ S2,S1 ;NO, GET THE LENGTH
ADDI S2,MTLBLK-1 ;POINT TO LAST WORD OF PACKET
MOVEM S2,STACP ;SAVE FOR SNDSYS
HRL S1,(P) ;MAKE RETURN ADDRESS BE ACK CODE
MOVEM S1,MTLBLK+.IPCS0 ;SAVE FUNCTION WORD FOR SNDSYS
MOVEI S2,SP.IPC ;TELL SNDSYS TO USE IPCC
PJRST SNDSYS ;HAVE IT DO THE WORK
SNDI.1: > ;END OF IFN FTFLBK
MOVEM S1,MTLBLK+.IPCS0 ;SAVE LEN,,FUNCTION FOR UUO
XMOVEI S1,[IP.CMP!<.IPCCC,,2> ;INVOKING PRIVS, TALK TO IPCC
IFIW MTLBLK] ;POINT TO UUO ARG BLOCK
IPCFM. S1, ;TALK TO [SYSTEM]IPCC
$RETF ;PROPAGATE FAILURE
$RETT ;AND SUCCESS
SUBTTL SNDSYS - Routine to converse with [SYSTEM]INFO & IPCC
;SNDSYS is used to carry on a SEND-RECEIVE dialog with the system
; IPCF facilities
;CALL IS: S1/ CODE WORD TO USE, I.E. ID,,FUNCTION CODE
; S2/ CANONICAL SYSTEM INDEX TO SEND TO, EITHER SP.IPC OR SP.INF
;
;TRUE RETURN: If acknowledgement comes back successfully
;
;FALSE RETURN: If for any reason we cannot sent, or the
; response contains an error.
;
;THIS ROUTINE IS USED ONLY WHEN THE MONITOR DOES NOT SUPPORT THE IPCFM. UUO
IFN FTFLBK,<
SNDSYS: $SAVE <P1,P2,SNDFLG,RCVMDB+MDB.MS,RCVMDB+MDB.FG,RCVMDB+MDB.SD,RCVMDB+MDB.CD,RCVMDB+MDB.SP,RCVMDB+MDB.RP,RCVMDB+MDB.PV,RCVMDB+MDB.SI,RSEFLG>
;PRESERVE WHAT WE TOUCH
DMOVE P1,S1 ;SAVE INPUT ARGUMENTS
SETZM RSEFLG ;ALWAYS WAIT FOR SYSINF TO START UP
SETOM QUELOK ;LOCK THE INTERNAL IPCF QUEUE
MOVEI S1,MTLBLK ;GET LOCATION OF PACKET
MOVEM S1,SNDSAB+SAB.MS ;STORE MESSAGE LOCATION
HRRZ S1,STACP ;LAST WORD USED BY SETNAM
SUBI S1,MTLBLK-1 ;COMPUTE SIZE
MOVEM S1,SNDSAB+SAB.LN ;STORE AS MESSAGE LENGTH
ZERO SNDSAB+SAB.PD ;SEND IS BY INDEX, NOT PID
ZERO SNDSAB+SAB.SI ;CLEAR OUT INDEX WORD
STORE P2,SNDSAB+SAB.SI,SI.IDX ;SET INDEX
MOVEI S1,1 ;GET A BIT
STORE S1,SNDSAB+SAB.SI,SI.FLG ;LIGHT BY-INDEX FLAG
;SNDSYS CONTINUED ON NEXT PAGE
;SNDSYS CONTINUED FROM PREVIOUS PAGE (STILL IN FTFLBK CONDITIONAL)
MOVEI S1,SAB.SZ ;SIZE OF SAB
MOVEI S2,SNDSAB ;AND ITS LOCATION
PUSHJ P,C%SEND ;SEND IT OFF
SKIPF ;SKIP IF FAILED !!!
SNDS.2: PUSHJ P,C%BRCV ;DO A WAITING RECEIVE NOW
JUMPF [SETZM QUELOK ;FAILED,,CLEAR IPCF QUEUE LOCK
$RETF ] ;AND RETURN
MOVE S1,RCVMDB+MDB.SI ;GET SPECIAL INDEX WORD
TXNN S1,SI.FLG ;FROM A 'SPECIAL' PID ???
JRST SNDS.3 ;NO,,TRY ANOTHER MESSAGE
LOAD S1,S1,SI.IDX ;GET THE SPECIAL PID INDEX
CAME S1,P2 ;REPLY FROM DESTINATION?
JRST SNDS.3 ;NO, TRY AGAIN
MOVE S1,MTLBLK+.IPCI0 ;GET CODE WORD
CAME S1,P1 ;DOES IT MATCH WHAT WE SENT?
JRST SNDS.3 ;NO
SETZM QUELOK ;CLEAR THE IPCF QUEUE LOCK
LOAD S1,RCVMDB+MDB.FG,IP.CFE ;DID WE GET ANY ERRORS?
JUMPN S1,.RETF ;IF WE DID, GIVE UP NOW
$RETT ;OTHERWISE, RETURN A GOOD RETURN
SNDS.3: SKIPN S1,IPCQUE ;GET THE IPCF QUEUE ID
PUSHJ P,[PUSHJ P,L%CLST ;NONE,,CREATE A LIST FOR IT
MOVEM S1,IPCQUE ;SAVE THE ID
POPJ P, ] ;AND CONTINUE
PUSHJ P,L%LAST ;POSITION TO THE LAST ENTRY
MOVE S1,IPCQUE ;GET THE ID AGAIN,,LIST MAY BE NULL
MOVX S2,MDB.SZ ;GET THE MDB LENGTH
PUSHJ P,L%CENT ;CREATE AN ENTRY AT THE END
MOVE S1,S2 ;GET THE ENTRY ADDRESS
HRLI S1,RCVMDB ;GET THE SOURCE ADDRESS
BLT S1,MDB.SZ-1(S2) ;COPY THE MDB TO THE IPCF QUEUE
LOAD S1,RCVMDB+MDB.MS,MD.CNT ;GET THE MESSAGE LENGTH
CAXN S1,PAGSIZ ;IS IT A PAGE ???
JRST SNDS.2 ;YES,,LETS TRY AGAIN (PAGE IS SAVED)
PUSH P,S2 ;SAVE THE MDB ADDRESS
PUSHJ P,M%GMEM ;NO,,GET A CHUNK TO SAVE IT IN
EXCH S1,0(P) ;GET MDB ADDRESS,,SAVE PACKET LENGTH
STORE S2,MDB.MS(S1),MD.ADR ;SAVE THE NEW PACKET ADDRESS
POP P,S1 ;RESTORE THE PACKET LENGTH
ADD S1,S2 ;CALC CHUNK END ADDRESS
HRLI S2,MTLBLK ;GET THE PACKET ADDRESS
BLT S2,-1(S1) ;SAVE THE PACKET AS WELL
SETOM MSGFLG ;INDICATE ANOTHER MSG POSSIBLE !!
JRST SNDS.2 ;AND GET THE NEXT MESSAGE
> ;END OF IFN FTFLBK FROM START OF SNDSYS
SUBTTL STAC - Routine to build INFO messages
; STAC IS USED IN THE $TEXT INSTRUCTION TO DEPOSIT CHARACTERS INTO
; THE MESSAGE THAT IS SENT TO SYSTEM-INFO
STAC: SOSL STACL ;IF THERE'S STILL ROOM,
IDPB S1,STACP ;STORE A BYTE
$RETT ;RETURN GOODLY
SUBTTL SIXASC Store sixbit word in S2 as an asciz string
;Accepts S1/ Pointer to destination
; S2/ Sixbit value
SIXASC: $SAVE <P1,P2>
TLC S1,777777 ;FIX DESTINATION POINTER
TLCN S1,777777
HRLI S1,(POINT 7)
MOVE P1,[POINT 6,S2] ;GET POINTER TO THE WORD
MOVEI P2,6 ;STORE SIX CHARACTERS
SIXAS1: ILDB TF,P1 ;STORE THE TEXT
ADDI TF," "
IDPB TF,S1
SOJG P2,SIXAS1
MOVE TF,S1
IDPB P2,TF ;TERMINATE WITH A NULL
$RETT
SUBTTL C%PIDJ Return PID owners job number
;CALL IS: S1/ PID
;
;TRUE RETURN S1/ Job number of PID's owner
C%PIDJ: PUSHJ P,C%PIDH ;GET PID OWNER'S JCH
$RETIF ;PROPAGATE ERRORS
ANDI S1,IP.SJN ;KEEP ONLY JOB NUMBER
$RETT ;RETURN GOODNESS
SUBTTL C%PIDH Return PID owner's JCH
;CALL IS: S1/ PID
;
;TRUE RETURN S1/ JCH of PID's owner
C%PIDH:
IFN FTFLBK,<
SKIPN OLDMON ;IS THE IPCFM. UUO PRESENT?
JRST PIDH.1 ;YES, DO THIS THE RIGHT WAY
$SAVE <P1> ;RESERVE AN AC
MOVX P1,%IPCPM ;PID INDEX MASK
GETTAB P1, ;FIND IT
MOVX P1,IP.SJN ;ASSUME JOB NUMBER MASK
MOVE S2,P1 ;COPY MASK
AND S2,S1 ;GET JUST INDEX INTO PIDTAB
HRLZS S2 ;PUT IN APPROPRIATE HALFWORD
HRRI S2,.GTPID ;PIDTAB'S GETTAB NUMBER
GETTAB S2, ;GET THE MONITOR INTERNAL PID
$RETF ;INVALID PID
EXCH S1,S2 ;SWAP FOR RETURNING JOB NUMBER
XOR S2,S1 ;CHECK SEQUENCE NUMBERING
AND S1,P1 ;KEEP ONLY JOB NUMBER HERE
ANDCM S2,P1 ;AND ONLY THE SEQUENCE BITS HERE
JUMPN S2,.RETF ;INVALID IF SEQUENCE NUMBERS DON'T MATCH
$RETT ;RETURN GOODNESS IF THEY DO
PIDH.1: > ;END OF IFN FTFLBK
MOVEM S1,MTLBLK+.IPCS1 ;SAVE IN MTLBLK FOR ASKING IPCC
MOVE S1,[3,,.IPCSJ] ;LENGTH,,IPCC FUNCTION FOR PID OWNER
PUSHJ P,SNDIPC ;ASK IPCC WHO OWNS THIS PID
$RETIF ;PROPAGATE SNDSYS'S ERRORS
MOVE S1,MTLBLK+.IPCS2 ;PICK UP THE ANSWER
$RETT ;AND RETURN GOODNESS
IPC%L: ;LABEL THE LITERAL POOL
END