Trailing-Edge
-
PDP-10 Archives
-
AP-D483B-SB_1978
-
qsradm.mac
There are 45 other files named qsradm.mac in the archive. Click here to see a list.
TITLE QSRADM -- System Administrative Functions
SUBTTL Larry Samberg 6 Jan 77
;***Copyright (C) 1976, Digital Equipment Corp., Maynard, MA.***
SEARCH QSRMAC ;PARAMETER FILE
PROLOGUE(QSRADM) ;GENERATE NECESSARY SYMBOLS
COMMENT \
STOPCDs found in QSRADM
UCW USE COUNT WRONG
\
SUBTTL Module Storage and Constants
MSGPDB: BLOCK IPCHSZ ;PDB FOR SENDING MESSAGES
MSGMSG: BLOCK RCK.SZ ;MESSAGE BLOCK FOR RCK (FOR NOW)
CNVPTR: POINT 6,CNVSTN(S1),5
POINT 6,CNVSTN(S1),11
POINT 6,CNVSTN(S1),17
POINT 6,CNVSTN(S1),23
POINT 6,CNVSTN(S1),29
POINT 6,CNVSTN(S1),35
;THE TABLE FOR CONVERSION STARTS OUT AS IDENTITY, CHANGED BY FUNCTION 17
CNVSTN: BYTE(6) 0,1,2,3,4,5,6,7,10,11,12,13,14,15,16,17,20,21
BYTE(6) 22,23,24,25,26,27,30,31,32,33,34,35,36,37,40,41,42,43
BYTE(6) 44,45,46,47,50,51,52,53,54,55,56,57,60,61,62,63,64,65
BYTE(6) 66,67,70,71,72,73,74,75,76,77
SUBTTL Initialization Entry
;CALLED DURING QUASAR INITIALIZATION TO INITIALIZE THE ADMINISTRATIVE
; DATABASE.
A$INIT:: PUSHJ P,I$NOW## ;GET NOW!!
MOVEM S1,G$ITEM+$$STAR ;SAVE IT
POPJ P, ;AND RETURN
SUBTTL Administrative Message Handlers
;THE MESSAGE HANDLERS ARE TOP LEVEL ROUTINES WHICH PROCESS THE
; VARIOUS MESSAGES THAT ARE SENT TO QUASAR. THEY ARE
; CALLED DIRECTLY OUT OF THE MAIN PROCESSING LOOP WITH
; ACCUMULATOR "M" POINTING TO THE FIRST WORD OF THE MESSAGE.
; THE MESSAGE HANDLERS HAVE FULL USE OF ALL ACCUMULATORS
; EXCEPTING "M" AND THE "P" REGS.
INTERN A$HELLO ;FUNCTION 1 -- HELLO
INTERN A$RCK ;FUNCTION 15 -- REQ FOR CHECKPOINT(*)
INTERN A$ROUTE ;FUNCTION 17 -- ROUTE
INTERN A$COUNT ;FUNCTION 20 -- COUNT
INTERN A$CANSWER ;FUNCTION 21 -- COUNT ANSWER(*)
;(*) REQUEST FOR CHECKPOINT AND COUNT ANSWER ARE SENT BY QUASAR
; THESE ARE NOT CALLED FROM THE MAIN LOOP BUT RATHER:
;
; REQUEST FOR CHECKPOINT IS CALLED FROM THE SCHEDULING ROUTINES
; COUNT ANSWER IS CALLED FROM THE COUNT FUNCTION
SUBTTL HELLO -- Function 1
;THE HELLO MESSAGE IS SENT TO QUASAR BY ONE OF THE KNOWN SYSTEM
; COMPONENTS UNDER THREE CIRCUMSTANCES, THE FIRST BEING PROGRAM
; STARTUP, THE SECOND, A STATUS CHANGE AND THE THIRD, PROGRAM
; SHUTDOWN.
A$HELLO:
PUSHJ P,.SAVE1## ;SAVE P1
LOAD T1,.MSTYP(M),MS.CNT ;GET THE MESSAGE SIZE
CAIGE T1,HEL.SZ ;AT LEAST BIG ENOUGH?
PJRST E$MTS## ;NO, INDICATE MESSAGE TOO SHORT
PUSHJ P,I$WHEEL## ;SEE IF CALLER IS AN OPERATOR
JUMPE S1,E$IPE## ;ISN'T, CANNOT BECOME A KNOWN COMPONENT
LOAD S1,HEL.ST(M),HELVER ;GET PROGRAMS VERSION OF QSRMAC
CAIE S1,%%.QSR ;BETTER BE THE SAME AS MINE
PJRST E$WVN## ;ISN'T, GIVE WRONG VERSION ERROR
LOAD S1,HEL.SD(M) ;GET SIXBIT DEVICE TO SCHEDULE
LOAD S2,HEL.ST(M),HELDSN ;GET SPOOLERS DEFAULT STATION
PUSHJ P,I$MIDS## ;CONVERT TO INTERNAL DEVICE SPEC
PJUMPE S1,E$IFD## ;GIVE NAK IF BAD
STORE S1,HEL.SD(M) ;NOW IS IN INTERNAL FORM
HELL.1: MOVE S1,G$SND## ;GET PID OF CURRENT SENDER
PUSHJ P,GETPSB ;FIND HIS PSB
MOVE P1,S1 ;STORE ADDRESS OF PSB IN P1
SKIPE PSBPID(P1) ;IS IT A NEW ONE?
JRST HELL.2 ;NO, MUST BE STATUS CHANGE
LOAD S1,HEL.SD(M) ;GET SCH DEVICE IDS
PUSHJ P,Q$FHDR## ;FIND THE QUEUE HEADER
JUMPE S1,HELL.6 ;NO SUCH QUEUE!!!
STORE S1,PSBSTS(P1),PSYHDR ;STORE THE HEADER'S ADDRESS
MOVE T2,G$SND## ;GET SENDER'S PID
MOVEM T2,PSBPID(P1) ;AND STORE IT IN THE PSB
MOVE T2,HEL.ST(M) ;GET STATUS WORD
TXNE T2,HELSTC ;STATUS CHANGE
JRST HELL.5 ;YES, IGNORE IT
JRST HELL.4 ;TRANSFER THE REST AND RETURN
;HERE WHEN WE RECEIVE HELLO MESSAGE FROM A "KNOWN" PID
HELL.2: MOVE T2,HEL.ST(M) ;GET THE STATUS WORD
TXNE T2,HELBYE ;IS IT A GOODBYE MESSAGE?
PJRST KILPSB ;YES, GO DO IT
TXNE T2,HELSTC ;NO, IS IT A STATUS CHANGE?
JRST HELL.4 ;YES, STORE THE REST OF THE MESSAGE
;HERE WHEN WE RECEIVE A HELLO FROM A KNOWN PROGRAM. WE ASSUME THE
; PROGRAM ABENDED AND HAS BEEN RESTARTED, SO WE FORCE A
; GOODBYE FOLLOWED BY A NEW HELLO.
HELL.3: PUSHJ P,KILPSB ;BYE....
JRST HELL.1 ;HI.....
;HERE TO STORE ALL INFORMATION WHICH WILL BE STORED ON BOTH
; HELLO MESSAGES AND STATUS CHANGE MESSAGES.
;
HELL.4: MOVE T2,HEL.NM(M) ;GET THE PROGRAM NAME
MOVEM T2,PSBNAM(P1) ;AND STORE IT
MOVE T2,HEL.SD(M) ;DEVICE FOR WHICH TO SCHEDULE
MOVEM T2,PSBSDV(P1) ;STORE
MOVE T2,HEL.PD(M) ;PROCESSING DEVICE
MOVEM T2,PSBPDV(P1) ;STORE
MOVE T2,HEL.I1(M) ;GET INFORMATION WORD 1
LOAD T3,PSBSTS(P1),PSYHDR ;GET ADDRESS OF THE QUEUE HEADER
LOAD T3,.QHTYP(T3),QH.TYP ;GET QUEUE TYPE
CAIN T3,.QHTOU ;IS IT AN OUTPUT QUEUE
ANDX T2,FRMSK1 ;MASK TO UNIQUE FORMS TYPE
MOVEM T2,PSBIN1(P1) ;STORE IT
MOVE T2,HEL.I2(M) ;GET INFO WORD 2
MOVEM T2,PSBIN2(P1) ;AND STORE IT
MOVE T2,HEL.I3(M) ;GET INFO WORD 3
MOVEM T2,PSBIN3(P1) ;AND STORE IT
LOAD T2,HEL.ST(M),HELSCH ;GET SCHEDULING FLAG
STORE T2,PSBSTS(P1),PSYSCH ;SET FOR SCHEDULER
LOAD T2,HEL.ST(M),HELFRZ ;GET FROZEN FORMS INDICATOR
STORE T2,PSBSTS(P1),PSYFRZ ;SET FOR FORMS CHANGER
LOAD T2,HEL.ST(M),HELLLP ;GET LOWER CASE PRINTER BIT
STORE T2,PSBSTS(P1),PSYLLP ;SET ACCORDINGLY
LOAD T2,HEL.ST(M),HELRDE ;GET ABILITY TO DO RDE JOBS
STORE T2,PSBSTS(P1),PSYRDE ;AND STORE IT
POPJ P, ;AND RETURN
;HERE TO RETURN THE PSB WE ARE POINTING TO IN P1. THIS IS DONE
; IF WE ENCOUNTER AN INCONSISTENCY IN A HELLO MESSAGE AFTER
; WE'VE ALLOCATED A PSB.
HELL.5: PUSHJ P,E$NKC## ;STATUS CHANGE FROM UNKNOWN PROGRAM
SKIPA ;SKIP THE OTHER ERROR
HELL.6: PUSHJ P,E$UQS## ;UNKNOWN QUEUE SPECIFIED
MOVEI H,HDRPSB## ;LOAD ADDRESS OF HEADER
MOVE AP,P1 ;LOAD ADDRESS OF PSB
PJRST M$RFRE## ;RETURN IT TO FREE SPACE
SUBTTL REQUEST FOR CHECKPOINT -- Function 15
;REQUEST FOR CHECKPOINT IS CALLED BY THE SCHEDULING LOOP TO SEND THE
; CHECKPOINT REQUEST TO A KNOWN COMPONENT.
;
;CALLED WITH T1 = THE PID TO SEND TO
A$RCK: MOVEI AP,MSGPDB ;POINT TO THE PDB FOR THE SEND
MOVEM T1,.IPCFR(AP) ;STORE THE RECEIVERS PID
ZERO .IPCFL(AP) ;NO FLAGS
MOVE T1,[RCK.SZ,,MSGMSG] ;MACRO WONT LET ME DO IT ANY OTHER WAY
MOVEM T1,.IPCFP(AP) ;STORE LENGTH AND ADDRESS
MOVX T1,<INSVL.(.QORCK,MS.TYP)!INSVL.(RCK.SZ,MS.CNT)>
MOVEM T1,MSGMSG+.MSTYP ;STORE FUNCTION AND MESSAGE LENGTH
TXO AP,IPS.ID ;DONT SEND IF OTHERS QUEUED FOR PID
PJRST C$SEND## ;SEND THE MESSAGE AND RETURN
SUBTTL ROUTE -- Function 17
;CALLED TO HANDLE "ROUTE" MESSAGE FROM MAIN LOOP.
A$ROUTE:
LOAD S1,.MSTYP(M),MS.CNT ;SIZE OF MESSAGE
CAIGE S1,ROU.SZ ;MINUMUM SIZE
PJRST E$MTS## ;MESSAGE TOO SHORT
PUSHJ P,I$WHEEL## ;CALLER MUST BE A WHEEL
PJUMPE S1,E$IPE## ;INSUFFICIENT PRIVS
LOAD S1,ROU.ST(M),RO.ORG ;ORIGINAL STATION (TABLE ENTRY)
LOAD TEMP,ROU.ST(M),RO.NEW ;NEW ROUTING
CAIG S1,^D63 ;MAXIMUM STATION NUMBER
CAILE TEMP,^D63 ;FOR EITHER NUMBER
PJRST E$NOR## ;RANGE CHECK ERROR
IDIVI S1,6 ;SPLIT INTO INDICES
DPB TEMP,CNVPTR(S2) ;STORE NEW STATION INFORMATION
POPJ P, ;AND ALL DONE
SUBTTL COUNT -- Function 20
;COUNT MESSAGE IS SENT TO QUASAR BY A WHEEL TO REQUEST A COUNT-ANSWER
; CONTAINING ALL OF QUASAR'S INTERESTING COUNTERS.
A$COUNT:
PUSHJ P,I$WHEEL ;IS USER A WHEEL?
PJUMPE S1,E$IPE## ;NO, INSUFICIENT PRIVS
LOAD S1,G$NOW## ;GET NOW
STORE S1,G$ITEM##+$$NOW ;SAVE IT
JRST A$CANSWER ;GIVE HIM THE ANSWER
SUBTTL CANSWER -- Function 21
;A$CANSWER IS CALLED BY THE COUNT MESSAGE CODE TO SEND A COUNT-ANSWER
; MESSAGE TO THE CURRENT SENDER.
A$CANSWER:
$COUNT (MCAN) ;NUMBER OF COUNTANSWER MESSAGES
PUSHJ P,M$ACQP## ;GET A PAGE
PG2ADR AP ;MAKE AN ADDRESS
MOVE S1,AP ;COPY OVER THE ADDRESS
PUSHJ P,.ZPAGA## ;AND ZERO THE PAGE
MOVSI S1,CAN.SZ ;GET LEN,,0
HRRI S1,.QOCAN ;GET LEN,,FUNCTION
STORE S1,.MSTYP(AP) ;STORE IT IN THE MESSAGE
MOVSI S1,G$ITEM## ;GET START ADDRESS
HRRI S1,CAN.BL(AP) ;GET DEST ADDRESS
BLT S1,CAN.BL+NITEMS(AP) ;BLT THE MESSAGE
ADR2PG AP ;CONVERT TO A PAGE NUMBER
HRLI AP,1000 ;PUT IN PAGE LENGTH
MOVEM AP,MSGPDB+.IPCFP ;STORE IN THE PDB
MOVEI AP,MSGPDB ;POINT TO THE PDB
MOVX S1,IP.CFV ;GET PAGE MODE BIT
MOVEM S1,.IPCFL(AP) ;STORE IN PDB
MOVE S1,G$SND## ;GET PID OF SENDER
MOVEM S1,.IPCFR(AP) ;SAVE AS RECEVIER
PJRST C$SEND## ;SEND IT
SUBTTL Global Routines
;THE FOLLOW ARE ADDITIONAL GLOBAL ROUTINES FOUND IN THIS MODULE
; OTHER THAN THE TOP-LEVEL MESSAGE HANDLERS.
INTERN A$KLPD ;KILL OFF A PSB GIVEN ITS PID
INTERN A$FPSB ;FIND A PSB GIVEN A PID
INTERN A$CSTN ;DO ACTUAL STATION RE-ROUTING
SUBTTL A$KLPD -- Routine to kill a PSB given its PID
;A$KLPD IS CALLED TO "KILL" A PSB ENTRY. A$KLPD IS CALLED
; WITH THE PID OF THE PSB TO BE KILLED (E.G. WHEN A SEND TO
; A KNOWN COMPONENT FAILS WITH "UNKNOWN PID").
;
;CALL WITH ARGUMENT IN S1
A$KLPD: SAVE AP ;SAVE CALLERS REGISTERS
SAVE H ; ""
PUSHJ P,A$FPSB ;FIND THE PSB GIVEN THE PID
PJUMPE S1,.POPJ## ;RETURN IF NOT THERE
PJRST KILPSB ;KILL THE PSB ENTRY AND RETURN
SUBTTL A$FPSB -- Subroutine to find a PSB
;A$FPSB IS CALLED WITH A PID IN S1. IT SCANS THE PSB LIST
; LOOKING FOR A MATCH. IF ONE IS FOUND, THE ADDRESS
; OF THE PSB IS RETURNED IN S1, ELSE S1 IS RETURNED
; CONTAINING 0.
A$FPSB: MOVEI H,HDRPSB## ;ADDRESS OF PSB QUEUE HEADER
MOVE S2,S1 ;COPY ARGUMENT TO S2
LOAD S1,.QHLNK(H),QH.PTF ;GET ADDRESS OF FIRST
FPSB.1: JUMPE S1,.POPJ## ;RETURN IF LAST ONE (OR NONE)
CAMN S2,PSBPID(S1) ;MATCH?
POPJ P, ;YES, RETURN WITH ADDRESS IN S1
LOAD S1,.QELNK(S1),QE.PTN ;GET POINTER TO NEXT
JRST FPSB.1 ;AND LOOP
SUBTTL A$CSTN -- Do station re-routing
;THIS ROUTINE IS CALLED WITH S1 CONTAINING A UDS. THIS UDS IS RETURNED
; (IN S1) WITH THE STAION FIELD MODIFIED TO REFLECT ANY RE-ROUTING
; DONE ON THE ORIGINAL STATION.
A$CSTN: PUSH P,S1 ;SAVE ORIGINAL SPEC
LOAD S1,S1,DV.STN ;EXTRACT STATION NUMBER
IDIVI S1,6 ;SPLIT INTO INDICES
LDB S1,CNVPTR(S2) ;LOAD NEW STATION
STORE S1,0(P),DV.STN ;INSERT NEW INTO SPEC
POP P,S1 ;RESTORE
POPJ P, ;AND RETURN UPDATED UDS
SUBTTL Utility Routines
; GETPSB -- FIND OR CREATE A PSB GIVEN A PID
; KILPSB -- KILL A SPECIFIED PSB
SUBTTL GETPSB -- Routine to get a PSB
;GETPSB IS CALLED WITH A PID IN S1. IT CALLS A$FPSB TO SEE IF
; THE PID IS ALREADY KNOWN, AND IF SO IT RETURNS ITS ADDRESS
; IN S1. IF NOT, A NEW PSB IS GOTTEN AND ZEROED AND ITS
; ADDRESS IS RETURNED IN S1.
;
GETPSB: PUSHJ P,A$FPSB ;FIND KNOWN PID
PJUMPN S1,.POPJ## ;FOUND IT
GETP.1: MOVEI H,HDRPSB ;LOAD ADR OF PSB HEADER
PUSHJ P,M$GFRE## ;GET A FREE CELL
MOVE S1,AP ;COPY ITS ADDRESS INTO S1
HRLI S2,PSBBGN(AP) ;GET ADDRESS OF FIRST WORD
HRRI S2,PSBBGN+1(AP) ;GET ADDRESS OF SEC WORD
ZERO PSBBGN(AP) ;CLEAR THE FIRST WORD
BLT S2,PSBSIZ-1(AP) ;CLEAR THE REST OUT
PUSH P,S1 ;SAVE THE ANSWER
PUSHJ P,M$ELNK## ;LINK IN THE PSB
POP P,S1 ;RESTORE THE ANSWER
POPJ P, ;AND RETURN
SUBTTL KILPSB -- Routine to kill a PSB given its address
;CALL KILPSB WITH THE ADDRESS OF THE PSB TO BE KILLED IN S1. KILPSB
; CLEARS ANY DEAD INTERLOCKS FOR THE PSB, AND RETURNS IT TO THE
; PSB FREE SPACE.
KILPSB: SAVE H ;SAVE H
SAVE AP ;AND AP
MOVE T1,S1 ;AND PUT ARGUMENT THERE
KILP.0: LOAD S1,PSBSTS(T1),PSYNJP ;GET NUMBER OF JOBS BEING PROCESSED
JUMPE S1,KILP.3 ;RETURN WHEN DONE
MOVEI H,HDRUSE## ;POINT TO THE USE QUEUE
LOAD AP,.QHLNK(H),QH.PTF ;GET GET THE FIRST
KILP.1: SKIPN AP ;IS THERE ONE?
STOPCD(UCW,FATAL) ;++USE COUNT WRONG
MOVE S1,PSBPID(T1) ;YES, GET PSB'S PID
CAMN S1,.QEPID(AP) ;INTERLOCKING THIS JOB?
JRST KILP.2 ;YUP, GO CLEAR THE INTERLOCK
LOAD AP,.QELNK(AP),QE.PTN ;NO, GET POINTER TO NEXT
JRST KILP.1 ;AND LOOP
KILP.2: LOAD S1,.QESTN(AP),QE.RQP ;GET THE RQP
ADDI S1,TBLHDR## ;CONVERT TO QUEUE HEADER ADDRESS
ZERO .QEPID(AP) ;CLEAR THE INTERLOCK
PUSHJ P,M$MOVE## ;MOVE IT BACK TO PROC QUEUE
PUSHJ P,S$RUSE## ;TELL SCHED (T1 IS ARG TO KILPSB)
JRST KILP.0 ;AND LOOP
KILP.3: MOVEI H,HDRPSB## ;LOAD HEADER FOR PSB QUEUE
MOVE AP,T1 ;COPY OVER PSB ADDRESS
PJRST M$RFRE## ;AND RELEASE THE PSB
END