Trailing-Edge
-
PDP-10 Archives
-
bb-d868c-bm_tops20_v4_2020_distr
-
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
; 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
MSGSIZ: BLOCK 1 ;RECIEVED MESSAGE LENGTH
SUBTTL Global Entry Points in QSRIPC
INTERN C$GET ;Get next message from the IPC queue
INTERN C$PUT ;Put IPC core back in free list
INTERN C$INT ;Interrupt Level Entry
INTERN C$SEND ;Send an IPCF Message
INTERN C$RSND ;Re-send messages that failed
SUBTTL C$GET -- Routine to return next IPC message
;RETURNS THE NEXT MESSAGE FROM THE IPCF RECIEVE QUEUE.
; RETURNS WITH "AP" POINTING TO THE MESSAGE. IF
; AP CONTAINS ZERO ON RETURN, NO REQUESTS ARE IN THE
; QUEUE.
C$GET: MOVEI H,HDRIPC## ;LOAD H
PUSHJ P,C%RECV ;GET ANY INCOMING MESSAGES
JUMPT GET.1 ;GOT ONE, INCLUDE IN IPC QUEUE
LOAD AP,.QHLNK(H),QH.PTF ;GET POINTER TO 1ST ENTRY
JUMPE AP,.RETT ;RETURN IF NONE
PJRST M$DLNK## ;DLINK THE ENTRY AND RETURN
GET.1: $COUNT (RIPC) ;TALLY MESSAGES RECEIVED
MOVE T1,S1 ;COPY MDB ADDRESS
PUSHJ P,M$GFRE## ;GET A CELL FOR THE MESSAGE
MOVE S1,MDB.SI(T1) ;GET SENDER'S SPECIAL INDEX
MOVEM S1,IPCIDX(AP) ;...
MOVE S1,MDB.SP(T1) ;SENDERS PID
MOVEM S1,IPCSDR(AP) ;...
MOVE S1,MDB.RP(T1) ;RECEIVERS PID
MOVEM S1,IPCRCR(AP) ;...
MOVE S1,MDB.CD(T1) ;SENDERS CONNECTED DIRECTORY
MOVEM S1,IPCCDI(AP) ;...
MOVE S1,MDB.SD(T1) ;SENDERS LOGGED IN DIRECTORY
MOVEM S1,IPCSID(AP) ;...
MOVE S1,MDB.PV(T1) ;SENDERS PRIVS
MOVEM S1,IPCPRV(AP) ;...
LOAD S1,MDB.MS(T1),MD.CNT ;LENGTH OF RECEIVED DATA
STORE S1,IPCMES(AP),IPM.CT ;...
STORE S1,MSGSIZ ;SAVE THE MSG LENGTH HERE ALSO
MOVE T2,[POINT 7,IPCACT(AP)] ;GET A DESTINATION BYTE POINTER.
MOVE S1,[POINT 7,G$ACTS##] ;GET SOURCE POINTER
GET.2: ILDB S2,S1 ;COPY THE ACCOUNT STRING FROM THE
IDPB S2,T2 ;MDB TO THE MESSAGE QUEUE ENTRY.
JUMPN S2,GET.2 ;END ON A NULL,,ELSE CONTINUE
MOVE S2,MDB.FG(T1) ;FLAGS
MOVEM S2,IPCFLG(AP) ;...
LOAD S1,MDB.MS(T1),MD.ADR ;ADDRESS OF RECEIVED DATA
TXNN S2,IP.CFV ;A PAGE MODE MESSAGE
JRST GET.3 ;NO, MUST MOVE THE DATA
STORE S1,IPCMES(AP),IPM.AD ;STORE THE ADDRESS
JRST GET.4 ;AND LINK IT IN
;CONTINUED ON THE NEXT PAGE
;CONTINUED FROM THE PREVIOUS PAGE
GET.3: HRLS S1 ;SOURCE = ADDRESS IN GLXIPC
HRRI S1,IPCDAT(AP) ;DESTIN = QUEUE SPACE
STORE S1,IPCMES(AP),IPM.AD ;STORE THAT NOW THAT WE HAVE IT
MOVE S2,G$MPS## ;GET THE MIN PACKET SIZE
CAIGE S2,SPL.SZ ;IF ITS LESS THEN THE SPOOL SIZE,
MOVEI S2,SPL.SZ ; THEN USE THE SPOOL SIZE
CAMGE S2,MSGSIZ ;IF THE MSG SIZE IS GREATER THEN THE
MOVEM S2,MSGSIZ ; QUEUE SIZE,,USE THE QUEUE SIZE
MOVE S2,MSGSIZ ;NOW USE THE MSG LENGTH FOR THE BLT
ADDI S2,(S1) ;COMPUTE END ADDRESS
BLT S1,-1(S2) ;MOVE THE MESSAGE TO OUR QUEUE SPACE
GET.4: PUSHJ P,M$ELNK## ;ADD NEW ENTRY AT THE END
JRST C$GET ;KEEP DOING THIS UNTIL NO MORE MESSAGES
SUBTTL C$PUT -- Routine to return free IPC core
;THIS ROUTINE IS CALLED TO PLACE AN IPC QUEUE ENTRY BACK INTO
; THE FREE SPACE. A CHECK IS MADE TO SEE IF IT IS A PAGED
; MESSAGE, AND IF SO THE PAGE IS RELEASED FIRST. CALLED
; WITH AP POINTING TO THE ENTRY.
C$PUT: MOVEI H,HDRIPC## ;SET UP H FOR M$PFRE
LOAD S1,IPCMES(AP),IPM.AD ;GET THE ADDRESS OF THE MESSAGE
ADR2PG S1 ;CONVERT TO A PAGE NUMBER
MOVE S2,IPCFLG(AP) ;GET FLAGS
TXNE S2,IP.CFV ;IS IT PAGED?
PUSHJ P,M%RELP ;YES, RELEASE THE PAGE
PJRST M$PFRE## ;AND RETURN VIA PFRE
SUBTTL C$INT -- Interrupt Level Entry
;TELL IPCF MODULE THAT AN IPCF INTERRUPT HAS OCCURED
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 IPCF Message
;C$SEND ROUTINES ARE CALLED WITH AP POINTING TO THE PACKET DESCRIPTOR
; BLOCK FOR THE MESSAGE TO BE SENT. THE MESSAGE IS SENT, AND
; IF IT WAS PAGED, M$RELP IS CALLED TO DESTROY THE PAGE.
; LEFT HALF OF AP CONTAINS FLAGS FOR THIS SEND.
C$SEND: MOVEM AP,SEND.A ;SAVE AP FOR LATER
MOVE S1,.IPCFL(AP) ;GET THE FLAG WORD
TXNN S1,IP.CFV ;PAGE MODE?
JRST SEND.1 ;NO, NO PROBLEM
HRRZ S1,.IPCFP(AP) ;GET PAGE NUMBER
PUSHJ P,M%IPSN ;NOTIFY GLXMEM
SEND.1: MOVE S2,G$QPID## ;ASSUME FROM [SYSTEM]QUASAR
SKIPN .IPCFS(AP) ;SENDER SUPPLIED
MOVEM S2,.IPCFS(AP) ;NO, STORE AS SENDER'S PID
TXNE AP,IPS.TF ;SKIP PASS OVER IPS QUEUE
JRST SEND.4 ;YES, GO TRY TO SEND IT
LOAD S1,<HDRIPS##+.QHLNK>,QH.PTF ;GET PTR TO 1ST ITEM IN IPS QUEUE
LOAD S2,.IPCFR(AP) ;GET THE PID WE'RE SENDING TO
SEND.2: JUMPE S1,SEND.4 ;NOTHING LEFT IN IPS QUEUE, DONE
CAME S2,IPCRCR(S1) ;SAME GUY??
JRST SEND.3 ;NO, KEEP LOOPING
TXNE AP,IPS.ID ;IGNORE IF DUPLICATE IN IPS QUEUE
TXO AP,IPS.IF ;YES, LITE IGNORE ALL FAILURES
MOVEI S1,IPE.RQ ;YES, LOAD A PHONY ERROR CODE
JRST SNDFAI ;AND QUEUE UP THE MESSAGE
SEND.3: LOAD S1,.QELNK(S1),QE.PTN ;GET POINTER TO NEXT
JRST SEND.2 ;AND KEEP LOOPING
SEND.4: MOVEI S1,IPCHSZ ;LOAD THE HEADER SIZE
HRRZ S2,AP ;AND THE ADDRESS
PUSHJ P,I$IPS## ;SEND IT
JUMPF SNDFAI ;IF FAILS, FIND OUT WHY
$COUNT (SIPC)
MOVE S2,.IPCFL(AP) ;GET THE FLAG WORD
TXNN S2,IP.CFV ;PAGE-MODE SEND?
$RETT ;NO, JUST RETURN
HRRZ S1,.IPCFP(AP) ;GET THE PAGE NUMBER
PJRST M%RELP ;RELEASE THE PAGE AND RETURN
SEND.A: BLOCK 1 ;STORE AP AROUND CALLS TO QSRMEM
SUBTTL SNDFAI -- IPCF Send Failure
;SNDFAI IS CALLED WHEN THE IPCF SEND ROUTINE C$SEND GETS THE
; ERROR RETURN FROM THE IPCF SEND ROUTINE. IF THE ERROR
; IS RECOVERABLE AT SOME POINT, THE MESSAGE IS LINKED TO
; THE END OF THE IPS QUEUE FOR A RETRY LATER, OTHERWISE
; THE MESSAGE IS SIMPLY FORGOTTEN ABOUT.
;
;IF THE SEND FAILURE IS DUE TO AN INVALID RECEIVER, WE IGNORE
; THE FAILURE, AND IF THE INTENDED RECEIVER WAS A KNOWN
; COMPONENT, WE ATTEMPT TO KILL THE PSB.
;
;ON ENTERING, S1 CONTAINS THE ERROR CODE AND AP CONTAINS ADDRESS OF
; PACKET DESCRIPTOR BLOCK OF THE BAD SEND (ALSO IN "SEND.A").
SNDFAI: $COUNT (IPCF)
CAIN S1,IPE.SF ;SYSTEM FREE SPACE USED UP?
JRST SNDF.1 ;YES, TRY AGAIN LATER
TXNE AP,IPS.IF ;IGNORE FAILURES
SETOB S1,.IPCFR(AP) ;YES, PHONY PID AND ERROR CODE
CAIE S1,IPE.SQ ;MY SEND QUOTA FULL?
CAIN S1,IPE.RQ ;OR HIS REC QUOTA FULL?
JRST SNDF.1 ;YES, QUEUE UP THE MESSAGE
;HERE IF WE WANT TO IGNORE THE ERROR. RETURN THE PAGE (IF IT
; WAS A PAGED SEND), AND IF THE RECEIVER'S PID IS NON-ZERO
; ATTEMPT TO KILL HIS PSB.
$COUNT (IPCU)
PUSH P,.IPCFR(AP) ;SAVE RECEIVER'S PID
MOVE S1,.IPCFL(AP) ;GET FLAG WORD
TXNN S1,IP.CFV ;IS IT PAGED?
JRST SNDF.0 ;NO, NOTIFY EVERYBODY
HRRZ S1,.IPCFP(AP) ;YES, GET PAGE NUMBER
PUSHJ P,M%IPRC ;PRETEND THAT WE REC'ED IT
HRRZ S1,.IPCFP(AP) ;GET PAGE NUMBER AGAIN
PUSHJ P,M%RELP ;AND RELEASE IT
SNDF.0: POP P,S1 ;GET PID BACK
PJRST G$SFAL## ;NOW TELL EVERYBODY
;CONTINUED FROM PREVIOUS PAGE
;HERE IF WE CAN QUEUE UP THE MESSAGE FOR A LATER RETRY
SNDF.1: MOVEI S1,1 ;GET 1 MINUTE
PUSHJ P,I$AFT## ;AGE IT
PUSHJ P,G$STIM## ;AND STORE WAKEUP TIME
$SAVE H ;SAVE THE QUEUE HEADER
MOVEI H,HDRIPS## ;LOAD ADR OF IPS HEADER
PUSHJ P,M$GFRE## ;GET A FREE CELL
MOVE S1,SEND.A ;GET ADDRESS OF PDB OF BAD SEND
MOVS S2,S1 ;MAKE SOURCE OF BLT POINTER
HRRI S2,IPCFLG(AP) ;SET DEST OF BLT
BLT S2,IPCMES(AP) ;BLT THE PDB
MOVE S2,.IPCFL(S1) ;GET THE FLAG WORD
TXNE S2,IP.CFV ;IS IT PAGED?
JRST SNDF.2 ;YES, HANDLE THE PAGE
MOVS S2,.IPCFP(S1) ;NO, GET ADR,,SIZE
HRRI S1,IPCDAT(AP) ;GET 0,,DEST
HRRM S1,IPCMES(AP) ;SAVE IT AS ADR OF MSG IN PDB
HLL S1,S2 ;GET SOURCE,,DEST
ADDI S2,-1(S1) ;GET END-OF-BLT ADR
BLT S1,(S2) ;BLT THE MESSAGE
PJRST M$ELNK## ;LINK INTO IPS QUEUE
SNDF.2: PUSH P,IPCMES(AP) ;SAVE ADR WORD
PUSHJ P,M$ELNK## ;LINK ENTRY INTO IPS QUEUE
POP P,S1 ;GET LEN,,ADR BACK
HRRZS S1 ;JUST GET ADR (PAGE NO.)
PJRST M%IPRC ;NOTIFY GLXMEM AND RETURN THROUGH IT
SUBTTL C$RSND -- Resend Unsendable Messages
;C$RSND IS CALLED EACH TIME THRU THE MAIN LOOP. IT ATTEMPTS TO
; RESEND EVERYTHING IN THE "IPS" QUEUE AGAIN.
C$RSND: SKIPN HDRIPS##+.QHLNK ;MAKE A VERY FAST CHECK FIRST
$RETT ;NOTHING THERE, RETURN
PUSHJ P,.SAVE1 ;SAVE P1 FIRST
LOAD P1,<HDRIPS##+.QHLNK>,QH.PTF ;LOAD PTR TO 1ST IN IPS QUEUE
ZERO <HDRIPS##+.QHLNK> ;MAKE BELIEVE THERE'S NOTHING THERE
RSND.1: JUMPE P1,RSND.2 ;NOTHING THERE (FOR REAL), RETURN
MOVEI AP,IPCFLG(P1) ;POINT AP TO THE MSG PDB
PUSHJ P,C$SEND ;AND SEND THE MESSAGE
MOVE AP,P1 ;COPY THE ADDRESS OF THE CELL
LOAD P1,.QELNK(P1),QE.PTN ;GET THE POINTER TO THE NEXT ONE
MOVEI H,HDRIPS## ;INSURE A PROPER HEADER
PUSHJ P,M$PFRE## ;AND PFRE THE CELL.
;**WARNING**
; DO NOT CALL DLNK OR RFRE!!!
JRST RSND.1 ;AND LOOP
RSND.2: SKIPN HDRIPS+.QHLNK ;IS THERE ANYTHING IN THE QUEUE?
$RETT ;NO, RETURN
MOVEI S1,1 ;LOAD 1 MINUTE
PUSHJ P,I$AFT## ;FROM NOW
PUSHJ P,G$STIM## ;SET ALARM CLOCK
$RETT ;AND RETURN
END