$CONTROL MAP,CODE,USLINIT                                               00010000
<< MESSAGE -- MODULDE 59 >>                                             00015000
<< HP32002C MPE SOURCE C.00.00 >>                                       00020000
$COPYRIGHT     "(C) COPYRIGHT HEWLETT-PACKARD CO. 1980. ",            & 00025000
$     "THIS PROGRAM MAY BE USED WITH ONE COMPUTER SYSTEM AT A ",      & 00030000
$     "TIME AND SHALL NOT OTHERWISE BE RECORDED, TRANSMITTED OR ",    & 00035000
$     "STORED IN A RETRIEVAL SYSTEM.  COPYING OR OTHER REPRODUCTION ",& 00040000
$     "OF THIS PROGRAM EXCEPT FOR ARCHIVAL PURPOSES IS PROHIBITED ",  & 00045000
$     "WITHOUT THE PRIOR WRITTEN CONSENT OF HEWLETT-PACKARD COMPANY."   00050000
$CONTROL SEGMENT=MESSAGE,MAIN=MESSAGE                                   00055000
BEGIN                                                                   00060000
COMMENT TABLE STRUCTURES TO SUPPORT NON-$STDLIST MESSAGES      <<02802>>00065000
                                                               <<02802>>00070000
MESSAGE BUFFERS DST - POINTED TO BY SYSGLOB %113               <<02802>>00075000
<<*****************************************************>>      <<02802>>00080000
<< WORD | DESCRIPTION                                  >>      <<02802>>00085000
<<*****************************************************>>      <<02802>>00090000
<< 0    | NUMBER OF BUFFERS IN THIS DST                >>      <<02802>>00095000
<< 1    | LENGTH OF BUFFERS IN THIS DST (128 CURRENTLY)>>      <<02802>>00100000
<< 2    | NEXT AVAILABLE BUFFER PTR - DST RELATIVE     >>      <<02802>>00105000
<< 3    | TAIL AVAILABLE BUFFER PTR - DST RELATIVE     >>      <<02802>>00110000
<< 4-N  | # OF BUFFERS * LENGTH OF BUFFER "BUFFER" AREA>>      <<02802>>00115000
<<      | WORD "0" OF EACH BUFFER IS AVAIL BUFFER LINK >>      <<02802>>00120000
<<*****************************************************>>      <<02802>>00125000
                                                               <<02802>>00130000
BUFFER IMPEDED QUEUE (BY PIN) - POINTED TO BY SYSGLOB %62      <<02802>>00135000
                                                               <<02802>>00140000
BASIC IPC (SENDMSG) MESSAGE FORMAT                             <<02802>>00145000
<<*****************************************************>>      <<02802>>00150000
<< WORD | DESCRIPTION                                  >>      <<02802>>00155000
<<*****************************************************>>      <<02802>>00160000
<< 0    | INTEGER "2" - MSG TYPE 2 TO IOMESSAGEPROC    >>      <<02802>>00165000
<< 1    | IOQ INDEX OF MESSAGE ATTACHIO TO TERMINAL    >>      <<02802>>00170000
<< 2    | MESSAGE BUFFER DST OFFSET OF BUFFER USED     >>      <<02802>>00175000
<< 3    | NOT USED, CURRENTLY "0"                      >>      <<02802>>00180000
<<*****************************************************>>      <<02802>>00185000
                                                               <<02802>>00190000
;                                                              <<02802>>00195000
                                                                        00200000
$INCLUDE INCLPCB5                                              <<06590>>00205000
LOGICAL POINTER PCB = SYSPCBINDEX;                             <<06590>>00210000
EQUATE                                                                  00215000
   QI      = 5,                                                         00220000
                                                                        00225000
   MSGBASE       = %1371,                                               00230000
   MSGSIR        = %24,                                                 00235000
   FISIR         = 37,                                         <<00820>>00240000
   SYSDISC       = 1,                                                   00245000
   SYSUP         = %1073,                                      <<01398>>00250000
   CONSOLECELL   = %1074,                                               00255000
   SYSDB         = 512,                                        <<00820>>00260000
   CLOADID       = SYSDB + %75,                                <<00820>>00265000
                                                               <<02802>>00270000
<< IF NUM'MSG'BUFS IS CHANGED, MUST ALSO CHANGE IN IOMSGPROC >><<02802>>00275000
   NUM'MSG'BUFS  =16,  <<NUMBER OF BUFFERS FOR MSG SYSTEM>>    <<02802>>00280000
   SBUFDSTN      = %10,                                                 00285000
   SBUFSIZEW     = 128,                                                 00290000
   SBUFSIZE      = 256,                                                 00295000
   SBUFSIZEWM1   = SBUFSIZEW -1;                                        00300000
DEFINE                                                         <<06877>>00305000
   SYS'CONSOLE'LDEV    =  ABSOLUTE(CONSOLECELL)#;              <<06877>>00310000
                                                                        00315000
DEFINE                                                                  00320000
   DISABLE = ASSEMBLE( SED 0) #,                                        00325000
   ENABLE  = ASSEMBLE( SED 1) #,                                        00330000
   PDISABLE= ASSEMBLE(PSDB)#,                                  <<02802>>00335000
   PENABLE = ASSEMBLE(PSEB)#,                                  <<02802>>00340000
                                                               <<02802>>00345000
   IOMSGQUEUE = ABSOLUTE(%1062)#, <<IMPEDED LIST HEAD FOR MSG>><<02802>>00350000
   IOMSGDST   = ABSOLUTE(%1113)#; << DST FOR MESSAGE BUFFERS >><<06590>>00355000
                                                               <<02802>>00360000
                                                                        00365000
<< Message layout Equates.  See also, SECTPERBLKD, below. >>   <<04362>>00370000
EQUATE                                                                  00375000
   CCG           = 0,                                                   00380000
   CCL           = 1,                                                   00385000
   CCE           = 2,                                                   00390000
                                                                        00395000
   HEADERSIZE    = 2,                                          <<00711>>00400000
   MAXNOSETS     = 62,                                         <<00711>>00405000
   MSGDIRSIZE    = HEADERSIZE + MAXNOSETS*2 + 2 <<WORK SPACE>>,<<00711>>00410000
   MAXSETNOCELL  = 0,                                          <<00711>>00415000
   MAXRECELL     = 1,                                          <<00711>>00420000
   CURRENTRECELL = MSGDIRSIZE - 1,                             <<00711>>00425000
   RECSIZE           = 40,                                              00430000
   RECSIZEB          = RECSIZE*2,                                       00435000
   RECSIZEM1         = RECSIZE -1,                                      00440000
   BUFFSIZE          = RECSIZE -4,                                      00445000
   BUFFSIZEM1        = BUFFSIZE -1,                                     00450000
   BUFFSIZEB         = BUFFSIZE*2,                                      00455000
   BLKFACTOR         = 16,                                              00460000
   PHYSBLK           = 16*40,                                           00465000
   SECTORPERBLK      = PHYSBLK/128,                                     00470000
                                                                        00475000
   ENDOFEQUATES      = 0;                                               00480000
                                                               <<04362>>00485000
<< Sectors per block DEFINEs used for Double arithmetic  >>    <<04362>>00490000
<< in READCAT.  See SECTORPERBLK equate, above.          >>    <<04362>>00495000
   DEFINE                                                      <<04362>>00500000
      SECTPERBLKD     = 5D #;                                  <<04362>>00505000
                                                               <<04362>>00510000
                                                                        00515000
INTEGER                                                                 00520000
   STATUS = Q-1,                                                        00525000
   S0 =S-0,                                                             00530000
   S6 = S-6,                                                            00535000
   X = X;                                                               00540000
                                                                        00545000
BYTE POINTER BPS0 = S-0;                                                00550000
POINTER PS0 = S-0;                                                      00555000
DOUBLE POINTER DPS0 = S-0;                                              00560000
                                                                        00565000
DEFINE                                                                  00570000
   MSGDSTN       = ABSOLUTE(MSGBASE+2)#,                                00575000
                                                                        00580000
   CONDCODE      = STATUS.(6:2)#,                                       00585000
   CCGRETN       = BEGIN                                                00590000
                      CONDCODE := CCG;                                  00595000
                      GO OUTL;                                          00600000
                   END#,                                                00605000
   CCLRETN       = BEGIN                                                00610000
                      CONDCODE := CCL;                                  00615000
                      GO OUTL;                                          00620000
                   END#,                                                00625000
   DEF'MOVEFROMDSEG =                                                   00630000
      MOVEFROMDSEG(TARGET,DSTN,OFFSET,COUNT);                           00635000
         VALUE TARGET,DSTN,OFFSET,COUNT;                                00640000
         LOGICAL TARGET,DSTN,OFFSET,COUNT;                              00645000
      BEGIN                                                             00650000
         X := TOS; << SAVE RETURN ADDRESS >>                            00655000
         ASSEMBLE(MFDS 0);                                              00660000
         TOS := X; << RESTORE RETURN ADDRESS >>                         00665000
      END #,                                                            00670000
                                                                        00675000
   DEF'MOVETODSEG =                                                     00680000
      MOVETODSEG(DSTN,OFFSET,SOURCE,COUNT);                             00685000
         VALUE DSTN,OFFSET,SOURCE,COUNT;                                00690000
         LOGICAL DSTN,OFFSET,SOURCE,COUNT;                              00695000
      BEGIN                                                             00700000
         X := TOS;                                                      00705000
         ASSEMBLE(MTDS 0);                                              00710000
         TOS := X;                                                      00715000
      END#;                                                    << 7469>>00720000
                                                                        00725000
                                                                        00730000
                                                                        00735000
<< END GLOBAL DECLS >>                                                  00740000
                                                                        00745000
        << HERE ARE THE PARM MASK DEFINITIONS >>                        00750000
        << FOR GENMSG & FORMSG PMASKS         >>                        00755000
LOGICAL                                                                 00760000
   PMASK = Q-4;                                                         00765000
DEFINE PCB'REPLYDONE = 3#;                                     <<06590>>00770000
                                                                        00775000
DEFINE                                                                  00780000
   PSETNO  = ( 3:1) #,                                                  00785000
   PMSGNO  = ( 4:1) #,                                                  00790000
   PPMASK  = ( 5:1) #,                                                  00795000
   PDEST   = (11:1) #,                                                  00800000
   PREPLY  = (12:1) #,                                                  00805000
   POFFSET = (13:1) #,                                                  00810000
   PDST    = (14:1) #,                                                  00815000
   PCONTROL = (15:1) #;                                                 00820000
$INCLUDE INCLPXG                                               << 7469>>00825000
$INCLUDE INCLJIT                                               << 7469>>00830000
$INCLUDE INCLRIT                                               <<04882>>00835000
$INCLUDE INCLLPDT                                              <<06224>>00840000
<< APL FUNNY TERMINAL STUFF >>                                          00845000
DEFINE FUNNYTERM = (2:2)#;                                              00850000
                                                               <<01646>>00855000
EQUATE GENERALSET=1;                                           <<04882>>00860000
EQUATE REPLYWOKEN=293;                                        <<<04882>>00865000
EQUATE REPLYIMPEDED=294;                                      <<<04882>>00870000
EQUATE QUEUEFULL=295;                                         <<<04882>>00875000
EQUATE TELLUSER'NOROOM =296;                                  <<<04882>>00880000
EQUATE TELLOP'QUEUED'USER = 297;                               <<04882>>00885000
                                                               <<01646>>00890000
EQUATE                                                                  00895000
   JMATX        = 3; << index of JMAT in PXGLOBAL >>           <<06592>>00900000
                                                               <<06592>>00905000
$SET X8=OFF                                                    <<06592>>00910000
$INCLUDE INCLJMAT                                              <<06592>>00915000
                                                               <<06592>>00920000
                                                               <<01646>>00925000
DEFINE  MYPIN = CURPRC/PCBSIZE#;                               <<06590>>00930000
                                                                        00935000
<< ASSOCIATION TABLE DEFINITIONS >>                            <<01646>>00940000
                                                               <<01646>>00945000
EQUATE                                                         <<01646>>00950000
   ASS'SIR = 24,       << SIR # FOR ASSOCIATION TABLE >>       <<01646>>00955000
   ASS'DST = 34,       << DST # FOR ASSOCIATION TABLE >>       <<01646>>00960000
   ASS'ENTRYSIZE = 7;  << SIZE OF ONE ENTRY IN TABLE  >>       <<01646>>00965000
                                                               <<01646>>00970000
DEFINE                                                         <<01646>>00975000
   ASS'JMAT = 0).(8:8#;      << JMAT INDEX >>                  <<01646>>00980000
                                                               <<01646>>00985000
                                                                        00990000
<< EXTERNAL DECLARATIONS >>                                             00995000
PROCEDURE SETLOCKSTATUS(LABELADDR,PURGEOK);                    <<06591>>01000000
   VALUE LABELADDR,PURGEOK;                                    <<06591>>01005000
   DOUBLE LABELADDR;                                           <<06591>>01010000
   LOGICAL PURGEOK;                                            <<06591>>01015000
   OPTION UNCALLABLE,PRIVILEGED,EXTERNAL;                      <<06591>>01020000
                                                               <<06591>>01025000
                                                                        01030000
PROCEDURE APLTRANSLATEOUT(MESSAGE,LENGTH,TRANSTYPE);                    01035000
   VALUE LENGTH,TRANSTYPE;INTEGER LENGTH,TRANSTYPE;                     01040000
   BYTE ARRAY MESSAGE;OPTION EXTERNAL;                                  01045000
                                                                        01050000
INTRINSIC ASCII,BINARY,DASCII,PRINT,FWRITE,FCHECK,FOPEN,                01055000
   FGETINFO,FREADLABEL,FCLOSE;                                          01060000
                                                                        01065000
PROCEDURE AWAKE(PIN,AF,WF);VALUE PIN,AF,WF;                             01070000
   INTEGER PIN,AF,WF;OPTION EXTERNAL;                                   01075000
                                                                        01080000
DOUBLE PROCEDURE ATTACHIO(A,B,C,D,E,F,G,H,I);                           01085000
   VALUE A,B,C,D,E,F,G,H,I;                                             01090000
   LOGICAL A,B,C,D,E,F,G,H,I;                                           01095000
   OPTION EXTERNAL;                                                     01100000
                                                                        01105000
PROCEDURE ERRORON; OPTION EXTERNAL;                                     01110000
                                                               <<01998>>01115000
   LOGICAL PROCEDURE JOBSESSIONMAIN;                           <<01998>>01120000
   OPTION UNCALLABLE,EXTERNAL;                                 <<01998>>01125000
                                                                        01130000
PROCEDURE ERROREXIT(INTRINEXIT,ERRWORD,PARAM);                          01135000
   VALUE INTRINEXIT,ERRWORD,PARAM;                                      01140000
   LOGICAL INTRINEXIT,ERRWORD,PARAM;                                    01145000
   OPTION EXTERNAL;                                                     01150000
                                                                        01155000
INTEGER PROCEDURE EXCHANGEDB(DSTX);                                     01160000
   VALUE DSTX; LOGICAL DSTX; OPTION EXTERNAL;                           01165000
PROCEDURE FGETCB (NEWVECTOR,DST,CB,VECTOR,FLAGS,S1,O1,S2,O2);  <<01391>>01170000
   VALUE NEWVECTOR,DST,CB,VECTOR,FLAGS,S1,O1,S2,O2;            <<01391>>01175000
   INTEGER NEWVECTOR,DST,VECTOR,S1,O1,S2,O2;                   <<01391>>01180000
   INTEGER POINTER CB;                                         <<00820>>01185000
   LOGICAL FLAGS;                                              <<00820>>01190000
   OPTION VARIABLE,EXTERNAL;                                   <<01391>>01195000
                                                               <<00820>>01200000
INTEGER PROCEDURE FLABIO (LDEV,SECTOR,FUNC,FLAB);              <<00820>>01205000
   VALUE LDEV,SECTOR,FUNC;                                     <<00820>>01210000
   INTEGER LDEV,FUNC;                                          <<00820>>01215000
   DOUBLE SECTOR;                                              <<00820>>01220000
   INTEGER ARRAY FLAB;                                         <<00820>>01225000
   OPTION PRIVILEGED,UNCALLABLE,EXTERNAL;                      <<00820>>01230000
                                                               <<00820>>01235000
PROCEDURE FRELCB (DST,VECTOR,FLAGS);                           <<00820>>01240000
   VALUE DST,VECTOR,FLAGS;                                     <<00820>>01245000
   INTEGER DST,VECTOR;                                         <<00820>>01250000
   LOGICAL FLAGS;                                              <<00820>>01255000
   OPTION PRIVILEGED,UNCALLABLE,EXTERNAL;                      <<00820>>01260000
                                                               <<00820>>01265000
                                                                        01270000
INTEGER PROCEDURE GETDATASEG(MEMSIZE,VDSIZE);                           01275000
   VALUE MEMSIZE,VDSIZE;                                                01280000
   INTEGER MEMSIZE,VDSIZE;                                              01285000
   OPTION EXTERNAL;                                                     01290000
                                                                        01295000
INTEGER PROCEDURE GETSIR(SIRNUM);                                       01300000
   VALUE SIRNUM; LOGICAL SIRNUM; OPTION EXTERNAL;                       01305000
                                                                        01310000
INTEGER PROCEDURE GETSYSBUF(NUM,IFLAG);VALUE NUM,IFLAG;                 01315000
   INTEGER NUM;LOGICAL IFLAG;OPTION EXTERNAL;                           01320000
                                                                        01325000
PROCEDURE IMPEDE(PINX);                                                 01330000
   VALUE PINX; INTEGER PINX; OPTION EXTERNAL;                           01335000
                                                                        01340000
   PROCEDURE LOG15(I,J,K,L);                                   <<KS.01>>01345000
   VALUE I,J,K,L;                                              <<KS.01>>01350000
   LOGICAL I,J,K,L;                                            <<KS.01>>01355000
   OPTION EXTERNAL;                                            <<KS.01>>01360000
                                                               <<04882>>01365000
                                                               <<00820>>01370000
PROCEDURE RELDATASEG(DSTNUM);                                  <<00820>>01375000
   VALUE DSTNUM;                                               <<00820>>01380000
   INTEGER DSTNUM;                                             <<00820>>01385000
   OPTION EXTERNAL;                                            <<00820>>01390000
                                                               <<00820>>01395000
INTEGER PROCEDURE RELSIR(SIRNUM,A);                                     01400000
   VALUE SIRNUM,A; LOGICAL SIRNUM,A; OPTION EXTERNAL;                   01405000
                                                               <<07395>>01410000
PROCEDURE STACKMARK( WHICH, DELQ, STAT, RELP, XREG );          <<07395>>01415000
   VALUE   WHICH;                                              <<07395>>01420000
   INTEGER WHICH, DELQ, STAT, RELP, XREG;                      <<07395>>01425000
OPTION VARIABLE, EXTERNAL;                                     <<07395>>01430000
                                                               <<07395>>01435000
                                                                        01440000
PROCEDURE SENDMSG(DESTPIN,DESTPORT,MSGLENGTH,FLAGS);           <<02802>>01445000
VALUE DESTPIN,DESTPORT,MSGLENGTH,FLAGS;                        <<02802>>01450000
INTEGER DESTPIN,DESTPORT,MSGLENGTH;                            <<02802>>01455000
LOGICAL FLAGS;                                                 <<02802>>01460000
OPTION EXTERNAL;                                               <<02802>>01465000
                                                               <<02802>>01470000
INTEGER PROCEDURE SETCRITICAL;                                 <<02802>>01475000
OPTION EXTERNAL;                                               <<02802>>01480000
                                                               <<02802>>01485000
PROCEDURE RESETCRITICAL(CRIT);                                 <<02802>>01490000
VALUE CRIT;                                                    <<02802>>01495000
INTEGER CRIT;                                                  <<02802>>01500000
OPTION EXTERNAL;                                               <<02802>>01505000
                                                               <<02802>>01510000
PROCEDURE SUDDENDEATH(A);VALUE A;INTEGER A;OPTION EXTERNAL;             01515000
                                                                        01520000
PROCEDURE WAIT(A,B);                                                    01525000
   VALUE A,B; LOGICAL A,B; OPTION EXTERNAL;                             01530000
                                                                        01535000
<< FORWARD DECLARATIONS >>                                              01540000
                                                                        01545000
INTEGER PROCEDURE CONSPREFIX(CONSREPLY,BUFF');                          01550000
   VALUE CONSREPLY;                                                     01555000
   LOGICAL CONSREPLY;                                                   01560000
   ARRAY BUFF';                                                         01565000
   OPTION FORWARD;                                                      01570000
                                                                        01575000
INTEGER PROCEDURE GENMSG(A,B,C,D,E,F,G,H,I,J,K,L,M);                    01580000
   VALUE A,B,C,D,E,F,G,H,I,J,K,L,M;INTEGER A,B,I,L;                     01585000
   LOGICAL C,D,E,F,G,H,J,K,M;OPTION VARIABLE,FORWARD;                   01590000
                                                                        01595000
<< PROCEDURES >>                                                        01600000
LOGICAL PROCEDURE PUT'IN'RIT'QUEUE(PINX);                      <<04882>>01605000
VALUE PINX;                                                    <<04882>>01610000
INTEGER PINX;                                                  <<04882>>01615000
OPTION PRIVILEGED,UNCALLABLE;                                  <<04882>>01620000
<< This procedure is designed to queue entries that were  >>   <<04882>>01625000
<< unable to be put in the Reply Information Table because>>   <<04882>>01630000
<< it was full.  If there is room in the queue then the   >>   <<04882>>01635000
<< PIN for that process will be placed in the queue.  If  >>   <<04882>>01640000
<< there is no room then the PIN will not be put in the   >>   <<04882>>01645000
<< queue and messages will be sent to the console and User>>   <<04882>>01650000
                                                               <<04882>>01655000
 BEGIN                                                         <<04882>>01660000
    INTEGER ARRAY RITABLE(*) = DB+0;                           <<04882>>01665000
   INTEGER NUMQUEUED;                                          <<04882>>01670000
                                                               <<04882>>01675000
PUT'IN'RIT'QUEUE := TRUE;                                      <<04882>>01680000
IF RITABLE(QUEUED'ENTRIES) <  MAX'QUEUED'ENTRIES THEN          <<04882>>01685000
   BEGIN                                                       <<04882>>01690000
     RITABLE(RITABLE(LIQ)) := PINX;                            <<04882>>01695000
     RITABLE(LIQ) := RITABLE(LIQ) + 1;                         <<04882>>01700000
     RITABLE(QUEUED'ENTRIES) := RITABLE(QUEUED'ENTRIES) + 1;   <<04882>>01705000
     NUMQUEUED := RITABLE(QUEUED'ENTRIES);                     <<04882>>01710000
     << This is decremented in REM'QUEUED'ENTRY           >>   <<04882>>01715000
     EXCHANGEDB(0);                                            <<04882>>01720000
     GENMSG(GENERALSET,REPLYIMPEDED); << TELL USER HE IS QUEUED<<04882>>01725000
     GENMSG(GENERALSET,TELLOP'QUEUED'USER,%10000,NUMQUEUED,    <<04882>>01730000
           ,,,,0);                                             <<04882>>01735000
   END                                                         <<04882>>01740000
   ELSE BEGIN << NO ROOM IN QUEUE >>                           <<04882>>01745000
          PUT'IN'RIT'QUEUE := FALSE;                           <<04882>>01750000
          EXCHANGEDB(0);                                       <<04882>>01755000
          GENMSG(GENERALSET,QUEUEFULL,,,,,,,0);                <<04882>>01760000
          GENMSG(GENERALSET,TELLUSER'NOROOM)                   <<04882>>01765000
          END;                                                 <<04882>>01770000
END; << PUT'IN'RIT'QUEUE >>                                    <<04882>>01775000
                                                                        01780000
$page                                                          << 7592>>01785000
                                                                        01790000
LOGICAL PROCEDURE PUTRITENTRY( PINX, DST, OFFSET, REPLY,       << 7592>>01795000
                              LEN, BUFF', SIRN );              << 7592>>01800000
   VALUE PINX,DST,OFFSET,REPLY,LEN;                                     01805000
   INTEGER PINX,DST,OFFSET,REPLY,LEN,SIRN;                     << 7592>>01810000
   ARRAY BUFF';                                                         01815000
   OPTION INTERNAL;                                                     01820000
COMMENT                                                                 01825000
   PLACES ENTRY IN RIT. SEARCHES THROUGH RIT & USES FIRST               01830000
   AVAILABLE ENTRY. IF NONE AVAILABLE, THIS PROCESS IS                  01835000
   IS PUT INTO A QUEUE BY A CALL TO PUT'IN'RIT'QUEUE AND THEN  <<04882>>01840000
   IT IS IMPEDED UNTIL A REPLY CALLS REM'QUEUED'ENTRY WHICH    <<04882>>01845000
   WILL WAKE THE PROCESS THATS BEEN QUEUED THE LONGEST         <<04882>>01850000
   THE AWOKEN PROCESS WILL THEN ATTEMPT TO ENTER THE RIT TABLE <<04882>>01855000
                                                               << 7592>>01860000
   Fix note:                                                   << 7592>>01865000
                                                               << 7592>>01870000
   PUTRITENTRY now takes the RIT SIR and does not release it if<< 7592>>01875000
   an entry is successfully placed in the RIT.  GENMSG will    << 7592>>01880000
   release the SIR before it WAITS for the reply.  If the entry<< 7592>>01885000
   cannot be entered, then the SIR is released.                << 7592>>01890000
                                                               << 7592>>01895000
   Note that PUTRITENTRY may NOT be called with someone else   << 7592>>01900000
   holding the RIT SIR since it releases the SIR and impedes   << 7592>>01905000
   if the RIT is full.                                         << 7592>>01910000
;                                                                       01915000
                                                               << 7592>>01920000
BEGIN                                                                   01925000
INTEGER                                                                 01930000
   INDEX;                                                               01935000
                                                                        01940000
LOGICAL NOPROBLEM;                                             <<04882>>01945000
INTEGER ARRAY RITABLE(*) = DB+0;                                        01950000
LOGICAL PCBPT;                                                 <<06590>>01955000
                                                                        01960000
SUBROUTINE DEF'MOVETODSEG;                                              01965000
                                                                        01970000
<< FILL IN RITDESCRIPTOR >>                                             01975000
   SIRN := 0;                                                  <<04811>>01980000
   BUFF' := PINX;                                                       01985000
   IF DST <> 0 THEN BUFF'(1) := DST                                     01990000
   ELSE                                                                 01995000
   BEGIN << COMPUTE SEG. REL. ADR. OF OFFSET >>                         02000000
      DISABLE;                                                          02005000
      TOS := ABSOLUTE( ABSOLUTE( QI ) -5);                              02010000
      TOS := ABSOLUTE(X := X-4) +1;                                     02015000
      ASSEMBLE( LSEA );                                                 02020000
      INDEX := TOS;                                                     02025000
      DDEL;                                                             02030000
      BUFF'(1) := ABSOLUTE(X:= X-7); << STACK DST # >>                  02035000
      ENABLE;                                                           02040000
      OFFSET := OFFSET+ INDEX;                                          02045000
   END;                                                                 02050000
   BUFF'(2) := OFFSET;                                                  02055000
   BUFF'(3) := REPLY;                                                   02060000
   BUFF'(6) := 0;  << CONTROL WORD. (VESTIGIAL) >>                      02065000
   BUFF'(RIT'MSGLEN) := IF LEN > RIT'MSGSIZE THEN RIT'MSGSIZE  <<04882>>02070000
      ELSE LEN;                                                         02075000
                                                                        02080000
AGAIN:                                                                  02085000
NOPROBLEM := TRUE; << ASSUME IT WILL WORK >>                   <<04882>>02090000
PCBPT := CURPRC;                                               <<06590>>02095000
IF PROCSTATE.SOFTKILLFLAG = 1                                  <<06590>>02100000
   THEN BEGIN                                                  <<04882>>02105000
        << SOFTKILL BIT IS SET ON >>                           <<04882>>02110000
        NOPROBLEM := FALSE;                                    <<04882>>02115000
        GO AROUND;                                             <<04882>>02120000
        END;                                                   <<04882>>02125000
SIRN := GETSIR(RIT'SIR);     << use temp variable because>>    <<*7797>>02130000
EXCHANGEDB(RIT'DST);                                           <<04882>>02135000
                             << we're in split stack mode>>    <<*7589>>02140000
IF RITABLE = RITABLE(RIT'HEAD'MAXENT) THEN << TABLE FULL >>    <<04882>>02145000
BEGIN                                                                   02150000
   NOPROBLEM := PUT'IN'RIT'QUEUE(PINX);                        <<04882>>02155000
   << using SIRN in the RELSIR works because the procedure>>   <<*7797>>02160000
   << PUT'IN'RIT'QUEUE always does an EXCHANGEDB(0) so we >>   <<*7797>>02165000
   << are back at this DB, not the RITs, when we return   >>   <<*7797>>02170000
   << from PUT'IN'RIT'QUEUE.                              >>   <<*7797>>02175000
                                                               <<*7797>>02180000
   RELSIR(RIT'SIR,SIRN);                                       <<*7797>>02185000
   IF NOPROBLEM THEN                                           <<04882>>02190000
      BEGIN                                                    <<04882>>02195000
        WAIT(%40,0);                                           <<04882>>02200000
        GENMSG(GENERALSET,REPLYWOKEN);                         <<04882>>02205000
        GO AGAIN;  << TRY AGAIN >>                             <<04882>>02210000
        END;                                                   <<04882>>02215000
END;                                                                    02220000
AROUND:                                                        <<04882>>02225000
IF NOPROBLEM                                                   <<04882>>02230000
   THEN BEGIN                                                  <<04882>>02235000
          RITABLE := RITABLE + 1;                              <<04882>>02240000
          INDEX := RIT'HEADSIZE - RIT'SIZE;                    <<04882>>02245000
                                                               <<04882>>02250000
          DO INDEX := INDEX + RIT'SIZE UNTIL RITABLE(INDEX)=0; <<04882>>02255000
          << FOUND EMPTY ENTRY >>                              <<04882>>02260000
          EXCHANGEDB(0);                                       <<04882>>02265000
          MOVETODSEG(RIT'DST,INDEX,@BUFF',RIT'SIZE);           <<04882>>02270000
          END                                                  <<04882>>02275000
       ELSE EXCHANGEDB(0);                                     <<04882>>02280000
       PUTRITENTRY := NOPROBLEM;                               <<04882>>02285000
                                                                        02290000
END; << PUTRITENTRY >>                                                  02295000
$TITLE "LENBUF - FINDS LENGTH, CRLF & CONTINUED"                        02300000
PROCEDURE LENBUF(BUFF,LEN,CRLF,RECNO);                                  02305000
   BYTE ARRAY BUFF;                                                     02310000
   INTEGER LEN;                                                <<02340>>02315000
   DOUBLE RECNO;                                               <<02340>>02320000
   LOGICAL CRLF;                                                        02325000
   OPTION INTERNAL;                                                     02330000
BEGIN                                                                   02335000
                                                                        02340000
                                                                        02345000
INTEGER SUBROUTINE DEBLANK(BUFF,WIDTH);                                 02350000
   VALUE WIDTH; INTEGER WIDTH;                                          02355000
   BYTE ARRAY BUFF;                                                     02360000
COMMENT                                                                 02365000
   DEBLANKS ON RIGHT                                                    02370000
;                                                                       02375000
BEGIN                                                                   02380000
                                                                        02385000
X := WIDTH -1;                                                          02390000
IF BUFF(X) <> " " THEN DEBLANK := WIDTH                                 02395000
ELSE                                                                    02400000
BEGIN                                                                   02405000
   TOS := @BUFF(X);                                                     02410000
   ASSEMBLE(DUP,DECA);                                                  02415000
   TOS := -X;                                                           02420000
   ASSEMBLE(CMPB 0);                                                    02425000
   S6 := -TOS;  << DEBLANK := -TOS >>                                   02430000
   DDEL;                                                                02435000
END;                                                                    02440000
                                                                        02445000
END; << DEBLANK >>                                                      02450000
                                                                        02455000
   << FIND LENGTH OF MSG & IF CONTINUED ON NEXT REC >>                  02460000
CRLF := 0;                                                              02465000
LEN := DEBLANK(BUFF,BUFFSIZEB);                                         02470000
IF BUFF(X:=LEN-1) = "&" OR BUFF(X) = "%" THEN                           02475000
BEGIN                                                                   02480000
   IF BUFF(X) = "&" THEN CRLF := %320;                                  02485000
   RECNO := RECNO + 1D; << CONTINUED ON NEXT RECORD >>         <<02340>>02490000
      << NOW FIND LENGTH WITHOUT % OR & >>                              02495000
   LEN := DEBLANK(BUFF,LEN -1);                                         02500000
END                                                                     02505000
ELSE  RECNO := 0D;  << NOT CONTINUED >>                        <<02340>>02510000
                                                                        02515000
END; <<  LENBUF >>                                                      02520000
$TITLE "READCAT"                                                        02525000
PROCEDURE READCAT( RECNO, BUFF', RECNOLO, RECNOHI );           <<04707>>02530000
   VALUE RECNO, RECNOLO, RECNOHI;                              <<04707>>02535000
   DOUBLE RECNO, RECNOLO, RECNOHI;                             <<04707>>02540000
   ARRAY BUFF';                                                         02545000
   OPTION UNCALLABLE;                                                   02550000
                                                                        02555000
COMMENT                                                                 02560000
   READS A RECORD FROM THE MESSAGE CATALOG.                             02565000
   RECNO - RECORD NUMBER. NO CHECKING DONE ON THIS NO.                  02570000
   BUFF' - BUFFER AS LARGE AS RECORD SIZE                               02575000
   CCE     EVERYTHING OK.                                               02580000
   CCL     ATTACHIO FAIL.                                               02585000
                                                               <<04707>>02590000
The ATTACHIO call in this procedure is optimized for the MPE   <<04707>>02595000
Message facility.  This is indicated by the special values in  <<04707>>02600000
the Flags parameter.  This special call requires a base sector <<04707>>02605000
address and a number of sectors in extent to be stacked before <<04707>>02610000
the call--thus, RECNOLO and RECNOHI are the limits of the      <<04707>>02615000
search for the message.  When these parameters are zero, there <<04707>>02620000
is no block search specified, and dummy values are given to the<<04707>>02625000
ATTACHIO call.                                                 <<04707>>02630000
                                                               <<04707>>02635000
;                                                                       02640000
BEGIN                                                                   02645000
                                                                        02650000
EQUATE                                                         <<04707>>02655000
   ATFLAGS = %100001;                                          <<04707>>02660000
                                                               <<04707>>02665000
DOUBLE                                                         <<04707>>02670000
   ATRETURN;                                                   <<04707>>02675000
                                                               <<04707>>02680000
INTEGER                                                        <<04707>>02685000
   ATRETSTAT = ATRETURN;                                       <<04707>>02690000
                                                               <<04707>>02695000
INTEGER                                                                 02700000
   CURRENTREC,                                                          02705000
   SECTS'IN'EXT,     << Sectors in extent (for attachio). >>   <<04707>>02710000
   OFFSET = CURRENTREC,                                                 02715000
   RECOFFSET;                                                           02720000
BYTE ARRAY BUFF(*)=BUFF';                                               02725000
<< Variables for message disc address calculations.  >>        <<04362>>02730000
                                                               <<04707>>02735000
DOUBLE TEMPADRD;     << For calculating sector addresses. >>   <<04707>>02740000
INTEGER TEMPADRHI  = TEMPADRD,                                 <<04707>>02745000
        TEMPADRLO  = TEMPADRD + 1;                             <<04707>>02750000
                                                               <<04707>>02755000
DOUBLE BASEADR,      << Base sector address for search.   >>   <<04707>>02760000
       HIGHADR,      << Limit sector address for search.  >>   <<04707>>02765000
       DISCADR;      << Target sector address.            >>   <<04707>>02770000
                                                               <<04707>>02775000
INTEGER  DISCADHI = DISCADR,                                   <<04707>>02780000
         DISCADLO = DISCADR + 1;                               <<04707>>02785000
                                                               <<04707>>02790000
                                                                        02795000
SUBROUTINE DEF'MOVEFROMDSEG;                                            02800000
                                                                        02805000
SUBROUTINE DEF'MOVETODSEG;                                              02810000
                                                                        02815000
DOUBLE SUBROUTINE SECTOR( REC );                               <<04707>>02820000
   VALUE REC;                                                  <<04707>>02825000
   DOUBLE REC;                                                 <<04707>>02830000
BEGIN                                                          <<04707>>02835000
                                                               <<04707>>02840000
<< Calculate a record's disc sector address.  First its   >>   <<04707>>02845000
<< sector offset is calculated (note: "//" is double      >>   <<04707>>02850000
<< divide), and this is added to the SYSGLOB message base.>>   <<04707>>02855000
   OFFSET := INTEGER(                                          <<04707>>02860000
                DOUBLE( REC // LOGICAL(BLKFACTOR) )            <<04707>>02865000
                * SECTPERBLKD                                  <<04707>>02870000
                + SECTPERBLKD           );                     <<04707>>02875000
   TEMPADRHI := INTEGER( ABSOLUTE( MSGBASE ).(8:8) );          <<04707>>02880000
   TEMPADRLO := ABSOLUTE( MSGBASE+1 );                         <<04707>>02885000
   TEMPADRD  := TEMPADRD + DOUBLE( OFFSET );                   <<04707>>02890000
   SECTOR := TEMPADRD;                                         <<04707>>02895000
                                                               <<04707>>02900000
END;                                                           <<04707>>02905000
                                                               <<04707>>02910000
                                                                        02915000
CONDCODE := CCE;                                                        02920000
                                                                        02925000
<< GET CURRENT RECORD, SEE IF RECNO IS IN DSEG >>                       02930000
                                                                        02935000
MOVEFROMDSEG(@CURRENTREC,MSGDSTN,CURRENTRECELL,1);                      02940000
IF (RECNO >= DOUBLE(CURRENTREC)) AND                           <<02340>>02945000
   (RECNO <= DOUBLE(CURRENTREC+BLKFACTOR-1)) THEN              <<02340>>02950000
ELSE << GO GET IT >>                                                    02955000
BEGIN                                                                   02960000
   << OFFSET OF LOG. REC. IN BLOCK >>                          <<02340>>02965000
   RECOFFSET := INTEGER(RECNO MODD LOGICAL(BLKFACTOR));        <<02340>>02970000
   DISCADR := SECTOR( RECNO );                                 <<04707>>02975000
   IF RECNOLO = 0D THEN    << No search block specified. >>    <<04707>>02980000
   BEGIN                                                       <<04707>>02985000
      BASEADR := DISCADR - 1D;                                 <<04707>>02990000
      SECTS'IN'EXT := 2;                                       <<04707>>02995000
   END                                                         <<04707>>03000000
   ELSE                                                        <<04707>>03005000
   BEGIN                   << Calculate search limits.   >>    <<04707>>03010000
      BASEADR := SECTOR( RECNOLO );                            <<04707>>03015000
      SECTS'IN'EXT := INTEGER(SECTOR(RECNOHI)-BASEADR) + 1;    <<04707>>03020000
   END;                                                        <<04707>>03025000
   TOS := BASEADR;   << Stacked parms for ATTACHIO       >>    <<04707>>03030000
   TOS := SECTS'IN'EXT;                                        <<04707>>03035000
   ATRETURN := ATTACHIO( ABSOLUTE(MSGBASE).(0:8), 0, MSGDSTN,  <<04707>>03040000
      MSGDIRSIZE, 0, PHYSBLK,                                  <<04707>>03045000
      DISCADHI, DISCADLO, ATFLAGS );                           <<04707>>03050000
   DDEL; DEL;  << Pop Attachio stacked parms >>                <<04707>>03055000
   IF ATRETSTAT.(8:8) <> 1 THEN CCLRETN;                       <<04707>>03060000
                                                                        03065000
   << UPDATE CURRENT RECORD PTR IN DSEG >>                              03070000
   CURRENTREC := INTEGER(RECNO // LOGICAL(BLKFACTOR))          <<02340>>03075000
                 * BLKFACTOR;                                  <<02340>>03080000
   MOVETODSEG(MSGDSTN,CURRENTRECELL,@CURRENTREC,1);                     03085000
END;                                                                    03090000
                                                                        03095000
   << RECNO IN DSEG. MOVE TO STACK >>                                   03100000
MOVEFROMDSEG(@BUFF',MSGDSTN,INTEGER(RECNO-DOUBLE(CURRENTREC))  <<02340>>03105000
       * RECSIZE + MSGDIRSIZE,BUFFSIZE);                       <<02340>>03110000
                                                                        03115000
                                                                        03120000
OUTL:                                                                   03125000
END; << READCAT >>                                                      03130000
                                                               <<00820>>03135000
                                                               <<00820>>03140000
$TITLE "FINDMSG"                                                        03145000
DOUBLE PROCEDURE FINDMSG(SETNO,MSGNO,BUFF',LEN,CRLF);          <<02340>>03150000
   VALUE SETNO,MSGNO;                                                   03155000
   INTEGER SETNO,MSGNO,LEN;                                             03160000
   ARRAY BUFF';                                                         03165000
   LOGICAL CRLF;                                                        03170000
   OPTION INTERNAL;                                                     03175000
COMMENT                                                                 03180000
   FETCHES ONE LINE OF MESSAGE FROM MSG CATALOG. TRANSFORMS             03185000
   SETNO & MSGNO INTO RECORD NUMBER & CALLS READCAT TO GET              03190000
   MSG.  REC NO. IS CALCULATED BY FINDING STARTING RECORD               03195000
   NUMBER OF FIRST MESSAGE IN DIRECTORY & ADDING IN THE                 03200000
   DIFFERENCE BETWEEN MSGNO & FIRST MSG NO. IN CATALOG                  03205000
   (ALSO IN DIRECTORY). IF THE MSG FOUND IN THE CATALOG                 03210000
   IS NOT THE ONE DESIRED, A BINARY SEARCH IS THEN DONE.                03215000
   BUFF' MUST BE AT LEAST AS LARGE AS RECORD SIZE.                      03220000
PARAMETERS                                                              03225000
   SETNO  = SETNO FROM GENMSG.                                          03230000
   MSGNO  = MSGNO FROM GENMSG.                                          03235000
   BUFF'  = ARRAY FOR MESSAGE. MUST BE "BUFFSIZE".                      03240000
   LEN    = LENGTH OF MESSAGE IN POSITIVE BYTES.                        03245000
   CRLF   = %320 CONTINUE WITH NO CRLF.                                 03250000
          = 0 CONTINUE NEXT MSG. AFTER CRLF.                            03255000
RETURNS                                                                 03260000
   - LEN IS THE LENGTH OF THE MESSAGE.                                  03265000
   - FINDMSG IS THE RECORD NUMBER OF THE CONTINUED MSG. 0               03270000
     INDICATES NO CONTINUATION.                                         03275000
   - CCG SET NUMBER OF 0, NON-EXISTENT SET OR MESSAGE.                  03280000
   - CCL READCAT FAILED (ATTATCHIO ERROR)                               03285000
;                                                                       03290000
BEGIN                                                                   03295000
   INTEGER ARRAY RECNO'ARRAY(0:2)=Q;                                    03300000
   INTEGER ARRAY HEAD'ARRAY(0:1) =Q;                                    03305000
                                                                        03310000
   INTEGER                                                              03315000
      MAXSETNO = HEAD'ARRAY,    << MAXSETNOCELL >>                      03320000
      NUMRECS  = HEAD'ARRAY +1, << MAXRECELL >>                         03325000
      MSGNOLEN = MAXSETNO;      << MAXSETNO OVERLAID >>        <<02340>>03330000
   LOGICAL                                                              03335000
      SIRN;                                                             03340000
                                                                        03345000
  DOUBLE                                                       <<02340>>03350000
      RECNO'LO,                 << SET'ROFFSET >>              <<02340>>03355000
      RECNO,                    << SET'FIRST'MSG >>            <<02340>>03360000
      RECNO'HI,                 << NEXT'SET'ROFFSET >>         <<02340>>03365000
      RECBND,                                                  <<02340>>03370000
      DUMRECNO,                                                <<02340>>03375000
      RECNO'NEW;                                               <<02340>>03380000
                                                               <<02340>>03385000
   INTEGER                                                              03390000
      VECTOR;                                                           03395000
   BYTE ARRAY BUFF(*)=BUFF';                                            03400000
                                                                        03405000
SUBROUTINE DEF'MOVEFROMDSEG;                                            03410000
                                                                        03415000
INTEGER SUBROUTINE CHKMSGNO(RECTEST);                                   03420000
   VALUE RECTEST;                                                       03425000
   DOUBLE RECTEST;                                             <<02340>>03430000
COMMENT                                                                 03435000
   READS CATALOG & CHECKS TO SEE IF LINE CONTAINS MESSAGE NO.           03440000
   SETS MSGNOLEN.                                                       03445000
;                                                                       03450000
BEGIN                                                                   03455000
      << TEST RECNO LIMITS.MISSING MSGNO WILL FAIL, SINCE >>            03460000
      << LO & HI LIMITS CONTRACT >>                                     03465000
                                                                        03470000
      IF (RECTEST >= RECNO'LO) AND (RECTEST <= RECNO'HI) THEN  <<02340>>03475000
      BEGIN                                                             03480000
         READCAT(RECTEST,BUFF',RECNO'LO,RECNO'HI);             <<04707>>03485000
         IF < THEN CCLRETN;                                             03490000
      END                                                               03495000
      ELSE CCGRETN;                                                     03500000
                                                                        03505000
      << NOW FIND MSGNO IN MSG >>                                       03510000
                                                                        03515000
      << EXTRACT MSGNO LEN FOR BINARY >>                                03520000
      TOS := @BUFF;                                                     03525000
      ASSEMBLE(DUP,DUP);                                                03530000
      MOVE * := * WHILE N,1;                                            03535000
      MSGNOLEN := -(TOS -TOS);                                          03540000
                                                               <<01321>>03545000
<< MAKE SURE CURRENT LINE ISN'T A CONTINUATION LINE. >>        <<01321>>03550000
   IF MSGNOLEN <> 0  AND  RECTEST > RECNO'LO THEN              <<01321>>03555000
   BEGIN                                                       <<01321>>03560000
                                                               <<01321>>03565000
      DUMRECNO := RECTEST -1D;                                 <<02340>>03570000
      READCAT(DUMRECNO,BUFF',RECNO'LO,RECNO'HI);               <<04707>>03575000
      LENBUF( BUFF, LEN, CRLF, DUMRECNO );                     <<01321>>03580000
      IF DUMRECNO = 0D                                         <<02340>>03585000
         THEN READCAT(RECTEST,BUFF',RECNO'LO,RECNO'HI)         <<04707>>03590000
         ELSE MSGNOLEN := 0;                                   <<01321>>03595000
                                                               <<01321>>03600000
   END;                                                        <<01321>>03605000
                                                               <<01321>>03610000
      CHKMSGNO := MSGNOLEN;                                             03615000
END; << CHKMSGNO >>                                                     03620000
                                                                        03625000
<< PROCEDURE MAIN BODY >>                                               03630000
                                                                        03635000
SIRN := GETSIR(MSGSIR);                                                 03640000
   << CAN NOW USE CCRETN MECHANISM >>                                   03645000
                                                                        03650000
CONDCODE := CCE;                                                        03655000
IF MSGDSTN = 0 THEN CCGRETN;                                            03660000
IF MSGNO < 0 THEN CCGRETN;                                              03665000
VECTOR := 1; << MOVE FORWARD INITIALLY >>                               03670000
                                                                        03675000
                                                                        03680000
<< GET MAXSETNO,NUMRECS FROM DIRECTORY >>                               03685000
MOVEFROMDSEG(@HEAD'ARRAY,MSGDSTN,0,2);                                  03690000
                                                                        03695000
IF SETNO < 1   << INVALID SET NO >>                                     03700000
   OR SETNO > MAXSETNO THEN CCGRETN;                                    03705000
                                                                        03710000
<< GET SET'ROFFSET,SET'FIRSTMSG,NEXT'SET'ROFFSET >>                     03715000
MOVEFROMDSEG(@RECNO'ARRAY,MSGDSTN,SETNO*2,3);                           03720000
                                                                        03725000
<< RECNO'LO = SET'ROFFSET >>                                            03730000
<< RECNO    = SET'FIRSTMSG >>                                           03735000
<< RECNO'HI = NEXT'SET'ROFFSET >>                                       03740000
RECNO'LO := DOUBLE(RECNO'ARRAY);                               <<02340>>03745000
RECNO := DOUBLE(RECNO'ARRAY(1));                               <<02340>>03750000
RECNO'HI := DOUBLE(RECNO'ARRAY(2));                            <<02340>>03755000
RECBND := DOUBLE(NUMRECS);                                     <<02340>>03760000
                                                               <<02340>>03765000
IF RECNO = -1D  THEN CCGRETN;  << SET NOT PRESENT >>           <<02340>>03770000
                                                                        03775000
<< SET BOUNDS ON REC. NO. FOR THIS SET >>                               03780000
RECNO'HI := IF SETNO = MAXSETNO THEN DOUBLE(NUMRECS)           <<02340>>03785000
   ELSE RECNO'HI -1D;                                          <<02340>>03790000
                                                                        03795000
<< SET RECNO FOR SETNO,MSGNO >>                                         03800000
RECNO := RECNO'LO + DOUBLE(MSGNO) - RECNO;                     <<02340>>03805000
<< SET'ROFFSET +MSGNO -SET'FIRSTMSG >>                                  03810000
IF RECNO >= RECNO'HI THEN << SET AT UPPER BOUNDS >>                     03815000
BEGIN                                                                   03820000
   RECNO := RECNO'HI;                                                   03825000
   VECTOR := -1;                                                        03830000
END;                                                                    03835000
                                                                        03840000
RECBND := -1D; << FORCES CHKMSGNO CALL 1ST TIME THRU >>        <<02340>>03845000
   << SEARCH FOR CORRECT MSGNO LOOP >>                                  03850000
                                                                        03855000
WHILE TRUE DO                                                           03860000
BEGIN                                                                   03865000
   IF RECBND <> RECNO THEN << GO FETCH A NEW MESSAGE >>                 03870000
      WHILE CHKMSGNO(RECNO) = 0  DO RECNO := RECNO -1D;        <<02340>>03875000
      << IF REC DOESN'T HAVE MSGNO, GO BACKWARDS >>                     03880000
      << NOW HAVE REC CONTAINING MSGNO, FIND IF CORRECT>>               03885000
   TOS := BINARY(BUFF,MSGNOLEN); <<SET IN CHKMSGNO>>                    03890000
   TOS := TOS -MSGNO; DEL;                                              03895000
   IF = THEN << FETCHED CORRECT MSG >>                                  03900000
   BEGIN << MOVE MSG OVER MSGNO & ADJUST LEN >>                         03905000
                                                                        03910000
         << NOW FIND END OF MSG & IF CONT'D. >>                         03915000
      LENBUF(BUFF,LEN,CRLF,RECNO);                                      03920000
      FINDMSG := RECNO;                                                 03925000
                                                                        03930000
      LEN := LEN-(MSGNOLEN +1);                                         03935000
         << MOVE MSG OVER MSGNO        >>                               03940000
         << MESSAGE STARTS 1 PAST MSGNO>>                               03945000
      MOVE BUFF := BUFF(MSGNOLEN +1),(LEN);                             03950000
                                                                        03955000
      GO OUTL; << ONLY SUCCESSFUL EXIT >>                               03960000
                                                                        03965000
   END;                                                                 03970000
                                                                        03975000
      << DIDN'T FIND MSG. NO. NOW BINARY SEARCH >>                      03980000
   IF < THEN VECTOR := +1 ELSE VECTOR := -1;                            03985000
      << IF MSGNO LO, THEN +1.IF HI, THEN -1 >>                         03990000
   RECNO'NEW := (RECNO + DOUBLE(RECNO'ARRAY(1+VECTOR)))/2D;    <<02340>>03995000
      << SET BOUND AT RECORD WITH MSGNO >>                              04000000
   RECBND := RECNO;                                                     04005000
      << BOUNDARY RECORD MUST BE A RECORD CONTAINING A >>               04010000
      << MESSAGE NO. RECBND WILL BE EITHER NEW HI OR LO>>               04015000
   DO RECBND := RECBND + DOUBLE(VECTOR)                        <<02340>>04020000
      UNTIL CHKMSGNO(RECBND) <> 0;                             <<02340>>04025000
   RECNO'ARRAY(1-VECTOR) := INTEGER(RECBND); <<NEW HI OR LO >> <<02340>>04030000
   <<VECTOR=1 THEN WANT RECNO'LO; IF -1 THEN RECNO'HI>>        <<02340>>04035000
   IF VECTOR=1 THEN RECNO'LO:=DOUBLE(RECNO'ARRAY(1-VECTOR))    <<02340>>04040000
    ELSE RECNO'HI:=DOUBLE(RECNO'ARRAY(1-VECTOR));              <<02340>>04045000
                                                               <<02340>>04050000
   RECNO := IF RECNO=RECNO'NEW THEN RECNO+DOUBLE(VECTOR)       <<02340>>04055000
    ELSE IF(RECNO'NEW >= RECNO'LO) AND (RECNO'NEW <= RECNO'HI) <<02340>>04060000
         THEN RECNO'NEW  ELSE DOUBLE(RECNO'ARRAY(1-VECTOR));   <<02340>>04065000
      << IF NEW SAME AS OLD, BUMP. IF NEW FALLS OUT OF>>                04070000
      << LIMITS BECAUSE OF MULTIPLE LINES/MSG SET AT  >>                04075000
      << NEW BOUND                                    >>                04080000
END; << FIND MSGNO LOOP >>                                              04085000
                                                                        04090000
OUTL:                                                                   04095000
      RELSIR(MSGSIR,SIRN);                                              04100000
END; << FINDMSG >>                                                      04105000
$TITLE "FORMSG"                                                         04110000
INTEGER PROCEDURE FORMSG(INBUFF,SETNO,MSGNO,MASK,P1,P2,P3,              04115000
      P4,P5,OUTBUFF,OUTBUFFSIZE,OUTLEN,DEST,CONTROL);                   04120000
   VALUE SETNO,MSGNO,MASK,P1,P2,P3,P4,P5,OUTBUFFSIZE,                   04125000
      DEST,CONTROL;                                                     04130000
   BYTE ARRAY INBUFF,OUTBUFF;                                           04135000
   INTEGER SETNO,MSGNO,OUTBUFFSIZE,DEST,OUTLEN;                         04140000
   LOGICAL MASK,P1,P2,P3,P4,P5,CONTROL;                                 04145000
   OPTION UNCALLABLE;                                                   04150000
COMMENT                                                                 04155000
                                                                        04160000
THIS PROCEDURE ASSEMBLES AND ROUTES MESSAGES. UP TO 5                   04165000
PARAMETERS CAN BE FORMATTED & INSERTED. MESSAGE CAN COME FROM           04170000
MESSAGE CATALOG OR BE PASSED IN. INPUT MESSAGE CAN BE                   04175000
CATENATED WITH STRING IN OUTPUT BUFFER. ASSEMBLED MESSAGE IS            04180000
PLACED IN OUPUT BUFFER. MESSAGE MAY THEN BE ROUTED TO                   04185000
DESTINATION. WHEN OUTPUT BUFFER IS FILLED, MESSAGE IS SENT TO           04190000
DESTINATION & BUFFER REFILLED UNTIL MESSAGE IS COMPLETE.                04195000
                                                                        04200000
INBUFF   INPUT BUFFER. IF IT CONTAINS MESSAGE, MESSAGE MUST             04205000
         TERMINATED BY A ZERO. IF MESSAGE IS IN CATALOG                 04210000
         INBUFF MUST BE 'BUFFSIZE'.                                     04215000
                                                                        04220000
SETNO    MESSAGE SET NUMBER.                                            04225000
         = -1  - MESSAGE IS IN INBUFF.                                  04230000
         = >0  - MESSAGE SET NUMBER IN CATALOG.                         04235000
                                                                        04240000
MSGNO    MESSAGE NUMBER. MUST BE GREATER THAN ZERO.                     04245000
                                                                        04250000
MASK     INDICATES PARAMETER TYPES.                                     04255000
         .(0:1) = NO PARAMETERS.                                        04260000
         .(1:3) = TYPE OF P1.                                           04265000
         .(4:3) = TYPE OF P2.                                           04270000
         .(7:3) = TYPE OF P3.                                           04275000
         .(10:3)= TYPE OF P4.                                           04280000
         .(13:3)= TYPE OF P5.                                           04285000
                                                                        04290000
         TYPE = 0 - PARM IS STRING BYTE POINTER, TERMINATED             04295000
                    BY ZERO.                                            04300000
                1 - PARM IS INTEGER.                                    04305000
                2 - PARM IS DOUBLE BY REFERENCE.                        04310000
                3 - IGNORE THIS PARM.                                   04315000
                                                                        04320000
P1,P2,P3,P4,P5  - PARAMETER, AS INDICATED BY MASK.                      04325000
                                                                        04330000
OUTBUFF  MESSAGE IS SCANNED IN INBUFF & MOVED TO OUTBUFF AS    <<00106>>04335000
         IS FORMATTED. WHEN BUFFER IS FULL, MESSAGE IS                  04340000
         ROUTED.                                               <<01321>>04345000
                                                               <<01321>>04350000
                                                                        04355000
OUTBUFFSIZE  SIZE OF OUTBUFF  IN POSITIVE BYTES.               <<00106>>04360000
                                                                        04365000
OUTLEN   LENGTH OF STRING IN OUTBUFF  IN POSITIVE BYTES.       <<00106>>04370000
         MUST BE SET TO ZERO WHEN FORMSG CALLED IF OUTBUFF  IS <<00106>>04375000
         EMPTY. OUTLEN > 0 INDICATES CATENATION OF STRING               04380000
         IN OUTBUFF  WITH INPUT MESSAGE.                       <<00106>>04385000
                                                                        04390000
DEST     DESTINATION.                                                   04395000
         = -FNUM  - FILE NUMBER.                                        04400000
         = -2     - $STDLIST                                            04405000
         = -1     - NOWHERE--MESSAGE DISAPPEARS.               <<01321>>04410000
         = 0      - NOT USED.                                           04415000
         = LDEV   - TERMINAL.                                           04420000
                                                                        04425000
CONTROL  (TERMINALS ONLY) FLAG WORD.                                    04430000
         .(0:1)  = EACH WRITE WILL HAVE CCTL %320.                      04435000
                                                                        04440000
         .(2:2)  = FUNNY TERMTYPE. TRANSLATE INTO APL.                  04445000
                                                                        04450000
         .(14:2) = IOTYPE FOR ATTACHIO.                                 04455000
                   0 - STANDARD.                                        04460000
                   1 - SOFT PREEMPTION.                                 04465000
                   2 - HARD PREEMTPION.                                 04470000
RETURNS  - THE NEXT MESSAGE VALUE IN THE CURRENT MESSAGE IS             04475000
           RETURNED. IF NONE, -1 IS RETURNED.                           04480000
                                                               <<01321>>04485000
                                                               <<01321>>04490000
CONDITION CODE                                                          04495000
           CCE = EVERYTHING OK                                          04500000
           CCG = SOMETHING WRONG, BUT PRINTED SOMETHING                 04505000
           CCL = I/O FAILURE (ATTACHIO, PRINT, FWRITE).                 04510000
;                                                                       04515000
                                                               <<07395>>04520000
<<*********************************************************>>  <<07395>>04525000
<<                                                         >>  <<07395>>04530000
<< Fix information:  this fix will print the Status and    >>  <<07395>>04535000
<< Delta-P of the stack marker that called GENMSG and the  >>  <<07395>>04540000
<< stack marker back past that one when a missing message  >>  <<07395>>04545000
<< is detected.  Hopefully, this information will help us  >>  <<07395>>04550000
<< find the problem easier.                                >>  <<07395>>04555000
<<                                                         >>  <<07395>>04560000
<<*********************************************************>>  <<07395>>04565000
BEGIN                                                                   04570000
INTEGER                                                                 04575000
   ZEROSTOP,                                                            04580000
   TANKI,                                                               04585000
   INDEX,                                                               04590000
   INLEN,                     <<INPUT BUF: LENGTH  >>                   04595000
   INX,                       <<INPUT BUF: INDEX >>                     04600000
   OUTX,                      <<OUTPUT BUF: INDEX >>                    04605000
   PNUM,                                                                04610000
   FINAL'OUTDEV,    <<ACTUAL DEVICE FOR OUTPUT>>               <<00702>>04615000
   DIT,TERM,                                                   <<00702>>04620000
   DSTX,                                                       <<02802>>04625000
   CRIT,      <<OLD CRITICAL STATE>>                           <<02802>>04630000
   IOQX,      <<ATTACHIO IOQ INDEX>>                           <<02802>>04635000
   SAVESTATUS,    << status of traps >>                                 04640000
   SIRN;                                                                04645000
                                                               <<07395>>04650000
INTEGER                                                        <<07395>>04655000
   WHICH,             << Specifies a Stack Marker for the  >>  <<07395>>04660000
                      << call to STACKMARK.                >>  <<07395>>04665000
   STAT, DELP;        << Return values from STACKMARK.     >>  <<07395>>04670000
                                                               <<07395>>04675000
                                                                        04680000
DOUBLE                                                         <<02340>>04685000
   RECNO;                                                      <<02340>>04690000
INTEGER LPDT'INDEX; << Index into LPDT/INCLLPDT >>             <<06224>>04695000
                                                               <<02340>>04700000
LOGICAL CRLF;                                                           04705000
LOGICAL UP:=TRUE;                                              <<00702>>04710000
EQUATE SYSGLOB=%1000, LPDTBASE=%10, LPDTSIZE=2;                <<00702>>04715000
EQUATE IOMSGPIN = SYSGLOB+%152;   <<SYSDB LOCATION OF PIN>>    <<02802>>04720000
DEFINE IOMSGPROC = ABSOLUTE(IOMSGPIN)/PCBSIZE#;                <<02802>>04725000
DEFINE DIT'UPBIT=DIT).(1:1#,                                   <<00702>>04730000
       DIT'TERM=DIT+7).(5:5#;                                  <<00702>>04735000
                                                               <<01646>>04740000
<< VARIABLES FOR ROUTING DEVICE     >>                         <<01646>>04745000
<< MESSAGES TO THE ASSOCIATED USER. >>                         <<01646>>04750000
                                                               <<01646>>04755000
INTEGER ARRAY                                                  <<01646>>04760000
   MSG'DST'BUF(0:3),    << MESSAGE BUFS HEADER AREA >>         <<02802>>04765000
   ASS'ENT(0:ASS'ENTRYSIZE-1),   << ENTRY FROM ASOC. TABLE >>  <<01646>>04770000
<< ......................................................... >><<06592>>04775000
<<        Declarations for referencing the JMAT              >><<06592>>04780000
<<   JMATARR -- is a local array into which an entry gets    >><<06592>>04785000
<<              read.  (i.e. JMATARR(0) = entryword 0)       >><<06592>>04790000
<<   JMATINX -- is an index used by the include file to      >><<06592>>04795000
<<              reference a specific entry if JMATARR(0) was >><<06592>>04800000
<<              the first word of the JMATHEADER. Here, since>><<06592>>04805000
<<              JMATARR is local this will be 0.             >><<06592>>04810000
<< ......................................................... >><<06592>>04815000
   JMATARR(0:JMATENTRYSIZE-1); << Holds entry from JMAT >>     <<06592>>04820000
INTEGER                                                        <<06592>>04825000
   JMATINX;    <<  Index into JMATARR used by include file  >> <<06592>>04830000
ARRAY QARRAY(*)=Q+0;                                           << 7469>>04835000
                                                               << 7469>>04840000
INTEGER PCBGLOBLOC;                                            << 7469>>04845000
                                                               <<01646>>04850000
INTEGER                                                        <<01646>>04855000
   DIVERT'DEVICE := 0,  << OUTPUT DEVICE FOR ASOC'D USER >>    <<01646>>04860000
   HIGHEST'LDEV;        << LAST LDEV# IN LPDT/ASOC. TABLE >>   <<01646>>04865000
                                                               <<01646>>04870000
                                                                        04875000
LOGICAL PCBPT;                                                 <<06590>>04880000
POINTER INBUFF';              <<INPUT BUF: WORD PTR>>                   04885000
POINTER OUTBUFF';             <<OUTPUT BUF: WORD PTR >>                 04890000
INTEGER ARRAY PARM'IA(*) = P1;<<PARM BUF: INPUT >>                      04895000
BYTE ARRAY BUFF1(0:11);       <<PARM BUF: OUTPUT >>                     04900000
                                                               <<KS.01>>04905000
   SUBROUTINE LOGIT(DEST);                                     <<KS.01>>04910000
   VALUE DEST;                                                 <<KS.01>>04915000
   INTEGER DEST;                                               <<KS.01>>04920000
   BEGIN                                                       <<KS.01>>04925000
      IF DEST=SYS'CONSOLE'LDEV<<OUTPUT TO CONSOLE?>>           <<06877>>04930000
         THEN LOG15(OUTX,@OUTBUFF,OUTX,15); <<THEN LOG IT>>    <<KS.01>>04935000
   END; <<LOGIT>>                                              <<KS.01>>04940000
                                                               <<KS.01>>04945000
SUBROUTINE DEF'MOVETODSEG;                                              04950000
SUBROUTINE DEF'MOVEFROMDSEG;                                   <<00552>>04955000
INTEGER SUBROUTINE GETXDSBUF;                                  <<02802>>04960000
<< THIS PROCEDURE OBTAINS AN AVAILABLE BUFFER IN >>            <<02802>>04965000
<< THE MSG SYSTEM BUFFER XDS AND RETURNS ITS     >>            <<02802>>04970000
<< INDEX.  IF NO BUFFER IS AVAILABLE, THIS PIN   >>            <<02802>>04975000
<< IS IMPEDED, WAITING FOR A BUFFER.             >>            <<02802>>04980000
BEGIN                                                          <<02802>>04985000
                                                               <<02802>>04990000
<<GET MSG SIR TO INSURE THAT WE HAVE EXCLUSIVE   >>            <<02802>>04995000
<<ACCESS TO THE MSG SYSTEM BUFFER.               >>            <<02802>>05000000
                                                               <<02802>>05005000
TRY'TO'GET'IT'AGAIN:                                           <<02802>>05010000
                                                               <<02802>>05015000
SIRN := GETSIR(MSGSIR);                                        <<02802>>05020000
                                                               <<02802>>05025000
<<MOVE MSG BUF HEADER TO OUR STACK>>                           <<02802>>05030000
MOVEFROMDSEG(@MSG'DST'BUF,IOMSGDST,0,4);                       <<02802>>05035000
                                                               <<02802>>05040000
<<OBTAIN NEXT BUFFER IN CHAIN>>                                <<02802>>05045000
IF MSG'DST'BUF(2) = 0 THEN                                     <<02802>>05050000
  BEGIN  <<ALL BUFFERS ARE CURRENTLY BEING USED>>              <<02802>>05055000
  PDISABLE;                                                    <<02802>>05060000
  RELSIR(MSGSIR,SIRN); <<RELEASE SIR>>                         <<02802>>05065000
  <<LINK THIS PCB INTO QUEUE FOR BUFFER>>                      <<02802>>05070000
  TOS := CURPRC/PCBSIZE; << CURRENT PROCESS PIN >>             <<06590>>05075000
  TOS := IOMSGQUEUE;   <<FIRST PCB WAITING>>                   <<02802>>05080000
  IF = THEN                                                    <<02802>>05085000
    BEGIN << THIS PIN IS TO BE FIRST IN-LINE >>                <<02802>>05090000
    ASSEMBLE(XCH); << PUT MY PIN ON TOS >>                     <<02802>>05095000
    IOMSGQUEUE := TOS; << SAVE PIN IN IMPEDE LIST >>           <<02802>>05100000
                                                               <<02802>>05105000
    << SINCE THIS IS 1ST IN LINE, WAKEN IOMSGPROC AS IF >>     <<02802>>05110000
    << A TIMER POPPED, SO IT CAN SET UP A WATCHDOG TIMER>>     <<02802>>05115000
    AWAKE(ABSOLUTE(IOMSGPIN),%10<<TIMER>>,0);                  <<02802>>05120000
                                                               <<02802>>05125000
    END                                                        <<02802>>05130000
  ELSE                                                         <<02802>>05135000
    BEGIN  << THERE ARE OTHER PINS WAITING >>                  <<02802>>05140000
    << BECAUSE IOMSGQUEUE IS A PIN AND THE NIMPPIMWORDNUM >>   <<06590>>05145000
    << IS A PCB RELATIVE INDEX, WE HAVE TO BE VERY CARE-  >>   <<06590>>05150000
    << FUL TO STORE THE CORRECT VALUE IN EACH LOCATION.   >>   <<06590>>05155000
    DO TOS := LPCB(TOS*PCBSIZE+NIMPPINWORDNUM)/PCBSIZE         <<06590>>05160000
       UNTIL =; << FIND END PIN ON LIST >>                     <<02802>>05165000
    ASSEMBLE(XCH);  << PUT MY PIN ON TOS >>                    <<02802>>05170000
    LPCB(X) := S0*PCBSIZE;                                     <<06590>>05175000
    ASSEMBLE(DEL);  << REMOVE MY PIN FROM TOS >>               <<02802>>05180000
    END;                                                       <<02802>>05185000
                                                               <<02802>>05190000
  << MAKE SURE MY NIMP IS ZERO >>                              <<02802>>05195000
  PCBPT := CURPRC;                                             <<06590>>05200000
  SPCBNIMPPIN := 0;                                            <<06590>>05205000
  << IMPEDE, WAITING FOR IOMSGPROC TO RELEASE A BUFFER >>      <<02802>>05210000
  IMPEDE(*);  << ZERO WAS LEFT ON TOS >>                       <<02802>>05215000
                                                               <<02802>>05220000
  << NOW, GO AND TRY OBTAINING BUFFER ALL OVER AGAIN >>        <<02802>>05225000
  GO TO TRY'TO'GET'IT'AGAIN;                                   <<02802>>05230000
  END                                                          <<02802>>05235000
ELSE                                                           <<02802>>05240000
  BEGIN  << THERE IS AN AVAIL BUFFER, SO DO NECESSARY LINKING ><<02802>>05245000
                                                               <<02802>>05250000
  << SEE IF NEXT POINTER IS VALID >>                           <<02802>>05255000
  IF MSG'DST'BUF(2) > (MSG'DST'BUF*MSG'DST'BUF(1)) <<OUT OF TAB<<02802>>05260000
     OR                                                        <<02802>>05265000
     (MSG'DST'BUF(2)-4) MOD MSG'DST'BUF(1) <> 0 THEN << BOUNDAR<<02802>>05270000
    BEGIN                                                      <<02802>>05275000
    RELSIR(MSGSIR,SIRN);                                       <<02802>>05280000
    RETURN;    << NO GOOD - PROBLEM EXISTS >>                  <<02802>>05285000
    END;                                                       <<02802>>05290000
                                                               <<02802>>05295000
  << SAVE INDEX AS RETURN FROM TYPED SUBROUTINE >>             <<02802>>05300000
  GETXDSBUF := MSG'DST'BUF(2);                                 <<02802>>05305000
                                                               <<02802>>05310000
  << UPDATE POINTER TO NEXT AVAILABLE BUFFER >>                <<02802>>05315000
  MOVEFROMDSEG(@MSG'DST'BUF(2),IOMSGDST,MSG'DST'BUF(2),1);     <<02802>>05320000
  << IF THIS IS THE END OF AVAIL BUFS, MARK TRLR 0 >>          <<02802>>05325000
  IF MSG'DST'BUF(2) = 0 THEN                                   <<02802>>05330000
    MSG'DST'BUF(3) := 0;                                       <<02802>>05335000
  MOVETODSEG(IOMSGDST,2,@MSG'DST'BUF(2),2);                    <<02802>>05340000
                                                               <<02802>>05345000
  RELSIR(MSGSIR,SIRN);                                         <<02802>>05350000
  END;                                                         <<02802>>05355000
END;  << OF SUBROUTINE GETXDSBUF >>                            <<02802>>05360000
                                                                        05365000
SUBROUTINE PRINTIT; << HANDLES ROUTING OF OUTPUT >>                     05370000
BEGIN                                                                   05375000
   IF CONTROL.FUNNYTERM <> 0 THEN << TRANSLATE INTO APL >>              05380000
      APLTRANSLATEOUT(OUTBUFF,OUTX,CONTROL.FUNNYTERM);                  05385000
   IF CONTROL&CSL(1) THEN CRLF := %320; << OVERRIDE >>                  05390000
   IF DEST < 0 THEN << RETURN STRING OR FWRITE >>                       05395000
   BEGIN  << $STDLIST IS DONE HERE >>                                   05400000
      IF DEST < -1 THEN << FWRITE >>                                    05405000
      BEGIN                                                             05410000
         PXGLOBAL;                                             << 7469>>05415000
         IF (DEST=-2) AND PXG'JOBTYPE=1<<SESSION>> AND         << 7469>>05420000
            JOBSESSIONMAIN THEN                                <<01998>>05425000
         BEGIN                                                          05430000
            TOS := ATTACHIO(PXG'INPUTLDEV,0,0,@OUTBUFF',1,     << 7469>>05435000
               -OUTX,CRLF,0,1); << BYPASS FILESYS >>                    05440000
         DEL;                                                           05445000
         IF TOS.(13:3) <> 1 THEN CCLRETN;                               05450000
         END                                                            05455000
         ELSE                                                           05460000
         BEGIN                                                          05465000
            FWRITE(-DEST,OUTBUFF',-OUTX,CRLF);                          05470000
            IF <> THEN CCLRETN;                                         05475000
         END;                                                           05480000
      END;                                                              05485000
      << DEST = -1, DO NOTHING.  MESSAGE DISAPPEARS. >>        <<01321>>05490000
   END                                                                  05495000
   ELSE << DEST >= 0, GO TO SOME DEVICE - NO WAIT I/O>>                 05500000
   BEGIN                                                                05505000
         LOGIT(DEST); <<LOG MESSAGE POSSIBLE CONSOLE MSG>>     <<KS.01>>05510000
                                                               <<02802>>05515000
      << MAKE SURE ENOUGH STACK IS HERE B/4 CRITICAL >>        <<02802>>05520000
      ASSEMBLE(ADDS 255;SUBS 255);                             <<02802>>05525000
                                                               <<02802>>05530000
      << SET CRITICAL TO NOT ABORT WHILE OWNING BUFFERS >>     <<02802>>05535000
      CRIT := SETCRITICAL;                                     <<02802>>05540000
                                                               <<02802>>05545000
      << GET BUFFER INDEX TO PLACE MESSAGE INTO >>             <<02802>>05550000
      DSTX := GETXDSBUF;                                       <<02802>>05555000
      IF DSTX = 0 THEN                                         <<02802>>05560000
        BEGIN  << FAILED TO GET A BUFFER >>                    <<02802>>05565000
        RESETCRITICAL(CRIT);                                   <<02802>>05570000
        CCLRETN;                                               <<02802>>05575000
        END;                                                   <<02802>>05580000
                                                               <<02802>>05585000
      << MOVE DATA TO XDS >>                                   <<02802>>05590000
      MOVETODSEG(IOMSGDST,DSTX,@OUTBUFF',(OUTX+1)&LSR(1));     <<02802>>05595000
                                                               <<00702>>05600000
<< FIRST DETERMINE ACTUAL OUTPUT DEVICE,  THEN IF SYSTEM >>    <<00702>>05605000
<< CONSOLE AND NOT LOGGED ON, ALLOCATE                   >>    <<00702>>05610000
<< OUTPUT MESSAGE, AND IF AN ALLOCATION WAS DONE, THEN   >>    <<00702>>05615000
<< DEALLOCATE DEVICE                                     >>    <<00702>>05620000
                                                               <<00702>>05625000
FINAL'OUTDEV:=IF DIVERT'DEVICE=0 THEN DEST ELSE DIVERT'DEVICE; <<00702>>05630000
LPDT'INDEX:=FINAL'OUTDEV*INTEGER(LPDT'ENTRY'SIZE);             <<06224>>05635000
IF FINAL'OUTDEV=SYS'CONSOLE'LDEV THEN <<SYS CONSOLE>>          <<06877>>05640000
BEGIN                                                          <<00702>>05645000
   << Turn traps off in case LPDT is to high up >>             <<04265>>05650000
   << We could get an integer overflow and sf 311 >>           <<04265>>05655000
   PUSH(STATUS);                                               <<04265>>05660000
   SAVESTATUS.(15:1) := S0.(2:1);  <<status of traps>>                  05665000
   TOS.(2:1) := 0;                                             <<04265>>05670000
   SET(STATUS);                                                <<04265>>05675000
   DIT:=ABSOLUTE(SYSGLOB+LPDT'DIT'PTR);                        <<06224>>05680000
   << Put traps back on >>                                     <<04265>>05685000
   PUSH(STATUS);                                               <<04265>>05690000
   TOS.(2:1) := SAVESTATUS.(15:1);                             <<07167>>05695000
   SET(STATUS);                                                <<04265>>05700000
   UP:=LOGICAL((DIT'UPBIT)=1);                                 <<06224>>05705000
<< TERM:=ABSOLUTE(DIT'TERM); >>  << USE DEFAULT TERM TYPE >>   <<02316>>05710000
   IF NOT UP THEN                                              <<00702>>05715000
      ATTACHIO(FINAL'OUTDEV,0,0,0,24,0,0,0,1);                 <<02316>>05720000
END;                                                           <<00702>>05725000
                                                               <<00702>>05730000
      TOS := ATTACHIO(FINAL'OUTDEV                             <<02802>>05735000
             ,0,IOMSGDST, << WHERE MESSAGE WAS PUT>>           <<02802>>05740000
          DSTX,1,-OUTX,CRLF,0,CONTROL.(14:2)&LSL(7));          <<02802>>05745000
      ASSEMBLE(DEL);                                           <<02802>>05750000
      IOQX := TOS;   <<STORE IOQ INDEX>>                       <<02802>>05755000
      IF NOT UP THEN ATTACHIO(FINAL'OUTDEV,0,0,0,4,0,0,0,1);   <<00702>>05760000
   <<SEND IOQ TO IOMESSAGEPROC TO WAIT FOR COMPLETION>>        <<02802>>05765000
   TOS := 2;  <<MSG TYPE 2 IS IOQ>>                            <<02802>>05770000
   TOS := IOQX; <<IOQ INDEX>>                                  <<02802>>05775000
   TOS := DSTX; <<DST USED TO PERFORM I/O>>                    <<02802>>05780000
   TOS := 0;    <<NOT USED>>                                   <<02802>>05785000
   SENDMSG(IOMSGPROC,0<<PORT 0>>,4<<LENGTH OF MSG>>,%140000);  <<02802>>05790000
                                                               <<02802>>05795000
   <<RESET CRITICAL SO CAN ABORT NOW>>                         <<02802>>05800000
   RESETCRITICAL(CRIT);                                        <<02802>>05805000
                                                               <<02802>>05810000
   END;                                                                 05815000
                                                                        05820000
   OUTLEN := OUTX; <<INDICATE CONTENTS OF OUTBUFF>>                     05825000
   OUTX := 0; <<RESET INDEX TO REFILL OUTBUFF>>                         05830000
END; << PRINTIT >>                                                      05835000
                                                                        05840000
SUBROUTINE TANK(LENGTH,STRING);                                         05845000
   VALUE LENGTH;                                                        05850000
   INTEGER LENGTH;                                                      05855000
   BYTE ARRAY STRING;                                                   05860000
BEGIN                                                                   05865000
   IF LENGTH=0 THEN RETURN;                                    <<00106>>05870000
   TANKI := -1;                                                         05875000
   WHILE (TANKI := TANKI+1) < LENGTH DO << TANKING LOOP>>               05880000
   BEGIN                                                                05885000
      IF OUTX >= OUTBUFFSIZE THEN PRINTIT; <<FLUSH OUTBUFF>>   <<00106>>05890000
      OUTBUFF(OUTX) := STRING(TANKI);                          <<00106>>05895000
      OUTX := OUTX+1;                                          <<00106>>05900000
   END; <<TANK LOOP>>                                                   05905000
END; << TANK >>                                                         05910000
                                                                        05915000
SUBROUTINE INSERTPARM;                                                  05920000
BEGIN                                                                   05925000
   << CATCH BOUNDARY CONDITION ON LAST CHAR "!" >>             <<00261>>05930000
   IF PNUM >= 5 THEN RETURN;                                   <<00261>>05935000
   CASE *INTEGER((MASK &CSL(4+PNUM*3)) LAND 3) OF << PARM X >>          05940000
   BEGIN                                                                05945000
      BEGIN << 0: STRING PARM >>                                        05950000
         TOS := PARM'IA(PNUM);                                          05955000
         ASSEMBLE(DUP,DUP);                                             05960000
         SCAN * UNTIL 0,1;                                              05965000
         ASSEMBLE(XCH,SUB;XCH);                                         05970000
         TANK(*,*);                                                     05975000
      END;                                                              05980000
                                                                        05985000
      << 1: INTEGER BY VALUE >>                                         05990000
      BEGIN                                                    <<01456>>05995000
                                                               <<01456>>06000000
      IF INBUFF(INDEX) = "\" THEN << EXPECT LDEV # >>          <<01456>>06005000
      BEGIN                                                    <<01456>>06010000
      HIGHEST'LDEV:=LPDT'MAX'ENTRIES;                          <<06224>>06015000
         IF 1 <= PARM'IA(PNUM) <= HIGHEST'LDEV THEN            <<01456>>06020000
         BEGIN   << VALID LDEV >>                              <<01456>>06025000
            << GET ASSOCIATE TABLE ENTRY FOR LDEV >>           <<01456>>06030000
            SIRN := GETSIR(ASS'SIR);  << LOCK ASOC. TABLE >>   <<01646>>06035000
            MOVEFROMDSEG(@ASS'ENT,ASS'DST,                     <<01456>>06040000
               PARM'IA(PNUM)*ASS'ENTRYSIZE,ASS'ENTRYSIZE);     <<01646>>06045000
            IF ASS'ENT(ASS'JMAT)<>0 THEN <<LDEV IS ASSOCIATED>><<01456>>06050000
            BEGIN                                              <<01456>>06055000
               JMATINX := 0;  << JMATARR is local >>           <<06592>>06060000
               << GET NEW LDEV FROM JMAT ENTRY >>              <<01456>>06065000
               MOVEFROMDSEG(@JMATARR, JMATDST,                 <<06592>>06070000
                            ASS'ENT(ASS'JMAT)*JMATENTRYSIZE,   <<06592>>06075000
                            JMATENTRYSIZE);                    <<06592>>06080000
               DIVERT'DEVICE := JMATJLISTDEV;                  <<06592>>06085000
            END;                                               <<01456>>06090000
            << DON'T RELEASE ASOC. TABLE UNTIL AFTER GETTING >><<01646>>06095000
            << JMAT ENTRY TO ENSURE ITS VALIDITY.            >><<01646>>06100000
            RELSIR(ASS'SIR,SIRN);                              <<01646>>06105000
         END;                                                  <<01456>>06110000
      END;                                                     <<01456>>06115000
                                                               <<01456>>06120000
      TANK(ASCII(PARM'IA(PNUM),10,BUFF1),BUFF1);                        06125000
                                                               <<01456>>06130000
      END;  << OF INTEGER BY VALUE >>                          <<01456>>06135000
                                                                        06140000
      << 2: DOUBLE BY REFERENCE >>                                      06145000
      BEGIN                                                             06150000
         TOS := PARM'IA(PNUM);                                          06155000
         TANK(DASCII(DPS0,10,BUFF1),BUFF1); DEL;                        06160000
      END;                                                              06165000
                                                                        06170000
      ;<< 3 IGNORE PARM >>                                              06175000
                                                                        06180000
   END; << CASE OF PARMS >>                                             06185000
   PNUM := PNUM+1;                                                      06190000
END; <<INSERTPARM>>                                                     06195000
                                                                        06200000
<< ........................................................ >> <<06592>>06205000
<<                                                          >> <<06592>>06210000
<<          ***** Main Body of FORMSG *****                 >> <<06592>>06215000
<<                                                          >> <<06592>>06220000
<< ........................................................ >> <<06592>>06225000
                                                                        06230000
                                                                        06235000
<< SET UP VARIABLES >>                                                  06240000
CRLF := ZEROSTOP := 0; << STOPPER FOR INPUT STRING SCAN >>              06245000
CONDCODE := CCE;                                                        06250000
FORMSG := -1; << SET TO NO CONTINUATION >>                              06255000
@INBUFF' := @INBUFF &LSR(1);                                            06260000
@OUTBUFF' := @OUTBUFF & LSR(1);                                         06265000
                                                                        06270000
<< STRING PASSED IN, OR CATALOG FETCH ? >>                              06275000
IF SETNO = -1 THEN                                                      06280000
                                                                        06285000
<< STRING PASSED IN >>                                                  06290000
                                                                        06295000
BEGIN                                                                   06300000
   SCAN INBUFF UNTIL 0,1; << STOPPED BY ZEROSTOP>>                      06305000
   INLEN := TOS -@INBUFF;                                               06310000
   RECNO := 0D;  << INDICATE NO CONTINUED MSGS >>              <<02340>>06315000
END                                                                     06320000
ELSE                                                                    06325000
                                                                        06330000
<< FETCH FROM CATALOG >>                                                06335000
                                                                        06340000
BEGIN                                                                   06345000
   RECNO := FINDMSG(SETNO,MSGNO,INBUFF',INLEN,CRLF);                    06350000
   IF < THEN CCLRETN;                                                   06355000
   IF > THEN <<CAN'T FIND MSG. PRINT DIAG. MSG>>                        06360000
   BEGIN                                                                06365000
      MOVE INBUFF := ("MISSING MSG. SET=!. MESSAGE=!.",0);              06370000
      GENMSG(-1,@INBUFF,%11000,SETNO,MSGNO,,,,DEST,                     06375000
         ,,,CONTROL.(14:2));                                            06380000
      IF NOT MASK&CSL(1) THEN                                           06385000
      BEGIN                                                             06390000
         MOVE INBUFF := ("PARM(S)= !;!;!;!;!",0);                       06395000
         GENMSG(-1,@INBUFF,MASK,P1,P2,P3,P4,P5,                         06400000
            DEST,,,,CONTROL.(14:2));                                    06405000
      << IF PARMS PRESENT THEN PRINT THEM >>                            06410000
      END;                                                              06415000
                                                               <<07395>>06420000
   << Print the stack markers for the procedure that       >>  <<07395>>06425000
   << called GENMSG and the procedure that called the      >>  <<07395>>06430000
   << GENMSG caller.                                       >>  <<07395>>06435000
      MOVE INBUFF := "GENMSG CALLER    STATUS:  %         ";   <<07395>>06440000
      MOVE INBUFF(27) := "     ; DELTA-P:  %        ";         <<07395>>06445000
      INBUFF(53) := 0;                                         <<07395>>06450000
      WHICH := 1;                                              <<07395>>06455000
      STACKMARK( WHICH, , STAT, DELP );                        <<07395>>06460000
      IF = THEN                                                <<07395>>06465000
      BEGIN                                                    <<07395>>06470000
         ASCII( STAT, 8, INBUFF(27) );                         <<07395>>06475000
         ASCII( DELP, 8, INBUFF(45) );                         <<07395>>06480000
         GENMSG( -1, @INBUFF,,,,,,,DEST,,,,CONTROL.(14:2));    <<07395>>06485000
      END;                                                     <<07395>>06490000
      MOVE INBUFF(13) := "+1";                                 <<07395>>06495000
      WHICH := 2;                                              <<07395>>06500000
      STACKMARK( WHICH, , STAT, DELP );                        <<07395>>06505000
      IF = THEN                                                <<07395>>06510000
      BEGIN                                                    <<07395>>06515000
         ASCII( STAT, 8, INBUFF(27) );                         <<07395>>06520000
         ASCII( DELP, 8, INBUFF(45) );                         <<07395>>06525000
         GENMSG( -1, @INBUFF,,,,,,,DEST,,,,CONTROL.(14:2));    <<07395>>06530000
      END;                                                     <<07395>>06535000
      CCGRETN;                                                          06540000
   END;                                                                 06545000
END;                                                                    06550000
                                                                        06555000
<< SET UP LOOP VARIABLES >>                                             06560000
PNUM := INDEX := INX := OUTX := 0;                                      06565000
OUTX := OUTLEN; << SKIP PAST ANY INITIAL STUFF >>                       06570000
                                                                        06575000
<< NOW GO TO WORK ON INPUT STRING & FORMAT >>                           06580000
                                                                        06585000
LOOP:                                                                   06590000
   IF (INBUFF(INDEX) = "!") OR                                 <<01456>>06595000
      (INBUFF(INDEX) = "\") THEN <<INSERT PARM OR NEXT MSGNO?>><<01456>>06600000
   BEGIN                                                                06605000
      TANK(INDEX-INX,INBUFF(INX));<<DUMP BUFF UP TO !>>                 06610000
      IF INBUFF(INDEX+1)=NUMERIC AND INLEN >INDEX+1 THEN                06615000
      BEGIN <<NEXT MSGNO !XXX >>                                        06620000
         FORMSG := BINARY(INBUFF(X),INLEN-X);                           06625000
         IF <> THEN CONDCODE:= CCG; <<BAD NEXTMSG>>                     06630000
         INLEN := INDEX;                                                06635000
         INX := INDEX + 1;  << ADVANCE PAST "!" >>             <<01524>>06640000
      END                                                               06645000
      ELSE                                                              06650000
      IF NOT MASK&CSL(1) THEN                                           06655000
      BEGIN << PARMS PRESENT >>                                         06660000
         INSERTPARM;                                                    06665000
         INX := INDEX+1; << ADVANCE PAST !>>                            06670000
      END                                                               06675000
      ELSE INX := INDEX; <<! WASN'T PARM >>                             06680000
   END;                                                                 06685000
                                                                        06690000
   << REFILL BUFF? >>                                                   06695000
   IF INDEX>=INLEN-1 THEN <<END OF LINE>>                      <<00616>>06700000
   BEGIN                                                                06705000
      IF INLEN>=0 THEN TANK(INDEX-INX+1,INBUFF(INX));          <<00662>>06710000
      IF OUTX <>0  << FLUSH OUT >>                                      06715000
         OR INLEN = 0 << NEED CRLF >> THEN PRINTIT;                     06720000
      INX := INDEX:= 0;                                                 06725000
      IF RECNO <> 0D THEN                                      <<02340>>06730000
      BEGIN                                                             06735000
         SIRN := GETSIR(MSGSIR);                                        06740000
         READCAT(RECNO,INBUFF',0D,0D); << No search block >>   <<04707>>06745000
            << NOW GET LENGTH,CRLF, CONT'D >>                           06750000
         IF < THEN CONDCODE := CCL;                                     06755000
         LENBUF(INBUFF,INLEN,CRLF,RECNO);                               06760000
         RELSIR(MSGSIR,SIRN);                                           06765000
         IF CONDCODE = CCL THEN RETURN;                                 06770000
         INDEX := -1; << RESET FOR LOOP>>                               06775000
      END                                                               06780000
      ELSE                                                              06785000
      GO OUTL << ALL FINISHED >>                                        06790000
   END;                                                                 06795000
   INDEX := INDEX+1;                                                    06800000
GO LOOP; <<END SCAN THRU MSG LOOP >>                                    06805000
                                                                        06810000
OUTL:                                                                   06815000
                                                                        06820000
END; << FORMSG >>                                                       06825000
$PAGE "GENMSG"                                                          06830000
INTEGER PROCEDURE GENMSG(SETNO,MSGNO,MASK,PARM1,PARM2,                  06835000
      PARM3,PARM4,PARM5,DEST,REPLY,OFFSET,DST,CONTROL);                 06840000
   VALUE   SETNO,MSGNO,MASK,PARM1,PARM2,PARM3,PARM4,PARM5,              06845000
           DEST,REPLY,OFFSET,DST,CONTROL;                               06850000
   INTEGER SETNO,MSGNO,DEST,DST;                                        06855000
   LOGICAL MASK,PARM1,PARM2,PARM3,PARM4,PARM5,REPLY,OFFSET,             06860000
      CONTROL;                                                          06865000
   OPTION VARIABLE,PRIVILEGED,UNCALLABLE;                               06870000
COMMENT                                                                 06875000
   THIS PROCEDURE IS A GENERAL MESSAGE HANDLER. IT FEATURES:            06880000
   - FINDING A MESSAGE IN THE MESSAGE CATALOG & PRINTING IT.            06885000
                                                               <<01321>>06890000
   - INSERTING PARAMETERS INTO MESSAGES, EITHER FROM THE                06895000
     MESSAGE CATALOG OR FROM AN INPUT STRING.                           06900000
   - PRINTING A MESSAGE ON $STDLIST, THE SYSTEM CONSOLE,                06905000
     TO A SPECIFIED LDEV, OR TO A FILE.                                 06910000
   - RETURNING THE NEXT MESSAGE NUMBER AS SPECIFIED IN THE              06915000
     MESSAGE CATALOG.                                                   06920000
PARAMETERS                                                              06925000
   SETNO - REQUIRED PARM. SET NUMBER FROM CATALOG.                      06930000
   MSGNO - REQUIRED PARM.                                               06935000
           IF SETNO > 0  - MESSAGE NUMBER WITHIN MESSAGE SET.           06940000
                           MSGNO >= 0.                                  06945000
           IF SETNO = -1 - STRING TO BE FORMATTED IS PASSED IN,         06950000
                           RATHER THAN FOUND IN CATALOG.                06955000
                           'MSGNO' CONTAINS BYTE ADDRESS ON             06960000
                           WORD BOUNDARY. STRING MUST BE                06965000
                           TERMINATED BY ZERO.                          06970000
           IF SETNO =-2  - SAME AS -1, EXCEPT CCTL = %320               06975000
                           INSTEAD OF 0.                                06980000
   MASK  - INDICATES TYPES OF ANY PARAMETERS WHICH ARE PASSED.          06985000
           MASK.(1:3) = TYPE OF PARM1.                                  06990000
           MASK.(4:3) = TYPE OF PARM2.                                  06995000
           MASK.(7:3) = TYPE OF PARM3.                                  07000000
           MASK.(10:3)= TYPE OF PARM4.                                  07005000
           MASK.(13:3)= TYPE OF PARM5.                                  07010000
                                                                        07015000
           TYPE = 0 - PARM IS STRING BYTE POINTER (I.E.                 07020000
                      @STRING). STRING IS TERMINATED BY ZERO.           07025000
                  1 - PARM IS INTEGER BY VALUE.                         07030000
                  2 - PARM IS DOUBLE BY REFERENCE (I.E.                 07035000
                      @DOUBLE).                                         07040000
   PARMX - PARAMETER, AS INDICATED BY MASK. PARM1 SUBSTITUTES           07045000
           FOR THE LEFTMOST PARAMETER IN THE MESSAGE, PARM2             07050000
           FOR THE NEXT PARAMETER TO THE RIGHT, AND SO FORTH.           07055000
           IF PARM(N) IF PRESENT, PARM(N-1) MUST BE PRESENT.            07060000
           IF PARM IS A STRING, A BYTE ADDRESS MUST BE PASSED           07065000
           (I.E. @STRING).                                              07070000
   DEST  - DESTINATION OF MESSAGE.                                      07075000
           MISSING - PRINT ON $STDLIST. FOR SYSTEM PROCESSES,           07080000
                     NO PCB/NO WAIT I/0 TO CONSOLE. SOFT-               07085000
                     PREEMPTION IS DONE                                 07090000
           = < -2  - NEGATIVE FILE NUMBER. FWRITE TO -DEST IS           07095000
                     DONE.                                              07100000
           = -2    - $STDLIST. IF SYSTEM PROCESS, THEN NO PCB/          07105000
                     NO WAIT I/O TO CONSOLE. SOFT-PREEMPTION            07110000
                     IS DEFAULT.                                        07115000
           = -1    - NOWHERE.  MESSAGE DISAPPEARS.             <<01321>>07120000
           = 0     - CONSOLE, NO PCB/NO WAIT I/O. SOFT-                 07125000
                     PREEMPTION IS DEFAULT.                             07130000
                     PREFIX IS ADDED TO MSG CONTAINING TIME             07135000
                     STAMP/[#J/S]/PIN/.                                 07140000
   REPLY - (CONSOLE ONLY). FORMAT SPECIFICATIONS FOR REPLY.             07145000
           XPECTED FROM CONSOLE MESSAGE.                                07150000
           REPLY.( 0:8) = MAXIMUM STRING LENGTH                         07155000
                          (REPLY TYPE 2 & 4 ONLY).             <<00813>>07160000
                                                                        07165000
           REPLY.(8:8) = REPLY TYPE.                           <<00620>>07170000
                         0 - NUMBER                                     07175000
                         1 - YES OR NO                                  07180000
                         2 - STRING                                     07185000
                         3 - YES/NO OR NUMBER                  <<00620>>07190000
                         4 - ONE STRING. (CURRENTLY USED FOR   <<00620>>07195000
                                  THE INTRINSIC PRINTOPREPLY)  <<00620>>07200000
   OFFSET- (CONSOLE ONLY). WORD ADDRESS FOR FORMATTED REPLY.            07205000
           IF 'DST' IS PRESENT, THEN SEGMENT RELATIVE,                  07210000
           OTHERWISE DB RELATIVE. REPLIES ARE FORMATTED AS              07215000
           FOLLOWS:                                                     07220000
           REPLY TYPE   CONTENTS AT 'OFFSET'                            07225000
           ----------   -------------------                             07230000
           0 -(NUM)     BINARY VALUE OF NUMBER TYPED BY                 07235000
                        OPERATOR.                                       07240000
           1 -(Y/N)     TRUE FOR "YES", FALSE FOR "NO".                 07245000
           2 -(STRING)  FIRST WORD CONTAINS CHARACTER COUNT.            07250000
                        STRING STARTS AT SECOND WORD.                   07255000
           3 -(NUM OR                                          <<00620>>07260000
                  Y/N)   SAME AS EITHER REPLY TYPES 0 OR 1     <<00620>>07265000
           4 -(1 STRING) SAME AS REPLY TYPE 2                  <<00620>>07270000
   DST   - (CONSOLE ONLY). IF PRESENT INDICATES DATA SEGMENT            07275000
           FOR REPLY.                                                   07280000
   CONTROL - (TERMINALS ONLY) FLAG WORD.                                07285000
             .(0:1)  = EACH WRITE WILL HAVE CCTL %320.                  07290000
                                                                        07295000
             .(2:2)  = FUNNY TERMTYPE. TRANSLATE INTO APL.              07300000
                                                                        07305000
             .(14:2) = IOTYPE FOR ATTACHIO.                             07310000
                       0 - STANDARD.                                    07315000
                       1 - SOFT PREEMPTION.                             07320000
                       2 - HARD PREEMTPION.                             07325000
CONSOLE REPLY RULES.                                                    07330000
   REPLIES ARE FORMATTED BY PROGEN AND RESULT (NOT RAW INPUT            07335000
   AT CONSOLE) IS PLACED IN 'OFFSET'. A '?' IS PLACED AT THE            07340000
   BEGINNING OF THE MESSAGE. TYPE OF REPLY EXPECTED MUST BE IN          07345000
   THE MESSAGE ITSELF (I.E. '(Y/N)' MUST BE SUPPLIED).                  07350000
   MESSAGES REQUIRING A REPLY ARE TRUNCATED IN REPLY                    07355000
   INFORMATION TABLE (CURRENT LIMIT = 74 -TOTAL PREFIX SIZE).           07360000
RETURNS                                                                 07365000
   NEXT MESSAGE NUMBER FROM CATALOG (!XXX). IF NONE, -1 IS              07370000
   RETURNED.                                                            07375000
CONDITION CODE                                                          07380000
   CCE = EVERYTHING OK                                                  07385000
   CCL = I/O FAILURE (ATTACHIO, FWRITE).                                07390000
   CCG = SOMETHING WRONG WITH CALL.  TRIED BEST TO PRINT SOMETHING.     07395000
;                                                                       07400000
BEGIN                                                                   07405000
                                                                        07410000
INTEGER                                                                 07415000
   SAVERITSIR,                                                 << 7488>>07420000
   ZERO := 0,                                                  <<00813>>07425000
   LEN,                                                                 07430000
   LPDT'INDEX,                                                 <<06588>>07435000
   OUTBUFFSIZE,                                                         07440000
   INDEX = OUTBUFFSIZE,                                                 07445000
   FUNNYSCR = OUTBUFFSIZE;                                              07450000
                                                                        07455000
LOGICAL CONSOLE; << INDICATES TO ADD PREFIX >>                          07460000
                                                                        07465000
BYTE POINTER INBUFF;                                                    07470000
INTEGER TMP;                                                   <<04882>>07475000
LOGICAL PENDING; << USED TO EXIT PROCEDURE W/O OP REPLY >>     <<04882>>07480000
LOGICAL NOPROBLEM;                                             <<04882>>07485000
POINTER OUTBUFF';                                                       07490000
POINTER CONSBUFF';                                                      07495000
LOGICAL PCBPT;                                                 <<06590>>07500000
ARRAY                                                          <<00813>>07505000
   CHAR'ZERO(0:1);                                             <<00813>>07510000
ARRAY QARRAY(*)=Q + 0;                                         << 7469>>07515000
INTEGER PCBGLOBLOC;                                            << 7469>>07520000
                                                                        07525000
                                                                        07530000
SUBROUTINE DEF'MOVEFROMDSEG;                                            07535000
SUBROUTINE DEF'MOVETODSEG;                                     <<00813>>07540000
                                                                        07545000
                                                                        07550000
SUBROUTINE MASKPARMS;                                                   07555000
BEGIN                                                                   07560000
                                                                        07565000
IF PMASK.PPMASK AND NOT MASK&CSL(1) THEN                                07570000
BEGIN                                                                   07575000
   PMASK := PMASK &CSR(5); <<RIGHT JUSTIFY>>                            07580000
   INDEX := 0;                                                          07585000
   DO BEGIN                                                             07590000
      IF NOT PMASK &CSR(INDEX) THEN MASK.(13:3)                         07595000
         := 3; << IGNORE PARM >>                                        07600000
      MASK := MASK &CSR(3);                                             07605000
   END UNTIL (INDEX := INDEX+1) >=5;                                    07610000
   PMASK := PMASK &CSL(5);                                              07615000
   MASK := MASK &CSR(1);                                                07620000
END                                                                     07625000
ELSE MASK := -1; <<IGNORE ALL PARMS>>                                   07630000
                                                                        07635000
END; << MASKPARMS >>                                                    07640000
                                                                        07645000
                                                                        07650000
<< MAIN PROCEDURE BODY >>                                               07655000
<< Check to see if the message facility is set up.  If not, >> <<06023>>07660000
<< there is nothing that can be done (since system logging  >> <<06023>>07665000
<< is probably not up either.                               >> <<06023>>07670000
   IF MSGDSTN = 0 THEN                                         <<06023>>07675000
   BEGIN                                                       <<06023>>07680000
      CONDCODE := CCL;                                         <<06023>>07685000
      RETURN;                                                  <<06023>>07690000
   END;                                                        <<06023>>07695000
                                                               <<06023>>07700000
                                                                        07705000
<<***** VARIABLE SET-UP       *****>>                                   07710000
PENDING := TRUE;  << ASSUME THERE IS ROOM >>                   <<04882>>07715000
CONDCODE := CCE;                                                        07720000
CONSOLE := << FALSE >> LEN := 0;                                        07725000
                                                                        07730000
<<***** CHECK REQUIRED PARMS       *****>>                              07735000
                                                                        07740000
IF NOT (PMASK.PSETNO LOR PMASK.PMSGNO) THEN                             07745000
   CCGRETN; << OMITTED REQUIRED PARMS >>                                07750000
IF PMASK.PREPLY AND NOT PMASK.POFFSET THEN CCGRETN;                     07755000
<< OFFSET REQUIRED FOR REPLY >>                                         07760000
                                                                        07765000
<<***** SET-UP PARMS          *****>>                                   07770000
                                                                        07775000
MASKPARMS;                                                              07780000
                                                                        07785000
<<***** SET-UP CONTROL      *****>>                                     07790000
                                                                        07795000
IF NOT PMASK.PCONTROL THEN CONTROL := 0;                                07800000
                                                                        07805000
<<***** RESOLVE DESTINATION ******>>                                    07810000
<<      AND PREEMPTION            >>                                    07815000
                                                                        07820000
PCBPT := CURPRC;                                               <<06590>>07825000
IF PMASK.PDEST THEN                                                     07830000
BEGIN << DEST SUPPLIED, NOT $STDLIST >>                                 07835000
   IF DEST > 0 THEN                                                     07840000
   BEGIN << CHECK FOR VALID LDEV, MAY BE SPOOLED >>                     07845000
      LPDT'INDEX:=DEST*INTEGER(LPDT'ENTRY'SIZE);               <<06588>>07850000
      IF LPDT'VIRTUAL'DEVICE = 1  << Possible Spoolfile >>     <<06588>>07855000
         THEN CCGRETN;                                                  07860000
   END;                                                                 07865000
   IF DEST = -2 AND PROCSTATE.SYSTEMPROCFLAG <> 0 THEN         <<06590>>07870000
   BEGIN << $STDLIST FOR SYSTEM PROC. IS CONSOLE >>                     07875000
      DEST := SYS'CONSOLE'LDEV;                                <<06877>>07880000
      IF CONTROL.(14:2) = 0 THEN CONTROL.(14:2) := 1;                   07885000
         << FORCE SOFT-PREEMPTIVE >>                                    07890000
   END;                                                                 07895000
   IF DEST = 0 THEN << CONSOLE MSG. NEEDS PREFIX >>                     07900000
   BEGIN                                                                07905000
      DEST := SYS'CONSOLE'LDEV;                                <<06877>>07910000
      CONSOLE := TRUE;                                                  07915000
   END;                                                                 07920000
END                                                                     07925000
ELSE                                                                    07930000
IF PROCSTATE.SYSTEMPROCFLAG <> 0 THEN                          <<06590>>07935000
BEGIN  << NO DEST SUPPLIED >>                                           07940000
   DEST := SYS'CONSOLE'LDEV;                                   <<06877>>07945000
   IF CONTROL.(14:2) = 0 THEN CONTROL.(14:2) := 1;                      07950000
      << FORCE SOFT-PREEMPTIVE >>                                       07955000
END                                                                     07960000
ELSE DEST := -2;                                                        07965000
   << CONSOLE FOR SYSTEM PROCESS, $STDLIST OTHERWISE>>                  07970000
                                                                        07975000
IF (CONSOLE OR PMASK.PREPLY) AND CONTROL.(14:2)=0 THEN CONTROL.(14:2)   07980000
   := 1; << FORCE SOFT PREEMPTIVE >>                                    07985000
                                                                        07990000
IF DEST = -2 THEN                                                       07995000
BEGIN << IF $STDLIST, CHECK FOR FUNNYTERM >>                            08000000
PXGLOBAL;                                                      << 7469>>08005000
   << Grab the JMAT word containing the funny terminal bits >> <<06592>>08010000
                                                               <<06592>>08015000
   MOVEFROMDSEG(@FUNNYSCR,JMATDST,PXG'JMATINX                  << 7469>>08020000
                *JMATENTRYSIZE + JMATFTBITSOFF,1);             <<06592>>08025000
                                                               <<06592>>08030000
   CONTROL.FUNNYTERM := FUNNYSCR.JMATFTBITSEXT;<< APL? >>      <<06592>>08035000
   << FUNNYTERM MAY BE PASSED IN CONTROL, OR >>                         08040000
   << FOUND WHEN LOOKING AT $STDLIST         >>                         08045000
END;                                                                    08050000
                                                                        08055000
<< TAKE CARE OF SETNO >>                                                08060000
                                                                        08065000
IF SETNO = -2 THEN                                                      08070000
BEGIN                                                                   08075000
   SETNO := -1;                                                         08080000
   CONTROL.(0:1) := 1;                                                  08085000
END;                                                                    08090000
                                                                        08095000
<<***** DONE WITH CONTROL *****>>                                       08100000
                                                                        08105000
<<***** SET-UP INPUT BUFF   *****>>                                     08110000
                                                                        08115000
IF SETNO = -1 THEN @INBUFF := MSGNO << SUPPLIED >>                      08120000
ELSE                                                                    08125000
BEGIN                                                                   08130000
   ASSEMBLE(ZERO; LRA S-0);                                             08135000
   @INBUFF := TOS &LSL(1);                                              08140000
   ASSEMBLE(ADDS BUFFSIZEM1);                                           08145000
END;                                                                    08150000
                                                                        08155000
<<***** SET-UP OUTPUT BUFF  *****>>                                     08160000
                                                                        08165000
IF CONSOLE OR PMASK.PREPLY THEN                                         08170000
BEGIN << ALLOCATE OUTPUT BUFFER 'SYSTEM BUFFER' SIZE >>                 08175000
   << BUFFER SIZE LIMITED FOR REPLYS. IF REPLY TOO LONG, >>             08180000
   << PART OF MSG WILL BE LOST FOR =RECALL.              >>             08185000
   ASSEMBLE( ZERO; LRA S-0 );                                           08190000
   @CONSBUFF' := TOS;                                                   08195000
   TOS := RIT'MSGBASE +SBUFSIZEWM1;                            <<04882>>08200000
   ASSEMBLE( ADDS 0 );                                                  08205000
   OUTBUFFSIZE := SBUFSIZE; << SET BUFFSIZE >>                          08210000
   @OUTBUFF' := @CONSBUFF'(RIT'MSGBASE); << BASE OF BUFF >>    <<04882>>08215000
END                                                                     08220000
ELSE                                                                    08225000
BEGIN << ALLOCATE BUFFER 'RECSIZE'. CAN RE-USE BUFF>>                   08230000
   ASSEMBLE(ZERO; LRA S-0);                                             08235000
   @OUTBUFF' := TOS;                                                    08240000
   ASSEMBLE( ADDS BUFFSIZEM1);                                          08245000
   OUTBUFFSIZE := BUFFSIZEB;                                            08250000
END;                                                                    08255000
                                                                        08260000
<<***** PUT IN PREFIX STRING IN OUTPUT BUFF IF CONSOLE***>>             08265000
                                                                        08270000
IF CONSOLE OR PMASK.PREPLY THEN LEN:=CONSPREFIX(PMASK.PREPLY,  <<00552>>08275000
   OUTBUFF');                                                           08280000
                                                                        08285000
<<***** NOW ASSEMBLE MESSAGE   ***** >>                                 08290000
                                                                        08295000
TMP := LEN;                                                    <<04882>>08300000
IF NOT PMASK.PREPLY THEN                                       <<04882>>08305000
     GENMSG :=FORMSG(INBUFF,SETNO,MSGNO,MASK,PARM1,PARM2,PARM3 <<04882>>08310000
          ,PARM4,PARM5,OUTBUFF',OUTBUFFSIZE,LEN,DEST,CONTROL)  <<04882>>08315000
     ELSE GENMSG:=FORMSG(INBUFF,SETNO,MSGNO,MASK,PARM1,PARM2,  <<04882>>08320000
        PARM3,PARM4,PARM5,OUTBUFF',OUTBUFFSIZE,TMP,-1,CONTROL);<<04882>>08325000
<< THE SECOND GENMSG WILL FORMAT INBUF TO BE PUT IN THE RIT >> <<04882>>08330000
<< BUT SINCE FORMSG WILL BE CALLED LATER, THE VARIABLE LEN  >> <<04882>>08335000
<< CANNOT BE CHANGED, SO TMP IS USED. THE DESTINATION IS -1 >> <<04882>>08340000
<< SO THE MESSAGE WILLL NOT BE PRINTED ANYWHERE             >> <<04882>>08345000
     IF < THEN CONDCODE := CCL                                 <<04882>>08350000
          ELSE IF > THEN CONDCODE := CCG;                      <<04882>>08355000
                                                                        08360000
<<***** HANDLE REPLY (MAY BE FOR CONSOLE OR OUTBUFFSIZE)*****>>         08365000
                                                                        08370000
IF PMASK.PREPLY AND CONDCODE <> CCL THEN                       <<04882>>08375000
<< IF NO I/O FAIL, CONSOLE, & REPLY >>                                  08380000
BEGIN                                                                   08385000
   IF NOT PMASK.PDST THEN DST := 0;                                     08390000
                                                               <<00813>>08395000
<< ......................................................... >><< 7592>>08400000
<<   Place the reply in the Reply Information Table (RIT)    >><< 7592>>08405000
<<   Note that PUTRITENTRY takes the RIT SIR and does not    >><< 7592>>08410000
<<   release it if successful.  This allows us to release the>><< 7592>>08415000
<<   SIR before we WAIT and thus prevent someone from reply- >><< 7592>>08420000
<<   ing too soon and hanging at the WAIT (an old problem)   >><< 7592>>08425000
<<   If PUTRITENTRY fails, it releases the SIR               >><< 7592>>08430000
<< ......................................................... >><< 7592>>08435000
                                                               << 7592>>08440000
                                                               << 7488>>08445000
   NOPROBLEM:=PUTRITENTRY(MYPIN,DST,OFFSET,REPLY,TMP           <<04882>>08450000
                ,CONSBUFF', SAVERITSIR);                       << 7592>>08455000
   IF NOPROBLEM                                                <<04882>>08460000
      THEN GENMSG :=FORMSG(INBUFF,SETNO,MSGNO,MASK,PARM1,PARM2,<<04882>>08465000
                           PARM3,PARM4,PARM5,OUTBUFF',         <<04882>>08470000
                           OUTBUFFSIZE,LEN,DEST,CONTROL)       <<04882>>08475000
      ELSE PENDING := FALSE; << NO ROOM IN TABLE >>            <<04882>>08480000
                                                               <<00813>>08485000
   << WAIT FOR REPLY. WILL AWAKEN WHEN RIT ENTRY DELETED >>    <<00813>>08490000
      IF PENDING THEN                                          << 7488>>08495000
      BEGIN                                                    << 7488>>08500000
        << PUTRITENTRY grabbed the RIT SIR >>                  << 7592>>08505000
         PDISABLE;    << keep the machine until we WAIT >>     << 7488>>08510000
         RELSIR( RIT'SIR, SAVERITSIR );                        << 7488>>08515000
         WAIT( %40, 0 );  << Does implicit PENABLE. >>         << 7488>>08520000
      END;                                                     << 7592>>08525000
                                                               <<00813>>08530000
   << CHECK SOFT KILL BIT IN PCB TO SEE IF THIS PROCESS IS >>  <<00813>>08535000
   << TO BE ABORTED BUT CAN'T RIGHT NOW BECAUSE IT'S >>        <<00813>>08540000
   << CRITICAL. >>                                             <<00813>>08545000
   IF PROCSTATE.SOFTKILLFLAG = 1 OR NOT PENDING                <<06590>>08550000
      THEN                                                     <<04882>>08555000
      << TRYING TO ABORT THIS PROCESS. FAKE AN OPERATOR >>     <<00813>>08560000
      << REPLY OF 0 SO THAT PROCESS WILL EVENTUALLY ABORT. >>  <<00813>>08565000
      IF REPLY.(8:8) = REPLYTYPE'STRINGS OR                    <<00813>>08570000
               REPLY.(8:8) = REPLYTYPE'ONESTRING THEN          <<00813>>08575000
         BEGIN                                                 <<00813>>08580000
         MOVE CHAR'ZERO := ( 1 <<BYTE COUNT>>, "0" );          <<00813>>08585000
         MOVETODSEG(CONSBUFF'(1),CONSBUFF'(2),@CHAR'ZERO,2);   <<00813>>08590000
         CONDCODE := CCL;                                      <<04882>>08595000
         END                                                   <<00813>>08600000
      ELSE BEGIN                                               <<04882>>08605000
         MOVETODSEG(CONSBUFF'(1),CONSBUFF'(2),@ZERO,1);        <<00813>>08610000
         CONDCODE := CCL;                                      <<04882>>08615000
         END;                                                  <<04882>>08620000
END;                                                                    08625000
                                                                        08630000
OUTL:                                                                   08635000
END; << GENMSG >>                                                       08640000
$TITLE "GENMSGU"                                                        08645000
PROCEDURE GENMSGU(A,B);                                                 08650000
   VALUE A,B;INTEGER A,B;                                               08655000
   OPTION PRIVILEGED;                                                   08660000
BEGIN                                                                   08665000
                                                                        08670000
ERRORON;                                                                08675000
GENMSG(A,B);                                                            08680000
ERROREXIT([10/85,6/2],0,0);<< INTRIN#85:EXIT2 >>                        08685000
                                                                        08690000
END; << GENMSGU >>                                                      08695000
$TITLE "CONSPREFIX"                                                     08700000
INTEGER PROCEDURE CONSPREFIX(CONSREPLY,BUFF');                          08705000
   VALUE CONSREPLY;                                                     08710000
   LOGICAL CONSREPLY;                                                   08715000
   ARRAY BUFF';                                                         08720000
   OPTION INTERNAL;                                                     08725000
COMMENT                                                                 08730000
   RETURNS "<TIME>[/#J\SXXX]/<PIN>/"                                    08735000
RETURNS - LENGTH OF PREFIX.                                             08740000
;                                                                       08745000
BEGIN                                                                   08750000
                                                                        08755000
EQUATE JIT = 6;                                                         08760000
                                                                        08765000
INTEGER                                                                 08770000
   INDEX = CONSPREFIX;                                                  08775000
                                                                        08780000
ARRAY QARRAY(*)= Q + 0;                                        << 7469>>08785000
INTEGER PCBGLOBLOC;                                            << 7469>>08790000
LOGICAL                                                                 08795000
   JOBNUM;                                                              08800000
                                                                        08805000
POINTER PXPTR;                                                          08810000
                                                               <<06590>>08815000
LOGICAL PCBPT;                                                 <<06590>>08820000
                                                                        08825000
DOUBLE HRSMIN;                                                          08830000
INTEGER HRS = HRSMIN;                                                   08835000
                                                                        08840000
BYTE ARRAY BUFF(*) = BUFF';                                             08845000
INTRINSIC CLOCK;                                                        08850000
                                                                        08855000
SUBROUTINE DEF'MOVEFROMDSEG;                                            08860000
                                                                        08865000
   << CONSOLE PREFIX :                                                  08870000
   <<  [?][H1]H2:MM[/#{J/S}X12[X3-5]]/PN/                               08875000
   >>                                                                   08880000
PCBPT := CURPRC;                                               <<06590>>08885000
IF CONSREPLY THEN                                                       08890000
BEGIN                                                                   08895000
   BUFF := "?";                                                         08900000
   INDEX := 1;                                                          08905000
END                                                                     08910000
ELSE INDEX := 0;                                                        08915000
                                                                        08920000
<< GET TIME >>                                                          08925000
                                                                        08930000
HRSMIN := CLOCK;                                                        08935000
INDEX := INDEX +ASCII(HRS.(0:8),10,BUFF(INDEX)); << HOURS >>            08940000
MOVE BUFF(INDEX) := ":00";                                              08945000
INDEX := INDEX +2;                                                      08950000
ASCII(HRS.(8:8),-10,BUFF(INDEX));<< SOLVES 0-9 MIN. PROBLEM >>          08955000
INDEX := INDEX +1;                                                      08960000
                                                                        08965000
   << GET #J/S NUM >>                                                   08970000
                                                                        08975000
IF PROCSTATE.SYSTEMPROCFLAG = 0 THEN                           <<06590>>08980000
BEGIN << USER PROCESS >>                                                08985000
      << PUT IN #J/S NUMBER >>                                          08990000
   MOVE BUFF(INDEX) := "/#";                                            08995000
   INDEX := INDEX +2;                                                   09000000
   PXGLOBAL;                                                   << 7469>>09005000
   MOVEFROMDSEG(@JOBNUM,PXG'JITDST,JIT'JOB'INFO'PTR,1);        << 7469>>09010000
   BUFF(INDEX) := IF JOBNUM.(0:1) THEN "J" ELSE "S";                    09015000
   INDEX := INDEX +1;                                                   09020000
   INDEX := INDEX +ASCII(JOBNUM.(2:14),10,BUFF(INDEX));                 09025000
END;                                                                    09030000
   BUFF(INDEX) := "/";                                                  09035000
   INDEX := INDEX +1;                                                   09040000
                                                                        09045000
   << ADD IN PIN >>                                                     09050000
INDEX := INDEX +ASCII(MYPIN,10,BUFF(INDEX));                            09055000
BUFF(INDEX) := "/";                                                     09060000
INDEX := INDEX +1;                                                      09065000
                                                                        09070000
   << CONSPREFIX = INDEX >>                                             09075000
                                                                        09080000
END; << CONSPREFIX >>                                                   09085000
                                                                        09090000
$TITLE "INITMSG"                                                        09095000
PROCEDURE INITMSG;                                                      09100000
   OPTION UNCALLABLE;                                                   09105000
COMMENT                                                                 09110000
   THIS PROCEDURE INITIALIZES THE MESSAGE SYSTEM.                       09115000
   - THE DISC ADDRESS OF THE MESSAGE CATALOG IS PUT IN SYS DB.          09120000
   - THE MESSAGE DIRECTORY DATA SEGMENT IS CREATED & STUFFED.           09125000
   - THE MESSAGE DST BUFFER IS OBTAINED AND INITIALIZED.       <<02802>>09130000
RETURNS                                                                 09135000
   CCE = EVERYTHING OK.                                                 09140000
   CCL = SOMETHING WRONG.                                               09145000
;                                                                       09150000
BEGIN                                                                   09155000
                                                                        09160000
ARRAY DIRECTORY(0:MSGDIRSIZE-1);                                        09165000
BYTE ARRAY BUFF(*) = DIRECTORY;                                         09170000
                                                                        09175000
INTEGER                                                                 09180000
   DSTN1,                                                               09185000
   OLDMSGDSTN,                                                 <<00820>>09190000
   SIRN,                                                                09195000
   CATFN,                                                               09200000
   ECODE;                                                               09205000
                                                                        09210000
                                                                        09215000
DOUBLE                                                         <<00820>>09220000
   LABELADR,                                                   <<00820>>09225000
   OLDLABEL;                                                   <<00820>>09230000
LOGICAL                                                                 09235000
   LABELADR1    = LABELADR,                                    <<00820>>09240000
   LABELADR2    = LABELADR +1,                                 <<00820>>09245000
   OLDLABEL1    = OLDLABEL,                                    <<00820>>09250000
   OLDLABEL2    = OLDLABEL +1;                                 <<00820>>09255000
EQUATE                                                         <<00820>>09260000
   FILELABEL'ERROR = 47,                                       <<00820>>09265000
   PURGEOK         = TRUE,                                     <<00820>>09270000
   NOPURGE         = FALSE;                                    <<00820>>09275000
                                                                        09280000
SUBROUTINE ERR(NUM);                                                    09285000
   VALUE NUM;                                                           09290000
   INTEGER NUM;                                                         09295000
BEGIN                                                                   09300000
   CASE NUM OF                                                 <<00820>>09305000
   BEGIN                                                                09310000
   <<0>>BEGIN                                                  <<00820>>09315000
        FCHECK(CATFN,ECODE);                                   <<00820>>09320000
        MOVE BUFF := ("**FILE ERROR ON CATALOG (!)",0);        <<00820>>09325000
        END;                                                   <<00820>>09330000
   <<1>>BEGIN                                                  <<00820>>09335000
        FCHECK(CATFN,ECODE);                                   <<00820>>09340000
        MOVE BUFF := ("**GETDATASEG FAILED ON CATALOG",0);     <<00820>>09345000
        END;                                                   <<00820>>09350000
   <<2>>BEGIN                                                  <<00820>>09355000
        ECODE := FILELABEL'ERROR;                              <<00820>>09360000
        MOVE BUFF := ("**FILE ERROR ON CATALOG (!)",0);        <<00820>>09365000
        END;                                                   <<00820>>09370000
   END;                                                                 09375000
   GENMSG(-1,@BUFF,%10000,ECODE);                                       09380000
   CONDCODE := CCL;                                                     09385000
END; << ERR >>                                                          09390000
                                                                        09395000
SUBROUTINE DEF'MOVETODSEG;                                              09400000
SUBROUTINE GET'MSG'DST;                                        <<02802>>09405000
BEGIN                                                          <<02802>>09410000
                                                               <<02802>>09415000
<<IF MESSAGE DST ALREADY EXISTS, RETURN>>                      <<02802>>09420000
IF IOMSGDST <> 0 THEN                                          <<02802>>09425000
  RETURN;                                                      <<02802>>09430000
                                                               <<02802>>09435000
<< OBTAIN A DST >>                                             <<02802>>09440000
                                                               <<02802>>09445000
                                                               <<02802>>09450000
<< NOW, FIGURE LENGTH OF XDS >>                                <<02802>>09455000
DSTN1:=(SBUFSIZEW * NUM'MSG'BUFS) + 4 <<OVERHEAD>> ;           <<02802>>09460000
                                                               <<02802>>09465000
IOMSGDST := GETDATASEG(DSTN1,DSTN1);                           <<02802>>09470000
IF IOMSGDST = 0 THEN                                           <<02802>>09475000
  RETURN;       <<FAILED TO GET XDS>>                          <<02802>>09480000
                                                               <<02802>>09485000
<< INITIALIZE XDS >>                                           <<02802>>09490000
DIRECTORY := NUM'MSG'BUFS;     <<NUMBER OF MESSAGE BUFFERS>>   <<02802>>09495000
DIRECTORY(1) := SBUFSIZEW;     <<SIZE OF MESSAGE BUFFER>>      <<02802>>09500000
DIRECTORY(2) := 4;             <<POINTER TO FIRST AVAIL>>      <<02802>>09505000
DIRECTORY(3) := (SBUFSIZEW*(NUM'MSG'BUFS-1))+4; << TAIL PTR >> <<02802>>09510000
MOVETODSEG(IOMSGDST,0,@DIRECTORY,4);                           <<02802>>09515000
                                                               <<02802>>09520000
<<LOOP & THREAD POINTERS>>                                     <<02802>>09525000
DSTN1 := 0;            <<LOOP BUFFER INDEX>>                   <<02802>>09530000
ECODE := 4;    <<START DISPLACEMENT OF BUFFERS>>               <<02802>>09535000
WHILE (DSTN1 := DSTN1 + 1) < NUM'MSG'BUFS DO                   <<02802>>09540000
  BEGIN                                                        <<02802>>09545000
  DIRECTORY := ECODE + SBUFSIZEW; <<PTR TO NEXT BUFFER>>       <<02802>>09550000
  MOVETODSEG(IOMSGDST,ECODE,@DIRECTORY,1);                     <<02802>>09555000
  ECODE := ECODE + SBUFSIZEW; <<POINT TO NEXT BUFFER>>         <<02802>>09560000
  END;                                                         <<02802>>09565000
                                                               <<02802>>09570000
<< PLACE ZERO LINK POINTER INTO LAST BUFFER >>                 <<02802>>09575000
DIRECTORY := 0;                                                <<02802>>09580000
MOVETODSEG(IOMSGDST,ECODE,@DIRECTORY,1);                       <<02802>>09585000
END;                                                           <<02802>>09590000
                                                               <<02802>>09595000
                                                                        09600000
GET'MSG'DST;  <<GET & INIT MSG BUFFERS>>                       <<02802>>09605000
                                                               <<02802>>09610000
CONDCODE := CCE;                                                        09615000
                                                                        09620000
<< OPEN MESSAGE CATALOG >>                                              09625000
MOVE BUFF := "CATALOG ";                                                09630000
CATFN := FOPEN(BUFF,5,0); <<OLDPERM,ASCII>>                             09635000
IF <> THEN ERR(0)                                                       09640000
ELSE                                                                    09645000
BEGIN                                                                   09650000
   FGETINFO(CATFN,,,,,,,,,,,,,,,,,,,LABELADR);                          09655000
   IF <> THEN ERR(0)                                                    09660000
   ELSE                                                                 09665000
   BEGIN                                                                09670000
                                                                        09675000
      << READ LABEL & GET MESSAGE DIRECTORY >>                          09680000
      FREADLABEL(CATFN,DIRECTORY,MSGDIRSIZE,0);                         09685000
      IF <> THEN ERR(0)                                                 09690000
      ELSE                                                              09695000
      BEGIN                                                             09700000
                                                                        09705000
         << GET DATA SEGMENT FOR DIRECTORY & MESSAGE BUFFER >>          09710000
         DSTN1 := GETDATASEG(PHYSBLK+MSGDIRSIZE,PHYSBLK+                09715000
            MSGDIRSIZE);                                                09720000
         IF DSTN1 = 0 THEN ERR(1)                                       09725000
         ELSE                                                           09730000
         BEGIN                                                          09735000
                                                                        09740000
            << PUT DIRECTORY IN DATA SEG >>                             09745000
            MOVETODSEG(DSTN1,0,@DIRECTORY,MSGDIRSIZE);                  09750000
                                                               <<00820>>09755000
            << MAKE NEW CATALOG NON-PURGEABLE >>               <<00820>>09760000
            SETLOCKSTATUS(LABELADR,NOPURGE);                   <<00820>>09765000
            IF <> THEN                                         <<00820>>09770000
            BEGIN                                              <<00820>>09775000
              RELDATASEG(DSTN1);                               <<00820>>09780000
              ERR(2);                                          <<00820>>09785000
            END                                                <<00820>>09790000
            ELSE                                               <<00820>>09795000
            BEGIN                                              <<00820>>09800000
                                                               <<00820>>09805000
                                                               <<00820>>09810000
               SIRN := GETSIR(MSGSIR);                         <<00820>>09815000
                                                               <<00820>>09820000
               << SAVE OLD LABEL AND DST >>                    <<00820>>09825000
               OLDLABEL1 := ABSOLUTE(MSGBASE);                 <<00820>>09830000
               OLDLABEL2 := ABSOLUTE(X:=X+1);                  <<00820>>09835000
               OLDMSGDSTN := MSGDSTN;                          <<00820>>09840000
               << STUFF DISC ADDRESS IN SYSDB.      >>         <<00820>>09845000
               << FILE MUST BE 1 EXTENT>>                      <<00820>>09850000
               ABSOLUTE(MSGBASE) := LABELADR1;                 <<00820>>09855000
               ABSOLUTE(X:=X+1) := LABELADR2;                  <<00820>>09860000
                                                               <<00820>>09865000
               << STUFF SYS DB WITH DATSEG NO. >>              <<00820>>09870000
               MSGDSTN:= DSTN1;  << PUT IN SYS DB >>           <<00820>>09875000
                                                               <<00820>>09880000
               RELSIR(MSGSIR,SIRN);                            <<00820>>09885000
                                                               <<00820>>09890000
               << UNLOCK OLD CAT IF ONE EXISTED >>             <<00820>>09895000
               IF OLDMSGDSTN <> 0 THEN                         <<00820>>09900000
                  SETLOCKSTATUS(OLDLABEL,PURGEOK);             <<00820>>09905000
               IF <> THEN                                      <<00820>>09910000
               BEGIN << RESTORE OLD CATALOG >>                 <<00820>>09915000
                  SIRN := GETSIR(MSGSIR);                      <<00820>>09920000
                  ABSOLUTE(MSGBASE) := OLDLABEL1;              <<00820>>09925000
                  ABSOLUTE(X:=X+1) := OLDLABEL2;               <<00820>>09930000
                  MSGDSTN := OLDMSGDSTN;                       <<00820>>09935000
                  RELSIR(MSGSIR,SIRN);                         <<00820>>09940000
                  << RELEASE 'NEW' CAT >>                      <<00820>>09945000
                  RELDATASEG(DSTN1);                           <<00820>>09950000
                  SETLOCKSTATUS(LABELADR,PURGEOK);             <<00820>>09955000
                  ERR(2);                                      <<00820>>09960000
               END;                                            <<00820>>09965000
            END;                                               <<00820>>09970000
         END;                                                  <<00820>>09975000
      END;                                                              09980000
   END;                                                                 09985000
END;                                                                    09990000
OUTL:                                                                   09995000
FCLOSE(CATFN,0,0);                                                      10000000
END; << INITMSG >>                                                      10005000
LOGICAL PROCEDURE REM'QUEUED'ENTRY(PIN);                       <<04882>>10010000
VALUE PIN;                                                     <<04882>>10015000
INTEGER PIN;                                                   <<04882>>10020000
OPTION PRIVILEGED,UNCALLABLE,VARIABLE;                         <<04882>>10025000
<< THIS PROCEDURE REMOVES ENTRIES FROM THE RIT QUEUE.  IF >>   <<04882>>10030000
<< PIN IS PASSED IN THEN THE QUEUE WILL BE CHECKED FOR    >>   <<04882>>10035000
<< THAT SPECIFIC NUMBER AND IF FOUND IT WILL BE DELETED   >>   <<04882>>10040000
<< FROM THE QUEUE AFTER THE PROCESS IS AWAKENED AND A TRUE>>   <<04882>>10045000
<< WILL BE RETURNED.  IF PIN IS NOT PASSED IN THEN THE    >>   <<04882>>10050000
<< FIRST ENTRY IN THE QUEUE WILL BE WOKEN AND REMOVED     >>   <<04882>>10055000
                                                               <<04882>>10060000
BEGIN                                                          <<04882>>10065000
  INTEGER SIRN;                                                <<04882>>10070000
  INTEGER ARRAY RITABLE(*)=DB+0;                               <<04882>>10075000
  LOGICAL PMAP = Q-4;                                          <<04882>>10080000
  INTEGER I;                                                   <<04882>>10085000
  LOGICAL FOUND;                                               <<04882>>10090000
  FOUND := FALSE;                                              <<04882>>10095000
                                                               <<04882>>10100000
  SIRN := GETSIR(RIT'SIR);                                     <<04882>>10105000
  IF RITABLE(QUEUED'ENTRIES) > 0 THEN                          <<04882>>10110000
     BEGIN                                                     <<04882>>10115000
       IF PMAP.(15:1)=0 THEN                                   <<04882>>10120000
          BEGIN                                                <<04882>>10125000
            << NO PIN PASSED IN >>                             <<04882>>10130000
            FOUND := TRUE;                                     <<04882>>10135000
            AWAKE((RITABLE(FIQ))*PCBSIZE,%40,0);               <<04882>>10140000
            RITABLE(QUEUED'ENTRIES):=RITABLE(QUEUED'ENTRIES)-1;<<04882>>10145000
            I:=0;                                              <<04882>>10150000
            WHILE I < RITABLE(QUEUED'ENTRIES) DO               <<04882>>10155000
            BEGIN                                              <<04882>>10160000
              RITABLE(FIQ+I):=RITABLE(FIQ+I+1);                <<04882>>10165000
              I := I+1;                                        <<04882>>10170000
              END;                                             <<04882>>10175000
            RITABLE(LIQ):=RITABLE(LIQ)-1;                      <<04882>>10180000
            END                                                <<04882>>10185000
       ELSE BEGIN                                              <<04882>>10190000
              << PIN WAS PASSED IN >>                          <<04882>>10195000
              I:=0;                                            <<04882>>10200000
            WHILE((NOT FOUND)LAND(I<RITABLE(QUEUED'ENTRIES)))DO<<04882>>10205000
                BEGIN                                          <<04882>>10210000
                  IF PIN = RITABLE(FIQ+I) THEN                 <<04882>>10215000
                     BEGIN                                     <<04882>>10220000
                       FOUND := TRUE;                          <<04882>>10225000
                       AWAKE(PIN*PCBSIZE,%40,0);               <<04882>>10230000
                       RITABLE(QUEUED'ENTRIES):=               <<04882>>10235000
                               RITABLE(QUEUED'ENTRIES)-1;      <<04882>>10240000
                       END;                                    <<04882>>10245000
                 I:=I+1;                                       <<04882>>10250000
                 END; << WHILE DO >>                           <<04882>>10255000
              IF FOUND THEN                                    <<04882>>10260000
                 BEGIN                                         <<04882>>10265000
                   WHILE I <= RITABLE(QUEUED'ENTRIES) DO       <<04882>>10270000
                   BEGIN                                       <<04882>>10275000
                     RITABLE((FIQ+I)-1) := RITABLE(FIQ+I);     <<04882>>10280000
                     I := I+1;                                 <<04882>>10285000
                     END;                                      <<04882>>10290000
                   RITABLE(LIQ):=RITABLE(LIQ)-1;               <<04882>>10295000
                   END;                                        <<04882>>10300000
            END;                                               <<04882>>10305000
       END;<< QUEUED'ENTRIES > 0 >>                            <<04882>>10310000
   REM'QUEUED'ENTRY := FOUND;                                  <<04882>>10315000
   RELSIR(RIT'SIR,SIRN);                                       <<04882>>10320000
   END; << REM'QUEUED'ENTRY >>                                 <<04882>>10325000
$TITLE "REMRITENTRY'"                                          <<01398>>10330000
PROCEDURE REMRITENTRY'(PIN,FLAG);                              <<01398>>10335000
   VALUE PIN, FLAG; INTEGER PIN, FLAG;                         <<01398>>10340000
OPTION UNCALLABLE;                                                      10345000
COMMENT                                                                 10350000
   REMOVES ENTRY FROM THE REPLY INFORMATION TABLE (RIT),                10355000
   THEN PROCESS IS AWAKENED - CONSOLE IS INFORMED.                      10360000
;                                                                       10365000
BEGIN                                                                   10370000
                                                                        10375000
LOGICAL FOUND;                                                 <<01398>>10380000
INTEGER                                                                 10385000
   INDEX,                                                               10390000
   LIMIT,                                                               10395000
   SAVEDSTN,                                                            10400000
   SIRN;                                                                10405000
                                                                        10410000
                                                                        10415000
INTEGER ARRAY JMATARR(*) = DB + 0;<< Array to access JMAT >>   <<06592>>10420000
INTEGER       JMATINX; << Index to each entry in the JMAT >>   <<06592>>10425000
                                                                        10430000
INTEGER ARRAY RITABLE(*) = DB+0;                                        10435000
LOGICAL PCBPT;                                                 <<06590>>10440000
                                                                        10445000
FOUND := FALSE;  <<ASSUME NO RIT ENTRY>>                       <<01398>>10450000
SAVEDSTN := EXCHANGEDB(RIT'DST);                               <<04882>>10455000
SIRN := GETSIR(RIT'SIR);                                       <<04882>>10460000
<< WHIRL THRU TABLE LOOKING FOR PIN IN 1ST WORD>>                       10465000
LIMIT := RIT'HEADSIZE +RITABLE(RIT'HEAD'MAXENT) *RIT'SIZE;     <<04882>>10470000
INDEX := RIT'HEADSIZE -RIT'SIZE;                               <<04882>>10475000
WHILE (INDEX := INDEX +RIT'SIZE) < LIMIT DO                    <<04882>>10480000
   IF RITABLE(INDEX) = PIN THEN                                         10485000
   BEGIN                                                                10490000
      FOUND := TRUE;   <<THERE IS A RIT ENTRY FOR PIN>>        <<01398>>10495000
      RITABLE(INDEX) := 0;                                              10500000
      RITABLE := RITABLE -1; <<DECR. ENTRY COUNT >>                     10505000
      PCBPT := PIN * PCBSIZE;                                  <<06590>>10510000
      PIINFO.OAFIELD := PCB'REPLYDONE;                         <<06590>>10515000
      AWAKE(PCBPT,%40,0); << AWAKE RIT WAIT >>                 <<06590>>10520000
      INDEX := LIMIT; << STOP THIS LOOP >>                              10525000
   END;                                                                 10530000
RELSIR(RIT'SIR,SIRN);                                          <<04882>>10535000
IF FOUND THEN REM'QUEUED'ENTRY << GET NEXT QUEUED ENTRY  >>    <<04882>>10540000
   ELSE IF REM'QUEUED'ENTRY(PIN) THEN GO OUT;                  <<04882>>10545000
   << IF THE PIN WASN'T IN TABLE HE MIGHT HAVE BEEN QUEUED >>  <<04882>>10550000
IF FLAG = 1 AND                                                <<01398>>10555000
   FOUND    AND                                                <<01398>>10560000
   ABSOLUTE(SYSUP) <> 0 THEN                                   <<01398>>10565000
   <<SEND CONSOLE MSG IF REQUESTED (FLAG) AND NOT =SHUTDOWN>>  <<01398>>10570000
   BEGIN                                                       <<01398>>10575000
     EXCHANGEDB(JMATDST);                                      <<01398>>10580000
     SIRN := GETSIR(JMATSIR);                                  <<01398>>10585000
     IF JMATLGBITS <> 1 THEN  << A logoff in progress? >>      <<06592>>10590000
        BEGIN        <<  No logoff  >>                         <<06592>>10595000
           RELSIR(JMATSIR,SIRN);                               <<01398>>10600000
           EXCHANGEDB(0);   <<BACK TO STACK FOR GENMSG>>       <<01398>>10605000
           GENMSG(1,38,%010000,PIN,,,,,0); <<TELL OPERATOR>>   <<01398>>10610000
        END                                                    <<01398>>10615000
      ELSE                                                     <<01398>>10620000
        RELSIR(JMATSIR,SIRN);                                  <<01398>>10625000
   END;                                                        <<01398>>10630000
OUT:                                                           <<04882>>10635000
EXCHANGEDB(SAVEDSTN);                                          <<01398>>10640000
                                                                        10645000
END; << REMRITENTRY >>                                                  10650000
$TITLE "REMRITENTRY"                                           <<01398>>10655000
PROCEDURE REMRITENTRY(PIN);                                    <<01398>>10660000
   VALUE PIN; INTEGER PIN;                                     <<01398>>10665000
   OPTION UNCALLABLE;                                          <<01398>>10670000
COMMENT REMOVES RIT ENTRY WITHOUT SENDING A MSG TO CONSOLE;    <<01398>>10675000
BEGIN                                                          <<01398>>10680000
   REMRITENTRY'(PIN,0);                                        <<01398>>10685000
END;                                                           <<01398>>10690000
                                                                        10695000
$CONTROL SEGMENT=MAIN                                                   10700000
END. << GENMSG >>                                                       10705000
