Google
 

Trailing-Edge - PDP-10 Archives - bb-v895a-bm_tops20_v41_2020_dist_2of2 - language-sources/qsripc.mac
There are 28 other files named qsripc.mac in the archive. Click here to see a list.
	TITLE	QSRIPC  --  IPC Handler for QUASAR

;
;
;        COPYRIGHT (c) 1975,1976,1977,1978,1979,1980,1981,1982
;                    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(QSRIPC)	;GENERATE THE NECESSARY SYMBOLS


SNDQUE:	BLOCK	1		;RESEND IPCF QUEUE LINK LIST ID


	;RESEND QUEUE STRUCTURE

	PHASE	0

RS.CNT:! BLOCK	1		;RESEND COUNT
RS.SAB:! BLOCK	SAB.SZ		;SENDERS SAB
RS.MSG:!			;THE MESSAGE
RS.LEN:!			;MINIUM RESEND QUEUE ENTRY LENGTH

	DEPHASE
	SUBTTL	C$INIT - ROUTINE TO INITIALIZE THE IPCF INTERFACE

	INTERN	C$INIT		;MAKE IT GLOBAL

C$INIT:	PUSHJ	P,L%CLST	;CREATE A LINK LIST FOR RESEND QUEUE
	MOVEM	S1,SNDQUE	;SAVE THE ID
	$RETT			;AND RETURN
	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

C$SEND:	PUSHJ	P,.SAVE2		;SAVE P1 & P2 FOR A MINUTE

	;Here to scan the RESEND queue to see if the reciever is in there

	SKIPE	P1,G$SAB##+SAB.PD	;GET THE RECIEVERS PID
	SETZM	G$SAB##+SAB.SI		;CLEAR SPECIAL INDEX IF PID PRESENT
	MOVE	P2,G$SAB##+SAB.SI	;GET SPECIAL INDEX
	SETZM	G$SAB##+SAB.PB		;CLEAR AUX PIB
	MOVE	S1,SNDQUE		;GET THE RESEND QUEUE ID
	PUSHJ	P,L%FIRST		;GET THE FIRST ENTRY
	JRST	SEND.1			;JUMP THE FIRST TIME THROUGH

SEND.0:	MOVE	S1,SNDQUE		;GET THE RESEND QUEUE ID
	PUSHJ	P,L%NEXT		;GET THE NEXT QUEUE ENTRY
SEND.1:	JUMPF	SEND.2			;NO MORE,,SEND THE MESSAGE
	CAMN	P1,RS.SAB+SAB.PD(S2)	;IS HE IN THE RESEND QUEUE ???
	CAME	P2,RS.SAB+SAB.SI(S2)
	JRST	SEND.0			;NO,,TRY NEXT ENTRY
	JRST	SEND.3			;YES,,QUEUE THIS MESSAGE UP


	;Here to send the IPCF Message

SEND.2:	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
		 $RETT  ]		;AND RETURN

	;Here if the SEND failed

	$COUNT	(IPCF)			;COUNT FAILURES...
	CAXE	S1,ERNSP$		;IS THE ERROR 'NO SUCH PID' ???
	JRST	SEND.3			;NO,,QUEUE THE MSG FOR A RETRY LATER
	$COUNT	(IPCU)			;NOT RECOVERABLE...
	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
	;Here to queue the message up for a later resend attempt

SEND.3:	MOVE	P1,G$SAB##+SAB.PD	;GET THE RECIEVERS PID
	MOVE	P2,G$SAB##+SAB.SI	; AND THE SPECIAL INDEX

	;Here to position to the last entry for the reciever in the resend queue

SEND.4:	MOVE	S1,SNDQUE		;GET THE RESEND QUEUE ID
	PUSHJ	P,L%NEXT		;GET THE NEXT ENTRY IN THE QUEUE
	JUMPF	SEND.5			;NO MORE...
	CAMN	P1,RS.SAB+SAB.PD(S2)	;DO PID MATCH ???
	CAME	P2,RS.SAB+SAB.SI(S2)
	JRST	SEND.5			;AT THE END...
	JRST	SEND.4			;PIDS MATCH,,TRY NEXT QUEUE ENTRY

	;Here to create an entry in the resend queue

SEND.5:	MOVE	S2,G$SAB##+SAB.LN	;GET THE MESSAGE LENGTH
	CAXN	S2,PAGSIZ		;SENDING A PAGE ???
	SETZM	S2			;YES,,ZAP MESSAGE LENGTH
	ADDI	S2,RS.LEN		;ADD IN THE RESEND QUEUE LENGTH
	MOVE	S1,SNDQUE		;GET THE RESEND QUEUE ID
	PUSHJ	P,L%CENT		;CREATE AN ENTRY IN THE QUEUE
	SKIPT
	$STOP(CCE,Can't create list entry)
	MOVE	P1,S2			;SAVE THE ENTRY ADDRESS
	MOVEI	S1,RS.SAB(P1)		;POINT TO THE DESTINATION SAB
	HRLI	S1,G$SAB##		;GET THE SOURCE SAB ADDRESS
	BLT	S1,RS.SAB+SAB.SZ-1(P1)	;SAVE THE SENDERS SAB
	MOVE	S2,G$SAB##+SAB.LN	;GET THE MESSAGE LENGTH
	CAXN	S2,PAGSIZ		;WAS IT A PAGE MODE SEND ???
	$RETT				;YES,,RETURN NOW
	ADDI	S2,RS.MSG-1(P1)		;GET THE BLT END ADDRESS
	HRL	S1,G$SAB##+SAB.MS	;GET THE SOURCE MESSAGE ADDRESS
	HRRI	S1,RS.MSG(P1)		;GET THE DESTINATION MESSAGE ADDRESS
	BLT	S1,0(S2)		;SAVE THE MESSAGE
	MOVEI	S1,RS.MSG(P1)		;GET THE NEW MESSAGE ADDRESS
	MOVEM	S1,RS.SAB+SAB.MS(P1)	;AND SET IT FOR THE RESEND
	$RETT				;RETURN
	SUBTTL	C$RSND - ROUTINE TO PERFORM IPCF RESEND 

	INTERN	C$RSND			;MAKE IT GLOBAL

C$RSND:	PUSHJ	P,.SAVE1		;SAVE P1 FOR A MINUTE
	MOVE	S1,SNDQUE		;GET THE RESEND QUEUE ID
	PUSHJ	P,L%FIRST		;GET THE FIRST ENTRY
	JRST	RSND.2			;JUMP THE FIRST TIME THROUGH

RSND.1:	MOVE	S1,SNDQUE		;GET THE RESEND QUEUE ID
	PUSHJ	P,L%NEXT		;GET THE NEXT QUEUE ENTRY
RSND.2:	JUMPF	.RETT			;NO MORE,,RETURN
RSND.3:	MOVE	P1,S2			;SAVE THE ENTRY ADDRESS
	AOS	S1,RS.CNT(P1)		;BUMP AND LOAD THE RESEND COUNT
	CAILE	S1,^D10			;ONLY TRY RESEND 10 TIMES...
	JRST	RSND.5			;TOO MANY,,GO DELETE THIS ENTRY
	MOVEI	S1,SAB.SZ		;GET THE SAB LENGTH
	MOVEI	S2,RS.SAB(P1)		;AND THE SAB ADDRESS
	PUSHJ	P,C%SEND		;RESEND THE MESSAGE
	JUMPT	[$COUNT (SIPC)		;COUNT WINNERS...
		 JRST RSND.6 ]		;AND GO DELETE THE CURRENT ENTRY
	$COUNT	(IPCF)			;COUNT FAILURES...
	CAXN	S1,ERNSP$		;DID WE FAIL FOR NO SUCH PID ???
	JRST	[$COUNT (IPCU)		;COUNT UNRECOVERABLE ERRORS
		 MOVE	S1,G$SAB##+SAB.PD ;GET RECIEVERS PID
		 PUSHJ	P,G$SFAL##	;TELL WORLD USER WENT AWAY...
		 JRST	RSND.5 ]	;AND GO DELETE THE CURRENT ENTRY

	;Here to skip all messages for the same reciever

	MOVE	P1,RS.SAB+SAB.PD(P1)	;NO,,GET THE RECIEVERS PID
RSND.4:	MOVE	S1,SNDQUE		;GET THE RESEND QUEUE ID
	PUSHJ	P,L%NEXT		;GET THE NEXT QUEUE ENTRY
	JUMPF	.RETT			;NO MORE,,RETURN
	CAMN	P1,RS.SAB+SAB.PD(S2)	;DO THE PIDS MATCH ???
	JRST	RSND.4			;YES,,SKIP THIS MSG AND TRY NEXT
	JRST	RSND.3			;NO,,GO PROCESS THIS MESSAGE

RSND.5:	MOVE	S2,RS.SAB+SAB.LN(P1)	;GET THE MESSAGE LENGTH
	MOVE	S1,RS.SAB+SAB.MS(P1)	;GET THE MESSAGE ADDRESS
	CAXN	S2,PAGSIZ		;IS IT A PAGE MODE SEND ???
	PUSHJ	P,M%RPAG		;YES,,RETURN PAGE TO THE MEMORY MANAGER
RSND.6:	MOVE	S1,SNDQUE		;GET THE RESEND QUEUE ID
	PUSHJ	P,L%DENT		;DELETE THE CURRENT QUEUE ENTRY
	JRST	RSND.1			;GO PROCESS NEXT QUEUE ENTRY
	END