Trailing-Edge
-
PDP-10 Archives
-
bb-m780d-sm
-
monitor-sources/clufrk.mac
There are 13 other files named clufrk.mac in the archive. Click here to see a list.
; UPD ID= 8492, RIP:<7.MONITOR>CLUFRK.MAC.14, 9-Feb-88 12:18:13 by GSCOTT
;TCO 7.1218 - Insert copyright notice.
; UPD ID= 8388, RIP:<7.MONITOR>CLUFRK.MAC.13, 27-Jan-88 10:30:23 by GSCOTT
;TCO 7.1200 - GETRTL is now in XCDSEC.
; UPD ID= 289, RIP:<7.MONITOR>CLUFRK.MAC.12, 12-Nov-87 15:13:49 by RASPUZZI
;Fix up previous edit. I used an old source for comparison and didn't
;use REDIT to merge the changes in.
; UPD ID= 288, RIP:<7.MONITOR>CLUFRK.MAC.11, 12-Nov-87 15:10:26 by RASPUZZI
;TCO 7.1132 - Bind CLUDGR fork in queue 1 and see how much more the response
; is for cluster SYSTAT. also, set JP%SYS for the CLUDGR fork.
; This is an experiment and maybe changed again later.
; UPD ID= 287, RIP:<7.MONITOR>CLUFRK.MAC.10, 11-Nov-87 14:23:05 by RASPUZZI
;Restore a line that was incidentally removed.
; UPD ID= 242, RIP:<7.MONITOR>CLUFRK.MAC.9, 4-Nov-87 16:29:20 by RASPUZZI
;TCO 7.1114 - Prevent ILMNRFs and KLPHOGs on remote system by making sure
; CLFLNS calculates the send word value correctly
; UPD ID= 233, RIP:<7.MONITOR>CLUFRK.MAC.8, 29-Oct-87 16:21:52 by RASPUZZI
;TCO 7.1105 - Now do TCO 7.1087 right since we are sober.
;TCO 7.1104 - Make CLFMTO execute the MTOPR% JSYS in section 0.
; UPD ID= 230, RIP:<7.MONITOR>CLUFRK.MAC.7, 28-Oct-87 19:01:10 by RASPUZZI
;Add the missing portions of TCO 7.1090 that I didn't put in.
; UPD ID= 225, RIP:<7.MONITOR>CLUFRK.MAC.6, 28-Oct-87 14:16:43 by RASPUZZI
;TCO 7.1094 - Make CLFMSR find structure name in correct location when
; performing remote MSTR function .MSGSS.
; UPD ID= 222, RIP:<7.MONITOR>CLUFRK.MAC.5, 28-Oct-87 10:27:13 by RASPUZZI
;TCO 7.1090 - ***PERFORMANCE*** Only send over the exact number of words
; across the CI to remote system. Also, calls to routine
; FILLIN have to change.
; UPD ID= 218, RIP:<7.MONITOR>CLUFRK.MAC.4, 27-Oct-87 15:57:23 by RASPUZZI
;TCO 7.1087 - Return class scheduling information for .INSYS function
; for remote INFO% request.
; UPD ID= 196, RIP:<7.MONITOR>CLUFRK.MAC.3, 22-Oct-87 14:46:54 by RASPUZZI
;More of TCO 7.1076 - Make CLFSYS use the local job number when obtaining
; logged in directory out of JOBDIR
; UPD ID= 188, RIP:<7.MONITOR>CLUFRK.MAC.2, 21-Oct-87 17:32:16 by RASPUZZI
;TCO 7.1076 - Add CLUDGR SYSYAP. This contains the CLUDGR fork's
; supporting routines.
; COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1988.
; 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 THAT IS NOT SUPPLIED BY DIGITAL.
SEARCH CLUPAR,PROLOG,SCAPAR,TTYDEF
EXTERN MTOLEN,MUTLEN,SKDLEN,HSTSIZ
SALL
TTITLE (CLUFRK,,< - Supporting routines for the CLUDGR fork>)
; M. Raspuzzi October 87
;CLUFRK - Routines that make CLUDGR's fork perform.
Subttl Table of Contents
; Table of Contents for CLUFRK
;
; Section Page
;
;
; 1. CLUDGR Fork
; 1.1 Data Storage . . . . . . . . . . . . . . . . . 4
; 1.2 CLSFRK (Start the CLUDGR fork) . . . . . . . . 5
; 1.3 CLFTAB (Dispatch table for CLUDGR fork) . . . 6
; 1.4 CLFRUN (Begin running CLUDGR fork here) . . . 7
; 1.5 CLFDED (Dead entry in CLREQQ) . . . . . . . . 9
; 1.6 CLFALL (All buffers for a request are in) . . 10
; 1.7 CLFDST (Do DIRST for remote system) . . . . . 11
; 1.8 CLFGTB (Do GETAB% simulation) . . . . . . . . 12
; 1.9 CLFGTY (Do GTTYP% simulation) . . . . . . . . 13
; 1.10 CLFINL (Simulate INLNM% JSYS) . . . . . . . . 14
; 1.11 CLFLNS (Logical name translation) . . . . . . 15
; 1.12 CLFJOB (Find jobs of given user) . . . . . . . 16
; 1.13 CLFMTO (Do MTOPR% function) . . . . . . . . . 17
; 1.14 DOMTO (Section 0 MTOPR%) . . . . . . . . . . . 18
; 1.15 CLFMUT (Do remote MUTIL% request) . . . . . . 19
; 1.16 CLFRCR/CLFRCD (RCUSR%/RCDIR% service) . . . . 20
; 1.17 CLFSNP (Simulate SNOOP%) . . . . . . . . . . . 21
; 1.18 CLFSGT (Routine to do SYSGT%) . . . . . . . . 22
; 1.19 CLFTMN (Routine to do TMON%) . . . . . . . . . 23
; 1.20 CLFSKD (Simulate SKED% JSYS) . . . . . . . . . 24
; 1.21 CLFXPK (Simulate XPEEK%) . . . . . . . . . . . 25
; 1.22 CLFDVC (Do the DVCHR%) . . . . . . . . . . . . 26
; 1.23 CLFSTV (Do STDEV% for remote) . . . . . . . . 27
; 1.24 CLFDVT (Remote DEVST% working routine) . . . . 28
; 1.25 CLFNTF (Do NTINF% for remote) . . . . . . . . 29
; 1.26 CLFGJI (Do remote GETJI% for someone) . . . . 30
; 1.27 CLFSYS (Get SYSTAT stuff for remote) . . . . . 31
; 1.28 CLFCFG (Do CNFIG% request) . . . . . . . . . . 36
; 1.29 CLFMSR (Do MSTR%) . . . . . . . . . . . . . . 37
; 1.30 CLFTIM (Do TIME% simulation) . . . . . . . . . 40
; 1.31 CLFTMG (Do TTMSG% request) . . . . . . . . . . 41
; 1.32 CLFBAD (Bad function from remote) . . . . . . 42
; 1.33 CLFFAL (Send Failure) . . . . . . . . . . . . 44
; 1.34 CLFRSP (Reassemble SCA packets) . . . . . . . 45
; 1.35 CLFWAT (Scheduler test to wait for action) . . 46
; 1.36 ZERDAT (Zero out data area) . . . . . . . . . 47
; 1.37 CLFSND (Routine to send results) . . . . . . . 48
; 2. End of CLUFRK . . . . . . . . . . . . . . . . . . . . 51
SUBTTL CLUDGR Fork -- Data Storage
NR (CLFSCR,PGSIZ) ;Scratch page for CLUDGR fork
NR (CLFREA,PGSIZ) ;Reassemble incoming data for CLUDGR fork here
SUBTTL CLUDGR Fork -- CLSFRK (Start the CLUDGR fork)
;CLSFRK - Routine called to start the CLUDGR fork running. It is
;called by MEXEC during system startup.
;
; Call with:
; no arguments
; CALL CLSFRK
;
; Returns:
; +1 - Always, CLUDGR fork number in CLFORK
XSWAPCD ;Called at system startup
CLSFRK::MOVX T1,CR%CAP ;Give same CAPs
CFORK% ;Make CLUDGR fork
ERJMP NOCLFK ;Error, let someone know about it
MOVE T2,[XCDSEC,,CLFRUN];Start the CLUDGR fork at this address
MSFRK% ;Do it
ERJMP NOCLFK ;Couldn't do it
RET ;Done
NOCLFK: BUG.(HLT,CLUFNC,CLUFRK,SOFT,<CLSFRK - Could not create CLUDGR fork>,<<T1,ERROR>>,<
Cause: CFORK% was unable to create a fork for CLUDGR or MSFRK%
was not able to start the CLUDGR fork in monitor mode.
Data: ERROR - Error code returned from JSYS
>) ;Slight problem
SUBTTL CLUDGR Fork -- CLFTAB (Dispatch table for CLUDGR fork)
;This table contains the legal functions that CLUDGR fork can handle.
;If the remote system requests a function that is not here, an error
;will be passed back to the remote system.
XSWAPCD ;Put table in swap area
CLFTAB: XADDR. CLFBAD ;Cannot do function 0 on remote node
XADDR. CLFCFG ;Simulate CNFIG%
XADDR. CLFDST ;Simulate DIRST%
XADDR. CLFGTB ;Simulate GETAB%
XADDR. CLFGJI ;Simulate GETJI%
XADDR. CLFGTY ;Simulate GTTYP%
XADDR. CLFINL ;Simulate INLNM%
XADDR. CLFLNS ;Simulate LNMST%
XADDR. CLFMSR ;Simulate MSTR%
XADDR. CLFMTO ;Simulate MTOPR%
XADDR. CLFMUT ;Simulate MUTIL%
XADDR. CLFRCR ;Simulate RCUSR%
XADDR. CLFSKD ;Simulate SKED%
XADDR. CLFSNP ;Simulate SNOOP%
XADDR. CLFSGT ;Simulate SYSGT%
XADDR. CLFTMN ;Simulate TMON%
XADDR. CLFXPK ;Simulate XPEEK%
XADDR. CLFDVC ;Simulate DVCHR%
XADDR. CLFNTF ;Simulate NTINF%
XADDR. CLFSTV ;Simulate STDEV%
XADDR. CLFDVT ;Simulate DEVST%
XADDR. CLFSYS ;Obtain SYSTAT information
XADDR. CLFJOB ;Get job numbers and terminals of user
XADDR. CLFRCD ;Simulate RCDIR%
XADDR. CLFTIM ;Simulate TIME%
TABLEN==<.-CLFTAB-1> ;Table length
SUBTTL CLUDGR Fork -- CLFRUN (Begin running CLUDGR fork here)
;CLFRUN - This is the entry point given to the MSFRK% JSYS to
;get the CLUDGR fork started in monitor context.
;
; Called with:
; T1/ fork handle
; T2/ XCDSEC,,CLFRUN
; MSFRK%
;
; Returns:
; In theory, this routine does not return. It is the start of
; the CLUDGR fork.
;
; [7.1132] - Note that the CLUDGR fork is bound in queue 1 much the
;same as CHKR. If this degrades performance too much, than it can be
;changed back to run as a normal process.
XSWAPCD ;Process context
CLFRUN::MOVX T1,USRCTX ;Start with user context set
MOVEM T1,FFL ;in PC flags
MCENTR ;Start new process
MOVEI T1,JP%SYS+1 ;[7.1132] Clamp it in queue 1 for responsiveness
MOVEM T1,JOBBIT ;[7.1132] Put in PSB so it is known
MOVE T1,FORKX ;Get our fork number
MOVEM T1,CLFORK ;And store it here for future generations
MOVX T1,<SC%GTB!SC%WHL!SC%OPR!SC%CNF!SC%MNT!SC%IPC!SC%DNA!SC%ANA>
;All this and privs too
MOVEM T1,CAPMSK ;Save the capability mask
MOVEM T1,CAPENB ;Now save as if we enabled all of them
TRVAR <REQBLK,CODE,REQID,FRK,FLAGS,CINODE,REMUSR,REMCID> ;Temp data storage for this fork
; REQBLK - Address of request block we are currently working on
; CODE - Function code to perform for remote user
; REQID - Request ID number from remote system
; FRK - Fork number from remote system
; FLAGS - Flags from remote system
; CINODE - Node number of remote system
; REMUSR - 36 bit user number of remote user
; REMCID - CID to send reply on
CLFRN1: HRRZI T1,CLFWAT ;Get scheduler test. No data
MDISMS ;Now sleep until it is time to do something
CLFR15: CALL ZERDAT ;(/) Zero out CLUDGR fork's data areas
CLFR16: SOS CLUFLG ;Say we have seen one request
XMOVEI Q1,CLREQQ ;Previous entry in queue is held here
SKIPN Q2,CLREQQ ;Get entry from request queue
JRST CLFRN1 ;If there are none, then go back to sleep
CLFRN2: MOVE T2,REQFLG(Q2) ;Get flags for this request
TXNN T2,CL%DED ;Is this a dead letter?
IFSKP. ;Yes, it is
CIOFF ;No interruptions while removing entry
MOVE T2,REQFLK(Q2) ;Get next request after the current one
MOVEM T2,REQFLK(Q1) ;And remove the current one
CION ;OK to let more things come in
MOVE T1,Q2 ;Get request block
CALL CLFDED ;(T1/) Now return stuff
SKIPE CLUFLG ;Still more to do?
JRST CLFR16 ;Yes, find it
JRST CLFRN1 ;No, go back to sleep
ENDIF.
TXNN T2,CL%ALL ;Are all items here?
IFSKP. ;Yes, remove this one
CIOFF ;No interruptions while diddling queue
MOVE T2,REQFLK(Q2) ;Get next request after the current one
MOVEM T2,REQFLK(Q1) ;And remove the current one
CION ;We done touching the queue
MOVE T1,Q2 ;Now do the work
CALL CLFALL ;(T1/) Yes, time to reassemble and do some work
SKIPE CLUFLG ;Still more to do?
JRST CLFR15 ;Yes, find it
JRST CLFRN1 ;No, go back to sleep
ENDIF.
MOVE Q1,Q2 ;Now this entry becomes the previous
SKIPN Q2,REQFLK(Q2) ;Keep scanning queue, get next entry
JRST CLFRN1 ;There are no more, back for a nap
JRST CLFRN2 ;Have next request, check it out
SUBTTL CLUDGR Fork -- CLFDED (Dead entry in CLREQQ)
;CLFDED - Routine to handle the dead letters in CLREQQ. We return
;things like free space and SCA buffers at this point. This routine
;can also be called when the CLUDGR fork has reassembled data for
;a request and no longer has a use for the request block and SCA
;buffers.
;
; Called with:
; T1/ Address of request block
; T2/ CID (when calling CLFGVB)
; CALL CLFDED or CALL CLFGVB
;
; Returns:
; +1 - Always, with all SCA buffers and request block returned
XSWAPCD ;Called from process level
CLFGVB: SAVEQ ;Preserve the work registers
JRST CLFDD0 ;Join common code
CLFDED: SAVEQ ;Save work registers
SETZ T2, ;Say which entry we came from
CLFDD0: MOVE Q1,T1 ;Put request block here for safe keeping
SKIPN Q2,REQSCA(Q1) ;Get address of first SCA buffer
JRST CLFDD2 ;If no buffers then just return the request block
CLFDD1: MOVE T3,Q2 ;Get SCA buffer
CALL GIVBCK ;(T2,T3/) And give this buffer to SCA or message free queue
SKIPE Q2,.CLFLI(Q2) ;Get next SCA buffer
JRST CLFDD1 ;And return it
CLFDD2: NOINT ;No interrupts whilest we return free space
MOVE T1,Q1 ;Get address of request block
CALLX (MSEC1,RELRES) ;(T1/) And give it back
OKINT ;Undo NOINT
RET ;Leave the dead letter office
SUBTTL CLUDGR Fork -- CLFALL (All buffers for a request are in)
;CLFALL - Routine called when all SCA buffers for a request on the
;CLREQQ have arrived. Dispatches to the routine to handle the request.
;
; Called with:
; T1/ Request block address
; CALL CLFALL
;
; Returns:
; +1 - Always, with request responded to
XSWAPCD ;Process level code
CLFALL: MOVEM T1,REQBLK ;Stash request block ID here
LOAD T2,REQFUN,(T1) ;Get function request
MOVEM T2,CODE ;Save function code
LOAD T2,REQNUM,(T1) ;Get remote request ID
MOVEM T2,REQID ;Stash it in the TRVAR
LOAD T2,.RQFRK,(T1) ;Get fork number of remote process
MOVEM T2,FRK ;Save fork number here
LOAD T2,.RQNOD,(T1) ;Get remote CI node number for when we answer
MOVEM T2,CINODE ;And stash it
MOVE T2,REQCID(T1) ;Get CID
MOVEM T2,REMCID ;And save it for later
MOVE T2,REQSCA(T1) ;Get address of first SCA buffer
LOAD T3,.CLUSR,(T2) ;And get user number
MOVEM T3,REMUSR ;Store user number
LOAD T3,.CLFLG,(T2) ;Get flags from remote system
HRLZM T3,FLAGS ;And save them for later if we need them
CALL CLFRSP ;(T1/) Reassemble SCA buffers
MOVE T1,REQBLK ;Get request block back
MOVE T2,REMCID ;Get connect ID
CALL CLFGVB ;(T1,T2/) Now return SCA buffers and free space
MOVE T1,CODE ;Remote function code
CAIN T1,CLSND ;Is it special (for TTMSG%)?
CALLRET CLFTMG ;Yes, handle TTMSG% separately
CAILE T1,0 ;Is function in valid range?
CAILE T1,TABLEN ;Between min and max?
IFNSK. ;Bad function
MOVEI T1,INFX09 ;Get error code
CALLRET CLFBAD ;Bad function from remote system
ENDIF. ;Else good function, so do it
CALLRET @CLFTAB(T1) ;Dispatch to the appropriate routine
SUBTTL CLUDGR Fork -- CLFDST (Do DIRST for remote system)
;CLFDST - Called when remote system wants us to do a DIRST% for them.
;
; Called with:
; CLFREA setup
; CALL CLFDST
;
; Returns:
; +1 - Always with data sent to remote system
XSWAPCD ;Fork code
CLFDST: HRROI T1,CLFSCR ;Make DIRST% put string here
MOVE T2,CLFREA ;Get directory number
DIRST% ;Do it
ERJMP DOLAST ;If error, pass error back to user
MOVEI T1,MAXLW+1 ;Send this many words back
CALLRET CLFSND ;(T1/) Done, give remote node the string
SUBTTL CLUDGR Fork -- CLFGTB (Do GETAB% simulation)
;CLFGTB - Routine to do a GETAB% request from a remote system.
;
; Call with:
; CLFREA setup
; CALL CLFGTB
;
; Returns:
; +1 - Always, with results sent across the wire
XSWAPCD ;Fork type code area
CLFGTB: MOVE T1,CLFREA ;Get GETAB% argument
GETAB% ;Do it
ERJMP DOLAST ;Curses, foiled again, give error back
MOVEM T1,CLFSCR ;Stash results here for sending back
CALLRET CL1SND ;(/) Send over 1 word
SUBTTL CLUDGR Fork -- CLFGTY (Do GTTYP% simulation)
;CLFGTY - Simulate a GTTYP% JSYS for a remote node as per an
;INFO% request.
;
; Called with:
; CLFREA setup
; CALL CLFGTY
;
; Returns:
; +1 - Always, with data sent to remote system
XSWAPCD ;Forky codey
CLFGTY: MOVE T1,CLFREA ;Get terminal number
GTTYP% ;Do the JSYS shuffle
ERJMP DOLAST ;Looks like we can't boogie
XMOVEI T4,CLFSCR ;Stash data here
MOVEM T1,.AC1(T4) ;Return non-updated AC1
MOVEM T2,.AC2(T4) ;Give user the results
MOVEM T3,.AC3(T4) ;This is a result too
CALLRET CL3SND ;Send over 3 words
SUBTTL CLUDGR Fork -- CLFINL (Simulate INLNM% JSYS)
;CLFINL - Called when an INFO% request is for the INLNM% JSYS.
;
; Call with:
; CLFREA setup
; CALL CLFINL
;
; Returns:
; +1 - With results sent back to requesting system
XSWAPCD ;CLUDGR fork code
CLFINL: MOVE T1,CLFREA ;Get index that was sent over
HRROI T2,CLFSCR ;Put byte pointer here
INLNM% ;Do the JSYS
ERJMP DOLAST ;OK, give error back to requestor
MOVEI T1,MAXLW+1 ;This is max number to send over
CALLRET CLFSND ;(T1/) Send results back
SUBTTL CLUDGR Fork -- CLFLNS (Logical name translation)
;CLFLNS - Translate a system logical name for a remote user.
;
; Call with:
; CLFREA setup
; CALL CLFLNS
;
; Returns:
; +1 - Always, with results mailed
XSWAPCD ;Fork fun
CLFLNS: MOVEI T1,.LNSSY ;We only do this function
HRROI T2,CLFREA ;User's argument is here
HRROI T3,CLFSCR ;Put translation here
LNMST% ;Do the translation
ERJMP DOLAST ;Shucks
HRRZ T1,T3 ;[7.1114] Get ending point
AOS T1 ;Make extra word in case we ended right on a word boundry
HRRZI T3,CLFSCR ;[7.1114] Get starting point
SUB T1,T3 ;[7.1114] Subtract to find out how many words to return
CALLRET CLFSND ;(T1/) Send over results
SUBTTL CLUDGR Fork -- CLFJOB (Find jobs of given user)
;CLFJOB - Find all jobs and terminals of given user name string and
;pass this back to requesting system.
;
; Call with:
; CLFREA setup
; CALL CLFJOB
;
; Returns:
; +1 - Always with results fired back to requesting system
XSWAPCD ;Fork code
CLFJOB: SAVEQ ;Save these
STKVAR <USRNUM> ;Temp storage
MOVX T1,RC%EMO ;We must have an exact match
HRROI T2,CLFREA ;User name string is here
RCUSR% ;Get user number
ERJMP DOLAST ;Give last error to remote system
TXNN T1,RC%NOM ;No match?
IFSKP. ;If not,
MOVEI T1,STRX08 ;Say bad user name
CALLRET CLFBAD ;And return
ENDIF.
HRRZM T3,USRNUM ;Save user number for later
XMOVEI Q2,CLFSCR ;Results go here
AOS Q2 ;Move past .JOLEN word
MOVSI Q1,-NJOBS ;Make AOBJN pointer
DO. ;Loop through all jobs
MOVE T1,JOBDIR(Q1) ;Get job's logged in number
CAME T1,USRNUM ;Same as the one we are looking for?
IFSKP. ;If so,
HRRZ T1,Q1 ;Get local job number
CALLX (MSEC1,LCL2GL) ;(T1/T1) Translate it to global
JRST CLFBAD ;On failure, pass back error
HRLZS T1 ;Put job number in left half
HLR T1,JOBPT(Q1) ;Get terminal number
MOVEM T1,(Q2) ;Now save terminal number
AOS Q2 ;Bump to next data word
AOS CLFSCR ;Count this word
ENDIF.
AOBJN Q1,TOP. ;Do next job
ENDDO.
SKIPE CLFSCR ;User not logged in?
IFSKP. ;Yes,
MOVEI T1,INFX07 ;Say so
CALLRET CLFBAD ;And return to remote system with this
ENDIF.
AOS T1,CLFSCR ;This is how many words to send to remote node
CALLRET CLFSND ;(T1/) Send the data and return
ENDSV.
SUBTTL CLUDGR Fork -- CLFMTO (Do MTOPR% function)
;CLFMTO - Called to perform some random MTOPR% function. CLUDGR fork can
;only do the functions listed in MTOTAB. If a function requested is past
;over, this system will return a INFX14 error to the remote node.
;
; Call with:
; CLFREA setup
; CALL CLFMTO
;
; Returns:
; +1 - Always, with results fired over to requestor
XSWAPCD ;Fork work code
CLFMTO: SAVEQ ;We touch these
XMOVEI Q2,CLFREA ;Data is in here
MOVE T1,.AC2(Q2) ;Get user's function
MOVSI Q1,-MTOLEN ;Make AOBJN pointer
DO. ;Loop over all entries
CAMN T1,MTOTAB(Q1) ;Do we match the function?
EXIT. ;Yes we do, got a legal one
AOBJN Q1,TOP. ;No, keep scanning
MOVEI T1,INFX14 ;Couldn't find a legal function
CALLRET CLFBAD ;Say so and give it to remote system
ENDDO.
MOVE T1,.AC1(Q2) ;Get device
DMOVE T2,.AC2(Q2) ;Get arguments (if necessary)
CALLX (MSEC1,DOMTO) ;[7.1104] (T1-T3/T1-T3) Do the MTOPR%
JRST DOLAST ;[7.1104] It failed
XMOVEI Q2,CLFSCR ;Put results in here for remote user
DMOVEM T1,.AC1(Q2) ;Pass this back datum
MOVEM T3,.AC3(Q2) ;And the final one of the trilogy
CALLRET CL3SND ;Send over 3 words
SUBTTL CLUDGR Fork -- DOMTO (Section 0 MTOPR%)
;[7.1104]
;Note that the following section of code (no matter how gross or
;disgusting it looks) must be. MTOPR% does not work if it is executed
;outside of section 0! It assumes that T1 will have a OWGB instead
;of a universal device designator.
SWAPCD ;Must be in section 0/1
DOMTO: S0.ENT ;Section 0 darn it!
MTOPR% ;Do MTOPR%
ERJMP R ;We had a failure
RETSKP ;We succeeded so continue
SUBTTL CLUDGR Fork -- CLFMUT (Do remote MUTIL% request)
;CLFMUT - Supporting routine for CLUDGR's fork to do a request
;of the MUTIL% JSYS on this node.
;
; Call with:
; CLFREA setup
; CALL CLFMUT
;
; Returns:
; +1 - Always, with results mailed back to requestor
XSWAPCD ;Fork code execution
CLFMUT: SAVEQ ;We touch these
XMOVEI Q2,CLFREA ;Data is in here
MOVE T1,.AC2(Q2) ;Get user's function
MOVSI Q1,-MUTLEN ;Make AOBJN pointer
DO. ;Loop over all entries
CAMN T1,MUTTAB(Q1) ;Do we match the function?
EXIT. ;Yes we do, got a legal one
AOBJN Q1,TOP. ;No, keep scanning
MOVEI T1,INFX14 ;Couldn't find a legal function
CALLRET CLFBAD ;Say so and give it to remote system
ENDDO.
MOVEM T1,CLFSCR ;Put function in our argument block
MOVE T1,.AC1(Q2) ;Get remote user's argument block size
XMOVEI T2,CLFSCR ;Here's our MUTIL% return address
MUTIL% ;Get the information
ERJMP DOLAST ;Pass back our failure
CALLRET CLFSND ;(T1/) And give to remote user
SUBTTL CLUDGR Fork -- CLFRCR/CLFRCD (RCUSR%/RCDIR% service)
;CLFRCR/CLFRCD - Called when the remote system needs an RCUSR%/RCDIR%
;JSYS done on this node.
;
; Call with:
; CLFREA setup
; CALL CLFRCR
; or
; CALL CLFRCD
;
; Returns:
; +1 - Always, with results filed to remote system
XSWAPCD ;Fork code
CLFRCR: SKIPA T1,[RCUSR] ;Flag that an RCUSR% is to be done
CLFRCD: MOVE T1,[RCDIR] ;Flag we want RCDIR%
SAVEQ ;Save the temps
STKVAR <DOJSYS> ;Place to save the JSYS
MOVEM T1,DOJSYS ;Save the JSYS to do
XMOVEI Q1,CLFREA ;Here's where the data is
MOVE T1,.AC1(Q1) ;Get the flags
MOVE T3,.AC2(Q1) ;Get the user/directory number in case of stepping
XMOVEI T2,.AC3(Q1) ;Now for the user/directory name
HRLI T2,(POINT 7,) ;Make it a 7 bit byte pointer
XCT DOJSYS ;Do the simulation
ERJMP DOLAST ;When failing, give error back to remote
XMOVEI Q1,CLFSCR ;Here's the data page to stash results in
MOVEM T1,.AC1(Q1) ;Pass back these flags
MOVEM T3,.AC2(Q1) ;Now pass back the user/directory number
CALLRET CL3SND ;Send over 3 words
ENDSV.
SUBTTL CLUDGR Fork -- CLFSNP (Simulate SNOOP%)
;CLFSNP - Routine to make CLUDGR fork do a SNOOP% JSYS for a remote
;node.
;
; Call with:
; CLFREA setup
; CALL CLFSNP
;
; Returns:
; +1 - Always, with results sent back
XSWAPCD ;Fork code
CLFSNP: MOVE T1,CLFREA ;Get function code from remote
CAIN T1,.SNPSY ;Is it this?
JRST CLFSP1 ;Yes, do it
CAIN T1,.SNPAD ;Or this?
IFSKP. ;If neither,
MOVEI T1,INFX14 ;Then say we don't do this
CALLRET CLFBAD ;And give it to remote caller
ENDIF.
CLFSP1: XMOVEI Q1,CLFREA ;Now get symbol name
MOVE T2,.AC2(Q1) ;Here it is, do the JSYS
MOVE T3,.AC3(Q1) ;Get this argument too
SNOOP% ;Do the work
ERJMP DOLAST ;If failure, let user know
XMOVEI T1,CLFSCR ;Here's where the data is going
DMOVEM T2,.AC2(T1) ;Stash T2 and T3
CALLRET CL3SND ;Send over 3 words
SUBTTL CLUDGR Fork -- CLFSGT (Routine to do SYSGT%)
;CLFSGT - Called by CLUDGR fork to handle a remote request for
;SYSGT% JSYS.
;
; Call with:
; CLFREA setup
; CALL CLFSGT
;
; Returns:
; +1 - Always, with results federal expressed to requesting CI node
XSWAPCD ;Fork code
CLFSGT: MOVE T1,CLFREA ;Get SIXBIT name
SYSGT% ;Do the JSYS shuffle
ERJMP DOLAST ;Handle badness
DMOVEM T1,CLFSCR ;Here's the results
CALLRET CL2SND ;Send over 2 words
SUBTTL CLUDGR Fork -- CLFTMN (Routine to do TMON%)
;CLFTMN - Called by CLUDGR fork to handle a remote request for
;TMON% JSYS.
;
; Call with:
; CLFREA setup
; CALL CLFTMN
;
; Returns:
; +1 - Always, with results federal expressed to requesting CI node
XSWAPCD ;Fork code
CLFTMN: MOVE T1,CLFREA ;Get function code
TMON% ;Do the JSYS shuffle
ERJMP DOLAST ;Handle badness
XMOVEI T1,CLFSCR ;Return setting here
MOVEM T2,.AC2(T1) ;Here's the results
CALLRET CL2SND ;Send over 2 words
SUBTTL CLUDGR Fork -- CLFSKD (Simulate SKED% JSYS)
;CLFSKD - Called when the remote system has requested a SKED% function.
;Legal remote SKED% functions are in SKDTAB.
;
; Call with:
; CLFREA setup
; CALL CLFSKD
;
; Returns:
; +1 - Always, with results sent to requesting system
XSWAPCD ;Process level code
CLFSKD: SAVEQ ;Save the quasi's
MOVE T1,CLFREA ;Get function code
MOVSI Q1,-SKDLEN ;Scan table for legal functions
DO. ;Loop through each entry
CAMN T1,SKDTAB(Q1) ;Good function?
EXIT. ;Yes, do it
AOBJN Q1,TOP. ;No, check the next one
MOVEI T1,INFX14 ;Couldn't find this one, can't do it
CALLRET CLFBAD ;Say naughty, naughty to remote system
ENDDO.
XMOVEI Q2,CLFREA ;Now that we have a function, get arg block length
XMOVEI T2,CLFSCR ;Return data here when we JSYS
MOVE T3,.AC2(Q2) ;Argument block length here
MOVEM T3,.SACNT(T2) ;Save our argument block lenght for JSYS
MOVE T3,.AC3(Q2) ;Get job number (if necessary)
MOVEM T3,.SAJOB(T2) ;Save it for JSYS
SKED% ;Do it
ERJMP DOLAST ;If failed, handle error
MOVEI T1,<.SACLU+1> ;Succeeded, only send maximum possible block back
CALLRET CLFSND ;(T1/) And do the send
SUBTTL CLUDGR Fork -- CLFXPK (Simulate XPEEK%)
;CLFXPK - Called when a remote system has a request for the local system
;to handle and this request is to do an XPEEK% on the local system.
;
; Call with:
; CLFREA setup
; CALL CLFXPK
;
; Returns:
; +1 - Always, with results set to requesting system
XSWAPCD ;Fork code
CLFXPK: XMOVEI T1,CLFSCR ;Place results in this page
XMOVEI T2,CLFREA ;Our argument block is here
MOVEM T1,.XPUAD(T2) ;Store destination data area in argument block
MOVE T1,.XPCN1(T2) ;Get requested size
CAIG T1,PGSIZ ;Small enough?
IFSKP. ;If not,
MOVEI T1,INFX17 ;Say this is too big
CALLRET CLFBAD ;And pass back this error code
ENDIF.
XMOVEI T1,CLFREA ;Here's the argument block
XPEEK% ;Do the work
ERJMP DOLAST ;We had an error, let remote know about it
MOVE T1,.XPCN2(T1) ;This is how many words to send back
CALLRET CLFSND ;(T1/) Now send them
SUBTTL CLUDGR Fork -- CLFDVC (Do the DVCHR%)
;CLFDVC - Routine called when CLUDGR fork has a request to do a
;DVCHR% JSYS.
;
; Call with:
; CLFREA setup
; CALL CLFDVC
;
; Returns:
; +1 - Always, with results returned to remote system
XSWAPCD ;Fork code
CLFDVC: MOVE T1,CLFREA ;Get device designator
DVCHR% ;Do the JSYS
ERJMP DOLAST ;We failed
XMOVEI T4,CLFSCR ;Here's where returned data goes
DMOVEM T1,.AC1(T4) ;Save this as returned data
MOVEM T3,.AC3(T4) ;And last but not least this too
CALLRET CL3SND ;Push over 3 words
SUBTTL CLUDGR Fork -- CLFSTV (Do STDEV% for remote)
;CLFSTV - Called when a request has been received to simulate the
;STDEV% JSYS on this system.
;
; Call with:
; CLFREA setup
; CALL CLFSTV
;
; Returns:
; +1 - Always, with results flown back on the CI
XSWAPCD ;Fork like code
CLFSTV: HRROI T1,CLFREA ;Here's the device name
STDEV% ;Get device designator
IFJER. ;When failed,
MOVE T1,T2 ;Error code in wrong AC
CALLRET CLFBAD ;Pass it back to requestor
ENDIF.
XMOVEI T1,CLFSCR ;Here's where to store device designator
MOVEM T2,.AC2(T1) ;Store results
CALLRET CL2SND ;Send over 2 words
SUBTTL CLUDGR Fork -- CLFDVT (Remote DEVST% working routine)
;CLFDVT - Routine called to do the work for a request that a DEVST%
;monitor call be performed on this system with results given back
;to remote system.
;
; Call with:
; CLFREA setup
; CALL CLFDVT
;
; Returns:
; +1 - Always, with results fired back to requestor
XSWAPCD ;Fork type code
CLFDVT: HRROI T1,CLFSCR ;Make DEVST% put string here
MOVE T2,CLFREA ;Get device designator
DEVST% ;Do it
ERJMP DOLAST ;If error, pass error back to user
MOVEI T1,MAXLW+1 ;Send this many words back
CALLRET CLFSND ;(T1/) Done, give remote node the string
SUBTTL CLUDGR Fork -- CLFNTF (Do NTINF% for remote)
;CLFNTF - Called when CLUDGR fork has a request for a NTINF% JSYS
;and this system is the sucker to handle the request.
;
; Call with:
; CLFREA setup
; CALL CLFNTF
;
; Returns:
; +1 - Always, with results sent back
XSWAPCD ;Fork code
CLFNTF: SAVEQ ;We use these politely
XMOVEI T1,CLFSCR ;Here's the argument block for the JSYS
XMOVEI Q1,CLFREA ;Here's the passed over data
MOVE T2,.NWABC(Q1) ;Get argument block count
MOVEM T2,.NWABC(T1) ;Prepare it for JSYS
MOVE T2,.NWFNC(Q1) ;Get function code
MOVEM T2,.NWFNC(T1) ;Save in argument block
SKIPL T2,.NWLIN(Q1) ;Get terminal number
IFSKP. ;If -1,
MOVEI T1,INFX14 ;Say this is bad
CALLRET CLFBAD ;And pass back the error
ENDIF.
MOVEM T2,.NWLIN(T1) ;Save in argument block
HRROI T2,CLFSCR ;Make a byte pointer for destination name
ADDI T2,<.NWNU1+2> ;And make it point past argument block
MOVEM T2,.NWNNP(T1) ;Save it in argument block
NTINF% ;Do the JSYS
ERJMP DOLAST ;Tell remote something went wrong
MOVEI T1,<.NWNU1+2+3*MAXLW> ;This is how many to send back
CALLRET CLFSND ;(T1/) Send it back
SUBTTL CLUDGR Fork -- CLFGJI (Do remote GETJI% for someone)
;CLFGJI - Supporting routine to handle a GETJI% request from another
;node.
;
; Call with:
; CLFREA setup
; CALL CLFGJI
;
; Returns:
; +1 - Always, with results rifled back to requestor
XSWAPCD ;Process level code
CLFGJI: SAVEPQ ;Save these
XMOVEI Q1,CLFREA ;Reassembled data is here
XMOVEI Q2,CLFSCR ;New ACs and results go here for return flight
SKIPL T1,.AC1(Q1) ;Get job number/tty number
IFSKP. ;If -1,
MOVEI T1,INFX14 ;Then no can do
CALLRET CLFBAD ;And tell other system
ENDIF.
HLLZ T2,.AC2(Q1) ;Get -count into this AC
HRR T2,Q2 ;Get argument block address
ADDI T2,3 ;Bump past 3 ACs to be sent back
MOVE T3,.AC3(Q1) ;Now get offset of first entry
MOVEI P1,.JISRM ;Here's the session remark word
SUB P1,T3 ;See if session remark requested
IFGE. P1 ;Session remark needed?
MOVEI P2,CLFSCR ;Stuff goes here
ADDI P2,<3+.JILJI+1> ;Session remark starts here
HRROS P2 ;Make it a byte pointer
MOVEM P2,CLFSCR(P1) ;Save session remark byte pointer here
ENDIF. ;Now do the JSYS
GETJI% ;Get the information
ERJMP DOLAST ;It didn't work
MOVEM T1,.AC1(Q2) ;Save updated this
MOVEM T2,.AC2(Q2) ;Save updated that
MOVEM T3,.AC3(Q2) ;Save updated the other thing
MOVEI T1,<3+.JILJI+MAXLW> ;Make sure we send this many words
CALLRET CLFSND ;(T1/) Give results to remote system
SUBTTL CLUDGR Fork -- CLFSYS (Get SYSTAT stuff for remote)
;CLFSYS - Called when a request on the CLUDGR request queue is asking
;for some SYSTAT information for a particular job/terminal.
;
; Call with:
; CLFREA setup
; CALL CLFSYS
;
; Returns:
; +1 - Always, with results sent to requesting node
;
; Note, this routine returns data in this order:
;Word 0 - Program name
;Word 1 - Controlling TTY
;Word 2 - Controlling job
;Word 3 - Global job number
;Word 4 - (-1=RUN) or (0=TI) state
;Word 5 - Job runtime
;Word 6 - Runtime limit
;Word 7 - Job class
;Word 10 - Job share
;Word 11 - Job use
;Word 12-21 - User name string
;Word 22-41 - Connected directory string
;Word 42-71 - Origin string
XSWAPCD ;Fork code
CLFSYS: SAVEPQ ;These are abused
STKVAR <JOB,TTY,<SKDBLK,7>,<NTNBLK,10>,<ORGSTR,3*MAXLW>> ;Temp storage
MOVE T1,CLFREA ;Get job/terminal number
TXZN T1,.TTDES ;Did remote user give us a terminal?
IFSKP. ;If so,
MOVEM T1,TTY ;Save terminal number for later
CAIL T1,0 ;Make sure terminal number is in range
CAILE T1,NLINES ;Is it?
IFNSK. ;No,
MOVEI T1,GTJIX2 ;Say terminal out of range
CALLRET CLFBAD ;And give it back to remote user
ENDIF.
MOVE T2,TTY ;Get terminal in correct AC
NOSKED ;Not while we are touching TTY database stuff
CALLX (MSEC1,GTCJOB) ;(T2/T3) Get controlling job number
IFNSK. ;If none,
OKSKED ;We are done
CALLRET CLFBAD ;And give the error back to remote system
ENDIF.
OKSKED ;Terminal data base done being looked at
MOVEM T3,JOB ;Save job number for later
ELSE. ;If no,
CALLX (MSEC1,GL2LCL) ;(T1/T1) Get local job number
CALLRET CLFBAD ;Failed, tell remote system
MOVEM T1,JOB ;And save it
ENDIF.
NOINT ;Don't bother me while I get the job's JSB
MOVE T1,JOB ;Get job number
CALLX (MSEC1,MAPJSB) ;(T1/T1) Map in foreign JSB
IFNSK. ;If no job,
OKINT ;Interrupts are OK
MOVEI T1,GTJIX4 ;Say so
CALLRET CLFBAD ;And send back our response
ENDIF.
MOVE Q2,T1 ;Save JSB offset for use later
XMOVEI Q1,CLFSCR ;Store data in the scratch area
MOVE T1,JOB ;Get job number
MOVE T2,JOBPNM(T1) ;Get job program name
MOVEM T2,(Q1) ;Save it in send block
AOS Q1 ;Move on to next word in block
MOVE T2,CTRLTT(Q2) ;Get controlling terminal
MOVEM T2,(Q1) ;Save it for sending
MOVEM T2,TTY ;Also, make sure we have TTY number
AOS Q1 ;Get ready for next datum
NOSKED ;Again, NOSKED while getting TTY stuff
CALLX (MSEC1,GTCJOB) ;(T2/T3) Get controlling terminal for this job
IFNSK. ;If failed,
OKSKED ;Allow scheduling
CALLX (MSEC1,CLRJSB) ;(/) Clear our JSB mapping and go OKINT
MOVEI T1,GTJIX2 ;Say error
CALLRET CLFBAD ;And return info to remote node
ENDIF.
OKSKED ;We now have the controlling job
MOVEM T3,(Q1) ;Store it for sending
AOS Q1 ;Move on to next word
MOVE T1,JOB ;Retrieve local job number
CALLX (MSEC1,LCL2GL) ;(T1/T1) Get global job number
IFNSK. ;If failure (shouldn't happen)
CALLX (MSEC1,CLRJSB) ;(/) Clear JSB mapping
CALLRET CLFBAD ;And give error back to caller
ENDIF.
MOVEM T1,(Q1) ;Save job number in data area
MOVE P2,T1 ;Get global job here for later
AOS Q1
SKIPGE T2,TTY ;Get TTY back
IFSKP. ;If line is active,
MOVE T1,TTACTL(T2) ;Get line block
LOAD T1,TWFRK,(T1) ;Get forks waiting for TI
SETOM (Q1) ;Assume running
CAIE T1,-1 ;Is it running
SETZM (Q1) ;No, say TI
ENDIF.
AOS Q1 ;Bump to next data word
MOVE T1,JOBRT(P1) ;Get job runtime too
MOVEM T1,(Q1) ;It is going to be passed back
AOS Q1 ;Next...
MOVE P1,JOB ;Get job number for this AC
CALL GETRTL ;[7.1200] (P1/T1) Get runtime limit
MOVEM T1,(Q1) ;Save it here
AOS Q1 ;Next data item
SKIPN CLASSF ;[7.1105] Class scheduling on?
IFSKP. ;If so,
MOVEI T2,SKDBLK ;Put SKED% results here
MOVEI T1,7 ;Argument block length
MOVEM T1,.SACNT(T2) ;Save count for JSYS
MOVEM P2,.SAJOB(T2) ;Stash global job in arg block
MOVEI T1,.SKRJP ;Read job parameters
SKED% ;From scheduler database
IFJER. ;If we failed,
CALLX (MSEC1,CLRJSB) ;(/) Clear JSB mapping
CALLRET DOLAST ;And past back our process error to remote
ENDIF.
MOVE T1,.SAJCL(T2) ;Get job's class
MOVEM T1,(Q1) ;Save for sending
AOS Q1 ;Move on to next storage word
MOVE T1,.SAJSH(T2) ;Get job's share
MOVEM T1,(Q1) ;Pass it along
AOS Q1 ;Next word
MOVE T1,.SAJUS(T2) ;Now for utilization
MOVEM T1,(Q1) ;Save it too
AOS Q1 ;Now ready for byte strings
ELSE. ;Class scheduling was not on
ADDI Q1,3 ;So account for the three words we didn't fill in
ENDIF.
MOVE P2,JOB ;Get local job number
SKIPE T1,JOBDIR(P2) ;Get logged in directory
IFSKP. ;If not logged in
MOVEI T1,3 ;Then blast not logged in string
XMOVEI T2,NOTLOG ;Here's the string
ELSE. ;Else, user for real
MOVEI T1,MAXLW ;This is how many words for user name string
XMOVEI T2,USRNAM(Q2) ;User name stored here in JSB
ENDIF.
AOS T2 ;But text starts one word later
XMOVEI T3,(Q1) ;Put user name here
CALLX (MSEC1,XBLTAT) ;(T1,T2,T3/T1,T2,T3) Blast user name in block
ADDI Q1,MAXLW ;Account for user name
MOVE T2,JSBSDN(Q2) ;Get connected directory number
HRRO T1,Q1 ;Now put in connected directory string
DIRST% ;Get it from monitor
IFJER. ;If failed,
HRROI T2,[ASCIZ /?/] ;Say we don't know
SETZB T3,T4 ;Terminate on the null
SOUT% ;Put "?" in data area
ERJMP .+1 ;Shouldna happen
ENDIF.
ADDI Q1,2*MAXLW ;Now blow past connected directory string
CALLX (MSEC1,CLRJSB) ;(/) Clear foreign JSB mapping and go OKINT
MOVEI T1,NTNBLK ;NTINF% info goes here
SETZM .NWFNC(T1) ;Say function .NWRHH
MOVEI T2,ORGSTR ;Destination string goes here
HRROM T2,.NWNNP(T1) ;Store it in NTINF% argument block
MOVEI T2,10 ;Count of words in NTINF% block
MOVEM T2,.NWABC(T1) ;Tell JSYS how many
MOVE T2,TTY ;Get terminal back
TXO T2,.TTDES ;Make it TTY device designator
MOVEM T2,.NWLIN(T1) ;Save for NTINF%
NTINF% ;Do the JSYS
ERJMP CLFSY2 ;If failed, don't care
MOVE Q2,.NWTTF(T1) ;Get terminal origin flags
LDB Q2,[POINT 9,Q2,17] ;Get flags
CAIN Q2,NW%NNT ;Non network terminal?
JRST CLFSY2 ;Yes, send off data to remote
HRROI T2,ORGSTR ;Get origin node
HRRO T1,Q1 ;Get destination of origin string
SETZB T3,T4 ;Terminate on null
SOUT% ;Blast string
ERJMP .+1 ;Never happens
MOVEI T2,NTNBLK ;Now find out what kind of terminal it was
MOVE T2,.NWTTF(T2) ;Get type word
LDB T2,[POINT 9,T2,17] ;Only get these flags
CAIE T2,NW%TCP ;TCP terminal?
IFSKP. ;If so,
HRROI T2,SYSTCP ;Say so
JRST CLFSY1 ;And put it in
ENDIF.
MOVEI T2,NTNBLK ;Not TCP, get other flags
HRRZ T2,.NWTTF(T2) ;Here they are
CAIE T2,NW%LH ;LAT terminal?
IFSKP. ;If so,
HRROI T2,SYSLAT ;Get LAT origin string
JRST CLFSY1 ;And put it in
ENDIF.
CAIE T2,NW%CH ;CTERM terminal?
IFSKP. ;If so,
HRROI T2,SYSCTM ;Put CTM in string
JRST CLFSY1 ;Do it
ENDIF.
HRROI T2,SYSNRT ;Must be a NRT terminal then
CLFSY1: SETZB T3,T4
SOUT%
ERJMP .+1
ADDI Q1,3*MAXLW ;Account for origin in block to be returned
CLFSY2: MOVE T1,Q1 ;Get current scratch page pointer
XMOVEI T2,CLFSCR ;Get scratch page address
SUB T1,T2 ;This is how many words to send to remote system
CALLRET CLFSND ;(T1/) Do the send and return to process more requests
ENDSV.
SUBTTL CLUDGR Fork -- CLFCFG (Do CNFIG% request)
;CLFCFG - Called when it is time to do a CNFIG% for a remote system.
;
; Call with:
; CLFREA setup
; CALL CLFCFG
;
; Returns:
; +1 - Always, with results sent back to requestor
XSWAPCD ;Process level stuff
CLFCFG: XMOVEI T2,CLFSCR ;Put results in this space
XMOVEI T1,CLFREA ;Get function code and length or argument block
MOVE T3,1(T1) ;This is the length of the argument block
MOVEM T3,CLFSCR ;Store length here for CNFIG%
MOVE T1,CLFREA ;Get function code for us to do
CNFIG% ;Get the data
ERJMP DOLAST ;Get last error and pass it across CI
MOVEI T1,<4*HSTSIZ> ;Send back this many words
CALLRET CLFSND ;(T1/) Now send reponse back
SUBTTL CLUDGR Fork -- CLFMSR (Do MSTR%)
;CLFMSR - Routine that does an MSTR% JSYS on behalf of the remote
;system
;
; Called with:
; CLFREA setup
; CALL CLFMSR
;
; Returns:
; +1 - Always, with reponse mailed to reqesting system
XSWAPCD ;CLUDGR Fork man
CLFMSR: SAVEQ ;Save quasi preserved thingies
XMOVEI Q2,CLFREA ;Get reassembled data area
XMOVEI Q3,CLFSCR ;Working page area
HRR T1,.AC1(Q2) ;Get user's function
CAIN T1,.MSGSS ;Is it this function?
JRST CLMSR2 ;OK, don't need privs neither
CAIN T1,.MSGSU ;How about this one?
JRST CLMSR2 ;Yep, don't check privs
CAIN T1,.MSRNU ;Or maybe this?
JRST CLMSR1 ;Check privs first
CAIN T1,.MSRUS ;This is it...
IFSKP. ;The function given was bad
MOVEI T1,INFX14 ;Say we can't do this function
CALLRET CLFBAD ;And return
ENDIF.
CLMSR1: MOVE T1,FLAGS ;Get user flags
TXNE T1,CL%PRV!CL%GAL ;Is remote GALAXY or prived?
IFSKP. ;Tis neither
MOVEI T1,MSTRX2 ;No privs, chump
CALLRET CLFBAD ;Get outta here
ENDIF.
CLMSR2: HRRZ Q1,T1 ;Save the function briefly
XMOVEI T3,CLFSCR ;This is where to put responses
XMOVEI T2,CLFREA ;User's arg block is down passed
ADDI T2,.INMAX ;These many words in CLFREA
HLRZ T1,.AC1(Q2) ;Get count of arg block
CAIG T1,.MSRLN ;Is it too big?
IFSKP. ;If so,
MOVEI T1,.MSRLN ;This is the max
HRLM T1,.AC1(Q2) ;And correct for it
ENDIF.
CALLX (MSEC1,XBLTAT) ;(T1-T3/T1-T3) Get it from CLFREA and put in CLFSCR
CAIE Q1,.MSRNU ;If this function or
CAIN Q1,.MSRUS ;If this function, then no structure either
JRST CLMR35 ;Set up byte pointers for return
SKIPL T1,.INMAX(Q2) ;Get "byte pointer" to structure
JRST CLMSR3 ;No byte pointer, we have device designator
MOVEI T1,<.INMAX+.MSRLN+1> ;[7.1094] Byte string starts at this offset
ADD T1,Q2 ;Get absolute address of byte string
HRROM T1,(Q3) ;[7.1094] Make this -1,,addr of structure string
CLMSR3: CAIE Q1,.MSGSS ;Must we check for physical ID too?
JRST CLMSR4 ;No, get the MSTR% data
MOVEI T1,<.INMAX+.MSGLN> ;Find string to put physical str name
ADD T1,Q2 ;Get the absolute offset
SKIPL (T1) ;If don't want this,
JRST CLMSR4 ; then fine, go on
MOVEI T1,<.INMAX+.MSGLN> ;Put physical name byte pointer at this offset
ADD T1,Q3 ;In scratch area to be sent back
HRROM T1,.MSGSI(Q3) ;[7.1094] Stick byte pointer here in arg block
JRST CLMSR4 ;Now do the MSTR%
;Here to set up structure name and alias byte pointers.
CLMR35: XMOVEI T1,CLFSCR ;Get scratch pad
XMOVEI T2,.MSRLN(T1) ;This is where byte pointer is going
HRROS T2 ;Make byte pointer
MOVEM T2,.MSRSN(T1) ;Put byte pointer here
ADDI T2,2 ;Alias goes 2 words later
MOVEM T2,.MSRSA(T1) ;Put it in MSTR% arg block
CLMSR4: MOVE T1,Q1 ;Get function back
HLL T1,.AC1(Q2) ;Put arg block length here too
XMOVEI T2,CLFSCR ;Make MSTR% put results here
MSTR% ;Do the MSTR%
ERJMP DOLAST ;Return last error to our requestor
MOVEI T1,<.INMAX+.MSRLN+MAXLW+1> ;Give back this many words
CALLRET CLFSND ;(T1/) Data page now ready to be sent
SUBTTL CLUDGR Fork -- CLFTIM (Do TIME% simulation)
;CLFGTB - Routine to do a TIME% request from a remote system.
;
; Call with:
; CLFREA setup
; CALL CLFTIM
;
; Returns:
; +1 - Always, with results sent across the wire
XSWAPCD ;Fork type code area
CLFTIM: MOVE T1,TODCLK ;Here's our uptime
MOVEM T1,CLFSCR ;Stash results here for sending back
CALLRET CL1SND ;Send only 1 word
SUBTTL CLUDGR Fork -- CLFTMG (Do TTMSG% request)
;CLFTMG - This is called when in coming packets represent a request for
;a remote TTMSG% and this node is the sucker to do the work. It always
;sends back a one word reply. This word either contains an error code
;when we failed or it has 0 meaning we succeeded.
;
; Call with:
; CLFREA setup
; CALL CLFTMG
;
; Returns:
; +1 - Always, with results sent back to requestor
XSWAPCD ;Fork context code
CLFTMG: XMOVEI T2,CLFREA ;Here's where we find it all
MOVE T1,(T2) ;This gets the terminal designator
MOVE T3,FLAGS ;Get flags from remote system
TXNE T3,CL%PRV!CL%GAL ;Check to see if prived or GALAXY
IFSKP. ;If not,
CAIE T1,.TTTTY ;If user wants all terminals
IFSKP. ;If so, and he ain't prived,
MOVEI T1,GTDIX1 ;Say he needs privs
CALLRET CLFBAD ;And get out of here
ENDIF.
TXZ T1,.TTDES ;Clear terminal designator and just get line #
CAIL T1,0 ;Range check the line
CAILE T1,NLINES ;Is it within range?
JRST CLFTM1 ;No, just TTMSG%, it will fail and then pass back error
JN TTNTM,(T1),NOTMG ;User inhibiting?
JE TTNUM,(T1),CLFTM1 ;Or is he refusing user messages?
JRST NOTMG ;Yes, can't let this go
ELSE.
CAIN T1,.TTTTY ;Want all terminals?
SETO T1, ;Yes, flag so
ENDIF.
CLFTM1: TXO T1,.TTDES ;Make .TTDES again
AOS T2 ;Now this is where the send all stuff is
HRLI T2,(POINT 7,) ;Stuff was sent over in 7 bit
TTMSG% ;The the TTMSG% for the user
ERJMP ERRTMG ;Do last error
SETZM CLFSCR ;This indicates send was successful
CALLRET CL1SND ;Send over 1 word
ERRTMG: SKIPA T1,LSTERR ;Get last error
NOTMG: MOVEI T1,TTMSX2 ;User refusing
TXO T1,IN%RER ;Say error from remote
CALLRET CLFBAD ;Tell remote system
SUBTTL CLUDGR Fork -- CLFBAD (Bad function from remote)
;CLFBAD - Routine to handle a bad function or error. We get here when a
;remote system sends us a CLUDGR request but we can't do it because it is
;not in our dispatch table or if we tried to do the request and some kind of
;error occurred while executing the request.
;
; Call with:
; T1/ Error code (if 0, error code gotten out of LSTERR)
; CALLRET CLFBAD
; or
; CALLRET DOLAST (when LSTERR is to be used)
;
; Returns:
; +1 - Always with remote system notified
XSWAPCD ;Done at process level
DOLAST: SETZ T1, ;Here when we want LSTERR
CLFBAD: STKVAR <ERROR,RETADR,TRIES,SCABUF> ;Place to save error code
SKIPN T1 ;If nothing passed in,
MOVE T1,LSTERR ;then get our last error
MOVEM T1,ERROR ;Save error code whilest we get SCA buffer
MOVEI T1,1 ;Tell SCA we only want a single buffer
CALL <XENT SC.ABF> ;(T1/T1,T2,T3) get an SCA buffer
CLFNOB: BUG. (HLT,CLUOSB,CLUFRK,SOFT,<CLUDGR fork could not get an SCA buffer>,,<
Cause: A request was made for CLUDGR fork to do something. Unfortunately,
this request failed for one reason or another. When CLUDGR fork
tried to tell the remote system it failed, the fork could not
get an SCA buffer to reply. This should not happen as SCA uses
an entire section for buffers.
>) ;What do you mean no buffers?
MOVEM T3,RETADR ;This is where return buffer
MOVEM T1,SCABUF ;Save SCA buffer address
AOS CLUBUF ;Say another buffer in use by CLUDGR
MOVX T2,CL%REQ ;Say this is a response
ANDCAM T2,FLAGS ;By clearing this bit
MOVX T2,CL%ERR ;Now say we had an error
IORM T2,FLAGS ;By setting this bit
BLCAL. (FILLIN,<T1,FLAGS,REQID,CODE,FRK,CINODE,REMUSR,[1]>) ;[7.1090]
;[7.1090] Fill in SCA buffer chain
MOVE T1,SCABUF ;Get SCA buffer address back
MOVE T2,ERROR ;Get error code back
MOVEM T2,CLDATA(T1) ;Store error in data area
MOVEI T2,MAXTRY ;Get max tries
MOVEM T2,TRIES ;And init our tries counter
MOVE T2,REMCID ;Send response on this CID
CLFBD1: MOVE T1,SCABUF ;Put SCA buffer address here for send
BLCAL. (<XENT SC.SMG>,<T2,[F.RTB+F.SPM],[CLDATA+1],T1,[CLUPRI],[0],[0]>) ;[7.1090]
IFNSK. ;Send failed
CAIE T1,SCSNEC ;Was it due to insufficient credit?
JRST CLFBD2 ;No, ignore it then
SOSGE TRIES ;Add this failure. Have we tried enough?
CALL CLFFAL ;(/) Yes, CRASH!
MOVEI T1,WAIT ;Sleep for a bit
DISMS%
JRST CLFBD1 ;And try to send again
ENDIF.
CLFBD2: RET ;And finished
ENDSV.
SUBTTL CLUDGR Fork -- CLFFAL (Send Failure)
;CLFFAL - Here when the CLUDGR fork tried to send something MAXTRY
;times. Now we BUGHLT.
;
; Called with:
; no arguments
; CALL CLFFAL
;
; Returns:
; NEVER
XSWAPCD ;Called by fork
CLFFAL: BUG. (HLT,CLUSCM,CLUFRK,SOFT,<CLUDGR fork send unconditionally failed>,,<
Cause: The local system attempted to send a response to a remote system
MAXTRY times. This BUGHLT indicates that the send failed each
time due to lack of receive credit on the remote system. The
system must be sucking all of the credits somehow. However, simply
not performing the send will hang a fork on the remote system.
At least the fork will wake up.
>) ;Crash
SUBTTL CLUDGR Fork -- CLFRSP (Reassemble SCA packets)
;CLFRSP - Routine called to reassemble a collection of SCA buffers
;associated with a request that was on the CLREQQ.
;
; Called with:
; T1/ Address of request block
; CALL CLFRSP
;
; Returns:
; +1 - Always, with data in SCA packets reassembled in the CLFREA page
XSWAPCD ;Process level code
CLFRSP: SAVEAC <Q1> ;Save scratch spot
XMOVEI T3,CLFREA ;Start putting stuff at this location
SKIPN Q1,REQSCA(T1) ;Get first SCA buffer
BUG. (HLT,CLFNSB,CLUFRK,SOFT,<No SCA buffers for request>,,<
Cause: This BUG indicates that a request came in from a remote system
for the local CLUDGR fork to perform. However, after the CL%ALL
bit was set in the request block, there were no SCA buffers to
reassemble. CL%ALL must have been erroneously set.
>) ;If no SCA buffers, die now
AOS Q3,CLDLEN(Q1) ;[7.1090] Get words we received
CLFRS1: LOAD T2,.CLPTR,(Q1) ;Get pointer to data area
ADDI T2,CLDFUN ;Find out where data starts (past this word)
ADD T2,Q1 ;Now make it absolute
MOVE T1,Q3 ;[7.1090] Assume we can BLT this many
CAILE T1,<C%MUDA-CLDATA+.MHUDA> ;[7.1090] Too many words?
MOVEI T1,<C%MUDA-CLDATA+.MHUDA> ;[7.1090] Yes, only do this many
CALLX (MSEC1,XBLTAT) ;(T1,T2,T3/T1,T2,T3) Blast data to CLUDGR fork's page
SKIPN Q1,.CLFLI(Q1) ;[7.1090] Get next SCA buffer in chain
IFSKP. ;[7.1090] If another buffer...
SUBI Q3,<C%MUDA-CLDATA+.MHUDA> ;[7.1090] Account for the words we just BLTed
JRST CLFRS1 ;[7.1090] Do next buffer
ENDIF. ;[7.1090]
RET ;All buffers reassembled
SUBTTL CLUDGR Fork -- CLFWAT (Scheduler test to wait for action)
;CLFWAT - Scheduler test used by the CLUDGR fork. The CLUDGR fork will
;will use this to wait for something to do.
;
; Called with:
; no arguments
; MDISMS to CLFWAT
;
; Returns:
; +1 - Go back to sleep, nothing to do
; +2 - CLUFLG was set, time to check out the action
RESCD ;Like all good scheduler tests
CLFWAT: SKIPN CLUFLG ;Is it time to process goodies?
RET ;No, too early to go to work
RETSKP ;Respond to alarm clock
SUBTTL CLUDGR Fork -- ZERDAT (Zero out data area)
;ZERDAT - Routine called to zero out the data area for CLUDGR fork.
;
; Called with:
; no arguments
; CALL ZERDAT
;
; Returns:
; +1 - Always, with CLFSCR page and CLFREA page all zeroes
XSWAPCD ;Called at process level
ZERDAT: SETZM CLFSCR ;Zero out scratch area
MOVE T1,[CLFSCR,,CLFSCR+1] ;Source and
BLT T1,CLFSCR+777 ;destination of overlap
SETZM CLFREA ;Now do reassembly page
MOVE T1,[CLFREA,,CLFREA+1] ;Start here and
BLT T1,CLFREA+777 ;do up to here
RET ;All zeroed
SUBTTL CLUDGR Fork -- CLFSND (Routine to send results)
;CLFSND - This routine is the responder. It sends the data obtained
;by the function and put into CLFSCR back to the requestor on the
;remote system.
;
; Call with:
; T1/ number of words in CLFSCR to be sent and
; CLFSCR setup
; CALL CLFSND
;
; Or call with:
; no arguments
; CALL CLxSND (where 0<x<4 and X is the number of words to send
;
; Returns:
; +1 - Always, data sent. However, this routine may block
; while several attempts to make the send are tried.
; If the send fails MAXTRY times, we crash.
XSWAPCD ;Fork fun
CL1SND: MOVEI T1,1 ;Send over 1 word
JRST CLFSND ;Common code
CL2SND: MOVEI T1,2 ;Send over 2 words
JRST CLFSND ;Join common code
CL3SND: MOVEI T1,3 ;Send over 3 words
JRST CLFSND ;Join common code
CLFSND: SAVEQ ;[7.1090] Save what we use
STKVAR <TRIES,WRDS,BUFCHN,NEXT,RETBUF> ;Temp data storage
MOVEM T1,WRDS ;Save the number of words
MOVEI T1,MAXTRY ;Max number of tries
MOVEM T1,TRIES ;Stash it for now
CLFSN1: HRR T2,WRDS ;Get count of words to move
HRLI T2,<CLDATA-.MHUDA> ;Start putting data in at this word
XMOVEI T1,CLFSCR ;Here's the data
NOINT ;To satisfy SC.BRK
CALL SC.BRK ;(T1,T2/T1,T2,T3) Put stuff in SCA message buffers
IFNSK. ;If we failed,
SOSGE TRIES ;See if we failed too much
BUG. (HLT,CLOUTB,CLUFRK,SOFT,<System out of SCA buffers>,,<
Cause: The CLUDGR fork was trying to send a response to a remote
system. However, it could not obtain the SCA bufferage to
do so.
Action: Find out who is eating up the SCA buffers.
>) ;We've had enough
OKINT ;Undo NOINT
MOVEI T1,WAIT ;Sleep a bit
DISMS% ;Maybe buffers will come back
JRST CLFSN1 ;Try it again
ENDIF.
OKINT ;All set now
ADDM T2,CLUBUF ;Add the buffers in use by CLUDGR
MOVEM T1,BUFCHN ;Save SCA buffer chain
MOVEM T3,RETBUF ;Routine to return the buffers
MOVX T2,CL%REQ ;Say this is a response
ANDCAM T2,FLAGS ;By clearing this bit
BLCAL. (FILLIN,<T1,FLAGS,REQID,CODE,FRK,CINODE,REMUSR,WRDS>) ;[7.1090]
;[7.1090] Fill in SCA buffer chain
MOVEI T1,MAXTRY ;Max number of tries
MOVEM T1,TRIES ;Stash it for now
MOVE Q1,WRDS ;[7.1090] Get word count
CLFSN2: MOVE T1,BUFCHN ;Get first buffer in chain
MOVE T2,.PKFLI(T1) ;Get next SCA buffer in chain
MOVEM T2,NEXT ;Save it to be sent later
MOVE T2,REMCID ;Get connect ID
MOVE Q2,Q1 ;[7.1090] Get word count
ADDI Q2,CLDATA ;[7.1090] Figure in the header
CAILE Q2,C%MUDA ;[7.1090] Good size?
MOVEI Q2,C%MUDA ;[7.1090] No, too big, so send maximum
BLCAL. (<XENT SC.SMG>,<T2,[F.RTB+F.SPM],Q2,T1,[CLUPRI],[0],[0]>) ;[7.1090]
IFNSK. ;Send failed
CAIE T1,SCSNEC ;Was it due to insufficient credit?
IFSKP. ;Yes
SOSGE TRIES ;Add this failure. Have we tried enough?
CALL CLFFAL ;(/) Yes, CRASH!
ELSE. ;Else node probably went away
JRST PNTCHN ;Punt the entire chain
ENDIF.
MOVEI T1,WAIT ;Sleep for a bit
DISMS%
JRST CLFSN2 ;And try to send again
ENDIF.
SKIPN T2,NEXT ;Get next SCA buffer
IFSKP. ;If there are more to send
MOVEM T2,BUFCHN ;Put it where it will be picked up
SUBI Q1,<C%MUDA-CLDATA+.MHUDA> ;[7.1090] Account for the words we just sent
JRST CLFSN2 ;And send it
ENDIF.
RET ;All done sending
;Here when send failed somehow. We are now going to give back
;the rest of the SCA buffers.
PNTCHN: MOVE T1,BUFCHN ;Get buffer back
SOS CLUBUF ;Discount this buffer
CALLX (MSEC1,SC.RBF) ;(T1/) Now return it
SKIPN T1,NEXT ;Was there more?
RET ;No more, go back
MOVEM T1,BUFCHN ;Put it here
MOVE T1,.PKFLI(T1) ;Get the next one in line
MOVEM T1,NEXT ;And stash it here
JRST PNTCHN ;And punt the rest of the chain
ENDSV.
SUBTTL End of CLUFRK
ENDTV.
END