Google
 

Trailing-Edge - PDP-10 Archives - AP-D483B-SB_1978 - quasar.mac
There are 41 other files named quasar.mac in the archive. Click here to see a list.
TITLE	QUASAR  --  QUASAR Controller - version 2
SUBTTL	C.D. O'Toole  L.S. Samberg  11 Oct 76

;***Copyright (C) 1974, 1975, 1976, Digital Equipment Corp., Maynard, Mass.***

	SEARCH	QSRMAC		;PARAMETER FILE

	PROLOGUE(QUASAR)	;GENERATE THE NECESSARY SYMBOLS


	LOC	41		;INSTALL CALL TO LUUO HANDLER
	PUSHJ	P,LUUO

	LOC	137		;INSTALL OUR VERSION NUMBER
	BYTE	(3)QSRWHO  (9)QSRVER  (6)QSRMIN  (18)QSREDT

	RELOC	0		;BACK TO RELOCATABLE CODE


;	STOPCDs found in QUASAR  Main Module

;ILU	ILLEGAL LOCAL UUO
;QNR	QUASAR NOT RESTARTABLE
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$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$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$CRAC:: BLOCK	24		;CRASH INFORMATION BLOCK

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$ITEM:: BLOCK	NITEMS		;COUNTER ITEMS

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


;LOCAL STORAGE

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

PDL::	BLOCK	50		;PUSHDOWN LIST
SUBTTL	Initialization

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

QUASAR:	MOVE	P,[IOWD	50,PDL]	;GET A PUSHDOWN LIST
	AOSE	STFLAG		;MAKE SURE WE AREN'T RESTARTED
	  STOPCD(QNR,FATAL)	;++QUASAR NOT RESTARTABLE
	ZERO	STGBPT		;CLEAR A FEW INTERNAL WORDS FIRST
	MOVE	S1,[G$BEG,,G$BEG+1]
	SETZM	G$BEG		;THIS IS ESSENTIALLY G$INIT, TO
	BLT	S1,G$END	; CLEAR OUT ALL GLOBAL VARIABLES
	PUSHJ	P,I$INIT##	;INITIALIZE THE SYSTEM INTERFACE
	PUSHJ	P,M$INIT##	;THE MEMORY MANAGER
	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
	PUSHJ	P,C$INIT##	;GET A PID
SUBTTL	Main Processing Loop

MAIN:	PUSHJ	P,I$NOW##		;GET "NOW"
	PUSHJ	P,C$GET##		;GET A MESSAGE
	JUMPN	AP,MAIN.1		;JUMP IF WE'VE GOT SOMETHING
	PUSHJ	P,I$SLP##		;AND SLEEP SOME
	SKIPE	HDRIPS##+.QHLNK		;ANY MESSAGES THAT DIDN'T MAKE IT
	  PUSHJ	P,C$RSND##		;YES, TRY RESENDING OLD MESSAGES
	PUSHJ	P,C$GET##		;GET A MESSAGE
	JUMPN	AP,MAIN.1		;GOT ONE!!
	PUSHJ	P,M$GCOL##		; "AN OUNCE OF PREVENTION..."
	JRST	MAIN.3			;NOW CHECK THE AFTER QUEUE

MAIN.1:	MOVEM	AP,G$ENT		;SAVE ADDRESS OF THE ENTRY
	ZERO	G$ERR			;CLEAR PREVIOUS ERROR INDICATOR
	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
	LOAD	M,IPCMES(AP),IPM.AD	;GET ADDRESS OF THE MESSAGE
	MOVE	T1,IPCFLG(AP)		;GET THE FLAG WORD
	MOVE	T3,G$MPS		;IPCF SHORT MESSAGE SIZE
	TXNN	T1,IP.CFV		;A PAGE MODE MESSAGE ?
	  JRST	MAIN.2			;NO, M AND T3 ARE STRAIGHT
	PG2ADR	M			;POINT TO THE MESSAGE
	MOVEI	T3,1000			;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,IPCRCR(AP)		;GET PID MESSAGE WAS SENT TO
	CAMN	S1,G$QPID		;TO [SYSTEM]QUASAR
	  JRST	QSRMSG			;YES, DISPATCH IT
RELMSG:	MOVE	AP,G$ENT		;GET ADDRESS OF IPC ENTRY
	PUSHJ	P,C$PUT##		;RETURN IT TO THE FREE SPACE
MAIN.3:	PUSHJ	P,Q$CKAF##		;CHECK THE AFTER QUEUE
	PUSHJ	P,S$SCHD##		;DO ANY SCHEDULING
	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

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
	PUSHJ	P,0(S1)			;CALL THE HANDLER
	JRST	RELMSG			;AND DISMISS THE MESSAGE

;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,.MSTYP(M),MS.ACK	;GET "ACK" CODE
	MOVEM	T4,G$ACK		;REMEMBER IF USER WANTS ONE
	ZERO	.MSTYP(M),MS.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"
	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	G$ERR			;DID AN ERROR OCCUR
	 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,,Q$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 TEXT (SENT BY QUASAR)
	     0,,E$IMT		;FUNCTION 15 REQUEST FOR CHECKPOINT (SENT BY QUASAR)
	     0,,Q$DEFER##	;FUNCTION 16 DEFER
	     0,,A$ROUTE##	;FUNCTION 17 ROUTING INFORMATION
	     0,,A$COUNT##	;FUNCTION 20 COUNT
	     0,,E$IMT		;FUNCTION 21 COUNTANSWER (SENT BY QUASAR)

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

	     0,,E$MTL		;HIGHEST + 1 = MESSAGE TOO LONG
SUBTTL	Tables for Error Codes Reported

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

ERRTBL:	ERRCDS				;EXPAND THE DISPATCH TABLE

DEFINE	X(SUFFIX,TEXT),<
	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),<
	TX.FAT!INSVL.(<SIXBIT\   SUFFIX\>,TX.SUF)
>  ;END OF DEFINE X

STSTBL:	TX.NMS				;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,(P)			;SAVE T1, GET ERROR DISPATCH
	SUBI	T1,ERRTBL		;CONVERT TO ERROR INDEX
	HRRZM	T1,G$ERR		;SET GLOBAL ERROR INDICATOR
	PJRST	.T1PJ##			;RESTORE T1 AND RETURN
SUBTTL	String Utilities for TEXT Message

;SUBROUTINE TO COPY AN ASCIZ STRING INTO THE CURRENT TEXT MESSAGE
;CALL WITH S1 AS THE ADDRESS OF THE STRING TO BE INCLUDED
;DESTROYS S1 AND S2

	INTERN	G$CSTG

G$CSTG:	HRLI	S1,(POINT 7,0)		;MAKE A BYTE POINTER
CSTG.1:	ILDB	S2,S1			;GET A CHARACTER
	PJUMPE	S2,.POPJ##		;STOP AT THE NULL
	PUSHJ	P,STGSTC		;STUFF IT AWAY
	JRST	CSTG.1			;GET THEM ALL

;SUBROUTINE TO INSERT A SIXBIT VALUE INTO THE CURRENT TEXT MESSAGE
;CALL WITH S1 CONTAINING THE SIXBIT QUANTITY
;DESTROYS S1 AND S2

	INTERN	G$CSIX

G$CSIX:	PUSHJ	P,.SAVE1##		;SAVE P1 FIRST
	MOVE	P1,[POINT 6,S1]		;AND GET A SIXBIT BYTE POINTER
CSIX.1:	ILDB	S2,P1			;GET A CHARACTER
	PJUMPE	S2,.POPJ##		;ALL DONE AT A BLANK
	ADDI	S2," "			;TO ASCII
	PUSHJ	P,STGSTC		;STICK A CHARACTER
	TLNE	P1,770000		;GET ALL SIX YET
	  JRST	CSIX.1			;NO, GET ANOTHER
	POPJ	P,			;RETURN

;SUBROUTINE TO INSERT A SINGLE ASCII CHARACTER INTO THE CURRENT TEXT MESSAGE
;CALL WITH S1 CONTAINING THE CHARACTER RIGHT JUSTIFIED
;DESTROYS S1 AND S2

	INTERN	G$CCHR

G$CCHR:	MOVE	S2,S1			;MOVE FOR STGSTC
	PJRST	STGSTC			;EXIT TRHOUGH THE CHARACTER STICKER
;SUBROUTINE TO INSERT A DECIMAL NUMBER INTO THE CURRENT TEXT MESSAGE
;CALL WITH S1 CONTAINING THE BINARY NUMBER
;DESTROYS S1 AND S2

	INTERN	G$CDEC

G$CDEC:	IDIVI	S1,^D10			;A STANDARD DECIMAL ROUTINE
	HRLM	S2,(P)			;SAVE ROOM ON THE STACK
	SKIPE	S1			;DONE YET
	  PUSHJ	P,G$CDEC		;NO, RECURSE A LITTLE
	HLRZ	S2,(P)			;RETRIEVE A DIGIT
	ADDI	S2,"0"			;CONVERT TO ASCII

;FALL INTO CHARACTER STICKER

STGSTC:	SKIPE	STGBPT			;STRING STARTED YET
	  JRST	STGS.1			;YES, JUST INSERT ONE
	PUSH	P,S2			;SAVE THE CHARACTER
	MOVE	S2,[POINT 7,ACKMSG+TEX.MS]  ;INIT THE BYTE POINTER
	MOVEM	S2,STGBPT		;TUCK IT AWAY
	POP	P,S2			;RESTORE THE CHARACTER
STGS.1:	IDPB	S2,STGBPT		;INCLUDE THIS CHARACTER
	POPJ	P,			;RETURN FOR THE NEXT

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)
	MOVE	S1,TXTTBL(P1)		;THE ASSOCIATED MESSAGE
	PUSHJ	P,G$CSTG		;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 TEX.ST
;DESTROYS S1 AND S2

	INTERN	G$MSND

G$MSND:	PUSHJ	P,.SAVE1##		;SAVE A REG
	SAVE	AP			;SAVE ANOTHER
	TXNN	S1,TX.MOR		;GOING TO GENERATE ANOTHER AFTER THIS
	  ZERO	G$ACK			;NO, CLEAR ACK REQUEST
	MOVEM	S1,ACKMSG+TEX.ST	;STORE REQUESTED STATUS INFORMATION
	ZERO	S2			;GET A NULL BYTE
	PUSHJ	P,STGSTC		;STUFF IT TO END THE MESSAGE
	HRRZ	P1,STGBPT		;NOW COMPUTE THE LENGTH
	ZERO	STGBPT			;BUT FIRST, INDICATE NO MESSAGE
	SUBI	P1,ACKMSG-1		;P1 = THE MESSAGE LENGTH
	STORE	P1,ACKMSG+.MSTYP,MS.CNT  ;STORE IN THE MESSAGE HEADER
	HRLM	P1,MSND.A+.IPCFP	;AND AS PACKET LENGTH
	MOVX	S2,.QOTEX		;MESSAGE TYPE
	STORE	S2,ACKMSG+.MSTYP,MS.TYP  ;STORE THE 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	P1,G$MPS		;SHOULD THIS REALLY BE PAGED
	  JRST	MSND.1			;NO, ALL READY TO SEND
	PUSHJ	P,M$ACQP##		;YES, GET A PAGE
	HRRM	AP,MSND.A+.IPCFP	;STORE THE PAGE NUMBER
	MOVEI	S1,1000			;LENGTH OF A PAGE
	HRLM	S1,MSND.A+.IPCFP	;AND STORE THAT
	MOVX	S1,IP.CFV		;GET BIT INDICATING PAGED
	MOVEM	S1,MSND.A+.IPCFL	;STORE THE FLAG
	HRLI	S1,ACKMSG		;ADDRESS OF ORIGINAL MESSAGE
	PG2ADR	AP			;CONVERT TO AN ADDRESS
	HRRI	S1,(AP)			;S1 NOW READY FOR THE BLT
	ADDI	P1,-1(AP)		;P1 = LAST LOC TO COPY
	BLT	S1,(P1)			;MOVE DATA TO THE PAGE
MSND.1:	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	20			;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	LUUO  --  Local UUO Handler for QUASAR

;THIS ROUTINE GETS CALLED WHENEVER A LOCAL UUO IS EXECUTED.
;	ITS RESPONSIBILITY IS TO SAVE ALL ACCUMULATORS, DISPATCH THE
;	UUO, AND THEN RESTORE THE ACCUMULATORS.

;ROUTINES CALLED WITH:	S1 = THE AC FIELD OF THE UUO
;			S2 = THE E  FIELD OF THE UUO

LUUO:	MOVEM	0,G$CRAC+0		;SAVE ALL REGISTERS
	MOVE	0,[1,,G$CRAC+1]		;IN THE CRASH BLOCK
	BLT	0,G$CRAC+17		;GET THEM ALL
	LDB	S1,[POINT 4,40,12]	;GET THE ACCUMULATOR FIELD
	HRRZ	S2,40			;AND THE EFFECTIVE ADDRESS
	HLRZ	T1,40			;NOW FIND THE OPCODE
	ANDI	T1,777000		;ONLY THE OPCODE
	CAIN	T1,(.STCD.)		;STOPCD UUO
	  HRROI	T1,I$STCD##		;GET, POINT TO HANDLER
	TLNN	T1,-1			;FIND A KNOWN UUO
	  STOPCD(ILU,FATAL)		;++ILLEGAL LOCAL UUO
	PUSHJ	P,0(T1)			;DISPATCH THE UUO
	MOVSI	17,G$CRAC		;FOR RESTORE
	BLT	17,17			;GET ALL THE REGS BACK
	POPJ	P,			;CALLED BY PUSHJ IN 41
	END	QUASAR