Google
 

Trailing-Edge - PDP-10 Archives - bb-d868b-bm_tops20_v3a_2020_dist - 3a-sources/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




;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1974, 1975, 1976, 1977, 1978 BY
;	DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.


	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