Google
 

Trailing-Edge - PDP-10 Archives - BB-H138B-BM - language-sources/quasar.mac
There are 41 other files named quasar.mac in the archive. Click here to see a list.
	TITLE	QUASAR  --  QUASAR Controller - version 4

;
;
;                COPYRIGHT (c) 1975,1976,1977,1978,1979
;                    DIGITAL EQUIPMENT CORPORATION
;
;     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

	QSRVRS==<VRSN.(QSR)>	;MAKE UP A VERSION NUMBER

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

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$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$QPID:: BLOCK	1		;QUASAR'S PID

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

G$APID:: BLOCK	1		;ACTDAE PID (-10 ONLY)

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$QUEU:: BLOCK	1		;CREATE GENERATION FLAG 0=CREATE, -1=NO CREATES

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

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.

G$LOGN:: BLOCK	1		;-1 IF BATCH LOGINS ARE ALLOWED

G$KSYS:: BLOCK	1		;NUMBER OF SECS TO KSYS
				;0=NO KSYS SET,  -1=T/S IS OVER

	;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$LNAM:: BLOCK	1		;LOCAL NODE NAME (IN SIXBIT)

G$LNBR:: BLOCK	1		;LOCAL NODE NUMBER

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$ACTS:: BLOCK	10		;ACCOUNT STRING BUFFER FOR IPCF MESSAGES

G$ACCT:: BLOCK	1		;ACCOUNT STRING ADDRESS 

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$SAB::	BLOCK	SAB.SZ		;AN SAB FOR SENDING IPCF MESSAGES

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

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

PDL::	BLOCK	100		;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.JWP!IP.SPB) ;PSI ON + JOBWIDE PID + SPECIAL PID
	 $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				;

	;DEFINE MESSAGE TYPES THAT ARE SYSTEM DEPENDENT

	SYSPRM	%IPCSR,0,.IPCSR		;FILE ARCHIVING MESSAGE	   (TOPS20)
	SYSPRM	%IPCDE,.IPCDE,0		;DEVICE DEASSIGN MSG	(TOPS10)
	SYSPRM	%IPCUO,.IPCUO,0		;DEVICE ONLINE MESSAGE	(TOPS10)

	;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)
	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	100,PDL]	;GET A PUSHDOWN LIST
	AOSE	STFLAG			;MAKE SURE WE AREN'T RESTARTED
	  $STOP(QNR,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,INPMAX		;GET THE MAX NUMBER OF BATCH STREAMS.
	MOVEM	S1,G$NBAT		;   AND SAVE IT.
	PUSHJ	P,N$INIT##		;SETUP THE NETWORK DATA BASE
	PUSHJ	P,I$INIT##		;INITIALIZE THE SYSTEM 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,S$INIT##		;THE TASK SCHEDULER
SUBTTL	Main Processing Loop

MAIN:	PUSHJ	P,I%NOW			;GET TIME AND DATE
	MOVEM	S1,G$NOW		;STORE FOR ANYONE WHO WANTS IT
	PUSHJ	P,C$GET##		;GET A MESSAGE
	JUMPN	AP,MAIN.1		;JUMP IF WE'VE GOT SOMETHING
	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.
	SETZ	S1,			;GET A CLEAR AC
	EXCH	S1,G$WTIM		;CLEAR SLEEP TIME AFTER READING IT
	MOVE	S2,G$NOW		;GET NOW
	CAML	S2,S1			;SKIP IF NOW IS LESS THAN THEN
	JUMPN	S1,MAIN			;JUMP IF THERE IS A TIMER (EXPIRED)
	SKIPE	S1			;SKIP IF NO-ONE SET TIMER
	PUSHJ	P,I$AGE##		;ELSE, GET THE DIFFERENCE
	PUSHJ	P,I%SLP			;AND SLEEP
	JRST	MAIN			;AND LOOP

MAIN.1:	MOVEM	AP,G$ENT		;SAVE ADDRESS OF THE ENTRY
	ZERO	G$ERR			;CLEAR PREVIOUS ERROR INDICATOR
	ZERO	G$BLKA			;CLEAR THE MESSAGE BLOCK ADDRESS
	MOVEI	T1,IPCACT(AP)		;GET THE ACCOUNT STRING ADDRESS.
	MOVEM	T1,G$ACCT		;AND SAVE IT
	MOVE	T1,IPCSDR(AP)		;GET SENDERS PID
	MOVEM	T1,G$SND		;AND SAVE IT
	MOVE	T1,IPCSID(AP)		;GET SENDERS OWNER ID
	MOVEM	T1,G$SID		;AND SAVE IT
	MOVE	T1,IPCCDI(AP)		;GET SENDER'S CONNECTED DIRECTORY
	MOVEM	T1,G$CDI		;SAVE IT
	MOVE	T1,IPCPRV(AP)		;GET SENDERS CAPABILITIES
	MOVEM	T1,G$PRVS		;SAVE THAT AS WELL
	MOVE	T1,IPCIDX(AP)		;GET SENDER'S SYSTEM INDEX WORD
	MOVEM	T1,G$IDX		;STORE IT
	LOAD	M,IPCMES(AP),IPM.AD	;GET ADDRESS OF THE MESSAGE
	MOVE	T1,IPCFLG(AP)		;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

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

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$SND		;GET THE SENDERS PID
	CAMN	S1,G$APID		;IS IT ACTDAE PID ???
	  JRST	ACTMSG			;YES,,DISPATCH IT
	LOAD	S1,IPCRCR(AP)		;GET PID MESSAGE WAS SENT TO
	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,D$VMDA##		;GO VALIDATE ALL MDA DATA STRUCTURES
	MOVE	AP,G$ENT		;GET ADDRESS OF IPC ENTRY
	PUSHJ	P,C$PUT##		;RETURN IT TO THE FREE SPACE
	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
;	T1 = THE PACKET FLAGS

	EXTERN	MDAOBJ			;MDA OBJECT BLOCK FOR WTO

SYSMSG:	TXNE	T1,IP.CFP		;REQUESTING PRIVILEGES
	  JRST	RELMSG			;YES, IGNORE IT
	MOVEI	S1,.POPJ		;IN CASE WE DON'T FIND ONE
	CAIN	P1,.IPCSU		;SPOOLING MESSAGE
	  MOVEI	S1,Q$SPOOL##		;YES, SET UP DISPATCH
	CAIN	P1,.IPCSL		;LOGOUT MESSAGE
	  MOVEI	S1,Q$LOGOUT##		;YES, SET UP DISPATCH
	CAIN	P1,%IPCSR		;ARCHIVE MESSAGE
	  MOVEI	S1,X$ARCHIVE		;YES, SET UP DISPATCH
	CAIN	P1,%IPCDE		;IS IT A DEASSIGN MESSAGE
	  MOVEI	S1,X$DEASSIGN		;YES,,SET UP DISPATCH
	CAIN	P1,%IPCUO		;IS IT A UNIT ON-LINE MESSAGE?
	  MOVEI	S1,X$AVR		;GO SEE WHAT KIND OF AVR
	PUSHJ	P,0(S1)			;CALL THE HANDLER
	SKIPE	S1,G$ERR		;WAS THERE ANY ERROR?
	CAIE	P1,%IPCDE		;YES, AND WAS IT ON A DEASSIGN?
	JRST	RELMSG			;NO, JUST GET RID OF THE MESSAGE

;Here with ER$xxx code in S1 to send a message to OPR
; complaining about MDA  related errors.
MDAERR:	$WTO	(<^T/@TXTTBL(S1)/>,,MDAOBJ)
	JRST	RELMSG			;AND DISMISS THE MESSAGE


;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:	TXNE	T1,IP.CFP		;REQUESTING PRIVILEGES
	  JRST	RELMSG			;YES, IGNORE THEM
	LOAD	T4,.MSCOD(M)		;GET TURN-AROUND CODE FOR MESSAGE
	MOVEM	T4,G$MCOD		;REMEMBER IT
	LOAD	T4,.MSFLG(M),MF.ACK	;GET "ACK" CODE
	MOVEM	T4,G$ACK		;REMEMBER IF USER WANTS ONE
	ZERO	.MSFLG(M),MF.ACK	;CLEAR REQUEST IN MESSAGE PROPER
	LOAD	T4,.MSTYP(M),MS.CNT	;GET THE LENGTH FROM THE USER
	CAILE	T4,(T3)			;SPECIFY AN IMPOSSIBLE LENGTH?
	  MOVEI	P1,QSRLEN+1		;YES, SET TO SAY "TOO LONG"
	CAXL	P1,.OMOFF		;IS THIS AN ORION MESSAGE?
	JRST	OPRMSG			;YES, HANDLE IT DIFFERENTLY
	CAILE	P1,QSRLEN		;AN UNKNOWN MESSAGE
	  ZERO	P1			;YES, MAKE IT LOOK INVALID
	MOVE	S1,QSRTAB(P1)		;ADDRESS OF PROCESSING ROUTINE
	PUSHJ	P,(S1)			;AND CALL THE ROUTINE
	SKIPE	S1,G$ERR		;DID AN ERROR OCCUR
	CAXE	P1,.QOTST		;WAS IT TAPE STATUS?
	SKIPA				;NO PROBLEMS,,CONTINUE
	JRST	MDAERR			;TELL OPR ABOUT THE ERROR
	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
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
	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)

QSRLEN==<.-QSRTAB>-1		;HIGHEST LEGAL MESSAGE FROM USER TO QUASAR

	     0,,E$IMT		;HIGHEST + 1 = INVALID MESSAGE
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:	MOVE	S1,G$IDX		;GET SPECIAL INDEX WORD
	TXZE	S1,IPS.FL		;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,.OTMES		;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
	SKIPE	G$ACK			;USER WANTS ACK?
	PUSHJ	P,STGSND		;YES, BUILD STRING AND SEND IT
	PJRST	RELMSG			;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.
	.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.
	.OMDEL,,A$ODEL##		;DELETE JOBS FROM SYSTEM QUEUES
	.OMMOD,,A$MODIFY##		;MODIFY QUEUE ENTRY PROCESSOR
	.OMENA,,A$ENABLE##		;ENABLE MESSAGE PROCESSOR
	.OMDIS,,A$DISABLE##		;DISABLE MESSAGE PROCESSOR
	.OMDEF,,A$DEFINE##		;NETWORK DEFINE COMMAND
	.OMDSP,,A$DN60##		;DN60 OPR MESSAGE PROCESSOR
	.OMSPN,,D$NPRM##		;NETWORK (IBM) SHOW PARAMETERS
	.OMSSN,,D$NSTS##		;NETWORK SHOW STATUS
	OPRLEN==.-OPRTAB		;LENGTH OF TABLE
		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,ACKMSG+.OHDRS+ARG.DA]  ;INIT THE BYTE POINTER
	MOVEM	S2,STGBPT		;TUCK IT AWAY
CCHR.1:	IDPB	S1,STGBPT		;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

STGSND:	MOVE	P1,G$ERR		;GET THE ERROR CODE (EVEN IF ZERO)
	$TEXT(G$CCHR,<^T/@TXTTBL(P1)/^A>);STORE THE MESSAGE
	MOVE	S1,STSTBL(P1)		;GET THE FLAGS AND PREFIX

;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,ACKMSG+.MSCOD	;STORE INTO THE PROPER PLACE
	TXNN	S1,MF.MOR		;IF NO CONTINUATION,
	SETZM	G$MCOD			;CLEAR THE CODE OUT
	MOVEM	S1,ACKMSG+.MSFLG	;STORE REQUESTED INFORMATION
	SETZM	ACKMSG+.OARGC		;CLEAR THE ARGUMENT COUNT
	SKIPN	S1,STGBPT		;HAVE WE INSERTED ANYTHING YET ???
	JRST	MSND.0			;NO,,THEN ITS A NULL ACK
	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,ACKMSG+.OHDRS+ARG.DA-2 ;   SUBTRACTING THE STARTING ADDRESS-2
	STORE	S1,ACKMSG+.OHDRS+ARG.HD,AR.LEN ;SAVE THE BLOCK SIZE
	MOVX	S2,.CMTXT		;GET THE BLOCK TYPE
	STORE	S2,ACKMSG+.OHDRS+ARG.HD,AR.TYP ;SAVE THE BLOCK TYPE
	AOS	ACKMSG+.OARGC		;BUMP THE ARGUMENT COUNT BY 1
MSND.0:	ADDI	S1,.OHDRS		;ADD THE HEADER LENGTH
	STORE	S1,ACKMSG+.MSTYP,MS.CNT ;SAVE THE MESSAGE LENGTH
	HRLM	S1,MSND.A+.IPCFP	;AND AS PACKET LENGTH
	MOVX	S2,.OMTXT		;GET THE MESSAGE TYPE
	STORE	S2,ACKMSG+.MSTYP,MS.TYP ;SAVE THE MESSAGE TYPE
	MOVEI	S2,ACKMSG		;POINT AT THE MESSAGE
	HRRM	S2,MSND.A+.IPCFP	;NOW HAS LENGTH,,ADDR
	ZERO	MSND.A+.IPCFL		;CLEAR FLAGS
	MOVE	S2,G$SND		;GET CURRENT SENDER
	MOVEM	S2,MSND.A+.IPCFR	;AS THE RECEIVER
	CAMG	S1,G$MPS		;SHOULD THIS REALLY BE PAGED
	  JRST	MSND.1			;NO, ALL READY TO SEND
	PUSHJ	P,M%ACQP		;YES, GET A PAGE
	HRRM	S1,MSND.A+.IPCFP	;STORE THE PAGE NUMBER
	PG2ADR	S1			;CONVERT TO AN ADDRESS

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

	MOVEI	S2,PAGSIZ		;LENGTH OF A PAGE
	HRLM	S2,MSND.A+.IPCFP	;AND STORE THAT
	MOVX	S2,IP.CFV		;GET BIT INDICATING PAGED
	MOVEM	S2,MSND.A+.IPCFL	;STORE THE FLAG
	LOAD	S2,ACKMSG+.MSTYP,MS.CNT	;LOAD THE MESSAGE LENGTH
	ADDI	S2,-1(S1)		;CALC THE ENDING ADDRESS
	HRLI	S1,ACKMSG		;ADDRESS OF ORIGINAL MESSAGE
	BLT	S1,0(S2)		;MOVE DATA TO THE PAGE
MSND.1:	SETZM	STGBPT			;CLEAR THE MSG BYTE POINTER
	MOVEI	AP,MSND.A		;PDB FOR C$SEND
	PJRST	C$SEND##		;SEND THE MESSAGE AND RETURN

MSND.A:	BLOCK	IPCHSZ			;RESERVE CORE FOR THE PDB
ACKMSG:	BLOCK	^D50			;SPACE FOR MESSAGE
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:	PJRST	A$KLPD##	;TELL QUASAR - QUEUE MANIPULATOR AND RETURN
SUBTTL	G$STIM  --  Set time to wakeup

;G$STIM is called by any process which wants to ensure that
;	QUASAR wakes up before a particular time.
;
;CALL:	S1/ TIME TO WAKEUP BY

G$STIM:: CAMG	S1,G$NOW		;IS TIME BEFORE NOW?
	$RETT				;YES, JUST RETURN
	SKIPE	G$WTIM			;SKIP IF NEVER SET BEFORE
	CAMGE	S1,G$WTIM		;ELSE, SEE IF NEW TIME IS SOONER
	MOVEM	S1,G$WTIM		;STORE NEW TIME
	$RETT				;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
	END	QUASAR