Twenex Muddle.
[pdp10-muddle.git] / <mdl.int> / ipc.mid.19
diff --git a/<mdl.int>/ipc.mid.19 b/<mdl.int>/ipc.mid.19
new file mode 100644 (file)
index 0000000..f171574
--- /dev/null
@@ -0,0 +1,815 @@
+TITLE IPC -- IPC COMMUNICATIONS HANDLER FOR MUDDLE
+
+RELOCATABLE
+
+; N. RYAN   October 1973
+
+.INSRT MUDDLE >
+
+;THIS PROGRAM HAS ENTRIES  SEND, SEND-WAIT, IPC-OFF,
+;               AND IPC-HANDLER.
+
+;THESE HANDLE THE IPC DEVICE.
+
+;SEND AND SEND-WAIT SEND OUT A MESSAGE ON THE IPC DEVICE.
+;THEY TAKE 6 ARGUMENTS, THE FIRST THREE OF WHICH ARE NECESSARY
+
+;      SEND (<HISNAME1> <HISNAME2> <MESSAGE> <MESSAGE-TYPE> <MYNAME1> <MYNAME2>)
+
+;      <HISNAME1> -- STRING USED AS SIXBIT FOR NAME 1
+;      <HISNAME2> -- STRING USED AS SIXBIT FOR NAME 2
+;      <MESSAGE>  -- THE MESSAGE TO SEND, EITHER A STRING OR A UVECTOR OF TYPE WORD
+;      <TYPE>     -- THE TYPECODE TO SEND, A FIXED NUMBER, DEFAULT 0
+;      <MYNAME1>  -- STRING USED AS SIXBIT FOR MY NAME 1
+;      <MYNAME2>  -- STRING USED AS SIXBIT FOR MY NAME 2
+
+;      SEND    -- TRIES TO SEND IMMEDIATELY, ELSE RETURNS FALSE WITH MESSAGE
+;      SEND-WAIT -- HANGS UNTIL MESSAGE CAN BE SENT
+
+;      IPC-OFF -- NO ARGUMENTS, CLOSES ALL IPC-RECEIVE CHANNELS
+
+;      IPC-ON  -- OPENS AN IPC RECEIVE CHANNEL
+;                 IT TAKES 2 OPTIONAL ARGS WHICH ARE THE NAMES TO LISTEN ON,
+;                      THE DEFAULT IS UNAME, JNAME
+
+
+
+\f; DEFINITIONS FOR STRUCTURE OF IPC BUFFER
+
+BUFL==200.                     ;LENGTH OF IPC BUFFER
+BUFHED==3                      ;LENGTH OF BUFFER HEADER
+CONT==400000                   ;LEFT HALF BIT INDICATING THIS IS CONTINUATION
+INCOMP==200000         ;LEFT HALF BIT INDICATING MESSAGE COMPLETE
+ASCIMS==100000         ;LEFT HALF BIT INDICATING THIS IS PACKED ASCII MESSAGE
+MESHED==2                      ;LENGTH OF CRUFT AT FRONT OF FIRST MESSAGE
+MAXMES==20000.         ;MAXIMUM LENGTH IN WORDS OF MESSAGES MUDDLE WILL LIKE
+
+
+.GLOBAL STRTO6,SAT,IBLOCK,MOPEN,MCLOSE,GFALS,TTOCHN,INCONS,MASK2,INTHLD
+.GLOBAL IPCS1,IBLOCK,IPCGOT,DIRQ,GIBLOK,6TOCHS,CAFRE,CAFRET,IPCBLS,PVSTOR,SPSTOR
+
+; DEFINITIONS OF BITS IN THE OPEN BLOCK FOR IPC DEVICE
+
+RFROMA==1                      ;READ FROM ANY
+RFROMS==2                      ;READ FROM SPECIFIC
+SANDH==4                       ;SEND AND HANG
+SIMM==10                       ;SEND IMMEDIATE
+USEUJ==20                      ;USE MY UNAME, JNAME
+
+
+;BUFFERFORMAT: HISNAME1
+;              HISNAME2
+;              COUNT
+;              BITS,,LENGTH
+;              TYPE
+
+;WHERE ASCII MESSAGES CONSIST OF A COUNT FOLLOWED BY CHARS
+;THE LENGTH IS THE LENGTH OF THE TYPE WORD PLUS ALL THE BODIES
+
+\f
+
+; THE FOLLOWING IS THE HANDLER WHICH WILL NORMALLY BE PUT ON THE
+; IPC INTERRUPT AND SO SERVE AS THE DEFAULT HANDLER FOR IPC RECEIVES
+; WHICH ARE NOT CAUGHT BY THE USER AND SERVICED IN SOME OTHER MANNER
+
+; NOTE THAT AS AN EXPERIMENT, MESSAGE WHICH ARE ASCII STRINGS WITH TYPE-CODE 1
+; ARE CONSIDERED AS EXECUTE COMMANDS.  THEY ARE FIRST PRINTED OUT,
+; THEN THEY ARE PARSED AND THAT RESULT IS EVALED.
+; ALL MESSAGES OF OTHER TYPES ARE CONSIDERED MERELY AS MESSAGES TO BE
+; PRINTED OUT WITH AN INDICATING OF WHO THEY ARE FROM
+
+; THE ARGS WHICH THIS SUBROUTINE IS CALLED WITH BY INTERRUPT ARE
+; <MESSAGE> <TYPE> <HIS NAME 1> <HIS NAME 2> <MY NAME 1> <MY NAME 2>
+; WHERE THE LAST TWO ARE OPTIONAL AND ONLY GIVEN IF THE SOCKET WAS NOT
+; LISTENING ON THE DEFAULT UNAME,JNAME COMBINATION.
+
+
+MFUNCTION      IPCH,SUBR,[IPC-HANDLER]
+
+       ENTRY
+
+       PUSH    P,[0]                   ;SAVE A SLOT FOR LATTER USE
+       HLRE    0,AB                    ;CHECK THE NUMBER OF ARGS WE GOT
+       CAMLE   0,[-8.]                 ;NEED AT LEAST 4 ARGS
+       JRST    WNA
+       GETYP   E,(AB)                  ;CHECK TYPE OF FIRST ARG
+       CAIN    E,TCHSTR                ;IS IT A CHARACTER STRING
+       JRST    .+3
+       CAIE    E,TUVEC                 ;IF NOT IT MUST BE A UVECTOR
+       JRST    WTYP1                   ;IF NEITHER THEN WE HAVE A LOOSER
+       GETYP   A,2(AB)                 ;GET TYPE OF MESSAGE TYPE, SHOULD BE A FIX
+       CAIE    A,TFIX
+       JRST    WTYP2                   ;IF NOT FIX COMPLAIN
+       GETYP   A,4(AB)
+       CAIE    A,TCHSTR                ;HIS NAME 1 SHOULD BE CHAR STRING
+       JRST    WTYP
+       GETYP   A,6(AB)
+       CAIE    A,TCHSTR
+       JRST    WTYP                    ;HIS NAME 2 SHOULD BE CHAR STRING
+       CAML    0,[-8.]                 ;SEE IF WE HAVE 4 OR 6 ARGS
+       JRST    IPCH1                   ;WE ONLY HAD 4 ARGS
+       CAME    0,[-12.]                ;THEN WE MUST HAVE EXACTLY 6 ARGS
+       JRST    WNA
+       GETYP   A,(AB)8.
+       CAIE    A,TCHSTR
+       JRST    WTYP                    ;CHECK TO SEE THE MY NAME 1 IS STRING
+       GETYP   A,10.(AB)
+       CAIE    A,TCHSTR
+       JRST    WTYP                    ;CHECK TO SEE THAT MY NAME 2 IS STRING
+
+IPCH1: PUSH    TP,$TCHAN
+       PUSH    TP,TTOCHN+1     ;PUSH ON TTY OUTPUT CHANNEL TO CALL TERPRI
+       MCALL   1,TERPRI
+       PUSH    TP,$TCHSTR
+       PUSH    TP,CHQUOTE [IPC MESSAGE FROM ]
+       PUSH    TP,$TCHAN
+       PUSH    TP,TTOCHN+1
+       MCALL   2,PRINC                 ;PRINT OUT BLURB TO TELL LOOSER WHATS HAPPENING
+       PUSH    TP,4(AB)
+       PUSH    TP,5(AB)                ;OUTPUT HIS NAME 1
+       PUSHJ   P,TO                    ;JUMP OUT OUTPUTTER OVER TTY OUTPUT CHANNEL
+       PUSHJ   P,STO                   ;JUMP TO SPACE OUTPUTTER OVER TTY OUTPUT CHANNEL
+       PUSH    TP,6(AB)
+       PUSH    TP,7(AB)                ;OUTPUT NAME 2
+       PUSHJ   P,TO
+       MOVE    E,3(AB)                 ;MESSAGE TYPE
+       JUMPE   E,IPCH3                 ;IF MESSAGE TYPE 0 DO NOTHING ABOUT IT
+       CAIE    E,1                     ;IF 1 SEE IF THIS IS EXECUTE MESSAGE
+       JRST    IPCH2                   ;IF NOT TELL LOOSER ABOUT THIS MESSAGE TYPE
+       GETYP   0,(AB)
+       CAIE    0,TCHSTR                ;SEE IF WE HAVE STRING
+       JRST    IPCH2                   ;IF NOT THIS CANT BE EXECUTE MESSAGE
+       AOS     (P)                     ;SET FLAG TO INDICATE EXECUTE MESSAGE
+       PUSH    TP,$TCHSTR
+       PUSH    TP,CHQUOTE [     EXECUTE]
+       PUSHJ   P,TO                    ;TELL THE LOOSER HE IS GETTING WHAT HE DESERVES
+       JRST    IPCH3
+IPCH2: PUSH    TP,$TCHSTR
+       PUSH    TP,CHQUOTE [     TYPE ]
+       PUSHJ   P,TO
+       PUSH    TP,2(AB)
+       PUSH    TP,3(AB)                ;PUSH ON THE MESSAGE TYPE
+       PUSHJ   P,TO
+IPCH3: HLRE    0,AB
+       CAME    0,[-12.]                ;SEE IF WE HAVE 6 ARGS AND SO MUST TELL HIM WHO MESS IS FOR
+       JRST    IPCH4                   ;IF NOT DONT WORRY
+       PUSH    TP,$TCHSTR
+       PUSH    TP,CHQUOTE [     TO ]
+       PUSHJ   P,TO
+       PUSH    TP,8.(AB)
+       PUSH    TP,9.(AB)               ;PUSH ON MY NAME 1
+       PUSHJ   P,TO
+       PUSHJ   P,STO                   ;LEAVE SPACE BETWEEN NAMES
+       PUSH    TP,10.(AB)              ;PUSH ON MY NAME 2
+       PUSH    TP,11.(AB)
+       PUSHJ   P,TO
+IPCH4: PUSH    TP,(AB)                 ;PUSH ON THE ACTUAL GOODIE
+       PUSH    TP,1(AB)
+       PUSH    TP,$TCHAN
+       PUSH    TP,TTOCHN+1
+       MCALL   2,PRINT                 ;AND PRINT IT OUT
+       SKIPN   (P)                     ;TEST TO SEE IF WE MUST EXECUTE THIS BAG BITTER
+       JRST    IPCHND
+       PUSH    TP,(AB)
+       PUSH    TP,1(AB)
+       MCALL   1,PARSE                 ;PARSE HIS CRUFT
+       PUSH    TP,A
+       PUSH    TP,B
+       MCALL   1,EVAL                  ;THEN EVAL THE RESULT
+IPCHND:        PUSH    TP,$TCHAN
+       PUSH    TP,TTOCHN+1
+       MCALL   1,TERPRI
+       MOVSI   A,TATOM
+       MOVE    B,IMQUOTE T
+       JRST    FINIS                   ;TO RETURN WITH SOMETHING NICE
+
+STO:   PUSH    TP,$TCHSTR              ;CROCK TO OUTPUT A SPACE ON THE TTY OUTPUT CHANNEL
+       PUSH    TP,CHQUOTE [ ]
+TO:    PUSH    TP,$TCHAN
+       PUSH    TP,TTOCHN+1
+
+       MCALL   2,PRINC
+       POPJ    P,                      ;GO BACK TO WHAT WE WERE DOING
+\f
+
+;THESE ARE THE FUNCTIONS TO ACTUALLY STUFF GOODIES OUT
+;OVER THE IPC DEVICE
+;DESCRIPTION OF CALLING ARGS TO THEM IS AT THE
+;FIRST OF THE FILE
+
+MFUNCTION      SEND,SUBR
+
+       ENTRY
+
+       PUSH    P,[0]                   ;FLAG TO INDICATE DONT WAIT
+       JRST    CASND
+
+MFUNCTION      SENDW,SUBR,[SEND-WAIT]
+
+       ENTRY
+
+       PUSH    P,[1]                   ;FLAG TO INDICATE WAITING
+
+CASND: HLRE    0,AB
+       CAMG    0,[-6]                  ;NEED AT LEAST 3 ARGS
+       CAMGE   0,[-12.]                ;AND NOT MORE THAN 6 ARGS
+       JRST    WNA
+       MOVE    A,(AB)
+       MOVE    B,1(AB)
+       PUSHJ   P,STRTO6                ;POOF FIRST ARG TO SIXBIT
+       MOVE    A,2(AB)
+       MOVE    B,3(AB)
+       PUSHJ   P,STRTO6                ;POOF SECOND ARG TO SIXBIT
+       GETYP   0,4(AB)
+       CAIN    0,TCHSTR
+       JRST    CASND1                  ;IF FIRST ARG IS STRING, NO PROBLEMS
+       CAIE    0,TSTORAGE
+       CAIN    0,TUVEC
+       JRST    .+2
+       JRST    WTYP3                   ;ELSE MUST BE OF TYPE STORAGE OR UVEC
+       MOVE    B,5(AB)
+       HLRE    C,B                     ;GET COUNT FIELD
+       SUBI    B,(C)                   ;AND ADD THAT AMOUNT TO FIND DOPE WORD
+       GETYP   A,(B)                   ;GET TYPE WORD OUT OF DOPE
+       PUSHJ   P,SAT                   ;GET ITS STORAGE TYPE
+       CAIE    A,S1WORD
+       JRST    WTYP3                   ;CRUFT MUST BE OF TYPE WORD
+CASND1:        PUSH    TP,4(AB)
+       PUSH    TP,5(AB)                ;SAVE THE STRUCTURE AROUND TO REST OFF AS WE SEND
+       PUSH    P,[0]                   ;SLOT FOR THIS MESSAGE TYPE, DEFAULT 0
+       HLRE    0,AB
+       CAMLE   0,[-8.]                 ;IF 4 OR MORE ARGS GET THE MESS TYPE
+       JRST    CASND2
+       GETYP   0,6(AB)                 ;CHECK TO SEE THAT TYPE IS A FIX
+       CAIE    0,TFIX
+       JRST    WTYP
+       MOVE    0,7(AB)
+       MOVEM   0,(P)                   ;SMASH IN THE SLOT RESERVED FOR TYPE
+CASND2:        HLRE    0,AB
+       CAMN    0,[-10.]                ;IF WE HAVE FIVE ARGS WE ARE A GLOBAL LOOSER NEED 4 OR 6
+       JRST    WNA
+       CAMGE   0,[-8.]                 ;IF WE HAVE 4 OR LESS DONT WORRY 
+       JRST    .+4                     ;GO GET LAST TO ARGS
+       PUSH    P,[0]                   ;NO SIXBIT OF FROM
+       PUSH    P,[0]                   ;SO SAVE SLOTS ANYWAY
+       JRST    CASND3                  ;GO WORRY ABOUT SENDING NOW
+       MOVE    A,8.(AB)
+       MOVE    B,9.(AB)
+       PUSHJ   P,STRTO6                ;CONVERT MY NAME1 TO SIXBIT
+       MOVE    A,10.(AB)
+       MOVE    B,11.(AB)               ;CONVERT MY NAME 2 TO SIXBIT
+       PUSHJ   P,STRTO6
+
+CASND3:        GETYP   0,-1(TP)
+       CAIE    0,TCHSTR                ;IS THIS A CHAR STRING
+       JRST    .+5
+       HRRZ    A,-1(TP)                ;IF SO GET COUNT
+       ADDI    A,9.
+       IDIVI   A,5                     ;IF SO ROUND UP AND ADD ONE
+       JRST    .+3
+       HLRE    A,(TP)
+       MOVN    A,A                     ;IF A VECTOR GET THE WORD COUNT
+       PUSH    P,A                     ;SAVE COUNT OF WORDS
+       CAILE   A,MAXMES
+       JRST    TOBIGR                  ;MESS OVER SIZE LIKED BY MUDDLE
+       CAILE   A,BUFL-MESHED           ;HOW BIG A BUFFER DO WE NEED?
+       MOVEI   A,BUFL-MESHED           ;IF TOO BIG WE USE DEFAULT MAX SIZE, ELSE LESS
+       ADDI    A,MESHED+BUFHED         ;PLUS ROOM FOR MESSAGE AND SYSTEM HEADERS
+       PUSHJ   P,IBLOCK
+       PUSH    TP,A
+       PUSH    TP,B                    ;GET BUFFER OF RIGHT SIZE AND SAVE ON STACK
+       PUSH    TP,A
+       PUSH    TP,B                    ;SAVE ANOTHER COPY WHICH WILL BE RESTED AT TIMES
+       MOVE    C,-5(P)                 ;GET HIS NAME 1
+       MOVEM   C,(B)                   ;AND STUFF IN RIGHT PLACE
+       MOVE    C,-4(P)
+       MOVEM   C,1(B)                  ;STUFF HIS NAME 2
+       MOVE    C,-3(P)
+       MOVEM   C,4(B)                  ;STUFF MESSAGE TYPE CODE WORD
+       GETYP   0,-5(TP)                ;IS THIS STRING OR UVECTOR?
+       CAIE    0,TCHSTR
+       JRST    CASND4
+       MOVE    C,(P)                   ;GET LENGTH OF CHAR STRING TO SEND
+       ADDI    C,1
+       MOVEM   C,3(B)                  ;STORE IN LENGTH FIELD IN MESS HEADER
+       SOS     (P)                     ;DECREMENT FOR COUNT WORD
+       HRRZ    C,-5(TP)                ;GET THE CHARACTER COUNT
+       MOVEM   C,5(B)                  ;STORE IN CORRECT SLOT IN MESSAGE
+       MOVE    D,[6,,6]                ;OFFSET FOR INITIAL HEADER ON ASCII MESSAGES
+       ADDM    D,(TP)                  ;OFFSET BUF PTR 2 BY THIS AMOUNT
+       JRST    CASND5
+CASND4:        MOVE    C,(P)                   ;GET COUNT OF MESSAGE
+       ADDI    C,1                     ;EXTRA FOR TYPE WORD
+       MOVEM   C,3(B)                  ;STORE IN SLOT FOR COUNT OF WHOLE MESSAGE
+       MOVE    D,[5,,5]                ;OFFSET FOR INITIAL HEADER ON UVECTOR MESSAGES
+       ADDM    D,(TP)                  ;OFFSET BUF PTR 2 BY THIS AMOUNT
+CASND5:        PUSHJ   P,STUFBF                ;GO FILL UP THE BUFFER WITH GARBAGE
+       MOVN    0,A                     ;GET NEGATIVE THE COUNT OF WORDS STUFFED
+       ADDM    0,(P)                   ;THAT MANY LESS WORDS REMAINING TO BE DONE
+       HRRZ    C,-2(TP)                ;GET A POINTER TO THE "UNRESTED" BUFFER
+       HRRZ    D,(TP)                  ;GET A POINTER TO THE "RESTED" BUFFER
+       SUB     D,C                     ;FIND OUT HOW MUCH WAS RESTED OFF
+       ADD     D,A                     ;ADD TO THAT THE COUNT OF WORDS STUFFED THIS TIME
+       SUBI    D,BUFHED                ;LESS THE SYSTEM CONSTANT HEADER THAT DOENT COUNT
+       MOVEM   D,2(C)                  ;STORE IN THE BUFFER IN CORRECT SLOT
+       PUSHJ   P,CASIOT                ;GO DO THE "IOT"--ACTUALLY AN OPEN
+       MOVE    C,-2(TP)
+       HRLZI   E,CONT                  ;THE "THIS IS A CONTINUATION" BIT
+       IORM    E,3(C)                  ;TURN BIT ON IN FUTURE MESSAGES
+       ADD     C,[4,,4]                ;REST OFF THE SHORTER HEADER FOR THE REST OF MESSAGES
+       MOVEM   C,(TP)                  ;STORE THIS IN THE "RESTED" BUFFER SLOT
+       SKIPLE  (P)                     ;IS THERE MORE TO DO?
+       JRST    CASND5
+       MOVSI   A,TATOM
+       MOVE    B,IMQUOTE T
+       JRST    FINIS                   ;RETURN HIM SOMETHING NICE
+
+TOBIGR:        ERRUUO  EQUOTE MESSAGE-TOO-BIG
+
+\f
+STUFBF:        MOVE    C,-2(TP)                        ;ROUTINE TO FILL UP BUFFER WITH GOODIES
+       HRLZI   E,INCOMP+ASCIMS
+       ANDCAM  E,3(C)                          ;CLEAR THE INCOMPLETE AND ASCII FLAGS IF SET
+       HLRE    B,(TP)                          ;GET THE BUFFER LENGTH
+       MOVN    B,B                             ;MAKE IT A POSITIVE NUMBER
+       CAML    B,-1(P)                         ;SEE IF THE WHOLE MESSAGE WILL FIT
+       JRST    .+4                             ;IT WILL ALL FIT
+       HRLZI   0,INCOMP                        ;THE INCOMPLETE FLAG
+       IORM    0,3(C)                          ;SET IT
+       JRST    .+2
+       MOVE    B,-1(P)                         ;ELSE THE WHOLE MESSAGE FITS
+       GETYP   0,-5(TP)
+       CAIN    0,TCHSTR
+       JRST    STUFAS
+       HRLZ    D,-4(TP)                        ;SET UP TO BLT UVECTOR
+       HRR     D,(TP)
+       HRRZ    E,(TP)
+       ADDI    E,(B)-1                         ;SET UP BLT POINTERS
+       SKIPLE  B                               ;IN CASE ZERO LENGTH UVECTOR
+       BLT     D,(E)                           ;BBBBLLLLLLLLLLLLLLLLLLTTTT?
+       MOVE    A,B                             ;MOVE COUNT OF WORDS DONE INTO A
+       HRL     B,B
+       ADDM    B,-4(TP)                        ;REST OFF THIS MUCH OF GOODIE FOR NEXT TIME
+       POPJ    P,
+STUFAS:        HRLZI   0,ASCIMS
+       IORM    0,3(C)                          ;TURN ON THE ASCII BIT IN THE MESSAGE
+       MOVE    A,B                             ;MOVE COUNT OF NUMBER OF WORDS INTO A
+       IMULI   B,5                             ;GET CHAR COUNT IN B
+       HRRZ    C,-5(TP)                        ;COMPARE THIS WITH COUNT FIELD IN STRING
+       MOVE    D,B
+       SUB     D,C                             ;SEE HOW MANY EXTRA BLANKS AT END OF MESS
+       JUMPGE  D,.+3
+       MOVEI   D,0                             ;NO EXTRA SPACES TO PAD
+       MOVE    C,B                             ;NOT EXTRA SPACES, DO 5*WORD CHARS
+       MOVN    E,C
+       ADDM    E,-5(TP)                        ;FIX UP COUNT IN ASCII
+       HRLZI   E,440700                        ;GET A IDPB PTR INTO THE BUFFER
+       HRR     E,(TP)                          ;POINT TO RIGHT PLACE IN BUFFER
+       JUMPLE  C,.+4                           ;ARE WE DONE MOVING CHARS?
+       ILDB    0,-4(TP)                        ;LOAD A BYTE FROM STRING
+       IDPB    0,E                             ;STUFF IN BUFFER
+       SOJG    C,.-2                           ;REPEAT THE LOOP
+       JUMPLE  D,.+4                           ;SEE IF WE NEED TO FILL OUT WITH NULLS
+       MOVEI   0,0
+       IDPB    0,E                             ;STUFF A NULL IN RIGHT SPOT IN BUFFER
+       SOJG    D,.-1
+       POPJ    P,
+
+CASIOT:        HRRZI   A,(SIXBIT /IPC/)                ;FIX UP OPEN BLOCK IN THE AC'S
+       MOVE    B,-2(TP)                        ;HOWS THAT FOR SNAZZY?
+       MOVE    C,-3(P)                         ;MY NAME 1
+       MOVE    D,-2(P)                         ;MY NAME 2
+       JUMPN   C,.+3
+       JUMPN   D,.+2
+       TLO     A,USEUJ                         ;IF BOTH ARE ZERO THEN USE DEFAULT UNAME,JNAME
+       SKIPN   -7(P)                           ;SEE IF SEND AND HANG FLAG IS SET
+       JRST    .+3
+       TLO     A,SANDH                         ;SET SEND AND HANG FLAG
+       JRST    .+3
+       TLO     A,SIMM                          ;ELSE WE MUST BE SENDING IMMEDIATE
+       AOS     -7(P)                           ;IF THERE IS MORE TO DO, IT MUST BE IN HANG MODE
+       MOVSI   0,TUVEC
+       MOVE    PVP,PVSTOR+1
+       MOVEM   0,BSTO(PVP)                     ;IN CASE WE ARE INTERRUPTED OUT WE WANT TO WIN
+       SETZM   E                               ;FLAG USED TO INDICATE NO SKIPPAGE
+       ENABLE
+       .OPEN   0,A                             ;WELL, THATS ALL THERE IS TO IT.
+       AOS     E                               ;IF WE DONT SKIP WE HAVE PROBLEMS
+       DISABLE
+       MOVE    PVP,PVSTOR+1
+       SETZM   BSTO(PVP)                       ;FIX UP THE SLOT IN PVP
+       SKIPN   E                               ;SEE IF WE LOST
+       POPJ    P,                              ;IF NOT WE ARE THROUGH WITH THIS PART
+       .STATUS 0,A                             ;FIND OUT REASON FOR LOSSAGE
+       MOVEI   B,0
+       PUSHJ   P,GFALS                         ;MAKE A FALSE WITH THAT REASON
+       JRST    FINIS                           ;GIVE THE MAGIC FALSE BACK TO THE LOOSER
+
+\f
+MFUNCTION      DEMSIG,SUBR
+
+       ENTRY 1
+
+       MOVE    A,(AB)
+       MOVE    B,1(AB)
+       PUSHJ   P,STRTO6                ;GET THE SIXBIT REPRESENTATION
+       MOVE    A,[SETZ]                ;FIX UP THE BLOCK IN THE AC'S
+       MOVE    B,[SIXBIT /DEMSIG/]
+       MOVE    C,[SETZ (P)]            ;THE SIXBIT IS ON TOP OF P STACK
+       .CALL   A
+       JRST    RFALS                   ;DIDNT WIN WITH DEMON SIGNAL
+RTRUE: MOVSI   A,TATOM
+       MOVE    B,IMQUOTE T
+       JRST    FINIS
+
+RFALS: MOVSI   A,TFALSE
+       MOVEI   B,0
+       JRST    FINIS                   ;FALSE INDICATING LACK OF WINNAGE
+
+\f
+MFUNCTION      IPCON,SUBR,[IPC-ON]
+
+       ENTRY
+
+       PUSH    P,[USEUJ,,0]            ;FLAG FOR WHETHER OR NOT TO USE DEFAULT
+       HLRZ    0,AB
+       JUMPE   0,IPCON1                ;NO ARGS ARE FINE
+       CAIE    0,-4                    ;ELSE MUST HAVE 2 ARGS
+       JRST    WNA
+       SETZM   (P)                     ;CLEAR OUR FLAG
+       MOVE    A,(AB)
+       MOVE    B,1(AB)
+       PUSHJ   P,STRTO6                ;GET SIXBIT OF OUR FIRST ARG
+       MOVE    A,2(AB)
+       MOVE    B,3(AB)
+       PUSHJ   P,STRTO6                ;GET SIXBIT OF OUR SECOND ARG
+       JRST    IPCON2
+IPCON1:        PUSH    P,[0]                   ;SAVE SLOT ON STACK FOR EVENNESS
+       PUSH    P,[0]
+IPCON2:        MOVEI   A,BUFL+BUFHED
+       PUSHJ   P,CAFRE                 ;GET A BUFFER OF RIGHT LENGTH TO READ INTO
+       PUSH    P,A                     ;AND SAVE IT AROUND SO WE DONT LOOSE
+       MOVEI   0,BUFL
+       MOVEM   0,2(A)                  ;FILL COUNT IN THE BUFFER SLOT
+       MOVEI   A,5
+       PUSHJ   P,IBLOCK                ;GET A BLOCK OF STORE FOR THE OPEN BLOCK
+       PUSH    TP,$TUVEC
+       PUSH    TP,B                    ;SAVE CRUFT ON TP
+       TLO     0,RFROMA                ;SET THE READ FROM ANY FLAG
+       IOR     0,-3(P)                 ;FIX FOR DEFAULT UNAME,JNAME IF FLAG INDICATES
+       MOVEM   0,(B)                   ;MAKE OPEN BLOCK
+       MOVE    0,[SIXBIT /IPC/]
+       MOVEM   0,1(B)
+       MOVE    0,-2(P)
+       MOVEM   0,3(B)                  ;MY NAME 1
+       MOVE    0,-1(P)
+       MOVEM   0,4(B)                  ;MY NAME 2 IF NOT USING DEFAULT
+       MOVE    0,(P)
+       MOVEM   0,2(B)                  ;PTR TO THE WIRED BUFFER FOR STUFFING CRUFT
+       MOVE    A,B
+       PUSHJ   P,MOPEN                 ;GO DO THE OPEN
+       JRST    IPCON3                  ;OPEN FAILED, FIND OUT WHY
+       PUSH    P,A                     ;SAVE THE CHANNEL NUMBER
+       MOVEI   E,1
+       LSH     E,(A)                   ;SET INTERRUPT BITS RIGHT
+       IORM    E,MASK2
+       .SUSET  [.SMSK2,,MASK2]
+       MOVE    C,-1(TP)
+       MOVE    D,(TP)                  ;GET THE OPEN BLOCK UVECTOR
+       PUSHJ   P,INCONS                ;THROW INTO PAIR SPACE
+       POP     P,C                     ;GET THE CHANNEL #
+       SUBI    C,1
+       IMULI   C,2
+       MOVEM   B,IPCS1+1(C)            ;STUFF PTR TO OPEN BLOCK INTO SLOT IN TVP
+       JRST    RTRUE                   ;WE WON, GO LET LUSER KNOW IT.
+IPCON3:        PUSH    P,A                     ;WE LOST, LETS FIND OUT WHY
+       MOVE    A,BUFL+BUFHED
+       MOVE    B,-1(P)                 ;LETS FREE UP OUR WIRED DOWN BUFFER TO BE CLEAN
+       PUSHJ   P,CAFRET
+       POP     P,A                     ;GET THE CHANNEL # BACK
+       JUMPL   A,NFCHN                 ;NO FREE CHANNELS?
+       MOVE    B,[.STATUS A]           ;MAKE A CALL TO STATUS TO FIND REASON
+       LSH     A,23.                   ;SHIFT THE CHANNEL NUMBER INTO RIGHT PLACE
+       IOR     B,A                     ;FIX UP .STATUS
+       XCT     B
+       MOVEI   B,0
+       PUSHJ   P,GFALS
+       JRST    FINIS                   ;RETURN A LOOSE WITH REASON FOR LOOSAGE
+
+NFCHN: ERRUUO  EQUOTE NO-ITS-CHANNELS-FREE
+
+\f
+MFUNCTION      IPCOFF,SUBR,[IPC-OFF]
+
+       ENTRY   0
+
+       PUSH    TP,$TVEC
+       MOVE    0,[IPCS1,,IPCS1]
+       PUSH    TP,0                    ;SAVE OUR PLACE IN RUNNING THROUGH SLOTS
+       PUSH    P,[1]                   ;COUNTER OF CHANNEL NUMBER
+
+IPCOF1:        MOVE    A,(TP)                  ;GET FIRST GOODIE
+       SKIPN   B,1(A)                  ;GET THE POINTER TO LIST
+       JRST    IPCOF2
+       SETZM   1(A)                    ;ZERO OUT SLOT TO BE CLEAN
+       MOVE    B,1(B)                  ;GET CAR OF LIST, PTR TO OPEN BLOCK
+       MOVE    C,(P)                   ;GET THE ACTUAL CHANNEL NUMBER
+       MOVEI   E,1                     ;TURN OFF INTERRUPT
+       LSH     E,(C)
+       ANDCAM  E,MASK2
+       .SUSET  [.SMSK2,,MASK2]
+       MOVE    A,C
+       PUSHJ   P,MCLOSE                ;CLOSE THIS CHANNEL
+       JFCL
+       MOVEI   A,BUFL+BUFHED           ;LENGTH OF WIRED STORE TO FREE UP
+       MOVE    B,1(B)                  ;GET THE POINTER TO WIRED STORE
+       PUSHJ   P,CAFRET                        ;FREE ALREADY
+IPCOF2:        MOVE    0,[2,,2]
+       ADDM    0,(TP)                  ;REST TO NEXT SLOT
+       AOS     D,(P)                   ;NEXT CHANNEL
+       CAIG    D,15.                   ;ARE WE THROUGH
+       JRST    IPCOF1
+       JRST    RTRUE                   ;RETURN HIM A TRUE FOR NICENESS
+
+\f
+IPCGOT:        MOVEI   D,IPCS1+1
+       ADDI    D,(B)
+       ADDI    D,(B)
+       SKIPN   D,-74.(D)       ;GET THE GOODIE LIST FOR CHANNEL WE INTERRUPTED ON
+       JRST    DIRQ            ;MIX UP MAYBE, LET HIM WORRY ABOUT IT
+       PUSH    P,B             ;SAVE THE CHAN #
+       PUSH    TP,$TLIST
+       PUSH    TP,D            ;SAVE GOODIE LIST
+       MOVE    E,1(D)          ;GET PTR TO OPEN BLOCK
+       PUSH    P,2(E)          ;SAVE PTR TO WIRED BUFFER
+       MOVE    E,2(E)
+       MOVE    0,3(E)          ;GET THE MAGIC BITS FOR THIS MESSAGE
+       TLNE    0,CONT          ;IS THIS MESSAGE A CONTINUATION?
+       JRST    IGCON           ;YES
+       MOVEI   A,10.           ;NO
+       PUSHJ   P,GIBLOK        ;GET A BLOCK FOR FUNNY MESSAGE VECTOR
+       PUSH    TP,$TVEC
+       PUSH    TP,B            ;SAVE THE BLOCK FOR FUNNY MESSAGE VECTOR
+       MOVE    E,(P)           ;GET PTR TO WIRED BUFFER
+       MOVE    0,3(E)          ;GET THE MAGIC BITS AGAIN
+       HRRZ    A,0             ;GET THE LENGTH IN WORDS OF THIS THE WHOLE MESSAGE HE HAS
+       SUBI    A,1             ;MINUS ONE FOR THE TYPE WORD WHICH IS COUNTED
+       TLNE    0,ASCIMS        ;IS THIS ASCII?
+       SUBI    A,1             ;IF YES THEN MUST SUB 1 MORE FOR ASCII CHAR COUNT
+       CAILE   A,MAXMES        ;IS THIS BIGGER THAN MUDDLE BLESSES?
+       JRST    TBGMS           ;IF SO THEN CLEAN UP AND FORGET ABOUT THE LOOSER
+       PUSHJ   P,IBLOCK
+       MOVE    E,(P)
+       MOVE    D,(TP)
+       MOVE    0,(E)           ;GET HIS NAME 1 OUT OF MESSAGE
+       MOVEM   0,5(D)          ;STORE INTO SLOT IN FUNNY MESSAGE VECTOR
+       MOVE    0,1(E)          ;GET HIS NAME 2 OUT OF MESSAGE
+       MOVEM   0,7(D)
+       MOVE    0,4(E)          ;GET THE MESSAGE TYPE WORD
+       MOVEM   0,9(D)          ;STORE INTO SLOT IN MESSAGE VECTOR
+       MOVSI   0,TFIX
+       MOVE    0,4(D)
+       MOVE    0,6(D)
+       MOVE    0,8(D)
+       MOVE    0,3(E)          ;GET THE MESSAGE BITS
+       TLNE    0,ASCIMS        ;IS IT ASCII?
+       JRST    IG1             ;YES
+       MOVSI   0,TUVEC
+       MOVEM   0,(D)
+       MOVEM   0,2(D)
+       MOVEM   B,1(D)
+       MOVEM   B,3(D)          ;STORE MESSAGE BLANK TWICE, THE SECOND TO REST THROUGH
+       HLRE    E,B
+       SUBM    B,E
+       MOVSI   0,TFIX
+       MOVEM   0,(E)           ;SET NICE TYPE TO PRINT GOODER
+       JRST    IGBLT
+IG1:   MOVSI   0,TUVEC
+       MOVEM   0,2(D)
+       MOVEM   B,3(D)          ;STORE MESSAGE BLANK AS UVECTOR TO REST THROUGH
+       HLRE    A,B
+       HRLI    B,010700        ;MAKE THE ILDB PTR
+       SUBI    B,1
+       MOVEM   B,1(D)          ;AND STORE IN THE SLOT
+       IMUL    A,[-5]          ;MAX CHAR COUNT FOR STRING
+       MOVE    B,5(E)          ;GET THE ACTUAL CHARACTER COUNT HE CLAIMED
+       MOVE    C,A
+       SUB     C,B             ;FIND DIFFERENCE BETWEEN MAX AND CLAIMED
+       JUMPL   C,.+2           ;IF COUNT TOO BIG, MUST DO BEST POSSIBLE AND USE MAX COUNT
+       CAILE   C,4             ;NO MORE THAN FOUR EXTRA CHARS IMPLIES GOODNESS
+       MOVE    B,A             ;IF LOSSAGE, THEN USE MAX COUNT INSTEAD OF HIS CLAIM
+       HRLI    B,TCHSTR        ;MAKE THIS A CHAR STRING TYPE WORD
+       MOVEM   B,(D)           ;AND FIX MESSAGE BLANK # 1 TO BE THE BLESSED STRING
+       JRST    IGBLT           ;BLT THE MESSAGE INTO THE BLANK
+
+IGCON: MOVE    D,(TP)          ;GET THE IPC SLOT LIST
+       MOVE    E,(P)           ;GET A PTR TO THE MESSAGE BUFFER
+       HRRZ    C,(D)           ;CDR THE IPC SLOT LIST TO POINT TO FIRST MESSAGE VECTOR
+IGCON1:        JUMPE   C,IGCONL        ;IF NIL, THEN ABANDON ALL HOPE
+       MOVE    B,1(C)          ;LOOK AT THE VECTOR
+       MOVE    0,5(B)          ;HIS NAME 1 FOR THIS BLOCK
+       CAME    0,(E)           ;COMPARE WITH HIS NAME 1 IN THIS MESSAGE
+       JRST    IGCON2          ;IMMEDIATE FAILURE, TRY THE NEXT IN THE LIST
+       MOVE    0,7(B)          ;SEE IF HIS NAME 2 ALSO MATCHES
+       CAME    0,1(E)          ;WELL, DOES IT MATCH?
+       JRST    IGCON2          ;NO, TRY THE NEXT ONE
+       PUSH    TP,$TVEC        ;WE GOT IT
+       PUSH    TP,1(C)         ;SAVE THIS MESSAGE BLOCK ON TP FOR LATER BLTING
+       HRRZ    C,(C)           ;CDR TO REST OF LIST
+       HRRM    C,(D)           ;AND SPLICE IT RIGHT OUT OF THE LIST, NEAT HUH?
+       JRST    IGBLT           ;GO BLT TO OUR HEART'S CONTENT
+IGCON2:        HRRZ    D,(D)           ;REST OUR FOLLOW UP POINTER
+       HRRZ    C,(C)           ;REST OUR ACTUAL TEST POINTER
+       JRST    IGCON1          ;TRY AGAIN
+
+IGCONL:        MOVE    A,(TP)
+       MOVE    A,1(A)          ;GET PTR TO OPEN BLOCK
+       MOVE    B,-1(P)
+       SUBI    B,36.           ;GET CHANNEL NUMBER
+       HLL     B,(A)
+       MOVE    C,(P)           ;GET THE WIRED BUFFER
+       SUB     P,[2,,2]        ;WE LOST SO CLEAN UP STACKS
+       SUB     TP,[2,,2]
+ROPNL: SETZM   (C)             ;REOPEN CHANNEL SO NOT PERMANENTLY CROGGLED
+       SETZM   1(C)            ;ZERO OUT THE HIS NAME SLOTS
+       MOVEI   0,BUFL
+       MOVEM   0,2(C)          ;RESET THE LENGTH FIELD IN WIRED BUF
+       DOTCAL  OPEN,[B,1(A),2(A),3(A),4(A)]
+       FATAL CANT REOPEN IPC CHN
+       JRST    DIRQ            ;LEFT IN NICE STATE AFTER LOOSAGE
+
+TBGMS: MOVE    A,-2(TP)
+       MOVE    A,1(A)          ;GET OPEN BLOCK
+       MOVE    B,-1(P)
+       SUBI    B,36.           ;CHANNEL #
+       HLL     B,(A)
+       MOVE    C,(P)           ;WIRED BUFFER
+       SUB     P,[2,,2]        ;CLEAN UP STACKS
+       SUB     TP,[4,,4]
+       JRST    ROPNL           ;REOPEN SO NEXT GUY CAN WIN
+
+\f
+
+IGBLT: MOVE    E,(TP)          ;POINTER TO MESSAGE VECTOR
+       MOVE    E,3(E)          ;GET VECTOR (MAYBE STRING IN DISGUISE) TO BLT IN
+       MOVE    D,(P)           ;GET THE WIRED BUFFER
+       MOVEI   C,4(D)          ;GET A POINTER TO THE REST OF THE WIRED BUF
+       MOVEI   0,BUFL-1        ;KLUDGE TO IGNORE ONE EXTRA WORD OF BITS
+       SUB     0,2(D)          ;GET LENGTH OF GOODIE GOT
+       MOVE    A,3(D)          ;GET THE RANDOM MESSAGE BITS
+       TLNE    A,CONT          ;TEST FOR CONTINUED MESSAGE
+       JRST    .+7             ;IF SO THEN NO NEED TO WORRY
+       SOS     0
+       AOS     C               ;FIX UP FOR ONE LESS WORD TO WORRY WITH
+       TLNN    A,ASCIMS        ;TEST FOR ASCII MESSAGE
+       JRST    .+3             ;IF NOT THEN NO WORRY
+       SOS     0
+       AOS     C               ;FIX UP FOR YET 1 FEWER WORD
+       HLRE    A,E
+       MOVM    A,A             ;GET LENGTH OF VECTOR TO BLT INTO
+       CAILE   0,(A)           ;CHECK TO SEE WE DONT HAVE TOO MUCH
+       MOVE    0,A             ;IF WE HAVE TOO MUCH, CHOP OFF--HA, HA, HA
+       MOVEI   B,-1(E)
+       ADD     B,0             ;B POINTS TO LAST WORD TO BLT INTO
+       HRL     C,E             ;BLT POINTER
+       MOVSS   C               ;NDR CANT REMEMBER HOW TO BLT POINTER
+       BLT     C,(B)           ;VIOLA
+       HRL     0,0
+       MOVE    E,(TP)          ;GET BACK POINTER TO MESSAGE VECTOR
+       ADDM    0,3(E)          ;REST OFF TO KEEP TRACK OF INCOMPLETE MESSAGE
+       MOVE    A,3(D)          ;GET THE RANDOM MESSAGE BITS BACK
+       TLNE    A,INCOMP        ;MESSAGE COMPLETE?
+       JRST    IGHALF          ;INCOMPLETE
+       JRST    IGMES           ;COMPLETE
+
+IGHALF:        MOVE    C,-1(TP)        ;GOT TO SPLICE MESSAGE VECTOR BACK IN
+       MOVE    D,(TP)
+       PUSHJ   P,INCONS        ;STICK INTO PAIR SPACE
+       HRRZ    E,-2(TP)        ;PTR TO LIST
+       HRRZ    D,(E)           ;CDR OF LIST
+       HRRM    D,(B)           ;MAKE SPLICE
+       HRRM    B,(E)           ;THAT IT
+       MOVE    B,1(E)          ;POINT TO OPEN BLOCK
+       MOVE    0,-1(P)         ;GET CHAN #
+       SUBI    0,36.
+       HLL     0,(B)
+       MOVE    E,(P)           ;GET THE WIRED BUF
+       MOVEI   D,BUFL
+       MOVEM   D,2(E)          ;REFIX THE WIRED BUF
+       SETZM   (E)
+       SETZM   1(E)
+       DOTCAL  OPEN,[0,1(B),2(B),3(B),4(B)]
+       FATAL CANT REOPEN IPC CHN
+       SUB     P,[2,,2]
+       SUB     TP,[4,,4]       ;CLEAN OURSELVES
+       JRST    DIRQ            ;THATS ALL THERE IS TO IT
+
+IGMES: HRRZ    E,-2(TP)        ;PTR TO OUR KLUDGE LIST
+       MOVE    B,1(E)          ;PTR TO OPEN BLOCK
+       MOVE    0,-1(P)         ;CHANNEL #
+       SUBI    0,36.
+       HLL     0.(B)
+       MOVE    D,(P)           ;GET THE WIRED BUF
+       MOVEI   C,BUFL
+       MOVEM   C,2(D)
+       SETZM   (D)
+       SETZM   1(D)            ;BLESS WIRED BUF FOR REOPENING
+       DOTCAL  OPEN,[0,1(B),2(B),3(B),4(B)]
+       FATAL CANT REOPEN IPC CHN
+       MOVE    E,(TP)          ;GET THE MESSAGE VECTOR (ALIAS GOODIE BLOCK)
+       SUB     P,[2,,2]        ;BLESS OUR P STACK
+       PUSH    P,5(E)          ;SAVE SIXBIT HIS NAME 1
+       PUSH    P,7(E)          ;SAVE SIXBIT HIS NAME 2
+       SUB     TP,[4,,4]       ;BLESS THE TP STACK
+       PUSH    TP,$TCHSTR
+       PUSH    TP,CHQUOTE IPC
+       PUSH    TP,(E)          ;STUFF STUFF ON TO CALL INTERRUPT
+       PUSH    TP,1(E)         ;THAT IS THE ACTUAL MESSAGE
+       MOVE    0,9(E)
+       CAMN    0,[400000,,0]
+        JRST   IGUG
+IGUGN: PUSH    P,3(B)          ;GET MY NAME 1 OUT OF OPEN BLOCK
+       PUSH    P,4(B)          ;GET MY NAME 2 OUT OF OPEN BLOCK
+       MOVE    0,(B)           ;GET SOME OF THE RANDOM OPEN FLAGS
+       TLNE    0,USEUJ
+       SETZ    -1(P)           ;MAKE SURE WE HAVE INDICATOR IF THIS IS TO UNAME,JNAME
+       PUSH    TP,$TFIX
+       PUSH    TP,9(E)         ;SAVE THE MESSAGE TYPE
+       MOVE    A,-3(P)         ;HIS NAME 1
+       PUSHJ   P,6TOCHS
+       PUSH    TP,A
+       PUSH    TP,B            ;GIVE HIM NICE CHAR STRING OF ALL THE NAMES
+       MOVE    A,-2(P)
+       PUSHJ   P,6TOCHS
+       PUSH    TP,A
+       PUSH    TP,B            ;NICE CHAR STRING OF HIS NAME 2
+       SKIPN   A,-1(P)         ;ISE THIS DEFAULT UNAME, JNAME
+       JRST    IGFOUR          ;ONLY FOUR ARGS TO THE IPC INTERRUPT
+       PUSHJ   P,6TOCHS
+       PUSH    TP,A
+       PUSH    TP,B
+       MOVE    A,(P)
+       PUSHJ   P,6TOCHS
+       PUSH    TP,A
+       PUSH    TP,B            ;GIVE HIM CHAR STRINGS OF MY NAME 1 AND 2 IF NOT DEFAULT
+       MOVEI   E,7             ;FOR ACALL INDICATING 6 ARGS TO THE IPC INTERRUPT HANDLER
+       JRST    .+2             ;SKIP OVER FIX FOR ONLY 4 ARGS TO IPC INTERRUPT
+IGFOUR:        MOVEI   E,5
+       SUB     P,[4,,4]        ;CLEAN UP OUR WHOLE WORLD
+       ACALL   E,INTERR        ;THATS IT FOLKS, THE REAL THING
+       JRST    DIRQ
+
+IGUG:  .SUSET  [.RMARPC,,0]
+       CAMN    0,[-1]
+        JRST   IGUGN           ; DISABLED, SO GO AWAY
+       SETZM   INTHLD          ; RE-ENABLEE INTERRUPTS
+       SUB     P,[2,,2]
+       MCALL   1,PARSE
+       SUB     TP,[2,,2]       ;FLUSH OFF STRING "IPC"
+       PUSH    TP,A
+       PUSH    TP,B
+       MCALL   1,EVAL
+       JRST    DIRQ
+
+\f
+IPCBLS:        PUSH    P,A
+       PUSH    P,B
+       PUSH    P,C
+       PUSH    P,D
+       PUSH    P,E                     ;PARANOIA STRIKES AGAIN
+       PUSH    P,0
+       MOVEI   E,0                     ;CRETIN ASSEMBLER
+       .SUSET  [.SMARPC,,E]
+       MOVEI   E,IPCS1                 ;BLESSES ALL CURRENTLY OPEN IPC CHANNELS
+       MOVEI   0,1
+IPCBL1:        SKIPN   B,1(E)
+       JRST    IPCBL2
+       HLLZS   (B)                     ;CLEAR OUT ANY PARTIAL BUFFER WE MAY HAVE
+       HRRZ    B,1(B)                  ;GET A POINTER TO THE OPEN BLOCK
+       MOVE    A,0                     ;GET THE CHANNEL NUMBER
+       HLL     A,(B)
+       MOVE    C,2(B)                  ;GET A POINTER TO THE BUFFER    
+       MOVEI   D,BUFL                  ;TO FIX UP THE BUFFER
+       MOVEM   D,2(C)                  ;FIX LENGTH UP RIGHT
+       SETZM   (C)
+       SETZM   1(C)                    ;FIX UP THE READ FROM FIELDS
+       DOTCAL  OPEN,[A,1(B),2(B),3(B),4(B)]
+       FATAL IPC DEVICE LOST
+IPCBL2:        ADDI    E,2
+       ADDI    0,1
+       CAIG    0,15.
+       JRST    IPCBL1                  ;IF ANY MORE GO BLESS THEM
+
+       POP     P,0
+       POP     P,E
+       POP     P,D
+       POP     P,C
+       POP     P,B
+       POP     P,A
+       POPJ    P,
+
+
+
+
+END
+\f\ 3\f
\ No newline at end of file