<<=========================================================             00010000
=                                                         =             00012000
=                  INCLHARD - A8                          =             00014000
=                                                         =             00016000
=========================================================>>             00018000
<<                                                    >>       <<04393>>00020000
<<           INCLHARD  CHANGE HISTORY                 >>       <<04393>>00022000
<<                                                    >>       <<04393>>00024000
<<    PLEASE NOTE ANY CHANGES MADE TO INCLHARD        >>       <<04393>>00026000
<<    PLEASE USE LINE INCREMENT OF .001               >>       <<04393>>00028000
<<                                                    >>       <<04393>>00030000
<<    INITIALS     PROCEDURE NAME       DATE      C#  >>       <<04393>>00032000
<<                                                    >>       <<04393>>00034000
<<      WEO            LOGERROR        820603     1   >>       <<04393>>00036000
<<      WEO            IOMESSAGE       820624     2   >>       <<04466>>00038000
<<      WEO            SIODM           820713     3   >>       <<04477>>00040000
<<      WEO            GETGBUF         820820     4   >>       <<04835>>00042000
<<      KWE            SIODM           820908     5   >>       <<04899>>00044000
                                                               <<MPEIV>>00046000
$PAGE "DEQUEUE DISC REQUEST"                                   <<JB.19>>00048000
                                                               <<MPEIV>>00050000
PROCEDURE DEQUEUEDISCREQ(REQP,DITSYSBASEINX);                  <<MPEIV>>00052000
VALUE REQP,DITSYSBASEINX;                                      <<MPEIV>>00054000
INTEGER REQP,DITSYSBASEINX;                                    <<MPEIV>>00056000
OPTION PRIVILEGED,UNCALLABLE;                                  <<MPEIV>>00058000
                                                               <<MPEIV>>00060000
COMMENT                                                        <<MPEIV>>00062000
                                                               <<MPEIV>>00064000
REMOVES THE SPECIFIED REQUEST FROM ITS QUEUE.  CALLED BY DISCQ <<MPEIV>>00066000
MANAGER WHEN ABORTING SEGMENT READ OR WRITE REQUESTS, AND FROM <<MPEIV>>00068000
CHECKFORPENDINGDISCIO TO REMOVE A REQUEST FROM THE QUEUE OF    <<MPEIV>>00070000
PENDING DISC TRANSFER REQUESTS. ALSO FROM SIODM ON BUFFER TRAPS<<MPEIV>>00072000
                                                               <<MPEIV>>00074000
;                                                              <<MPEIV>>00076000
BEGIN                                                          <<MPEIV>>00078000
INTEGER NEXT,                                                  <<MPEIV>>00080000
        PREV;                                                  <<MPEIV>>00082000
INTEGER QHEADERSYSBASEINX;                                     <<MPEIV>>00084000
X:=REQP;                                                       <<MPEIV>>00086000
DISCREQFLAGS.REQQUEUEDFLAG:=0;                                 <<MPEIV>>00088000
IF LOGICAL(DISCREQFLAGS).DISABLEDREQFLAG                       <<MPEIV>>00090000
THEN QHEADERSYSBASEINX:=DISCREQTABSYSBASEINX                   <<MPEIV>>00092000
ELSE QHEADERSYSBASEINX:=DITSYSBASEINX;                         <<MPEIV>>00094000
X:=REQP;                                                       <<MPEIV>>00096000
PREV:=PREVREQP;                                                <<MPEIV>>00098000
IF = THEN                                                      <<MPEIV>>00100000
   BEGIN <<FIRST REQ IN QUEUE>>                                <<MPEIV>>00102000
   NEXT:=NEXTREQP;                                             <<MPEIV>>00104000
   NEXTREQP:=0;                                                <<MPEIV>>00106000
   X:=QHEADERSYSBASEINX;                                       <<MPEIV>>00108000
   IF NEXT = 0 THEN DITQHEADP:=DITQTAILP:=0 ELSE               <<MPEIV>>00110000
      BEGIN                                                    <<MPEIV>>00112000
      DITQHEADP:=NEXT;                                         <<MPEIV>>00114000
      X:=NEXT; <<FOR DIRECT ARRAY ACCESS TO TO NEXT REQUEST>>  <<MPEIV>>00116000
      PREVREQP:=0; <<ZERO OUT NEXT REQUEST'S PREV PTR>>        <<MPEIV>>00118000
      END;                                                     <<MPEIV>>00120000
   END                                                         <<MPEIV>>00122000
ELSE                                                           <<MPEIV>>00124000
   BEGIN <<IN THE MIDDLE>>                                     <<MPEIV>>00126000
   PREVREQP:=0;                                                <<MPEIV>>00128000
   NEXT:=NEXTREQP;                                             <<MPEIV>>00130000
   NEXTREQP:=0;                                                <<MPEIV>>00132000
   IF NEXT = 0 THEN                                            <<MPEIV>>00134000
      BEGIN <<REQUEST IS AT THE TAIL OF DISC'S QUEUE>>         <<MPEIV>>00136000
      X:=PREV;                                                 <<MPEIV>>00138000
      NEXTREQP:=0;                                             <<MPEIV>>00140000
      X:=QHEADERSYSBASEINX;                                    <<MPEIV>>00142000
      DITQTAILP:=PREV;                                         <<MPEIV>>00144000
      END                                                      <<MPEIV>>00146000
   ELSE                                                        <<MPEIV>>00148000
      BEGIN <<REQUEST IS IN THE MIDDLE OF DISC'S QUEUE>>       <<MPEIV>>00150000
      X:=NEXT;                                                 <<MPEIV>>00152000
      PREVREQP:=PREV;                                          <<MPEIV>>00154000
      X:=PREV;                                                 <<MPEIV>>00156000
      NEXTREQP:=NEXT;                                          <<MPEIV>>00158000
      END;                                                     <<MPEIV>>00160000
   END;                                                        <<MPEIV>>00162000
END  <<PROCEDURE DEQUEUEDISCREQ>>;                             <<MPEIV>>00164000
$PAGE  "                 STORE'IOQ"                            <<01830>>00166000
 PROCEDURE STORE'IOQ(IOQP, FLAG);                              <<01830>>00168000
                                                               <<01830>>00170000
 COMMENT                                                       <<01830>>00172000
 ************************************************************* <<01830>>00174000
 THIS PROCEDURE IS USED WHEN IOSTATFLAG IS ENABLED.  IT WILL   <<01830>>00176000
 MOVE THE IOQ AND DISCREQ ENTRIES ONTO AN EXTRY DATA SEGMENT.  <<01830>>00178000
                                                               <<01830>>00180000
 THE PARAMETER IOQP IS THE POINTER TO THE OUTGOING IOQ/DISCREQ <<01830>>00182000
 AND FLAG INDICATES WHETHER IT IS AN IOQ (TRUE) OR DISCREQ.    <<01830>>00184000
 ************************************************************* <<01830>>00186000
 ;                                                             <<01830>>00188000
 VALUE IOQP, FLAG;                                             <<01830>>00190000
 LOGICAL FLAG;                                                 <<01830>>00192000
 POINTER IOQP;                                                 <<01830>>00194000
 OPTION PRIVILEGED;                                            <<01830>>00196000
                                                               <<01830>>00198000
 BEGIN                                                         <<01830>>00200000
    INTEGER MAX'CNT;                                           <<01830>>00202000
                                                               <<01830>>00204000
    IF  NOT (IOSTATSENBLD)  THEN  RETURN; << NOT ENABLED >>    <<01830>>00206000
                                                               <<01830>>00208000
    DISABLE;                                                   <<01830>>00210000
    TOS := IOSTATXDSBANK;                                      <<01830>>00212000
    TOS := IOSTATXDSBASE;                                      <<01830>>00214000
    IF  FLAG  THEN  ASMB(DDUP);  << TO BE USED LASTER >>       <<01830>>00216000
    ASMB(LDEA);                  << GET S-2 FOR MTDS >>        <<01830>>00218000
    MAX'CNT := TOS;                                            <<01830>>00220000
    TOS := IOSTATXDSNUM;         << S-3 FOR MTDS >>            <<01830>>00222000
    ASMB(XCH; LSL 4);         << GET RIGHT PATTERN AND SIZE >> <<01830>>00224000
    TOS := @IOQP;                                              <<01830>>00226000
    IF  FLAG  THEN             << MOVE 11 WORDS IOQ >>         <<01830>>00228000
    BEGIN                                                      <<01830>>00230000
       TOS := 11;                                              <<01830>>00232000
       ASMB(MTDS 2; DELB; ADD);  << SET UP ABSOLUTE ADDR >>    <<01830>>00234000
       TOS := @IOQP;             << OF OFFSET INTO XDS   >>    <<01830>>00236000
       ASMB(SSEA; INCA);                                       <<01830>>00238000
       TOS := -1D;                                             <<01830>>00240000
       ASMB(SDEA; INCA; INCA);   << STORE IDENTIFIER  >>       <<01830>>00242000
       TOS := TIMER;                                           <<01830>>00244000
       ASMB(SDEA; DDEL);                                       <<01830>>00246000
    END  ELSE                   << MOVE 16 WORDS DISCREQ >>    <<01830>>00248000
    BEGIN                                                      <<01830>>00250000
       TOS := 16;                                              <<01830>>00252000
       ASMB(MTDS);                                             <<01830>>00254000
    END;                                                       <<01830>>00256000
    ASMB(LSEA; INCA);           << LOAD INDEX TO XDS >>        <<01830>>00258000
    IF  S0 > MAX'CNT  THEN      << WRAP AROUND >>              <<01830>>00260000
    BEGIN                                                      <<01830>>00262000
       ASMB(DEL; LDI 1);                                       <<01830>>00264000
    END;                                                       <<01830>>00266000
    ASMB(SSEA);                 << STORE NEW INDEX TO XDS >>   <<01830>>00268000
    TOS := TOS + 2;                                            <<01830>>00270000
    ASMB(LDEA);                                                <<01830>>00272000
    TOS := TOS + 1D;           << TOTAL COUNT OF I/O REQUEST >><<01830>>00274000
    ASMB(SDEA);                                                <<01830>>00276000
 END;                                                          <<01830>>00278000
$PAGE "QUEUE DISC REQUEST"                                     <<JB.19>>00280000
PROCEDURE QUEUEDISCREQ(REQP,DITSYSBASEINX);                    <<MPEIV>>00282000
VALUE REQP,DITSYSBASEINX;                                      <<MPEIV>>00284000
INTEGER REQP,DITSYSBASEINX;                                    <<MPEIV>>00286000
OPTION PRIVILEGED,UNCALLABLE;                                  <<MPEIV>>00288000
                                                               <<MPEIV>>00290000
COMMENT                                                        <<MPEIV>>00292000
                                                               <<MPEIV>>00294000
INSERTS THE SPECIFIED DISC TRANSFER REQUEST INTO THE DIT'S     <<MPEIV>>00296000
REQUEST QUEUE.   THE QUEUE IS PRIORITY ORDERED.  IF THE DIT IS <<MPEIV>>00298000
INACTIVE, AWAKEIO IS CALLED TO GET THINGS MOVING. CALLED FROM <<<MPEIV>>00300000
ATTACHIO, STARTSEGWRITE, PRROCESSINITMSG, DISCQMANAGER         <<MPEIV>>00302000
;                                                              <<MPEIV>>00304000
BEGIN                                                          <<MPEIV>>00306000
                                                               <<MPEIV>>00308000
INTEGER NEXT,                                                  <<MPEIV>>00310000
        PREV,                                                  <<MPEIV>>00312000
        LASTINQUEUE,                                           <<MPEIV>>00314000
        FIRSTINQUEUE;                                          <<MPEIV>>00316000
INTEGER POINTER DITPOINTER;                                    <<MPEIV>>00318000
                                                               <<MPEIV>>00320000
LOGICAL THISREQPRI;                                            <<MPEIV>>00322000
                                                               <<MPEIV>>00324000
SUBROUTINE QUEUEATHEAD;                                        <<MPEIV>>00326000
                                                               <<MPEIV>>00328000
BEGIN                                                          <<MPEIV>>00330000
X:=DITSYSBASEINX;                                              <<MPEIV>>00332000
FIRSTINQUEUE:=DITQHEADP;                                       <<MPEIV>>00334000
DITQHEADP:=REQP;                                               <<MPEIV>>00336000
X:=FIRSTINQUEUE;                                               <<MPEIV>>00338000
IF <> THEN                                                     <<MPEIV>>00340000
   BEGIN <<Q WAS NON-EMPTY>>                                   <<MPEIV>>00342000
   PREVREQP:=REQP;                                             <<MPEIV>>00344000
   X:=REQP;                                                    <<MPEIV>>00346000
   NEXTREQP:=FIRSTINQUEUE;                                     <<MPEIV>>00348000
   PREVREQP:=0;                                                <<MPEIV>>00350000
   END                                                         <<MPEIV>>00352000
ELSE                                                           <<MPEIV>>00354000
   BEGIN                                                       <<MPEIV>>00356000
   X:=REQP;                                                    <<MPEIV>>00358000
   PREVREQP:=NEXTREQP:=0;                                      <<MPEIV>>00360000
   END;                                                        <<MPEIV>>00362000
END <<SUBROUTINE QUEUEATHEAD>>;                                <<MPEIV>>00364000
                                                               <<MPEIV>>00366000
SUBROUTINE QUEUEATTAIL;                                        <<MPEIV>>00368000
                                                               <<MPEIV>>00370000
BEGIN                                                          <<MPEIV>>00372000
X:=DITSYSBASEINX;                                              <<MPEIV>>00374000
LASTINQUEUE:=DITQTAILP;                                        <<MPEIV>>00376000
DITQTAILP:=REQP;                                               <<MPEIV>>00378000
X:=LASTINQUEUE;                                                <<MPEIV>>00380000
IF <> THEN                                                     <<MPEIV>>00382000
   BEGIN                                                       <<MPEIV>>00384000
   NEXTREQP:=REQP;                                             <<MPEIV>>00386000
   X:=REQP;                                                    <<MPEIV>>00388000
   PREVREQP:=LASTINQUEUE;                                      <<MPEIV>>00390000
   END                                                         <<MPEIV>>00392000
ELSE                                                           <<MPEIV>>00394000
   BEGIN                                                       <<MPEIV>>00396000
   X:=REQP;                                                    <<MPEIV>>00398000
   PREVREQP:=NEXTREQP:=0;                                      <<MPEIV>>00400000
   END;                                                        <<MPEIV>>00402000
END;                                                           <<MPEIV>>00404000
                                                               <<MPEIV>>00406000
                                                               <<MPEIV>>00408000
                                                               <<MPEIV>>00410000
X:=REQP;                                                       <<MPEIV>>00412000
DISCREQFLAGS.REQQUEUEDFLAG:=1;                                 <<MPEIV>>00414000
IF <> THEN SUDDENDEATH(660); <<REQ ALREADY QUEUED>>            <<01640>>00416000
X:=@DITPOINTER:=DITSYSBASEINX;                                 <<MPEIV>>00418000
DISABLE;                                                       <<MPEIV>>00420000
IF DITIOQP = 0 THEN                                            <<MPEIV>>00422000
   BEGIN <<NO CURRENT REQUEST AGAINST THIS DEVICE-MAKE THIS ONE<<MPEIV>>00424000
   DITIOQP:=REQP;                                              <<MPEIV>>00426000
   X:=REQP;                                                    <<MPEIV>>00428000
   DISCREQFLAGS.DITSCURRREQFLAG:=1;                            <<MPEIV>>00430000
   END                                                         <<MPEIV>>00432000
ELSE                                                           <<MPEIV>>00434000
   BEGIN  <<MUST QUEUE REQUEST>>                               <<MPEIV>>00436000
   IF DITQHEADP = 0  THEN                                      <<MPEIV>>00438000
      BEGIN  <<FIRST REQUEST IN QUEUE>>                        <<MPEIV>>00440000
      DITQTAILP:=DITQHEADP:=REQP; <<QUEUE AT HEAD>>            <<MPEIV>>00442000
      X:=REQP;                                                 <<MPEIV>>00444000
      NEXTREQP:=PREVREQP:=0;                                   <<MPEIV>>00446000
      END                                                      <<MPEIV>>00448000
   ELSE                                                        <<MPEIV>>00450000
      BEGIN                                                    <<MPEIV>>00452000
      X:=REQP;                                                 <<MPEIV>>00454000
      IF REQURGCLASS=BKGRNDPRI THEN QUEUEATTAIL ELSE           <<MPEIV>>00456000
         BEGIN <<MERGE REQUEST INTO QUEUE>>                    <<MPEIV>>00458000
         THISREQPRI:=REQURGCLASS;                              <<MPEIV>>00460000
         X:=DITSYSBASEINX;                                     <<MPEIV>>00462000
         X:=FIRSTINQUEUE:=DITQHEADP;                           <<MPEIV>>00464000
         WHILE <> AND LOGICAL(REQURGCLASS) <= THISREQPRI       <<MPEIV>>00466000
         DO X:=NEXTREQP; <<INSERT IN FRONT OF X>>              <<MPEIV>>00468000
         IF X = 0 THEN QUEUEATTAIL ELSE                        <<MPEIV>>00470000
         IF X=FIRSTINQUEUE THEN QUEUEATHEAD ELSE               <<MPEIV>>00472000
            BEGIN  <<QUEUE IN MIDDLE>>                         <<MPEIV>>00474000
            NEXT:=X;                                           <<MPEIV>>00476000
            PREV:=PREVREQP;                                    <<MPEIV>>00478000
            PREVREQP:=REQP;                                    <<MPEIV>>00480000
            X:=PREV;                                           <<MPEIV>>00482000
            NEXTREQP:=REQP;                                    <<MPEIV>>00484000
            X:=REQP;                                           <<MPEIV>>00486000
            PREVREQP:=PREV;                                    <<MPEIV>>00488000
            NEXTREQP:=NEXT;                                    <<MPEIV>>00490000
            END;                                               <<MPEIV>>00492000
         END;                                                  <<MPEIV>>00494000
      END;                                                     <<MPEIV>>00496000
   END;                                                        <<MPEIV>>00498000
X:=DITSYSBASEINX;                                              <<MPEIV>>00500000
IF DITIOQP=LOGICAL(REQP) THEN AWAKEIO(DITPOINTER,0);           <<MPEIV>>00502000
END  <<QUEUEDISCREQ>>;                                         <<MPEIV>>00504000
                                                               <<MPEIV>>00506000
                                                               <<MPEIV>>00508000
$PAGE "DISC Q MANAGER"                                         <<JB.19>>00510000
PROCEDURE DISCQMANAGER(REQP,REQUESTTYPE);                      <<MPEIV>>00512000
VALUE REQP,REQUESTTYPE;                                        <<MPEIV>>00514000
INTEGER REQP,        <<SYSDB INX OF REQUEST ELEMENT>>          <<MPEIV>>00516000
        REQUESTTYPE; << IF < 0 THEN ABORT (MM TRANSFERS ONLY)>><<MPEIV>>00518000
                    << IF = 0 THEN QUEUE   >>                  <<MPEIV>>00520000
                    << IF > THEN DISABLE>>                     <<MPEIV>>00522000
OPTION PRIVILEGED,UNCALLABLE;                                  <<MPEIV>>00524000
                                                               <<MPEIV>>00526000
                                                               <<MPEIV>>00528000
COMMENT                                                        <<MPEIV>>00530000
                                                               <<MPEIV>>00532000
DISCQMANAGER IS CALLED TO QUEUE A REQUEST FOR A DISC           <<MPEIV>>00534000
I/O OR TO DISABLE A PREVIOSLY QUEUED REQUEST. THE PROCEDURE    <<MPEIV>>00536000
IS CALLED FROM ATTACHIO FOR FILE SYSTEM INITIATED DISC         <<MPEIV>>00538000
TRANSFERS, AND FROM PERFORMINITMSG, PERFORMCOMPMSG             <<MPEIV>>00540000
SWAPOUT FOR INITIATING OR ABORTING SEGMENT READ OR             <<MPEIV>>00542000
WRITE REQUESTS ON BEHALF OF MEMORY MANAGEMENT.                 <<MPEIV>>00544000
                                                               <<MPEIV>>00546000
DISC TRANSFER REQUESTS ARE ORDERED WITHIN A DISC QUEUE         <<MPEIV>>00548000
ACCORDING TO THE CPU SCHEDULING CLASS OF THE INITIATING        <<MPEIV>>00550000
PROCESS SO THAT MORE URGENT TRANSFERS ARE PERFORMED FIRST.     <<MPEIV>>00552000
THE DISC MONITOR (SIODM) SELECTS THE MOST URGENT ENABLED       <<MPEIV>>00554000
REQUEST AS THE CURRENT REQUEST FOR THE DEVICE WHEN THE LAST    <<MPEIV>>00556000
REQUEST IS COMPLETED. A SEEK WILL BE PERFORMED FOR THIS        <<MPEIV>>00558000
REQUEST WHILE THE DEVICE IS WAITING FOR THE CONTROLLER.        <<MPEIV>>00560000
CONSEQUENTLY, THE REQUEST WHICH THE MONITOR HAS SELECTED       <<MPEIV>>00562000
AS CURRENT WILL NOT BE PREMTED EVEN IF A MORE URGENT REQUEST   <<MPEIV>>00564000
COMES IN AND REQUESTS TO DELAY OR ABORT THE CURRENT REQUEST    <<MPEIV>>00566000
WILL NOT BE HONORED-THE TRANSFER WILL BE PERFORMED, AND        <<MPEIV>>00568000
THE MONITOR COMPLETER WILL TAKE CARE OF ENABLING ANY           <<MPEIV>>00570000
ACTION PENDING THE DISC TRANSFER.                              <<MPEIV>>00572000
                                                               <<MPEIV>>00574000
STATUS IS RETURNED THROUGH THE CONDITION CODE AS FOLLOWS :     <<MPEIV>>00576000
   CC=CCL ==> INDICATED TRANSFER REQUEST                       <<MPEIV>>00578000
              ALREADY COMPLETED                                <<MPEIV>>00580000
   CC=CCE ==> SUCCESSFUL COMPLETION OF                         <<MPEIV>>00582000
              REQUESTED ACTION                                 <<MPEIV>>00584000
   CC=CCG ==> INDICATED REQUEST IS THE                         <<MPEIV>>00586000
              DISC'S CURRENT REQUEST                           <<MPEIV>>00588000
                                                               <<MPEIV>>00590000
                                                               <<MPEIV>>00592000
;                                                              <<MPEIV>>00594000
                                                               <<MPEIV>>00596000
BEGIN                                                          <<MPEIV>>00598000
                                                               <<MPEIV>>00600000
INTEGER  DITSYSBASEINX,                                        <<MPEIV>>00602000
         QHEADERP;                                             <<MPEIV>>00604000
INTEGER POINTER DITPOINTER;                                    <<MPEIV>>00606000
LOGICAL URGCLASS;                                              <<MPEIV>>00608000
INTEGER QCLASS;                                                <<MPEIV>>00610000
                                                               <<MPEIV>>00612000
<<DB IS ASSUMED TO BE AT SYSDB>>                               <<MPEIV>>00614000
                                                               <<MPEIV>>00616000
                                                               <<MPEIV>>00618000
X:=REQP; <<FOR DIRECT ARRAY ACCESS TO REQUEST INFO>>           <<MPEIV>>00620000
DISABLE;                                                       <<MPEIV>>00622000
TOS:=DISCREQFLAGS;                                             <<MPEIV>>00624000
ASMB(TBC COMPLETED');                                          <<MPEIV>>00626000
IF <> THEN RSTATUS.CC:=CCL   <<ALREADY COMPLETED>> ELSE        <<MPEIV>>00628000
   BEGIN                                                       <<MPEIV>>00630000
   ASMB (TBC DITSCURRREQBIT);                                  <<MPEIV>>00632000
   IF <> THEN                                                  <<MPEIV>>00634000
      BEGIN <<REQUEST IS THE DISC'S CURRENT REQUEST>>          <<MPEIV>>00636000
      RSTATUS.CC:=CCG;                                         <<MPEIV>>00638000
      TOS:=REQUESTTYPE;                                        <<MPEIV>>00640000
      ASMB(DEL);                                               <<MPEIV>>00642000
      IF > THEN TOS.DISABLEREQATTMPTFLAG:=1                    <<MPEIV>>00644000
      ELSE IF < THEN TOS.ABORTREQATTMPTFLAG:=1;                <<MPEIV>>00646000
      DISCREQFLAGS:=TOS;                                       <<MPEIV>>00648000
      END                                                      <<MPEIV>>00650000
   ELSE                                                        <<MPEIV>>00652000
      BEGIN                                                    <<MPEIV>>00654000
      RSTATUS.CC:=CCE;                                         <<MPEIV>>00656000
      X:=REQLDEVN; <<LOGICAL DEVICE NUMBER FROM REQUEST>>      <<MPEIV>>00658000
      TOS:=LPDTD(X); <<DITSYSBASEINX FROM LPDT>>               <<MPEIV>>00660000
      ASMB(DEL);                                               <<MPEIV>>00662000
      DITSYSBASEINX:=S0;                                       <<MPEIV>>00664000
      @DITPOINTER:=S0;                                         <<MPEIV>>00666000
      X:=TOS; <<DIRECT ACCESS TO DIT INFO>>                    <<MPEIV>>00668000
      QHEADERP:=DITQHEADP;                                     <<MPEIV>>00670000
      X:=REQP;                                                 <<MPEIV>>00672000
      TOS:=REQUESTTYPE;                                        <<MPEIV>>00674000
      ASMB(DEL);                                               <<MPEIV>>00676000
      IF <> THEN                                               <<MPEIV>>00678000
         BEGIN <<DISABLE OR ABORT REQUEST>>                    <<MPEIV>>00680000
         IF < THEN                                             <<MPEIV>>00682000
            BEGIN <<AN ABORT REQUEST>>                         <<MPEIV>>00684000
            DEQUEUEDISCREQ(REQP,DITSYSBASEINX);                <<MPEIV>>00686000
            TOS:=REQP;                                         <<01640>>00688000
            RETURNDISCREQ(*);                                  <<01640>>00690000
            END                                                <<MPEIV>>00692000
         ELSE                                                  <<MPEIV>>00694000
            BEGIN <<A DISABLE REQUEST>>                        <<MPEIV>>00696000
            TOS.DISABLEDREQFLAG:=1;                            <<MPEIV>>00698000
            IF <> THEN SUDDENDEATH(661);                       <<01640>>00700000
            TOS.REQQUEUEDFLAG:=1;                              <<MPEIV>>00702000
            IF <> THEN SUDDENDEATH(661);                       <<01640>>00704000
            DISCREQFLAGS:=TOS;                                 <<MPEIV>>00706000
            END;                                               <<MPEIV>>00708000
         END                                                   <<MPEIV>>00710000
      ELSE                                                     <<MPEIV>>00712000
         BEGIN <<QUEUE, INCREASE URGENCY, OR ENABLE>>          <<MPEIV>>00714000
         ASMB (TBC REQQUEUEDBIT);                              <<MPEIV>>00716000
         IF = THEN                                             <<MPEIV>>00718000
            begin <<must queue request>>                       <<MPEIV>>00720000
            DISCREQFLAGS.DISABLEDREQFLAG:=0;                   <<MPEIV>>00722000
            QUEUEDISCREQ(REQP,DITSYSBASEINX);                  <<MPEIV>>00724000
            END                                                <<MPEIV>>00726000
         ELSE                                                  <<MPEIV>>00728000
            BEGIN <<ALREADY QUEUED-MAYBE HAVE TO MOVE IN QUEUE><<MPEIV>>00730000
            URGCLASS:=REQURGCLASS;                             <<MPEIV>>00732000
            X:=PREVREQP;                                       <<MPEIV>>00734000
            IF <> THEN                                         <<MPEIV>>00736000
               BEGIN <<NOT ALONE IN THE QUEUE>>                <<MPEIV>>00738000
               IF LOGICAL(REQURGCLASS) > URGCLASS THEN         <<MPEIV>>00740000
                  BEGIN <<MUST MOVE REQ IN QUEUE>>             <<MPEIV>>00742000
                  DEQUEUEDISCREQ(REQP,DITSYSBASEINX);          <<MPEIV>>00744000
                  QUEUEDISCREQ(REQP,DITSYSBASEINX);            <<MPEIV>>00746000
                  END;                                         <<MPEIV>>00748000
               END;                                            <<MPEIV>>00750000
            END;                                               <<MPEIV>>00752000
         END;                                                  <<MPEIV>>00754000
      END;                                                     <<MPEIV>>00756000
   END;                                                        <<MPEIV>>00758000
END  <<PROCEDURE DISCQMANAGER>>;                               <<MPEIV>>00760000
$PAGE "MPE TABLE FULL PROCESSOR"                               <<02801>>00762000
procedure MPE'TABLE'FULL(TABLE'NUMBER);                        <<02801>>00764000
value TABLE'NUMBER;  integer TABLE'NUMBER;                     <<02801>>00766000
option uncallable,privileged;                                  <<02801>>00768000
begin                                                          <<02801>>00770000
<< This procedure sends a basic IPC message to IOMESSPROC >>   <<02801>>00772000
<< passing the index of an MPE table that has filled.     >>   <<02801>>00774000
                                                               <<02801>>00776000
define IOMSGPIN = absolute(%1152)/PCBSIZE#;                    <<02801>>00778000
                                                               <<02801>>00780000
tos := 1;   << Msg type 1 is table overflow >>                 <<02801>>00782000
tos := TABLE'NUMBER;  << Number of MPE table that overflowed >><<02801>>00784000
tos := 0D;  << dummy parameters >>                             <<02801>>00786000
SENDMSG(IOMSGPIN,0,4,%40000<<pri or secondary>>);              <<02801>>00788000
end;                                                           <<02801>>00790000
$PAGE "MPE DEVICE MAINTENENCE REQUEST SCHEDULER"               <<03071>>00792000
procedure MAINT'REQUEST(LDEV,TYPE,SUBTYPE);                    <<03071>>00794000
value LDEV,TYPE,SUBTYPE;                                       <<03071>>00796000
integer LDEV,TYPE,SUBTYPE;                                     <<03071>>00798000
option privileged,uncallable;                                  <<03071>>00800000
begin                                                          <<03071>>00802000
<< This procedure sends a basic IPC message to process >>      <<03071>>00804000
<< IOMESSAGE to perform maintenence processing on a    >>      <<03071>>00806000
<< requesting LDEV.                                    >>      <<03071>>00808000
                                                               <<03071>>00810000
define IOMSGPIN = absolute(%1152)/PCBSIZE#;                    <<03071>>00812000
                                                               <<03071>>00814000
tos := 4;       << MSG type 4 is maintenence request >>        <<03071>>00816000
tos := LDEV;                                                   <<03071>>00818000
tos := TYPE;                                                   <<03071>>00820000
tos := SUBTYPE;                                                <<03071>>00822000
SENDMSG(IOMSGPIN,0,4,%40000 << pri or secondary >> );          <<03071>>00824000
end;                                                           <<03071>>00826000
$PAGE "MPE DCU LOGGING REQUEST SCHEDULER"                      <<04188>>00828000
procedure DCU'REQUEST(PARM);                                   <<04188>>00830000
value PARM;  integer PARM;                                     <<04188>>00832000
option privileged,uncallable;                                  <<04188>>00834000
begin                                                          <<04188>>00836000
                                                               <<04188>>00838000
<< This procedure is called by ININ to process DCU   >>        <<04188>>00840000
<< requests from the Series/64 processor.  The msg   >>        <<04188>>00842000
<< sent to IOMSGPROC tells it to either initiate a   >>        <<04188>>00844000
<< new DCU information dump or that the DCU dump is  >>        <<04188>>00846000
<< done.                                             >>        <<04188>>00848000
                                                               <<04188>>00850000
define IOMSGPIN = absolute(%1152)/PCBSIZE#;                    <<04188>>00852000
                                                               <<04188>>00854000
tos := 5;      << MSG type 5 is DCU request from ININ >>       <<04188>>00856000
tos := PARM;   << PARM.(0:15) is the byte count Xfered>>       <<04188>>00858000
               << PARM.(15:1) = 0 for initiate, 1 for >>       <<04188>>00860000
               <<               completed.            >>       <<04188>>00862000
tos := 0D;     << Dummy parameters                    >>       <<04188>>00864000
SENDMSG(IOMSGPIN,0,4,%40000 << pri or sec. table >> );         <<04188>>00866000
end;      << of procedure DCU'REQUEST >>                       <<04188>>00868000
$PAGE "GET T/SYS BUF"                                          <<JB.19>>00870000
INTEGER PROCEDURE GETGBUF(TYPE);   << NO LONGER TBUF >>                 00872000
  VALUE  TYPE;   INTEGER TYPE;                                          00874000
  OPTION UNCALLABLE, PRIVILEGED;                                        00876000
                                                                        00878000
  << THIS PROCEDURE GETS AN I/O TABLE ENTRY FROM A PRIMARY OR           00880000
     SECONDARY TABLE, IF THE TABLE IS EMPTY THE CALLER MAY BE           00882000
     IMPEDED IF HE SO SPECIFIES.  RETURNS A SYSDB RELATIVE POINTER TO   00884000
     THE GOTTEN BUFFER.                                                 00886000
                                                                        00888000
     TYPE -   0  - IMPEDE IF PRIMARY TABLE EMPTY                        00890000
              1  - GET FROM PRIMARY ONLY, RETURN 0 IF EMPTY             00892000
              2  - GET FROM PRIMARY OR SECONDARY, RETURN 0 IF BOTH EMPTY00894000
  >>                                                                    00896000
  BEGIN                                                                 00898000
                                                               <<02801>>00900000
    integer TBLNUM    = q+1;   << tbl # being accessed >>      <<02801>>00902000
    integer pointer TBASE = q+2; << ptr to table base >>       <<02801>>00904000
    integer pointer TBASE1= q+3; << base of tbl +/- 1 >>       <<02801>>00906000
    DOUBLE POINTER DTBASE = TBASE;                                      00908000
    LOGICAL POINTER LTBASE = TBASE;                                     00910000
                                                                        00912000
    INTEGER THISPCB = Q+2;   << PCB NUMBER OF CALLER >>                 00914000
                                                                        00916000
    ENTRY GETSBUF;                                                      00918000
    ENTRY GETIOQ;                                                       00920000
    ENTRY GETDISCREQ;                                          <<01640>>00922000
                                                                        00924000
    tos := 0;   << tbl 0 is TBUF >>                            <<02801>>00926000
    TOS := @TBUF;    << SET TBASE TO TBUF BASE >>                       00928000
    TOS := S0;  << TBUF LINKS IN ZEROTH ELEMENT >>                      00930000
    GOTO L2;                                                            00932000
                                                                        00934000
GETSBUF:                                                                00936000
    tos := 1;   << tbl 1 is SBUF >>                            <<02801>>00938000
    TOS := @SBUF;    << SET TBASE TO SBUF BASE >>                       00940000
    TOS := S0 - 1;  << SET TBASE1 TO ADDRESS SBUF LINKS >>              00942000
    GOTO L2;                                                            00944000
                                                                        00946000
GETIOQ:                                                                 00948000
    tos := 2;   << tbl 2 is IOQ >>                             <<02801>>00950000
    TOS := @IOQ;     << SET TBASE TO IOQ BASE >>                        00952000
    TOS := S0 + 1; << SET TBASE1 TO ADDRESS IOQ LINKS >>                00954000
                                                                        00956000
                                                               <<01640>>00958000
GETDISCREQ:                                                    <<01640>>00960000
    tos := 3;   << tbl 3 is Disc Request Queue >>              <<02801>>00962000
    TOS:=ABSOLUTE(SYSDISCREQTAB);                              <<01640>>00964000
    TOS:=S0+1;  <<SET TBASE1 TO ADDR NEXT LINK>>               <<01640>>00966000
                                                               <<01640>>00968000
L2:                                                                     00970000
    TOS := DTBASE(TRQSTS);  << GET REQUEST COUNTER >>                   00972000
    TOS := TOS + 1;  << INCREMENT REQUEST COUNTER >>                    00974000
    IF CARRY THEN ASMB(INCB     );                                      00976000
    DTBASE(X) := TOS;                                                   00978000
                                                                        00980000
L3:                                                                     00982000
    DISABLE;                                                            00984000
    IF TBASE(TUSE).INUSE>=TBASE.LIMIT1 THEN                             00986000
      BEGIN   << PRIMARY TABLE EMPTY >>                                 00988000
       << if first time table overflowed, send message >>      <<02801>>00990000
       tos := TBASE(TOVRFL);                                   <<02801>>00992000
       if = then                                               <<02801>>00994000
         MPE'TABLE'FULL(TBLNUM);                               <<02801>>00996000
       TBASE(TOVRFL) := tos + 1; << inc ovrflow ctr >>         <<02801>>00998000
        IF TYPE = PRIMARY THEN RETURN;  << GET FROM PRIMARY ONLY >>     01000000
        IF < THEN  << IMPEDABLE >>                                      01002000
          BEGIN  IOIMPEDE(@TBASE);  GOTO L3;  END;                      01004000
      END;                                                              01006000
                                                                        01008000
    TOS := TBASE(THEAD);                                                01010000
    IF = THEN RETURN;     << SECONDARY TABLE EMPTY >>                   01012000
                                                                        01014000
    X := S0;          << POINT TO LINK >>                               01016000
    CHECKINDEX(S0,TBASE);                                               01018000
    GETGBUF := TOS + @TBASE;   << FORM SYSDB RELATIVE POINTER >>        01020000
                                                                        01022000
    TOS := TBASE1(X);     << GET LINK OF NEXT ELEMENT >>                01024000
    IF = THEN   << TABLE EMPTY NOW >>                                   01026000
      TBASE(TTAIL) := THEAD+@TBASE-@TBASE1                              01028000
    ELSE                                                                01030000
      TBASE1(X) := 0;     << CLEAR LINK IN  GOTTEN ELEMENT >>           01032000
    TBASE(THEAD) := TOS; << RE LINK REST OF LIST >>                     01034000
                                                                        01036000
    TBASE(TUSE) := TBASE(TUSE) + 1;                                     01038000
    IF LTBASE(X)<LTBASE(X)&LSL(8) THEN << MAX<CURRENT IN USE >>         01040000
      TBASE(X) := TBASE(X) + %400;   << BUMP MAX IN USE >>              01042000
  END;    <<  GETIOQ   GETSBUF   GETTBUF  >>                            01044000
$PAGE                                                                   01046000
                                                                        01048000
$PAGE "RETURN T/SYS BUF"                                       <<JB.19>>01050000
PROCEDURE RETURNGBUF(PNTR);  << NO LONGER TBUF >>                       01052000
  VALUE PNTR;   INTEGER POINTER PNTR;                                   01054000
  OPTION PRIVILEGED, UNCALLABLE;                                        01056000
                                                                        01058000
  << THIS PROCEDURE RETURNS THE ELEMENT POINTED TO BY PNTR AND IF       01060000
     UNIMPEDES ANY WAITING PROCESSES                                    01062000
  >>                                                                    01064000
  BEGIN                                                                 01066000
    DEFINE  SIZE = TBASE(1).(8:8)#,      << SIZE OF TABLE ENT>><<02627>>01068000
            NOOFENTRIES = TBASE&LSR(8)#; << NO. OF ENTRIES >>  <<02627>>01070000
    INTEGER POINTER DITP   = Q+1;                                       01072000
    INTEGER POINTER TBASE  = Q+1;    << POINTS TO BASE OF I/O TABLE >>  01074000
    INTEGER POINTER TBASE1 = Q+2; << TBASE MODIFIED TO ADDR LINKS >>    01076000
    ENTRY RETURNSBUF;                                                   01078000
    ENTRY RETURNIOQ;                                                    01080000
    ENTRY RETURNDISCREQ;                                       <<01640>>01082000
                                                                        01084000
    IF TBUF(TTAIL)=(@PNTR-@TBUF)                                        01086000
      OR 1<=PNTR<=@TBUF THEN  << ALREADY IN FREE LIST >>                01088000
        SUDDENDEATH(202);                                               01090000
                                                                        01092000
    TOS := DEQUEUE(DTBLK,TBQN);    << SET DITP >>                       01094000
    ASMB(TEST     );                                                    01096000
    IF > THEN   << A REQUEST FOR A TBUF QUEUED >>                       01098000
      BEGIN                                                             01100000
        DISABLE;                                                        01102000
        X := DITP(DIOQP);  << ANY REQUESTS WAITING >>                   01104000
        IF <> AND WA0(X:=X+QMISC).RSTATE>=PRETOPOST THEN                01106000
          BEGIN  << REQUEST WAITING FOR A TBUF >>                       01108000
            DITP(DNXTB) := @PNTR;                                       01110000
            PNTR := 0;   << CLEAR LINK >>                               01112000
            AWAKETERMINAL(DITP);                                        01114000
            RETURN;                                                     01116000
          END;                                                          01118000
      END;                                                              01120000
                                                                        01122000
    TOS := @TBUF;    <<  SET TBASE  >>                                  01124000
    DELB;  TOS := S0;  << DELETE DITP, TBUF LINK IS WORD 0 >>           01126000
    GOTO L2;                                                            01128000
                                                                        01130000
RETURNSBUF:                                                             01132000
    TOS := @SBUF;    <<  SET TBASE  >>                                  01134000
    TOS := S0 - 1;  << SET TBASE1 TO ADDRESS SBUF LINKS >>              01136000
    GOTO L2;                                                            01138000
                                                                        01140000
RETURNIOQ:                                                              01142000
 TOS := ABSOLUTE(SYSDISCREQTAB);  << CHECK TO SEE IF DISCREQ >><<02627>>01144000
 TOS := S0 + 1;                                                <<02627>>01146000
 TOS := @PNTR - @TBASE -%20;    << GET WORD INDEX OF ENTRY >>  <<02627>>01148000
 IF 0<=S0<=SIZE*NOOFENTRIES     << IS INDEX IN THE TABLE >>    <<02627>>01150000
   THEN                         << TAKE QUICK PATCH TO DISC >> <<02627>>01152000
    BEGIN                                                      <<02627>>01154000
     DEL;       << DELETE TABLE WORD INDEX >>                  <<02627>>01156000
     GO TO QUICKDISC;                                          <<02627>>01158000
    END                                                        <<02627>>01160000
   ELSE ASSEMBLE(DEL,DDEL);     << NOT DISC POP ITS PNTRS >>   <<02627>>01162000
    IF  IOQ(TTAIL)=(@PNTR-@IOQ)                                <<01.02>>01164000
      OR 1<=PNTR(1)<=@IOQ THEN   << ALREADY IN FREE LIST >>    <<01.02>>01166000
        SUDDENDEATH(204);                                      <<01.02>>01168000
                                                               <<01.02>>01170000
    TOS := @IOQ;     << SET TBASE  >>                                   01172000
    TOS := S0 + 1;  << SET TBASE1 TO ADDRESS IOQ LINKS >>               01174000
    STORE'IOQ(PNTR, TRUE);                                     <<01830>>01176000
    GO TO L2;                                                  <<01772>>01178000
                                                                        01180000
RETURNDISCREQ:                                                 <<01640>>01182000
REALLYDISCREQ:                                                 <<01640>>01184000
    TOS:=ABSOLUTE(SYSDISCREQTAB); <<SET TBASE>>                <<01640>>01186000
    TOS:=S0+1; <<SET TBASE1 TO ADDRESS LINKS>>                 <<01640>>01188000
QUICKDISC:                      << FROM RETURNIOQ ENTRY >>     <<02627>>01190000
    DISCREQTAB(@PNTR-ABSOLUTE(SYSDISCREQTAB)+15) :=            <<01772>>01192000
     @PNTR-@IOQ; <<STAMP DISC REQ WITH LAST IOQ FOR IOSTAT>>   <<01772>>01194000
L2:                                                                     01196000
    DISABLE;                                                            01198000
    TBASE(TUSE) := TBASE(TUSE) - 1;                                     01200000
    TOS := @PNTR - @TBASE;  << FORM ELEMENT INDEX >>                    01202000
    CHECKINDEX(S0,TBASE);                                               01204000
    ASMB( DUP,STBX);                                                    01206000
    TBASE1(X) := 0;    << ZERO LINK OF ONE BEING RETURNED  >>           01208000
    X := TBASE(TTAIL);         << INDEX OF LAST ENTRY >>                01210000
    TBASE1(X) := TOS;      << LINK THIS TO LAST >>                      01212000
    TBASE(TTAIL) := TOS;  << SET TAIL POINTER >>                        01214000
                                                                        01216000
    TOS := TBASE(TSIZE).PCBN;    << GET IMPEDED LINK >>                 01218000
    IF <> AND TBASE(TUSE).INUSE<TBASE.LIMIT1 THEN                       01220000
      IOUNIMPEDE(@TBASE);                                               01222000
  END;   << RETURNIOQ  RETURNSBUF   RETURNTBUF  >>                      01224000
$PAGE "CLEAR WAKE"                                             <<JB.19>>01226000
                                                                        01228000
PROCEDURE CLEARWAKE(IOQX);                                              01230000
  VALUE IOQX;   INTEGER IOQX;                                           01232000
  OPTION UNCALLABLE, PRIVILEGED;                                        01234000
                                                                        01236000
    << THIS PROCEDURE SETS/CLEARS IOWAKE BIT.  IT CHECKS THE  COMPLETED 01238000
       FLAG BEFORE PREFORMING REQUEST.  IF THE REQUEST HAS COMPLETED    01240000
       A CCL IS RETURNED TO THE CALLER OTHERWISE IOWAKE IS SET AS       01242000
       REQUESTED AND A CCE IS RETURNED.  INTERRUPT DISABLED STATUS      01244000
       IS MAINTAINED OVER THE CALL.                                     01246000
    >>                                                                  01248000
  BEGIN                                                                 01250000
    POINTER IOQT = 5;      << SYSTEM TABLE POINTER TO IOQ >>            01252000
    INTEGER FLAG = Q+1;                                                 01254000
    ENTRY  SETWAKE;                                                     01256000
                                                                        01258000
    TOS := 0;    << SET FLAG TO CLEAR IOWAKE >>                         01260000
    GOTO L1;                                                            01262000
                                                                        01264000
SETWAKE:                                                                01266000
    TOS := 1;    << SET FLAG TO SET IOWAKE >>                           01268000
                                                                        01270000
L1:                                                                     01272000
    TOS := RSTATUS;                                                     01274000
    DISABLE;                                                            01276000
   TOS:=IOQX;                                                  <<MPEIV>>01278000
   ASMB(TRBC 1); <<SEE IF DISC REQ>>                           <<01685>>01280000
   IF <> THEN TOS:=DISCREQTAB(X:=TOS)                          <<MPEIV>>01282000
   ELSE TOS:=IOQT(X:=TOS);                                     <<MPEIV>>01284000
    TESTBIT COMPLETED');                                                01286000
    IF = THEN             << REQUEST NOT COMPLETED >>                   01288000
      BEGIN                                                             01290000
        TOS.IOWAKE := FLAG;    << SET OR CLEAR IOWAKE  >>               01292000
      TOS:=IOQX;                                               <<MPEIV>>01294000
      ASMB(TRBC 1); <<SEE IF DISC REQ>>                        <<01685>>01296000
      IF <> THEN                                               <<MPEIV>>01298000
         BEGIN                                                 <<MPEIV>>01300000
         X:=TOS;                                               <<MPEIV>>01302000
         DISCREQTAB(X):=TOS;                                   <<MPEIV>>01304000
         END                                                   <<MPEIV>>01306000
      ELSE                                                     <<MPEIV>>01308000
         BEGIN                                                 <<MPEIV>>01310000
         X:=TOS;                                               <<MPEIV>>01312000
         IOQT(X):=TOS;                                         <<MPEIV>>01314000
         END;                                                  <<MPEIV>>01316000
        TOS := CCE;                                                     01318000
      END                                                               01320000
    ELSE   << REQUEST  COMPLETED >>                                     01322000
      BEGIN                                                             01324000
        DEL;   << DELETE QFLAGS >>                                      01326000
        TOS := CCL;                                                     01328000
      END;                                                              01330000
                                                                        01332000
    TOS.CC := TOS;                                                      01334000
    RSTATUS := TOS;       << SET NEW RETURN CC >>                       01336000
  END;    <<   CLEARWAKE  /  SET WAKE  >>                               01338000
                                                                        01340000
$PAGE "PROCEDURE: P'ATTACHIO"                                  <<04317>>01342000
DOUBLE PROCEDURE P'ATTACHIO(LDEV, QMISC, DSTX, ADDR, FNCT,     <<04317>>01344000
                            CNT, P1, P2, FLAGS,                <<04500>>01346000
                            EXTBASE, EXTSIZE);                 <<04500>>01348000
                                                               <<04317>>01350000
VALUE                       LDEV, QMISC, DSTX, ADDR, FNCT,     <<04317>>01352000
                            EXTBASE, EXTSIZE,                  <<04500>>01354000
                            CNT, P1, P2, FLAGS;                <<04317>>01356000
                                                               <<04317>>01358000
INTEGER                     LDEV, QMISC, DSTX, ADDR, FNCT,     <<04317>>01360000
                            CNT, P1, P2, FLAGS;                <<04317>>01362000
                                                               <<04317>>01364000
DOUBLE                      EXTBASE;                           <<04500>>01366000
                                                               <<04500>>01368000
LOGICAL                     EXTSIZE;                           <<04500>>01370000
                                                               <<04500>>01372000
OPTION PRIVILEGED, UNCALLABLE, VARIABLE;                       <<04500>>01374000
  BEGIN                                                                 01376000
comment                                                        <<02801>>01378000
<<*****************************************************>>      <<02801>>01380000
LDEV   - Logical device number                                 <<02801>>01382000
QMISC  - Misc parameter specified for device                   <<02801>>01384000
DSTX   - DST number of data segment.  If zero, then            <<02801>>01386000
         specifies that ADDR is DB relative to the caller's    <<02801>>01388000
         stack.  Must be zero if system buffers is specified.  <<02801>>01390000
ADDR   - Depending on FLAGS.(14:1) and DSTX, this may be:      <<02801>>01392000
         1)Offset to data in DST.                              <<02801>>01394000
         2)Offset to data from DB in callers stack.            <<02801>>01396000
         3)Index to a system buffer.                           <<02801>>01398000
FUNC   - Function code.  Device defined, but usually:          <<02801>>01400000
         0 - Read.                                             <<02801>>01402000
         1 - Write.                                            <<02801>>01404000
         2 - Open file.                                        <<02801>>01406000
         3 - Close file.                                       <<02801>>01408000
         4 - Close device.                                     <<02801>>01410000
CNT    - Data transfer count, + words or - bytes.              <<02801>>01412000
P1     - Parameter 1.  Device dependant.                       <<02801>>01414000
P2     - Parameter 2.  Device dependant.                       <<02801>>01416000
FLAGS  - Control and specification flags.                      <<02801>>01418000
         (0:4) - Caller is unknown(0), file system(1), or      <<02801>>01420000
                 spooler(2).                                   <<02801>>01422000
         (4:3) - Available                                     <<02801>>01424000
         (7:2) - Premption flags, soft(1) or hard(2).          <<02801>>01426000
         (9:1) - 0.                                            <<02801>>01428000
         (10:1)- Special request, device defined.  Usually     <<02801>>01430000
                 memory management.                            <<02801>>01432000
         (11:1)- If set, this is a diagnostic request.         <<02801>>01434000
         (12:1)- System buffer flag.  If set, ADDR is an index <<02801>>01436000
                 relative to the SBUF table.  For devices      <<02801>>01438000
                 that support chaining, the data is trans-     <<02801>>01440000
                 ferred to and from a set of chained buffers,  <<02801>>01442000
                 up to a maximum of 1024 words.                <<02801>>01444000
         (13:3)- Request type:                                 <<02801>>01446000
                 0)Unblocked, no wake.  Impede if no IOQ.      <<02801>>01448000
                 1)Blocked (caller is waited until done).      <<02801>>01450000
                 2)Unblocked, wake caller, impede if no IOQ.   <<02801>>01452000
                 3)Unblocked & no PIN is to be associated      <<02801>>01454000
                   with this I/O.  Impede if no IOQ.           <<02801>>01456000
                 4)Unblocked, no wake, no impede if no IOQ.    <<02801>>01458000
                 5)Reserved.                                   <<02801>>01460000
                 6)Unblocked, wake, no impede if no IOQ.       <<02801>>01462000
                 7)Same as 3 but no impede & get secondary     <<02801>>01464000
                   IOQ if necessary.                           <<02801>>01466000
                                                               <<02801>>01468000
RETURN:                                                        <<02801>>01470000
                                                               <<02801>>01472000
Blocked-                                                       <<02801>>01474000
                                                               <<02801>>01476000
S-1    - (0:8) - PCB number.                                   <<02801>>01478000
         (8:5) - Qualifying status.                            <<02801>>01480000
         (13:3)- General status.                               <<02801>>01482000
S-0    - Transmission log (+words or -bytes).                  <<02801>>01484000
                                                               <<02801>>01486000
Unblocked-                                                     <<02801>>01488000
                                                               <<02801>>01490000
S-1    - IOQ index of request  (1 if no PCB I/O)               <<03686>>01492000
S-0    - 0                                                     <<02801>>01494000
                                                               <<02801>>01496000
<<************************************************************><<02801>>01498000
;                                                              <<02801>>01500000
    INTEGER PCBNUM=Q+1;                                        <<01.03>>01502000
    INTEGER DBSAVE = PCBNUM + 1;                               <<01.03>>01504000
    INTEGER ARRAY DITP(@) = DBSAVE + 1;                        <<01.03>>01506000
    LOGICAL POINTER DITPL = DITP;                                       01508000
    INTEGER SAVECRIT = DITP + 1;                               <<01.03>>01510000
<<>>                                                           <<03031>>01512000
<<>>                                                           <<03031>>01516000
<<>>                                                           <<03031>>01520000
<<>>                                                           <<03031>>01522000
<<>>                                                           <<03031>>01526000
<<>>                                                           <<03031>>01528000
<<>>                                                           <<03031>>01530000
<<>>                                                           <<03031>>01532000
    ARRAY QARRAY(*)=Q+0;                                       <<03031>>01534000
                                                               <<03031>>01536000
equate TERMINAL   = 16,    << Device type 16 is terminal >>    <<03686>>01538000
       DTYPE      = 5;     << Device type word in DLT    >>    <<03686>>01540000
                                                               <<03686>>01542000
define DDTYPE     = (8:8)#;<< Device type field in DLT   >>    <<03686>>01544000
                                                               <<03686>>01546000
    INTEGER ARRAY DLTP(@)=SAVECRIT + 1;                        <<00192>>01548000
    INTEGER POINTER IOQP  = DLTP + 1;                          <<00192>>01550000
    LOGICAL POINTER IOQPL = IOQP;                                       01552000
    DOUBLE  POINTER IOQPD = IOQP;                                       01554000
                                                                        01556000
    LOGICAL PFLAG = IOQP+1;  << SET IF PREMPTIVE REQUEST QUEUED >>      01558000
                                                                        01560000
    INTEGER STACKDST = PFLAG+1;  << HOLDS STACK DST IF A STACK ADDR >>  01562000
                                                                        01564000
    DOUBLE POINTER DSTD = DST;                                          01566000
    DOUBLE ARRAY PARAMS(*) = Q - %22;  << FOR MOVE TO IOQ ELEME<<04500>>01568000
    LOGICAL LFLAGS = FLAGS;                                             01570000
                                                                        01572000
    << TRAPSOFF; >>                                            <<04500>>01574000
    << FORCE STACK OVERFLOWS, LEAVE 2 WORDS OF LOCAL DATA >>   <<02074>>01576000
    ASMB(ADDS 255;SUBS 253);                                   <<02074>>01578000
                                                               <<02074>>01580000
    PUSH(DB);   IF TOS=%1000 D THEN ASMB(DEL,ZERO) ELSE                 01582000
    ASMB( PCAL SETSYSDB );  << SET DBSAVE >>                            01584000
    TOS := LPDTD(LDEV);  << SET DITP >>                                 01586000
                                                                        01590000
                                                                        01592000
    X := DBSAVE;   << TEST IF I/O SYSTEM CALL >>                        01594000
    IF <> THEN ASMB(PCAL SETCRITICAL);  << SET SAVECRIT >>              01596000
                                                                        01598000
                                                               <<04500>>01600000
                                                               <<04500>>01602000
    IF ABS(SYSMON) THEN    << MONITOR ENABLED >>               <<04500>>01604000
      IF DITPL.TDFLAGS = 1 THEN  << DISC TRAFFIC >>            <<04500>>01606000
        BEGIN                                                  <<04500>>01608000
        PDISABLE;                                              <<04500>>01610000
        MMSTAT(-98,CNT,FLAGS.(0:4),FNCT);                      <<04500>>01612000
        tos := -130;    << MMSTAT event number >>              <<04500>>01614000
        tos := LDEV;    << Logical device number >>            <<04500>>01616000
        tos := QARRAY(-(QARRAY + 2)); << Caller's P-register >><<04500>>01618000
        tos := QARRAY(X:=X+1); << Caller's status register   >><<04500>>01620000
        MMSTAT(*,*,*,*);                                       <<04500>>01622000
        TOS := -131;                                           <<04500>>01624000
        TOS := EXTBASE;                                        <<04500>>01626000
        TOS := EXTSIZE;                                        <<04500>>01628000
        MMSTAT(*,*,*,*);                                       <<04500>>01630000
        MMSTAT(-132,P1,P2,FLAGS);                              <<04500>>01632000
        PENABLE;                                               <<04500>>01634000
        END;                                                   <<04500>>01636000
     FLAGS.(0:4) := 0;                                         <<00.04>>01638000
    TOS := DITP(DDLTP);    <<SET UP DLT>>                      <<00192>>01640000
    IF DITPL.TDFLAGS=1 THEN TOS:=GETDISCREQ(FLAGS.             <<01640>>01642000
    NOTIMPEDABLE) ELSE                                         <<01640>>01644000
    << if request type 7, get IOQ from secondary area, >>      <<02801>>01646000
    << else get IOQ from primary area & impede if 13:1 >>      <<02801>>01648000
    << in FLAGS is off (zero).                         >>      <<02801>>01650000
    tos := GETIOQ(if FLAGS.(13:3)=7 then 2                     <<02801>>01652000
                     else FLAGS.NOTIMPEDABLE);                 <<02801>>01654000
    ASMB(TEST,DZRO);   << FOR STACKDST AND PFLAG >>                     01656000
    IF = THEN GOTO OUT;   << NO IOQ'S AVAILABLE >>                      01658000
                                                                        01660000
    IF LFLAGS.SYSBUFRS THEN DSTX := 8;  << DST # OF SYS BUFS >>         01662000
                                                                        01664000
    X := DSTX;                                                          01666000
    IF = THEN   << A STACK RELATIVE ADDRESS >>                          01668000
      BEGIN                                                             01670000
        STACKDST := ABS(ABS(CPCB)+PCB3).DSTFIELD;              <<00.05>>01672000
        TOS := STACKDST;  TOS.STACKFLAG := 1;  DSTX := TOS;    <<00.05>>01674000
      END                                                      <<MPEIV>>01676000
   ELSE IF DITPL.TDFLAGS=1 AND FLAGS.RTYPE=1                   <<MPEIV>>01678000
   AND DSTX <> ABSOLUTE(ABSOLUTE(CPCB)+DBXDSINFOWORDNUM).      <<MPEIV>>01680000
   XDSDSTFIELD THEN                                            <<MPEIV>>01682000
      BEGIN <<BLOCKED DISC I/O,NOT TO STACK OR DB SEG>>        <<MPEIV>>01684000
      IF DST(DSTX&LSL(2)) < 0 THEN QUEUEONSEGMENT(DSTX);       <<MPEIV>>01686000
      DST(X).REFERENCEDFLAG:=1;                                <<MPEIV>>01688000
      TOS:=ABSOLUTE(ABSOLUTE(CPCB)+SLLIXWORDNUM);              <<MPEIV>>01690000
      TOS:=DSTX;                                               <<MPEIV>>01692000
      TOS:=0;                                                  <<MPEIV>>01694000
      TOS.SETDISCIOSEGFLAG:=1;                                 <<MPEIV>>01696000
      ADDTOLOCALITY(*,*,*);                                    <<MPEIV>>01698000
      END;                                                     <<MPEIV>>01700000
                                                                        01702000
    X := 5;                                                             01704000
    WHILE DXBZ DO IOQPD(X) := PARAMS(X);  << MOVE LDEV/P2 TO IOQ >>     01706000
    IOQP(QSTAT) := 0;                                                   01708000
                                                                        01710000
    TOS := 0;   TOS.(1:3) := FLAGS.(10:3);  << SPEC,DIAG,SYSBUF >>      01712000
                                                                        01714000
    X := FLAGS.RTYPE;   << SWITCH ON REQUEST TYPE >>                    01716000
    ASMB( BR *+1,X ;                                                    01718000
      br RT0;  br RT1;  br RT2;  br RT3 );                     <<03655>>01720000
                                                               <<03655>>01722000
RT1:  << Blocked I/O - must clear WWS bit in PCB >>            <<03655>>01724000
    tos.BLOCKED := 1;  << Turn on blocked bit in FLAGS >>      <<03655>>01726000
    DISABLE;                                                   <<03655>>01728000
    CLEARWWS;                                                  <<03655>>01730000
                                                                        01732000
RT2:                                                                    01734000
    TOS.IOWAKE := 1;                                                    01736000
RT0:                                                                    01738000
    IOQP(QSTAT) := ((ABS(CPCB)-ABS(PCBB))/PCBSIZE)&LSL(8);  << SET PCB>>01740000
RT3:                                                                    01742000
   PCBNUM := IOQP(QSTAT).PCBN;                                 <<01805>>01744000
    TOS := FLAGS.PREMPTFIELD;                                           01746000
    DISABLE;                                                            01748000
    IF <> OR DITP<0 AND DITPL(DMODEM).CMODE AND                         01750000
     (ABS(CPCB)-ABS(PCBB))=PROGENPCBP THEN                              01752000
      BEGIN << PREMPTIVE OR TERMINAL IN CONSOLE MODE >>                 01754000
        PFLAG := TRUE;     << SET SO AWAKEIO CALLED >>                  01756000
        if PCBNUM <> 0 then CLEARWWS; << May be on ICS >>      <<03686>>01758000
        X := DITP;                                                      01760000
        IF < THEN    << A TERMINAL >>                                   01762000
          BEGIN                                                         01764000
            TOS := TOS + 2;  << FORM HARD/SOFT/CONSMODE PREMPT CODE >>  01766000
            DITP(DMODEM).PREMPT := 1;                                   01768000
          END                                                           01770000
        ELSE                                                            01772000
          BEGIN                                                         01774000
            TOS := TOS&LSL(2);  << POSITION TO (12:2) >>                01776000
            DITP.SIOPREMPT := 1;                                        01778000
          END;                                                          01780000
      END;                                                              01782000
                                                                        01784000
    IOQP := TOS LOR TOS; << MERGE RPLEVEL WITH FLAGS >>                 01786000
                                                               <<MPEIV>>01788000
IF DITPL.TDFLAGS = 1 THEN                                      <<MPEIV>>01790000
   BEGIN <<DISC REQUEST>>                                      <<MPEIV>>01792000
   TOS:=ABSOLUTE(ABSOLUTE(CPCB)+QUEUEINGINFOWORDNUM).PRIFIELD; <<MPEIV>>01794000
   IOQP(QPRIWORDNUM):=TOS;                                     <<MPEIV>>01796000
   QUEUEDISCREQ(@IOQP,@DITP);                                  <<MPEIV>>01798000
   <<DISCQMANAGER AWOKE DEVICE IF NOT ACTIVE SO NO PFLAG>>     <<MPEIV>>01800000
   END                                                         <<MPEIV>>01802000
ELSE                                                           <<MPEIV>>01804000
   BEGIN                                                       <<MPEIV>>01806000
                                                                        01808000
    TOS := DITP(DIOQP);                                                 01810000
    IF = THEN    << FIRST REQUEST >>                                    01812000
      BEGIN                                                             01814000
        DITP(X) := @IOQP;   << LINK IN REQUEST >>                       01816000
        PFLAG := TRUE;  << FORCE AWAKEIO >>                             01818000
      END                                                               01820000
    ELSE                                                                01822000
      BEGIN  << FIND END OF IOQ LIST >>                                 01824000
        WHILE <> DO  << SCAN TO END >>                                  01826000
          BEGIN                                                         01828000
            X := TOS+1;  << SYSDB RELATIVE INDEX TO LINK >>             01830000
            TOS := WA0(X);  << GET NEXT LINK >>                         01832000
          END;                                                          01834000
                                                                        01836000
        WA0(X) := @IOQP;  << LINK TO END >>                             01838000
      END;                                                              01840000
   END;                                                        <<MPEIV>>01842000
$PAGE                                                                   01844000
                                                                        01846000
    IF PFLAG THEN  << PREMPTIVE OR FIRST REQUEST >>                     01848000
      BEGIN   << CALL MONITOR/DRIVER >>                                 01850000
                                                               <<03655>>01852000
CALLMONITOR:                                                   <<03655>>01854000
                                                               <<03655>>01856000
        TOS := @DITP;     TOS := STACKDST&LSL(6);                       01858000
        IF NOT LFLAGS.NOTIMPEDABLE THEN TOS.IMPEDEOK := 1;              01860000
        <<PDISABLE IF DISC>>                                 <<01.02>>  01862000
        IF DITPL.TDFLAGS = 1 THEN PDISABLE;                  <<01.02>>  01864000
        ENABLE;                                                         01866000
        AWAKEIO( *, * );    << CALL MONITOR >>                          01868000
        <<PENABLE IF DISC>>                                  <<01.02>>  01870000
        IF DITPL.TDFLAGS = 1 THEN PENABLE;                   <<01.02>>  01872000
      end                                                      <<03655>>01874000
    else                                                       <<03655>>01876000
      ENABLE;  << Disc I/O may finish by now (if real fast) >> <<03655>>01878000
                                                               <<03655>>01880000
    IF PCBNUM = 0 THEN    <<NO PCBIO, RETURN WITH COMPLETION>><<<01.03>>01882000
      BEGIN                                                    <<01.03>>01884000
      TOS := 1;                                                <<01.03>>01886000
      TOS := 0;                                                <<01.03>>01888000
      GO TO OUT1;                                              <<01.03>>01890000
      END                                                      <<01.03>>01892000
    ELSE                                                       <<01.03>>01894000
      BEGIN                                                    <<01.03>>01896000
    DISABLE;                                                            01898000
    TOS := IOQP;  << GET QFLAGS >>                                      01900000
    IF FLAGS.RTYPE=1 THEN   << BLOCKED I/O >>                           01902000
      BEGIN                                                             01904000
        IF NOT TOS.COMPLETED THEN  << NOT COMPLETED SO WAIT >>          01906000
          BEGIN                                                         01908000
          IF GCLASSENABLEDMASK.CLASS0 THEN                     <<MPEIV>>01910000
             BEGIN  <<MEASURE STOP ON BLOCKED I/O EVENT>>      <<MPEIV>>01912000
             TOS:=MEASSTATXDSBANK;                             <<MPEIV>>01914000
             TOS:=MEASSTATXDSBASE;                             <<MPEIV>>01916000
             TOS:=TOS+C0SUB0'SEGRELOFF;                        <<MPEIV>>01918000
             IF DITPL.(0:2)=DISC' THEN TOS:=TOS+1<<DISC I/O>>  <<MPEIV>>01920000
             ELSE IF (DITP.(0:1)=1 LAND FNCT.FUNC=0)<<TERM READ<<MPEIV>>01922000
             THEN TOS:=TOS+9 ELSE IF DITP.(0:1)=1<<TERM I/O>>  <<MPEIV>>01924000
             THEN TOS:=TOS+10 ELSE TOS:=TOS+24;<<MISC BIO>>    <<MPEIV>>01926000
             ASMB(LSEA);                                       <<MPEIV>>01928000
             TOS:=TOS+1;                                       <<MPEIV>>01930000
             ASMB(SSEA;DDEL);                                  <<MPEIV>>01932000
             END;                                              <<MPEIV>>01934000
          IF GCLASSENABLEDMASK.CLASS15 THEN                    <<01805>>01936000
             BEGIN <<PROCESS LEVEL BLOCKED IO>>                <<01805>>01938000
             TOS:=MEASPROCXDSBANK;                             <<01805>>01940000
             TOS:=MEASPROCXDSBASE;                             <<01805>>01942000
             TOS:=TOS+IOQP(QSTAT).PCBN*CLASS15'SUB0SIZE;       <<01805>>01944000
             IF DITPL.(0:2)=DISC' THEN                         <<01805>>01946000
                TOS:=TOS+CP'STOPBLOCKDISC ELSE                 <<01805>>01948000
             IF (DITP.(0:1)=1 LAND FNCT.FUNC=0) THEN           <<01805>>01950000
                TOS:=TOS+CP'STOPTERMREAD ELSE                  <<01805>>01952000
             IF DITP.(0:1) <> 1 THEN                           <<01805>>01954000
                TOS:=TOS+CP'STOPBLOCKEDIO                      <<01805>>01956000
             ELSE  <<DON'T WANT TO COUNT IT NOW>>              <<01805>>01958000
                GO TO SKIPIT;                                  <<01805>>01960000
             ASMB(LSEA);                                       <<01805>>01962000
             TOS:=TOS+1;                                       <<01805>>01964000
             ASMB(SSEA);                                       <<01805>>01966000
     SKIPIT: ASMB(DDEL);                                       <<01805>>01968000
             END;                                              <<01805>>01970000
          <<STUFF AWAY REASON STOPPED IN PROCESSES PCBX>>      <<01805>>01972000
          <<DONE UNCONDITIONALLY FOR HISTORY FOR MEAS INTF>>   <<01805>>01974000
          TOS:=ICS(-ICSSTKBANK);                               <<01805>>01976000
          TOS:=ICS(-ICSSTKBASE)+PXGLOBSIZE+MEASSTOPREASON'IDX; <<01805>>01978000
          IF DITPL.(0:2)=DISC' THEN                            <<01805>>01980000
             TOS:=STOPDISCWAIT ELSE                            <<01805>>01982000
          IF (DITP.(0:1)=1 LAND FNCT.FUNC=0) THEN              <<01805>>01984000
             TOS:=STOPTERMREAD ELSE                            <<01805>>01986000
          IF DITP.(0:1) <> 1 THEN                              <<01805>>01988000
             TOS:=STOPBLKIONONTERM ELSE                        <<01805>>01990000
             TOS:=0;                                           <<01805>>01992000
          ASMB(SSEA;DDEL);                                     <<01805>>01994000
          TOS:=-%200;                                          <<MPEIV>>01996000
          TOS:=0; <<FOR WAIT'S SPECIAL INFORMATION PARAMETER>> <<MPEIV>>01998000
          IF DITPL.TDFLAGS = 1 then                            <<03686>>02000000
            begin   << DISC I/O >>                             <<03686>>02002000
            ASMB(tsbc SWBIT);  << Turn on short-wait bit >>    <<03686>>02004000
            absolute(SYSWAITTODISPMSG).DISCWAITFLAG := 1;      <<03686>>02006000
            end    << of special DISC processing >>            <<03686>>02008000
                                                               <<03686>>02010000
          else                                                 <<03686>>02012000
                                                               <<03686>>02014000
            if FNCT.FUNC = 0 then  << This is a read >>        <<03686>>02016000
              if DITP.(0:1) = 1 or << is a terminal  >>        <<03686>>02018000
                 DLTP(DTYPE).DDTYPE = TERMINAL then << MTS >>  <<03686>>02020000
                begin                                          <<03686>>02022000
                ASMB(tsbc 15);   << Tell DISP this is TRW >>   <<03686>>02024000
                absolute(SYSWAITTODISPMSG).TERMREADFLAG := 1;  <<03686>>02026000
                end;  << of special Terminal Read handling >>  <<03686>>02028000
                                                               <<03686>>02030000
            WAIT( *, * );                                      <<MPEIV>>02034000
                                                               <<MPEIV>>02036000
            IF NOT IOQPL.COMPLETED THEN GOTO CALLMONITOR;      <<MPEIV>>02038000
          END;                                                 <<MPEIV>>02040000
                                                               <<MPEIV>>02042000
        ENABLE;                                                <<MPEIV>>02044000
        TOS := IOQP(QFUNC);    << RETURN LEFT BYTE OF QFUNC >> <<MPEIV>>02046000
        TOS.(8:8) := IOQP(QSTAT);    << RETURN STATUS >>       <<MPEIV>>02048000
        TOS := IOQP(QWBCT);                                    <<MPEIV>>02050000
        RETURNIOQ(IOQP);                                       <<MPEIV>>02052000
      END                                                      <<MPEIV>>02054000
    ELSE                                                       <<MPEIV>>02056000
      BEGIN << UNBLOCKED REQUEST, RETURN IOQ INDEX >>          <<MPEIV>>02058000
        ENABLE;                                                <<MPEIV>>02060000
        IF DITPL.TDFLAGS = 1 THEN                              <<MPEIV>>02062000
           BEGIN                                               <<MPEIV>>02064000
           TOS:=@IOQP-ABS(SYSDISCREQTAB);                      <<MPEIV>>02066000
            TOS.(1:1):=1;<<FLAG AS DISC REQ>>                  <<01685>>02068000
           END                                                 <<MPEIV>>02070000
        ELSE                                                   <<MPEIV>>02072000
        TOS := @IOQP - @IOQ;  << FORM IOQ INDEX >>                      02074000
OUT:                                                                    02076000
        TOS := 0;  << FOR P'ATTACHIO RETURN >>                 <<04317>>02078000
      END;                                                              02080000
      END;                                                     <<01.03>>02082000
                                                                        02084000
OUT1:  P'ATTACHIO := TOS;                                      <<04317>>02086000
                                                                        02088000
    TOS := DBSAVE;    IF = THEN RETURN;  << NOT SET HERE >>             02090000
    RESETCRITICAL(SAVECRIT);                                            02092000
    RESETDB( * );                                                       02094000
  END;      <<  P'ATTACHIO >>                                  <<04317>>02096000
$PAGE "PROCEDURE: ATTACHIO"                                    <<04317>>02098000
DOUBLE PROCEDURE ATTACHIO(LDEV, QMISC, DSTX, ADDR, FNCT,       <<04317>>02100000
                          CNT, P1, P2, FLAGS);                 <<04317>>02102000
                                                               <<04317>>02104000
VALUE                     LDEV, QMISC, DSTX, ADDR, FNCT,       <<04317>>02106000
                          CNT, P1, P2, FLAGS;                  <<04317>>02108000
                                                               <<04317>>02110000
INTEGER                   LDEV, QMISC, DSTX, ADDR, FNCT,       <<04317>>02112000
                          CNT, P1, P2, FLAGS;                  <<04317>>02114000
                                                               <<04317>>02116000
OPTION PRIVILEGED, UNCALLABLE;                                 <<04317>>02118000
                                                               <<04317>>02120000
BEGIN                                                          <<04317>>02122000
                                                               <<04317>>02124000
COMMENT                                                        <<04317>>02126000
                                                               <<04317>>02128000
     WHO:  Allan Walthers/Boise Division CIPER/3000 software.  <<04317>>02130000
Modified 4/20/82 for possible inclusion in BFD or CUB MITS.    <<04317>>02132000
                                                               <<04317>>02134000
     WHAT:  The old ATTACHIO is now known as P'ATTACHIO.       <<04317>>02136000
This procedure known as ATTACHIO is essentially a new module.  <<04317>>02138000
                                                               <<04317>>02140000
     PURPOSE:  This  procedure  determines the  type of device <<04317>>02142000
the  request  is  destined for, and routes  the request to the <<04317>>02144000
appropriate  device handling procedure,  if any.  For example, <<04317>>02146000
if  the  device is a CIPER device,   a logical driver for that <<04317>>02148000
class of device is called.                                     <<04317>>02150000
                                                               <<04317>>02152000
     INPUT:                                                    <<04317>>02154000
                                                               <<04317>>02156000
LDEV      Logical device number to which the IO is destined.   <<04317>>02158000
                                                               <<04317>>02160000
QMISC     Miscellaneous  parameter  specified for  the device. <<04317>>02162000
          If not specified must be zero.                       <<04317>>02164000
                                                               <<04317>>02166000
DSTX      DST  number of data segment.  If zero then specifies <<04317>>02168000
          that addr is DB relative to the callers stack.  Must <<04317>>02170000
          be zero if system buffers is specified.              <<04317>>02172000
                                                               <<04317>>02174000
ADDR      If  FLAGS.(12:1)  =  1  then  this is an  index to a <<04317>>02176000
          system  buffer.  If FLAGS.(12:1) =  0 then ADDR is a <<04317>>02178000
          relative address within data segment DSTX.           <<04317>>02180000
                                                               <<04317>>02182000
FNCT      Function code:  device defined but usually:          <<04317>>02184000
                                                               <<04317>>02186000
          0 = Read                                             <<04317>>02188000
          1 = Write                                            <<04317>>02190000
          2 = Open file                                        <<04317>>02192000
          3 = Close file                                       <<04317>>02194000
          4 = Close device                                     <<04317>>02196000
                                                               <<04317>>02198000
CNT       Data transfer count:                                 <<04317>>02200000
                                                               <<04317>>02202000
          If CNT > 0 then CNT value is a word count.  If CNT < <<04317>>02204000
          0 then CNT value is a byte count.                    <<04317>>02206000
                                                               <<04317>>02208000
P1        Parameter 1,  device dependent.                      <<04317>>02210000
                                                               <<04317>>02212000
P2        Parameter 2,  device dependent.                      <<04317>>02214000
                                                               <<04317>>02216000
FLAGS     Bit word.  Definitions are:                          <<04317>>02218000
                                                               <<04317>>02220000
.( 0:4)   Control and specification flags:                     <<04317>>02222000
                                                               <<04317>>02224000
          0 = unknown                                          <<04317>>02226000
          1 = file system                                      <<04317>>02228000
          2 = spooler                                          <<04317>>02230000
          10 = File system, NOBUF, sequential                  <<04500>>02232000
          11 = File system, NOBUF, direct access               <<04500>>02234000
          12 = File system, BUF, sequential                    <<04500>>02236000
          13 = File system, BUF, direct access                 <<04500>>02238000
          14 = File system, KSAM access (determined)           <<04500>>02240000
          15 = File system, IMAGE access (determined)          <<04500>>02242000
           9 = File system, BUF, FQUIESCEIO                    <<04500>>02244000
           8 = GENMESSAGE, msg set base, msg set size          <<04500>>02246000
          << * * See IOMOVE and FQUIESCEIO * * >>              <<04500>>02248000
                                                               <<04317>>02250000
.( 4:3)   0   Reserved. Not used.                              <<04317>>02252000
                                                               <<04317>>02254000
.( 7:2)   Premption flags.                                     <<04317>>02256000
                                                               <<04317>>02258000
          1 = soft premption                                   <<04317>>02260000
          2 = hard premption                                   <<04317>>02262000
                                                               <<04317>>02264000
.( 9:1)   0   Reserved. Not used.                              <<04317>>02266000
                                                               <<04317>>02268000
.(10:1)   Special  request.   Device  defined.   If  set  then <<04317>>02270000
          handling is to be applied to this request.           <<04317>>02272000
                                                               <<04317>>02274000
.(11:1)   If set then this is a diagnostic request.            <<04317>>02276000
                                                               <<04317>>02278000
.(12:1)   System  buffer  flag.   If set the  ADDR is an index <<04317>>02280000
          relative  to  the  SBUF  table.   For  devices which <<04317>>02282000
          support chaining the data is transferred to and from <<04317>>02284000
          a  set  of chained buffers, up  to a maximum of 1024 <<04317>>02286000
          words.   IF  clear  then  ADDR  is  a  data  segment <<04317>>02288000
          relative address.                                    <<04317>>02290000
                                                               <<04317>>02292000
.(13:3)   Request type:                                        <<04317>>02294000
                                                               <<04317>>02296000
          0  = Unblocked, no wake on completion.  Impede if no <<04317>>02298000
              LIOQ element is available.                       <<04317>>02300000
                                                               <<04317>>02302000
          1  = Blocked.  Caller is  to be waited until request <<04317>>02304000
              is completed.                                    <<04317>>02306000
                                                               <<04317>>02308000
          2   =   Unblocked,   wake  caller  when  request  is <<04317>>02310000
              completed.  impede if no LIOQ available.         <<04317>>02312000
                                                               <<04317>>02314000
          3  =  Unblocked  and no process  is to be associated <<04317>>02316000
              with this request.  Impede if no LIOQ available. <<04317>>02318000
                                                               <<04317>>02320000
          4  =  Unblocked,  no  wake on completion  but do not <<04317>>02322000
              impede if no LIOQ available.                     <<04317>>02324000
                                                               <<04317>>02326000
          5 = Reserved.                                        <<04317>>02328000
                                                               <<04317>>02330000
          6  = Unblocked, wake on completion but do not impede <<04317>>02332000
              if no LIOQ is available.                         <<04317>>02334000
                                                               <<04317>>02336000
          7  =  Unblocked  and no process  is to be associated <<04317>>02338000
              with  this request but do  not impede if no LIOQ <<04317>>02340000
              available.                                       <<04317>>02342000
                                                               <<04317>>02344000
$PAGE                                                          <<04317>>02346000
     OUTPUT:                                                   <<04317>>02348000
                           Blocked                             <<04317>>02350000
                           -------                             <<04317>>02352000
                                                               <<04317>>02354000
        0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15         <<04317>>02356000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>02358000
 S-1  |    Zero execpt for    |  Qualifying  |General |        <<04317>>02360000
      |    DISC routines      |    Status    | Status |        <<04317>>02362000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>02364000
 S-0  |               Transmission Log                |        <<04317>>02366000
      |               /Control Returns                |        <<04317>>02368000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>02370000
                                                               <<04317>>02372000
                    Unblocked (IO system)                      <<04317>>02374000
                    ---------------------                      <<04317>>02376000
                                                               <<04317>>02378000
        0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15         <<04317>>02380000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>02382000
 S-1  | 0| 0| 0|         IOQ Index of request         |        <<04317>>02384000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>02386000
 S-0  |                       0                       |        <<04317>>02388000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>02390000
                                                               <<04317>>02392000
                     Unblocked (DISC IO)                       <<04317>>02394000
                     -------------------                       <<04317>>02396000
                                                               <<04317>>02398000
        0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15         <<04317>>02400000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>02402000
 S-1  | 1| 0| 0|      Disk Request Table Pointer      |        <<04317>>02404000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>02406000
 S-0  |                       0                       |        <<04317>>02408000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>02410000
                                                               <<04317>>02412000
                    Unblocked (CS devices)                     <<04317>>02414000
                    ----------------------                     <<04317>>02416000
                                                               <<04317>>02418000
        0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15         <<04317>>02420000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>02422000
 S-1  | 0| 1| 0|         ?????????????????????        |        <<04317>>02424000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>02426000
 S-0  |                       0                       |        <<04317>>02428000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>02430000
                                                               <<04317>>02432000
                    Unblocked (CIPER IO)                       <<04317>>02434000
                    --------------------                       <<04317>>02436000
                                                               <<04317>>02438000
Note  that  CIPER  logical IOQ is  included here for reference <<04317>>02440000
only.   The first implementation of CIPER does not include the <<04317>>02442000
use of LIOQ's.  The second release of CIPER will, however, use <<04317>>02444000
this structure.                                                <<04317>>02446000
        0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15         <<04317>>02448000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>02450000
 S-1  | 0| 0| 1|    Logical IOQ number of request     |        <<04317>>02452000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>02454000
 S-0  |                       0                       |        <<04317>>02456000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>02458000
                                                               <<04317>>02460000
$PAGE                                                          <<04317>>02462000
Discussion:                                                    <<04317>>02464000
                                                               <<04317>>02466000
  Control Returns:                                             <<04317>>02468000
                                                               <<04317>>02470000
  Disk Request Table Pointer:                                  <<04317>>02472000
                                                               <<04317>>02474000
  General Status:                                              <<04317>>02476000
                                                               <<04317>>02478000
  IOQ index of request:                                        <<04317>>02480000
                                                               <<04317>>02482000
  Logical IOQ Number of request:                               <<04317>>02484000
                                                               <<04317>>02486000
  PCB Number:                                                  <<04317>>02488000
                                                               <<04317>>02490000
  Qualifing Status:                                            <<04317>>02492000
                                                               <<04317>>02494000
  Transmission log:                                            <<04317>>02496000
     If CNT > 0 then CNT value is a word count.                <<04317>>02498000
                If CNT < 0 then CNT value is a byte count.     <<04317>>02500000
     This is the same as the CNT parameter of ATTACHIO.        <<04317>>02502000
                                                               <<04317>>02504000
The  IOQ index/number returned above  is used as the parameter <<04317>>02506000
to IOSTATUS to determine the completion status of the request. <<04317>>02508000
If  the  request type in FLAGS  specified that this request is <<04317>>02510000
not  impedable  then the IOQ index/LIOQ  number return will be <<04317>>02512000
zero if no IOQ/LIOQ elements are available.                    <<04317>>02514000
                                                               <<04317>>02516000
For type 3 requests, if ADDR is not zero then it is assumed to <<04317>>02518000
be a system buffer index.  At the completion of a request, the <<04317>>02520000
system  buffer(s) pointed to by ADDR  are returned to the free <<04317>>02522000
list by the I/O system.                                        <<04317>>02524000
                                                               <<04317>>02526000
The second part, P'ATTACHIO, consists of what is now the       <<04317>>02528000
bulk of ATTACHIO's code.  It will perform all the same         <<04317>>02530000
functions as the prior ATTACHIO which you all have come        <<04317>>02532000
to know and to ---------------.                                <<04317>>02534000
               Love                                            <<04317>>02536000
               Hate                                            <<04317>>02538000
               Care less about                                 <<04317>>02540000
               Huh?                                            <<04317>>02542000
                                                               <<04317>>02544000
;   <<END OF COMMENT>>                                         <<04317>>02546000
$PAGE                                                          <<04317>>02548000
<<Declaration of Variables>>                                   <<04317>>02550000
                                                               <<04317>>02552000
Equate                                                         <<04317>>02554000
  PRINTER'TYPE     = 32     <<First check for CIPER>>          <<04317>>02556000
 ,CIPER'09'SUBTYPE = 9      <<First check for CIPER subtype>>  <<04317>>02558000
 ,CIPER'13'SUBTYPE = 13     <<2nd check for CIPER subtype  >>  <<04317>>02560000
;                                                              <<04317>>02562000
                                                               <<04317>>02564000
<<Supported Serial Disc Types.  See ALLOCATE>>                 <<04317>>02566000
                                                               <<04317>>02568000
Equate                                                         <<04317>>02570000
  SIO'SDISC'TYP0   = 0      <<Series II/III types>>            <<04317>>02572000
 ,HPIB'SDISC'TYP2  = 2      <<Floppy on Series 30/33/44/64>>   <<04317>>02574000
 ,HPIB'SDISC'TYP3  = 3      <<7935 on Series 30/33/44/64>>     <<04317>>02576000
;                                                              <<04317>>02578000
                                                               <<04317>>02580000
<<Supported Serial Disc Subtypes.  See ALLOCATE>>              <<04317>>02582000
                                                               <<04317>>02584000
Equate                                                         <<04317>>02586000
  MH7920'7935      = 8    <<7920 Type 0 or 7935 type 3>>       <<04317>>02588000
 ,MH7905R          = 4    <<7905R Serial/removable only>>      <<04317>>02590000
 ,MH7906R          = 10   <<7906R Serial/removable only>>      <<04317>>02592000
 ,MH7925           = 9    <<7925 Serial Disc>>                 <<04317>>02594000
 ,MH7902'linus     = 0    <<7902 Type 2 dbl sided floppy>>     <<04317>>02596000
                          <<or 9140A type 3 Cartridge tape>>   <<04317>>02598000
;                                                              <<04317>>02600000
                                                               <<04317>>02602000
<<Definitions to access the LPDT entry specified by LDEV>>     <<04317>>02604000
                                                               <<04317>>02606000
Equate                                                         <<04317>>02608000
  LPDT'BASE        = %10                                       <<04317>>02610000
;                                                              <<04317>>02612000
                                                               <<04317>>02614000
Logical                                                        <<04317>>02616000
  LPDT'0                                                       <<04317>>02618000
 ,LPDT'1                                                       <<04317>>02620000
;                                                              <<04317>>02622000
                                                               <<04317>>02624000
Integer Pointer                                                <<04317>>02626000
  SYS'LPDTP        = LPDT'BASE                                 <<04317>>02628000
;                                                              <<04317>>02630000
                                                               <<04317>>02632000
Integer                                                        <<04317>>02634000
  DLTP                                                         <<04317>>02636000
;                                                              <<04317>>02638000
                                                               <<04317>>02640000
Define                                                         <<04317>>02642000
  DITP             = LPDT'0 #                                  <<04317>>02644000
 ,LPDT'FLAGS       = LPDT'1 #                                  <<04317>>02646000
 ,F'OR'S           = (11:1)#                                   <<04317>>02648000
 ,DEV'SUB'TYPE     = (12:4)#                                   <<04317>>02650000
 ,DEVICE'IS'DISC   = (0 <= DEV'TYPE <= 7)#                     <<04317>>02652000
;                                                              <<04500>>02654000
<< Disc type/subtypes that are supported as SERIAL DISC >>     <<04500>>02656000
equate MAX'SUPPORTED = 7;                                      <<04500>>02658000
integer array DEV'TYPE'ARR(0:MAX'SUPPORTED-1) = PB :=          <<04500>>02660000
                           0,  << 7920 >>                      <<04500>>02662000
                           0,  << 7925 >>                      <<04500>>02664000
                           3,  << 7933 >>                      <<04500>>02666000
                           2,  << 7902 >>                      <<04500>>02668000
                           0,  << 7905R>>                      <<04500>>02670000
                           0,  << 7906R>>                      <<04500>>02672000
                           3;  << LINUS>>                      <<04500>>02674000
integer array DEV'SUBTYPE'ARR(0:MAX'SUPPORTED-1) = PB :=       <<04500>>02676000
                           8,  << 7920 >>                      <<04500>>02678000
                           9,  << 7925 >>                      <<04500>>02680000
                           8,  << 7933 >>                      <<04500>>02682000
                           0,  << 7902 >>                      <<04500>>02684000
                           4,  << 7905R>>                      <<04500>>02686000
                           10, << 7906R>>                      <<04500>>02688000
                           0;  << LINUS>>                      <<04500>>02690000
                                                               <<04500>>02692000
                                                               <<04500>>02694000
                                                               <<04500>>02696000
                                                               <<04500>>02698000
                                                               <<04317>>02700000
<<Local/miscellaneous variables required>>                     <<04317>>02702000
                                                               <<04317>>02704000
Define                                                         <<04317>>02706000
  SPECIAL'SDISC'REQ     = (10:1)#                              <<04317>>02708000
;                                                              <<04317>>02710000
                                                               <<04317>>02712000
Integer                                                        <<04317>>02714000
  DEV'TYPE, SUBTYPE    << Device TYPE and SUBTYPE >>           <<04500>>02716000
;                                                              <<04317>>02718000
Double EXTBASE;                 << File system EXTENT base (sec<<04500>>02720000
Logical EXTSIZE;               << File system current EXTENT si<<04500>>02722000
double DQM17  = Q - 17;    << Loc file sys places EXTENT base ><<04500>>02724000
logical LQM15 = Q - 15;   << Loc file sys places EXTENT size >><<04500>>02726000
$PAGE                                                          <<04500>>02728000
<< This subroutine returns TRUE if this disc is SERIAL  >>     <<04500>>02730000
<< and to be processed by SDISCIO.                      >>     <<04500>>02732000
logical subroutine CHECK'IF'SDISC;                             <<04500>>02734000
begin                                                          <<04500>>02736000
                                                               <<04500>>02738000
<< See if device is in proper DEVREC state >>                  <<04500>>02740000
if LPDT'FLAGS.DRSTATE = 1 then                                 <<04500>>02742000
                                                               <<04500>>02744000
<< Make sure it is not in system domain >>                     <<04500>>02746000
if LPDT'FLAGS.F'OR'S = 0 then                                  <<04500>>02748000
                                                               <<04500>>02750000
<< check if it is a valid Type/Subtype >>                      <<04500>>02752000
  begin                                                        <<04500>>02754000
                                                               <<04500>>02756000
  X := -1;    << X is used to index through device arrays >>   <<04500>>02758000
  while (X:=X+1) < MAX'SUPPORTED do                            <<04500>>02760000
    if DEV'TYPE'ARR(X) = DEV'TYPE then                         <<04500>>02762000
      if DEV'SUBTYPE'ARR(X) = SUBTYPE then                     <<04500>>02764000
        begin                                                  <<04500>>02766000
        CHECK'IF'SDISC := true;                                <<04500>>02768000
        return;                                                <<04500>>02770000
        end;                                                   <<04500>>02772000
                                                               <<04500>>02774000
  end;                                                         <<04500>>02776000
                                                               <<04500>>02778000
CHECK'IF'SDISC := false;                                       <<04500>>02780000
end;  << of subroutine CHECK'IF'SDISC >>                       <<04500>>02782000
$PAGE "PROCEDURE: ATTACHIO"                                    <<04500>>02784000
                                                               <<04317>>02786000
                                                               <<04317>>02788000
<<Turn off internal traps.  Expand stack>>                     <<04317>>02790000
                                                               <<04317>>02792000
TRAPSOFF;                                                      <<04317>>02794000
                                                               <<04317>>02796000
ASMB(ADDS 255; SUBS 255);                                      <<04317>>02798000
                                                               <<04317>>02800000
<< Must have valid LDEV to continue.                        >> <<04317>>02802000
                                                               <<04317>>02804000
CHECKLDEV (LDEV);                                              <<04317>>02806000
IF < THEN SUDDENDEATH (206);                                   <<04317>>02808000
                                                               <<04317>>02810000
<<Get visiting LPDT entry for this LDEV>>                      <<04317>>02812000
                                                               <<04317>>02814000
                                                               <<04317>>02816000
<<The first word is DIT pointer.  Make it absolute>>           <<04317>>02818000
                                                               <<04317>>02820000
LPDT'0 := %1000 + (SYS'LPDTP(LDEV * LPDTSIZE));                <<04317>>02822000
                                                               <<04317>>02824000
LPDT'1 := SYS'LPDTP(X + 1);                                    <<04317>>02826000
                                                               <<04317>>02828000
                                                               <<04317>>02830000
<<Now, Get DLT pointer from DIT and make it absolute>>         <<04317>>02832000
                                                               <<04317>>02834000
DLTP := %1000 + ABS(DITP+4);                                   <<04317>>02836000
                                                               <<04317>>02838000
                                                               <<04317>>02840000
<<Finally, get the device type from the absolute DLT entry>>   <<04317>>02842000
                                                               <<04317>>02844000
DEV'TYPE := ABS(DLTP+5).(8:8);                                 <<04317>>02846000
SUBTYPE := integer(LPDT'FLAGS.DEV'SUB'TYPE);                   <<04500>>02848000
                                                               <<04317>>02850000
<<Check for CIPER device/sub-type. If CIPER, call LDVR>>       <<04317>>02852000
                                                               <<04317>>02854000
If DEV'TYPE = PRINTER'TYPE and                                 <<04317>>02856000
            ( SUBTYPE = CIPER'09'SUBTYPE or                    <<04500>>02858000
              SUBTYPE = CIPER'13'SUBTYPE )                     <<04500>>02860000
            then                                               <<04317>>02862000
                                                               <<04317>>02864000
  Begin <<Begin CIPER device processing>>                      <<04317>>02866000
                                                               <<04317>>02868000
  ATTACHIO := B08'LOGICAL'DVR(LDEV, QMISC, DSTX, ADDR, FNCT,   <<04317>>02870000
                              CNT, P1, P2, FLAGS);             <<04317>>02872000
  RETURN;                                                      <<04317>>02874000
                                                               <<04317>>02876000
  End;  <<CIPER device processing>>                            <<04317>>02878000
                                                               <<04317>>02880000
<<Check for serial disc>>                                      <<04317>>02882000
                                                               <<04317>>02884000
if ABS(DITP).TDFLAGS = 1 then  << DIT says it's a disc >>      <<04500>>02886000
  begin                                                        <<04500>>02888000
  if CHECK'IF'SDISC then                                       <<04500>>02890000
                                                               <<04317>>02892000
      <<serial disc access.  Check for special call>>          <<04317>>02894000
                                                               <<04317>>02896000
    If FLAGS.SPECIAL'SDISC'REQ = 0 Then                        <<04317>>02898000
                                                               <<04317>>02900000
      Begin   <<Not special.  Call SDISCIO>>                   <<04317>>02902000
                                                               <<04317>>02904000
      <<Note that we do not have to be concerned about where>> <<04317>>02906000
      <<the stack is at this point.  SDISCIO says that the  >> <<04317>>02908000
      <<stack can be anywhere on entry.  Lets hope so, since>> <<04317>>02910000
      <<at this point, we do not know or care where it is.  >> <<04317>>02912000
                                                               <<04317>>02914000
      ATTACHIO := SDISCIO(LDEV, QMISC, DSTX, ADDR, FNCT,       <<04317>>02916000
                          CNT, P1, P2, FLAGS);                 <<04317>>02918000
      RETURN;                                                  <<04317>>02920000
                                                               <<04317>>02922000
      End  <<End of Call SDISCIO>>                             <<04317>>02924000
                                                               <<04317>>02926000
    Else                                                       <<04317>>02928000
                                                               <<04317>>02930000
    FLAGS.SPECIAL'SDISC'REQ := 0;<<Special. Do physical I/O>>  <<04317>>02932000
  << If FILESYSTEM called ATTACHIO, as indicated by the >>     <<04500>>02934000
  << setting of FLAGS.(0:4) greater than 9, the EXTENT  >>     <<04500>>02936000
  << base and extent size will have been placed on the  >>     <<04500>>02938000
  << stack prior to the ATTACHIO double return value.   >>     <<04500>>02940000
  if FLAGS.(0:4) >= 8  then                                    <<04500>>02942000
    begin                                                      <<04500>>02944000
                                                               <<04317>>02946000
<<All other calls are normal I/O.  So, call P'ATTACHIO>>       <<04317>>02948000
                                                               <<04317>>02950000
    EXTBASE := DQM17; << Double EXTENT base sector # >>        <<04500>>02952000
    EXTSIZE := LQM15; << Logical EXTENT size in sectors >>     <<04500>>02954000
    end    << of processing TYPED disc I/O >>                  <<04500>>02956000
  else                                                         <<04500>>02958000
    begin  << Non-typed disc I/O >>                            <<04500>>02960000
    EXTBASE := 0D;                                             <<04500>>02962000
    EXTSIZE := 0;                                              <<04500>>02964000
    end;                                                       <<04500>>02966000
  end;  << of special DISC processing >>                       <<04500>>02968000
                                                               <<04500>>02970000
ATTACHIO := P'ATTACHIO(LDEV, QMISC, DSTX, ADDR, FNCT,          <<04500>>02972000
                       CNT, P1, P2, FLAGS, EXTBASE, EXTSIZE);  <<04500>>02974000
                                                               <<04317>>02976000
END;  <<ATTACHIO>>                                             <<04317>>02978000
$PAGE "PROCEDURE: IOSTATUS"                                    <<04317>>02980000
DOUBLE PROCEDURE IOSTATUS(IOQX);                                        02982000
  VALUE IOQX;  INTEGER IOQX;                                            02984000
  OPTION UNCALLABLE, PRIVILEGED;                                        02986000
  <<                                                                    02988000
     THIS PROCEDURE RETURNS THE STATUS & TRANSMISSION LOG/CONTROL       02990000
     RETURNS OF THE REQUEST IDENTIFIED BY IOQX. IN ADDITION,IOSTATUSX   02992000
     RETURNS THE CONTENTS OF QMISC IN THE X REGISTER.                   02994000
                                                                        02996000
                                                                        02998000
                                                                        03000000
     RETURN:  CCE - REQUEST COMPLETED                                   03002000
              CCG - REQUEST NOT COMPLETED                               03004000
  >>                                                                    03006000
  BEGIN                                                                 03008000
    ENTRY IOSTATUSX;                                                    03010000
                                                                        03012000
    INTEGER OLDXREG = Q-3;  << TO RETURN STATION IN X REQISTER >>       03014000
    LOGICAL XFLAG   = Q+1;  << SET IF ENTRY FROM IOSTATUSX >>           03016000
    INTEGER POINTER IOQP = Q + 6;                                       03018000
    INTEGER RETURNCC = Q + 3;   << CONDITION CODE TO BE RETURNED >>     03020000
                                                                        03022000
    TOS := 0;    << SET XFLAG OFF >>                                    03024000
    GOTO L1;                                                            03026000
                                                                        03028000
IOSTATUSX:                                                              03030000
    TOS := 1;    << SET XFLAG ON >>                                     03032000
                                                                        03034000
L1:                                                                     03036000
    TOS := RSTATUS;                                                     03038000
    ASMB(DZRO,INCB);    << FOR EXCHANGE DB AND SET CCL >>               03040000
    TOS := SYSDB;                                                       03042000
    PDISABLE;    XCHDB;      << SET SYSDB  >>                           03044000
                                                                        03046000
   TOS:=IOQX;                                                  <<MPEIV>>03048000
   ASMB(TRBC 1); <<SEE IF DISC REQ>>                           <<01685>>03050000
   IF <> THEN TOS:=TOS+ABSOLUTE(SYSDISCREQTAB)                 <<MPEIV>>03052000
   ELSE TOS:=TOS+@IOQ;                                         <<MPEIV>>03054000
                                                                        03056000
    IF LOGICAL(IOQP).COMPLETED THEN      << COMPLETED >>                03058000
      BEGIN                                                             03060000
      RETURNCC := RETURNCC+1;      << SET CCE RETURN >>                 03062000
      TOS := IOQP(QFUNC);     << RETURN LEFT BYTE OF QFUNC >>           03064000
      TOS.(8:8) := IOQP(QSTAT);     << STATUS RETURN >>                 03066000
      TOS := IOQP(QWBCT);                                               03068000
      IOSTATUS := TOS;                                                  03070000
      IF XFLAG THEN OLDXREG := IOQP(QMISC);  << HOWARD MADE ME >>       03072000
      RETURNIOQ(IOQP);                                                  03074000
      END                                                               03076000
    ELSE RETURNCC := RETURNCC-1;      << SET CCG RETURN >>              03078000
                                                                        03080000
    DEL;   << DELETE IOQP >>                                            03082000
    XCHDB;   PENABLE;   << RESTORE  DB  >>                              03084000
    DDEL;  << DELETE SYSDB >>                                           03086000
                                                                        03088000
    TOS.CC := TOS;    RSTATUS := TOS;                                   03090000
  END;      <<   I/O STATUS >>                                          03092000
                                                                        03094000
                                                                        03096000
                                                                        03098000
$PAGE "WAIT FOR I/O"                                           <<JB.19>>03100000
                                                                        03102000
DOUBLE PROCEDURE WAITFORIO(IOQX);                                       03104000
  VALUE IOQX;   INTEGER IOQX;                                           03106000
  OPTION PRIVILEGED,UNCALLABLE;                                         03108000
  <<                                                                    03110000
    THIS PROCEDURE CHECKS TO SEE IF THE I/O IS DONE. IF IT IS THE       03112000
    STATUS AND TRANSMISSION LOG ARE RETURNED.  IF IT IS NOT, THE        03114000
    CALLER IS WAITED UNTIL THE I/O IS DONE.  THE PCB NUMBER IN THE      03116000
    REQUEST IS SET TO THE PCB NUMBER OF THE CALLER AND THE WAKE BIT     03118000
    IS SET IN THE I/O REQUEST.  RETURN SAME AS ATTACHIO. WAITFORIOX     03120000
    ALSO RETURNS QMISC IN THE X REGISTER.                               03122000
                                                                        03124000
    CONDITION CODE RETURNS: CCE I/O DONE;  CCL INVALID IOQX             03126000
  >>                                                                    03128000
  BEGIN                                                                 03130000
    ENTRY WAITFORIOX;                                                   03132000
                                                                        03134000
    INTEGER ARRAY WAITTYPE(0:3) = PB :=  0,%100000,1,1;                 03136000
                                                                        03138000
    INTEGER POINTER IOQT = 5, LPDT = %10;                               03140000
LOGICAL XFLAG;                                                 <<MPEIV>>03142000
INTEGER REQINX,                                                <<MPEIV>>03144000
        WAITINGPIN,                                            <<MPEIV>>03146000
        DSTNUM;                                                <<MPEIV>>03148000
INTEGER POINTER ST=2;<<DST DECLARED DB REL UP FRONT>>          <<MPEIV>>03150000
    INTEGER OLDXREG = Q-3;  << TO RETURN QMISC IN WAITFORIOX >>         03152000
                                                                        03154000
XFLAG:=FALSE;                                                  <<MPEIV>>03156000
    GOTO L1;                                                            03158000
                                                                        03160000
WAITFORIOX:                                                             03162000
XFLAG:=TRUE;                                                   <<MPEIV>>03164000
                                                                        03166000
L1:                                                                     03168000
    DISABLE;                                                            03170000
    WAITFORIO := IOSTATUSX(IOQX);                                       03172000
    IF = THEN  << REQUEST COMPLETED >>                                  03174000
      BEGIN                                                             03176000
        IF XFLAG THEN OLDXREG := X;  << RETURN QMISC FOR WAITFORIOX >>  03178000
        TOS := CCE;                                                     03180000
        GOTO OUT;                                                       03182000
      END;                                                              03184000
                                                                        03186000
    IF > THEN  << NOT COMPLETED >>                                      03188000
      BEGIN                                                             03190000
      WAITINGPIN:=(ABS(CPCB)-ABS(PCBB))/PCBSIZE;               <<MPEIV>>03192000
        TOS:=IOQX;                                             <<MPEIV>>03194000
      ASMB(TRBC 1); <<SEE IF DISC REQ>>                        <<01685>>03196000
        X:=TOS;                                                <<MPEIV>>03198000
         IF IOQX.(1:1) <> 0 THEN  <<CHECK IF DISC REQ>>        <<01685>>03200000
           BEGIN                                               <<MPEIV>>03202000
           REQINX:=X;                                          <<MPEIV>>03204000
           DSTNUM:=DISCREQTAB(REQINX+QDSTN).DSTN;              <<MPEIV>>03206000
           IF ST(DSTNUM&LSL(2))<0 THEN                         <<MPEIV>>03208000
              BEGIN                                            <<MPEIV>>03210000
              QUEUEONSEGMENT(DSTNUM);                          <<MPEIV>>03212000
              GO TO L1;                                        <<MPEIV>>03214000
              END;                                             <<MPEIV>>03216000
           PDISABLE;                                           <<MPEIV>>03218000
           ST(DSTNUM&LSL(2)).REFERENCEDFLAG:=1;                <<MPEIV>>03220000
           DISCREQTAB(REQINX+QSTAT).PCBN:=WAITINGPIN;          <<MPEIV>>03222000
           IF DISCREQTAB(REQINX+QDSTN)>0 AND DSTNUM            <<MPEIV>>03224000
             <> ABSOLUTE(ABSOLUTE(CPCB)+DBXDSINFOWORDNUM).     <<MPEIV>>03226000
                XDSDSTFIELD THEN                               <<MPEIV>>03228000
              BEGIN <<WAIT ON A DATA SEG, NOT STACK OR DB SEG>><<MPEIV>>03230000
              TOS:=%1000D;ASMB(XCHD);                          <<MPEIV>>03232000
              TOS:=DSTNUM;                                     <<MPEIV>>03234000
              TOS:=ABSOLUTE(ABSOLUTE(CPCB)+SLLIXWORDNUM);      <<MPEIV>>03236000
              ASMB(XCH,ZERO);                                  <<MPEIV>>03238000
              TOS.SETDISCIOSEGFLAG:=1;                         <<MPEIV>>03240000
              ADDTOLOCALITY(*,*,*);                            <<MPEIV>>03242000
              ASMB(XCHD;DDEL);                                 <<MPEIV>>03244000
              END;                                             <<MPEIV>>03246000
           SETWAKE(IOQX);                                      <<MPEIV>>03248000
           ABSOLUTE(SYSWAITTODISPMSG).DISCWAITFLAG:=1;         <<MPEIV>>03250000
           TOS:=IOWAIT;                                        <<MPEIV>>03252000
           TOS:=0;                                             <<MPEIV>>03254000
           ASMB(TSBC SWBIT);                                   <<MPEIV>>03256000
           WAIT(*,*);                                          <<MPEIV>>03258000
           IF GCLASSENABLEDMASK.CLASS0 THEN                    <<MPEIV>>03260000
              BEGIN  <<MEASURE STOP ON UNBLOCKED DISC I/O>>    <<MPEIV>>03262000
              TOS:=MEASSTATXDSBANK;                            <<MPEIV>>03264000
              TOS:=MEASSTATXDSBASE;                            <<MPEIV>>03266000
              TOS:=TOS+C0SUB0'SEGRELOFF+C'STOPUNBLOCKDISC;     <<MPEIV>>03268000
              ASMB(LSEA);                                      <<MPEIV>>03270000
              TOS:=TOS+1;                                      <<MPEIV>>03272000
              ASMB(SSEA;DDEL);                                 <<MPEIV>>03274000
              END;                                             <<MPEIV>>03276000
           IF GCLASSENABLEDMASK.CLASS15 THEN                   <<01805>>03278000
              BEGIN <<PROCESS LEVEL UNBLOCKED DISC IO>>        <<01805>>03280000
              TOS:=MEASPROCXDSBANK;                            <<01805>>03282000
              TOS:=MEASPROCXDSBASE;                            <<01805>>03284000
              TOS:=TOS+WAITINGPIN*CLASS15'SUB0SIZE+            <<01805>>03286000
                   CP'STOPUNBLOCKDISC;                         <<01805>>03288000
              ASMB(LSEA);                                      <<01805>>03290000
              TOS:=TOS+1;                                      <<01805>>03292000
              ASMB(SSEA;DDEL);                                 <<01805>>03294000
              <<STUFF AWAY REASON STOPPED IN PCBX>>            <<01945>>03296000
              TOS:=ICS(-ICSSTKBANK);                           <<01945>>03298000
              TOS:=ICS(-ICSSTKBASE);                           <<01945>>03300000
              TOS:=TOS+PXGLOBSIZE+MEASSTOPREASON'IDX;          <<01945>>03302000
              TOS:=STOPDISCWAIT;                               <<01945>>03304000
              ASMB(SSEA;DDEL);                                 <<01945>>03306000
              END;                                             <<01945>>03308000
           END                                                 <<MPEIV>>03310000
        ELSE                                                   <<MPEIV>>03312000
           BEGIN <<NOT A DISC>>                                <<MPEIV>>03314000
           X:=X+QSTAT;                                         <<MPEIV>>03316000
      IOQT(X).PCBN:=WAITINGPIN;                                <<MPEIV>>03318000
        SETWAKE(IOQX);                                                  03320000
        X := LPDT(IOQT(X:=X-QLD'ST).(8:8)*2) + SYSDB;  << DIT ADDR >>   03322000
        WAIT(IOWAIT,WAITTYPE(ABS(X).TDFLAGS));                          03324000
           END;                                                <<MPEIV>>03326000
        GOTO L1;                                                        03328000
      END;                                                              03330000
                                                                        03332000
    TOS := CCL;   <<  REQUEST DOES NOT BELONG TO ANYONE >>              03334000
                                                                        03336000
OUT:                                                                    03338000
    RSTATUS.CC := TOS;    << SET RETURN CC >>                           03340000
  END;   << WAIT FOR IO >>                                              03342000
                                                               <<RH.PV>>03344000
                                                                        03346000
$PAGE "SIODM - SIO DEVICE MONITOR PROCEDURE"                            03348000
PROCEDURE SIODM(DITP,FLAGS);                                            03350000
VALUE DITP,FLAGS;                                                       03352000
INTEGER POINTER DITP;                                                   03354000
LOGICAL FLAGS;                                                          03356000
OPTION PRIVILEGED,UNCALLABLE;                                           03358000
BEGIN                                                                   03360000
<<                                                                      03362000
   STATE DISCRIPTION:                                                   03364000
        0 - START REQUEST                                               03366000
        1 - UNUSED                                                      03368000
        2 - CALL DRIVER INITIATOR                                       03370000
        3 - CALL DRIVER COMPLETOR                                       03372000
        4 - UNUSED                                                      03374000
        5 - COMPLETE REQUEST                                            03376000
        6 - UNEXPECTED INTERRUPT                                        03378000
        7 - START OPERATOR INTERVENTION WAIT                            03380000
      %10 - WAIT FOR OPERATOR INTERVENTION (RESTART AT STATE 0)         03382000
      %11 - WAIT FOR DATA MAKEPRESENT                                   03384000
      %12 - WAIT FOR INITIATOR CODE MAKEPRESENT (FREEZE)                03386000
      %13 - WAIT FOR I/O COMPLETION                                     03388000
      %14 - WAIT FOR DEVICE CONTROLLER                                  03390000
      %15 - WAITING FOR ATTN INTERRUPT FROM ANOTHER UNIT        RK0PV   03392000
      %16 - WAIT FOR INITIATOR MAKEPRESENT                              03394000
      %17 - WAIT FOR COMPLETOR MAKEPRESENT                              03396000
>>                                                                      03398000
DEFINE                                                         <<MPEIV>>03400000
   SEGF     = (8:8)#; << CST FIELD OF LABELS IN DLT >>                  03402000
DOUBLE ARRAY                                                            03404000
   DSTD(*)  = DST;                                                      03406000
DOUBLE                                                                  03408000
   DISCADR  = DB + %331;      << LAST DISC ERROR LDEV & ADRESS>>        03410000
INTEGER                                                                 03412000
   DISCERR  = DB + %330;      << LAST DISC ERROR STATUS >>              03414000
                                                                        03416000
<< THE FOLLOWING VARIABLES ARE INITIALIZED AS NEEDED >>                 03418000
                                                                        03420000
INTEGER                                                                 03422000
   PC       = Q+1;            << PREMPTIVE REQUEST COUNTER >>           03424000
INTEGER                                                                 03426000
   PL       = PC+1;           << HIGEST PREMPTIVE LEVEL >>              03428000
INTEGER                                                                 03430000
   CSTN     = PC;             << DRIVER SEGMENT NUMBER >>               03432000
POINTER                                                                 03434000
   THISP    = PL+1;           << CURRENT SCAN POINTER >>                03436000
POINTER                                                                 03438000
   LASTP    = THISP+1;        << LAST SCAN POINTER >>                   03440000
DOUBLE                                                                  03442000
   THESEPTRS= THISP;                                                    03444000
POINTER                                                                 03446000
   STP      = LASTP+1;        << CURRENT SAVE PTR >>                    03448000
POINTER                                                                 03450000
   SLP      = STP+1;          << LAST SAVE PTR >>                       03452000
DOUBLE                                                                  03454000
   SAVEPTRS = STP;                                                      03456000
LOGICAL XL  = X;              << LOGICAL X >>                  <<01496>>03458000
                                                                        03460000
<< THE FOLLOWING VARIABLES ARE INITIALIZED AT ENTRY >>                  03462000
                                                                        03464000
LOGICAL                                                                 03466000
   FRZFLAG  = SLP+1;          << INTERNAL INITIATOR FROZEN FLAG >>      03468000
INTEGER POINTER                                                         03470000
   DLTP     = FRZFLAG+1,      << DRIVER LINKAGE TABLE >>                03472000
   ILTP     = DLTP+1;         << INTERRUPT LINKAGE TABLE >>             03474000
INTEGER                                                                 03476000
   CONTROLLER = ILTP+1,       << CONTROLLER QUEUE NUMBER >>             03478000
   STATE    = CONTROLLER+1;   << CURRENT MONITOR STATE >>               03480000
INTEGER POINTER                                                         03482000
   IOQP     = STATE + 1;      << I/O REQUEST QUEUE POINTER >>           03484000
LOGICAL THISDEVPRI=IOQP+1;                                     <<MPEIV>>03486000
INTEGER DISCQLENGTH=THISDEVPRI+1;                             <<<MPEIV>>03488000
INTEGER POINTER HEADDIT=DISCQLENGTH+1,                         <<MPEIV>>03490000
                NEXTDIT=HEADDIT+1;                             <<MPEIV>>03492000
                                                               <<03686>>03494000
<< Variables for subroutine RECOGNIZE'DEVICE >>                <<03686>>03496000
integer S3'FLAG      = s-3,                                    <<03686>>03498000
        S2'TYPE      = s-2,                                    <<03686>>03500000
        S1'STYPE     = s-1,                                    <<03686>>03502000
        S0'LPDT1     = s-0;                                    <<03686>>03504000
                                                               <<03686>>03506000
LOGICAL POINTER                                                         03508000
   DITPL    = DITP,                                                     03510000
   DLTPL    = DLTP,                                                     03512000
   IOQPL    = IOQP;                                                     03514000
                                                                        03516000
DEFINE                                                         <<03031>>03518000
   TYPE     = DLTP(DSIZE).DEVTYPE#,                            <<03031>>03520000
   LPDT1    = LS0#;                                            <<03031>>03522000
                                                                        03524000
logical subroutine RECOGNIZE'DEVICE;                           <<03686>>03526000
begin                                                          <<03686>>03528000
                                                               <<03686>>03530000
<< This subroutine returns TRUE if the device can be AVR'd >>  <<03686>>03532000
<< Stack usage:                                            >>  <<03686>>03534000
<<              S-3   Flag stating if TRUE                 >>  <<03686>>03536000
<<              S-2   Device type                          >>  <<03686>>03538000
<<              S-1   Device subtype                       >>  <<03686>>03540000
<<              S-0   LPDT word 2                          >>  <<03686>>03542000
                                                               <<03686>>03544000
tos := 0;        << Flag is false initially >>                 <<03686>>03546000
tos := TYPE;     << Device type             >>                 <<03686>>03548000
tos := LPDTD(DITP(DLDEV).DLDEVN);                              <<03686>>03550000
S1'STYPE := S0'LPDT1.SUBTYPEF;                                 <<03686>>03552000
                                                               <<03686>>03554000
<< LPDT word 2 MUST be on TOS in this subroutine >>            <<03686>>03556000
if UNOWNED and JDACCPT then                                    <<03686>>03558000
  go to MAKE'TRUE                                              <<03686>>03560000
                                                               <<03686>>03562000
else                                                           <<03686>>03564000
                                                               <<03686>>03566000
if UNOWNED then                                                <<03686>>03568000
  if AVR then         << System Global Flag is on >>           <<03686>>03570000
    if S2'TYPE = 24 then  << This is a mag tape   >>           <<03686>>03572000
      go to MAKE'TRUE;                                         <<03686>>03574000
                                                               <<03686>>03576000
<< Only look at device types 0 through 3 >>                    <<03686>>03578000
if 0 <= S2'TYPE <= 3 then                                      <<03686>>03580000
  case *S2'TYPE of                                             <<03686>>03582000
    begin                                                      <<03686>>03584000
                                                               <<03686>>03586000
<<0>> begin   << 13037 disc family >>                          <<03686>>03588000
      if S0'LPDT1.NSDF = 1 then << This is not a sysdisc >>    <<03686>>03590000
        go to MAKE'TRUE;                                       <<03686>>03592000
      if S1'STYPE = 5 or    << 7905 Fixed >>                   <<03686>>03594000
         S1'STYPE = 11 then << 7906 Fixed >>                   <<03686>>03596000
        go to MAKE'TRUE;                                       <<03686>>03598000
      end;                                                     <<03686>>03600000
                                                               <<03686>>03602000
<<1>> ;                                                        <<03686>>03604000
                                                               <<03686>>03606000
<<2>> go to MAKE'TRUE;  << Floppy disc >>                      <<03686>>03608000
                                                               <<03686>>03610000
<<3>> begin    << CS'80 devices  >>                            <<03686>>03612000
      if S0'LPDT1.NSDF = 1 then                                <<03686>>03614000
        go to MAKE'TRUE;                                       <<03686>>03616000
      end;                                                     <<03686>>03618000
                                                               <<03686>>03620000
    end;    << Of case on device type >>                       <<03686>>03622000
                                                               <<03686>>03624000
<< At this point, the DEVICE does NOT qualify for AVR >>       <<03686>>03626000
go to MAKE'FALSE;                                              <<03686>>03628000
                                                               <<03686>>03630000
MAKE'TRUE:                                                     <<03686>>03632000
                                                               <<03686>>03634000
if UNOWNED or ALLOCATED then                                   <<03686>>03636000
  S3'FLAG := 1;                                                <<03686>>03638000
                                                               <<03686>>03640000
MAKE'FALSE:                                                    <<03686>>03642000
                                                               <<03686>>03644000
<< Remove 3 tos words >>                                       <<03686>>03646000
ASMB(DDEL,DEL);                                                <<03686>>03648000
                                                               <<03686>>03650000
if tos <> 0 then                                               <<03686>>03652000
  RECOGNIZE'DEVICE := true;                                    <<03686>>03654000
                                                               <<03686>>03656000
end;   << of subroutine RECOGNIZE'DEVICE >>                    <<03686>>03658000
                                                               <<03686>>03660000
   SUBROUTINE CHECKPOLL;                                       <<01496>>03662000
      BEGIN                                                    <<01496>>03664000
      DISABLE;                                                 <<01496>>03666000
      X := BUSY(CONTROLLER);                                   <<01496>>03668000
      IF <> AND WA0(X).STATEF = %15 THEN                       <<01496>>03670000
         BEGIN                                                 <<01496>>03672000
         WA0(X).STATEF := 5;                                   <<01496>>03674000
         WA0(X).IOPROG := 0;       << IT RAN POLL SIOPROG >>   <<01496>>03676000
         SIOCOUNT := SIOCOUNT - 1; << AND GOT NO INTERRUPT >>  <<01496>>03678000
         TOS := X;                                             <<01496>>03680000
         ENABLE;                                               <<01496>>03682000
         MMSTAT(191,@DITP,X,DITP);                             <<01496>>03684000
         TOS := ILTP;                                          <<01496>>03686000
         IF < THEN                                             <<01496>>03688000
            BEGIN                                              <<01496>>03690000
            TOS := X;                                          <<01496>>03692000
            CHKCHANNELQUE(*,*);                                <<01496>>03694000
            END                                                <<01496>>03696000
         ELSE DEL;                                             <<01496>>03698000
         AWAKEIO(*,0);                                         <<01496>>03700000
         END;                                                  <<01496>>03702000
      ENABLE;                                                  <<01496>>03704000
      END;                                                     <<01496>>03706000
                                                                        03708000
SUBROUTINE RELCONTROLLER;                                      <<01496>>03710000
BEGIN                                                          <<01496>>03712000
                                                               <<01496>>03714000
<< THIS ROUTINE RELEASES THE CONTROLLER RESOURCE >>            <<01496>>03716000
<< AND GIVES IT TO THE NEXT WAITER >>                          <<01496>>03718000
                                                               <<01496>>03720000
   DISABLE;                                                    <<01496>>03722000
   IF DITPL.MUNIT AND BUSY(CONTROLLER) = @DITP THEN            <<01496>>03724000
   BEGIN << I'VE GOT IT, GIVE IT BACK >>                       <<01496>>03726000
      BUSY(X) := 0;                                            <<01496>>03728000
      X := DEQUEUE(DLINK,X);                                   <<01496>>03730000
      IF > THEN                                                <<01496>>03732000
      BEGIN << SOMEONE IS WAITING, GIVE THEM CONTROLLER >>     <<01496>>03734000
         ASMB(LDXA,DUP);                                       <<JB.19>>03736000
         BUSY(CONTROLLER) := TOS; << SET RESOURCE BUSY >>      <<01496>>03738000
         ENABLE;                                               <<01496>>03740000
      IF BUSY(X) = @DITP THEN ASMB(DEL) ELSE AWAKEIO(*,0);     <<JB.19>>03742000
      END;                                                     <<01496>>03744000
   END;                                                        <<01496>>03746000
   ENABLE;                                                     <<01496>>03748000
END;                                                           <<01496>>03750000
                                                               <<01496>>03752000
                                                               <<01496>>03754000
                                                               <<01496>>03756000
SUBROUTINE UNFREEZEDATASEG;                                    <<01496>>03758000
BEGIN                                                          <<01496>>03760000
                                                               <<01496>>03762000
<< THIS ROUTINE UNFREEZES THE CALLER'S DATA SEGMENT >>         <<01496>>03764000
                                                               <<01496>>03766000
   IOQP.DATAFRZN := 0;                                         <<01496>>03768000
   IF <> THEN   IF NOT (IOQPL.SYSBUFR) THEN                    <<04477>>03770000
   BEGIN << SEG IS FROZEN, UNFREEZE IT >>                      <<01496>>03772000
      IOUNFREEZE'(IOQP(QDSTN).DSTN);                           <<MPEIV>>03774000
      IF < THEN SUDDENDEATH(299);                              <<01496>>03776000
   END;                                                        <<01496>>03778000
END;                                                           <<01496>>03780000
                                                                        03782000
<< Log SIODM events in MMSTAT table >>                         <<03660>>03784000
subroutine LOG'MMSTAT(EVENT);                                  <<03660>>03786000
value EVENT;                                                   <<03660>>03788000
integer EVENT;                                                 <<03660>>03790000
begin                                                          <<03660>>03792000
                                                               <<03660>>03794000
tos := EVENT;    << Event number for MMSTAT >>                 <<03660>>03796000
tos := @IOQP;                                                  <<03660>>03798000
if <> then       << If there is an IOQP     >>                 <<03660>>03800000
  if DITP.(0:2) = DISC' then                                   <<03660>>03802000
    tos := tos - DISCREQTABSYSBASEINX                          <<03660>>03804000
  else                                                         <<03660>>03806000
    tos := tos - @IOQ;                                         <<03660>>03808000
tos.(0:7) := DITP(DLDEV).DLDEVN;  << Overlay with LDEV >>      <<03660>>03810000
tos := DITP;     << DIT pointer on tos >>                      <<03660>>03812000
tos.STATEF := STATE;  << Exit state >>                         <<03660>>03814000
tos := TIMER;  ASMB(delb);  << Timer LSW >>                    <<03660>>03816000
tos.(0:4) := DITP.STATEF;   << Entry state >>                  <<03660>>03818000
MMSTAT(*,*,*,*);                                               <<03660>>03820000
                                                               <<03660>>03822000
end;   << of subroutine LOG'MMSTAT >>                          <<03660>>03824000
                                                                        03826000
$PAGE "SIODM - PROCEDURE MAINLINE"                             <<03660>>03828000
   ASSEMBLE(ADDS 6); << SET UP LOCAL VARIABLES >>                       03830000
   TOS := 0;                                                            03832000
   TOS := DITP(DDLTP);                                                  03834000
   TOS := DITP(DILTP);                                                  03836000
   TOS := ILTP(IQUEUE).CQUEN;                                           03838000
   DISABLE;                                                             03840000
   TOS := DITP.STATEF;                                                  03842000
   TOS := DITP(DIOQP);                                                  03844000
   ASMB(ADDS 4); <<REST OF LOCAL VARIABLES>>                   <<MPEIV>>03846000
                                                               <<03660>>03848000
  << Log SIODM entry in MMSTAT table >>                        <<03660>>03850000
  LOG'MMSTAT(194);   << %302=Event number >>                   <<03660>>03852000
                                                               <<03660>>03854000
   PDISABLE;                                                   <<01496>>03856000
                                                               <<01496>>03858000
AGAIN:                                                                  03860000
   TOS := DITP;                                                         03862000
   TOS.ACTIVE := 1; << SET THIS DIT ACTIVE AND WORK ON REQUEST >>       03864000
   IF <> THEN                                                           03866000
   BEGIN << ALREADY ACTIVE, SET REQUEST AND EXIT >>                     03868000
      TOS.REQUEST := 1;                                                 03870000
      DITP := TOS;                                                      03872000
      PENABLE;                                                 <<01496>>03874000
      RETURN;                                                           03876000
   END;                                                                 03878000
   TOS.REQUEST := 0;                                           <<01496>>03880000
   DITP := TOS;                                                         03882000
   ENABLE;                                                     <<01496>>03884000
STAY:                                                                   03886000
   X := STATE;                                                          03888000
ASMB(LOAD SWT,X; ADAX; BR SWT,X; << FAST SWITCH >>                      03890000
SWT:                                                                    03892000
CON STATE0;  CON STATE1;  CON STATE2;  CON STATE3;                      03894000
CON STATE4;  CON STATE5;  CON STATE6;  CON STATE7;                      03896000
CON STATE10; CON STATE11; CON STATE12; CON STATE13;                     03898000
CON STATE14; CON STATE15; CON STATE16; CON STATE17);                    03900000
<<>>                                                                    03902000
   HELP;                                                                03904000
<<>>                                                                    03906000
STATE0:                                                                 03908000
   @IOQP := DITP(DIOQP);                                                03910000
      IF DITPL.SIOPREMPT AND DITP.(0:2)<>DISC' THEN            <<MPEIV>>03912000
   BEGIN << SERVICE PREMTIVE REQUEST >>                                 03914000
      PC := 0;                                                          03916000
      PL := 0;                                                          03918000
      @THISP := @IOQP;                                                  03920000
      WHILE <> DO                                                       03922000
      BEGIN << SEARCH IOQ LIST FOR HIGHEST PREMPTION >>                 03924000
         TOS := THISP.PREMPTFLD; << GET PREMPTION FIELD FROM IOQ >>     03926000
         IF <> THEN PC := PC + 1; << FOUND ONE, INCREMENT COUNT >>      03928000
         IF TOS > PL THEN                                               03930000
         BEGIN << FOUND HIGHER PREMPT CODE, REMEMBER THIS ONE >>        03932000
            PL := THISP.PREMPTFLD;                                      03934000
            SAVEPTRS := THESEPTRS;                                      03936000
         END;                                                           03938000
         @LASTP := @THISP;                                              03940000
         @THISP := THISP(QLINK);                                        03942000
      END;                                                              03944000
      DISABLE;                                                 <<01496>>03946000
      IF PC <= 1 THEN DITP.SIOPREMPT := 0;                              03948000
      IF PC > 0 AND @IOQP <> @STP THEN                                  03950000
      BEGIN << REORDER REQUESTS, BRING PREMPTIVE REQUEST TO HEAD >>     03952000
         SLP(QLINK) := STP(QLINK); << DELINK REQUEST FROM CUR POS >>    03954000
         STP(QLINK) := @IOQP;  << ADD REQUEST TO FRONT OF LIST >>       03956000
         DITP(DIOQP) := @STP;                                           03958000
         @IOQP := @STP;                                                 03960000
      END;                                                              03962000
      ENABLE;                                                  <<01496>>03964000
   END;                                                                 03966000
   IF @IOQP = 0 THEN                                           <<01496>>03968000
   BEGIN << CHECK FOR WAIT START >>                            <<01496>>03970000
CHECKWAIT:                                                     <<01496>>03972000
      X := ILTP(IFLAG);                                        <<01496>>03974000
      IF < AND NOT LOGICAL(X).WAITPROG THEN                             03976000
      BEGIN << WAIT PROG IS NOT RUNNING >>                     <<01496>>03980000
         DISABLE;                                              <<01496>>03982000
         TOS := DITP;                                          <<01496>>03984000
         TOS.STWAIT := 1;                                      <<01496>>03986000
         IF STATE = %10 THEN TOS.NOTRDY := 1;                  <<01496>>03988000
         <<REMEMBER STATE %10>>                                <<01496>>03990000
         DITP := TOS;                                          <<01496>>03992000
         ENABLE;                                               <<01496>>03994000
         GO TO STATE2;                                         <<01496>>03996000
      END;                                                     <<01496>>03998000
IF @IOQP=0 THEN IF NOT DITPL.MUNIT OR BUSY(CONTROLLER)<>@DITP  <<MPEIV>>04000000
THEN GO TO OUT ELSE GO TO CONT7;                               <<MPEIV>>04002000
      GO OUT;                                                  <<01496>>04004000
   END;                                                        <<01496>>04006000
 IF IOQPL.SYSBUFR THEN IOQP.DATAFRZN := 1;    << ITS FROZEN >> <<04477>>04008000
   IF NOT IOQPL.SYSBUFR AND NOT(IOQP(QWBCT)=0)                 <<01782>>04010000
   AND IOQP.DATAFRZN=0 THEN                                    <<01782>>04012000
     BEGIN                                                     <<MPEIV>>04014000
     IF DITP.(0:2)<>DISC' OR NOT IOQPL.SPEC THEN               <<MPEIV>>04016000
        BEGIN <<FREEZE THE DATA SEGMENT>>                      <<MPEIV>>04018000
         DISABLE;                                              <<01911>>04020000
        IOFREEZE'(IOQP(QDSTN).DSTN);                           <<MPEIV>>04022000
        IF = THEN IOQP.DATAFRZN:=1 ELSE                        <<MPEIV>>04024000
           BEGIN <<SEND MSG TO SCHEDULER AND RETURN>>          <<MPEIV>>04026000
           IF DITP.(0:2)=DISC' THEN                            <<MPEIV>>04028000
              BEGIN <<TOSS THIS REQUEST>>                      <<MPEIV>>04030000
              MMSTAT(%125,@IOQP,IOQP(QDSTN).DSTN,0);           <<01782>>04032000
              IF GCLASSENABLEDMASK.CLASS0 THEN                 <<MPEIV>>04034000
                 BEGIN  <<MEASURE DISC BUFFER TRAP>>           <<MPEIV>>04036000
                 TOS:=MEASSTATXDSBANK;                         <<MPEIV>>04038000
                 TOS:=MEASSTATXDSBASE;                         <<MPEIV>>04040000
                 TOS:=TOS+DITPL(DLDEV).(8:8);                  <<MPEIV>>04042000
                 ASMB(LSEA); <<SEG REL OFFSET OF ITEM 0>>      <<MPEIV>>04044000
                 TOS:=TOS-DITPL(DLDEV).(8:8);<<SUB IDX TO TBL>><<MPEIV>>04046000
                 TOS:=TOS+C'BUFFERTRAP;                        <<MPEIV>>04048000
                 ASMB(LADD;LSEA;INCA;SSEA;DDEL);               <<MPEIV>>04050000
                 END;                                          <<MPEIV>>04052000
              X:=@IOQP;                                        <<MPEIV>>04054000
              TOS:=DISCREQFLAGS;                               <<MPEIV>>04056000
              TOS.DISABLEDREQFLAG:=1;                          <<MPEIV>>04058000
              TOS.DITSCURRREQFLAG:=0;                          <<MPEIV>>04060000
              TOS.REQQUEUEDFLAG:=0;                            <<MPEIV>>04062000
              DISCREQFLAGS:=TOS;                               <<MPEIV>>04064000
                                                               <<MPEIV>>04066000
              IF LOGICAL(DISCREQFLAGS).IOWAKE THEN             <<MPEIV>>04068000
                 BEGIN <<MUST MARK REQ PROCESS ABSENT>>        <<MPEIV>>04070000
                 TOS:=(DISCREQSTAT.PCBN)*PCBSIZE;              <<MPEIV>>04072000
               IF = THEN SUDDENDEATH(662); <<NO PCB?>>         <<01640>>04074000
                 TOS:=TOS+PCBSYSBASEINX;                       <<MPEIV>>04076000
                 TOS:=IOQP(QDSTN).DSTN;                        <<MPEIV>>04078000
                 FLAGPROCABSENT(*,*);                          <<MPEIV>>04080000
                 END;                                          <<MPEIV>>04082000
              DITP(DIOQP):=0;                                  <<MPEIV>>04084000
              X:=DISCREQTABSYSBASEINX;                         <<MPEIV>>04086000
              TOS:=DITQTAILP;                                 <<<MPEIV>>04088000
              IF = THEN                                        <<MPEIV>>04090000
                 BEGIN  <<PENDING Q IS EMPTY>>                 <<MPEIV>>04092000
                 ASMB(DEL);                                    <<MPEIV>>04094000
                 DITQHEADP:=DITQTAILP:=@IOQP;            <<JB.I<<MPEIV>>04096000
                 END                                           <<MPEIV>>04098000
              ELSE                                             <<MPEIV>>04100000
                 BEGIN  <<QUEUE AT TAIL OF PNDG REQ Q>>        <<MPEIV>>04102000
                 DITQTAILP:=@IOQP;                            <<<MPEIV>>04104000
                 X:=S0;                                        <<MPEIV>>04106000
                 NEXTREQP:=@IOQP;                              <<MPEIV>>04108000
                 X:=@IOQP;                                     <<MPEIV>>04110000
                 PREVREQP:=TOS;                                <<MPEIV>>04112000
                 END;                                          <<MPEIV>>04114000
              STATE:=0;                                        <<MPEIV>>04116000
              GO TO CONT7; <<GET NEXT REQUEST>>                <<MPEIV>>04118000
            END                                                <<MPEIV>>04120000
         ELSE                                                  <<MPEIV>>04122000
      BEGIN                                                    <<MPEIV>>04124000
      FETCHIOSEG(IOQP(QDSTN).DSTN,DITP(DLDEV).DLDEVN,@IOQP,    <<01772>>04126000
         %100000); <<ASK FOR BUFFER TO BE FETCHED AND FROZEN>> <<01772>>04128000
      IF = THEN SUDDENDEATH(29);                               <<04302>>04130000
           <<WAIT FOR DATA SEGMENT MAKE PRESENT>>              <<MPEIV>>04132000
            TOS := %11;                                                 04134000
OUTTOS:                                                                 04136000
            STATE := TOS;                                               04138000
STATE1:                                                                 04140000
STATE4:                                                                 04142000
OUT:                                                                    04144000
            DISABLE;                                                    04146000
                                                               <<01782>>04148000
            <<MAKE AN MMSTAT RECORD OF LEAVING SIODM>>         <<01782>>04150000
            LOG'MMSTAT(195);  << %303=Event number >>          <<03660>>04152000
            TOS := DITP;                                                04156000
            TOS.STATEF := STATE; << INSERT NEW STATE FIELD >>           04158000
            TOS.ACTIVE := 0;                                            04160000
            TOS.REQUEST := 0;                                           04162000
            DITP := TOS;                                                04164000
            IF <> THEN GO TO AGAIN; << ANOTHER REQUEST PENDING >>       04166000
            PENABLE;                                           <<01496>>04168000
            END;                                               <<MPEIV>>04170000
            RETURN;                                                     04172000
         END;                                                           04174000
         IOQP.DATAFRZN := 1;                                   <<01496>>04176000
      END;                                                              04178000
   END;                                                                 04180000
<<>>                                                                    04182000
STATE2:                                                                 04184000
   STATE := 2;                                                          04186000
   IF NOT DITPL.MUNIT THEN GO TO CONT3;                                 04188000
   IF NOT DLTPL.CORERES THEN                                            04190000
      BEGIN << NOT CORE RESIDENT, SO FREEZE DRIVER >>          <<MPEIV>>04192000
      CSTN := DLTP(DINIT).SEGF; FRZFLAG:=TRUE;                 <<MPEIV>>04194000
      TOS:=CSTN;                                               <<MPEIV>>04196000
      TOS.SEGIDTYPEFIELD:=SEGIDSLTYPE;                         <<MPEIV>>04198000
      FETCHIOSEG(*,DITP(DLDEV).DLDEVN,@IOQP,%100000);<<I/O FZ>><<01772>>04200000
      IF = THEN DLTP.DVRFRZN:=1 <<ALL OK>> ELSE                <<01772>>04202000
         BEGIN <<COME BACK WHEN SEG SHOWS UP>>                 <<01772>>04204000
         TOS := %12;                                           <<MPEIV>>04206000
         GO TO OUTTOS;                                         <<MPEIV>>04208000
         END;                                                  <<MPEIV>>04210000
      END;                                                     <<MPEIV>>04212000
CONT12:                                                                 04214000
   DISABLE;                                                             04216000
   IF BUSY(CONTROLLER) <> 0 AND BUSY(X) <> @DITP THEN                   04218000
   BEGIN << DEVICE CONTROLLER BUSY, QUE REQUEST >>                      04220000
      IF DITPL.STWAIT THEN                                     <<01496>>04222000
      BEGIN << SOMEONE HAS RESOURCE, DON'T START WAIT >>       <<01496>>04224000
         IF NOT DLTPL.CORERES THEN FRZFLAG := TRUE;            <<01496>>04226000
         TOS := 5; << RETURN STATE >>                          <<01496>>04228000
         GO TO RETURNDVR; << COMPLETE REQ W/O CALLING DVR >>   <<01496>>04230000
      END;                                                     <<01496>>04232000
      IF GCLASSENABLEDMASK.CLASS0  THEN                        <<MPEIV>>04234000
         BEGIN  <<MEAS BUSY CONTROLLER EVENT>>                 <<MPEIV>>04236000
         TOS:=MEASSTATXDSBANK;                                 <<MPEIV>>04238000
         TOS:=MEASSTATXDSBASE;                                 <<MPEIV>>04240000
         TOS:=TOS+DITPL(DLDEV).(8:8);                          <<MPEIV>>04242000
         ASMB(LSEA); <<ENTRY OF LDEVTAB IN MEASXDS>>           <<MPEIV>>04244000
         TOS:=TOS-DITPL(DLDEV).(8:8); <<SUB LDEV IDX TO SEG>>  <<MPEIV>>04246000
         TOS:=TOS+C'BUSYCONTROLLER;                            <<MPEIV>>04248000
         ASMB(LADD;LSEA;INCA;SSEA;DDEL);                       <<MPEIV>>04250000
         END;                                                  <<MPEIV>>04252000
      ADDTAIL(DITP,DLINK,CONTROLLER);  << QUEUE ON CONTROLLER >>        04254000
      TOS := %14;                                                       04256000
      GO TO OUTTOS;                                                     04258000
   END;                                                                 04260000
CONT14:                                                                 04262000
   BUSY(X) := @DITP; << SET CONTROLLER BUSY >>                          04264000
   ENABLE;                                                              04266000
   IF NOT DLTPL.CORERES THEN FRZFLAG := TRUE; <<INITIATOR CODE IS FRZN>>04268000
   STATE := 2;                                                          04270000
   GO TO CALLDVR;                                                       04272000
<<>>                                                                    04274000
STATE3: << STATE 3 AND NON-MULTIUNIT STATE 2 >>                         04276000
   STATE := 3;                                                          04278000
CONT3:                                                                  04280000
   IF NOT DLTPL.CORERES THEN                                   <<MPEIV>>04282000
      BEGIN << DRIVER NOT CORE RES., SO CHECK FOR ABSENCE >>   <<MPEIV>>04284000
      CSTN := DLTP(STATE).SEGF; << GET PCAL LABEL>>            <<MPEIV>>04286000
      IF ABSOLUTE(ABSOLUTE(0)+CSTN&LSL(2))<0 THEN              <<MPEIV>>04288000
         BEGIN <<NOT FROZEN>>                                  <<MPEIV>>04290000
         TOS:=CSTN;                                            <<MPEIV>>04292000
         TOS.SEGIDTYPEFIELD:=SEGIDSLTYPE;                      <<MPEIV>>04294000
         FETCHIOSEG(*,DITP(DLDEV).DLDEVN,@IOQP,0); <<REQ SEG>> <<01772>>04296000
         IF = THEN SUDDENDEATH(29);                            <<04302>>04298000
         TOS:=STATE+%14;                                       <<MPEIV>>04300000
         GO TO OUTTOS;                                         <<MPEIV>>04302000
         END;                                                  <<MPEIV>>04304000
      END;                                                     <<MPEIV>>04306000
CALLDVR:                                                                04308000
   IF ABS(SYSMON) AND STATE = 2 THEN                           <<01496>>04310000
   BEGIN << I/O START MMSTAT CALL >>                           <<01496>>04312000
      TOS := -110;                                             <<01496>>04314000
      TOS := IOQPL(QSTAT) LOR IOQPL(QLDEV).LDEVN;              <<01496>>04316000
      TOS := IOQP(QWBCT);                                      <<01496>>04318000
      TOS := IOQP(QFUNC).FUNC;                                 <<01496>>04320000
      IF S0 > 2 THEN                                           <<01496>>04322000
      BEGIN                                                    <<01496>>04324000
         DEL;                                                  <<01496>>04326000
         TOS := 2;                                             <<01496>>04328000
      END;                                                     <<01496>>04330000
      TOS := TOS&LSL(14) LOR IOQPL(QDSTN).DSTN;                <<01496>>04332000
      MMSTAT(*,*,*,*);                                         <<01496>>04334000
   END;                                                        <<01496>>04336000
   TOS := STATE; << MONITOR STATE FOR DRIVER >>                         04338000
   IF DITPL.STWAIT THEN                                        <<01496>>04340000
   BEGIN << START WAIT PROG, NO IOQ >>                         <<01496>>04342000
      TOS := 0; << IOQP >>                                     <<01496>>04344000
      TOS := @DITP;  << DIT POINTER >>                         <<01496>>04346000
      TOS := 0D; << BUFFER ADRESS >>                           <<01496>>04348000
   END ELSE                                                    <<01496>>04350000
   BEGIN << NORMAL PROG START >>                               <<01496>>04352000
                                                               <<01496>>04354000
   TOS := @IOQP; << VALUE >>                                   <<01496>>04356000
      TOS := @DITP;  << DIT POINTER >>                         <<01496>>04358000
   TOS := IOQP(QDSTN).DSTN;                                    <<01496>>04360000
   IF      (IOQP(QWBCT)=0)            << INCLHARD C #3 >>      <<04477>>04362000
    OR (IOQP.DATAFRZN=0) OR IOQPL.SPEC THEN TOS:=0  ELSE       <<04351>>04364000
   BEGIN      << FIND DB OFFSET IN SEGMENT >>                  <<04351>>04366000
      TOS := DSTD(TOS&LSL(1)+1); << ABS DST ADR >>             <<01496>>04368000
      IF IOQP(QDSTN) < 0 THEN << STACK, ADD DB OFFSET >>       <<01496>>04370000
     ASMB(LDI 1; LADD; LSEA; LADD; LDI 1; LSUB); <<ABS BUFADR>><<01496>>04372000
   END;                                                        <<01496>>04374000
   TOS := TOS + LOGICAL(IOQP(QADDR)); << ADD DST/BANK OFFSET >><<02074>>04376000
   IF IOQP(QFUNC).FUNC = 0 THEN                                         04378000
   BEGIN << CHECK FOR BANK WRAP-AROUND ON READS >>                      04380000
      ASMB(DUP,DUP); << CHECK FOR BANK WRAP - AROUND >>                 04382000
      TOS := IOQP(QWBCT);                                               04384000
      IF < THEN TOS := -(TOS&ASR(1)); << POS. XFER COUNT >>             04386000
      ASMB(LADD,LCMP); << (S-1) > (S) MEANS WRAP-AROUND >>              04388000
      IF > THEN SUDDENDEATH(260);                                       04390000
   END;                                                                 04392000
                                                               <<01496>>04394000
   END;                                                        <<01496>>04396000
   TOS := ILTP(ISIOP); << SIO PROG AREA PTR >>                          04398000
   TOS := ILTP(ICNTRL).(7:9);  << GET DRT # OUT OF ILT >>      <<03014>>04400000
   TOS := DLTP(STATE); << PCAL LABEL >>                                 04402000
   ASSEMBLE(PCAL 0);                                                    04404000
   IF DITP(DSERR) <> 0 THEN                                    <<02801>>04406000
   BEGIN << LOG I/O ERROR >>                                   <<02801>>04408000
      LOGERROR(DITP,IOQP,DITP(X));                             <<02801>>04410000
      IF DITPL.DISC AND IOQP(QSTAT).STATUS <> 1 THEN           <<02801>>04412000
      BEGIN << DISC REQUEST FAILED, ENTER INFO IN SYSDB >>     <<02801>>04414000
         DISCERR := DITP(DITP(DSERR).(8:8));                   <<02801>>04416000
         TOS := DITPL(DLDEV)&LSL(8) LOR IOQPL(QPAR1);          <<02801>>04418000
         TOS := IOQP(QPAR2);                                   <<02801>>04420000
         DISCADR := TOS;                                       <<02801>>04422000
      END;                                                     <<02801>>04424000
      DITP(DSERR) := 0;                                        <<02801>>04426000
   END;                                                        <<02801>>04428000
RETURNDVR:                                                     <<01496>>04430000
   STATE := TOS; << SAVE DRIVER RETURN STATE >>                         04432000
   IF FRZFLAG THEN                                             <<MPEIV>>04434000
      BEGIN << UNFREEZE INIATIOR IF NEEDED >>                  <<MPEIV>>04436000
      FRZFLAG := FALSE;                                        <<MPEIV>>04438000
      TOS:=DLTP(DINIT).SEGF;                                   <<MPEIV>>04440000
      TOS.SEGIDTYPEFIELD:=SEGIDSLTYPE;                         <<MPEIV>>04442000
      IOUNFREEZE'(*);                                          <<MPEIV>>04444000
      IF < THEN SUDDENDEATH(299);                              <<MPEIV>>04446000
      IF = THEN DLTP.DVRFRZN := 0;                             <<MPEIV>>04448000
      END;                                                     <<MPEIV>>04450000
   GO TO STAY;                                                          04452000
<<>>                                                                    04454000
MAMERR:                                                                 04456000
   IF NOT DITPL.STWAIT THEN << LOG ERROR IN IOQ >>             <<01496>>04458000
   IOQP(QSTAT).IOSTAT := %124; << IRRECOVERABLE SYS ERROR >>            04460000
<<>>                                                                    04462000
STATE5:                                                                 04464000
   DISABLE;                                                    <<01496>>04466000
   DITP.STWAIT := 0;                                           <<01496>>04468000
   IF <> THEN                                                  <<01496>>04470000
   BEGIN << WAIT PROG STARTED, FINISH HERE >>                  <<01496>>04472000
      DITP.NOTRDY := 0;                                        <<01496>>04474000
      IF <> THEN TOS := %10 ELSE TOS := 0; <<RECOVER STATE>>   <<01496>>04476000
      RELCONTROLLER;                                           <<01496>>04478000
      GO TO OUTTOS;                                            <<01496>>04480000
   END;                                                        <<01496>>04482000
   ENABLE;                                                     <<01496>>04484000
   IF ABS(SYSMON) THEN                                         <<01496>>04486000
   BEGIN << LOG I/O COMPLETION >>                              <<01496>>04488000
      TOS := -111;                                             <<01496>>04490000
      TOS := IOQP(QLDEV).LDEVN;                                <<01496>>04492000
      IF DITPL.DISC THEN                                       <<01496>>04494000
      BEGIN                                                    <<01496>>04496000
         TOS := IOQP(QPAR1);                                   <<01496>>04498000
         TOS := IOQP(QPAR2);                                   <<01496>>04500000
      END ELSE TOS := 0D;                                      <<01496>>04502000
      MMSTAT(*,*,*,*);                                         <<01496>>04504000
   END;                                                        <<01496>>04506000
IF GCLASSENABLEDMASK.CLASS0 THEN                               <<MPEIV>>04508000
   BEGIN  <<MEASUREMENT ENABLED>>                              <<MPEIV>>04510000
   TOS:=MEASSTATXDSBANK;                                       <<MPEIV>>04512000
   TOS:=MEASSTATXDSBASE;                                       <<MPEIV>>04514000
   IF DITP.(0:2)=DISC' THEN                                    <<MPEIV>>04516000
      BEGIN <<UPDATE DISC COUNTER>>                            <<MPEIV>>04518000
      TOS:=TOS+DITPL(DLDEV).(8:8);                             <<MPEIV>>04520000
      ASMB(LSEA); <<TOS HAS SEG REL OFFSET OF ITEM 0>>         <<MPEIV>>04522000
      TOS:=TOS-DITPL(DLDEV).(8:8); <<SUB LDEV IDX TO SEG>>     <<MPEIV>>04524000
      IF IOQPL.SPEC THEN                                       <<MPEIV>>04526000
         BEGIN <<SEGMENT TRANSFER>>                            <<MPEIV>>04528000
         IF NOT IOQPL(QFUNC).FUNC THEN                         <<MPEIV>>04530000
            BEGIN <<SEGMENT READ>>                             <<MPEIV>>04532000
            X:=@IOQP;                                          <<MPEIV>>04534000
            IF REQSEGIDENT.SEGIDTYPEFIELD<>SEGIDDATATYPE THEN  <<MPEIV>>04536000
            TOS:=TOS+C'CODEREAD                                <<MPEIV>>04538000
            ELSE TOS:=TOS+C'DATAREAD;                          <<MPEIV>>04540000
            END                                                <<MPEIV>>04542000
         ELSE                                                  <<MPEIV>>04544000
            BEGIN <<DATA SEG WRITE>>                           <<MPEIV>>04546000
            X:=@IOQP;                                          <<MPEIV>>04548000
            IF REQURGCLASS <> BKGRNDPRI THEN                   <<MPEIV>>04550000
            TOS:=TOS+C'MMWRITEFORCED                           <<MPEIV>>04552000
            ELSE TOS:=TOS+C'MMWRITEBKGRD;                      <<MPEIV>>04554000
            END;                                               <<MPEIV>>04556000
         END                                                   <<MPEIV>>04558000
      ELSE                                                     <<MPEIV>>04560000
         BEGIN <<PROCESS INITIATED DISC TRANSFER>>             <<MPEIV>>04562000
         IF IOQPL.BLOCKED THEN                                 <<MPEIV>>04564000
            BEGIN  <<BLOCKED DISC I/O>>                        <<MPEIV>>04566000
            IF (TOS:=IOQP(QFUNC).FUNC) > 1 THEN                <<MPEIV>>04568000
               BEGIN                                           <<MPEIV>>04570000
               DEL;                                            <<MPEIV>>04572000
               TOS:=2; <<TURN ANY NON READ/WRITE INTO CONTROL>><<MPEIV>>04574000
               END;                                            <<MPEIV>>04576000
            CASE TOS OF                                        <<MPEIV>>04578000
               BEGIN                                           <<MPEIV>>04580000
               TOS:=TOS+C'BLKREAD; <<0>>                       <<MPEIV>>04582000
               TOS:=TOS+C'BLKWRITE; <<1>>                      <<MPEIV>>04584000
               TOS:=TOS+C'DISCCONTROL; <<2>>                   <<MPEIV>>04586000
               END; <<CASE>>                                   <<MPEIV>>04588000
            END                                                <<MPEIV>>04590000
         ELSE                                                  <<MPEIV>>04592000
            BEGIN <<UNBLOCKED DISC TRAFFIC>>                   <<MPEIV>>04594000
            IF IOQPL.(IOWAKE':1) THEN                          <<MPEIV>>04596000
               BEGIN <<AWAKE SET>>                             <<MPEIV>>04598000
               IF (TOS:=IOQP(QFUNC).FUNC) > 1 THEN             <<MPEIV>>04600000
                  BEGIN                                        <<MPEIV>>04602000
                  DEL;                                         <<MPEIV>>04604000
                  TOS:=2; <<TURN ANY NON READ/WRITE INTO CONT>><<MPEIV>>04606000
                  END;                                         <<MPEIV>>04608000
               CASE TOS OF                                     <<MPEIV>>04610000
                  BEGIN                                        <<MPEIV>>04612000
                  TOS:=TOS+C'UNBLKREADAWAKE; <<0>>             <<MPEIV>>04614000
                  TOS:=TOS+C'UNBLKWRITEAWAKE; <<1>>            <<MPEIV>>04616000
                  TOS:=TOS+C'DISCCONTROL; <<2>>                <<MPEIV>>04618000
                  END; <<CASE>>                                <<MPEIV>>04620000
               END                                             <<MPEIV>>04622000
            ELSE <<AWAKE NOT YET SET>>                         <<MPEIV>>04624000
               BEGIN                                                    04626000
               IF (TOS:=IOQP(QFUNC).FUNC) > 1 THEN             <<MPEIV>>04628000
                  BEGIN                                        <<MPEIV>>04630000
                  DEL;                                         <<MPEIV>>04632000
                  TOS:=2; <<TURN ANY NON READ/WRITE INTO CONT>><<MPEIV>>04634000
                  END;                                         <<MPEIV>>04636000
               CASE TOS OF                                     <<MPEIV>>04638000
                  BEGIN                                        <<MPEIV>>04640000
                  TOS:=TOS+C'UNBLKREAD; <<0>>                  <<MPEIV>>04642000
                  TOS:=TOS+C'UNBLKWRITE; <<1>>                 <<MPEIV>>04644000
                  TOS:=TOS+C'DISCCONTROL; <<2>>                <<MPEIV>>04646000
                  END; <<CASE>>                                <<MPEIV>>04648000
               END;                                                     04650000
            END;                                               <<MPEIV>>04652000
         END;                                                  <<MPEIV>>04654000
      ASMB(LADD;LSEA;INCA;SSEA;DDEL);                          <<MPEIV>>04656000
      END                                                      <<MPEIV>>04658000
   ELSE                                                        <<MPEIV>>04660000
      BEGIN <<POSSIBLY UPDATE NON-DISC DEVICE COUNTER>>        <<MPEIV>>04662000
      TOS:=TOS+DITPL(DLDEV).(8:8);                             <<MPEIV>>04664000
      ASMB(LSEA); <<SEGRELOFF FOR ITEM0 OF THIS DEVICE>>       <<MPEIV>>04666000
      IF <> THEN                                               <<MPEIV>>04668000
         BEGIN <<WE ARE KEEPING COUNTERS FOR THIS DEVICE>>     <<MPEIV>>04670000
         TOS:=TOS-DITPL(DLDEV).(8:8);<<SUB LDEV IDX TO SEG>>   <<RAY.>> 04672000
         IF (TOS:=IOQP(QFUNC).FUNC) > 1 THEN                   <<MPEIV>>04674000
            BEGIN                                              <<MPEIV>>04676000
            DEL;                                               <<MPEIV>>04678000
            TOS:=2; <<TURN ANY NON READ/WRITE INTO CONTROLL>>  <<MPEIV>>04680000
            END;                                               <<MPEIV>>04682000
         CASE TOS OF                                           <<MPEIV>>04684000
            BEGIN                                              <<MPEIV>>04686000
            TOS:=TOS+C'DEVREAD; <<0>>                          <<MPEIV>>04688000
            TOS:=TOS+C'DEVWRITE; <<1>>                         <<MPEIV>>04690000
            TOS:=TOS+C'DEVCONTROL; <<2>>                       <<MPEIV>>04692000
            END; <<CASE>>                                      <<MPEIV>>04694000
         ASMB(LADD;LSEA;INCA;SSEA;DDEL);                       <<MPEIV>>04696000
         END  <<NON-DISC COUNTER UPDATE>>                      <<MPEIV>>04698000
      ELSE                                                     <<MPEIV>>04700000
         <<WE ARE NOT KEEPING COUNTER FOR THIS DEVICE>>        <<MPEIV>>04702000
         ASMB(DEL,DDEL); <<BANK, ADDR, SEGRELOFF>>             <<MPEIV>>04704000
      END;                                                     <<MPEIV>>04706000
   END; <<UPDATING CODE>>                                      <<MPEIV>>04708000
   IF GCLASSENABLEDMASK.CLASS15 THEN                           <<01805>>04710000
      BEGIN <<PROCESS LEVEL DISC I/O COUNTERS>>                <<01805>>04712000
      IF DITP.(0:2)=DISC' AND NOT IOQPL.SPEC AND               <<01805>>04714000
         IOQP(QFUNC).FUNC <= 1 THEN                            <<01805>>04716000
         BEGIN <<PROCESS LEVEL DISC IO>>                       <<01805>>04718000
         TOS:=MEASPROCXDSBANK;                                 <<01805>>04720000
         TOS:=MEASPROCXDSBASE+IOQPL(QSTAT).PCBN*               <<01805>>04722000
              CLASS15'SUB0SIZE;                                <<01805>>04724000
         IF IOQP(QFUNC).FUNC = 0 THEN TOS:=TOS+CP'DISCREAD     <<01805>>04726000
            ELSE TOS:=TOS+CP'DISCWRITE;                        <<01805>>04728000
         ASMB(LSEA);                                           <<01805>>04730000
         TOS:=TOS+1;                                           <<01805>>04732000
         ASMB(SSEA);                                           <<01805>>04734000
         <<NOW BUMP TRANSFER COUNTS>>                          <<01805>>04736000
         IF IOQP(QFUNC).FUNC = 0 THEN                          <<01805>>04738000
            TOS:=TOS-CP'DISCREAD+CP'WORDSTRANS                 <<01805>>04740000
            ELSE TOS:=TOS-CP'DISCWRITE+CP'WORDSTRANS;          <<01805>>04742000
         ASMB(LDEA;ZERO); <<OLD COUNT, ZERO FOR DBL ADD>>      <<01805>>04744000
         IF IOQP(QWBCT) < 0 THEN TOS:=IOQP(QWBCT)/-2           <<01805>>04746000
            ELSE TOS:=IOQP(QWBCT);                             <<01805>>04748000
         ASMB(DADD;SDEA;DDEL);                                 <<01805>>04750000
         END;                                                  <<01805>>04752000
      END;                                                     <<01805>>04754000
   STATE := 0;                                                          04758000
   IF DITP.(0:2)=DISC' THEN                                    <<01782>>04760000
   BEGIN                                                       <<MPEIV>>04762000
      STORE'IOQ(IOQPL, FALSE);                                 <<02536>>04764000
   IF IOQPL.SPEC THEN                                          <<MPEIV>>04766000
      BEGIN                                                    <<MPEIV>>04768000
      IOQP.COMPLETED:=1;                                       <<01697>>04770000
      IF <> THEN SUDDENDEATH(261);<<ALREADY COMPLETED>>        <<01697>>04772000
      IF IOQPL(QFUNC).FUNC THEN SEGWRITECOMPLETOR(@IOQP)       <<MPEIV>>04774000
      ELSE SEGREADCOMPLETOR(@IOQP);                            <<MPEIV>>04776000
      GO TO CONT7;                                             <<MPEIV>>04778000
      END                                                      <<MPEIV>>04780000
   ELSE                                                        <<MPEIV>>04782000
      BEGIN <<PROCESS DISC I/O>>                               <<MPEIV>>04784000
      TOS:=IOQP(QSTAT)&PCBS*PCBSIZE;                           <<MPEIV>>04786000
      IF = THEN                                                <<MPEIV>>04788000
         BEGIN <<BETTER BE SYS BUF I/O>>                       <<MPEIV>>04790000
         ASMB(DEL);                                            <<MPEIV>>04792000
         IF NOT IOQPL.SYSBUFR THEN SUDDENDEATH(661);           <<01805>>04794000
         END                                                   <<MPEIV>>04796000
      ELSE IF IOQP(QDSTN)>0 LAND (IOQPL.BLOCKED                <<MPEIV>>04798000
       LOR IOQPL.(IOWAKE':1)) THEN                             <<MPEIV>>04800000
         BEGIN <<CLEAR DISC IO SEG FOR NON-STACK, WAITING>>    <<MPEIV>>04802000
         X:=ABSOLUTE(3);                                       <<MPEIV>>04804000
         X:=X+S0;                                              <<MPEIV>>04806000
         X:=X+DBXDSINFOWORDNUM;                                <<MPEIV>>04808000
         IF ABSOLUTE(X).XDSDSTFIELD <> IOQP(QDSTN).DSTN THEN   <<MPEIV>>04810000
            BEGIN <<MUST ADJUST>>                              <<MPEIV>>04812000
            TOS:=TOS+PCBSYSBASEINX;                            <<MPEIV>>04814000
            TOS:=IOQP(QDSTN).DSTN; <<SEGIDENT>>                <<MPEIV>>04816000
            TOS:=0D;                                           <<MPEIV>>04818000
            ASMB(TSBC CLEARDISCIOSEGBIT);                      <<MPEIV>>04820000
            ADJUSTLOCALITY(*,*,*,*);                           <<MPEIV>>04822000
            END;                                               <<MPEIV>>04824000
         END;                                                  <<MPEIV>>04826000
      END;                                                     <<MPEIV>>04828000
   END;                                                        <<MPEIV>>04832000
   UNFREEZEDATASEG;                                            <<01496>>04834000
DD3:                                                                    04836000
   DISABLE;                                                    <<MPEIV>>04838000
   IOQP.COMPLETED:=1;                                          <<MPEIV>>04840000
   IF <> THEN SUDDENDEATH(261); <<ALREADY COMPLETED>>          <<MPEIV>>04842000
   TOS := IOQP(QSTAT)&PCBS; << SAVE CALLER PIN ON TOS >>       <<MPEIV>>04844000
   IF DITP.(0:2)<>DISC' THEN                                   <<MPEIV>>04846000
   DITP(DIOQP) := IOQP(QLINK);  << DELINK IOQ >>               <<MPEIV>>04848000
   IF IOQPL.IOWAKE THEN AWAKE(S0*PCBSIZE,                      <<MPEIV>>04850000
         (IF IOQPL.BLOCKED THEN BLKDIO ELSE IOWAIT),NOWAIT);   <<MPEIV>>04852000
   << DO BLOCKED OR UNBLOCKED I/O AWAKE IF NEEDED >>           <<MPEIV>>04854000
   IF TOS = 0 THEN                                             <<MPEIV>>04856000
   BEGIN << NO PCB I/O, CHECK FOR SBUF RETURN >>               <<MPEIV>>04858000
      ENABLE;                                                  <<MPEIV>>04860000
      IF IOQPL.SYSBUFR AND IOQP(QADDR) <> 0 THEN               <<MPEIV>>04862000
      RETURNSYSBUF(IOQP(X));                                   <<MPEIV>>04864000
      RETURNIOQ(IOQP); << SYSTEM RETURNS THE IOQ >>            <<MPEIV>>04866000
   END;                                                        <<MPEIV>>04868000
CONT7:                                                         <<MPEIV>>04870000
IF DITP.(0:2)=DISC' THEN                                       <<MPEIV>>04872000
   BEGIN  <<SELECT NEXT REQUEST FOR DEVICE, Q FOR CONTROLLER>> <<MPEIV>>04874000
   DISABLE;                                                    <<MPEIV>>04876000
   X:=@DITP;                                                   <<MPEIV>>04878000
   DITP(DIOQP):=DITQHEADP;                                <<JB.<<MPEIV>>04880000
   @IOQP:=DITP(DIOQP);  <<UPDATE NEW IOQP>>                    <<01782>>04882000
   <<UPDATE DISC'S NEW CURRENT REQUEST>>                       <<MPEIV>>04884000
   IF GCLASSENABLEDMASK.CLASS0  THEN                           <<MPEIV>>04886000
      BEGIN  <<UPDATE Q LENGTH HISTOGRAM>>                     <<MPEIV>>04888000
      TOS:=MEASSTATXDSBANK;                                    <<MPEIV>>04890000
      TOS:=MEASSTATXDSBASE;                                    <<MPEIV>>04892000
      TOS:=TOS+DITPL(DLDEV).(8:8);                             <<MPEIV>>04894000
      ASMB(LSEA); <<TOS HAS SEG REL OFFSET OF ITEM 0 >>        <<MPEIV>>04896000
      TOS:=TOS-DITPL(DLDEV).(8:8); <<SUB LDEV IDX TO SEG>>     <<MPEIV>>04898000
      DISCQLENGTH:=0;                                          <<MPEIV>>04900000
      X:=@DITP;                                                <<MPEIV>>04902000
      X:=DITQHEADP;                                            <<MPEIV>>04904000
      WHILE <> DO                                              <<MPEIV>>04906000
         BEGIN                                                 <<MPEIV>>04908000
         DISCQLENGTH:=DISCQLENGTH+1;                           <<MPEIV>>04910000
         X:=NEXTREQP;                                          <<MPEIV>>04912000
         END;                                                  <<MPEIV>>04914000
      TOS:=DISCQLENGTH;                                        <<MPEIV>>04916000
      IF (TOS:=TOS) > 6 THEN                                   <<MPEIV>>04918000
         BEGIN                                                 <<MPEIV>>04920000
         ASMB(DEL);                                            <<MPEIV>>04922000
         TOS:=6;                                               <<MPEIV>>04924000
         END;                                                  <<MPEIV>>04926000
      CASE TOS OF                                              <<MPEIV>>04928000
         BEGIN                                                 <<MPEIV>>04930000
         TOS:=TOS+C'DISCQUEUE0;                                <<MPEIV>>04932000
         TOS:=TOS+C'DISCQUEUE1;                                <<MPEIV>>04934000
         TOS:=TOS+C'DISCQUEUE2;                                <<MPEIV>>04936000
         TOS:=TOS+C'DISCQUEUE3;                                <<MPEIV>>04938000
         TOS:=TOS+C'DISCQUEUE4;                                <<MPEIV>>04940000
         TOS:=TOS+C'DISCQUEUE5;                                <<MPEIV>>04942000
         TOS:=TOS+C'DISCQUEUE6;                                <<MPEIV>>04944000
         END; <<CASE>>                                         <<MPEIV>>04946000
      ASMB(LADD;LSEA;INCA;SSEA;DDEL);                          <<MPEIV>>04948000
      END;                                                     <<MPEIV>>04950000
   <<DEQUEUE THAT REQUEST, AND Q DISC FOR CONTROLLER>>         <<MPEIV>>04952000
   X:=DITP(DIOQP);                                             <<MPEIV>>04954000
   IF <> THEN                                                  <<MPEIV>>04956000
      BEGIN <<DEQUEUE DISC REQ, QUEUE DISC FOR CONTRL>>        <<MPEIV>>04958000
      <<TAKE REQUEST OFF DISC'S QUEUE>>                        <<MPEIV>>04960000
      DEQUEUEDISCREQ(X,@DITP);                                 <<MPEIV>>04962000
      DISCREQFLAGS.DITSCURRREQFLAG:=1;                         <<MPEIV>>04964000
      IF <> THEN SUDDENDEATH(663);                             <<01640>>04966000
      IF NOT IOQPL.SYSBUFR AND NOT IOQPL.SPEC THEN             <<01782>>04968000
         BEGIN  <<FREEZE BUFFER BEFORE SEEK-AHEAD>>            <<01782>>04970000
         IOFREEZE'(IOQP(QDSTN).DSTN);                          <<01782>>04972000
         IF = THEN IOQP.DATAFRZN:=1;                           <<01782>>04974000
         END;                                                  <<01782>>04976000
COMMENT                                                        <<04899>>04978000
   CODE 3599000 TO 3611000 REMOVED TO PERMIT SOFTWARE          <<04899>>04980000
   CHANNELIZING TO WORK PROPERLY. DEVICE WON'T BE ON           <<04899>>04982000
   CONTROLLER QUEUE WHILE OWNING QUEUE RESOURCE.  ;            <<04899>>04984000
      END;                                                     <<MPEIV>>04988000
   END;                                                        <<MPEIV>>04990000
   RELCONTROLLER;                                              <<01496>>04992000
   GO TO STAY;                                                          04994000
<<>>                                                                    04996000
STATE6:                                                                 04998000
   IF DITPL.MUNIT AND DITPL.DISC   THEN CHECKPOLL;             <<01496>>05000000
   IF @IOQP = 0 AND SYSUP THEN                                          05002000
   BEGIN                                                                05004000
DO'DEVREC:                                                     <<01496>>05006000
                                                               <<03686>>05008000
      << The following subroutine returns TRUE if this  >>     <<03686>>05010000
      << device qualifies for recognition.              >>     <<03686>>05012000
                                                               <<03686>>05014000
      if RECOGNIZE'DEVICE then                                 <<03686>>05016000
         begin                                                 <<03686>>05018000
         DISABLE;                                                       05022000
         TOS := LPDTD(DITP(DLDEV).DLDEVN); << SET SERVICE REQUEST >>    05024000
         TOS.DIRCSTATE:=SERVREQ;                                        05026000
         LPDTD(X) := TOS;                                               05028000
         LPDT(X) := LPDT(1) + 1; << INCREMENT DEVREC COUNTER >>         05030000
         DITP.IAK := 0;  << IAK SET BY DIP/GIP >>              <<01496>>05032000
         ENABLE;                                                        05034000
         AWAKE(DEVRECPCBP,JUNKWAIT,NOWAIT);                             05036000
         end;                                                  <<03686>>05038000
                                                               <<03686>>05040000
                                                               <<03686>>05042000
   END;                                                                 05044000
   STATE := 0;                                                          05046000
   GO TO STATE0;                                                        05048000
<<>>                                                                    05050000
STATE7:                                                                 05052000
   UNFREEZEDATASEG;                                            <<01496>>05054000
   STATE := STATE + 1;                                                  05056000
   RELCONTROLLER;                                              <<01496>>05058000
   GO TO STAY;                                                 <<01496>>05060000
<<>>                                                                    05062000
STATE10:                                                                05064000
   IF DITPL.MUNIT AND DITPL.DISC   THEN CHECKPOLL;             <<01496>>05066000
   DISABLE;                                                             05068000
   DITP.IAK:=0;                                                <<01496>>05070000
   IF <> THEN                                                  <<01496>>05072000
      BEGIN                                                    <<01496>>05074000
      IF DITP.(0:2)=DISC' THEN GOTO DO'DEVREC                  <<01496>>05076000
         ELSE BEGIN                                            <<01496>>05078000
              STATE:=0;                                        <<01496>>05080000
              GOTO STAY;                                       <<01496>>05082000
              END;                                             <<01496>>05084000
      END;                                                     <<01496>>05086000
   IF DITPL.SIOPREMPT THEN DITP.IAK := 1  << RESTART ON PREEMPTION >>   05088000
    ELSE GO TO CHECKWAIT;  << CHECK TO START IDLE CPGM >>      <<01496>>05090000
<<>>                                                                    05092000
STATE13:                                                                05094000
   DISABLE;                                                             05096000
   DITP.IAK := 0;                                                       05098000
   IF = THEN GO TO OUT;                                                 05100000
CONT10:                                                        <<01496>>05102000
   ENABLE;                                                              05104000
   STATE := STATE - %10;                                                05106000
   GO TO STAY;                                                          05108000
<<>>                                                                    05110000
STATE11:                                                                05112000
   IF DITPL.MUNIT AND DITPL.DISC   THEN CHECKPOLL;             <<01496>>05114000
   @IOQP := DITP(DIOQP); << UPDATE IOQ PTR IF COMING FROM ST. 5 >>      05116000
   IOQP.PREQ := 0; << RESET PRIOR REQUEST >>                            05118000
   IF IOQPL.DATAFRZN THEN GO TO STATE2; << DATA SEG FROZEN ? >>         05120000
   IF IOQPL.MAMERRORD THEN GO TO MAMERR; << MAKEPRESENT ERROR >>        05122000
   GO TO OUT;                                                           05124000
<<>>                                                                    05126000
STATE12:                                                                05128000
   IF DLTPL.DVRFRZN THEN GO TO CONT12; << INITIATOR CODE FROZEN >>      05130000
   IF DLTPL.MAMERRORC THEN GO TO MAMERR; << MAKEPRESENT ERROR ON CS >>  05132000
   GO TO OUT;                                                           05134000
<<>>                                                                    05136000
STATE14:                                                                05138000
   IF DITPL.MUNIT AND DITPL.DISC   THEN CHECKPOLL;             <<01496>>05140000
   DISABLE;                                                             05142000
   IF BUSY(CONTROLLER) = 0 OR BUSY(X) = @DITP THEN GO TO CONT14;        05144000
   ADDTAIL(DITP,DLINK,X);                                               05146000
   GO TO OUT; << STILL BUSY,WAIT >>                                     05148000
<<>>                                                           <<01496>>05150000
STATE15:                                                       <<01496>>05152000
   DISABLE;                                                    <<01496>>05154000
   DITP.IAK:=0;        << DID GIP CALL SIODM TO GET US HERE? >><<01496>>05156000
   IF = THEN GOTO OUT;<< OR ARE WE JUST LEAVING FROM STATE 3?>><<01496>>05158000
   STATE:=5;    << WE WERE DOING A RQST AND THE UNIT WE WERE >><<01496>>05160000
                           << RQST'ING HAPPENED TO INTERRUPT >><<01496>>05162000
   TOS := LPDTD(DITP(DLDEV).DLDEVN); <<SO SET SERVICE REQUEST>><<01496>>05164000
   TOS.DIRCSTATE:=2;                                           <<01496>>05166000
   LPDTD(X) := TOS;                                            <<01496>>05168000
   LPDT(X) := LPDT(1) + 1; << AND INCREMENT DEVREC COUNTER >>  <<01496>>05170000
   ENABLE;                                                     <<01496>>05172000
   AWAKE(DEVRECPCBP,JUNKWAIT,NOWAIT);    << AWAKEN DEVREC >>   <<01496>>05174000
   GOTO STAY;                                                  <<01496>>05176000
<<>>                                                                    05178000
STATE16:                                                                05180000
STATE17:                                                                05182000
   IF DLTPL.MAMERRORC THEN GO TO MAMERR; << MAKPRESENT ERROR >>         05184000
   STATE := STATE - %14;                                                05186000
   GO TO STAY;                                                 <<01496>>05188000
                                                                        05190000
END;                                                                    05192000
                                                               <<02664>>05194000
                                                               <<02664>>05196000
$PAGE  "REPORT'IOERROR"                                        <<02664>>05198000
INTEGER PROCEDURE GENMSG(SETNO,MSGNO,MASK,PARM1,PARM2,         <<02664>>05200000
      PARM3,PARM4,PARM5,DEST,REPLY,OFFSET,DST,CONTROL);        <<02664>>05202000
   VALUE   SETNO,MSGNO,MASK,PARM1,PARM2,PARM3,PARM4,PARM5,     <<02664>>05204000
           DEST,REPLY,OFFSET,DST,CONTROL;                      <<02664>>05206000
   INTEGER SETNO,MSGNO,DEST,DST;                               <<02664>>05208000
   LOGICAL MASK,PARM1,PARM2,PARM3,PARM4,PARM5,REPLY,OFFSET,    <<02664>>05210000
      CONTROL;                                                 <<02664>>05212000
   OPTION VARIABLE,EXTERNAL;                                   <<02664>>05214000
                                                               <<02664>>05216000
                                                               <<02664>>05218000
                                                               <<02664>>05220000
PROCEDURE REPORT'IOERROR(LDEV,IOSTATUS);                       <<02664>>05222000
   VALUE LDEV,IOSTATUS;                                        <<02664>>05224000
   INTEGER LDEV,IOSTATUS;                                      <<02664>>05226000
   OPTION PRIVILEGED,UNCALLABLE;                               <<02664>>05228000
                                                               <<02664>>05230000
COMMENT                                                        <<02664>>05232000
                                                               <<02664>>05234000
   Procedures doing device recognition call REPORT'IOERROR to  <<02664>>05236000
print a message on the console when it is important that the   <<02664>>05238000
operator know immediately that an IO error has occured on a    <<02664>>05240000
device.  This could be of use to the entire operating system.  <<02664>>05242000
                                                               <<02664>>05244000
   INPUTS:                                                     <<02664>>05246000
      LDEV - the device on which the error occured.            <<02664>>05248000
      IOSTATUS - the low order 8-bits of the PCB/STATUS word   <<02664>>05250000
                 returned by ATTACHIO.                         <<02664>>05252000
   CALLERS:                                                    <<02664>>05254000
      DEVREC, and RECOGNIZE (in LABSEG).                       <<02664>>05256000
                                                               <<02664>>05258000
   DB:                                                         <<02664>>05260000
      DB must be at the stack when calling this procedure.     <<02664>>05262000
                                                               <<02664>>05264000
;     << end of comment >>                                     <<02664>>05266000
                                                               <<02664>>05268000
BEGIN                                                          <<02664>>05270000
   INTEGER                                                     <<02664>>05272000
      LENGTH,       << Return from ASCII >>                    <<02664>>05274000
      ERRNUM,       << Set 1 error message number >>           <<02664>>05276000
      I;            << Loop variable >>                        <<02664>>05278000
   BYTE ARRAY                                                  <<02664>>05280000
      RESULT(0:6);  << Array for ASCII >>                      <<02664>>05282000
   EQUATE                                                      <<02664>>05284000
      << Error message number equates >>                       <<02664>>05286000
      EXTERNAL'ABORT    = 305,  << % 33 >>                     <<02664>>05288000
      NOT'ONLINE        = 401,  << % 53 >>                     <<02664>>05290000
      PFAIL'ABORT       = 306,  << % 63 >>                     <<02664>>05292000
      POWER'UP          = 402,  << %213 >>                     <<02664>>05294000
      INVALID'FUNC      = 307,  << %  4 >>                     <<02664>>05296000
      TRANSFER'ERROR    = 309,  << % 14 >>                     <<02664>>05298000
      IO'TIMEOUT        = 308,  << % 24 >>                     <<02664>>05300000
      TIMING'ERROR      = 403,  << % 34 >>                     <<02664>>05302000
      SIO'FAILURE       = 281,  << % 44 >>                     <<02664>>05304000
      UNIT'FAILURE      = 404,  << % 54 >>                     <<02664>>05306000
      PARITY'ERROR      = 405,  << % 74 >>                     <<02664>>05308000
      SYSTEM'ERROR      = 406,  << %124 >>                     <<02664>>05310000
      CHANNEL'FAILURE   = 407,  << %144 >>                     <<02664>>05312000
      END'OF'FILE       = 408,  << % X2 >>                     <<02664>>05314000
      LEFT'OVERS        = 400,  << % XX >>                     <<02664>>05316000
      END'OF'EQUATES    =   0;                                 <<02664>>05318000
                                                               <<02664>>05320000
   INTEGER ARRAY                                               <<02664>>05322000
      STATUS'TABLE(*) = PB :=                                  <<02664>>05324000
         << Each pair is (status return, errnum).  The table >><<02664>>05326000
         << ends with a zero pair. >>                          <<02664>>05328000
                                                               <<02664>>05330000
       %33, EXTERNAL'ABORT,                                    <<02664>>05332000
       %53, NOT'ONLINE,                                        <<02664>>05334000
       %63, PFAIL'ABORT,                                       <<02664>>05336000
      %213, POWER'UP,                                          <<02664>>05338000
                                                               <<02664>>05340000
        %4, INVALID'FUNC,                                      <<02664>>05342000
       %14, TRANSFER'ERROR,                                    <<02664>>05344000
       %24, IO'TIMEOUT,                                        <<02664>>05346000
       %34, TIMING'ERROR,                                      <<02664>>05348000
       %44, SIO'FAILURE,                                       <<02664>>05350000
       %54, UNIT'FAILURE,                                      <<02664>>05352000
       %74, PARITY'ERROR,                                      <<02664>>05354000
      %124, SYSTEM'ERROR,                                      <<02664>>05356000
      %144, CHANNEL'FAILURE,                                   <<02664>>05358000
                                                               <<02664>>05360000
         0, 0;     << End of table >>                          <<02664>>05362000
                                                               <<02664>>05364000
   INTRINSIC ASCII;                                            <<02664>>05366000
                                                               <<02664>>05368000
                                                               <<02664>>05370000
   LENGTH := ASCII(IOSTATUS,8,RESULT);                         <<02664>>05372000
   MOVE RESULT := RESULT(6 - LENGTH),(LENGTH);  << Justify >>  <<02664>>05374000
   RESULT(LENGTH) := 0;   << GENMSG needs zero terminator. >>  <<02664>>05376000
                                                               <<02664>>05378000
   << Search the table for the appropriate error message. >>   <<02664>>05380000
   ERRNUM := 0;                                                <<02664>>05382000
   I := 0;                                                     <<02664>>05384000
   DO BEGIN                                                    <<02664>>05386000
      IF IOSTATUS = STATUS'TABLE(I) THEN                       <<02664>>05388000
         ERRNUM := STATUS'TABLE(I+1);                          <<02664>>05390000
      END                                                      <<02664>>05392000
   UNTIL (ERRNUM <> 0) OR (STATUS'TABLE(I:=I+2) = 0);          <<02664>>05394000
                                                               <<02664>>05396000
   << If no specific message, then report end-of-file >>       <<02664>>05398000
   << or use the general error message. >>                     <<02664>>05400000
   IF ERRNUM = 0 THEN                                          <<02664>>05402000
      ERRNUM := IF IOSTATUS.(13:3) = 2 THEN END'OF'FILE        <<02664>>05404000
                                       ELSE LEFT'OVERS;        <<02664>>05406000
                                                               <<02664>>05408000
   GENMSG(1,ERRNUM,%10000,LDEV,@RESULT,,,,0);                  <<02664>>05410000
                                                               <<02664>>05412000
END;    << of REPORT'IOERROR >>                                <<02664>>05414000
                                                               <<03031>>05418000
<<===========REQSTATUS=============>><< SPLIT STACK CALLS OK >><<03031>>05420000
                                                               <<03031>>05422000
DOUBLE PROCEDURE REQSTATUS(LDN);                               <<03031>>05424000
VALUE LDN; INTEGER LDN;                                        <<03031>>05426000
BEGIN                                                          <<03031>>05428000
  << request status from "DISC DEVICE" and return 2-WORDS >>   <<03031>>05430000
  << of DISC INFO in approximately the same format as the >>   <<03031>>05432000
  << 2-Word Status Returned by the 13037 Disc Controller  >>   <<03031>>05434000
                                                               <<03031>>05436000
  ARRAY   QARRAY (*)  = Q+0,   << USED TO LOAD VAL @ DL-1 >>   <<03031>>05438000
          RQSTAT(0:11)= Q;     <<  BIG ENOUGH FOR DCS'80  >>   <<03031>>05440000
  LOGICAL RQSTAT0     = RQSTAT,                                <<03031>>05442000
          RQSTAT1     = RQSTAT0+1,                             <<03031>>05444000
          STATWORD1   = REQSTATUS,                             <<03031>>05446000
          STATWORD2   = STATWORD1+1;                           <<03031>>05448000
  INTEGER TYPE        = RQSTAT+10,                             <<03031>>05450000
          OFSET       = TYPE+1;                                <<03031>>05452000
                                                               <<03031>>05454000
  DOUBLE  DRQSTAT     = RQSTAT;                                <<03031>>05456000
                                                               <<03031>>05458000
  DEFINE  LPDT1= S'LPDT(LDN&LSL(1)+1)#,                        <<03031>>05460000
          STK  = ABS(ABS(CPCB)+PCB3).DSTFIELD#,                <<03031>>05462000
          FLG  = (IF ALLOCATED AND NOTFOREIN THEN %41 ELSE 1)#,<<03031>>05464000
                                                               <<03031>>05466000
          NOTREADY    = ( 3:1)#,                               <<03031>>05468000
          READONLY    = ( 4:1)#,                               <<03031>>05470000
          ANYERRORBIT = ( 0:1)#,                               <<03031>>05472000
          VSFLD       = ( 3:5)#,                               <<03031>>05474000
          READONLYBIT = ( 9:1)#,                               <<03031>>05476000
          FORMATSWBIT = (10:1)#,                               <<03031>>05478000
          NOTREADYBIT = (14:1)#,                               <<03031>>05480000
                                                               <<03031>>05482000
          VS7911      = 109823D#,   << %000001, %126377 >>     <<03031>>05484000
          VS7912      = 256255D#,   << %000003, %164377 >>     <<03031>>05486000
          VS7935      = 1579915D#,  << %000030, %015613 >>     <<03031>>05488000
          LIN16M      = 16351D#,    << %000000, %037737 >>     <<03031>>05490000
          LIN65M      = 65407D#;    << %000000, %177577 >>     <<03031>>05492000
                                                               <<03031>>05494000
                                                               <<03031>>05496000
  RSTATUS.CC := CCL;     <<** ASSUME LDN NOT VALID DISC **>>   <<03031>>05498000
  REQSTATUS:=0D;           <<**  CLEAR OUT RETURN VALUE **>>   <<03031>>05500000
  TYPE:=LDEVTOTYPE(LDN);                                       <<03031>>05502000
  IF = AND CARRY AND DISCDEVICE THEN                           <<03031>>05504000
  BEGIN  << VALID LDN AND DISC >>                              <<03031>>05506000
    RSTATUS.CC := CCG;   <<** ASSUME AN ERROR CONDITION **>>   <<03031>>05508000
    PUSH(Q,DL);                                                <<03031>>05510000
    ASMB(XCH,SUB);                     << COMPUTE DL TO Q >>   <<03031>>05512000
    X:=S0-1;                                                   <<03031>>05514000
    TOS:=QARRAY(X);             << DL OFFSET IN STACK DST >>   <<03031>>05516000
    ASMB(XCH,SUB);              << Q  OFFSET IN STACK DST >>   <<03031>>05518000
    OFSET:=TOS+1;               <<    DST OFFSET TO Q+1   >>   <<03031>>05520000
             << -- FUNCT =  7  REQST STATUS FOR ALL DISCS >>   <<03031>>05522000
    TOS:=ATTACHIO(LDN,0,STK,OFSET,7,10,0,0,FLG);               <<03031>>05524000
             << -- WCNT  = 10 DISC DVR MAY TRIM THIS TO 4 >>   <<03031>>05526000
    IF LS1.STATUS<>1 THEN << ATTACHIO RETURNED ERROR COND >>   <<03031>>05528000
      REQSTATUS:=TOS            << RETURN ERROR CONDITION >>   <<03031>>05530000
    ELSE                                                       <<03031>>05532000
    BEGIN  << GOOD STATUS >>                                   <<03031>>05534000
      DDEL;                        << POP ATTACHIO RETURN >>   <<03031>>05536000
      IF TYPE<>3 THEN REQSTATUS:=DRQSTAT                       <<03031>>05538000
      ELSE                                                     <<03031>>05540000
      BEGIN  << CS'80 DEV >>   << MUST MASAGE RETURN BITS >>   <<03031>>05542000
        STATWORD2.NOTREADYBIT:=RQSTAT(3).NOTREADY;             <<03031>>05544000
        IF STATWORD2<>0 THEN STATWORD2.ANYERRORBIT:=TRUE;      <<03031>>05546000
        STATWORD2.READONLYBIT:=RQSTAT(3).READONLY;             <<03031>>05548000
        STATWORD2.FORMATSWBIT:=TRUE;                           <<03031>>05550000
        <<>>                                                   <<03031>>05552000
        << MAYBE MORE LATER >>                                 <<03031>>05554000
        <<>>                                                   <<03031>>05556000
             << -- FUNCT = 13  RET VOL SIZE FOR ALL CS'80 >>   <<03031>>05558000
      IF NOT STATWORD2.NOTREADYBIT THEN                        <<03686>>05560000
        << YOU CAN ONLY DO A DESCRIBE  IF DISC IS READY  >>    <<03686>>05562000
        << ELSE IT WILL EAT THE ONLINE INTERRUPT..WEO    >>    <<03686>>05564000
       BEGIN  <<  GOOD STATUS.... GET DESCRIPTION  >>          <<03686>>05566000
        TOS:=ATTACHIO(LDN,0,STK,OFSET,13,2,0,0,FLG);           <<03031>>05568000
        IF LS1.STATUS=1 THEN                                   <<03031>>05570000
        BEGIN                                                  <<03031>>05572000
          IF DRQSTAT=VS7911 THEN STATWORD2.VSFLD:=%11;         <<03031>>05574000
          IF DRQSTAT=VS7912 THEN STATWORD2.VSFLD:=%12;         <<03031>>05576000
          IF DRQSTAT=VS7935 THEN STATWORD2.VSFLD:=%13;         <<03031>>05578000
          IF DRQSTAT=LIN16M THEN STATWORD2.VSFLD:=%14;         <<03031>>05580000
          IF DRQSTAT=LIN65M THEN STATWORD2.VSFLD:=%15;         <<03031>>05582000
        END;                                                   <<03031>>05584000
       END;  << GOOD STATUS DESCRIBE >>                        <<03686>>05586000
      END;   << CS'80 DEV >>                                   <<03031>>05588000
      RSTATUS.CC:=CCE;  <<** SET COND-CODE TO NON ERROR **>>   <<03031>>05590000
    END;   << GOOD STATUS >>                                   <<03031>>05592000
  END;   << VALID LDN AND DISC >>                              <<03031>>05594000
END;   << REQSTATUS >>                                         <<03031>>05596000
$PAGE "PROCEDURE TO SCHEDULE I/O ERRORS TO BE LOGGED"          <<02801>>05598000
procedure LOGERROR(DITP,IOQP,DEVSTAT);                         <<02801>>05600000
value DITP,IOQP,DEVSTAT;                                       <<02801>>05602000
integer DEVSTAT;                                               <<02801>>05604000
integer pointer DITP,IOQP;                                     <<02801>>05606000
option privileged,uncallable;                                  <<02801>>05608000
begin                                                          <<02801>>05610000
<<***********************************************************>><<02801>>05612000
<< I/O Error Logging Message Format                          >><<02801>>05614000
<<***********************************************************>><<02801>>05616000
<< Word | Desciption                                         >><<02801>>05618000
<<***********************************************************>><<02801>>05620000
<< 0    | DEVSTAT: (0:8)-Len of area/(8:8)-DIT rel start addr>><<02801>>05622000
<< 1    | IOQ pointer                                        >><<02801>>05624000
<< 2-10 | 9 words of IOQ (2-10)                              >><<02801>>05626000
<< 11   | (0:8)-Subtype / (8:8)-Device Type                  >><<02801>>05628000
<< 12   | (0:8)-LDEV    / (8:8)-DRT                          >><<02801>>05630000
<< 13-n | Variable len logged info (len of word 2 (0:8)      >><<02801>>05632000
<< n+1  | Length of variable logged info in prior line       >><<02801>>05634000
<< n+2  | The integer constant 11 for I/O error logging      >><<02801>>05636000
<<***********************************************************>><<02801>>05638000
                                                               <<02801>>05640000
                                                               <<02801>>05642000
equate IOLOGQX = %63,                                          <<02801>>05644000
       IOMSGPINDEX = %152;                                     <<02801>>05646000
integer IOMSGPROC = db + IOMSGPINDEX, <<pin of IOMESSAGEPROC>> <<02801>>05648000
        IOLOG     = db + IOLOGQX;     <<error flags word    >> <<02801>>05650000
integer pointer SBUFX;                                         <<02801>>05652000
integer LEN;   <<length of data in SYSBUF>>                    <<02801>>05654000
                                                               <<02801>>05656000
<<  IF THE SYSTEM IS NOT UP THE LOGGING PROCESS WILL  >>       <<04393>>05658000
<<  NOT BE INITIALIZED OR EXECUTING AND THIS SYSTEM   >>       <<04393>>05660000
<<  BUFFER MAY BE LOST OR THE LOGGING PROCESS MAY     >>       <<04393>>05662000
<<  GET A SF 16 TRYING TO ACCESS ITS DATA SEGMENTS    >>       <<04393>>05664000
<<  WHICH HAVE NOT BEEN OBTAINED BY ITS INITIALIZATION>>       <<04393>>05666000
<<  CALL SO........                  CHANGE# C# 1     >>       <<04393>>05668000
                                                               <<04393>>05670000
IF NOT SYSUP THEN RETURN;                                      <<04393>>05672000
                                                               <<04393>>05674000
<<first, attempt to obtain a system buffer to log this error.>><<02801>>05676000
<<We will obtain this SYSBUF from primary area only          >><<02801>>05678000
<<with NO impedes.                                           >><<02801>>05680000
@SBUFX := GETSBUF(1);                                          <<02801>>05682000
if @SBUFX = 0 then                                             <<02801>>05684000
  begin   <<we failed to obtain a SYSTEM BUFFER!>>             <<02801>>05686000
  DISABLE;                                                     <<02801>>05688000
  IOLOG.(0:1) := 1; <<log fact that there was no SYSBUF>>      <<02801>>05690000
  return;                                                      <<02801>>05692000
  end;                                                         <<02801>>05694000
                                                               <<02801>>05696000
<<now that we have system buffer, move info to it>>            <<02801>>05698000
                                                               <<02801>>05700000
SBUFX    := DEVSTAT;           <<load in ERROR log control>>   <<02801>>05702000
                                                               <<02801>>05704000
<< if there is no IOQ, move zeros into logging >>              <<02801>>05706000
if @IOQP = 0 then                                              <<02801>>05708000
  begin        << no IOQ exists >>                             <<02801>>05710000
  SBUFX(1) := 0;                                               <<02801>>05712000
  move SBUFX(2) := SBUFX(1),(9);                               <<02801>>05714000
  end                                                          <<02801>>05716000
else                                                           <<02801>>05718000
  begin        << do log IOQ information >>                    <<02801>>05720000
  SBUFX(1) := IOQP;              <<IOQ word 0>>                <<02801>>05722000
  move SBUFX(2):=IOQP(2),(9);    <<words 2-10 of IOQ>>         <<02801>>05724000
  end;                                                         <<02801>>05726000
                                                               <<02801>>05728000
tos := DITP(DDLTP);         <<pointer to DLT on tos-temp>>     <<02801>>05730000
tos := PS0(DTYPEDLT).DEVTYPE;  <<dev type on tos>>             <<02801>>05732000
assemble(delb);             <<remove temporary pointer to DLT>><<02801>>05734000
tos := LPDTD(DITP(DLDEV).DLDEVN); <<LPDT dbl wd entry on tos>> <<02801>>05736000
assemble(delb);             <<remove high-order word>>         <<02801>>05738000
tos := tos & lsl(12);       <<shift off garbage on the left>>  <<02801>>05740000
SBUFX(11):=(tos&lsr(4)) lor tos;<<dev subtype/type on tos>>    <<02801>>05742000
                                                               <<02801>>05744000
tos := logical(DITP(DLDEV)) land %037400; <<extract UNIT from D<<02801>>05746000
tos := DITP(DILTP);         <<ILT pointer on tos>>             <<02801>>05748000
tos := logical(PS0(ICNTRL)) land %377; <<extract DRT number>>  <<02801>>05750000
assemble(delb);             <<remove pointer to ILT>>          <<02801>>05752000
SBUFX(12) := tos lor tos;      <<store ldev/DRT for logging>>  <<02801>>05754000
                                                               <<02801>>05756000
<<now, store off the variable info>>                           <<02801>>05758000
<<if length of variable info is greater than the remainder of t<<02801>>05760000
<<System Buffer size (128-13), then truncate the length to the <<02801>>05762000
<<length  we CAN handle.                                       <<02801>>05764000
LEN := DEVSTAT.(0:8);   <<LEN requested of info to log>>       <<02801>>05766000
if LEN > 115 then                                              <<02801>>05768000
  begin  <<we must truncate info to 114 words>>                <<02801>>05770000
  LEN := 115;                                                  <<02801>>05772000
  SBUFX(1).(0:8) := 115;                                       <<02801>>05774000
  end;                                                         <<02801>>05776000
move SBUFX(13) := DITP(DEVSTAT.(8:8)),(LEN);                   <<02801>>05778000
                                                               <<02801>>05780000
<<now, inform IOMESSAGEPROC that I/O error exists to process>> <<02801>>05782000
tos := 0;    <<message type 0 to IOMESSAGEPROC>>               <<02801>>05784000
tos := @SBUFX;    <<system buffer index with info>>            <<02801>>05786000
tos := LEN + 13;  <<length of message>>                        <<02801>>05788000
tos := 0;         <<filler, not used as of yet>>               <<02801>>05790000
SENDMSG(IOMSGPROC/PCBSIZE,0,4,%40000);  <<wake up IOMESSPROC>> <<02801>>05792000
end;   <<of procedure LOGERROR>>                               <<02801>>05794000
$PAGE "IOMESSAGE - SEND GENMSG MESSAGES FROM ICS"              <<02801>>05796000
LOGICAL PROCEDURE IOMESSAGE(SETNO,MSGNO,MASK,P1,P2,P3,P4,P5,   <<02801>>05798000
   DEST,REPLY,OFFSET,DITP,IOTYPE);                             <<02801>>05800000
VALUE SETNO,MSGNO,MASK,P1,P2,P3,P4,P5,DEST,REPLY,OFFSET,DITP,  <<02801>>05802000
   IOTYPE;                                                     <<02801>>05804000
INTEGER SETNO,MSGNO,MASK,P1,P2,P3,P4,P5,DEST,REPLY,OFFSET,     <<02801>>05806000
   IOTYPE;                                                     <<02801>>05808000
INTEGER POINTER DITP;                                          <<02801>>05810000
OPTION VARIABLE,PRIVILEGED,UNCALLABLE;                         <<02801>>05812000
BEGIN                                                          <<02801>>05814000
EQUATE                                                         <<02801>>05816000
   IOMSGPINDEX = %152,                                         <<02801>>05818000
   IOLOGINDEX  = %63;                                          <<02801>>05820000
ARRAY                                                          <<02801>>05822000
   PARM(*)     = Q-18;  << ONE BELOW FIRST PARM >>             <<02801>>05824000
INTEGER                                                        <<02801>>05826000
   IOMSGPROC   = DB + IOMSGPINDEX,                             <<02801>>05828000
   IOLOG       = DB + IOLOGINDEX;                              <<02801>>05830000
INTEGER                                                        <<02801>>05832000
   CHEKINT=Q-1;                                                <<02801>>05834000
INTEGER POINTER                                                <<02801>>05836000
   SBUFX;                                                      <<02801>>05838000
                                                               <<02801>>05840000
<<  IF THE SYSTEM IS NOT UP THE LOG/MSG PROCESS WILL  >>       <<04466>>05842000
<<  NOT BE INITIALIZED OR EXECUTING AND THIS SYSTEM   >>       <<04466>>05844000
<<  BUFFER MAY BE LOST OR THE LOGGING PROCESS MAY     >>       <<04466>>05846000
<<  GET A SF 16 TRYING TO ACCESS ITS DATA SEGMENTS    >>       <<04466>>05848000
<<  WHICH HAVE NOT BEEN OBTAINED BY ITS INITIALIZATION>>       <<04466>>05850000
<<  CALL SO........              A8: CHANGE# C# 2     >>       <<04466>>05852000
                                                               <<04466>>05854000
IF NOT SYSUP THEN RETURN;                                      <<04466>>05856000
                                                               <<04466>>05858000
<<get a system buffer to send message>>                        <<02801>>05860000
@SBUFX := GETSBUF(1);  <<secondary area only, no impede>>      <<02801>>05862000
if @SBUFX = 0 then                                             <<02801>>05864000
  begin                                                        <<02801>>05866000
  DISABLE;                                                     <<02801>>05868000
  IOLOG.(1:1) := 1; <<IOMESSAGE could not get a system buffer>><<02801>>05870000
  return;                                                      <<02801>>05872000
  end;                                                         <<02801>>05874000
                                                               <<02801>>05876000
<<now, move GENMSG parms to SBUF>>                             <<02801>>05878000
X := 15;                                                       <<02801>>05880000
while dxbz do                                                  <<02801>>05882000
  SBUFX(X) := PARM(X);                                         <<02801>>05884000
                                                               <<02801>>05886000
<<send message to IOMESSAGEPROC>>                              <<02801>>05888000
tos := 3;           <<message type 3>>                         <<02801>>05890000
tos := @SBUFX;      <<System buffer index>>                    <<02801>>05892000
tos := 0D;          <<double word dummy>>                      <<02801>>05894000
SENDMSG(IOMSGPROC/PCBSIZE,0,4,%40000); <<waken IOMSGPROC>>     <<02801>>05896000
IOMESSAGE := true;  <<successfully sent message>>              <<02801>>05898000
end;                                                           <<02801>>05900000
$PAGE "ISSUE'HARD'MSG MEMORY-RESIDENT MESSAGES"                <<03686>>05902000
procedure ISSUE'HARD'MSG(MSGNO,PARM,FLAGS);                    <<03686>>05904000
value MSGNO,PARM,FLAGS;                                        <<03686>>05906000
integer MSGNO,PARM;                                            <<03686>>05908000
logical FLAGS;                                                 <<03686>>05910000
option uncallable,privileged;                                  <<03686>>05912000
begin                                                          <<03686>>05914000
<<*********************************************************>>  <<03686>>05916000
<< This procedure attempts to send a message to the system >>  <<03686>>05918000
<< console.  If normal mechanism won't work, the MPE I/O   >>  <<03686>>05920000
<< message system will be bypassed and direct I/O to the   >>  <<03686>>05922000
<< system console will be attempted.                       >>  <<03686>>05924000
<<*********************************************************>>  <<03686>>05926000
<< The parameters are currently:                           >>  <<03686>>05928000
<< MSGNO      - A message number index into a PB-relative  >>  <<03686>>05930000
<<              array that contains the message that is to >>  <<03686>>05932000
<<              be printed at the system console.          >>  <<03686>>05934000
<<              To add a message, the EQUATE for HIGHEST'  >>  <<03686>>05936000
<<              MSGNO must be incremented and the actual   >>  <<03686>>05938000
<<              message added to the CASE statement.       >>  <<03686>>05940000
<< PARM       - An integer parm that is to be converted to >>  <<03686>>05942000
<<              decimal and placed in the message text.    >>  <<03686>>05944000
<< FLAGS      - Control information with the following     >>  <<03686>>05946000
<<              meaning:                                   >>  <<03686>>05948000
<<      (15:1)- If writing message in a non-destructive    >>  <<03686>>05950000
<<              manner fails, attempt methods that may     >>  <<03686>>05952000
<<              destroy the environment of the CONSOLE.    >>  <<03686>>05954000
<<      (14:1)- Set locally if write was successful        >>  <<03691>>05956000
<<      (13:1)- Do potentially destructive I/O to the      >>  <<03686>>05958000
<<              CONSOLE & don't attempt a non-destructive  >>  <<03686>>05960000
<<              write.  If bit 15 is set and non-destruc-  >>  <<03686>>05962000
<<              tive I/O fails, bit 13 will be turned-on by>>  <<03686>>05964000
<<              this procedure.                            >>  <<03686>>05966000
<<                                                         >>  <<03686>>05968000
<<  DB can be anywhere, can be called from anywhere.       >>  <<03694>>05970000
<<                                                         >>  <<03686>>05972000
<<*********************************************************>>  <<03686>>05974000
<< This procedure returns:                                 >>  <<03686>>05976000
<<            CCE if something got out                     >>  <<03686>>05978000
<<            CCL if nothing got out                       >>  <<03686>>05980000
<<*********************************************************>>  <<03686>>05982000
                                                               <<03686>>05984000
equate HIGHEST'MSGNO = 6,   << Currently, only 6 msgs >>       <<03686>>05986000
       SERIES'III    = 2,   << CPU number of S/III SPU >>      <<03691>>05988000
       MAX'WORDS     = 40;  << Maximum of 40 words text >>     <<03686>>05990000
                                                               <<03686>>05992000
define CONSLDEV = ABS(%1074)#; << SYSGLOB console ldev cell >> <<03694>>05994000
                                                               <<03694>>05996000
<< Stack required to perform an ATTACHIO is calculated by   >> <<03694>>05998000
<< MAX'WORDS+PCAL'OVRHD(14)+LOCAL'OVRHD(16)+ATTIO'OVHD(255) >> <<03694>>06000000
equate STACK'REQD = MAX'WORDS + 285;                           <<03694>>06002000
                                                               <<03694>>06004000
integer CPUNUM,          << CPU type executing on >>           <<03686>>06006000
        LENGTH,          << Length of message to display >>    <<03686>>06008000
        I,LOC;           << Utility integer for DCONVERT >>    <<03686>>06010000
                                                               <<03686>>06012000
logical LDEV'IS'LYNX,    << True if LYNX console  >>           <<03686>>06014000
        CONS'WAS'UP;     << Whether console is allocated >>    <<03686>>06016000
                                                               <<03686>>06018000
<< Q-relative variables to save stack environment >>           <<03691>>06020000
double DBBANK'DB;                                              <<03691>>06022000
integer DBBANK=DBBANK'DB,                                      <<03691>>06024000
        DBREGISTER=DBBANK+1,                                   <<03691>>06026000
        Q'REGISTER,                                            <<03691>>06028000
        Z'REGISTER,                                            <<03691>>06030000
        SBANK;                                                 <<03691>>06032000
                                                               <<03691>>06034000
integer LDEV,                                                  <<03686>>06036000
        DRTN;                                                  <<03686>>06038000
integer pointer DITP,                                          <<03686>>06040000
                DLTP;                                          <<03686>>06042000
pointer MSG;   << Dynamically allocated array to hold MSG >>   <<03691>>06044000
                                                               <<03691>>06046000
$PAGE "ISSUE'HARD'MSG SUPPORT SUBROUTINES"                     <<03686>>06048000
<< save a byte in B'MSG >>                                     <<03686>>06050000
subroutine SAVE'BYTE(VAL);                                     <<03691>>06052000
value VAL; integer VAL;                                        <<03691>>06054000
begin                                                          <<03691>>06056000
if logical(LOC) then  << Odd byte >>                           <<03691>>06058000
  MSG(LOC/2).(8:8) := VAL + "0"                                <<03691>>06060000
else                                                           <<03691>>06062000
  MSG(LOC/2).(0:8) := VAL + "0";                               <<03691>>06064000
LOC := LOC + 1;                                                <<03691>>06066000
end;                                                           <<03686>>06068000
                                                               <<03686>>06070000
<< Convert parameter to decimal and place in MSG array >>      <<03686>>06072000
<< at byte location LOC.                               >>      <<03686>>06074000
subroutine DCONVERT;                                           <<03686>>06076000
begin                                                          <<03686>>06078000
                                                               <<03686>>06080000
tos := PARM;  tos := 1000;                                     <<03686>>06082000
ASMB(div, xch);                                                <<03686>>06084000
                                                               <<03691>>06086000
if <> or PARM > 999 then                                       <<03691>>06088000
  SAVE'BYTE(*) else DEL;                                       <<03691>>06090000
tos := 100;                                                    <<03686>>06092000
ASMB(div, xch);                                                <<03686>>06094000
                                                               <<03691>>06096000
if <> or PARM > 99 then                                        <<03686>>06098000
  SAVE'BYTE(*) else DEL;                                       <<03691>>06100000
tos := 10;                                                     <<03686>>06102000
ASMB(div, xch);                                                <<03686>>06104000
                                                               <<03691>>06106000
if <> or PARM > 9 then                                         <<03691>>06108000
  SAVE'BYTE(*) else DEL;                                       <<03691>>06110000
                                                               <<03691>>06112000
SAVE'BYTE(*);                                                  <<03691>>06114000
end;   << of subroutine DCONVERT >>                            <<03686>>06116000
                                                               <<03686>>06118000
<< Convert a parameter at byte location LOC in array B'MSG >>  <<03686>>06120000
<< to OCTAL.                                               >>  <<03686>>06122000
subroutine OCONVERT;                                           <<03686>>06124000
begin                                                          <<03686>>06126000
                                                               <<03686>>06128000
tos := PARM;         << PARM to convert on tos >>              <<03691>>06130000
tos := 0;            << Shift word on tos      >>              <<03691>>06132000
tos := tos & dlsr(2);<< Set up for shift in loop >>            <<03691>>06134000
I := 6;                                                        <<03691>>06136000
do                                                             <<03691>>06138000
  begin                                                        <<03691>>06140000
  tos := tos & dcsl(3); << Move high-order 3-bits to tos >>    <<03691>>06142000
  SAVE'BYTE(*);                                                <<03691>>06144000
  tos := 0;             << Replace shift-in word >>            <<03691>>06146000
  I := I - 1;                                                  <<03691>>06148000
  end until =;          << Perform 6 times       >>            <<03691>>06150000
DDEL;                   << Remove stacked parms  >>            <<03691>>06152000
end;   << of subroutine OCONVERT >>                            <<03686>>06154000
                                                               <<03686>>06156000
<< This subroutine returns TRUE if the CST pointed to  >>      <<03686>>06158000
<< is non-existant OR is present in memory.            >>      <<03686>>06160000
logical subroutine CHECK'CST(CST'NUM);                         <<03686>>06162000
value CST'NUM;                                                 <<03686>>06164000
integer CST'NUM;                                               <<03686>>06166000
begin                                                          <<03686>>06168000
                                                               <<03686>>06170000
if CST'NUM = 0 then                                            <<03686>>06172000
  CHECK'CST := true                                            <<03686>>06174000
                                                               <<03686>>06176000
else                                                           <<03686>>06178000
                                                               <<03686>>06180000
  begin    << Extract CST number from LABEL and examine >>     <<03686>>06182000
  CST'NUM := integer(logical(CST'NUM) land %377);              <<03686>>06184000
  if CST'NUM <= 192 then       << not an XCST >>               <<03686>>06186000
    if integer(ABS(ABS(0) + (CST'NUM*4))) > 0 then             <<03686>>06188000
      CHECK'CST := true;   << Is in main memory >>             <<03686>>06190000
  end;                                                         <<03686>>06192000
end;   << of subroutine CHECK'CST >>                           <<03686>>06194000
                                                               <<03691>>06196000
<< See if SYSIOPROC's stack is present in memory >>            <<03691>>06198000
logical subroutine CHECK'SYSIO'STACK;                          <<03691>>06200000
begin                                                          <<03691>>06202000
                                                               <<03691>>06204000
X := PCB(SYSIOPCBP + PCB3).(1:10) & lsl(2); << Stk DST offset ><<03691>>06206000
if DST(X) > 0 then                                             <<03691>>06208000
  CHECK'SYSIO'STACK := true;  << Stack is present >>           <<03691>>06210000
end;                                                           <<03691>>06212000
                                                               <<03691>>06214000
<< Subroutine to set HARD'IO bit if SOFT'IO failed >>          <<03691>>06216000
subroutine SOFT'IO'FAILED;                                     <<03691>>06218000
begin                                                          <<03691>>06220000
if FLAGS then      << If HARD I/O permitted >>                 <<03691>>06222000
  FLAGS.(13:1) := 1;  << Do HARD I/O >>                        <<03691>>06224000
end;                                                           <<03691>>06226000
                                                               <<03691>>06228000
<< Subroutine to set DBBANK to SBANK >>                        <<03691>>06230000
subroutine SETDBBANK'TO'SBANK;                                 <<03691>>06232000
begin                                                          <<03691>>06234000
                                                               <<03691>>06236000
tos := SBANK;                                                  <<03691>>06238000
tos := DBREGISTER;   << Old DB register value >>               <<03694>>06240000
set(db);                                                       <<03691>>06242000
end;                                                           <<03691>>06244000
                                                               <<03691>>06246000
<< Subroutine to set DBBANK back to original >>                <<03691>>06248000
subroutine SETDBBANK'TO'ORIGINAL;                              <<03691>>06250000
begin                                                          <<03691>>06252000
                                                               <<03691>>06254000
tos := DBBANK'DB;                                              <<03691>>06256000
set(db);                                                       <<03691>>06258000
                                                               <<03691>>06260000
end;                                                           <<03691>>06262000
<< subroutine to set SYSDB >>                                  <<03691>>06264000
subroutine SETSYSDB;                                           <<03691>>06266000
begin                                                          <<03691>>06268000
                                                               <<03691>>06270000
tos := 0;                                                      <<03691>>06272000
tos := SYSDB;                                                  <<03691>>06274000
set(db);                                                       <<03691>>06276000
                                                               <<03691>>06278000
end;                                                           <<03691>>06280000
                                                               <<03691>>06282000
$PAGE                                                          <<03686>>06284000
<< Save old DB/DBBANK/SBANK >>                                 <<03691>>06286000
TRAPSOFF;                                                      <<03691>>06288000
PDISABLE;   << in case we're running on user's stack >>        <<03691>>06290000
push(sbank,db,z,q);                                            <<03691>>06292000
SBANK := tos;                                                  <<03691>>06294000
DBBANK'DB := tos;                                              <<03691>>06296000
Z'REGISTER := tos;                                             <<03691>>06298000
Q'REGISTER := tos;                                             <<03691>>06300000
                                                               <<03691>>06302000
<< Put DBBANK to SBANK for local storage allocation >>         <<03691>>06304000
SETDBBANK'TO'SBANK;                                            <<03691>>06306000
                                                               <<03691>>06308000
<< allocate local storage >>                                   <<03691>>06310000
@MSG := @S0 + 1;                                               <<03691>>06312000
tos := MAX'WORDS;                                              <<03691>>06314000
ASMB(adds 0);                                                  <<03691>>06316000
                                                               <<03691>>06318000
<< See if message number is valid >>                           <<03686>>06320000
FLAGS.(14:1) := 0;    << Set to return bad status >>           <<03691>>06322000
if not (0<=MSGNO<=HIGHEST'MSGNO) then                          <<03686>>06324000
  begin   << Invalid message number >>                         <<03686>>06326000
                                                               <<03691>>06328000
  go to EXIT;                                                  <<03686>>06330000
  end;                                                         <<03686>>06332000
                                                               <<03686>>06334000
<< Save CPU number >>                                          <<03686>>06336000
ASMB(pcn);                                                     <<03686>>06338000
CPUNUM := tos;                                                 <<03686>>06340000
                                                               <<03686>>06342000
<< Turn-on flag if LYNX >>                                     <<03686>>06344000
if CPUNUM > SERIES'III and   << This is a HP-IB system >>      <<03691>>06346000
   CHANNEL'ID(CONSLDEV) = LYNX'TYPE then                       <<03686>>06348000
  LDEV'IS'LYNX := true                                         <<03686>>06350000
else                                                           <<03686>>06352000
  LDEV'IS'LYNX := false;                                       <<03686>>06354000
                                                               <<03686>>06356000
<<***************************************************>>        <<03686>>06358000
<< This section of code is always executed.  If flags>>        <<03686>>06360000
<< 15:1 is set, section III will be executed if sec. >>        <<03686>>06362000
<< II's ATTACHIO fails.                              >>        <<03686>>06364000
<<                                                   >>        <<03686>>06366000
<<      S E C T I O N   I                            >>        <<03686>>06368000
<<                                                   >>        <<03686>>06370000
<<***************************************************>>        <<03686>>06372000
<< move message to DB array & format it >>                     <<03686>>06374000
case *MSGNO of                                                 <<03686>>06376000
  begin                                                        <<03686>>06378000
                                                               <<03686>>06380000
<< 0 >> begin    << Not ready message >>                       <<03686>>06382000
        move MSG := (CRLF,"LDEV #     NOT READY",CRLF,%3407),2;<<03686>>06386000
        LENGTH := tos - @MSG;  << Length of text >>            <<03686>>06388000
        LOC := 8;              << Byte loc of number >>        <<03686>>06390000
        DCONVERT;              << Put in LDEV number >>        <<03686>>06392000
        end;                                                   <<03686>>06394000
                                                               <<03686>>06396000
<< 1 >> begin    << Disc not responding message >>             <<03686>>06398000
        move MSG := (CRLF,                                     <<03686>>06400000
        "DISC LDEV #    NOT RESPONDING TO I/O",CRLF,%3407),2;  <<03686>>06402000
        LENGTH := tos - @MSG;                                  <<03686>>06404000
        LOC := 13;         << Byte loc of number in B'MSG >>   <<03686>>06406000
        DCONVERT;          << Put in LDEV number >>            <<03686>>06408000
        end;                                                   <<03686>>06410000
                                                               <<03686>>06412000
<< 2 >> begin    << Powerfail message >>                       <<03686>>06414000
        move MSG := (CRLF,"*** POWERFAIL ***",CRLF,%3407),2;   <<03686>>06416000
        LENGTH := tos - @MSG;                                  <<03686>>06418000
        end;                                                   <<03686>>06420000
                                                               <<03686>>06422000
<< 3 >> begin   << Non-responding DRT >>                       <<03686>>06424000
        move MSG:=(CRLF,"NON-RESPONDING DRT #   ",CRLF),2;     <<03686>>06426000
        LENGTH := tos-@MSG;                                    <<03686>>06428000
        LOC := 22;                                             <<03686>>06430000
        DCONVERT;                                              <<03686>>06432000
        end;                                                   <<03686>>06434000
                                                               <<03686>>06436000
<< 4 >> begin   << SUDDENDEATH >>                              <<03686>>06438000
        move MSG:=(CRLF,CRLF,"**** SYSTEM FAILURE #    "),2;   <<03686>>06440000
        LENGTH := tos-@MSG;                                    <<03686>>06442000
        LOC := 25;                                             <<03686>>06444000
        DCONVERT;                                              <<03686>>06446000
        end;                                                   <<03686>>06448000
                                                               <<03686>>06450000
<< 5 >> begin   << SUDDENDEATH >>                              <<03686>>06452000
        move MSG:=(CRLF,"STATUS %      "),2;                   <<03686>>06454000
        LENGTH := tos - @MSG;                                  <<03686>>06456000
        LOC := 10;                                             <<03686>>06458000
        OCONVERT;                                              <<03686>>06460000
        end;                                                   <<03686>>06462000
                                                               <<03686>>06464000
<< 6 >> begin   << SUDDENDEATH >>                              <<03686>>06466000
        move MSG := (CRLF,"DELTA-P %       "),2;               <<03686>>06468000
        LENGTH := tos - @MSG;                                  <<03686>>06470000
        LOC := 11;                                             <<03686>>06472000
        OCONVERT;                                              <<03686>>06474000
        end;                                                   <<03686>>06476000
                                                               <<03686>>06478000
  end;   << of case on MSGNO >>                                <<03686>>06480000
                                                               <<03686>>06482000
                                                               <<03691>>06484000
                                                               <<03686>>06486000
                                                               <<03686>>06488000
<<***************************************************>>        <<03686>>06490000
<< This section is performed only if FLAGS.(13:1) is >>        <<03686>>06492000
<< NOT true.  This is the normal "SOFT" type I/O done>>        <<03686>>06494000
<< to the console via ATTACHIO which hopefully will  >>        <<03686>>06496000
<< NOT lock up the console port.                     >>        <<03686>>06498000
<<              S E C T I O N   I I                  >>        <<03686>>06500000
<<                                                   >>        <<03686>>06502000
<<***************************************************>>        <<03686>>06504000
                                                               <<03686>>06506000
if not FLAGS.(13:1) and  << HARD I/O not requested >>          <<03691>>06508000
                                                               <<03686>>06510000
   (Z'REGISTER-Q'REGISTER) > STACK'REQD then <<ATTIO space >>  <<03694>>06512000
  << At this point, we will try to write a non-destructive >>  <<03686>>06514000
  << message if at all possible.                           >>  <<03686>>06516000
                                                               <<03686>>06518000
  begin                                                        <<03686>>06520000
                                                               <<03686>>06522000
  SETSYSDB;   << Point DB to I/O system >>                     <<03691>>06524000
                                                               <<03691>>06526000
  @DITP := LPDT(CONSLDEV*2);  << Console's DIT pointer >>      <<03686>>06528000
  @DLTP := DITP(DDLTP);       << Driver linkage table  >>      <<03686>>06530000
                                                               <<03686>>06532000
  if LDEV'IS'LYNX or          << LYNX is always resident >>    <<03686>>06534000
     << See if console's monitor and initiator are present >>  <<03686>>06536000
     CHECK'CST(DLTP(DMNTR)) and CHECK'CST(DLTP(DINIT)) and     <<03691>>06538000
     CHECK'SYSIO'STACK then    << SYSIOPROC stack is present >><<03691>>06540000
    begin                                                      <<03686>>06542000
    I := GETSBUF(2);                                           <<03686>>06544000
    if I = 0 then                                              <<03686>>06546000
      begin   << Failed to get a system buffer >>              <<03686>>06548000
      SOFT'IO'FAILED;                                          <<03691>>06550000
                                                               <<03691>>06552000
      end                                                      <<03686>>06554000
    else                                                       <<03686>>06556000
      begin  << Got a system buffer, move data to it >>        <<03686>>06558000
      LOC := I - WA0(SYSSBUF); << DST offset in system bufs >> <<03694>>06560000
                                                               <<03694>>06562000
      SETDBBANK'TO'SBANK;                                      <<03691>>06564000
      tos := 8;            << SBUF DST number >>               <<03691>>06566000
      tos := LOC;   << SYSBUF DST offset >>                    <<03694>>06568000
      tos := @MSG;         << Source DB address >>             <<03691>>06570000
      tos := LENGTH;                                           <<03691>>06572000
      ASMB(mtds 4);   << Move data to system buffer >>         <<03691>>06574000
      SETSYSDB;                                                <<03691>>06576000
                                                               <<03691>>06578000
      << * * Do the ATTACHIO * * >>                            <<03694>>06580000
                                                               <<03686>>06582000
      << See if console isn't allocated >>                     <<03686>>06584000
      if DITP.(1:1) <> 0 then                                  <<03686>>06586000
        CONS'WAS'UP := true  << DIT is allocated >>            <<03686>>06588000
      else                                                     <<03686>>06590000
        begin   << We must allocate DIT >>                     <<03686>>06592000
        CONS'WAS'UP := false;                                  <<03686>>06594000
        ATTACHIO(CONSLDEV,0,0,0,24,0,0,0,%407);                <<03686>>06596000
        end;                                                   <<03686>>06598000
                                                               <<03686>>06600000
      tos := ATTACHIO(CONSLDEV,0,0,LOC,1,LENGTH,0,0,           <<03686>>06602000
             %417);  << Hard-preempt,SBUF,no impede,sec IOQ >> <<03686>>06604000
      if tos = 0D then                                         <<03686>>06606000
        begin   << ATTACHIO failed >>                          <<03686>>06608000
        SOFT'IO'FAILED;                                        <<03691>>06610000
                                                               <<03691>>06612000
        RETURNSBUF(I);  << Return system buffer >>             <<03686>>06614000
        end                                                    <<03691>>06616000
      else                                                     <<03691>>06618000
        FLAGS.(14:1) := 1;  << I/O succeeded >>                <<03691>>06620000
                                                               <<03686>>06622000
      << If we allocated console, we must now UNDO it. >>      <<03686>>06624000
      if not CONS'WAS'UP then                                  <<03686>>06626000
        ATTACHIO(CONSLDEV,0,0,0,4,0,0,0,%407);                 <<03686>>06628000
                                                               <<03686>>06630000
      end;  << ATTACHIO was successful >>                      <<03686>>06632000
    end                                                        <<03686>>06634000
  else                                                         <<03686>>06636000
    SOFT'IO'FAILED;                                            <<03691>>06638000
                                                               <<03691>>06640000
  SETDBBANK'TO'SBANK;                                          <<03691>>06642000
  end                                                          <<03691>>06644000
else                                                           <<03691>>06646000
  SOFT'IO'FAILED;  << Not enough tos for ATTACHIO >>           <<03691>>06648000
                                                               <<03686>>06650000
<<*********************************************************>>  <<03686>>06652000
<< This section is done only if FLAGS.(13:1) is set. LYNX  >>  <<03686>>06654000
<< is currently the only type of device where we have to   >>  <<03686>>06656000
<< worry about destroying the environment.                 >>  <<03686>>06658000
<<                                                         >>  <<03686>>06660000
<<            S E C T I O N   I I I                        >>  <<03686>>06662000
<<                                                         >>  <<03686>>06664000
<<*********************************************************>>  <<03686>>06666000
                                                               <<03686>>06668000
<< Now, see if ATTACHIO failed to LYNX.  If so and flags >>    <<03686>>06670000
<< permit, cram info out to LYNX console.                >>    <<03686>>06672000
if FLAGS.(13:1) then   << Forced I/O is permitted        >>    <<03686>>06674000
    begin                                                      <<03686>>06676000
    for I := 0 until LENGTH-1 do                               <<03758>>06678000
      begin                                                    <<03758>>06680000
      tos := MSG(I);                                           <<03758>>06682000
      SETSYSDB;                                                <<03758>>06684000
      WRITE2(*);                                               <<03758>>06686000
      SETDBBANK'TO'SBANK;                                      <<03758>>06688000
      end;                                                     <<03758>>06690000
                                                               <<03758>>06692000
    FLAGS.(14:1) := 1;  << I/O succeeded >>                    <<03691>>06694000
    end;                                                       <<03686>>06696000
                                                               <<03686>>06698000
                                                               <<03691>>06700000
                                                               <<03686>>06702000
EXIT:                                                          <<03686>>06704000
                                                               <<03686>>06706000
RSTATUS.CC := if FLAGS.(14:1) then CCE else CCL;               <<03691>>06708000
                                                               <<03691>>06710000
SETDBBANK'TO'ORIGINAL;                                         <<03691>>06712000
                                                               <<03691>>06714000
PENABLE;                                                       <<03691>>06716000
end;   << of procedure >>                                      <<03686>>06718000
$PAGE "LDEVNOTRDY"                                             <<03686>>06720000
procedure LDEVNOTRDY(DITP);                                    <<03686>>06722000
integer array DITP;                                            <<03686>>06724000
option uncallable,privileged;                                  <<03686>>06726000
                                                               <<03686>>06728000
<< DB must be at SYSDB >>                                      <<03686>>06730000
<<*************************************************>>          <<03730>>06732000
<< This procedure sends a message to IOMSGPROC to  >>          <<03730>>06734000
<< print the LDEV #  NOT READY on the system cons. >>          <<03730>>06736000
<< DB must be pointing to SYSDB when calling this  >>          <<03730>>06738000
<< procedure.  The condition codes returned are:   >>          <<03730>>06740000
<<         CCE - MSG has been scheduled            >>          <<03730>>06742000
<<         CCL - MSG could not be scheduled        >>          <<03730>>06744000
<< If this device is disc, an optional message will>>          <<03730>>06746000
<< be printed on the console in case the device    >>          <<03730>>06748000
<< that is not ready is the system disc.           >>          <<03730>>06750000
<<*************************************************>>          <<03730>>06752000
                                                               <<03730>>06754000
begin                                                          <<03730>>06756000
                                                               <<03686>>06758000
integer ENTRY'TYPE    = q+1;                                   <<03686>>06760000
integer pointer IOQP  = q+2;                                   <<03686>>06762000
integer LDEV          = q+3;                                   <<03686>>06764000
logical FLAGS         = q+4;                                   <<03686>>06766000
                                                               <<03686>>06768000
entry DISC'NOT'RESP;                                           <<03686>>06770000
                                                               <<03686>>06772000
<< Normal entry, device not ready >>                           <<03686>>06774000
tos := 0;          << MSG type 0 - device not ready >>         <<03686>>06776000
go to START;                                                   <<03686>>06778000
                                                               <<03686>>06780000
DISC'NOT'RESP:                                                 <<03686>>06782000
                                                               <<03686>>06784000
tos := 1;          << MSG type 1 - disc device not responding ><<03686>>06786000
                                                               <<03686>>06788000
START:                                                         <<03686>>06790000
                                                               <<03686>>06792000
<< Get IOQ pointer from DIT >>                                 <<03686>>06794000
tos := DITP(DIOQP);                                            <<03686>>06796000
                                                               <<03686>>06798000
<< If no IOQ, get the LDEV from the DIT >>                     <<03686>>06800000
tos := if <> then IOQP(QLDEV).QLDEVN                           <<03686>>06802000
       else                                                    <<03686>>06804000
         DITP(DLDEV).DLDEVN;                                   <<03686>>06806000
                                                               <<03686>>06808000
<< Initialize FLAGS word >>                                    <<03686>>06810000
tos := 0;   << Only try ATTACHIO >>                            <<03691>>06812000
                                                               <<03686>>06814000
<< Now, put the message on the console >>                      <<03686>>06816000
if DITP.TDFLAGS = 1 then   << If this is a DISC >>             <<03730>>06818000
ISSUE'HARD'MSG(ENTRY'TYPE,LDEV,FLAGS);                         <<03694>>06820000
                                                               <<03686>>06822000
<< Call GENMESSAGE to log the information >>                   <<03691>>06826000
if                                                             <<03730>>06828000
IOMESSAGE(1,NOTRDYMSG,%10000,LDEV,,,,,OPCONSOLE) then          <<03730>>06830000
  RSTATUS.CC := CCE                                            <<03730>>06832000
else                                                           <<03730>>06834000
  RSTATUS.CC := CCL;                                           <<03730>>06836000
                                                               <<03730>>06838000
end;   << of procedure >>                                      <<03686>>06840000
$PAGE  "CORE RESIDENT I/O SERVICE ROUTINES"                             06842000
                                                                        06844000
PROCEDURE ADDTAIL(NEW,LINKINDEX,QUEUENUMBER);                           06846000
  VALUE   LINKINDEX, QUEUENUMBER;                                       06848000
  INTEGER LINKINDEX, QUEUENUMBER;                                       06850000
  INTEGER ARRAY NEW;                                                    06852000
  OPTION UNCALLABLE, PRIVILEGED;                                        06854000
                                                                        06856000
  <<                                                                    06858000
    ADDS ELEMENT NEW TO THE END OF THE I/O RESOURCE QUEUE. IF THE       06860000
    ELEMENT IS ALREADY IN A QUEUE, IT IS NOT ADDED.                     06862000
  >>                                                                    06864000
  BEGIN                                                                 06866000
    DISABLE;                                                            06868000
    TOS := NEW(LINKINDEX);                                              06870000
    IF = THEN   << NOT IN A QUEUE >>                                    06872000
      BEGIN                                                             06874000
        NEW(LINKINDEX) := -1;   << INDICATE IN A QUEUE >>               06876000
        TOS := HEAD(QUEUENUMBER);                                       06878000
        IF < THEN HEAD(QUEUENUMBER) := @NEW  << EMPTY QUEUE >>          06880000
          ELSE WA0(TAIL(QUEUENUMBER)+LINKINDEX) := @NEW;                06882000
        TAIL(QUEUENUMBER) := @NEW;                                      06884000
      END;                                                              06886000
  END;    <<  ADD TAIL >>                                               06888000
                                                                        06890000
PROCEDURE ADDHEAD(NEW,LINKINDEX,QUEUENUMBER);                           06892000
  VALUE   LINKINDEX, QUEUENUMBER;                                       06894000
  INTEGER LINKINDEX, QUEUENUMBER;                                       06896000
  INTEGER ARRAY NEW;                                                    06898000
  OPTION UNCALLABLE, PRIVILEGED;                                        06900000
                                                                        06902000
  <<                                                                    06904000
    ADDS ELEMENT NEW TO THE BEGINING OF THE I/O RESOURCE QUEUE. IF THE  06906000
    ELEMENT IS ALREADY IN A QUEUE, IT IS NOT ADDED.                     06908000
  >>                                                                    06910000
  BEGIN                                                                 06912000
    DISABLE;                                                            06914000
    TOS := NEW(LINKINDEX);                                              06916000
    IF = THEN   << NOT IN A QUEUE >>                                    06918000
      BEGIN                                                             06920000
        TOS := HEAD(QUEUENUMBER);                                       06922000
        IF < THEN TAIL(QUEUENUMBER) := @NEW;  << EMPTY QUEUE >>         06924000
        NEW(LINKINDEX) := TOS;   << LINK REST OF LIST TO THIS >>        06926000
        HEAD(QUEUENUMBER) := @NEW;  << LINK IN THIS >>                  06928000
      END;                                                              06930000
  END;   << ADD HEAD >>                                                 06932000
                                                                        06934000
INTEGER PROCEDURE DEQUEUE(LINKINDEX,QUEUENUMBER);                       06936000
  VALUE LINKINDEX, QUEUENUMBER;   INTEGER LINKINDEX, QUEUENUMBER;       06938000
  OPTION UNCALLABLE, PRIVILEGED;                                        06940000
                                                                        06942000
  <<                                                                    06944000
      REMOVES THE FIRST ELEMENT IN AN I/O RESOUCE QUEUE AND RETURNS     06946000
      RETURNS THE DIT POINTER.  IF QUEUE IS EMPTY -1 IS RETURNED.       06948000
  >>                                                                    06950000
  BEGIN                                                                 06952000
    DISABLE;                                                            06954000
    TOS := HEAD(QUEUENUMBER);                                           06956000
    X := S0;    DEQUEUE := TOS;                                         06958000
    IF > THEN   << SOMETHING IN THE QUEUE >>                            06960000
      BEGIN                                                             06962000
        X := LINKINDEX + X;                                             06964000
        TOS := WA0(X);   << GET LINK TO NEXT ELEMENT >>                 06966000
        WA0(X) := 0;   << CLEAR LINK OF GOTTEN ELEMENT >>               06968000
        HEAD(QUEUENUMBER) := TOS;     << LINK IN REST OF LIST >>        06970000
      END;                                                              06972000
  END;    << DEQUEUE >>                                                 06974000
$PAGE " PROCEDURE CHECKLDEV  .... IN INCLHARD "                         06976000
<<===========CHECKLDEV=============>><< SPLIT STACK CALLS OK >><<03031>>06978000
                                                               <<03031>>06980000
PROCEDURE CHECKLDEV(LDEV);                                     <<03031>>06982000
VALUE LDEV;INTEGER LDEV;                                       <<03031>>06984000
OPTION PRIVILEGED,UNCALLABLE;                                  <<03031>>06986000
                                                               <<03031>>06988000
<< THIS PROCEDURE CHECKS THAT LDEV IS A VALID LOGICAL DEVICE >><<03031>>06990000
<< ( I.E. LDEV < LPDT MAXENTRY AND LPDT DITP > 0 AND LDEV IN >><<03031>>06992000
<< DIT MATCHES LDEV ).  ALSO INDICATES IF DEVICE IS A DISC   >><<03031>>06994000
<< ( I.E. DIT0.(0:2)=1 ) OR A TERMINAL ( I.E. DIT0.(0:1)=1 ) >><<03031>>06996000
                                                               <<03031>>06998000
<<   RETURNS:  CCL - INVALID LDEV                            >><<03031>>07000000
<<             CCG - VALID TERMINAL                          >><<03031>>07002000
<<             CCE - VALID LDEV - IF CARRY THEN A DISC       >><<03031>>07004000
                                                               <<03031>>07006000
BEGIN                                                          <<03031>>07008000
                                                               <<03031>>07010000
  DEFINE MAXLDEV     = S'LPDT(0).MAXENTRY#,                    <<03031>>07012000
         LDEVDITP    = S'LPDT(LDEV&LSL(1))#,                   <<03031>>07014000
         DITLDEVN    = ABS(LDEVDITP+SYSDB+DLDEV).DLDEVN#,      <<03031>>07016000
         DITTDFLD    = ABS(LDEVDITP+SYSDB).TDFLAGS#;           <<03031>>07018000
                                                               <<03031>>07020000
  IF 1<=LDEV<=MAXLDEV AND LDEVDITP>0 THEN                      <<03686>>07022000
    IF (X:=DITTDFLD)>1 THEN RSTATUS.CCC:=CCG                   <<03031>>07024000
    ELSE RSTATUS.CCC:=X&LSL(2)+CCE                             <<03031>>07026000
  ELSE RSTATUS.CCC:=CCL;    << RETURN INVALID LDEV CONDITION >><<03031>>07028000
                                                               <<03031>>07030000
END;    << CHECK LDEV >>                                       <<03031>>07032000
$PAGE  "    PROCEDURE IOFAILURE   ....   IN INCLHARD  "                 07034000
                                                                        07036000
PROCEDURE IOFAILURE(DRTN,DITP);                                         07038000
  VALUE DRTN;  INTEGER DRTN;                                            07040000
  ARRAY DITP;  OPTION UNCALLABLE, PRIVILEGED;                           07042000
  <<                                                                    07044000
    THIS PROCEDURE OUTPUTS THE MESSAGE "NON RESPONDING DEVICE           07046000
    DRT XXX, LDEV YYY" AND CALL SUDDENDEATH 201                         07048000
    IF THE FAILURE OCCURED ON THE CONSOLE, A HALT %15 IS DONE.          07050000
  >>                                                                    07052000
  BEGIN                                                                 07054000
    INTEGER LDEV;                                                       07056000
                                                                        07058000
    DISABLE;                                                            07062000
    X := @DITP;                                                         07064000
    LDEV := IF <> THEN WA0(X:=X+DLDEV).DLDEVN ELSE 0; << SET LDEV >>    07066000
    TOS := DOUBLE(SYSDB);    XCHDB;   << SET TO SYSDB >>                07068000
                                                                        07070000
    IF LDEV=CONSLDEV THEN ASMB(HALT %15);  << IO FAILURE ON CONSOLE >>  07072000
                                                                        07074000
  ISSUE'HARD'MSG(3,DRTN,%4); << NON-RESP DRT MSG >>            <<03686>>07076000
                                                                        07080000
    SUDDENDEATH(201);                                                   07082000
  END;     << I/O FAILURE >>                                            07084000
$PAGE   "     PROCEDURE LDEVTOTYPE   ... IN INCLHARD  "                 07086000
                                                                        07088000
<<==========LDEVTOTYPE=============>><< SPLIT STACK CALLS OK >><<03031>>07090000
                                                               <<03031>>07092000
INTEGER PROCEDURE LDEVTOTYPE(LDEV);                            <<03031>>07094000
VALUE LDEV;  INTEGER LDEV;                                     <<03031>>07096000
OPTION PRIVILEGED,UNCALLABLE;                                  <<03031>>07098000
                                                               <<03031>>07100000
<< THIS PROCEDURE CHECKS THAT LDEV IS A VALID LOGICAL DEVICE >><<03031>>07102000
<< CHECKS FOR VALID LDEV AND RETURNS DEVICE TYPE LDT2.(10:6) >><<03031>>07104000
<< IF BIT 0 OF LDEV IS SET / THEN RETURNS.(0:8) = LDT3.(0:8) >><<03031>>07106000
                                                               <<03031>>07108000
<<   RETURNS  CCL   = INVALID LDEV PSEUDO DEVICE             >><<03031>>07110000
<<            CCE   = VALID REAL DEVICE                      >><<03031>>07112000
<<            CARRY = DEVICE IS A DISC                       >><<03031>>07114000
BEGIN                                                          <<03031>>07116000
                                                               <<03031>>07118000
  INTEGER TYPEWORD,LDTFLAGS,OLDDB;                             <<03031>>07120000
  EQUATE  LDTDST   = 14,                                       <<03031>>07122000
          LDTSIZE  =  5,                                       <<03031>>07124000
          TOFFSET  =  2;                                       <<03031>>07126000
  DEFINE  FLAGFLD  = ( 0:8)#,                                  <<03031>>07128000
          SPECLREQ =LOGICAL(LDEV.(0:1))#,                      <<03031>>07130000
          DEV      =INTEGER(LDEV.(1:15))#;                     <<03031>>07132000
                                                               <<03031>>07134000
  CHECKDB;                                                     <<03031>>07136000
  IF <> THEN OLDDB:=EXCHANGEDB(0)                              <<03031>>07138000
        ELSE OLDDB:=0;                                         <<03031>>07140000
  CHECKLDEV(DEV);               << CHECK LDEV IS VALID & REAL>><<03031>>07142000
  IF < THEN                                                    <<03031>>07144000
  RSTATUS.CCC:=CCL              << CCL   = LDEV IS NOT VALID >><<03031>>07146000
  ELSE                          << CCE   = VALID RETURN DATA >><<03031>>07148000
  BEGIN                         << CARRY = DEVICE IS A DISC  >><<03031>>07150000
    RSTATUS.CCC:=(IF CARRY THEN 6 ELSE CCE);                   <<03031>>07152000
    TOS:=@TYPEWORD;                                            <<03031>>07154000
    TOS:=LDTDST;                                               <<03031>>07156000
    TOS:=DEV*LDTSIZE+TOFFSET;                                  <<03031>>07158000
    TOS:=2;                             << GET LDT2 AND LDT3 >><<03031>>07160000
    ASSEMBLE(MFDS 4);                                          <<03031>>07162000
    LDEVTOTYPE:=TYPEWORD.DEVTYPEF;                             <<03031>>07164000
    IF SPECLREQ THEN                       <<FOR SPECIAL REQ.>><<03031>>07166000
    LDEVTOTYPE.FLAGFLD:=LDTFLAGS.FLAGFLD;  <<INCLD LDT3.(0:8)>><<03031>>07168000
  END;                                                         <<03031>>07170000
  IF OLDDB<>0 THEN EXCHANGEDB(OLDDB);                          <<03031>>07172000
END;    << LDEVTOTYPE >>                                       <<03031>>07174000
                                                               <<03031>>07176000
<<=========LDEVTOSUBTYPE===========>><< SPLIT STACK CALLS OK >><<03031>>07178000
                                                               <<03031>>07180000
INTEGER PROCEDURE LDEVTOSUBTYPE(LDEV);                         <<03031>>07182000
VALUE LDEV; INTEGER LDEV;                                      <<03031>>07184000
OPTION PRIVILEGED,UNCALLABLE;                                  <<03031>>07186000
BEGIN                                                          <<03031>>07188000
                                                               <<03031>>07190000
  CHECKLDEV(LDEV);              << CHECK LDEV IS VALID & REAL>><<03031>>07192000
  IF < THEN                                                    <<03031>>07194000
  RSTATUS.CCC:=CCL              << CCL   = LDEV IS NOT VALID >><<03031>>07196000
  ELSE                          << CCE   = VALID RETURN DATA >><<03031>>07198000
  BEGIN                         << CARRY = DEVICE IS A DISC  >><<03031>>07200000
    RSTATUS.CCC:=(IF CARRY THEN 6 ELSE CCE);                   <<03031>>07202000
    LDEVTOSUBTYPE:=S'LPDT(LDEV&LSL(1)+1).SUBTYPEF              <<03031>>07204000
  END;                                                         <<03031>>07206000
END;                                                           <<03031>>07208000
                                                               <<03031>>07210000
INTEGER PROCEDURE LDEVTODRT(LDEV);                             <<03031>>07212000
  VALUE LDEV;                                                  <<03031>>07214000
  INTEGER LDEV;                                                <<03031>>07216000
 option privileged,uncallable;                                 <<03031>>07218000
  BEGIN                                                        <<03031>>07220000
  INTEGER POINTER LPDT=%10;                                    <<03031>>07222000
                                                               <<03031>>07224000
  COMMENT - THIS PROCEDURE ACCEPTS LDEV AND RETURNS:           <<03031>>07226000
          (0:7) -- UNIT                                        <<03031>>07228000
          (7:9) -- DRT NUMBER ;                                <<03031>>07230000
                                                               <<03031>>07232000
   IF ( 1 <= LDEV <= LPDT(0).(0:8) ) AND                       <<03031>>07234000
      <<  CHECK TO SEE IF THIS DEVICE HAS A DS PSEUDO DRT >>   <<04302>>07236000
      <<  0 MEANS NOT A DS DEVICE, -2 MEANS NO DS ON SYSTEM >> <<04302>>07238000
      <<  HOPEFULLY SOME DAY GET'DSDEVICE WILL BECOME       >> <<04302>>07240000
      <<  GET'DATACOM'DEVICE AND CHECK FOR ALL DATACOM      >> <<04302>>07242000
      <<  PSEUDO DEVICES.                          >>          <<04302>>07244000
                                                               <<04302>>07246000
      ((0 = GET'DSDEVICE(LDEV)) OR (GET'DSDEVICE(LDEV) = -2))  <<04302>>07248000
       AND                                                     <<04302>>07250000
      ( X := LPDT(LDEV*LPDTSIZE) ) > 0 THEN << DITP IF > 0 >>  <<03031>>07252000
                                        << SPOOLED IF <= 0 >>  <<03031>>07254000
      BEGIN                                                    <<03031>>07256000
      TOS := ABS(X+SYSDB+DLDEV) LAND %037400;     << UNIT >>   <<03031>>07258000
      TOS:=TOS&LSL(1);<<SHIFT LEFT 1,MAKE ROOM FOR DRT>>       <<03031>>07260000
      TOS.DRTNUMBER:= ABS(ABS(X+DILTP-DLDEV)+SYSDB+ICNTRL);    <<03031>>07262000
                                      <<DRT NUMBER>>           <<03031>>07264000
      END                                                      <<03031>>07266000
   ELSE TOS := 0;  << ILLEGAL LDEV OR VIRTUAL DEVICE >>        <<03031>>07268000
   LDEVTODRT := TOS;                                           <<03031>>07270000
   END;                                                        <<03031>>07272000
$PAGE                                                                   07274000
                                                                        07276000
$PAGE "SOFT'DEATH"                                                      07278000
PROCEDURE SOFT'DEATH (ID'NUMBER);                                       07280000
   VALUE ID'NUMBER;                                                     07282000
   INTEGER ID'NUMBER;                                                   07284000
                                                                        07286000
   OPTION PRIVILEGED,UNCALLABLE;                                        07288000
                                                                        07290000
<<=======================================================               07292000
                                                                        07294000
      This procedure is an interface to SUDDENDEATH.                    07296000
   There is a flag in SYSGLOB, word %350 (absolute %1350),              07298000
   bit 15, which, if set to one, will tell SOFT'DEATH to call           07300000
   crash the system.  If the flag is zero, the id'number passed         07302000
   along with the status and delta-P from the stack marker will         07304000
   be logged with MMSTAT.                                               07306000
                                                                        07308000
   Parameters:                                                          07310000
      ID'NUMBER - Number to be passed to SUDDENDEATH or MMSTAT.         07312000
                                                                        07314000
   Assumptions on entry:                                                07316000
      None, DB can be anywhere.                                         07318000
                                                                        07320000
   Exit conditions:                                                     07322000
      DB is unchanged.                                                  07324000
                                                                        07326000
   Fix i.d.                                                             07328000
      The fix i.d. on the procedure header applies to the entire        07330000
      procedure.                                                        07332000
                                                                        07334000
=======================================================>>               07336000
                                                                        07338000
BEGIN                                                          <<03526>>07340000
                                                               <<03526>>07342000
   << Low core flag, if 1 then call SUDDENDEATH >>             <<03526>>07344000
                                                               <<03526>>07346000
   DEFINE CRASH'ON'SOFT'DEATH = ABSOLUTE (%1350).(15:1)#;      <<03526>>07348000
                                                               <<03526>>07350000
   << Info from stack marker >>                                <<03526>>07352000
                                                               <<03526>>07354000
   INTEGER DELTA'P = Q-2;                                      <<03526>>07356000
   INTEGER STATUS'REG  = Q-1;                                  <<03526>>07358000
                                                               <<03526>>07360000
   << Event number for MMSTAT >>                               <<03526>>07362000
                                                               <<03526>>07364000
   EQUATE SOFT'DEATH'EVENT = 120;                              <<03526>>07366000
                                                               <<03526>>07368000
   << - - - - - - - - - >>                                     <<03526>>07370000
                                                               <<03526>>07372000
   IF CRASH'ON'SOFT'DEATH THEN                                 <<03526>>07374000
      SUDDENDEATH (ID'NUMBER)                                  <<03526>>07376000
   ELSE                                                        <<03526>>07378000
     MMSTAT (SOFT'DEATH'EVENT, ID'NUMBER, STATUS'REG, DELTA'P);<<03526>>07380000
                                                               <<03526>>07382000
END;   << SOFT'DEATH >>                                        <<03526>>07384000
                                                               <<03526>>07386000
                                                               <<03526>>07388000
                                                               <<03526>>07390000
$PAGE "  PROCEDURE SUDDENDEATH .... IN INCLHARD   "            <<03526>>07392000
PROCEDURE SUDDENDEATH( N);                                              07394000
  VALUE N;  INTEGER N;                                                  07396000
  OPTION UNCALLABLE, PRIVILEGED;                                        07398000
  <<                                                                    07400000
     OUTPUTS THE SYSTEM HALT MESSAGE WITH THE DECIMAL NUMBER N          07402000
  >>                                                                    07404000
<<***********************************************>>            <<03694>>07406000
<< SUDDENDEATH will attempt to save the environ- >>            <<03694>>07408000
<< ment of the CONSOLE DRT by saving it on TOS   >>            <<03694>>07410000
<< before PRINTCHAR gets hold of it.  When read- >>            <<03694>>07412000
<< ing dumps, the locations in this procedure    >>            <<03694>>07414000
<< will be:                                      >>            <<03694>>07416000
<<           Q+1       - DRT number of console   >>            <<03694>>07418000
<<           Q+2/5     - 4 words of console DRT  >>            <<03694>>07420000
<<***********************************************>>            <<03694>>07422000
  BEGIN                                                                 07424000
    INTEGER DELTAP = Q-2;     << DELTA P IN STACK MARKER >>             07426000
  integer DRTN        = q+1;   << DRT # of console >>          <<03694>>07428000
                                                               <<03694>>07430000
  integer pointer LPDT'S = %10; << System table LPDT >>        <<03694>>07432000
                                                               <<03694>>07434000
  define CONSLDEV = ABS(%1074)#; << Console LDEV # >>          <<03694>>07436000
                                                                        07438000
    TRAPSOFF;  << TURN OFF TRAPS >>                            <<03526>>07442000
    DISABLE;                                                            07444000
                                                               <<03694>>07446000
    << We will now save the 4 DRT words of the console. >>     <<03694>>07448000
    << PRINTCHAR will destroy these values, so we must  >>     <<03694>>07450000
    << save them here.                                  >>     <<03694>>07452000
    tos := LPDT'S(CONSLDEV*2);  << DIT pointer on tos   >>     <<03694>>07454000
    tos := ABS(tos + SYSDB + DILTP); << ILT ptr on tos  >>     <<03694>>07456000
    tos := ABS(tos + SYSDB + ICNTRL).DRTNUMBER; << DRT  >>     <<03694>>07458000
    X := -1;                                                   <<03694>>07460000
    while (X:=X+1) < 4 do                                      <<03694>>07462000
      tos := GETDRT(DRTN,X);                                   <<03694>>07464000
                                                               <<03694>>07466000
    ASMB(ZROX,ZERO);  << FOR DELAY AND SETTING SYSDB >>                 07468000
    TOS := SYSDB;    XCHDB;                                             07470000
    WHILE DXBZ DO N := N;  << DELAY TO LET ANY I/O FINISH >>            07472000
                                                                        07474000
  ISSUE'HARD'MSG(4,N,%4);  << SYSTEM FAILURE # >>              <<03686>>07476000
  ISSUE'HARD'MSG(5,RSTATUS,%4);  << STATUS =   >>              <<03686>>07478000
  ISSUE'HARD'MSG(6,DELTAP,%4);                                 <<03686>>07480000
    XCHDB;    << RESTORE DB >>                                          07484000
                                                                        07486000
L3:                                                                     07488000
    ASMB( HALT %17 );                                                   07490000
    HELP;                                                               07492000
    GOTO L3;                                                            07494000
                                                                        07496000
  END;        <<  SUDDEN  DEATH  >>                                     07498000
$PAGE                                                                   07500000
                                                                        07502000
PROCEDURE AWAKEIO( DITP,FLAGS);                                         07504000
  VALUE DITP, FLAGS;                                                    07506000
  INTEGER POINTER DITP;  INTEGER FLAGS;                                 07508000
  OPTION UNCALLABLE, PRIVILEGED;                                        07510000
  <<                                                                    07512000
     FLAGS.(0:10) = 0 OR STACK DST NUMBER                               07514000
          .(13:1) = IF SET THEN PROCESS IS IMPEDABLE                    07516000
                                                                        07518000
     THIS PROCEDURE CALLS THE MONITOR OR AWAKES AN I/O PROCESS.         07520000
     TYPE 1 MONITORS (CAN BE RUN ON ANY STACK) ARE CALLED. TYPE 2       07522000
     MONITORS (CAN BE RUN IN ANY PROCESS) ARE CALLED IF IMPEDABLE       07524000
     OR A REQUEST IS QUEUED AND THE I/O PROCESS IS AWAKENED IF NOT      07526000
     IMPEDABLE. THE ASSOCIATED PROCESS IS AWAKENED FOR TYPE 3           07528000
     MONITORS (RUN ONLY IN OWN PROCESS).                                07530000
  >>                                                                    07532000
  BEGIN                                                                 07534000
    INTEGER POINTER DLTP = Q+1;                                         07536000
                                                                        07538000
    TOS := DITP(DDLTP);    <<  SET DLTP >>                              07540000
                                                                        07542000
    X := (DLTP+FLAGS).(13:3);                                           07544000
    TOS := 0;   << SET IFLAG TO FALSE >>                                07546000
    << SWITCH CODES 0,4     - NOT USED, IGNORED NOT RESIDENT            07548000
                    1,5,6   - CALL MONITOR                              07550000
                    2       - QUEUE REQUEST AND WAKE UP                 07552000
                    3,7     - WAKE UP TO RUN IN OWN PROCESS             07554000
    >>                                                                  07556000
    ASMB( BR * +1, X  ;                                                 07558000
      BR CHK'SEG; BR CALLMNTR;  BR QUEUE;     BR WAKEUP;       <<03031>>07560000
      BR CALLMNTR;BR CALLMNTR;  BR CALLMNTR);                  <<03031>>07562000
                                                                        07564000
WAKEUP:                                                                 07566000
    TOS := DITP(DPCBN).PCBM*PCBSIZE;                                    07568000
    GOTO WAKE;                                                          07570000
                                                                        07572000
QUEUE:                                                                  07574000
    X := DLTP&LSR(8);  << GET I/O PROCESS QUEUE NUMBER >>               07576000
    ADDTAIL(DITP,DLINK,X);                                              07578000
    TOS := BUSY(X);  << GET I/O PROCESS PCB INDEX >>                    07580000
                                                                        07582000
WAKE:                                                                   07584000
    AWAKE( *, JUNKWAIT,NOWAIT);                                         07586000
    RETURN;                                                             07588000
                                                               <<03031>>07590000
CHK'SEG:                                                       <<03031>>07592000
    PDISABLE;                                                  <<03031>>07594000
    IF CST (DLTP(DMNTR).(8:8)*4) < 0 THEN                      <<03031>>07596000
      BEGIN   << ABSENT >>                                     <<03031>>07598000
        PENABLE;                                               <<03031>>07600000
        GO QUEUE;                                              <<03031>>07602000
      END;                                                     <<03031>>07604000
                                                               <<03031>>07606000
    TOS := @DITP;                                              <<03031>>07608000
    TOS := FLAGS;                                              <<03031>>07610000
    TOS := DLTP(DMNTR);                                        <<03031>>07612000
    ASMB(PCAL 0);     << RUN DRIVER HERE >>                    <<03031>>07614000
    PENABLE;                                                   <<03031>>07616000
    RETURN;                                                    <<03031>>07618000
                                                               <<03031>>07620000
CALLMNTR:                                                               07622000
    TOS := @DITP;                                                       07624000
    TOS := FLAGS;  << TO SATISFY CALLING SEQUENCE >>                    07626000
    TOS := DLTP(DMNTR);    << MONITOR PLABEL >>                         07628000
    ASMB( PCAL 0 );                                                     07630000
  END;    <<        AWAKEIO   >>                                        07632000
$PAGE   "  SYSTEM IO PROCESS "                                          07634000
                                                                        07636000
PROCEDURE SYSIOPROC;                                                    07638000
  OPTION PRIVILEGED, UNCALLABLE;                                        07640000
  BEGIN                                                                 07642000
    INTEGER POINTER DITP;                                               07644000
    INTEGER IOPROCQN = DITP + 1;   << SYS IO PROCESS QUEUE NUMBER >>    07646000
                                                                        07648000
    TOS := X;    << SET IOPROCQN >>                                     07650000
                                                                        07652000
LOOP:                                                                   07654000
    DISABLE;                                                            07656000
    @DITP := DEQUEUE(DLINK,IOPROCQN);                                   07658000
    X := @DITP;   << SEE IF ANYTHING QUEUED >>                          07660000
    IF > THEN     << A DEVICE NEEDS SERVICE >>                          07662000
      BEGIN                                                             07664000
        ENABLE;                                                         07666000
        AWAKEIO(DITP,IMPEDABLE);      << CALL MONITOR >>                07668000
      END                                                               07670000
    << THE NEGATIVE WAITFIELD IS USED TO ALLOW TEPE/3000 >>    <<03031>>07672000
    << TO ABORT. IF THE WWS (WORD 3, BIT 0 OF THE PCB)   >>    <<03031>>07674000
    << IS SET,AN AWAKE IS MISSING SO RETURN TO SYSIOPROC >>    <<03031>>07676000
    << WITHOUT WAITING.                                  >>    <<03031>>07678000
                                                               <<03031>>07680000
    ELSE WAIT(-JUNKWAIT,NULL);   << NOTHING TO DO >>           <<03031>>07682000
    GOTO LOOP;   << CHECK FOR MORE TO DO >>                             07684000
  END;   << SYS I/O PROC >>                                             07686000
                                                                        07688000
INTEGER PROCEDURE GETDRT(DRT,OFFSET);                          <<03031>>07690000
<<=================================>>                          <<03031>>07692000
    VALUE DRT,OFFSET;                                          <<03031>>07694000
    INTEGER DRT,OFFSET;                                        <<03031>>07696000
                                                               <<03031>>07698000
    COMMENT: USE FIXED LOW CORE CELLS "DRTBANK","DRTADDR"      <<03031>>07700000
      TO GET DEVICE REF TABLE START ADDRESS, THEN INDEX        <<03031>>07702000
      TO THE DESIRED "DRT" ENTRY (4 WORD), AND USE             <<03031>>07704000
      "OFFSET" TO SPECIFY THE DESIRED WORD IN THE TABLE;       <<03031>>07706000
                                                               <<03031>>07708000
BEGIN                                                          <<03031>>07710000
                                                               <<03694>>07712000
define HSYSDRT = ABS(%1071)#; << Highest conf'd DRT >>         <<03694>>07714000
                                                               <<03694>>07716000
  if not (3 <= DRT <= HSYSDRT) then SUDDENDEATH(278);          <<03694>>07718000
  TOS:=ABSOLUTE(DRTBANK);                                      <<03031>>07720000
  TOS:=ABSOLUTE(DRTADDR)+DRT&LSL(2)+OFFSET;                    <<03031>>07722000
  ASSEMBLE(LSEA);                                              <<03031>>07724000
  PUSH(STATUS);                                                <<03031>>07726000
  TOS:=TOS.CC;                                                 <<03031>>07728000
  RSTATUS.CC:=TOS;  <<SET CC FOR FUTURE TEST>>                 <<03031>>07730000
    <<ORIGINAL CODE ASSIGNMENT SET THE CC>>                    <<03031>>07732000
  GETDRT:=TOS;                                                 <<03031>>07734000
END;                                                           <<03031>>07736000
                                                               <<03031>>07738000
PROCEDURE PUTDRT(DRT,OFFSET,NUM);                              <<03031>>07740000
<<=============================>>                              <<03031>>07742000
    VALUE DRT,OFFSET,NUM;                                      <<03031>>07744000
    INTEGER DRT,OFFSET,NUM;                                    <<03031>>07746000
                                                               <<03031>>07748000
    COMMENT: USE FIXED LOW CORE CELLS "DRTBANK","DRTADDR"      <<03031>>07750000
      TO GET DEVICE REF TABLE START ADDRESS, THEN INDEX        <<03031>>07752000
      TO THE DESIRED "DRT" ENTRY (4 WORD), AND USE             <<03031>>07754000
      "OFFSET" TO SPECIFY THE DESIRED WORD.                    <<03031>>07756000
      LOAD THE VALUE "NUM" INTO THAT WORD IN THE TABLE;        <<03031>>07758000
                                                               <<03031>>07760000
BEGIN                                                          <<03031>>07762000
                                                               <<03694>>07764000
define HSYSDRT = ABS(%1071)#; << Highest conf'd DRT >>         <<03694>>07766000
                                                               <<03694>>07768000
  if not (3 <= DRT <= HSYSDRT) then SUDDENDEATH(278);          <<03694>>07770000
  TOS:=ABSOLUTE(DRTBANK);                                      <<03031>>07772000
  TOS:=ABSOLUTE(DRTADDR) + DRT&LSL(2) + OFFSET;                <<03031>>07774000
  TOS:=NUM;                                                    <<03031>>07776000
  ASSEMBLE(SSEA);                                              <<03031>>07778000
END;                                                           <<03031>>07780000
                                                               <<03031>>07782000
$PAGE "EOFCHECK - CHECK FOR END OF FILE COND."                          07784000
PROCEDURE EOFCHECK(IOQP,BUF,CNT,HARDCHK);                               07786000
VALUE IOQP,BUF,CNT,HARDCHK;                                             07788000
INTEGER POINTER IOQP;                                                   07790000
DOUBLE BUF;                                                             07792000
LOGICAL CNT,HARDCHK;                                                    07794000
OPTION PRIVILEGED,UNCALLABLE;                                           07796000
BEGIN                                                                   07798000
EQUATE                                                                  07800000
   READ        = 0,                                                     07802000
   HARDWAREOF  = 1,                                                     07804000
   DATA        = 2,                                                     07806000
   EOD         = 3,                                                     07808000
   HELLO       = 4,                                                     07810000
   BYE         = 5,                                                     07812000
   JOB         = 6,                                                     07814000
   EOJ         = 7,                                                     07816000
   SESSIONRD   = 3,                                                     07818000
   DATARD      = 2,                                                     07820000
   JOBRD       = 4,                                                     07822000
   NOEOF       = 0;                                                     07824000
DEFINE                                                                  07826000
   CEOF        = (13:3)#,  << EOF CHECK FIELD OF QPAR1 >>               07828000
   FUNCT       = (8:8)#;  << FUNCTION FIELD OF IOQ >>                   07830000
BYTE                                                                    07832000
   B2          = Q+2,                                          <<03031>>07834000
   B4          = Q+3;                                                   07836000
BYTE ARRAY                                                              07838000
   BA(*)       = Q+1;                                                   07840000
DOUBLE                                                                  07842000
   DWORD0      = Q+1,                                                   07844000
   DWORD1      = Q+2,                                                   07846000
   DWORD2      = Q+3,                                          <<03031>>07848000
   DWORD4      = Q+5;                                          <<03031>>07850000
DOUBLE ARRAY                                                            07852000
   DA(*)       = Q+1;                                                   07854000
INTEGER                                                                 07856000
   TYPE        = Q+8,                                                   07858000
   LAST        = Q+9,                                                   07860000
   WORD0       = Q+1;                                                   07862000
LOGICAL POINTER                                                         07864000
   LPDTP       = Q+7;                                                   07866000
                                                                        07868000
                                                                        07870000
   << INITIALIZE LOCAL VARIABLES >>                                     07872000
   ASMB(ADDS 6); << LOCAL CHECK BUFFER >>                               07874000
   TOS := @LPDT(IOQP(QLDEV).QLDEVN&LSL(1) + LFLAGS); << LPDT PTR >>     07876000
   TOS := IOQP(QPAR1).CEOF; << TYPE OF EOF CHECK CALLED FOR >>          07878000
   IF S0 > JOBRD THEN GO TO SETCCE; << SKIP ANY CHECKING >>             07880000
   TOS := LPDTP.EOF; << EOF FROM LAST READ >>                           07882000
   TOS := BUF;                                                          07884000
   IF = THEN                                                            07886000
   BEGIN << PRE READ CHECK >>                                           07888000
      IF LAST = NOEOF THEN GO TO SETCCE;                                07890000
      IF TYPE = NOEOF OR TYPE = HARDWAREOF AND LAST > HARDWAREOF THEN   07892000
      BEGIN << NO EOF - NONE ON LAST READ OR CHK LEVEL TOO LOW >>       07894000
RESETEOF:                                                               07896000
         LPDTP.EOF := 0; << RESET EOF IN LPDT >>                        07898000
SETCCE:                                                                 07900000
         TOS := CCE;                                                    07902000
SETRSTAT:                                                               07904000
         RSTATUS.CC := TOS; << SET CALLER'S CONDITION CODE >>           07906000
         RETURN;                                                        07908000
      END;                                                              07910000
SETLAST:                                                                07912000
      TOS := CCG;                                                       07914000
      TOS := LAST;                                                      07916000
SETRETURN:                                                              07918000
      IOQP(QWBCT) := 0;                                                 07920000
      TOS := TOS&LSL(3) + 2;                                            07922000
      IOQP(QSTAT).IOSTAT := TOS;                                        07924000
      GO TO SETRSTAT;                                                   07926000
   END;                                                                 07928000
   IF LAST = HARDWAREOF THEN GO TO SETLAST;                             07930000
   << ALWAYS RETURN HARDWARE EOF ON POST READ CHECK >>                  07932000
   IF IOQP(QFUNC).FUNCT <> READ THEN GO TO SETCCE;             <<03031>>07934000
   << CAN'T CHECK DATA IF NO READ >>                           <<03031>>07936000
   TOS := CNT;                                                          07938000
   IF < THEN TOS := -TOS ELSE TOS := TOS&LSL(1);                        07940000
   CNT := TOS; << POS BYTE COUNT >>                                     07942000
   IF = THEN GO TO RESETEOF; << ZERO READ LENGTH >>                     07944000
   X := 0;                                                              07946000
   DO                                                                   07948000
   BEGIN << GET FIRST SIX WORDS OF DATA >>                              07950000
      ASMB(LDEA);                                                       07952000
      DA(X) := TOS;                                                     07954000
      TOS := TOS + 2;                                                   07956000
   END UNTIL (X:=X+1) > 2;                                              07958000
   TOS := HARDCHK;                                                      07960000
   DDEL;                                                                07962000
   DEL;                                                                 07964000
   IF < THEN                                                            07966000
   BEGIN << COLUMN BINARY ":EOF:" CHECK >>                              07968000
      IF DWORD0 = [16/%202,16/%4020]D AND DWORD2 = [16/%2010,16/%4010]D 07970000
      AND DWORD4 = [16/%202,16/%0]D THEN                                07972000
      BEGIN << HARDWARE EOF >>                                          07974000
SETHARD:                                                                07976000
         TOS := CCG;                                                    07978000
         TOS := HARDWAREOF;                                             07980000
SETEOF:                                                                 07982000
         ASMB(DUP);                                                     07984000
         LPDTP.EOF := TOS;                                              07986000
         GO TO SETRETURN;                                               07988000
      END ELSE GO TO RESETEOF;                                          07990000
   END;                                                                 07992000
   FOR * X := 0 UNTIL 5 DO                                              07994000
   BEGIN << UPSHIFT ASCII DATA FOR DATA CHECK >>                        07996000
      TOS := BA(X);                                                     07998000
      IF = THEN TOS := TOS LAND %337; << ALPHA CHARECTER >>             08000000
      BA(X) := TOS;                                                     08002000
   END;                                                                 08004000
   IF CNT < 6 THEN BA(CNT) := " ";                                      08006000
   << BLANK ODD BYTE SO CHECK MAY BE DONE ON WORDS >>                   08008000
   TOS := HARDCHK;                                                      08010000
   DEL;                                                                 08012000
   IF > AND WORD0 = ":E" AND DWORD1 = "OF: " THEN GO TO SETHARD;        08014000
   IF TYPE <= HARDWAREOF THEN GO TO RESETEOF; << NO DATA CHECKS >>      08016000
   TOS := CCL;                                                          08018000
   IF TYPE = SESSIONRD THEN                                             08020000
   BEGIN << SESSION READ TESTS - NO LEADING COLON >>                    08022000
      IF DWORD0 = "HELL" AND B4 = "O" AND BA(5) <> ALPHA THEN  <<03031>>08024000
      BEGIN << HELLO >>                                                 08026000
         TOS := HELLO;                                                  08028000
         GO SETEOF;                                                     08030000
      END;                                                              08032000
      IF DWORD0 = "DATA" AND B4 <> ALPHA THEN GO TO DATACMD;   <<03031>>08034000
      IF WORD0 = "JO" AND B2 = "B" AND BA(3) <> ALPHA THEN     <<03031>>08036000
                                                GO TO JOBCMD;  <<03031>>08038000
      IF WORD0 = "BY" AND B2 = "E" AND BA(3) <> ALPHA THEN     <<03031>>08040000
      BEGIN                                                             08042000
         TOS := CCG; << DON'T BACKSPACE BYE >>                          08044000
         TOS := BYE;                                                    08046000
         GO SETEOF;                                                     08048000
      END;                                                              08050000
      GO RESETEOF;                                                      08052000
   END;                                                                 08054000
   IF BA <> ":" THEN GO TO RESETEOF;                                    08056000
   IF WORD0 = ":D" AND DWORD1 = "ATA " THEN                             08058000
   BEGIN << DATA >>                                                     08060000
DATACMD:                                                                08062000
      TOS := DATA;                                                      08064000
      GO SETEOF;                                                        08066000
   END;                                                                 08068000
   IF B4 <> " " THEN GO RESETEOF;                                       08070000
   IF DWORD0 = ":JOB" THEN                                              08072000
   BEGIN                                                                08074000
JOBCMD:                                                                 08076000
      TOS := JOB;                                                       08078000
      GO SETEOF;                                                        08080000
   END;                                                                 08082000
   DEL;                                                                 08084000
   TOS := CCG;                                                          08086000
   IF TYPE = DATARD AND DWORD0 = ":EOD" THEN                            08088000
   BEGIN                                                                08090000
      TOS := EOD;                                                       08092000
      GO SETEOF;                                                        08094000
   END;                                                                 08096000
   IF TYPE = JOBRD AND DWORD0 = ":EOJ" THEN                             08098000
   BEGIN                                                                08100000
      TOS := EOJ;                                                       08102000
      GO SETEOF;                                                        08104000
   END;                                                                 08106000
   GO RESETEOF;                                                         08108000
END;                                                                    08110000
$PAGE "CHANNEL QUEUE CHECKER"                                           08112000
PROCEDURE CHKCHANNELQUE(CHANNEL,DITP);                                  08114000
VALUE CHANNEL,DITP;                                                     08116000
INTEGER CHANNEL;                                                        08118000
POINTER DITP;                                                           08120000
OPTION PRIVILEGED,UNCALLABLE;                                           08122000
BEGIN << CONTROLLER IS ON A CHANNEL >>                                  08124000
LOGICAL POINTER                                                         08126000
   DLTPL   = Q+1;                                                       08128000
                                                                        08130000
   TOS := DITP(DDLTP);   << SET DLTPL >>                                08132000
   TOS := CHANNEL; << IS THERE REALLY A CHANNEL? >>                     08134000
   IF < THEN                                                            08136000
   BEGIN << MULTI-CONTROLLER CHANNEL >>                                 08138000
      CHANNEL := TOS.CHANQUE; << SET CHANNEL QUEUE # >>                 08140000
      DISABLE;                                                          08142000
      WHILE BUSY(CHANNEL) = 0 OR BUSY(CHANNEL) = @DITP DO               08144000
      BEGIN                                                             08146000
         BUSY(CHANNEL) := 0; << RESET CHANNEL BUSY >>                   08148000
         X := DEQUEUE(DLINK,CHANNEL);                                   08150000
         IF > THEN                                                      08152000
         BEGIN << ANOTHER CONTROLLER IS WAITING >>                      08154000
            ENABLE;                                                     08156000
            TOS := X;   TOS := S0;    << GET  AND DUPLICATE DITP >>     08158000
            TOS := PS0(DILTP); << ILT POINTER >>                        08160000
            TOS := PS0(ICPGM); << SIO PROGRAM POINTER >>       <<03086>>08162000
            DELB;                                                       08164000
            STARTIO(*,*,0);    << START THE I/O FOR THIS DIT >><<03031>>08166000
            IF <> THEN IF DLTPL.QABORTS THEN  << SEND FAILURE REQUEST >>08168000
              ATTACHIO(DITP(DLDEV).DLDEVN,0,0,0,SIOFAIL,0,0,0,NOPCB)    08170000
            ELSE  << SET BITS TO INDICATE FAILURE >>                    08172000
            BEGIN << I/O FAILED TO START >>                             08174000
               PS0.IAK := 1;                                            08176000
               TOS := PS0(DIOQP);                                       08178000
               IF > THEN PS0.SFAIL := 1; << SET SIO FAIL >>             08180000
               DEL;                                                     08182000
               AWAKEIO(*,NOIMPEDE); << INFORM DRIVER >>                 08184000
            END ELSE DEL;                                               08186000
         END ELSE RETURN;                                               08188000
         DISABLE;                                                       08190000
      END;                                                              08192000
   END;                                                                 08194000
END;                                                                    08196000
                                                                        08198000
                                                                        08200000
PROCEDURE IOIMPEDE(TABLE);                                              08202000
VALUE TABLE;                                                            08204000
INTEGER TABLE;                                                          08206000
OPTION PRIVILEGED,UNCALLABLE;                                           08208000
BEGIN                                                                   08210000
                                                                        08212000
EQUATE                                                                  08214000
   SYSDB1     = SYSDB + 1;                                              08216000
                                                                        08218000
INTEGER                                                                 08220000
   THISPCB        = Q+1;                                                08222000
INTEGER POINTER                                                         08224000
   PCBP           = SYSPCB;                                             08226000
                                                                        08228000
                                                                        08230000
   DISABLE;                                                             08232000
   TOS := (ABS(CPCB) - ABS(PCBB)) / PCBSIZE; << SET THISPCB >>          08234000
   TOS := ABS(SYSDB1+TABLE).PCBN; << PCB FIELD OF TABLE >>              08236000
   IF = THEN                                                            08238000
   ABS(X).PCBN := THISPCB << LIST NULL, ENTER THIS PCB >>               08240000
   ELSE                                                                 08242000
   BEGIN << APPEND THIS PROCESS TO THE LIST >>                          08244000
      DO TOS := PCBP(TOS*PCBSIZE+PCB8).PCBM UNTIL =;                    08246000
      PCBP(X).PCBM := THISPCB;                                          08248000
   END;                                                                 08250000
   ABS(CPCB+PCB8).PCBM := 0; << SET THIS PROCESS AT END-OF-LIST >>      08252000
   IMPEDE(*); << ZERO ON TOS MEANS THIS PROCESS >>                      08254000
END;                                                                    08256000
$PAGE  "      PROCEDURE    IOUNIMPEDE     "                             08258000
                                                                        08260000
PROCEDURE IOUNIMPEDE(TABLE);                                            08262000
VALUE TABLE;                                                            08264000
INTEGER TABLE;                                                          08266000
OPTION PRIVILEGED,UNCALLABLE;                                           08268000
BEGIN                                                                   08270000
                                                                        08272000
EQUATE                                                                  08274000
   SYSDB1     = SYSDB + 1;                                              08276000
                                                                        08278000
INTEGER POINTER                                                         08280000
   PCBP       = SYSPCB;                                                 08282000
                                                                        08284000
                                                                        08286000
   DISABLE;                                                             08288000
   TOS := ABS(SYSDB1+TABLE).PCBN; << GET START OF LIST PIN >>           08290000
   IF = THEN RETURN;                                                    08292000
   ASMB(LDXA,XCH; DUP); << SAVE ADRESS AND DATA >>                      08294000
   TOS := PCBP(TOS*PCBSIZE+PCB8); << GET NEXT PIN >>                    08296000
   TOS := S0.PCBM; << NEXT PIN NUMBER >>                                08298000
   ASMB(XCH);                                                           08300000
   TOS.PCBM := 0; << ZERO NEXT PIN # ON HEAD PROCESS PCB >>             08302000
   PCBP(X) := TOS;                                                      08304000
   ASMB(CAB,STAX); << PUT PIN INTO TABLE >>                             08306000
   ABS(X).PCBN := TOS;                                                  08308000
   UNIMPEDE(TOS*PCBSIZE); << RUN HEAD PROCESS >>                        08310000
END;                                                                    08312000
$PAGE "SYSTEM BUFFER ROUTINES"                                          08314000
PROCEDURE RETURNSYSBUF(INDEX);                                          08316000
VALUE INDEX;                                                            08318000
INTEGER INDEX;                                                          08320000
OPTION PRIVILEGED,UNCALLABLE;                                           08322000
BEGIN                                                                   08324000
                                                                        08326000
INTEGER                                                                 08328000
   NUM           = Q+1,                                                 08330000
   SIZE          = Q+2; << BUFFER SIZE >>                               08332000
                                                                        08334000
INTEGER POINTER                                                         08336000
   SYSBUF      = SYSSBUF;                                               08338000
                                                                        08340000
   TOS := 0;                                                            08342000
   TOS := SYSBUF(TSIZE).ESIZE;                                          08344000
   DISABLE;                                                             08346000
   TOS := FIRSTINDEX;                                                   08348000
   TOS := (SYSBUF(LIM).LIMIT2 - 1) * SIZE + FIRSTINDEX;                 08350000
   TOS := INDEX;                                                        08352000
   DUPLICATE;                                                           08354000
   SYSBUF(SYSBUF(TTAIL)-1) := TOS; << APPEND RETURNED LIST >>           08356000
   DO                                                                   08358000
   BEGIN << FIND END OF LIST >>                                         08360000
      X := TOS;                                                         08362000
      ASMB(DDUP,DECX);                                                  08364000
      IF NOT(TOS <= X <= TOS) THEN SUDDENDEATH(251);                    08366000
      TOS := X - FIRSTINDEX; << CHECK THAT INDEX IS MODULO >>           08368000
      TOS := SIZE;                                                      08370000
      ASMB(DIV,TEST; DDEL);                                             08372000
      IF <> THEN SUDDENDEATH(251);                                      08374000
      NUM := NUM + 1;                                                   08376000
      TOS := SYSBUF(X);                                                 08378000
   END UNTIL =;                                                         08380000
   SYSBUF(TTAIL) := X + 1; << POINT TAIL AT LAST BUFFER >>              08382000
   TOS := SYSBUF(TUSE).INUSE - NUM;                                     08384000
   IF < THEN SUDDENDEATH(252);                                          08386000
   SYSBUF(X).INUSE := TOS; << UPDATE IN USE COUNTER >>                  08388000
   IOUNIMPEDE(ABS(SYSDB+SYSSBUF));                                      08390000
   << WAKE UP ANYONE WAITING FOR BUFFERS >>                             08392000
END;                                                                    08394000
