Google
 

Trailing-Edge - PDP-10 Archives - bb-bt99l-bb - quasar.x18
There is 1 other file named quasar.x18 in the archive. Click here to see a list.
	TITLE	QUASAR  --  QUASAR Controller - version 5

;
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1975,1976,1977,1978,1979,
;1980,1981,1982,1983,1984,1985,1986,1987.  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	QSRMAC,GLXMAC	;PARAMETER FILE

	PROLOGUE(QUASAR)	;GENERATE THE NECESSARY SYMBOLS
	SEARCH	ORNMAC		;NEED ORION SYMBOLS
	SEARCH	CATPRM		;NEED CATALOG SYMBOLS

IFN FTDQS,<
	.REQUE	CHRFRM		;GET CHARACTERISTICS/FORMS FILE HANDLER
>; END IFN FTDQS

	%%.QSR==:%%.QSR		;REFERENCE QSRMAC'S VERSION

	LOC	137		;INSTALL OUR VERSION NUMBER
	EXP	QSRVRS
	RELOC	0		;BACK TO RELOCATABLE CODE

COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1971,1987.
ALL RIGHTS RESERVED.
\;END OF COPYRIGHT MACRO
	SUBTTL	Global Variables

	MSGLN==:^D200		;MESSAGE BUFFER LENGTH

G$BEG:				;BEGINNING OF GLOBAL VARIABLES
G$ENT::	 BLOCK	1		;ADDRESS OF CURRENT IPC ENTRY

G$SND::	 BLOCK	1		;SENDER OF CURRENT REQUEST (PID)

G$RCVR:: BLOCK	1		;RECIEVERS PID

G$SID::	 BLOCK	1		;OWNER ID OF CURRENT SENDER

G$CDI::	 BLOCK	1		;CONNECTED DIRECTORY OF SENDER

G$MCOD:: BLOCK	1		;TURN-AROUND CODE OF CURRENT MESSAGE

G$IDX::  BLOCK	1		;SENDER'S SPECIAL INDEX

G$NOW::	 BLOCK	1		;"NOW" IN INTERNAL DATE-TIME FORMAT

G$ERR::	 BLOCK	1		;ERROR CODE FOR ACK'ING THIS REQUEST

G$QSTR:: BLOCK	1		;QUEUE STRUCTURE

G$SPLD:: BLOCK	1		;QUEUE PPN OR SPOOLED DIRECTORY NUMBER

G$SYSD:: BLOCK	1		;SYSTEM PPN

G$GPID:: BLOCK	1		;[SYSTEM]GOPHER'S PID

G$QPID:: BLOCK	1		;QUASAR'S PID

G$MPID:: BLOCK	1		;MDA'S PID (-10 ONLY)

IFN FTINFO,<
G$IPID:: BLOCK	1		;[SYSTEM]INFO'S PID
> ;END IFN FTINFO

G$OPR::	BLOCK	1		;ORION'S PID

G$NBW::	 BLOCK	1		;NUMBER OF BLKS WRITTEN IN MASTER QUEUES

G$SPRT:: BLOCK	1		;PROTECTION OF SPOOLED FILES

G$PRVS:: BLOCK	1		;ENABLED PRIVS OF CURRENT SENDER

G$ACK::	 BLOCK	1		;NON-ZERO IF CALLER WANTS A RESPONSE

G$ACKO:: BLOCK	1		;ACKING OPR CREATES

G$MPS::	 BLOCK	1		;MAX IPCF PACKET SIZE

G$MCOR:: BLOCK	1		;MINIMUM VALUE OF /CORE

G$XCOR:: BLOCK	1		;MAXIMUM VALUE OF /CORE

G$CNET:: BLOCK	1		;NETWORK CHANGE FLAG. -1=YES, 0=NO.

TOPS10<
G$KSYS:: BLOCK	1		;NUMBER OF SECS TO KSYS
				;0=NO KSYS SET,  -1=T/S IS OVER
G$KSYI:: BLOCK	1		;KSYS INTERRUPT FLAG
G$KUDT:: BLOCK	1		;UDT WHEN KSYS EXPIRES

G$DTCI:: BLOCK	1		;DATE/TIME CHANGE INTERRUPT FLAG. -1=YES, 0=NO.
G$OUDT:: BLOCK	1		;G$NOW BEFORE LAST INTERRUPT
> ;END TOPS10

G$LOGN:: BLOCK	1		;BATCH LOGIN FLAG. 0=NO. -1=YES.

G$OPRA:: BLOCK	1		;OPERATOR AVAILABLE FLAG. 0=NO, -1=YES

	;CONTINUED ON THE NEXT PAGE
	;CONTINUED FROM THE PREVIOUS PAGE

G$ITEM:: BLOCK	NITEMS		;COUNTER ITEMS

G$WTIM:: BLOCK	1		;TIME TO WAKEUP

G$TXBP:: BLOCK	1		;BYTE POINTER FOR G$TEXT

G$SCHD:: BLOCK	1		;FLAG FOR DOSCHD MACRO

G$PASS:: BLOCK	1		;PASS OF THE SCHEDLER (-1, 0, OR 1)

G$LNAM:: BLOCK	1		;LOCAL NODE NAME (IN SIXBIT)

G$LNBR:: BLOCK	1		;LOCAL NODE NUMBER
TOPS10 <
G$MST2:: BLOCK	1		;GETTAB %CNST2 VALUES
>
G$QOPR:: BLOCK	1		;OPERATOR QUEUE SEARCH FLAG.

G$NBAT:: BLOCK	1		;MAX NUMBER OF BATCH STREAMS WHICH CAN BE STARTED.

G$ACTV:: BLOCK	1		;ACCOUNT VALIDATION FLAG 0=NO, -1=YES

G$MDA::  BLOCK	1		;MDA SUPPORT FLAG 0=NO, -1=YES

G$ACTS:: BLOCK	10		;ACCOUNT STRING BUFFER FOR IPCF MESSAGES

G$LOCN:: BLOCK	2		;NODE FROM WHICH THE MESSAGE CAME

G$RMTE:: BLOCK	1		;NODE FOR WHICH OPERATOR Q SEARCHS ARE MADE

G$NTFY:: BLOCK	1		;FILE ARCHIVING NOTIFICATION FLAG (0=NO,-1=YES)

G$BLKA:: BLOCK	1		;IPCF MESSAGE BLOCK ADDRESS

G$PLSR:: BLOCK	1		;PULSAR'S PID

G$EVENT:: BLOCK	1		;EVENT QUEUE ID

G$MAXJ:: BLOCK	1		;MAX NUMBER OF JOBS SUPPORTED IN THIS MONITOR

G$SAB::	BLOCK	SAB.SZ		;AN SAB FOR SENDING IPCF MESSAGES

G$ACKB:: BLOCK	1		;BUFFER ADDRESS FOR ERROR MESSAGES

G$MSG::	BLOCK	MSGLN		;BUFFER FOR BUILDING MESSAGES

G$DEAD:: BLOCK	1		;DEADLOCK AVOIDANCE FLAG

G$PERM:: BLOCK	1		;PERMANENT STRUCTURE FLAG

G$TIC::	BLOCK	1		;CLOCK TICKS/SECOND

	G$END==.-1		;END OF GLOBAL VARIABLES

STFLAG:	EXP	-1		;FLAG TO MAKE SURE WE AREN'T RESTARTED

	PDLSIZ==^D300		;[1175] PUSHDOWN LIST SIZE
PDL::	BLOCK	PDLSIZ   	;[1175] PUSHDOWN LIST

	SUBTTL	Initialization

; Initialization Block


IB:	$BUILD(IB.SZ)			;
	 $SET(IB.PRG,,%%.MOD)		;PROGRAM NAME
	 $SET(IB.INT,,INTBLK##)		;SET UP INTERRUPT VECTOR ADDRESS
	 $SET(IB.PIB,,G$PIB)		;SET UP PIB ADDRESS
	 $SET(IB.FLG,IP.STP,1)		;STOPCODES TO ORION
	$EOB				;

G$PIB::	$BUILD(PB.MXS)			;
	 $SET(PB.HDR,PB.LEN,PB.MXS)	;BLOCK LENGTH
	 $SET(PB.FLG,,IP.PSI!IP.SPB!IP.RSE) ;LITE LOTS OF BITS
	 $SET(PB.INT,IP.SPI,SP.QSR)	;MAKE US [SYSTEM]QUASAR
	 $SET(PB.INT,IP.CHN,INT.PI)	;INTERRUPT CHANNEL
	 $SET(PB.SYS,IP.MNP,5)		;NEED AT LEAST 5 PIDS
	 $SET(PB.SYS,IP.BQT,-1)		;MAX SEND/RECIEVE IPCF QUOTA'S
	 $SET(PB.ACT,,<-1,,G$ACTS>)	;ACCOUNT STRING ADDRESS
	 $SET(PB.LOC,,<-1,,G$LOCN>)	;IPCF MSG LOCATION ADDRESS
	$EOB				;

IFN FTINFO,<
;INFO'S PIB (KEEP IN PHASE WITH G$PIB)
G$IPIB:: $BUILD(PB.MXS)			;
	 $SET(PB.HDR,PB.LEN,PB.MXS)	;BLOCK LENGTH
	 $SET(PB.FLG,,IP.PSI!IP.SPB!IP.RSE) ;LITE LOTS OF BITS
	 $SET(PB.INT,IP.SPI,SP.INF)	;MAKE US [SYSTEM]INFO
	 $SET(PB.SYS,IP.MNP,1)		;INCREMENT PID QUOTA
;	 $SET(PB.NAM,,0)		;CHANGED BY P$INIT IF DEBUGGING
	$EOB				;
> ;END IFN FTINFO

	;DEFINE MESSAGE TYPES THAT ARE SYSTEM DEPENDENT

	SYSPRM	%IPCSR,0,.IPCSR		;FILE ARCHIVING MESSAGE	(TOPS20)
	SYSPRM	%IPCCG,.IPCCG,0		;[SYSTEM]GOPHER		(TOPS10)
	SYSPRM	%IPCDE,.IPCDE,0		;DEVICE DEASSIGN MSG	(TOPS10)
	SYSPRM	%IPCUO,.IPCUO,0		;DEVICE ONLINE MESSAGE	(TOPS10)
	SYSPRM	%IPATT,.IPCAT,0		;MONITOR ATTACH MESSAGE	(TOPS10)
	SYSPRM	%IPDET,.IPCDT,0		;MONITOR DETACH MESSAGE	(TOPS10)
	SYSPRM	%IPMTA,.IPCMT,0		;MONITOR MAGTAPE ACCESSIBLE (TOPS10)
	SYSPRM	%IPRMS,.IPCRM,0		;MONITOR STR REMOVE MSG	(TOPS10)
	SYSPRM	%IPXCH,.IPCXC,0		;MONITOR EXCHANGE MSG	(TOPS10)
	SYSPRM	%IPCLC,.IPCLC,0		;SEARCH LIST CHANGE MSG	(TOPS10)
	SYSPRM	%IPCON,.IPCON,0		;MONITOR LOGIN MESSAGES	(TOPS10)
	SYSPRM	%IPCRS,.IPCRS,0		;MONITOR RESET ON LOCK MSG (TOPS10)
	SYSPRM	%IPCAC,SP.ACT,-1	;ACTDAE SPECIAL PID INDEX  (TOPS10)
	SYSPRM	%IPCST,.IPCST,0		;[1217] MONITOR STR MOUNTED MSG (TOPS10)
	SYSPRM	%IPCSS,.IPCSS,0		;[SYSTEM]INFO DROP SOME PIDS (TOPS10)
	SYSPRM	%IPCIM,.IPCIM,0		;IPCFM. UUO REQUEST TO INFO (TOPS10)
	SYSPRM	%IPCQU,.IPCQU,0		;QUEUE. UUO FROM GOPHER (TOPS10)
	SYSPRM	%IPCSM,.IPCSM,0		;[1502] SCHEDULE BITS CHANGE

	;DEFINE MESSAGE ENTRY POINTS THAT ARE SYSTEM DEPENDENT

	SYSPRM	X$MTR,E$IMT,I$MTR##	;MOUNT REQUEST RELEASE MSG (TOPS20)
	SYSPRM	X$CHKP,E$IMT,I$CHKP##	;TAPE MOUNT CHECKPOINT MSG (TOPS20)
	SYSPRM	X$MATR,E$IMT,I$MATR##	;TAPE MOUNT ATTRIBUTE  MSG (TOPS20)
	SYSPRM	X$ARCH,E$IMT,I$ARCHIVE## ;FILE ARCHIVING MSG	   (TOPS20)
	SYSPRM	X$DEAS,D$DEAS##,E$IMT	;TAPE DEASSIGN MESSAGE  (TOPS10)
	SYSPRM	X$DEVS,D$DEVS##,E$IMT	;TAPE STATUS MESSAGE    (TOPS10)
	SYSPRM	X$AVR,D$AVR##,E$IMT	;AVR MESSAGE		(TOPS10)
	SYSPRM	X$VSR,D$VSR##,E$IMT	;VOLUME SWITCH REQUEST	(TOPS10)
	SYSPRM	X$VACT,I$VACT##,E$IMT	;ACCOUNT VALIDATION MSG	(TOPS10)
	SYSPRM	X$RCAT,E$IMT,E$IMT	;RESPONSE TO CATALOG REQUEST (OBSOLETE)
	SYSPRM	X$ACK,D$ACK##,E$IMT	;MDA ACK RESPONSE	(TOPS10)
	SYSPRM	X$DVS,D$DVS##,E$IMT	;MDA DELETE/DEALLOCATE MSG (TOPS10)
	SYSPRM	X$GOFR,I$GOFR##,E$IMT	;IPCF MESSAGE FROM [SYSTEM]GOPHER
	SYSPRM	X$DTCH,I$DTCH##,E$IMT	;MONITOR DETACH MESSAGE	(TOPS10)
	SYSPRM	X$ATCH,I$ATCH##,E$IMT	;MONITOR ATTACH MESSAGE	(TOPS10)
	SYSPRM	X$SLCM,I$SLCM##,E$IMT	;MON SRCH LIST CHNG MSG	(TOPS10)
	SYSPRM	X$RMS,D$RMS##,E$IMT	;MON STR REMOVED MSG	(TOPS10)
	SYSPRM	X$XCH,D$XCH##,E$IMT	;MON EXCHANGE MESSAGE	(TOPS10)
	SYSPRM	X$MTAC,I$MTAC##,E$IMT	;MON MAGTAPE UNIT ACCESSIBLE (TOPS10)
	SYSPRM	X$LCKM,D$LCKM##,E$IMT	;MON RESET ON LOCK MSG	(TOPS10)
	SYSPRM	X$UMDR,I$UMDR##,E$IMT	;ALLOC MDR UPDATE MSG 	(TOPS10)
	SYSPRM	X$INID,D$INID##,E$IMT	;TAPE INITIALIZATION DONE  (TOPS10)
	SYSPRM	X$MSTR,I$MSTR##,E$IMT	;[1217] MON STR MOUNTED MSG (TOPS10)
	SYSPRM	X$SCDM,I$SCDM##,E$IMT	;[1502] SCHED BITS CHANGE MSG (TOPS10)
	SUBTTL		SYSTEM QUASAR

;WARNING  THE ORDERING OF THE FOLLOWING CALLS TO THE VARIOUS
;	INITIALIZATION ROUTINES IS FIXED, AND SHOULD NOT BE
;	CHANGED UNDER ANY CIRCUMSTANCES.

QUASAR:	RESET				;RESET THE WORLD
	MOVE	P,[IOWD	PDLSIZ,PDL]	;[1175] GET A PUSHDOWN LIST
	AOSE	STFLAG			;MAKE SURE WE AREN'T RESTARTED
	STOPCD	(QNR,HALT,,<QUASAR not restartable>) ;WE WERE,,THIS JUST CAN'T HAPPEN

	MOVEI	S1,IB.SZ		;GET THE IB SIZE
	MOVEI	S2,IB			;AND THE IB ADDRESS
	PUSHJ	P,I%INIT		;INITIALIZE THE OTS
	MOVE	S1,G$PIB+PB.PID		;GET THE PID ASSIGNED TO US
	MOVEM	S1,G$QPID		;STORE FOR LATER
	MOVEI	S1,SP.GFR		;[SYSTEM]GOPHER INDEX
	$CALL	C%RPRM			;READ GOPHER'S PID
	MOVEM	S1,G$GPID		;SAVE FOR LATER COMPARES
	PUSHJ	P,CNTINI		;INITIALIZE CNTANSWER ITEMS

	MOVEI	S1,INPMAX		;GET THE MAX NUMBER OF BATCH STREAMS.
	MOVEM	S1,G$NBAT		;   AND SAVE IT.
	PUSHJ	P,C$INIT##		;INITIALIZE IPCF INTERFACE
TOPS10 <
	PUSHJ	P,I$DINT##		;SETUP FOR DATE/TIME CHANGE INTERRUPTS
>
	PUSHJ	P,N$INIT##		;SETUP THE NETWORK DATA BASE
	PUSHJ	P,I$INIT##		;INITIALIZE THE SYSTEM INTERFACE
	PUSHJ	P,S$INIT##		;THE TASK SCHEDULER
	PUSHJ	P,V$INIT##		;THE CATALOG DAEMON INTERFACE
	PUSHJ	P,D$INIT##		;THE MOUNTABLE DEVICE ALLOCATOR
	PUSHJ	P,A$INIT##		;ADMINISTRATIVE FUNCTIONS
	PUSHJ	P,Q$INIT##		;THE QUEUE DATABASE MANAGER
	PUSHJ	P,F$INIT##		;THE FAILSOFT SYSTEM!!
	PUSHJ	P,I$KINT##		;SET UP FOR KSYS PSI INTERRUPTS
	PUSHJ	P,Q$EVTD##		;DELETE ANY EXPIRED EVENTS

IFN FTINFO,<PUSHJ P,P$INIT##>		;THE [SYSTEM]INFO INTERFACE

TOPS10 <
	PUSHJ	P,I$AUTO##		;INITIATE PROCESSING OF SYS:SYSTEM.CMD
>; END TOPS10

	MOVEI	S1,E$XXX+1		;GET THE GENERIC ERROR TEXT PROCESSOR
	SUBI	S1,ERRTBL		;CALC THE ERROR CODE
	MOVE	S1,TXTTBL(S1)		;GET THE GENERIC ERROR BUFFER ADDRESS
	MOVEM	S1,G$ACKB		;AND SAVE IT
	SUBTTL	Main Processing Loop

MAIN:	SETZM	G$ERR			;CLEAR ERROR FLAG
	PUSHJ	P,I%NOW			;GET TIME AND DATE
	MOVEM	S1,G$NOW		;STORE FOR ANYONE WHO WANTS IT
TOPS10 <
	SKIPGE	G$KSYI			;KSYS INTERRUPT HAPPEN
	PUSHJ	P,I$KSYS##		;YES,,GO CHECK PROCESS IF NECESSARY
>
	PUSHJ	P,C%RECV		;GET A MESSAGE IF ONE IS IN QUEUE
	JUMPT	MAIN.1			;FOUND ONE,,GO PROCESS IT
TOPS10 <PUSHJ	P,A$PSBC##>		;GO CHECK ON "WAITING" PSB'S
	PUSHJ	P,Q$DLFL##		;DELETE A FILE IF NECESSARY
	SKIPE	G$CNET			;DID THE NETWORK CHANGE ???
	PUSHJ	P,N$INTR##		;YES,,GO ANALYZE IT.
	PUSHJ	P,C$RSND##		;RESEND MESSAGES
	PUSHJ	P,S$SCHD##		;TRY A SCHEDULING PASSS
	SKIPE	G$NTFY			;IS IT TIME TO SEND NOTIFICATIONS
	PUSHJ	P,I$NTFY##		;FOR FILE ARCHIVING ?? YES,,DO IT.
	SKIPN	S1,G$WTIM		;CHECK AND LOAD WAKEUP TIME
	JRST	[MOVEI S1,^D60		;THERE IS NONE,,LOAD UP 1 MINUTE
		 PUSHJ P,I%SLP		;WAIT
		 JRST  MAIN ]		;BACK TO SCHEDULER
	SETZM	G$WTIM			;CLEAR WAKEUP TIME
	MOVE	S2,G$NOW		;GET NOW
	CAML	S2,S1			;CURRENT TIME .GT. WAKEUP TIME ???
	JRST	MAIN			;YES,,THE EVENT HAS PASSED,,TRY AGAIN
	PUSHJ	P,A$AGE##		;ELSE, GET THE DIFFERENCE
	CAIG	S1,^D60			;WITHIN THE RANGE OF
	CAIGE	S1,0			; 0 TO 60 SECONDS?
	MOVEI	S1,^D60			;NO - MAKE IT A MINUTE
	SKIPN	S1			;ZERO?
	MOVEI	S1,1			;THEN SNOOZE FOR A SECOND
	PUSHJ	P,I%SLP			;AND SLEEP
	JRST	MAIN			;AND LOOP
;Here to process incoming IPCF traffic

MAIN.1:	MOVEM	S1,G$ENT		;SAVE ADDRESS OF THE ENTRY
	ZERO	G$ERR			;CLEAR PREVIOUS ERROR INDICATOR
	ZERO	G$BLKA			;CLEAR THE MESSAGE BLOCK ADDRESS
	$COUNT (RIPC)			;BUMP MESSAGE RECIEVED COUNTER
	MOVE	T1,MDB.SP(S1)		;GET THE SENDERS PID
	MOVEM	T1,G$SND		;AND SAVE IT
	CAMN	T1,G$OPR		;[1470] FROM OPR?
	SETOM	G$ACKO			;[1470] YES, SET FLAG
	MOVE	T1,MDB.RP(S1)		;GET THE RECIEVERS PID
	MOVEM	T1,G$RCVR		;SAVE IT
	MOVE	T1,MDB.SD(S1)		;GET THE SENDERS ID
	MOVEM	T1,G$SID		;AND SAVE IT
	MOVE	T1,MDB.CD(S1)		;GET THE SENDERS CONNECTED DIRECTORY
	MOVEM	T1,G$CDI		;SAVE IT
	MOVE	T1,MDB.PV(S1)		;GET SENDERS CAPABILITIES
	MOVEM	T1,G$PRVS		;SAVE THAT AS WELL
	MOVE	T1,MDB.SI(S1)		;GET THE SENDERS SPECIAL PID INDEX
	MOVEM	T1,G$IDX		;STORE IT
	LOAD	M,MDB.MS(S1),MD.ADR	;GET THE MESSAGE ADDRESS
	MOVE	T1,.MSCOD(M)		;GET THE MESSAGE ACK CODE
	MOVEM	T1,G$MCOD		;AND SAVE IT
	LOAD	T1,.MSFLG(M),MF.ACK	;GET THE ACK CODE BIT
	MOVEM	T1,G$ACK		;AND SAVE IT
	MOVE	T1,MDB.FG(S1)		;GET THE FLAG WORD
	TXNN	T1,IP.CFV		;A PAGE MODE MESSAGE ?
	 SKIPA	T3,G$MPS		;IPCF SHORT MESSAGE SIZE
	  MOVEI	T3,PAGSIZ		;PAGE MODE LENGTH

MAIN.2:	LOAD	P1,.MSTYP(M),MS.TYP	;GET MESSAGE TYPE
	TXNE	T1,IP.CFM		;A RETURNED MESSAGE
	  JRST	RTNMSG			;YES, PROCESS IT OVER THERE
	TXNE	T1,IP.CFC		;A SYSTEM MESSAGE
	  JRST	SYSMSG			;YES, DISPATCH THEM DIFFERENTLY
	LOAD	S1,G$IDX,SI.IDX		;GET THE SENDERS SPECIAL PID INDEX
	CAIN	S1,SP.CAT		;IS SENDER [SYSTEM]CATALOG?
	JRST	CATMSG			;YES
	CAXN	S1,%IPCAC		;IS IT THE ACTDAE ???
	  JRST	ACTMSG			;YES,,DISPATCH IT
	MOVE	S1,G$RCVR		;GET THE RECIEVERS PID
IFN FTINFO,<
	CAMN	S1,G$IPID		;TO [SYSTEM]INFO ???
	  JRST	INFMSG			;YES, DISPATCH IT
> ;END IFN FTINFO
	CAME	S1,G$MPID		;TO SYSTEM[MDA] ???
	CAMN	S1,G$QPID		;OR TO [SYSTEM]QUASAR ???
	  JRST	QSRMSG			;YES, DISPATCH IT


;HERE TO RETURN A PROCESSED MESSAGE

RELMSG:	PUSHJ	P,C%REL			;RELEASE THE CURRENT MESSAGE
	SETZM	G$ACKO			;[1470] CLEAR "FROM OPR" FLAG
	JRST	MAIN			;AND LOOP
	SUBTTL	Message Dispatch Handlers


;HERE UPON RECEIPT OF AN UNDELIVERABLE PACKET
;	T1 = PACKET FLAGS

RTNMSG:	TXNE	T1,IP.CFP		;REQUESTING PRIVILEGES
	  JRST	RELMSG			;YES, IGNORE THEM
	MOVE	S1,G$SND		;PID THAT WENT AWAY
	PUSHJ	P,G$SFAL		;TELL ALL CONCERNED
	JRST	RELMSG			;AND RELEASE THE MESSAGE


;HERE TO DISPATCH SYSTEM MESSAGES.
;	P1 = THE MESSAGE TYPE
;	M = THE MESSAGE PROPER
;	T1 = THE PACKET FLAGS

SYSMSG:	TXNN	T1,IP.CFP		;REQUESTING PRIVILEGES?
	  JRST	SYSM.0			;NO, IT'S OK
	MOVE	S1,G$RCVR		;GET RECEIVER'S PID
	CAME	S1,G$IPID		;IS IT INFO?
	  JRST	RELMSG			;NO, AND PRIVED, IGNORE IT

SYSM.0:	MOVE	S2,[-TBLLEN,,SYSTBL]	;GET AOBJN SEARCH AC

SYSM.1:	HLRZ	S1,0(S2)		;GET A MSG TYPE
	CAME	P1,S1			;DO WE MATCH ???
	AOBJN	S2,SYSM.1		;NO,,TRY NEXT
	HRRZ	S1,0(S2)		;YES,,GET THE PROCESSOR ADDRESS

SYSM.2:	PUSHJ	P,0(S1)			;CALL THE MESSAGE PROCESSOR
	JRST	RELMSG			;GO RELEASE THE MESSAGE

SYSTBL:	.IPCSU,,Q$SPOOL##		;SPOOLING MESSAGE
	.IPCSL,,Q$LOGOUT##		;LOGOUT MESSAGE
IFN FTINFO,<
	%IPCSS,,P$PCSS##		;[SYSTEM]IPCC DROP SOME PIDS
	%IPCIM,,P$IGFR##		;[SYSTEM]GOPHER IPCFM. UUO
> ;END FTINFO
	%IPCQU,,X$GOFR			;[SYSTEM]GOPHER QUEUE. UUO
	%IPCON,,I$LOGN##		;LOGIN MESSAGE 
	%IPCSR,,X$ARCHIVE		;ARCHIVE MESSAGE
	%IPCDE,,X$DEASSIGN		;DEASSIGN MESSAGE
	%IPCRS,,X$LCKM			;RESET ON LOCK MESSAGE 
	%IPCUO,,X$AVR			;UNIT ON-LINE MESSAGE
	%IPATT,,X$ATCH			;ATTACH MESSAGE 
	%IPDET,,X$DTCH			;DETACH MESSAGE 
	%IPCLC,,X$SLCM			;SEARCH LIST CHANGE MSG 
	%IPRMS,,X$RMS			;STRUCTURE REMOVED MSG
	%IPXCH,,X$XCH			;EXCHANGE MESSAGE
	%IPMTA,,X$MTAC			;MAGTAPE UNIT ACCESSIBLE
	%IPCST,,X$MSTR			;[1217] STR MOUNTED MSG
	%IPCSM,,X$SCDM			;[1502] SCHEDULE BITS CHANGE MSG

	TBLLEN==.-SYSTBL		;TABLE LENGTH

	0,,.RETT			;INVALID MESSAGE RECIEVED
	

;HERE FOR ACCOUNTING MESSAGES

ACTMSG:	PUSHJ	P,X$VACT		;PROCESS THE MESSAGE
	JRST	RELMSG			;AND RETURN
	SUBTTL	QSRMSG - ROUTINE TO PROCESS MESSAGES TO QUASAR

;HERE WHEN A MESSAGE IS DIRECTED AT [SYSTEM]QUASAR
;	P1 = THE MESSAGE TYPE
;	M  = THE MESSAGE PROPER
;	T3 = THE MAXIMUM MESSAGE SIZE POSSIBLE ( 1000 OR G$MPS )
;	T1 = PACKET FLAGS

QSRMSG:	LOAD	S1,G$PRVS,MR.JOB	;GET 'JOB' FIELD
	ANDX	S1,MD.PJB		;KEEP ONLY REAL JOB NUMBER
	STORE	S1,G$PRVS,MR.JOB	;PUT IT BACK
	TXNE	T1,IP.CFP		;REQUESTING PRIVILEGES
	  JRST	RELMSG			;YES, IGNORE THEM
	LOAD	T4,.MSTYP(M),MS.CNT	;GET THE LENGTH FROM THE USER
	SKIPE	T4			;IS THE MESSAGE LENGTH 0 ???
	CAILE	T4,(T3)			;   OR GREATER THEN MAXIMUM ALLOWED ???
	SETZM	P1			;YES,,THEN ITS INVALID !!!
	CAXL	P1,.OMOFF		;IS THIS AN ORION MESSAGE?
	JRST	OPRMSG			;YES, HANDLE IT DIFFERENTLY
	CAXLE	P1,QSRLEN		;NO,,IS IT A VALID MESSAGE TYPE ???
	SETZM	P1			;NO,,THEN ITS INVALID !!!
	MOVE	S1,QSRTAB(P1)		;ADDRESS OF PROCESSING ROUTINE
	PUSHJ	P,(S1)			;AND CALL THE ROUTINE
	SKIPE	G$ERR			;ANY ERRORS ???
	 SKIPL	QSRTAB(P1)		;YES, A KNOWN COMPONENT TYPE CALL
	  SKIPE	G$ACK			;NO, DOES USER WANT A RETURN MESSAGE
	   PUSHJ P,STGSND		;YES, BUILD STRING ANSWER AND SEND IT
	JRST	RELMSG			;AND DISMISS THE MESSAGE
;HERE WHEN A MESSAGE IS SENT TO [SYSTEM]INFO
;	P1 = MESSAGE TYPE
;	M  = MESSAGE PROPER
;	T1 = PACKET FLAGS

IFN FTINFO,<
INFMSG:	PUSHJ	P,P$INFO##		;PROCESS [SYSTEM]INFO REQUEST
	PJRST	RELMSG			;RELEASE MESSAGE
>  ;END OF IFN FTINFO
SUBTTL	Message Dispatch Tables

;THE DISPATCH TABLE IS ORDERED BY MESSAGE TYPE AND CONTAINS THE ADDRESS OF THE
;	CORRECT PROCESSING ROUTINE FOR THAT MESSAGE.

;BY DEFINITION, ANY ROUTINE CALLED THROUGH THIS DISPATCH IS A TOP LEVEL ROUTINE

;THE SIGN BIT (1B0) IS USED TO INDICATE THOSE MESSAGES THAT PROBABLY CAME FROM
;	A KNOWN COMPONENT (OR SOMEONE TRYING TO BECOME ONE) AND IS USED TO
;	DETERMINE IF A RESPONSE IS TO BE SENT ON ERRORS (EVEN IF DIDN'T ASK FOR THEM)

QSRTAB:	     0,,E$IMT		;FUNCTION 0  INVALID MESSAGE
	400000,,A$HELLO##	;FUNCTION 1  HELLO
	400000,,Q$RELEA##	;FUNCTION 2  RELEASE
	400000,,Q$CHECK##	;FUNCTION 3  CHECKPOINT
	400000,,Q$REQUE##	;FUNCTION 4  REQUEUE
	     0,,E$IMT		;FUNCTION 5  NEXTJOB (SENT BY QUASAR)
	     0,,E$IMT		;FUNCTION 6  ABORT   (SENT BY QUASAR)
	     0,,Q$CREATE##	;FUNCTION 7  CREATE
	     0,,D$LIST##	;FUNCTION 10 LIST
	     0,,Q$MODIFY##	;FUNCTION 11 MODIFY
	     0,,Q$KILL##	;FUNCTION 12 KILL
	     0,,E$IMT		;FUNCTION 13 LISTANSWER	(SENT BY QUASAR)
	     0,,E$IMT		;FUNCTION 14 (OBSOLETED)
	     0,,E$IMT		;FUNCTION 15 REQUEST FOR CHECKPOINT (SENT BY QUASAR)
	     0,,Q$DEFER##	;FUNCTION 16 DEFER
	     0,,E$IMT		;FUNCTION 17 OLD A$ROUTE MESSAGE.
	     0,,A$COUNT##	;FUNCTION 20 COUNT
	     0,,E$IMT		;FUNCTION 21 COUNTANSWER (SENT BY QUASAR)
	     0,,E$IMT		;FUNCTION 22 SETUP (SENT BY QUASAR)
	400000,,S$RSETUP##	;FUCNTION 23 RESPONSE-TO-SETUP
	     0,,E$IMT		;FUNCTION 24 OPERATOR-ACTION (SENT BY QUASAR)
	     0,,Q$HOLD##	;FUNCTION 25 HOLD/RELEASE MESSAGE
	     0,,E$IMT		;FUNCTION 26 MONITOR SPOOL MESSAGE
	     0,,E$IMT		;FUNCTION 27 MONITOR LOGOUT MESSAGE
	     0,,D$MOUNT##	;FUNCTION 30 USER TAPE MOUNT REQUEST
	400000,,A$STATUS##	;FUNCTION 31 DEVICE STATUS UPDATE MSG
	400000,,X$MTR		;FUNCTION 32 RELEASE MESSAGE FROM MTCON
	400000,,X$CHKP		;FUNCTION 33 TAPE MOUNT CHECKPOINT MESSAGE
	     0,,E$IMT		;FUNCTION 34 TAPE/DISK MNT ABORT MSG
	400000,,X$MATR		;FUNCTION 35 MNT ATTRIBUTE MSG REQUEST
	     0,,E$IMT		;FUNCTION 36 NODE WENT AWAY MSG (SEND BY QUASAR)
	     0,,Q$CRQE##	;FUNCTION 37 SHORT CREATE MESSAGE
	     0,,E$IMT		;FUNCTION 40 RECOGNOZE MESSAGE (QUASAR->PULASR)
	     0,,X$DEVSTA	;FUNCTION 41 TAPE/DISK DEVICE STATUS MESSAGE
	     0,,E$IMT		;FUNCTION 42 TAPE UNLOAD MSG (QUASAR TO PULSAR)
	     0,,E$IMT		;FUNCTION 42 TAPE VOLUME IN USE (QUA TO PLR)
	     0,,E$IMT		;FUNCTION 44 TAPE VOL WAS DEASSIGNED (QUA 2 PLR)
	     0,,X$VSR		;FUNCTION 45 VOLUME SWITCH REQUEST (PLR 2 QUA)
	     0,,E$IMT		;FUNCTION 46 VOLUME SWITCH DIRECTIVE (QUA 2 PLR)
	     0,,E$IMT		;FUNCTION 47 TAPE REWIND MSG (QUASAR 2 PULSAR)
	     0,,E$IMT		;FUNCTION 50 ASK FOR CATALOG INFO (QUA 2 PLR)
	     0,,E$IMT		;FUNCTION 51 CATALOG RESPONSE (PLR TO QUA)
	     0,,E$IMT		;FUNCTION 52 BUILD STRUCTURE MSG (QUA 2 PLR)
	     0,,E$IMT		;FUNCTION 53 DISMOUNT STRUCTURE MSG (QUA 2 PLR)
	     0,,X$ACK		;FUNCTION 54 MDA ACK MESSAGE (PLR TO QUA)
	     0,,E$IMT		;FUNCTION 55 MDA ADD STRUCTURE TO SEARCH LIST
	     0,,X$DVS		;FUNCTION 56 MDA DISMOUNT/DEALLOCATE MSG
	     0,,D$LALC##	;FUNCTION 57 SHOW ALLOCATION MSG
	     0,,E$IMT		;FUNCTION 60 ALLOC SCAN REQUEST (QSR TO BATCON)
	     0,,X$UMDR		;FUNCTION 61 ALLOC SCAN ANSWER	(BATCON TO QSR)
	     0,,X$INID		;FUNCTION 62 TAPE INITIALIZE DONE (PULSAR 2 QSR)
	     0,,E$IMT		;FUNCTION 63 FORMS CHANGE MESSAGE TO LPTSPL
	     0,,IBMSTS		;FUNCTION 64 IBMCOM STATISTICS UPDATE MESSAGE
	     0,,E$IMT		;FUNCTION 65 TOPS20 [SYSTEM]GOPHER TO QUASAR
	     0,,E$IMT		;FUNCTION 66 KSYS TIMEOUT (QUASAR TO BATCON)
	     0,,E$IMT		;FUNCTION 67 AUTO-FILE (QUASAR TO ORION)
	     0,,E$IMT		;FUNCTION 70 OPR LOG CLOSURE (QUASAR TO ORION)
	     0,,A$STATUS##	;FUNCTION 71 FAL STATUS UPDATE MSG (FAL TO QSR)
	     0,,Q$EQR##		;FUNCTION 72 EQ REQUEST
	     0,,E$IMT		;FUNCTION 73 EQ ANSWER
	     0,,E$IMT		;FUNCTION 74 OBJECT DATA BLOCK MSG (QSR TO SPLR)
	     0,,Q$BLSR##	;FUNCTION 75 BINARY QUEUE LIST REQUEST
	     0,,E$IMT		;FUNCTION 76 BINARY QUEUE LIST ANSWER
QSRLEN==<.-QSRTAB>-1		;HIGHEST LEGAL MESSAGE FROM USER TO QUASAR
SUBTTL	Operator Message Dispatch

;HERE UPON RECEIPT OF A MESSAGE WHICH IS SENT TO [SYSTEM]QUASAR AND
;	HAS A MESSAGE CODE WHICH INDICATES THAT IS IS FROM ORION.

;	P1 = MESSAGE TYPE
;	M  = THE MESSAGE PROPER
;	T3 = THE MAXIMUM MESSAGE SIZE POSSIBLE (PAGSIZ OR G$MPS)
;	T1 = FLAGS
;	T4 = ACTUAL SIZE OF MESSAGE

OPRMSG:	LOAD	S1,G$PRVS,MR.JOB	;GET 'JOB' NUMBER
	ANDX	S1,MD.PJB		;KEEP JUS REAL JOB NUMBER
	STORE	S1,G$PRVS,MR.JOB	;PUT IT BACK
	MOVE	S1,G$IDX		;GET SPECIAL INDEX WORD
	TXZE	S1,SI.FLG		;IS IT IN USE?
	CAXE	S1,SP.OPR		;AND IS MESSAGE FROM ORION?
	JRST	RELMSG			;NO, FORGET ABOUT IT
	CAIN	P1,MT.TXT		;IS IT AN ACK TXT MESSAGE ???
	JRST	RELMSG			;YES,,PITCH IT !!!
	CAIL	P1,.ODMES		;IS THIS A OPR MOUNT REQUEST ???
	JRST	OPRM.2			;YES,,GO PROCESS IT
	MOVSI	S1,-OPRLEN		;GET LENGTH OF DISPATCH TABLE

OPRM.1:	HLRZ	S2,OPRTAB(S1)		;GET CODE FOR ENTRY
	CAME	P1,S2			;DOES THIS MATCH AN ENTRY IN THE TABLE?
	AOBJN	S1,OPRM.1		;NO, LOOP FOR NEXT ENTRY
	HRRZ	S1,OPRTAB(S1)		;GET PROCESSOR FOR THIS ENTRY
	PUSHJ	P,0(S1)			;CALL PROPER ROUTINE
	HRRZ	S1,G$ERR		;GET POSSIBLE ERROR CODE
	SKIPE	S1			;ANY ERRORS?
	$ACK	(<^T/@TXTTBL(S1)/>,,,.MSCOD(M)) ;YES,,TELL OPERATOR
	PJRST	RELMSG			;NO,,RELEASE MESSAGE AND RETURN

OPRM.2:	PUSHJ	P,I$OMNT##		;GO PROCESS THE MESSAGE
	PJRST	RELMSG			;RELEASE MESSAGE AND RETURN



; TABLE OF LEGAL ORION TO QUASAR MESSAGES

OPRTAB:	.OMSTA,,A$OSTA##		;STARTUP MESSAGE
	.OMSHT,,A$OSHT##		;SHUTDOWN MESSAGE
	.OMSET,,A$OSET##		;SET MESSAGE
	.OMPAU,,A$OPAU##		;PAUSE MESSAGE
	.OMCON,,A$OCON##		;CONTINUE
	.OMSHS,,D$SHST##		;SHOW STATUS MESSAGE.
	.OMSHC,,A$OSHC##		;SHOW COMMAND FILE (EXAMINE)
	.OMSHP,,D$SHPR##		;SHOW PARAMETERS.
	.OMSHQ,,D$SHQS##		;SHOW QUEUES MESSAGE.
	.OMSQN,,D$SHQN##		;SHOW QUEUE-NAMES
	.OMSHR,,D$SHRT##		;SHOW ROUTE TABLE
	.OMREQ,,A$OREQ##		;REQUEUE
	.OMCAN,,A$OCAN##		;CANCEL
	.OMFWS,,A$OFWS##		;FORWARD SPACE MSG.
	.OMALI,,A$OALI##		;ALIGN PRINTER
	.OMSUP,,A$OSUP##		;SUPPRESS CARRAIGE CONTROL
	.OMSND,,A$OSND##		;SEND COMMAND
	.OMBKS,,A$OBKS##		;BACK SPACE COMMAND
	.OMHLD,,A$OHLD##		;OPERATOR HOLD COMMAND.
	.OMREL,,A$OREL##		;OPERATOR RELEASE COMMAND.
	.OMRTE,,A$ORTE##		;OPERATOR ROUTE COMMAND.
	.OMRTD,,N$NRTE##		;DEVICE ROUTE COMMAND
	.OMDEL,,A$ODEL##		;DELETE JOBS FROM SYSTEM QUEUES
	.OMMOD,,A$MODIFY##		;MODIFY QUEUE ENTRY PROCESSOR
	.OMENA,,A$QUEUE##		;[1152] ENABLE MESSAGE PROCESSOR
	.OMDIS,,A$QUEUE##		;[1152] DISABLE MESSAGE PROCESSOR
	.OMDEF,,A$DEFINE##		;NETWORK DEFINE COMMAND
	.OMDQN,,A$DQNM##		;DEFINE QUEUE-NAME
	.OMDSP,,A$DN60##		;DN60 OPR MESSAGE PROCESSOR
	.OMSPN,,D$NPRM##		;NETWORK (IBM) SHOW PARAMETERS
	.OMSSN,,D$NSTS##		;NETWORK SHOW STATUS
	.OMNXT,,A$NEXT##		;[NXT] NEXT COMMAND
TOPS10 <
	.OMETS,,A$ETSR##		;ENABLE TIMESHARING
	.OMODB,,A$OODB##		;OBJECT TYPE DATA DEFINITION
> ;END TOPS10
	OPRLEN==.-OPRTAB		;LENGTH OF TABLE
		E$IMT			;PROCESSOR IF NONE FOUND IN TABLE
SUBTTL	[SYSTEM]CATALOG message dispatch


; Here upon receipt of a message which is sent to [SYSTEM]QUASAR and
; from the [SYSTEM]CATALOG, the catalog daemon.

CATMSG:	CAIN	P1,MT.TXT		;IS IT AN ACK TXT MESSAGE ???
	JRST	RELMSG			;YES,,PITCH IT !!!
	MOVSI	S1,-CATSIZ		;GET LENGTH OF DISPATCH TABLE

CATM.1:	HLRZ	S2,CATTAB(S1)		;GET MESSAGE TYPE
	CAME	P1,S2			;A MATCH?
	AOBJN	S1,CATM.1		;KEEP SEARCHING
	HRRZ	S1,CATTAB(S1)		;GET PROCESSOR FOR THIS ENTRY
	PUSHJ	P,0(S1)			;CALL PROPER ROUTINE
	HRRZ	S1,G$ERR		;GET POSSIBLE ERROR CODE
	SKIPE	S1			;ANY ERRORS?
	$ACK	(<^T/@TXTTBL(S1)/>,,,.MSCOD(M)) ;YES
	PJRST	RELMSG			;RELEASE MESSAGE AND RETURN


; Table of legal catalog daemon to QUASAR message functions
CATTAB:	.CFACT,,V$RCAT##		;ANSWER TO REQUEST FOR CATALOG INFO
	.CFRQS,,V$AQST##		;REQUEST FOR QUEUE STRUCTURE INFO
	.CFDIS,,V$DISA##		;DISABLE CATALOG UPDATES BY MDA
	.CFENA,,V$ENAB##		;ENABLE CATALOG UPDATES BY MDA
CATSIZ==.-CATTAB			;LENGTH OF TABLE
	000000,,E$IMT			;PROCESSOR IF NONE FOUND IN TABLE
	SUBTTL	Tables for Error Codes Reported

DEFINE	X(SUFFIX,TEXT,ERRLVL),<
E$'SUFFIX:: PUSHJ P,RPTERR		;DISPATCH TO ERROR HANDLER
>  ;END OF DEFINE X

ERRTBL:	ERRCDS				;EXPAND THE DISPATCH TABLE

DEFINE	X(SUFFIX,TEXT,ERRLVL),<
	EXP	[ASCIZ\TEXT\]		;TABLE OF MESSAGES
>  ;END OF DEFINE X

TXTTBL::EXP	[BYTE (7)0]		;0 IS NOT REALLY AN ERROR
	ERRCDS				;DEFINE THE REST OF THEM

DEFINE	X(SUFFIX,TEXT,ERRLVL),<
	ERRLVL!INSVL.(<SIXBIT\   SUFFIX\>,MF.SUF)
>  ;END OF DEFINE X

STSTBL:	MF.NOM				;0 HAS NO TEXT ASSOCIATED
	ERRCDS				;EXPAND THE REST NOW

;HERE WHEN SOMEONE CALLS (OR EXITS THROUGH) ANY OF THE E$xxx ERROR CODES
;	THIS STORES THE RELATIVE ERROR NUMBER INTO G$ERR

RPTERR:	EXCH	T1,0(P)			;SAVE T1, GET ERROR DISPATCH
	SUBI	T1,ERRTBL		;CONVERT TO ERROR INDEX
	HRRZM	T1,G$ERR		;SET GLOBAL ERROR INDICATOR
	POP	P,T1			;RESTORE T1
	$RETF				;RETURN FALSE
	SUBTTL	Message Formatting Utilities for TEXT Message

;SUBROUTINE TO INSERT A SINGLE ASCII CHARACTER INTO THE CURRENT TEXT MESSAGE
;CALL WITH S1 CONTAINING THE CHARACTER RIGHT JUSTIFIED
;TRUE RETURN:	ALWAYS

	INTERN	G$CCHR

G$CCHR:	SKIPE	STGBPT			;STRING STARTED YET
	JRST	CCHR.1			;YES, JUST INSERT ONE
	MOVE	S2,[POINT 7,G$MSG+.OHDRS+ARG.DA]  ;INIT THE BYTE POINTER
	MOVEM	S2,STGBPT		;TUCK IT AWAY
	SETZM	G$MSG+MSGLN-1		;[1223]BUFFER IS NOT FULL
CCHR.1:	SKIPN	G$MSG+MSGLN-1		;ARE WE AT THE END OF THE BUFFER
	IDPB	S1,STGBPT		;NO,,INCLUDE THIS CHARACTER
	$RETT				;RETURN FOR THE NEXT ONE

STGBPT:	BLOCK	1			;POINTER TO CURRENT STRING (0 IF NONE)
;ROUTINE TO STORE THE CURRENT ERROR CODE INTO THE TEXT MESSAGE

G$STGS::				;GLOBAL ENTRY POINT
STGSND:	HRRZ	S1,G$ERR		;GET THE ERROR CODE (EVEN IF ZERO)
	$TEXT(G$CCHR,<^T/@TXTTBL(S1)/^A>);STORE THE MESSAGE
	MOVE	S1,STSTBL(S1)		;GET THE FLAGS AND PREFIX
	HRRZ	S2,S1			;COPY PREFIX
	CAIN	S2,'XXX'		;GENERIC?
	HLRZ	S2,G$ERR		;YES--GET ALTERNATE
	SKIPN	S2			;NON-ZERO?
	MOVEI	S2,'XXX'		;NO--LEAVE AS XXX
	HRR	S1,S2			;UPDATE

;FALL INTO THE GLOBAL ROUTINE TO SEND THE MESSAGE TO THE USER

;SUBROUTINE TO SEND THE CURRENT STRING TO THE USER (G$SND)
;CALL WITH S1 CONTAINING THE FLAGS AND PREFIX TO STORE INTO FLAG WORD
;DESTROYS S1 AND S2

	INTERN	G$MSND

G$MSND:	PUSHJ	P,.SAVE1		;SAVE A REG
	$SAVE	AP			;SAVE ANOTHER
	TXNN	S1,MF.MOR		;GOING TO GENERATE ANOTHER AFTER THIS
	SETZM	G$ACK			;NO, CLEAR ACK REQUEST
	MOVE	S2,G$MCOD		;GET TURN-AROUND CODE
	MOVEM	S2,G$MSG+.MSCOD		;STORE INTO THE PROPER PLACE
	TXNN	S1,MF.MOR		;IF NO CONTINUATION,
	SETZM	G$MCOD			;CLEAR THE CODE OUT
	MOVEM	S1,G$MSG+.MSFLG		;STORE REQUESTED INFORMATION
	SETZM	G$MSG+.OARGC		;CLEAR THE ARGUMENT COUNT
	SKIPN	S1,STGBPT		;HAVE WE INSERTED ANYTHING YET ???
	JRST	[MOVX  S2,MF.NOM	;NO,,A NULL ACK SO GET 'NO MESSAGE'
		 MOVEM S2,G$MSG+.MSFLG	;AND SET THE FLAG BITS
		 JRST  MSND.0 ]		;SEND THE MESSAGE OFF
	MOVEI	S1,0			;APPEND A NULL BYTE
	PUSHJ	P,G$CCHR		;   TO THE END OF THE MESSAGE
	HRRZ	S1,STGBPT		;NOW COMPUTE THE BLOCK LENGTH BY
	SUBI	S1,G$MSG+.OHDRS+ARG.DA-2 ;   SUBTRACTING THE STARTING ADDRESS-2
	STORE	S1,G$MSG+.OHDRS+ARG.HD,AR.LEN ;SAVE THE BLOCK SIZE
	MOVX	S2,.CMTXT		;GET THE BLOCK TYPE
	STORE	S2,G$MSG+.OHDRS+ARG.HD,AR.TYP ;SAVE THE BLOCK TYPE
	AOS	G$MSG+.OARGC		;BUMP THE ARGUMENT COUNT BY 1
MSND.0:	ADDI	S1,.OHDRS		;ADD THE HEADER LENGTH
	STORE	S1,G$MSG+.MSTYP,MS.CNT	;SAVE THE MESSAGE LENGTH
	MOVEM	S1,G$SAB+SAB.LN		;SAVE THE MESSAGE LENGTH IN SAB
	MOVEI	S2,.OMTXT		;GET THE MESSAGE TYPE
	STORE	S2,G$MSG+.MSTYP,MS.TYP	;SAVE THE MESSAGE TYPE
	MOVEI	S2,G$MSG		;POINT AT THE MESSAGE
	MOVEM	S2,G$SAB+SAB.MS		;SAVE THE MESSAGE ADDRESS
	MOVE	S2,G$SND		;GET CURRENT SENDER
	MOVEM	S2,G$SAB+SAB.PD		;SAVE RECIEVERS PID
	SETZM	STGBPT			;CLEAR THE MSG BYTE POINTER
	SKIPN	G$ACKO			;ACKING OPR CREATES?
	PJRST	C$SEND##		;NO--SEND THE MESSAGE AND RETURN
	$ACK	(<^T/G$MSG+.OHDRS+ARG.DA/>,,,G$MSG+.MSCOD)
	$RETT				;RETURN
	SUBTTL	G$SFAL  --  Notify all Processors of Unknown PID

;CALLED WITH S1 = THE NOW INVALID PID

;THIS IN TURN, CALLS ANYONE WHO WORRYS ABOUT THAT SITUATION

	INTERN	G$SFAL

G$SFAL:	CAMN	S1,G$GPID	;DID GOPHER BOUNCE A PACKET?
	POPJ	P,		;YES, FORGET ABOUT IT
IFN FTINFO,<
	PUSHJ	P,P$KLPD##	;NOTIFY INFO AND ITS WAITERS (PRESERVES S1)
>
	PJRST	A$KLPD##	;TELL QUASAR - QUEUE MANIPULATOR AND RETURN
SUBTTL	$TEXT Utilities

;G$STTX - ROUTINE TO SETUP A BYTE-POINTER FOR G$TEXT.
;
;CALL:	S1/ ADDRESS OF THE BLOCK OF STORAGE TO POINT TO

G$STTX:: HRLI	S1,(POINT 7,0)		;MAKE A BYTE POINTER
	MOVEM	S1,G$TXBP		;STORE IT
	$RETT				;AND RETURN

;G$TEXT - $TEXT SUBROUTINE TO DEPOSIT A BYTE ACCORDING TO THE BYTE
;	POINTER SETUP IN G$TXBP.

G$TEXT:: IDPB	S1,G$TXBP		;DEPOSIT THE BYTE
	$RETT				;AND RETURN

	SUBTTL	CNTINI - INITIALIZE ITEMS USED IN COUNT/CNTANSWER EXCHANGE

	;This routine initializes the CNTANSWER message.
	;Users wishing to keep track of GALAXY performance over time can
	;send COUNT messages to QUASAR as they desire, and compare the rate
	;of change of various of the counters.

CNTINI:	SETOM	S1			;WANT INFO FOR THIS JOB
	MOVX	S2,JI.JNO		;LETS GET JOB NUMBER
	$CALL	I%JINF			;GET IT
	$SITEM	S2,QJOB			;SAVE IT
	$CALL	I%NOW			;GET CURRENT TIME
	$SITEM	S1,STAR			;SAVE AS QUASAR'S START TIME
	MOVEI	S1,NITEMS		;get the number of items in record
	$SITEM	S1,ICNT			;save it in the record

TOPS10<	MOVX	S1,%CNSUP		;WANT SYSTEM UPTIME IN CLOCK TICKS
	GETTAB	S1,			;GET IT
	 MOVX	S1,.INFIN		;SHOULD NOT HAPPEN
	MOVX	S2,%CNTIC		;WANT CLOCK TICKS PER SECOND
	GETTAB	S2,			;GET IT
	 MOVX	S2,^D60			;SHOULD NOT HAPPEN
> ;END TOPS10 CONDITIONAL

TOPS20<	TIME  >				;GET SYSTEM UPTIME IN MILLISECONDS
	IDIV	S1,S2			;CALC # SECONDS OF UPTIME
	IDIVI	S1,^D60			;CALC # MINUTES OF UPTIME

	CAILE	S1,^D10			;STARTING AFTER 10 MINUTE WINDOW ?
	SETOM	G$ITEM+$$IPCI		;NO,,INDICATE QUASAR RESTARTED
	POPJ	P,			;RETURN
	SUBTTL	IBMSTS - Routine to update counters for IBMCOM

	;CALL:	M/ The update message address
	;
	;RET:	True always

IBMSTS:	PUSHJ	P,A$WHEEL##		;Is sender a wheel ???
	JUMPF	.RETT			;No,,ignore it
	MOVE	S1,3(M)			;Get the function code
	CAXN	S1,%TOUT		;Termination printer request ???
	$COUNT	(TOUT)			;Yes,,account for it
	CAXN	S1,%TINP		;Termination batch request ???
	$COUNT	(TINP)			;Yes,,account for it
	CAXN	S1,%TCNI		;Termination console input ???
	$COUNT	(TCNI)			;Yes,,account for it
	CAXN	S1,%TCNO		;Termination console output ??
	$COUNT	(TCNO)			;Yes,,account for it
	CAXN	S1,%EOUT		;Emulation printer request ???
	$COUNT	(EOUT)			;Yes,,account for it
	CAXN	S1,%EINP		;Emulation batch request ???
	$COUNT	(EINP)			;Yes,,account for it
	CAXN	S1,%ECNI		;Emulation console input ???
	$COUNT	(ECNI)			;Yes,,account for it
	CAXN	S1,%ECNO		;Emulation console output ??
	$COUNT	(ECNO)			;Yes,,account for it
	$RETT				;Return
	END	QUASAR