TITLE	GALAXY interface to GALAXY


	SEARCH	QSRMAC		;GALAXY PARAMETERS
	SEARCH	SBSMAC		;SUB-SYSTEMS GROUP MACROS
	SEARCH	MACTEN		;USEFUL MACROS
	SEARCH	UUOSYM		;TOPS10-UUO SYMBOLS
IFN FTJSYS,<SEARCH MONSYM>	;TOPS20-JSYS SYMBOLS
	SEARCH	QPRM		;MPB PARAMETERS
	SEARCH	IMPPRM		;IMP PARAMETERS



DEFINE	FAIL(MSG)<
	JRST	[MOVEI	1,%A
		MOVEI	2,ERRMSG##
		JSP	J,.$MOVE##
		POP	P,J	;GET ORIG RETURN ADDRESS
		MOVEI	ARG1,^D15	;%SIGNAL 15
		SETZB	ARG2,ARG3
		GOTO	.$SNAL##
%A:	MSG]
>  ;END OF DEFINE FAIL



;	MACRO TO MOVE DATA AROUND  -- WIPES TEMP

DEFINE	DATAM(SWRD,SFIELD,DWRD,DFIELD)<
	LOAD(TEMP,SWRD,SFIELD)
	XLIST
	STORE(TEMP,DWRD,DFIELD)
	LIST
	SALL
>  ;END OF DEFINE DATAM

	TWOSEG
	RELOC	400000
;%EXTERNALROUTINE QUEUEIT(%NAME ARG BLOCK,%STRING(1)%NAME MESSAGE)

QUEUEIT::
	SETMM	110(P)		;STACK CHECK
	PUSHJ	P,SAVEACS##	;SAVE IMP REGISTERS
	MOVEM	ARG2,SARG2#	;SAVE THE STRING NAME ADDRESS
	HRRZ	M,ARG1		;SET UP M
	MOVEI	T1,1000		;NUMBER OF WORDS
	PUSHJ	P,CORGET	;GET A PAGE
	MOVE	T1,.JBFF##	;GET TOP OF CORE
	SOS	T1		;MAKE SURE IN LOWER PAGE
	ANDI	T1,777000	;GET START OF PAGE
	MOVEI	T2,(T1)		;GET ANOTHER COPY
	SETZM	(T1)		;CLEAR IT
	HRLI	T3,(T1)		;SET UP BLT POINTER
	HRRI	T3,1(T1)
	BLT	T3,777(T1)	;ZERO PAGE
	HRL	T1,M		;SET UP BLT POINTER
	BLT	T1,77(T2)	;COPY ARG BLOCK INTO FREE PAGE
	MOVE	M,T2		;SET UP NEW M
	TXO	M,1B0		;MARK AS PAGE MODE
	PUSHJ	P,MSGSND	;SEND THE MESSAGE
	PUSHJ	P,RCVACK	;GET THE ACK
	PJRST	RESTORE##	;RESTORE ACS AND RETURN TO CALLER
CPOPJ:	POPJ	P,


CORGET:	ADDB	T1,.JBFF##		;BUMP HIGHEST, GET SAME
	SUBI	T1,1			;BACK OFF BY ONE
	CAMG	T1,.JBREL##		;ALREADY HAVE ENOUGH
	  POPJ	P,			;YES, CAN SAVE A CORE UUO
	CORE	T1,			;ACQUIRE THE CORE
	  FAIL(IMPSTR<NEC Not enough core>)
	POPJ	P,			;AND RETURN



;ERROR ROUTINES

;ERR CONCATENATES THE STRING POINTED TO BY T1 ONTO THE END OF ERRMSG
ERR:	MOVE 1,T1
	MOVEI	2,ERRMSG##
	JSP	J,.$CONC##	;CONCATENATE ONTO ERRMSG
	POPJ	P,


IFN FTUUOS,<
QUEQRY:	SETZB	T1,T2			;CLEAR QUERY BLOCK
	SETZB	T3,T4			;FOR GOOD MEASURE
	MOVE	S2,[4,,T1]		;LENGTH,,ARGUMENTS
	IPCFQ.	S2,			;FIND OUT WHATS THERE
	  SETZ	T4,			;NOTHING, CLEAR T4
	MOVE	S2,T4			;COPY QUEUE STATUS INTO S2
	JUMPE	S2,CPOPJ		;RETURN IF NOTHING THERE
	CAMN	T2,QSRPID		;FROM QUASAR
	  POPJ	P,			;YES, RETURN NOW
	PUSHJ	P,QUEIGN		;FLUSH THE JUNK MAIL
	JRST	QUEQRY			;LOOK AGAIN

QUEIGN:	ANDX	T1,IP.CFV		;CLEAR ALL BUT PAGE MODE BIT
	TXO	T1,IP.CFT		;SET TO TRUNCATE
	SETZB	T2,T3			;CLEAR THEM AGAIN
	MOVEI	T4,1			;LENGTH = 0 , LOC = 1
	MOVE	S2,[4,,T1]		;SET UP LENGTH AND BLOCK ADDRESS
	IPCFR.	S2,			;THROW AWAY THE MESSAGE
	  FAIL(IMPSTR<CFR Cannot flush the IPCF receive queue>)
	POPJ	P,			;RETURN

QUEWAT:	PUSHJ	P,QUEQRY		;FIND OUT WHATS THERE
	JUMPN	S2,CPOPJ		;SOMETHING, RETURN
	MOVX	S2,<HB.IPC+^D2000>	;FLAGS,,NAP TIME
	HIBER	S2,			;WAIT FOR A REASONABLE TIME
	  JFCL				;WATCH THIS LOOP
	JRST	QUEWAT			;TRY NOW

>  ;END OF IFN FTUUOS
; SUBROUTINE TO RECEIVE AN EXPECTED "ACK" FROM QUASAR
;	IT RETURNS TO THE CALLER AFTER RECEIVING A "GOOD" ONE
;	ISSUES AN ERROR MESSAGE AND QUITS ON A "BADDY"

RCVACK:	MOVEI	M,FBTEMP		;AREA FOR SHORT RECEIVE

IFN FTUUOS,<

	PUSHJ	P,QUEWAT		;WAIT FOR A RETURNED MESSAGE
	ANDX	T1,IP.CFV		;CLEAR ALL BUT THE PAGE MODE BIT
	SETZB	T2,T3			;CLEAR THESE AGAIN
	HRRI	T4,(M)			;WHERE TO RECEIVE INTO
	TXNN	T1,IP.CFV		;IS IT A PAGE
	  JRST	RCVA.1			;NO, GO GET IT
	MOVE	M,.JBREL##		;GET A PAGE TO RECEIVE INTO
	MOVEI	M,777(M)		;ROUND UP
	ADR2PG	M			;CONVERT TO PAGE NUMBER
	HRRI	T4,(M)			;SET THE ADDRESS
	HRLI	T4,1000			;LENGTH OF A PAGE
	PG2ADR	M			;STILL NEED TO POINT TO IT
RCVA.1:	MOVE	S2,[4,,T1]		;READY TO GET IT
	IPCFR.	S2,			;GET THE ACK FROM QUASAR
	  FAIL(IMPSTR<ARF Acknowledgement Receive Failed>)

>  ;END OF IFN FTUUOS

IFN FTJSYS,<

	SETZB	T1,T2			;CLEAR FLAGS, SENDER
	MOVE	T3,MYPID		;RECEIVER
	HRLI	T4,FBAREA		;SIZE OF SHORT MESSAGE
	HRRI	T4,FBTEMP		;TEMPORARY BLOCK
	PUSH	P,S1			;SAVE USER AREA BASE
	MOVEI	S1,4			;FOUR WORDS
	MOVEI	S2,T1			;IN T1-T4
	MRECV				;RECEIVE THE ACK
	  FAIL(IMPSTR<ARF Acknowledgement Receive Failed>)
	POP	P,S1			;RESTORE USER BASE

>  ;END OF IFN FTJSYS

	LOAD	S2,TEX.ST(M)		;GET THE MESSAGE STATUS WORD
	TXNE	S2,TX.NMS		;NORMAL "ACK" (NO MESSAGE ASSOCIATED)
	  JRST	RCVA.3			;YES, SEE IF IT IS TIME TO RETURN


;FALL ONTO THE NEXT PAGE FOR THE OUTPUT OF THE MESSAGE RECEIVED
;HERE TO OUTPUT THE BODY OF THE ACK MESSAGE

RCVA.4:
	SETZM	ERRMSG##		;CLEAR ERROR MESSAGE
	PUSH	P,S2		;SAVE S2
	MOVEI	T1,[IMPSTR<[>]		;CHARACTER FOR INFORMATIONAL MESSAGES
	TXNN	S2,TX.FAT!TX.WRN	;FATAL OR WARNING
	  JRST	RCVA.2			;NEITHER, JUST REPORT THE TEXT
	MOVEI	T1,[IMPSTR<?QSR>]	;FATAL CHARACTER
	TXNN	S2,TX.FAT		;WAS IT FATAL
	  MOVEI	T1,[IMPSTR<%QSR>]	;NO, LOAD WARNING CHARACTER
	PUSHJ	P,ERR			;OUTPUT THE "?" OR "%"
	LOAD	T1,TEX.ST(M),TX.SUF	;GET THE MESSAGE SUFFIX
	HRLZS	T1			;INTO THE OTHER SIDE FOR TTYSIX
	MOVE	ARG1,T1
	ADDI	P,4
	PUSHJ	P,SIXTOS##		;OUTPUT THE FULL ERROR CODE
	MOVEI	T1,-1(P)
	PUSHJ	P,ERR
	SUBI	P,4
	MOVEI	T1,[IMPSTR< >]
RCVA.2:	PUSHJ	P,ERR			;MAKE THE OUTPUT PRETTY
	MOVEI	ARG1,TEX.MS(M)		;AND FINALLY, OUTPUT THE MESSAGE
	ADDI	P,103
	PUSHJ	P,ASCTOS##
	MOVEI	T1,-77(P)
	PUSHJ	P,ERR
	SUBI	P,103
	MOVE	S2,(P)
	TXNN	S2,TX.FAT!TX.WRN	;ANOTHER CHECK
	  JRST	[MOVEI	T1,[IMPSTR<]>]			;GEE..IT TAKES A LOT TO DO NICE WORK
		PUSHJ	P,ERR
		JRST	.+1]
	POP	P,S2
	TXNE	S2,TX.FAT		;AGAIN, WAS IT FATAL
	  JRST	FAIL1
;NO, WELL STORE IT FOR IMP
	PUSH	P,S2
	MOVEI	1,ERRMSG
	MOVE	2,SARG2
	JSP	J,.$MOVE		;MOVE IT TO SECOND ARGUMENT
	POP	P,S2
RCVA.3:	TXNE	S2,TX.MOR		;MORE COMING
	  JRST	RCVACK			;YES, DO THIS ALL OVER AGAIN
	POPJ	P,			;CONTINUE PROCESSING
FAIL1:	POP	P,J	;GET ORIGINAL RETURN ADDRESS
	MOVEI	ARG1,^D15
	SETZB	ARG2,ARG3
	JRST	.$SNAL##
IFN FTUUOS,<

MSGSND:	MOVX	T4,%CNST2		;GET SECOND STATES WORD
	GETTAB	T4,			;TO LOOK FOR GALAXY-10
	  ZERO	T4			;WHAT!!
	TXNN	T4,ST%GAL		;SYSTEM HAVE SUPPORT FOR GALAXY-10
	  FAIL(IMPSTR<NGS No GALAXY-10 Support in this monitor>)
	SETO	T4,			;FLAG INDICATING FIRST TRY
MSGS.1:	MOVX	T3,%SIQSR		;GETTAB FOR PID OF [SYSTEM]QUASAR
	GETTAB	T3,			;SEE IF IT IS RUNNING
	  FAIL(IMPSTR<SGF SYSID. GETTAB failed>)
	MOVEM	T3,QSRPID		;REMEMBER QUASAR'S PID
	SETOM	RTYCNT		;INIT RETRY COUNTER
	JUMPN	T3,MSGGO		;THERE HE IS, SEND THE MESSAGE
	MOVEI	T3,3			;NOT UP YET, TRY A SLEEP
	SLEEP	T3,			;GIVE IT A CHANCE
	AOJN	T4,MSGS.1		;JUMP IF ALREADY GAVE A MESSAGE
	OUTSTR	[ASCIZ/
%QMRWFQ Waiting For [SYSTEM]QUASAR to Start
/]
	JRST	MSGS.1			;TRY NOW
MSGGO:	SETZB	T1,T2			;CLEAR FLAGS,MY PID
	MOVEI	T4,(M)			;MESSAGE ADDRESS, T3 = QSRPID
	LOAD	S2,.MSTYP(M),MS.CNT	;GET THE LENGTH OF THE MESSAGE
	TXNN	M,1B0			;IS THIS A PAGE MODE REQUEST
	  JRST	MSGGO1			;NO, SEND IT
	MOVX	T1,IP.CFV		;INDICATE A PAGE SEND
	LSH	T4,-^D9			;CONVERT 'M' TO A PAGE NUMBER
	MOVEI	S2,1000			;LENGTH MUST BE 1000
MSGGO1:	HRL	T4,S2			;INCLUDE CORRECT SIZE IN HEADER
MSGGO2:	MOVE	S2,[4,,T1]		;ARGUMENT FOR SEND
	IPCFS.	S2,			;SEND THE MESSAGE
	 SKIPA				;FAILED, SEE WHY
	  POPJ	P,			;RETURN TO CALLER
	CAIE	S2,IPCDD%		;QUASAR DISABLED
	 CAIN	S2,IPCRS%		;OR MY QUOTA EXHAUSTED
	  JRST	RETRY			;YES, TRY IT AGAIN
	CAIE	S2,IPCRR%		;QUASAR FULL
	 CAIN	S2,IPCRY%		;OR SYSTEM FULL
	  JRST	RETRY			;YES, TRY IT AGAIN
	FAIL(IMPSTR<SQF Send to [SYSTEM]QUASAR failed>)
RETRY:	MOVEI	S2,2			;WAIT BEFORE TRYING AGAIN
	SLEEP	S2,			;TAKE A QUICK NAP
	AOSE	RTYCNT		;COUNT THE RETRIES
	  JRST	MSGGO2			;TRY NOW
	OUTSTR	[ASCIZ/
%QMRMBR Send has failed, Message Being Re-sent
/]
	JRST	MSGGO2			;NOW RETRY IT

>  ;END OF IFN FTUUOS
IFN FTJSYS,<

MSGSND:	SETO	T4,			;FLAG INDICATING FIRST TRY
	PUSH	P,S1			;SAVE USER BASE
MSGS.1:	MOVEI	S1,3			;NUMBER OF WORDS
	MOVEI	S2,T1			;USE T1-T3
	MOVEI	T1,.MURSP		;READ SYSTEM PID TABLE
	MOVX	T2,.SPQSR		;WANT PID OF SYSTEM QUASAR
	MUTIL				;READ THE TABLE
	  SETZ	T3,			;ASSUME IT CONTAINS AN INVALID PID
	MOVEM	T3,QSRPID		;REMEMBER QUASAR'S PID
	SETOM	RTYCNT		;INIT RETRY COUNTER
	JUMPN	T3,MSGGO		;JUMP IF QUASAR IS RUNNING
	MOVEI	S1,^D3000		;WAIT FOR IT
	DISMS				;TAKE A NAP
	AOJN	T4,MSGS.1		;JUMP IF ALREADY GAVE A MESSAGE
	OUTSTR	[ASCIZ/
%QMRWFQ Waiting For [SYSTEM]QUASAR to Start
/]
	JRST	MSGS.1			;TRY NOW
MSGGO:	SETZ	T1,			;ASSUME NO FLAGS
	SKIPN	T2,MYPID		;DO I HAVE A PID
	  TXO	T1,IP%CPD		;NO, CREATE ONE ON THIS SEND
	MOVEI	T4,(M)			;POINT TO THE MESSAGE
	LOAD	S2,.MSTYP(M),MS.CNT	;GET THE LENGTH OF THE MESSAGE
	TXNN	M,1B0			;IS THIS PAGED
	  JRST	MSGGO1			;NO, SEND IT
	TXO	T1,IP.CFV		;SET PAGE MODE FLAG
	LSH	T4,-^D9			;CONVERT ADDR TO A PAGE NUMBER
	MOVEI	S2,1000			;LENGTH OF A PAGE
MSGGO1:	HRL	T4,S2			;INCLUDE THE LENGTH
	MOVEI	S1,4			;FOUR WORDS
	MOVEI	S2,T1			;IN T1-T4
	MSEND				;SEND THE PACKET
	  JRST	MSGGO2			;FAILED, SEE WHY
	SKIPN	MYPID		;DO I ALREADY HAVE THE PID
	  MOVEM	T2,MYPID		;NO, SAVE IT
	POP	P,S1			;RESTORE S1
	POPJ	P,			;AND RETURN TO CALLER


;MORE OF THE TOPS20 VERSION ON THE NEXT PAGE
MSGGO2:	CAIE	S1,IPCFX6		;CHECK FOR EXHAUSTED QUOTAS
	 CAIN	S1,IPCFX7		;AND RETRY IF POSSIBLE
	  JRST	RETRY			;IS POSSIBLE
	CAIE	S1,IPCFX8		;ANOTHER RECOVERABLE ERROR
	 CAIN	S1,IPCFX5		;QUASAR DISABLED
	  JRST	RETRY			;YES, TRY AGAIN
	FAIL(IMPSTR<SQF Send to [SYSTEM]QUASAR failed>)
RETRY:	SKIPN	MYPID		;DO I HAVE A PID
	  MOVEM	T2,MYPID		;NO, MAYBE THIS IS IT
	MOVEI	S1,^D2000		;WAIT BEFORE TRYING AGAIN
	DISMS				;WAIT
	AOSE	RTYCNT		;COUNT THE RETRIES
	  JRST	MSGGO			;TRY NOW
	OUTSTR	[ASCIZ/
%QMRMBR Send has failed, Message Being Re-sent
/]
	JRST	MSGGO			;AND TRY THE SEND AGAIN

>  ;END OF IFN FTJSYS
SUBTTL	Data Storage

	XLIST	;FORCED OUT LITERAL POOL
	LIT
	LIST
	SALL

FBSIZE==FPXSIZ+FDXSIZ		;THE LARGEST FD/FP WE CAN BUILD
	MAX	<FBSIZE,KIL.SZ,LIS.SZ,DFR.SZ>
FBAREA==MAXSIZ			;THE LARGEST FILE BLOCK/MESSAGE NEEDED

	RELOC	0

MYPID:	 BLOCK	1		;MY PID (NECESSARY FOR SEND/RECEIVE)
QSRPID: BLOCK	1		;PID OF SYSTEM QUASAR
RTYCNT: BLOCK	1		;RETRY COUNTER WHEN SEND TO QUASAR FAILS
FBTEMP: BLOCK	FBAREA		;LARGEST FILE BLOCK THAT CAN BE BUILT FROM MPB DATA
				;ALSO USED TO SEND/RECEIVE "SHORT" MESSAGES



	END			;END, NO STARTING ADDRESS
