Trailing-Edge
-
PDP-10 Archives
-
bb-jr93d-bb
-
7,6/ap016/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