Google
 

Trailing-Edge - PDP-10 Archives - tops10_703a_sys_atpch16_bb-fr67f-bb - qsripc.x16
There are 2 other files named qsripc.x16 in the archive. Click here to see a list.
	TITLE	QSRIPC  --  IPC Handler for QUASAR

;
;
;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(QSRIPC)	;GENERATE THE NECESSARY SYMBOLS

	%%.QSR==:%%.QSR
	QSRVRS==:QSRVRS
	SUBTTL	C$INIT - IPCF MODULE INITIALIZATION

	INTERN	C$INIT			;MAKE IT GLOBAL

C$INIT:	$RETT				;RESERVE THE RIGHT TO ADD AN INIT
					; ROUTINE SOMETIME IN THE FUTURE
	SUBTTL	C$INT - IPCF INTERRUPT PROCESSOR

	INTERN	C$INT			;MAKE IT GLOBAL

C$INT:	$BGINT(INT.PL)			;ASSUME INTERRUPT CONTEXT
	$COUNT	(IPCI)			;COUNT IPCF INTERRUPTS
	PUSHJ	P,C%INTR		;CALL SUPPORT INTERRUPT ROUTINE
	$DEBRK				;AND DISMISS THE INTERRUPT
	SUBTTL	C$SEND - ROUTINE TO SEND AN IPCF MESSAGE

	;CALL:	G$SAB containing the SAB 
	;
	;RET:	True if send wins, False otherwise

	INTERN	C$SEND			;MAKE IT GLOBAL
	INTERN	C$SNDA			; DITTO

C$SEND:	SETZM	G$SAB##+SAB.PB		;CLEAR AUX PIB
C$SNDA:	$SAVE	<AP,E,H,P1>		;SAVE CALLER'S REGISTERS
	MOVEI	P1,G$SAB##		;POINT TO THE SAB
	PUSHJ	P,FIND			;SEE IF RECEIVER IS IN RESEND QUEUE
	JUMPT	SEND.1			;YES, JUST ADD THIS ENTRY TO THE QUEUE

	;Here to send the IPCF Message

	MOVX	S1,SAB.SZ		;GET THE SAB LENGTH
	MOVEI	S2,G$SAB##		;AND THE SAB ADDRESS
	PUSHJ	P,C%SEND		;SEND THE MESSAGE OFF
	JUMPT	[$COUNT (SIPC)		;WIN,,COUNT'EM UP
		 MOVX	TF,SF.ECD	;MASK OF ERROR BITS
		 ANDCAM	TF,G$SAB##+SAB.FL ;CLEAR THEM
		 $RETT  ]		;AND RETURN

	;Here if the SEND failed

	$COUNT	(IPCF)			;COUNT FAILURES...
	CAXE	S1,ERNSP$		;IS THE ERROR 'NO SUCH PID' ???
	CAXN	S1,ERPWA$		;OR 'PID WENT AWAY' ???
	JRST	SEND.2			;YES,,GIVE UP

	;Here when receiver was found in IPC queue to insert without sending

SEND.1:	PUSHJ	P,COPY			;COPY SAB TO A NEW IPC CELL
        MOVX	TF,SF.ECD		;MASK OF ERROR BITS
	ANDCAM	TF,G$SAB##+SAB.FL	;CLEAR THEM
	PJRST	M$LINK##		;AND GO LINK INTO QUEUE

	;Here when send fails absolutely

SEND.2:	$COUNT	(IPCU)			;NOT RECOVERABLE...
        MOVX	TF,SF.ECD		;MASK OF ERROR BITS
	ANDCAM	TF,G$SAB##+SAB.FL	;CLEAR THEM
	MOVE	S1,G$SAB##+SAB.PD	;GET RECIEVERS PID
	PUSHJ	P,G$SFAL##		;TELL WORLD USER WENT AWAY...
	MOVE	S2,G$SAB##+SAB.LN	;GET THE MESSAGE LENGTH
	CAXE	S2,PAGSIZ		;SENDING A PAGE ???
	$RETF				;NO,,JUST RETURN
	MOVE	S1,G$SAB##+SAB.MS	;YES,,GET THE PAGE ADDRESS
	PUSHJ	P,M%RPAG		;RETURN THE PAGE
	$RETF				;AND RETURN
	SUBTTL	C$LINK - ROUTINE TO INSERT A SAB INTO THE RESEND QUEUE

;CALL:	AP/ IPC CELL TO LINK

	INTERN	C$LINK			;MAKE IT GLOBAL

C$LINK:	$SAVE	<H,E,P1>		;PRESERVE CALLER'S REGISTERS
	MOVEI	P1,RS.SAB(AP)		;POINT TO THE SAB
	PUSHJ	P,FIND			;LOCATE THIS PID IF PRESENT (POSITION)
	PJRST	M$LINK##		;PUT IN IPC QUEUE AND RETURN
	SUBTTL	FIND - ROUTINE TO LOCATE INTENDED RECEIVER IN RESEND QUEUE

;CALL WITH SAB ADDRESS IN P1
;RETURN	TRUE IF FOUND, RESEND QUEUE POINTING AT FIRST ENTRY NOT FOR PID
;RETURN FALSE IF NOT FOUND, RESEND QUEUE POINTER AT END
;CLOBBERS E & H

FIND:	SKIPE	S1,SAB.PD(P1)		;GET THE RECIEVERS PID
	SETZM	SAB.SI(P1)		;CLEAR SPECIAL INDEX IF PID PRESENT
	MOVE	S2,SAB.SI(P1)		;GET SPECIAL INDEX
	MOVEI	H,HDRIPC##		;POINT TO IPC (RESEND) QUEUE HEADER
	LOAD	E,.QHLNK(H),QH.PTF	;LOAD POINTER TO FIRST ENTRY

FIND.1:	JUMPE	E,.RETF			;NOT THERE, RETURN FALSE
	CAMN	S1,RS.SAB+SAB.PD(E)	;IS HE IN THE RESEND QUEUE ???
	CAME	S2,RS.SAB+SAB.SI(E)
	JRST	FIND.3			;NO, TRY NEXT ENTRY

FIND.2:	LOAD	E,.QELNK(E),QE.PTN	;ADVANCE ENTRY POINTER
	JUMPE	E,.RETT			;NO LONGER FOR THIS PID IF END
	CAMN	S1,RS.SAB+SAB.PD(E)	;IS THIS STILL A MATCH?
	CAME	S2,RS.SAB+SAB.SI(E)	; ?
	$RETT				;NO,,RETURN POINTER PAST THIS PID
	JRST	FIND.2			;YES,,KEEP LOOKING FOR A NON-MATCH

FIND.3:	LOAD	E,.QELNK(E),QE.PTN	;ADVANCE QUEUE ENTRY POINTER
	JRST	FIND.1			;AND TRY NEXT ENTRY
	SUBTTL	C$RSND - ROUTINE TO PERFORM IPCF RESEND 

	INTERN	C$RSND			;MAKE IT GLOBAL

C$RSND:	$SAVE	<AP,H,E>		;SAVE QUEUE ACS
	$SAVE	<P1,P2>			;ALSO SOME SCRATCH ACS
	MOVEI	H,HDRIPC##		;POINT TO OUR QUEUE
	LOAD	E,.QHLNK(H),QH.PTF	;POINT TO FIRST ENTRY

RSND.1:	JUMPE	E,.RETT			;NO MORE,,RETURN

RSND.2:	MOVE	AP,E			;SAVE ENTRY ADDRESS IN CASE WE ZAP IT
	AOS	S1,RS.CNT(E)		;BUMP AND LOAD THE RESEND COUNT
	CAILE	S1,^D10			;ONLY TRY RESEND 10 TIMES...
	JRST	RSND.6			;TOO MANY,,GO DELETE THIS ENTRY
	MOVEI	S1,SAB.SZ		;GET THE SAB LENGTH
	MOVEI	S2,RS.SAB(E)		;AND THE SAB ADDRESS
	PUSHJ	P,C%SEND		;RESEND THE MESSAGE
	JUMPT	[$COUNT (SIPC)		;COUNT WINNERS...
		 JRST RSND.7 ]		;AND GO DELETE THE CURRENT ENTRY
	$COUNT	(IPCF)			;COUNT FAILURES...
	CAXE	S1,ERNSP$		;DID WE FAIL FOR NO SUCH PID ???
	CAXN	S1,ERPWA$		;OR FOR PID WENT AWAY ???
	JRST	RSND.4			;YES,,TELL WORLD IT WENT AWAY
	MOVE	S1,RS.SAB+SAB.PD(E)	;GET RECIEVER'S PID
	MOVE	S2,RS.SAB+SAB.SI(E)	;AND RECEIVER'S SYSTEM INDEX

	;Here to skip all messages for the same reciever. PID and SI in S1 & S2.

RSND.3:	LOAD	E,.QELNK(E),QE.PTN	;POINT TO NEXT ENTRY
	JUMPE	E,.RETT			;NO MORE,,RETURN
	CAMN	S1,RS.SAB+SAB.PD(E)	;DO THE PIDS MATCH ???
	CAME	S2,RS.SAB+SAB.SI(E)	; ?
	JRST	RSND.2			;NO,,GO PROCESS THIS MESSAGE
	JRST	RSND.3			;YES,,SKIP THIS MSG AND TRY NEXT

RSND.4:	$COUNT (IPCU)			;YES,,COUNT UNRECOVERABLE ERRORS
	MOVE	S1,RS.SAB+SAB.PD(E)	;GET RECIEVER'S PID
	PUSHJ	P,G$SFAL##		;TELL WORLD USER WENT AWAY...
	MOVE	P1,RS.SAB+SAB.PD(E)	;GET PID THAT DIED
	MOVE	P2,RS.SAB+SAB.SI(E)	;AND SYSTEM INDEX
RSND.5:	LOAD	E,.QELNK(E),QE.PTN	;GET NEXT (CURRENT STILL IN AP)
	PUSHJ	P,C$PUT			;RETURN CELL TO FREE SPACE
	SKIPN	AP,E			;SET TO EXAMINE NEXT POINTER
	$RETT				;DONE IF NO MORE
	CAMN	P1,RS.SAB+SAB.PD(E)	;IF PIDS MATCH
	CAME	P2,RS.SAB+SAB.SI(E)	; (?)
	JRST	RSND.2			;NO,,TRY TO RESEND THE NEXT
	JRST	RSND.5			;YES,,DELETE NEXT ONE AS WELL

RSND.6:	$COUNT (IPCE)			;COUNT IPC QUEUE EXPIRATIONS
	LOAD	E,.QELNK(E),QE.PTN	;PICK UP NEXT POINTER (CURRENT IN AP)
	PUSHJ	P,C$PUT			;RETURN CELL TO FREE SPACE
	JRST	RSND.1			;RETRY NEXT

RSND.7:	LOAD	E,.QELNK(E),QE.PTN	;GET NEXT POINTER (CURRENT IN AP)
	PUSHJ	P,M$RFRE##		;RETURN CELL (NOT C$PUT, PAGE IS GONE)
	JRST	RSND.1			;GO PROCESS NEXT QUEUE ENTRY
	SUBTTL	C$GET - OBTAIN AN IPC CELL FOR A SAB

;CALL:	P1/ SAB ADDRESS
;RETURN TRUE, AP POINTING TO CELL OBTAINED
;
;COPIES SAB AND PACKET, EVEN IF PAGE-MODE PACKET.

	INTERN	C$GET			;MAKE IT GLOBAL

C$GET:	$SAVE	<H>			;DON'T CLOBBER CALLER'S QUEUE HEADER
	MOVEI	H,HDRIPC##		;TYPE OF CELL TO GET
	PUSHJ	P,COPY			;GRAB A CELL AND COPY SAB
	MOVE	S1,RS.SAB+SAB.LN(AP)	;GET SIZE OF MESSAGE
	CAIE	S1,PAGSIZ		;PAGE MODE?
	$RETT				;NO,,COPY DID ALL OUR WORK FOR US
	$CALL	M%GPAG			;YES,,OBTAIN A FREE PAGE
	MOVS	S2,RS.SAB+SAB.MS(AP)	;GET SOURCE ADDRESS OF PACKET
	HRRI	S2,(S1)			;AND DESTINATION
	MOVEM	S1,RS.SAB+SAB.MS(AP)	;UPDATE PACKET ADDRESS IN SAB
	BLT	S2,PAGSIZ-1(S1)		;COPY THE PACKET
	$RETT				;AND RETURN GOODNESS
	SUBTTL	COPY - COPY A SAB AND NON-PAGED PACKET TO A NEW IPC CELL

;CALL:	P1/ SAB ADDRESS
;RETURN TRUE, AP POINTING TO CELL OBTAINED

COPY:	MOVE	AP,SAB.LN(P1)		;GET SIZE OF MESSAGE TO SEND
	TRZ	AP,PAGSIZ		;USE ZERO IF PAGED MODE
	PUSHJ	P,M$GFRE##		;GET SOME SPACE FOR THE IPC QUEUE
	MOVEI	S1,RS.SAB(AP)		;PLACE TO MOVE SAB
	HRLI	S1,(P1)			;FROM HERE
	BLT	S1,RS.SAB+SAB.SZ-1(AP)	;COPY TO RESEND CELL
	MOVE	S1,SAB.LN(P1)		;GET PACKET SIZE AGAIN
	CAIN	S1,PAGSIZ		;PAGE MODE?
	$RETT				;YES,,DONE
	MOVEI	S2,RS.MSG(AP)		;NO,,GET WHERE PACKET SHOULD GO
	MOVEM	S2,RS.SAB+SAB.MS(AP)	;UPDATE PACKET ADDRESS
	ADDI	S1,(S2)			;FIND END OF TRANSFER
	HRL	S2,SAB.MS(P1)		;AND START
	BLT	S2,-1(S1)		;COPY PACKET TO RESEND CELL
	$RETT				;RETURN GOODNESS
	SUBTTL	C$PUT - RETURN AN UNSENT IPC CELL TO FREE CORE

;CALL:	AP/ THE CELL TO BE RETURNED
;
;THE MAIN DIFFERENCE BETWEEN C$PUT AND M$RFRE IS THAT C$PUT LOADS H ITSELF,
;AND TAKES CARE OF UNSENT PAGE-MODE PACKETS IN THE SAB

	INTERN	C$PUT			;MAKE IT GLOBAL

C$PUT:	$SAVE	<H>			;PRESERVE CALLER'S QUEUE HEAD POINTER
	MOVEI	H,HDRIPC##		;TYPE OF CELL TO RETURN
	MOVE	S1,RS.SAB+SAB.MS(AP)	;GET PACKET ADDRESS
	MOVE	S2,RS.SAB+SAB.LN(AP)	;AND ITS LENGTH
	CAIN	S2,PAGSIZ		;IS IT A PAGE?
	$CALL	M%RPAG			;YES,,RETURN IT
	PJRST	M$RFRE##		;EXIT, RETURNING THE CELL
	END