         << LINES .001/.009 ARE RESERVED FOR SYSTEMS INTEGRATION >>     00000001
<<=========================================================             00005000
=                                                         =             00010000
=                  INCLHARD - A8                          =             00015000
=                                                         =             00020000
=========================================================>>             00025000
<<                                                    >>       <<04393>>00030000
<<           INCLHARD  CHANGE HISTORY                 >>       <<04393>>00035000
<<                                                    >>       <<04393>>00040000
<<    PLEASE NOTE ANY CHANGES MADE TO INCLHARD        >>       <<04393>>00045000
<<    PLEASE USE LINE INCREMENT OF .001               >>       <<04393>>00050000
<<                                                    >>       <<04393>>00055000
<<    INITIALS     PROCEDURE NAME       DATE      C#  >>       <<04393>>00060000
<<                                                    >>       <<04393>>00065000
<<      WEO            LOGERROR        820603     1   >>       <<04393>>00070000
<<      WEO            IOMESSAGE       820624     2   >>       <<04466>>00075000
<<      WEO            SIODM           820713     3   >>       <<04477>>00080000
<<      WEO            GETGBUF         820820     4   >>       <<04835>>00085000
<<      KWE            SIODM           820908     5   >>       <<04899>>00090000
                                                               <<MPEIV>>00095000
$PAGE "FUNCTION THISCPU"                                       <<*2070>>00095010
INTEGER PROCEDURE THISCPU;                                     <<*2070>>00095020
  OPTION PRIVILEGED;   << THIS PROCEDURE SHOULD BE CALLABLE. >><<*2070>>00095030
COMMENT                                                        <<*2070>>00095040
**BEGIN_IS*****************************************************<<*2070>>00095050
*                                                             *<<*2070>>00095060
* PROCEDURE THISCPU                                           *<<*2070>>00095070
*                                                             *<<*2070>>00095080
* PURPOSE:  THISCPU IS A INTEGER FUNCTION CALLED TO RETURN A  *<<*2070>>00095090
*           VALUE IDENTIFYING THE TYPE OF CPU CURRENTLY       *<<*2070>>00095100
*           RUNNING.                                          *<<*2070>>00095110
*                                                             *<<*2070>>00095120
*           FIRST DETERMINE IF THE CPU IS A SERIES I OR NOT.  *<<*2070>>00095130
*           IF IT IS, THEN RETURN THE TYPE AS A SERIES I AND  *<<*2070>>00095140
*           RETURN.  IF NOT, THEN DO A PCN INSTRUCTION (CON   *<<*2070>>00095150
*           %020362) TO HAVE MICROCODE RETURN THE CPU TYPE    *<<*2070>>00095160
*           AND TRANSLATED TO THE PROPER VALUE TO BE RETURNED *<<*2070>>00095170
*           TO THE CALLER.                                    *<<*2070>>00095180
*                                                             *<<*2070>>00095190
* ENTRY:    NONE                                              *<<*2070>>00095200
*                                                             *<<*2070>>00095210
* EXIT:     THISCPU=CPU NUMBER OF THIS SYSTEM                 *<<*2070>>00095220
*                  =0 IF SERIES I                             *<<*2070>>00095230
*                  =1 IF SERIES II                            *<<*2070>>00095240
*                  =2 IF SERIES 33                            *<<*2070>>00095250
*                  =3 IF SERIES III                           *<<*2070>>00095260
*                  =4 IF SERIES 44                            *<<*2070>>00095270
*                  =5 IF SERIES 64                            *<<*2070>>00095280
*                  =6 IF SERIES 37                            *<<*2070>>00095290
*                                                             *<<*2070>>00095300
*                  =7-15 IF MIGHTY MOUSE FAMILY               *<<*2070>>00095310
*                        =7 IF TIOGA                          *<<*2070>>00095320
*                        =8 IF MICROMOUSE                     *<<*2070>>00095330
*                        (9-15 TO BE ASSIGNED)                *<<*2070>>00095340
*                                                             *<<*2070>>00095350
**END_IS*******************************************************<<*2070>>00095360
;                                                              <<*2070>>00095370
  BEGIN                                                        <<*2070>>00095380
    INTEGER X=X;                                               <<*2070>>00095390
                                                               <<*2070>>00095400
!   DETERMINE IF THE HARDWARE IS A SERIES I                    <<*2070>>00095410
!   ---------------------------------------                    <<*2070>>00095420
    TOS:=0;         <<INITIALIZE RETURN (SERIES I)>>           <<*2070>>00095430
    TOS:=-1;        <<TEST FLAG - ILLEGAL BANK #  >>           <<*2070>>00095440
    PUSH(DB);       <<1 WORD ON SERIES I          >>           <<*2070>>00095450
                    <<2 WORDS ON SERIES II/TOOTHPICK>>         <<*2070>>00095460
    DEL;            <<DON'T NEED DB ADDRESS       >>           <<*2070>>00095470
    IF TOS <> -1 THEN <<WAS BANK # PUSHED?        >>           <<*2070>>00095480
                                                               <<*2070>>00095490
!     IF NOT, DO PCN INSTRUCTION TO GET CPU TYPE               <<*2070>>00095500
!     ------------------------------------------               <<*2070>>00095510
      BEGIN         <<YES - NOT SERIES I          >>           <<*2070>>00095520
        DEL;        <<DELETE TEST FLAG            >>           <<*2070>>00095530
        DEL;        <<DELETE RETURN VALUE         >>           <<*2070>>00095540
                                                               <<*2070>>00095550
!       DO TRANSLATION OF CPU TYPE TO PASS BACK TO CALLER      <<*2070>>00095560
!       -------------------------------------------------      <<*2070>>00095570
        ASSEMBLE(CON %020362); <<GET MICROCODE CPU #>>         <<*2070>>00095580
        X:=TOS;                                                <<*2070>>00095590
                                                               <<*2070>>00095600
        IF X=1 THEN TOS:=1      !SERIES II                     <<*2070>>00095610
         ELSE IF X=8 THEN TOS:=2 !SERIES 33                    <<*2070>>00095620
          ELSE IF X=2 THEN TOS:=3 !SERIES III                  <<*2070>>00095630
           ELSE IF X=3 THEN TOS:=4 !SERIES 44                  <<*2070>>00095640
            ELSE IF X=4 THEN TOS:=5 !SERIES 64                 <<*2070>>00095650
             ELSE IF X=5 THEN TOS:=6 !SERIES 37                <<*2070>>00095660
              ELSE IF X=6 THEN TOS:=7 !TIOGA                   <<*2070>>00095670
               ELSE IF X=7 THEN TOS:=8 !UMOUSE                 <<*2070>>00095680
                ELSE SUDDENDEATH(13); !BAD PCN VALUE           <<*2070>>00095690
                                                               <<*2070>>00095700
      END;                                                     <<*2070>>00095710
                                                               <<*2070>>00095720
!   PASS BACK CPU NUMBER                                       <<*2070>>00095730
!   --------------------                                       <<*2070>>00095740
    THISCPU:=TOS;  <<RETURN VALUE>>                            <<*2070>>00095750
  END;    << END THISCPU >>                                    <<*2070>>00095760
$PAGE "DEQUEUE DISC REQUEST"                                   <<JB.19>>00100000
PROCEDURE DEQUEUEDISCREQ(REQP,QTYPE,TABLE'PTR);                <<06768>>00105000
VALUE REQP,QTYPE,TABLE'PTR;                                    <<06768>>00110000
INTEGER REQP,QTYPE,TABLE'PTR;                                  <<06768>>00115000
OPTION PRIVILEGED,UNCALLABLE;                                  <<06768>>00120000
                                                               <<06768>>00125000
COMMENT                                                        <<06768>>00130000
                                                               <<06768>>00135000
REMOVES THE SPECIFIED REQUEST FROM ITS QUEUE.  CALLED BY DISCQ <<06768>>00140000
MANAGER WHEN ABORTING SEGMENT READ OR WRITE REQUESTS, AND FROM <<06768>>00145000
CHECKFORPENDINGDISCIO TO REMOVE A REQUEST FROM THE QUEUE OF    <<06768>>00150000
PENDING DISC TRANSFER REQUESTS. ALSO FROM SIODM ON BUFFER TRAPS<<06768>>00155000
                                                               <<06768>>00160000
REQP      - A disc request table relative entry index of the   <<06768>>00165000
            element to be queued on the list type QTYPE.       <<06768>>00170000
                                                               <<06768>>00175000
QTYPE     - This is the queue type that the request is to      <<06768>>00180000
            be linked to.  They are:                           <<06768>>00185000
                                                               <<06768>>00190000
            0 - for DEFERREDREQQ (deferred request queue).     <<06768>>00195000
            1 - for CDTREQQ (CDT request queue).               <<06768>>00200000
            2 - for DITREQQ (DIT request queue).               <<06768>>00205000
                                                               <<06768>>00210000
            The deferred queue is maintained in the disc       <<06768>>00215000
            request table header entry.  This list contains all<<06768>>00220000
            the disc requests held off because their target    <<06768>>00225000
            object was not in memory.                          <<06768>>00230000
                                                               <<06768>>00235000
            The CDT queue links the logical disc request on a  <<06768>>00240000
            mapped cache domain's ACTIVE queue.                <<06768>>00245000
                                                               <<06768>>00250000
            The DIT queue links the disc request, by priority, <<06768>>00255000
            on the disc's DIT, and optionally AWAKENs the      <<06768>>00260000
            device IF it was inactive.                         <<06768>>00265000
                                                               <<06768>>00270000
TABLE'PTR - This parameter is depENDant on QTYPE.  If          <<06768>>00275000
            QTYPE = :                                          <<06768>>00280000
                                                               <<06768>>00285000
            0 - This parameter is ignored.                     <<06768>>00290000
            1 - This parameter is the CDT entry number.        <<06768>>00295000
            2 - This is the SYSDB-relative DIT pointer.        <<06768>>00300000
                                                               <<06768>>00305000
                                                               <<06768>>00310000
                                                               <<06768>>00315000
;                                                              <<06768>>00320000
BEGIN                                                          <<06768>>00325000
INTEGER                                                        <<07410>>00330000
   ABSDITP,                                                    <<07410>>00335000
   DRQ'ENTRY'INDEX,                                            <<07410>>00340000
   NEXT,                                                       <<07410>>00345000
   PREV,                                                       <<07410>>00350000
   SAVE;                                                       <<07410>>00355000
                                                               <<07410>>00360000
LOGICAL                                                        <<07410>>00365000
   LDR'ENTRY'INDEX=REQP,                                       <<07410>>00370000
   IN'DISABLED'Q;                                              <<07410>>00375000
                                                               <<07410>>00380000
DOUBLE DBSAVE;                                                 <<07410>>00385000
                                                               <<07410>>00390000
EQUATE                                                         <<07410>>00395000
   DITHEAD = 8, << (%10) LOCATION OF DIT DRQ HEAD AND >>       <<07410>>00400000
   DITTAIL = 9; << (%11) TAIL IN DIT                  >>       <<07410>>00405000
                                                               <<07410>>00410000
SUBROUTINE CLEARLINKS;                                         <<07410>>00415000
BEGIN                                                          <<07410>>00420000
COMMENT                                                        <<07410>>00425000
   SET THE HEAD AND TAIL POINTERS TO ZERO AS WE ARE DELETING   <<07410>>00430000
   THE ONLY ELEMENT IN THE QUEUE. THE HEAD AND TAIL POINTERS   <<07410>>00435000
   CAN BE FOR EITHER THE DISABLE OR DIT QUEUES.                <<07410>>00440000
;                                                              <<07410>>00445000
IF IN'DISABLED'Q                                               <<07410>>00450000
   THEN  AQH'DISAHEAD :=  AQH'DISATAIL := 0                    <<07410>>00455000
   ELSE ABS(ABSDITP+DITHEAD) := ABS(ABSDITP+DITTAIL) := 0;     <<07410>>00460000
END; << CLEARLINKS >>                                          <<07410>>00465000
                                                               <<07410>>00470000
SUBROUTINE RELINKHEAD;                                         <<07410>>00475000
BEGIN                                                          <<07410>>00480000
COMMENT                                                        <<07410>>00485000
   THE FIRST ELEMENT OF THE QUEUE HAS BEEN DELETED AND IT IS   <<07410>>00490000
   NECCESSARY TO UPDATE THE HEAD POINTER. THIS CAN BE EITHER   <<07410>>00495000
   IN THE DQH OR DIT DEPENDING ON WHETHER WE HAVE A DISABLED   <<07410>>00500000
   ARQX ELEMENT OR A DIT ARQX ELEMENT.                         <<07410>>00505000
;                                                              <<07410>>00510000
                                                               <<07410>>00515000
IF IN'DISABLED'Q                                               <<07410>>00520000
   THEN  AQH'DISAHEAD := DRQ'ENTRY'INDEX                       <<07410>>00525000
   ELSE ABS(ABSDITP+DITHEAD) := DRQ'ENTRY'INDEX;               <<07410>>00530000
                                                               <<07410>>00535000
END; << RELINKHEAD >>                                          <<07410>>00540000
                                                               <<07410>>00545000
SUBROUTINE RELINKTAIL;                                         <<07410>>00550000
BEGIN                                                          <<07410>>00555000
COMMENT                                                        <<07410>>00560000
   THE LAST ELEMENT OF THE QUEUE HAS BEEN DELETED AND IT IS    <<07410>>00565000
   NECCESSARY TO UPDATE THE TAIL POINTER. THIS CAN BE EITHER   <<07410>>00570000
   IN THE DQH OR DIT DEPENDING ON WHETHER WE HAVE A DISABLED   <<07410>>00575000
   ARQX ELEMENT OR A DIT ARQX ELEMENT.                         <<07410>>00580000
;                                                              <<07410>>00585000
                                                               <<07410>>00590000
IF IN'DISABLED'Q                                               <<07410>>00595000
   THEN  AQH'DISATAIL := DRQ'ENTRY'INDEX                       <<07410>>00600000
   ELSE ABS(ABSDITP+DITTAIL) := DRQ'ENTRY'INDEX;               <<07410>>00605000
                                                               <<07410>>00610000
END; << RELINKTAIL >>                                          <<07410>>00615000
$PAGE "SUBROUTINE DO'DEQUEUE OF DEQUEUEDISCREQ"                <<07410>>00620000
SUBROUTINE DO'DEQUEUE;                                         <<07410>>00625000
BEGIN                                                          <<07410>>00630000
COMMENT                                                        <<07410>>00635000
   SEARCH FOR AND DROP THE ELEMENT INDICATED BY                <<07410>>00640000
   DRQ'ENTRY'INDEX, A ARQX RELATIVE INDEX.                     <<07410>>00645000
;                                                              <<07410>>00650000
                                                               <<07410>>00655000
ARQX'PREQ := 0; << RESET ALREADY QUEUED BIT >>                 <<07410>>00660000
IF (PREV := ARQX'PREVQ) = 0                                    <<07410>>00665000
   THEN                                                        <<07410>>00670000
      BEGIN << REMOVING 1ST ELEMENT ON QUEUE >>                <<07410>>00675000
      IF ARQX'NEXTQ = 0                                        <<07410>>00680000
              << WE ARE DELETING THE ONE AND ONLY ELEMENT >>   <<07410>>00685000
              << IN THE QUEUE HERE.                       >>   <<07410>>00690000
         THEN CLEARLINKS << ALSO ONLY ELEMENT ON Q >>          <<07410>>00695000
         ELSE                                                  <<07410>>00700000
            BEGIN                                              <<07410>>00705000
               << WE ARE DELETING THE 1ST ELEMENT IN A QUEUE >><<07410>>00710000
               << OF AT LEAST 2 ELEMENTS.                    >><<07410>>00715000
            SAVE := DRQ'ENTRY'INDEX;                           <<07410>>00720000
               << ADV. TO NEXT ELEMENT >>                      <<07410>>00725000
            DRQ'ENTRY'INDEX := ARQX'NEXTQ;                     <<07410>>00730000
               << TIDY UP DELETED ELEMENT POINTERS >>          <<07410>>00735000
            DRQ'NEXTQ'WORD(SAVE) := 0;                         <<07410>>00740000
            ARQX'PREVQ := 0; << MARK AS NEW 1ST ELEMENT >>     <<07410>>00745000
               << POINT TO NEW HEAD OF QUEUE >>                <<07410>>00750000
            RELINKHEAD;                                        <<07410>>00755000
            END; << ELSE IF ARQX'NEXTQ >>                      <<07410>>00760000
      END << IF PREV >>                                        <<07410>>00765000
   ELSE                                                        <<07410>>00770000
      BEGIN << NOT 1ST ELEMENT OF QUEUE >>                     <<07410>>00775000
      IF (NEXT := ARQX'NEXTQ) = 0                              <<07410>>00780000
         THEN                                                  <<07410>>00785000
            << WERE ARE DELETING THE LAST ELEMENT IN A QUEUE >><<07410>>00790000
            << THAT HAS AT LEAST TWO ELEMENTS.               >><<07410>>00795000
            BEGIN << BUT IS LAST ELEMENT >>                    <<07410>>00800000
            SAVE := DRQ'ENTRY'INDEX;                           <<07410>>00805000
            DRQ'ENTRY'INDEX := ARQX'PREVQ;                     <<07410>>00810000
               << TIDY UP DELETED ELEMENT POINTER >>           <<07410>>00815000
            DRQ'PREVQ'WORD(SAVE) := 0;                         <<07410>>00820000
            ARQX'NEXTQ := 0; << MARK AS NEW LAST ELEMENT >>    <<07410>>00825000
               << POINT TO NEW TAIL >>                         <<07410>>00830000
            RELINKTAIL;                                        <<07410>>00835000
            END                                                <<07410>>00840000
         ELSE                                                  <<07410>>00845000
            << WERE DELETING AN ELEMENT SOMEWHERE IN A QUEUE >><<07410>>00850000
            << THAT HAS AT LEAST 3 ELEMENTS.                 >><<07410>>00855000
            BEGIN << ELEMENT SOMEWHERE IN THE MIDDLE >>        <<07410>>00860000
               << LINK AROUND DELETED ELEMENT >>               <<07410>>00865000
            DRQ'NEXTQ'WORD(PREV) := ARQX'NEXTQ;                <<07410>>00870000
            DRQ'PREVQ'WORD(NEXT) := ARQX'PREVQ;                <<07410>>00875000
               << TIDY UP DELETED ELEMENT POINTERS >>          <<07410>>00880000
            ARQX'PREVQ := ARQX'NEXTQ := 0;                     <<07410>>00885000
            END; << ELSE OF IF NEXT >>                         <<07410>>00890000
      END; << ELSE OF IF PREV  >>                              <<07410>>00895000
                                                               <<07410>>00900000
END; << DO'DEQUEUE >>                                          <<07410>>00905000
$PAGE "PROCEDURE DEQUEUEDISCREQ"                               <<07410>>00910000
IF QTYPE = CDTREQQ << IE IS DISC CACHE REQUEST >>              <<07410>>00915000
   THEN   << DEQUEUE LOG REQ FROM MAPPED CDT ENTRY >>          <<07410>>00920000
      BEGIN                                                    <<07410>>00925000
      CDT'DEQUEUE'LDR(LDR'CDT,LDR'ENTRY'INDEX,                 <<07410>>00930000
                      CDT'MD'LDR'HEAD);                        <<07410>>00935000
      END                                                      <<07410>>00940000
   ELSE   << DEQUEUE EITHER DIT OR DISABLE QUEUE >>            <<07410>>00945000
      BEGIN                                                    <<07410>>00950000
      DRQ'ENTRY'INDEX := REQP;                                 <<07410>>00955000
      IN'DISABLED'Q := IF QTYPE = DEFERREDREQQ                 <<07410>>00960000
                          THEN TRUE ELSE FALSE;                <<07410>>00965000
      ABSDITP := TABLE'PTR + SYSDB;                            <<07410>>00970000
      DISABLE;                                                 <<07410>>00975000
      DBTODRQ;                                                 <<07410>>00980000
      DO'DEQUEUE;                                              <<07410>>00985000
      TOS := DBSAVE;                                           <<07410>>00990000
      ASMB( XCHD );                                            <<07410>>00995000
      END;                                                     <<07410>>01000000
                                                               <<07410>>01005000
END; << PROCEDURE DEQUEUEDISCREQ >>                            <<07410>>01010000
 PROCEDURE STORE'IOQ(IOQP, FLAG);                              <<01830>>01015000
                                                               <<01830>>01020000
 COMMENT                                                       <<01830>>01025000
 ************************************************************* <<01830>>01030000
 THIS PROCEDURE IS USED WHEN IOSTATFLAG IS ENABLED.  IT WILL   <<01830>>01035000
 MOVE THE IOQ AND DISCREQ ENTRIES ONTO AN EXTRY DATA SEGMENT.  <<01830>>01040000
                                                               <<01830>>01045000
 THE PARAMETER IOQP IS THE POINTER TO THE OUTGOING IOQ/DISCREQ <<01830>>01050000
 AND FLAG INDICATES WHETHER IT IS AN IOQ (TRUE) OR DISCREQ.    <<01830>>01055000
 ************************************************************* <<01830>>01060000
 ;                                                             <<01830>>01065000
 VALUE IOQP, FLAG;                                             <<01830>>01070000
 LOGICAL FLAG;                                                 <<01830>>01075000
INTEGER IOQP;                                                  <<07341>>01080000
OPTION PRIVILEGED,UNCALLABLE;                                  <<*7866>>01085000
                                                               <<01830>>01090000
 BEGIN                                                         <<01830>>01095000
    INTEGER MAX'CNT;                                           <<01830>>01100000
DEFINE                                                         <<06768>>01105000
      ENTRY'IS'DRQ = NOT FLAG#,                                <<06768>>01110000
      ENTRY'IS'IOQ = FLAG#;                                    <<06768>>01115000
INTEGER                                                        <<06768>>01120000
      Q'ENTRY'INDEX=IOQP;                                      <<06768>>01125000
                                                               <<01830>>01130000
DOUBLE SUBROUTINE ATIOQP;                                      <<06768>>01135000
BEGIN                                                          <<06768>>01140000
COMMENT                                                        <<06768>>01145000
   LEAVE DOUBLE WORD ADDRESS OF IOQP CONSISTING OF             <<06768>>01150000
   A DST # AND AN OFFSET INTO THE DATA SEGMENT.                <<06768>>01155000
;                                                              <<06768>>01160000
    TOS := IF ENTRY'IS'DRQ THEN DRQ'DST ELSE IOQ'DST;          <<06768>>01165000
    TOS := Q'ENTRY'INDEX;                                      <<06768>>01170000
    ASSEMBLE(STD S-4); << SAVE CONSTRUCTED ADDR >>             <<07341>>01175000
END; << SUBROUTINE ATIOQP >>                                   <<06768>>01180000
    IF  NOT (IOSTATSENBLD)  THEN  RETURN; << NOT ENABLED >>    <<01830>>01185000
                                                               <<01830>>01190000
    DISABLE;                                                   <<01830>>01195000
    TOS := IOSTATXDSBANK;                                      <<01830>>01200000
    TOS := IOSTATXDSBASE;                                      <<01830>>01205000
    ASMB(DDUP);                                                <<*7572>>01210000
ASMB(LDEA); << LOAD NEXT DST ENTRY # AND MAX # OF ENTRIES >>   <<06768>>01215000
MAX'CNT := TOS; << SAVE MAX # OF ENTRIES >>                    <<06768>>01220000
TOS := TOS*20;                                                 <<*7698>>01225000
TOS := IOSTATXDSNUM; << LOAD DST # AND SWAP AS ORDER IS >>     <<06768>>01230000
ASMB(XCH); << DST#, OFFSET >>                                  <<06768>>01235000
       << LOAD DST ADDR OF DRQ/IOQP >>                         <<06768>>01240000
    TOS := ATIOQP;                                             <<06768>>01245000
IF ENTRY'IS'IOQ THEN << MOVE IOQ ENTRY INTO DST >>             <<06768>>01250000
    BEGIN                                                      <<01830>>01255000
    TOS := IQH'ENT'SIZE;                                       <<06768>>01260000
    ASMB(MDS 3; DELB; ADD); << SET UP ADDR FOR MEAS. INFO >>   <<06768>>01265000
       TOS := ATIOQP;<< MAKE 2 WD DST ADDR FOR MPE V >>       <<<06768>>01270000
    ASMB(SDEA; INCA,INCA); << RECORD Q ADDR >>                 <<06768>>01275000
   TOS := -1D;  << FILLER TO MAKE 20 WORDS LONG >>             <<*7572>>01280000
    ASMB(SDEA; INCA,INCA);                                     <<*7698>>01285000
       TOS := TIMER;                                           <<01830>>01290000
      ASMB(SDEA;INCA,INCA;DZRO,SDEA;DDEL);                     <<*7572>>01295000
    END  ELSE                   << MOVE 16 WORDS DISCREQ >>    <<01830>>01300000
    BEGIN                                                      <<01830>>01305000
    TOS := DQH'ENT'SIZE;                                       <<06768>>01310000
      ASMB(MDS 3;  DELB;  ADD);                                <<*7572>>01315000
      TOS := TIMER;                                            <<*7572>>01320000
      ASMB(SDEA;                                               <<*7572>>01325000
           INCA,INCA;                                          <<*7572>>01330000
           ZERO;                                               <<*7572>>01335000
           SSEA;                                               <<*7572>>01340000
           DDEL);                                              <<*7572>>01345000
    END;                                                       <<01830>>01350000
    ASMB(LSEA; INCA);           << LOAD INDEX TO XDS >>        <<01830>>01355000
    IF  S0 > MAX'CNT  THEN      << WRAP AROUND >>              <<01830>>01360000
    BEGIN                                                      <<01830>>01365000
       ASMB(DEL; LDI 1);                                       <<01830>>01370000
    END;                                                       <<01830>>01375000
    ASMB(SSEA);                 << STORE NEW INDEX TO XDS >>   <<01830>>01380000
    TOS := TOS + 2;                                            <<01830>>01385000
    ASMB(LDEA);                                                <<01830>>01390000
    TOS := TOS + 1D;           << TOTAL COUNT OF I/O REQUEST >><<01830>>01395000
    ASMB(SDEA);                                                <<01830>>01400000
 END;                                                          <<01830>>01405000
$PAGE "QUEUE DISC REQUEST"                                     <<JB.19>>01410000
PROCEDURE QUEUEDISCREQ(REQP,QTYPE,TABLE'PTR);                  <<06768>>01415000
VALUE REQP,TABLE'PTR,QTYPE;                                    <<06768>>01420000
INTEGER REQP,TABLE'PTR,QTYPE;                                  <<06768>>01425000
OPTION PRIVILEGED,UNCALLABLE;                                  <<06768>>01430000
                                                               <<06768>>01435000
COMMENT                                                        <<06768>>01440000
                                                               <<06768>>01445000
This procedure queues the disc request entry pointed to by     <<06768>>01450000
REQP and places it in the appropriate position on the queue    <<06768>>01455000
specIFied by QTYPE.  Each QTYPE has its own particular         <<06768>>01460000
characteristics.  The input parameters are:                    <<06768>>01465000
                                                               <<06768>>01470000
REQP      - A disc request table relative entry index of the   <<06768>>01475000
            element to be queued on the list type QTYPE.       <<06768>>01480000
                                                               <<06768>>01485000
QTYPE     - This is the queue type that the request is to      <<06768>>01490000
            be linked to.  They are:                           <<06768>>01495000
                                                               <<06768>>01500000
            0 - for DEFERREDREQQ (deferred request queue).     <<06768>>01505000
            1 - for CDTREQQ (CDT request queue).               <<06768>>01510000
            2 - for DITREQQ (DIT request queue).               <<06768>>01515000
                                                               <<06768>>01520000
            The deferred queue is maintained in the disc       <<06768>>01525000
            request table header entry.  This list contains all<<06768>>01530000
            the disc requests held off because their target    <<06768>>01535000
            object was not in memory.                          <<06768>>01540000
                                                               <<06768>>01545000
            The CDT queue links the logical disc request on a  <<06768>>01550000
            mapped cache domain's ACTIVE queue.                <<06768>>01555000
                                                               <<06768>>01560000
            The DIT queue links the disc request, by priority, <<06768>>01565000
            on the disc's DIT, and optionally AWAKENs the      <<06768>>01570000
            device IF it was inactive.                         <<06768>>01575000
                                                               <<06768>>01580000
TABLE'PTR - This parameter is depENDant on QTYPE.  If          <<06768>>01585000
            QTYPE = :                                          <<06768>>01590000
                                                               <<06768>>01595000
            0 - This parameter is ignored.                     <<06768>>01600000
            1 - This parameter is the CDT entry number.        <<06768>>01605000
            2 - This is the SYSDB-relative DIT pointer.        <<06768>>01610000
                                                               <<06768>>01615000
                                                               <<06768>>01620000
This procedure is called from ATTACHIO, STARTSEGWRITE,         <<06768>>01625000
PROCESSINITMSG, and DISCQMANAGER.                              <<06768>>01630000
;                                                              <<06768>>01635000
BEGIN                                                          <<MPEIV>>01640000
                                                               <<07410>>01645000
EQUATE                                                         <<07410>>01650000
   DITIOQ       = 2,                                           <<07410>>01655000
   DITHEAD      = 8,                                           <<07410>>01660000
   DITTAIL      = 9;                                           <<07410>>01665000
DOUBLE DBSAVE;                                                 <<07410>>01670000
INTEGER ABSDITP;                                               <<07410>>01675000
INTEGER NEXT,                                                  <<07410>>01680000
        PREV,                                                  <<07410>>01685000
        LASTINQUEUE,                                           <<07410>>01690000
        FIRSTINQUEUE;                                          <<07410>>01695000
INTEGER POINTER DITPOINTER;                                    <<07410>>01700000
INTEGER                                                        <<07410>>01705000
   DITSYSBASEINX=TABLE'PTR,                                    <<07410>>01710000
   DRQ'ENTRY'INDEX=REQP,                                       <<07410>>01715000
   LDR'ENTRY'INDEX=REQP,                                       <<07410>>01720000
   DRQ'X;                                                      <<07410>>01725000
LOGICAL                                                        <<07410>>01730000
   IN'DISABLED'Q,                                              <<07410>>01735000
   FOUND;                                                      <<07410>>01740000
LOGICAL THISREQPRI;                                            <<07410>>01745000
$PAGE "MISC SUBROUTINES OF QUEUEDISCREQ"                       <<07410>>01750000
INTEGER SUBROUTINE CHECK'IOQP;                                 <<07410>>01755000
COMMENT                                                        <<07410>>01760000
   RETURN EITHER THE CURRENT REQUEST INDEX FROM THE DRQ        <<07410>>01765000
   OR THE EQUIVALENT LOCATION IN THE DQH FOR THE DISABLED      <<07410>>01770000
   QUEUE. EXPECTS X := DITSYSBASEINX.                          <<07410>>01775000
;                                                              <<07410>>01780000
BEGIN                                                          <<07410>>01785000
CHECK'IOQP := IF IN'DISABLED'Q                                 <<07410>>01790000
   THEN  AQH'DISAHEAD ELSE ABS(ABSDITP+DITIOQ);                <<07410>>01795000
END; << CHECK'IOQP >>                                          <<07410>>01800000
                                                               <<07410>>01805000
INTEGER SUBROUTINE CHECK'HEAD;                                 <<07410>>01810000
COMMENT                                                        <<07410>>01815000
   RETURN EITHER THE QUEUE HEAD INDEX FROM THE DIT             <<07410>>01820000
   OR THE DQH. EXPECTS X := DITSYSBASEINX.                     <<07410>>01825000
;                                                              <<07410>>01830000
BEGIN                                                          <<07410>>01835000
CHECK'HEAD := IF IN'DISABLED'Q                                 <<07410>>01840000
   THEN  AQH'DISAHEAD ELSE ABS(ABSDITP+DITHEAD);               <<07410>>01845000
END; << CHECK'HEAD >>                                          <<07410>>01850000
                                                               <<07410>>01855000
INTEGER SUBROUTINE CHECK'TAIL;                                 <<07410>>01860000
COMMENT                                                        <<07410>>01865000
   RETURN EITHER THE QUEUE TAIL INDEX FROM THE DIT             <<07410>>01870000
   OR THE DQH. EXPECTS X := DITSYSBASEINX.                     <<07410>>01875000
;                                                              <<07410>>01880000
BEGIN                                                          <<07410>>01885000
CHECK'TAIL := IF IN'DISABLED'Q                                 <<07410>>01890000
   THEN  AQH'DISATAIL ELSE ABS(ABSDITP+DITTAIL);               <<07410>>01895000
END; << CHECK'TAIL >>                                          <<07410>>01900000
                                                               <<07410>>01905000
SUBROUTINE SET'HEAD(ADDR);                                     <<07410>>01910000
   VALUE ADDR;                                                 <<07410>>01915000
   INTEGER ADDR;                                               <<07410>>01920000
COMMENT                                                        <<07410>>01925000
   STORE THE ADDRESS VALUE "ADDR" INTO THE HEAD OF             <<07410>>01930000
   EITHER THE DIT OR THE DQH. EXPECTS X := DITSYSBASEINX.      <<07410>>01935000
;                                                              <<07410>>01940000
BEGIN                                                          <<07410>>01945000
IF IN'DISABLED'Q                                               <<07410>>01950000
   THEN  AQH'DISAHEAD := ADDR                                  <<07410>>01955000
   ELSE ABS(ABSDITP+DITHEAD) := ADDR;                          <<07410>>01960000
END; << SET'HEAD >>                                            <<07410>>01965000
                                                               <<07410>>01970000
SUBROUTINE SET'TAIL(ADDR);                                     <<07410>>01975000
   VALUE ADDR;                                                 <<07410>>01980000
   INTEGER ADDR;                                               <<07410>>01985000
COMMENT                                                        <<07410>>01990000
   STORE THE ADDRESS VALUE "ADDR" INTO THE TAIL OF             <<07410>>01995000
   EITHER THE DIT OR THE DQH. EXPECTS X := DITSYSBASEINX.      <<07410>>02000000
;                                                              <<07410>>02005000
BEGIN                                                          <<07410>>02010000
IF IN'DISABLED'Q                                               <<07410>>02015000
   THEN  AQH'DISATAIL := ADDR                                  <<07410>>02020000
   ELSE ABS(ABSDITP+DITTAIL) := ADDR;                          <<07410>>02025000
END; << SET'TAIL >>                                            <<07410>>02030000
                                                               <<07410>>02035000
SUBROUTINE SET'IOQP(ADDR);                                     <<07410>>02040000
   VALUE ADDR;                                                 <<07410>>02045000
   INTEGER ADDR;                                               <<07410>>02050000
COMMENT                                                        <<07410>>02055000
   STORE THE ADDRESS VALUE "ADDR" INTO THE CURRENT IOQP OF     <<07410>>02060000
   THE DIT. NEEDED TO AVOID X CLOBBERING.                      <<07410>>02065000
;                                                              <<07410>>02070000
BEGIN                                                          <<07410>>02075000
ABS(ABSDITP+DITIOQ) := ADDR;                                   <<07410>>02080000
END; << SET'TAIL >>                                            <<07410>>02085000
                                                               <<07410>>02090000
$PAGE "SUBROUTINE QUEUEATHEAD OF QUEUEDISCREQ"                 <<07410>>02095000
SUBROUTINE QUEUEATHEAD;                                        <<07410>>02100000
                                                               <<07410>>02105000
BEGIN                                                          <<07410>>02110000
FIRSTINQUEUE := CHECK'HEAD;                                    <<07410>>02115000
SET'HEAD(DRQ'ENTRY'INDEX);                                     <<07410>>02120000
                                                               <<07410>>02125000
                                                               <<07410>>02130000
IF FIRSTINQUEUE <> 0 THEN                                      <<07410>>02135000
   BEGIN <<Q WAS NON-EMPTY>>                                   <<07410>>02140000
                                                               <<07410>>02145000
   DRQ'PREVQ'WORD(FIRSTINQUEUE) := DRQ'ENTRY'INDEX;            <<07410>>02150000
                                                               <<07410>>02155000
   ARQX'NEXTQ := FIRSTINQUEUE;                                 <<07410>>02160000
   ARQX'PREVQ := 0;                                            <<07410>>02165000
   END                                                         <<07410>>02170000
ELSE                                                           <<07410>>02175000
   BEGIN                                                       <<07410>>02180000
   ARQX'NEXTQ := ARQX'PREVQ := 0;                              <<07410>>02185000
                                                               <<07410>>02190000
   END;                                                        <<07410>>02195000
END <<SUBROUTINE QUEUEATHEAD>>;                                <<07410>>02200000
$PAGE "SUBROUTINE QUEUEATTAIL OF QUEUEDISCREQ"                 <<07410>>02205000
SUBROUTINE QUEUEATTAIL;                                        <<07410>>02210000
                                                               <<07410>>02215000
BEGIN                                                          <<07410>>02220000
LASTINQUEUE := CHECK'TAIL;                                     <<07410>>02225000
SET'TAIL(DRQ'ENTRY'INDEX);                                     <<07410>>02230000
                                                               <<07410>>02235000
                                                               <<07410>>02240000
IF LASTINQUEUE <> 0 THEN                                       <<07410>>02245000
   BEGIN                                                       <<07410>>02250000
                                                               <<07410>>02255000
   DRQ'NEXTQ'WORD(LASTINQUEUE) := DRQ'ENTRY'INDEX;             <<07410>>02260000
                                                               <<07410>>02265000
   ARQX'NEXTQ := 0;                                            <<07410>>02270000
   ARQX'PREVQ := LASTINQUEUE;                                  <<07410>>02275000
   END                                                         <<07410>>02280000
ELSE                                                           <<07410>>02285000
   BEGIN                                                       <<07410>>02290000
                                                               <<07410>>02295000
   ARQX'PREVQ := ARQX'NEXTQ := 0;                              <<07410>>02300000
   END;                                                        <<07410>>02305000
END;                                                           <<07410>>02310000
$PAGE "QUEUE DISC REQUEST"                                     <<07410>>02315000
                                                               <<07410>>02320000
IF QTYPE=SERWQ THEN                                            <<07410>>02325000
   BEGIN <<SERIALIZED WRITE QUEUE>>                            <<07410>>02330000
   IF SERIALWRITEQMGR(REQP,                                    <<07410>>02335000
                        SERWQQUEUECODE,0)                      <<07410>>02340000
   <> SERWQERRALLOK THEN SUDDENDEATH(SFKERNCACHEINTBAD);       <<07410>>02345000
   END                                                         <<07410>>02350000
ELSE   BEGIN                                                   <<07410>>02355000
                                                               <<07410>>02360000
DISABLE;                                                       <<07410>>02365000
IF QTYPE = CDTREQQ THEN  << QUEUE ON DISC CACHE QUEUE >>       <<07410>>02370000
   BEGIN                                                       <<07410>>02375000
   CDT'QUEUE'LDR(TABLE'PTR<<CDT>>,LDR'ENTRY'INDEX,             <<07410>>02380000
                 CDT'MD'LDR'HEAD);                             <<07410>>02385000
   END                                                         <<07410>>02390000
 ELSE BEGIN  << QUEUE ON EITHER DIT OR DISABLE QUEUE >>        <<07410>>02395000
DBTODRQ;                                                       <<07410>>02400000
IF ARQX'PREQ   AND   (DRQ'SERWQ = 0)                           <<07410>>02405000
   THEN SUDDENDEATH(660) ELSE ARQX'PREQ := 1;                  <<07410>>02410000
IN'DISABLED'Q := IF QTYPE = DEFERREDREQQ                       <<07410>>02415000
                    THEN TRUE ELSE FALSE;                      <<07410>>02420000
@DITPOINTER := DITSYSBASEINX;                                  <<07410>>02425000
ABSDITP := DITSYSBASEINX + SYSDB;                              <<07410>>02430000
                                                               <<07410>>02435000
IF (CHECK'IOQP = 0) AND NOT IN'DISABLED'Q THEN << PUT IN DIT >><<07410>>02440000
   BEGIN <<NO CURRENT REQUEST AGAINST THIS DEVICE-MAKE THIS ONE<<07410>>02445000
   SET'IOQP(DRQ'ENTRY'INDEX);                                  <<07410>>02450000
                                                               <<07410>>02455000
   ARQX'CUR'REQ := 1;                                          <<07410>>02460000
   END                                                         <<07410>>02465000
ELSE                                                           <<07410>>02470000
   BEGIN  <<MUST QUEUE REQUEST>>                               <<07410>>02475000
   IF CHECK'HEAD = 0 THEN                                      <<07410>>02480000
      BEGIN  <<FIRST REQUEST IN QUEUE>>                        <<07410>>02485000
      SET'HEAD(DRQ'ENTRY'INDEX);                << QUEUE >>    <<07410>>02490000
      SET'TAIL(DRQ'ENTRY'INDEX);                << AT HEAD >>  <<07410>>02495000
      ARQX'NEXTQ := ARQX'PREVQ := 0;                           <<07410>>02500000
      END                                                      <<07410>>02505000
   ELSE                                                        <<07410>>02510000
      BEGIN                                                    <<07410>>02515000
         << FIND THE POSITION IN THE QUEUE THAT THIS ENTRY >>  <<07410>>02520000
         << SHOULD GO, BASED UPON ITS PRIORITY WHICH IS    >>  <<07410>>02525000
         << DRQ'URGCLASS, AND INSERT IT IN THE QUEUE.      >>  <<07410>>02530000
      IF DRQ'URGCLAS=BKGRNDPRI THEN QUEUEATTAIL ELSE           <<07410>>02535000
         BEGIN <<MERGE REQUEST INTO QUEUE>>                    <<07410>>02540000
         THISREQPRI:=DRQ'URGCLAS;                              <<07410>>02545000
                                                               <<07410>>02550000
         DRQ'X:=FIRSTINQUEUE:=CHECK'HEAD;                      <<07410>>02555000
         FOUND := FALSE;                                       <<07410>>02560000
         WHILE DRQ'X<>0 AND NOT FOUND DO                       <<07410>>02565000
            BEGIN                                              <<07410>>02570000
            IF LOGICAL(DRQ'URGCLAS'WORD(DRQ'X)) <=             <<07410>>02575000
               THISREQPRI                                      <<07410>>02580000
               THEN DRQ'X:=DRQ'NEXTQ'WORD(DRQ'X)               <<07410>>02585000
               ELSE FOUND := TRUE;                             <<07410>>02590000
            END; << WHILE DRQ'X >>                             <<07410>>02595000
                                                               <<07410>>02600000
         IF DRQ'X = 0 THEN QUEUEATTAIL ELSE                    <<07410>>02605000
         IF DRQ'X=FIRSTINQUEUE THEN QUEUEATHEAD ELSE           <<07410>>02610000
            BEGIN  <<QUEUE IN MIDDLE>>                         <<07410>>02615000
            << INSERT BEFORE ELEMENT DRQ'X >>                  <<07410>>02620000
            PREV := DRQ'PREVQ'WORD(DRQ'X);                     <<07410>>02625000
            DRQ'NEXTQ'WORD(PREV) := DRQ'ENTRY'INDEX;           <<07410>>02630000
            ARQX'PREVQ := PREV;                                <<07410>>02635000
            ARQX'NEXTQ := DRQ'X;                               <<07410>>02640000
            DRQ'PREVQ'WORD(DRQ'X) := DRQ'ENTRY'INDEX;          <<07410>>02645000
                                                               <<07410>>02650000
                                                               <<07410>>02655000
                                                               <<07410>>02660000
            END;                                               <<07410>>02665000
         END;                                                  <<07410>>02670000
      END;                                                     <<07410>>02675000
   END;                                                        <<07410>>02680000
                                                               <<07410>>02685000
IF NOT IN'DISABLED'Q THEN                                      <<07410>>02690000
IF CHECK'IOQP = DRQ'ENTRY'INDEX THEN                           <<07410>>02695000
   BEGIN                                                       <<07410>>02700000
   TOS := DBSAVE;                                              <<07410>>02705000
   ASMB( XCHD );                                               <<07410>>02710000
   AWAKEIO( DITPOINTER, 0);                                    <<07410>>02715000
   END;                                                        <<07410>>02720000
TOS := DBSAVE;                                                 <<07410>>02725000
ASMB( XCHD );                                                  <<07410>>02730000
END; << ELSE OF IF CDTREQQ >>                                  <<07410>>02735000
END;   <<   ELSE CLAUSE OF IF SERIALIZED WRITE  >>             <<07410>>02740000
END  <<QUEUEDISCREQ>>;                                         <<07410>>02745000
                                                               <<MPEIV>>02750000
$PAGE "DISC Q MANAGER"                                         <<JB.19>>02755000
PROCEDURE DISCQMANAGER(REQP,REQUESTTYPE);                      <<MPEIV>>02760000
VALUE REQP,REQUESTTYPE;                                        <<MPEIV>>02765000
INTEGER REQP,        <<SYSDB INX OF REQUEST ELEMENT>>          <<MPEIV>>02770000
        REQUESTTYPE; << IF < 0 THEN ABORT (MM TRANSFERS ONLY)>><<MPEIV>>02775000
                  << IF = 0 THEN QUEUE ON DIT QUEUE >>         <<06768>>02780000
                  << IF > THEN QUEUE ON DISABLE (DQH) QUEUE >> <<06768>>02785000
OPTION PRIVILEGED,UNCALLABLE;                                  <<MPEIV>>02790000
                                                               <<MPEIV>>02795000
                                                               <<MPEIV>>02800000
COMMENT                                                        <<MPEIV>>02805000
                                                               <<MPEIV>>02810000
DISCQMANAGER IS CALLED TO QUEUE A REQUEST FOR A DISC           <<MPEIV>>02815000
I/O OR TO DISABLE A PREVIOSLY QUEUED REQUEST. THE PROCEDURE    <<MPEIV>>02820000
IS CALLED FROM ATTACHIO FOR FILE SYSTEM INITIATED DISC         <<MPEIV>>02825000
TRANSFERS, AND FROM PERFORMINITMSG, PERFORMCOMPMSG             <<MPEIV>>02830000
SWAPOUT FOR INITIATING OR ABORTING SEGMENT READ OR             <<MPEIV>>02835000
WRITE REQUESTS ON BEHALF OF MEMORY MANAGEMENT.                 <<MPEIV>>02840000
                                                               <<MPEIV>>02845000
DISC TRANSFER REQUESTS ARE ORDERED WITHIN A DISC QUEUE         <<MPEIV>>02850000
ACCORDING TO THE CPU SCHEDULING CLASS OF THE INITIATING        <<MPEIV>>02855000
PROCESS SO THAT MORE URGENT TRANSFERS ARE PERFORMED FIRST.     <<MPEIV>>02860000
THE DISC MONITOR (SIODM) SELECTS THE MOST URGENT ENABLED       <<MPEIV>>02865000
REQUEST AS THE CURRENT REQUEST FOR THE DEVICE WHEN THE LAST    <<MPEIV>>02870000
REQUEST IS COMPLETED. A SEEK WILL BE PERFORMED FOR THIS        <<MPEIV>>02875000
REQUEST WHILE THE DEVICE IS WAITING FOR THE CONTROLLER.        <<MPEIV>>02880000
CONSEQUENTLY, THE REQUEST WHICH THE MONITOR HAS SELECTED       <<MPEIV>>02885000
AS CURRENT WILL NOT BE PREMTED EVEN IF A MORE URGENT REQUEST   <<MPEIV>>02890000
COMES IN AND REQUESTS TO DELAY OR ABORT THE CURRENT REQUEST    <<MPEIV>>02895000
WILL NOT BE HONORED-THE TRANSFER WILL BE PERFORMED, AND        <<MPEIV>>02900000
THE MONITOR COMPLETER WILL TAKE CARE OF ENABLING ANY           <<MPEIV>>02905000
ACTION PENDING THE DISC TRANSFER.                              <<MPEIV>>02910000
                                                               <<MPEIV>>02915000
STATUS IS RETURNED THROUGH THE CONDITION CODE AS FOLLOWS :     <<MPEIV>>02920000
   CC=CCL ==> INDICATED TRANSFER REQUEST                       <<MPEIV>>02925000
              ALREADY COMPLETED                                <<MPEIV>>02930000
   CC=CCE ==> SUCCESSFUL COMPLETION OF                         <<MPEIV>>02935000
              REQUESTED ACTION                                 <<MPEIV>>02940000
   CC=CCG ==> INDICATED REQUEST IS THE                         <<MPEIV>>02945000
              DISC'S CURRENT REQUEST                           <<MPEIV>>02950000
                                                               <<MPEIV>>02955000
                                                               <<MPEIV>>02960000
;                                                              <<MPEIV>>02965000
                                                               <<MPEIV>>02970000
BEGIN                                                          <<MPEIV>>02975000
                                                               <<MPEIV>>02980000
INTEGER  DITSYSBASEINX,                                        <<MPEIV>>02985000
         QHEADERP;                                             <<MPEIV>>02990000
INTEGER POINTER DITPOINTER;                                    <<MPEIV>>02995000
LOGICAL URGCLASS;                                              <<MPEIV>>03000000
INTEGER QCLASS;                                                <<MPEIV>>03005000
INTEGER LPDT'INDEX;                                            <<06768>>03010000
                                                               <<MPEIV>>03015000
INTEGER                                                        <<06768>>03020000
   LDR'ENTRY'INDEX=REQP,                                       <<06768>>03025000
   DRQ'ENTRY'INDEX=REQP,                                       <<06768>>03030000
   DRQ'X;                                                      <<06768>>03035000
<<DB IS ASSUMED TO BE AT SYSDB>>                               <<MPEIV>>03040000
                                                               <<MPEIV>>03045000
                                                               <<MPEIV>>03050000
                                                              <<<06768>>03055000
DISABLE;                                                       <<MPEIV>>03060000
TOS:=DRQ'FLAGS;                                                <<06768>>03065000
ASMB(TBC COMPLETED');                                          <<MPEIV>>03070000
IF <> THEN RSTATUS.CC:=CCL   <<ALREADY COMPLETED>> ELSE        <<MPEIV>>03075000
   BEGIN                                                       <<MPEIV>>03080000
   ASMB (TBC DITSCURRREQBIT);                                  <<MPEIV>>03085000
   IF <> THEN                                                  <<MPEIV>>03090000
      BEGIN <<REQUEST IS THE DISC'S CURRENT REQUEST>>          <<MPEIV>>03095000
      RSTATUS.CC:=CCG;                                         <<MPEIV>>03100000
      TOS:=REQUESTTYPE;                                        <<MPEIV>>03105000
      ASMB(DEL);                                               <<MPEIV>>03110000
      IF > THEN SUDDENDEATH(SFKERNBADPARM) <<NOT SUPPORTED>>   <<06768>>03115000
      ELSE IF < THEN TOS.ABORTREQATTMPTFLAG:=1;                <<MPEIV>>03120000
      DRQ'FLAGS := TOS;                                        <<06768>>03125000
      END                                                      <<MPEIV>>03130000
   ELSE                                                        <<MPEIV>>03135000
      BEGIN                                                    <<MPEIV>>03140000
      RSTATUS.CC:=CCE;                                         <<MPEIV>>03145000
      LPDT'INDEX :=INTEGER(DRQ'LDEV)* INTEGER(LPDT'ENTRY'SIZE);<<06768>>03150000
      TOS := LPDT'DIT'PTR;                                     <<06768>>03155000
                                                               <<06768>>03160000
      DITSYSBASEINX:=S0;                                       <<MPEIV>>03165000
      @DITPOINTER:=S0;                                         <<MPEIV>>03170000
      X:=TOS; <<DIRECT ACCESS TO DIT INFO>>                    <<MPEIV>>03175000
      QHEADERP:=DITQHEADP;                                     <<MPEIV>>03180000
                                                               <<06768>>03185000
      TOS:=REQUESTTYPE;                                        <<MPEIV>>03190000
      ASMB(DEL);                                               <<MPEIV>>03195000
      IF <> THEN                                               <<MPEIV>>03200000
         BEGIN <<DISABLE OR ABORT REQUEST>>                    <<MPEIV>>03205000
         IF < THEN                                             <<MPEIV>>03210000
            BEGIN <<AN ABORT REQUEST>>                         <<MPEIV>>03215000
            IF LDR'LDREQ THEN SUDDENDEATH(SFKERNBADPARM);      <<06768>>03220000
            DEQUEUEDISCREQ(DRQ'ENTRY'INDEX,                    <<06768>>03225000
                           2,DITSYSBASEINX);                   <<06768>>03230000
            TOS := DRQ'ENTRY'INDEX;                            <<06768>>03235000
            RETURNDISCREQ(*);                                  <<01640>>03240000
            END                                                <<MPEIV>>03245000
         ELSE                                                  <<MPEIV>>03250000
            BEGIN <<A DISABLE REQUEST>>                        <<MPEIV>>03255000
            << Not currently supported >>                      <<06768>>03260000
                                                               <<06768>>03265000
            SUDDENDEATH(SFKERNBADPARM);                        <<06768>>03270000
                                                               <<06768>>03275000
                                                               <<06768>>03280000
            END;                                               <<MPEIV>>03285000
         END                                                   <<MPEIV>>03290000
      ELSE                                                     <<MPEIV>>03295000
         BEGIN <<QUEUE, INCREASE URGENCY, OR ENABLE>>          <<MPEIV>>03300000
         ASMB (TBC REQQUEUEDBIT);                              <<MPEIV>>03305000
         IF = THEN                                             <<MPEIV>>03310000
            BEGIN << MUST QUEUE REQUEST >>                     <<06768>>03315000
            DRQ'DISABLE:=0;                                    <<06768>>03320000
            QUEUEDISCREQ(DRQ'ENTRY'INDEX,                      <<06768>>03325000
                         2,DITSYSBASEINX);                     <<06768>>03330000
            END                                                <<MPEIV>>03335000
         ELSE                                                  <<MPEIV>>03340000
            BEGIN <<ALREADY QUEUED-MAYBE HAVE TO MOVE IN QUEUE><<MPEIV>>03345000
            IF DRQ'PREVQ <> 0  THEN                            <<06768>>03350000
                                                               <<06768>>03355000
                                                               <<06768>>03360000
               BEGIN <<NOT ALONE IN THE QUEUE>>                <<MPEIV>>03365000
            IF LOGICAL(DRQ(DRQ'PREVQ                           <<06768>>03370000
               +DRQ'URGCLAS'INDEX)) >                          <<06768>>03375000
                  DRQ'URGCLAS THEN                             <<06768>>03380000
                  BEGIN <<MUST MOVE REQ IN QUEUE>>             <<MPEIV>>03385000
                  DEQUEUEDISCREQ(DRQ'ENTRY'INDEX               <<06768>>03390000
                              ,2,DITSYSBASEINX);               <<06768>>03395000
                  QUEUEDISCREQ(DRQ'ENTRY'INDEX                 <<06768>>03400000
                            ,2,DITSYSBASEINX);                 <<06768>>03405000
                  END; << IF LOGICAL DRQ >>                    <<06768>>03410000
               END; << IF DRQ'PREVQ <> 0 >>                    <<06768>>03415000
            END; << ELSE OF IF REQQUEUEBIT = >>                <<06768>>03420000
         END; << ELSE OF IF REQUESTTYPE <> >>                  <<06768>>03425000
      END; << ELSE OF IF DITSCURRREQBIT <> >>                  <<06768>>03430000
   END; << IF COMPLETED' <> >>                                 <<06768>>03435000
END  <<PROCEDURE DISCQMANAGER>>;                               <<MPEIV>>03440000
                                                               <<06768>>03445000
$PAGE "BUMP WRITE PRIORITY"                                    <<06768>>03450000
                                                               <<06768>>03455000
PROCEDURE BUMPWRITEPRI(DISCREQENTRYINDEX,NEWPRI);              <<06768>>03460000
VALUE DISCREQENTRYINDEX, NEWPRI;                               <<06768>>03465000
INTEGER DISCREQENTRYINDEX;                                     <<06768>>03470000
LOGICAL NEWPRI;                                                <<06768>>03475000
OPTION PRIVILEGED,UNCALLABLE;                                  <<06768>>03480000
                                                               <<06768>>03485000
COMMENT                                                        <<06768>>03490000
                                                               <<06768>>03495000
BUMPWRITEPRI PUTS THE CURRENT PRIORITY OF THE DISC WRITE REQUES<<06768>>03500000
SPECIFIED IN THE DISCREQENTRYINDEX PARAMETER TO THE VALUE PASSE<<06768>>03505000
IN THE NEWPRI PARAMETER.  IF THE SPECIFIED DISC REQUEST IS IN T<<06768>>03510000
SERIALIZED WRITE QUEUE, ALL DISC REQUESTS IN FRONT OF IT ARE   <<06768>>03515000
BUMPED TO AT LEAST ITS PRIORITY.  IF THE DISC REQUEST ENTRY IS <<06768>>03520000
A DIT QUEUE, THE DISCQUEUEMANAGER IS CALLED TO MOVE THE DISC RE<<06768>>03525000
TO ITS PROPER LOCATION IN THE QUEUE.                           <<06768>>03530000
                                                               <<06768>>03535000
DB IS ASSUMED TO BE AT SYSDB.                                  <<06768>>03540000
;                                                              <<06768>>03545000
                                                               <<06768>>03550000
BEGIN                                                          <<06768>>03555000
                                                               <<06768>>03560000
INTEGER DRQ'ENTRY'INDEX,                                       <<06768>>03565000
        LDR'ENTRY'INDEX = DRQ'ENTRY'INDEX;                     <<06768>>03570000
                                                               <<06768>>03575000
DRQ'ENTRY'INDEX := DISCREQENTRYINDEX;                          <<06768>>03580000
                                                               <<06768>>03585000
IF DRQ'PREQ = 0  THEN  RETURN;  << RETURN IF NOT QUEUED >>     <<07341>>03590000
                                                               <<07341>>03595000
<<BUMP THIS GUYS PRI IF NOT ALREADY BETTER>>                   <<06768>>03600000
                                                               <<06768>>03605000
IF DRQ'URGCLAS > NEWPRI                                        <<06768>>03610000
THEN DRQ'URGCLAS := NEWPRI;                                    <<06768>>03615000
                                                               <<06768>>03620000
<<NOW POSITION HIM IN QUEUE OR BUMP IN FRONT>>                 <<06768>>03625000
                                                               <<06768>>03630000
IF DRQ'SERWQ THEN                                              <<06768>>03635000
   BEGIN  <<ITS ON THE SERIAL WRITE QUEUE>>                    <<06768>>03640000
   DISABLE;                                                    <<06768>>03645000
   IF NOT LDR'CUR'REQ THEN  << SAME AS DRQ DEFINE >>           <<06768>>03650000
   IF NOT LDR'DONE THEN                                        <<06768>>03655000
      BEGIN                                                    <<06768>>03660000
      DRQ'ENTRY'INDEX := DQH'SERWQHEAD;                        <<06768>>03665000
      WHILE DRQ'ENTRY'INDEX <> DISCREQENTRYINDEX DO            <<06768>>03670000
         BEGIN <<BUMP>>                                        <<06768>>03675000
         IF DRQ'URGCLAS > NEWPRI                               <<06768>>03680000
         THEN DRQ'URGCLAS := NEWPRI;                           <<06768>>03685000
         DRQ'ENTRY'INDEX := DRQ'NEXTQ;                         <<06768>>03690000
         END;                                                  <<06768>>03695000
      END;                                                     <<06768>>03700000
   END                                                         <<06768>>03705000
ELSE                                                           <<06768>>03710000
   BEGIN <<MUST BE A DIT Q>>                                   <<06768>>03715000
   DISCQMANAGER(DISCREQENTRYINDEX,                             <<06768>>03720000
      QUEUEREQCODE);                                           <<06768>>03725000
   IF < THEN SUDDENDEATH(618); <<ALREADY COMPLETED>>           <<06768>>03730000
   END;                                                        <<06768>>03735000
END;  << PROCEDURE BUMPWRITEPRI >>                             <<06768>>03740000
$PAGE "SERIAL WRITE QUEUE MANAGER"                             <<06768>>03745000
INTEGER PROCEDURE SERIALWRITEQMGR (DISCREQENTRYINDEX,          <<06768>>03750000
                                   CONTROLCODE, AUXINFO);      <<06768>>03755000
VALUE DISCREQENTRYINDEX, CONTROLCODE, AUXINFO;                 <<06768>>03760000
INTEGER DISCREQENTRYINDEX, CONTROLCODE, AUXINFO;               <<06768>>03765000
OPTION PRIVILEGED,UNCALLABLE;                                  <<06768>>03770000
                                                               <<06768>>03775000
COMMENT                                                        <<06768>>03780000
                                                               <<06768>>03785000
THE SERIALWRITEQMGR MANAGES THE SERIAL WRITE Q.                <<06768>>03790000
                                                               <<06768>>03795000
MANAGEMENT FUNCTIONS INCLUDE INSERTION AT THE TAIL, DELETION FR<<06768>>03800000
THE HEAD, AND URG'CLASS CHANGING OF ALREADY QUEUED MEMORY MANAG<<06768>>03805000
WRITE REQUEST ENTRIES.                                         <<06768>>03810000
                                                               <<06768>>03815000
               PARAMETER DESCRIPTION                           <<06768>>03820000
                                                               <<06768>>03825000
DISCREQENTRYINDEX :                                            <<06768>>03830000
                                                               <<06768>>03835000
THE DISC REQ TAB INX OF THE DISC REQUEST ENTRY TO BE ADJUSTED I<<06768>>03840000
THE DISCREQENTRYINDEX PARAMETER.                               <<06768>>03845000
                                                               <<06768>>03850000
CONTROLCODE :                                                  <<06768>>03855000
                                                               <<06768>>03860000
THE CONTROLCODE PARAMETER TELLS THE SERIAL WRITE QUEUE MANAGER <<06768>>03865000
FUNCTION TO PERFORM.                                           <<06768>>03870000
                                                               <<06768>>03875000
   CONTROLCODE = SERQQUEUECODE   ==> QUEUE THIS REQUEST AT THE <<06768>>03880000
                                     OF THE SERIAL WRITE Q     <<06768>>03885000
                                                               <<06768>>03890000
   CONTROLCODE = SERQDEQUEUECODE ==> TAKE THIS REQUEST OFF OF T<<06768>>03895000
                                     SERIAL WRITE QUEUE. (MUST <<06768>>03900000
                                     AT HEAD OF QUEUE)         <<06768>>03905000
                                                               <<06768>>03910000
                                                               <<06768>>03915000
AUXINFO :                                                      <<06768>>03920000
                                                               <<06768>>03925000
THE AUXINFO PARAMETER IS USED TO PASS ALONG INFO NEEDED TO COMP<<06768>>03930000
THE REQUESTED ACTION ON THE SPECIFIED DISC WRITE REQUEST.  THE <<06768>>03935000
PARAMETER USAGE DEPENDS ON THE CONTROL CODE.                   <<06768>>03940000
                                                               <<06768>>03945000
                                                               <<06768>>03950000
RETURNVALUE :                                                  <<06768>>03955000
                                                               <<06768>>03960000
THE ERROR STATUS IS RETURNED .                                 <<06768>>03965000
                                                               <<06768>>03970000
   SERIALWRITEQMGR = SERWQERRALLOK ==> ALL OK                  <<06768>>03975000
                   = SERWQERRNOTATHEAD ==> TRIED TO DELETE     <<06768>>03980000
                                           ELT NOT AT HEAD     <<06768>>03985000
;                                                              <<06768>>03990000
                                                               <<06768>>03995000
                                                               <<06768>>04000000
BEGIN                                                          <<06768>>04005000
                                                               <<06768>>04010000
INTEGER DRQ'ENTRY'INDEX,  LPDT'INDEX; << FOR INCLUDE FILES >>  <<07341>>04015000
INTEGER POINTER DITPOINTER;                                    <<06768>>04020000
INTEGER WRITEQLENGTH := 0;                                     <<06768>>04025000
                                                               <<06768>>04030000
SERIALWRITEQMGR := SERWQERRALLOK; <<ASSUME SUCCESS>>           <<06768>>04035000
LPDT'INDEX := INTEGER(DRQ(DRQ'LDEV'INDEX+DISCREQENTRYINDEX))   <<07341>>04040000
                 * INTEGER(LPDT'ENTRY'SIZE);  << PEG LPDT >>   <<07341>>04045000
DISABLE;  <<THROUGHOUT>>                                       <<06768>>04050000
                                                               <<06768>>04055000
IF CONTROLCODE = SERWQDEQUEUECODE THEN                         <<06768>>04060000
   BEGIN <<TAKE OFF OF HEAD OF SERIAL WRITEQ>>                 <<06768>>04065000
   IF DQH'SERWQHEAD <> LOGICAL(DISCREQENTRYINDEX)              <<06768>>04070000
   THEN SERIALWRITEQMGR := SERWQERRNOTHEAD <<WASN'T HEAD>>     <<06768>>04075000
   ELSE                                                        <<06768>>04080000
      BEGIN <<OK-TAKE IT OFF, MAKE NEXT NEW HEAD>>             <<06768>>04085000
      DRQ'ENTRY'INDEX := DISCREQENTRYINDEX;                    <<06768>>04090000
      DQH'SERWQHEAD := DRQ'NEXTQ;                              <<06768>>04095000
      DRQ'NEXTQ := 0;                                          <<06768>>04100000
      END;                                                     <<06768>>04105000
   END                                                         <<06768>>04110000
ELSE IF CONTROLCODE = SERWQQUEUECODE THEN                      <<06768>>04115000
   BEGIN <<QUEUE AT TAIL OF SERIAL WRITE Q>>                   <<06768>>04120000
   DRQ'ENTRY'INDEX := DISCREQENTRYINDEX;                       <<06768>>04125000
   DRQ'SERWQ := 1; <<MARK AS A SERIAL WRITE REQ>>              <<06768>>04130000
   IF DRQ'PREQ  THEN  SUDDENDEATH(660);                        <<07341>>04135000
   DRQ'PREQ := 1;   <<  MARK  REQUEST  AS  QUEUED  >>          <<07341>>04140000
   IF DQH'SERWQHEAD = 0 THEN                                   <<06768>>04145000
      BEGIN <<QUEUE IS EMPTY>>                                 <<06768>>04150000
      @DITPOINTER := LPDT'DIT'PTR;                             <<07341>>04155000
      IF DITPOINTER(DIOQP) = 0 <<TEMP-FIX WITH MPEV>>          <<06768>>04160000
      AND DQH'FLAGS.DQH'ACTSERWRFLAG=0 THEN                    <<06768>>04165000
         BEGIN <<GIVE THIS REQ DIRECTLY TO SIODM>>             <<06768>>04170000
         DQH'FLAGS.DQH'ACTSERWRFLAG := 1;                      <<06768>>04175000
         QUEUEDISCREQ(DISCREQENTRYINDEX,                       <<06768>>04180000
                        DITREQQ,@DITPOINTER)                   <<06768>>04185000
         END                                                   <<06768>>04190000
      ELSE                                                     <<06768>>04195000
         BEGIN <<INSERT INTO THE SERIALIZED WRITE Q>>          <<06768>>04200000
         DQH'SERWQHEAD := DISCREQENTRYINDEX;                   <<06768>>04205000
         DRQ'NEXTQ := 0;                                       <<06768>>04210000
         END;                                                  <<06768>>04215000
      END                                                      <<06768>>04220000
   ELSE                                                        <<06768>>04225000
      BEGIN                                                    <<06768>>04230000
      <<LOCATE TAIL>>                                          <<06768>>04235000
      WRITEQLENGTH := 1;                                       <<06768>>04240000
      DRQ'ENTRY'INDEX := DQH'SERWQHEAD;                        <<06768>>04245000
      WHILE DRQ'NEXTQ <> 0 DO                                  <<06768>>04250000
         BEGIN <<FLIP TO END OF SER W Q>>                      <<06768>>04255000
         WRITEQLENGTH := WRITEQLENGTH+1;                       <<06768>>04260000
         DRQ'ENTRY'INDEX := DRQ'NEXTQ;                         <<06768>>04265000
         END;                                                  <<06768>>04270000
                                                               <<06768>>04275000
      <<UPDATE MAX Q LENGTH CTR>>                              <<06768>>04280000
                                                               <<06768>>04285000
      IF WRITEQLENGTH > INTEGER(DQH'MAXSERWQ)                  <<06768>>04290000
      THEN DQH'MAXSERWQ := WRITEQLENGTH;                       <<06768>>04295000
                                                               <<06768>>04300000
      <<PUT THE NEW ELEMENT AT THE TAIL>>                      <<06768>>04305000
                                                               <<06768>>04310000
      DRQ'NEXTQ := DISCREQENTRYINDEX;                          <<06768>>04315000
                                                               <<06768>>04320000
      <<ZAP NEXT PTR, SET SERIAL BIT IN ELEMENT TO BE ADDED>>  <<06768>>04325000
                                                               <<06768>>04330000
      DRQ'ENTRY'INDEX := DISCREQENTRYINDEX;                    <<06768>>04335000
      DRQ'NEXTQ := 0;                                          <<06768>>04340000
                                                               <<06768>>04345000
      <<NOW BUMP PRI OF EVERYONE IN FRONT TO AT LEAST THIS>>   <<06768>>04350000
                                                               <<06768>>04355000
      BUMPWRITEPRI(DRQ'ENTRY'INDEX,DRQ'URGCLAS);               <<06768>>04360000
      END;                                                     <<06768>>04365000
   END;                                                        <<06768>>04370000
END;  <<PROCEDUE SERIALWRITEQMGR>>                             <<06768>>04375000
$PAGE "MPE TABLE FULL PROCESSOR"                               <<02801>>04380000
procedure MPE'TABLE'FULL(TABLE'NUMBER);                        <<02801>>04385000
value TABLE'NUMBER;  integer TABLE'NUMBER;                     <<02801>>04390000
option uncallable,privileged;                                  <<02801>>04395000
begin                                                          <<02801>>04400000
<< This procedure sends a basic IPC message to IOMESSPROC >>   <<02801>>04405000
<< passing the index of an MPE table that has filled.     >>   <<02801>>04410000
                                                               <<02801>>04415000
define IOMSGPIN = absolute(%1152)/PCBSIZE#;                    <<02801>>04420000
                                                               <<02801>>04425000
tos := 1;   << Msg type 1 is table overflow >>                 <<02801>>04430000
tos := TABLE'NUMBER;  << Number of MPE table that overflowed >><<02801>>04435000
tos := 0D;  << dummy parameters >>                             <<02801>>04440000
SENDMSG(IOMSGPIN,0,4,%40000<<pri or secondary>>);              <<02801>>04445000
end;                                                           <<02801>>04450000
$PAGE "MPE DEVICE MAINTENENCE REQUEST SCHEDULER"               <<03071>>04455000
procedure MAINT'REQUEST(LDEV,TYPE,SUBTYPE);                    <<03071>>04460000
value LDEV,TYPE,SUBTYPE;                                       <<03071>>04465000
integer LDEV,TYPE,SUBTYPE;                                     <<03071>>04470000
option privileged,uncallable;                                  <<03071>>04475000
begin                                                          <<03071>>04480000
<< This procedure sends a basic IPC message to process >>      <<03071>>04485000
<< IOMESSAGE to perform maintenence processing on a    >>      <<03071>>04490000
<< requesting LDEV.                                    >>      <<03071>>04495000
                                                               <<03071>>04500000
define IOMSGPIN = absolute(%1152)/PCBSIZE#;                    <<03071>>04505000
                                                               <<03071>>04510000
tos := 4;       << MSG type 4 is maintenence request >>        <<03071>>04515000
tos := LDEV;                                                   <<03071>>04520000
tos := TYPE;                                                   <<03071>>04525000
tos := SUBTYPE;                                                <<03071>>04530000
SENDMSG(IOMSGPIN,0,4,%40000 << pri or secondary >> );          <<03071>>04535000
end;                                                           <<03071>>04540000
$PAGE "MPE DCU LOGGING REQUEST SCHEDULER"                      <<04188>>04545000
procedure DCU'REQUEST(PARM);                                   <<04188>>04550000
value PARM;  integer PARM;                                     <<04188>>04555000
option privileged,uncallable;                                  <<04188>>04560000
begin                                                          <<04188>>04565000
                                                               <<04188>>04570000
<< This procedure is called by ININ to process DCU   >>        <<04188>>04575000
<< requests from the Series/64 processor.  The msg   >>        <<04188>>04580000
<< sent to IOMSGPROC tells it to either initiate a   >>        <<04188>>04585000
<< new DCU information dump or that the DCU dump is  >>        <<04188>>04590000
<< done.                                             >>        <<04188>>04595000
                                                               <<04188>>04600000
define IOMSGPIN = absolute(%1152)/PCBSIZE#;                    <<04188>>04605000
                                                               <<04188>>04610000
tos := 5;      << MSG type 5 is DCU request from ININ >>       <<04188>>04615000
tos := PARM;   << PARM.(0:15) is the byte count Xfered>>       <<04188>>04620000
               << PARM.(15:1) = 0 for initiate, 1 for >>       <<04188>>04625000
               <<               completed.            >>       <<04188>>04630000
tos := 0D;     << Dummy parameters                    >>       <<04188>>04635000
SENDMSG(IOMSGPIN,0,4,%40000 << pri or sec. table >> );         <<04188>>04640000
end;      << of procedure DCU'REQUEST >>                       <<04188>>04645000
$PAGE  "CHECKINDEX"                                                     04650000
<<*********************************************************>>           04655000
                                                                        04660000
<<                   CHECKINDEX                                         04665000
                                                                        04670000
    CALLS     :   SUDDENDEATH(249)                                      04675000
                                                                        04680000
    CALLED BY :   RETURNGBUF                                            04685000
                  GETGBUF                                               04690000
                                                                        04695000
    INPUTS    :   INDEX OF TABLE                                        04700000
                  TBASE                                                 04705000
                                                                        04710000
    OUTPUTS   :   NONE                                                  04715000
                                                                        04720000
    MODIFIED  :   1/16/83  RK                                           04725000
                                                                        04730000
    PURPOSE   :   THIS PROCEDURE CHECKS THAT INDEX IS                   04735000
                  A VALID INDEX IN THE TABLE WHOSE BASE                 04740000
                  IS TBASE.  IF INDEX IS OUT OF BOUNDS OR               04745000
                  INVALID THEN SUDDENDEATH 249 OCCURS.                 04750000
                                                            >>          04755000
<<**********************************************************>>          04760000
                                                                        04765000
                                                               <<06768>>04770000
PROCEDURE CHECKINDEX( INDEX, TBLNUM);                          <<07410>>04775000
   VALUE INDEX, TBLNUM;                                        <<07410>>04780000
   LOGICAL INDEX;                                              <<07410>>04785000
   INTEGER TBLNUM;                                             <<07410>>04790000
   OPTION PRIVILEGED, UNCALLABLE;                              <<07410>>04795000
BEGIN                                                          <<07410>>04800000
                                                               <<07410>>04805000
   IF NOT( 1<= TBLNUM <= 3 ) THEN SUDDENDEATH( 249);           <<07410>>04810000
                                                               <<07410>>04815000
   CASE *X OF                                                  <<07410>>04820000
      BEGIN                                                    <<07410>>04825000
                                                               <<07410>>04830000
<<0>> ;                                                        <<07410>>04835000
                                                               <<07410>>04840000
<<1>> BEGIN << CHECK SBUF INDEX BOUNDS >>                      <<07410>>04845000
      IF INDEX > LOGICAL( SBH'ENT'SIZE*(SBH'TOT'ENT+1) )       <<07410>>04850000
         THEN SUDDENDEATH( 249);                               <<07410>>04855000
      END;                                                     <<07410>>04860000
                                                               <<07410>>04865000
<<2>> BEGIN << CHECK IOQ INDEX BOUNDS >>                       <<07410>>04870000
      IF (INDEX > LOGICAL( IQH'ENT'SIZE*(IQH'TOT'ENT+1) )) OR  <<07410>>04875000
         (INDEX MOD LOGICAL( IQH'ENT'SIZE ) <> 0)              <<07410>>04880000
         THEN SUDDENDEATH( 249);                               <<07410>>04885000
      END;                                                     <<07410>>04890000
                                                               <<07410>>04895000
<<3>> BEGIN << CHECK DRQ INDEX BOUNDS >>                       <<07410>>04900000
      IF (INDEX > LOGICAL( DQH'ENT'SIZE*(DQH'TOT'ENT+1) )) OR  <<07410>>04905000
         (INDEX MOD LOGICAL( DQH'ENT'SIZE ) <> 0)              <<07410>>04910000
         THEN SUDDENDEATH( 249);                               <<07410>>04915000
      END;                                                     <<07410>>04920000
                                                               <<07410>>04925000
      END; <<CASE>>                                            <<07410>>04930000
                                                               <<07410>>04935000
END;   << CHECKINDEX >>                                        <<07410>>04940000
<<*********************************************************>>           04945000
                                                                        04950000
<<                  GETSBUF                                             04955000
                                                                        04960000
    CALLS      :                                                        04965000
                                                                        04970000
    CALLED BY  :                                                        04975000
                                                                        04980000
    INPUTS     :                                                        04985000
                                                                        04990000
    OUTPUTS    :                                                        04995000
                                                                        05000000
    MODIFIED   :  12/30/82  RK                                          05005000
                                                                        05010000
    PURPOSE    :  THIS PROCEDURE GETS AN I/O TABLE ENTRY FROM           05015000
                  A PRIMARY OR SECONDARY TABLE.  IF THE TABLE           05020000
                  IS EMPTY THE CALLER MAY BE IMPEEDED IF HE             05025000
                  SO SPECIFIES.  A SYSDB RELATIVE POINTER IS            05030000
                  RETURNED TO THE BUFFER RETRIEVED.                     05035000
                                                           >>           05040000
                                                                        05045000
<<*********************************************************>>           05050000
                                                                        05055000
INTEGER PROCEDURE GETSBUF(TYPE);                               <<06768>>05060000
   VALUE TYPE;                                                 <<06768>>05065000
   INTEGER TYPE;                                               <<06768>>05070000
   OPTION UNCALLABLE,PRIVILEGED;                               <<06768>>05075000
                                                               <<06768>>05080000
   << TYPE  -  0 - IMPEDE IF PRIMARY TABLE IS EMPTY                     05085000
               1 - GET FROM PRIMARY ONLY,IF EMPTY RETURN 0              05090000
               2 - GET FROM PRIMARY OR SECONDARY, RETURN 0              05095000
                   IF BOTH TABLES ARE EMPTY  >>                         05100000
                                                               <<06768>>05105000
                                                               <<06768>>05110000
BEGIN                                                          <<06768>>05115000
                                                               <<06768>>05120000
                                                               <<06768>>05125000
                                                               <<06768>>05130000
                                                               <<06768>>05135000
                                                               <<06768>>05140000
                                                               <<06768>>05145000
                                                               <<06768>>05150000
                                                               <<06768>>05155000
   INTEGER SBF'ENTRY'INDEX;                                    <<06768>>05160000
                                                               <<06768>>05165000
                                                               <<06768>>05170000
                                                               <<06768>>05175000
   DISABLE;                                                    <<07410>>05180000
                                                               <<07410>>05185000
                                                               <<*7698>>05190000
                                                               <<*7698>>05195000
                                                               <<*7698>>05200000
L3:                                                            <<07410>>05205000
                                                               <<06768>>05210000
   PDISABLE;   << PROTECT AGAINST IOMESSPROC >>                <<*7572>>05215000
   SBF'ENTRY'INDEX := SBH'FREEHEAD;                            <<06768>>05220000
                                                               <<06768>>05225000
                                                               <<06768>>05230000
   << CHECK IF ENTRIES CURRENTLY IN USE ARE MORE THAN >>       <<06768>>05235000
   << THE PRIMARY ENTRIES AVAILABLE                   >>       <<06768>>05240000
                                                               <<*7572>>05245000
   DISABLE;                                                    <<06768>>05250000
   IF SBH'CUR'NUSE >= SBH'PRI'ENT                              <<06768>>05255000
      THEN                                                     <<06768>>05260000
         BEGIN  << IF TABLE OVERFLOWED FIRST TIME >>           <<06768>>05265000
                << THEN SEND A MESSAGE >>                      <<06768>>05270000
         IF SBH'OVRFLOWS = 0                                   <<06768>>05275000
           THEN MPE'TABLE'FULL( SBUF'TABLE);                   <<07410>>05280000
         SBH'OVRFLOWS := SBH'OVRFLOWS + 1; << BUMP>>           <<06768>>05285000
         IF TYPE = PRIMARY THEN GO TO EXIT;                    <<*7572>>05290000
         IF <          << IMPEDABLE       >>                   <<06768>>05295000
            THEN                                               <<06768>>05300000
               BEGIN                                           <<06768>>05305000
               IOIMPEDE(  SBUF'TABLE    );  << WILL PENABLE >> <<*7572>>05310000
               GOTO L3;                                        <<06768>>05315000
               END;                                            <<06768>>05320000
         END;                                                  <<06768>>05325000
                                                               <<06768>>05330000
   IF SBH'FREEHEAD = 0                                         <<06768>>05335000
      THEN GO EXIT;          << SEC. TAB. EMPTY>>              <<*7572>>05340000
                                                               <<06768>>05345000
                             << PT. TO LINK >>                 <<06768>>05350000
   CHECKINDEX( SBF'ENTRY'INDEX, SBUF'TABLE);                   <<07410>>05355000
   GETSBUF := SBF'ENTRY'INDEX;                                 <<06768>>05360000
   SBH'FREEHEAD := SBF'LINK;         << RELINK LIST>>          <<06768>>05365000
   IF SBF'LINK = 0                   << TABLE EMP.>>           <<06768>>05370000
       << the +1 below is so that the header acts as an      >><<*7983>>05375000
       << sbuf entry on the first return after all sbuf are  >><<*7983>>05380000
       << in use.  The index points to the free tail and the >><<*7983>>05385000
       << free head is used as the link word by RETURNSBUF   >><<*7983>>05390000
      THEN SBH'FREETAIL := SBH'FREEHEAD'INDEX  + 1             <<*7983>>05395000
      ELSE SBF'LINK := 0;            << CLEAR LINK>>           <<06768>>05400000
   SBH'CUR'NUSE  := SBH'CUR'NUSE + 1;                          <<06768>>05405000
   SBH'REQCOUNU := INTEGER(SBH'REQCOUNU + 1);                  <<*7698>>05410000
   IF CARRY   << INC. DOUBLE WORD COUNT - REQCOUNT & REQCOUNU>><<*7698>>05415000
      THEN SBH'REQCOUNT := SBH'REQCOUNT + 1;                   <<*7698>>05420000
   IF SBH'MAX'NUSE < SBH'CUR'NUSE                              <<06768>>05425000
      THEN                       << MAX < CUR. USE>>           <<06768>>05430000
         SBH'MAX'NUSE := SBH'CUR'NUSE;     << BUMP >>          <<06768>>05435000
EXIT:                                                          <<*7572>>05440000
   PENABLE;                                                    <<*7572>>05445000
END;                                                           <<06768>>05450000
                                                               <<06768>>05455000
                                                               <<06768>>05460000
<<*********************************************************>>           05465000
                                                                        05470000
<<                  GETIOQ                                              05475000
                                                                        05480000
    CALLS      :                                                        05485000
                                                                        05490000
    CALLED BY  :                                                        05495000
                                                                        05500000
    INPUTS     :                                                        05505000
                                                                        05510000
    OUTPUTS    :                                                        05515000
                                                                        05520000
    MODIFIED   :  12/30/82  RK                                          05525000
                                                                        05530000
    PURPOSE    :  THIS PROCEDURE GETS AN I/O TABLE ENTRY FROM           05535000
                  A PRIMARY OR SECONDARY TABLE.  IF THE TABLE           05540000
                  IS EMPTY THE CALLER MAY BE IMPEEDED IF HE             05545000
                  SO SPECIFIES.  A SYSDB RELATIVE POINTER IS            05550000
                  RETURNED TO THE BUFFER RETRIEVED.                     05555000
                                                           >>           05560000
                                                                        05565000
<<*********************************************************>>           05570000
                                                                        05575000
INTEGER PROCEDURE GETIOQ(TYPE);                               <<*IO5*>> 05580000
   VALUE TYPE;                                                 <<06768>>05585000
   INTEGER TYPE;                                               <<06768>>05590000
   OPTION UNCALLABLE,PRIVILEGED;                               <<06768>>05595000
                                                               <<06768>>05600000
   << TYPE  -  0 - IMPEDE IF PRIMARY TABLE IS EMPTY                     05605000
               1 - GET FROM PRIMARY ONLY,IF EMPTY RETURN 0              05610000
               2 - GET FROM PRIMARY OR SECONDARY, RETURN 0              05615000
                   IF BOTH TABLES ARE EMPTY  >>                         05620000
                                                               <<06768>>05625000
                                                               <<06768>>05630000
BEGIN                                                          <<06768>>05635000
                                                               <<06768>>05640000
                                                               <<06768>>05645000
                                                               <<06768>>05650000
                                                               <<06768>>05655000
                                                               <<06768>>05660000
                                                               <<06768>>05665000
                                                               <<06768>>05670000
   INTEGER IOQ'ENTRY'INDEX;                                    <<06768>>05675000
                                                               <<06768>>05680000
   DISABLE;                                                    <<06768>>05685000
                                                               <<06768>>05690000
                                                               <<*7698>>05695000
                                                               <<*7698>>05700000
                                                               <<*7698>>05705000
L3:                                                            <<07410>>05710000
                                                               <<06768>>05715000
   PDISABLE;   << PROTECT AGAINST IOMESSPROC >>                <<*7572>>05720000
   IOQ'ENTRY'INDEX := IQH'FREEHEAD;                            <<06768>>05725000
                                                               <<07341>>05730000
                                                               <<07341>>05735000
                                                               <<06768>>05740000
                                                               <<06768>>05745000
   << CHECK IF ENTRIES CURRENTLY IN USE ARE MORE THAN >>       <<06768>>05750000
   << THE PRIMARY ENTRIES AVAILABLE                   >>       <<06768>>05755000
                                                               <<*7572>>05760000
                                                               <<06768>>05765000
   IF IQH'CUR'NUSE >= IQH'PRI'ENT                              <<06768>>05770000
      THEN                                                     <<06768>>05775000
         BEGIN  << IF TABLE OVERFLOWED FIRST TIME >>           <<06768>>05780000
                << THEN SEND A MESSAGE >>                      <<06768>>05785000
         IF IQH'OVRFLOWS = 0                                   <<06768>>05790000
           THEN MPE'TABLE'FULL( IOQQ'TABLE);                   <<07410>>05795000
         IQH'OVRFLOWS := IQH'OVRFLOWS + 1; << BUMP>>           <<06768>>05800000
         IF TYPE = PRIMARY THEN GO TO EXIT;                    <<*7572>>05805000
         IF <          << IMPEDABLE       >>                   <<06768>>05810000
            THEN                                               <<06768>>05815000
               BEGIN                                           <<06768>>05820000
               IOIMPEDE(   IOQQ'TABLE     ); << WILL PENABLE >><<*7572>>05825000
               GOTO L3;                                        <<06768>>05830000
               END;                                            <<06768>>05835000
         END;                                                  <<06768>>05840000
                                                               <<06768>>05845000
   IF IQH'FREEHEAD = 0                                         <<06768>>05850000
      THEN GO EXIT;          << SEC. TAB. EMPTY>>              <<*7572>>05855000
                                                               <<06768>>05860000
                             << PT. TO LINK >>                 <<06768>>05865000
   CHECKINDEX( IOQ'ENTRY'INDEX, IOQQ'TABLE);                   <<07410>>05870000
   IF NOT IOQ'ON'FREELIST THEN SUDDENDEATH(249)                <<07341>>05875000
                      ELSE IOQ'ON'FREELIST := 0;               <<07341>>05880000
   GETIOQ := IOQ'ENTRY'INDEX;                                  <<06768>>05885000
   IQH'FREEHEAD := IOQ'QLINK;         << RELINK LIST>>         <<06768>>05890000
   IF IOQ'QLINK = 0                   << TABLE EMP.>>          <<06768>>05895000
                                                               <<f9326>>05899010
       << the -1 below is so that the header acts as an      >><<f9326>>05899020
       << ioq entry on the first return after all ioq's are  >><<f9326>>05899030
       << in use.  The index points to the free tail and the >><<f9326>>05899040
       << free head is used as the link word by RETURNIOQ.   >><<f9326>>05899050
                                                               <<f9326>>05899060
      THEN IQH'FREETAIL := IQH'FREEHEAD'INDEX - 1              <<f9326>>05900000
      ELSE IOQ'QLINK := 0;            << CLEAR LINK>>          <<06768>>05905000
   IQH'CUR'NUSE  := IQH'CUR'NUSE + 1;                          <<06768>>05910000
   IQH'REQCOUNU := INTEGER(IQH'REQCOUNU + 1);                  <<*7698>>05915000
   IF CARRY   << INC. DOUBLE WORD COUNT - REQCOUNT & REQCOUNU>><<*7698>>05920000
      THEN IQH'REQCOUNT := IQH'REQCOUNT + 1;                   <<*7698>>05925000
   IF IQH'MAX'NUSE < IQH'CUR'NUSE                              <<06768>>05930000
      THEN                       << MAX < CUR. USE>>           <<06768>>05935000
         IQH'MAX'NUSE := IQH'CUR'NUSE;     << BUMP >>          <<06768>>05940000
EXIT:                                                          <<*7572>>05945000
   PENABLE;                                                    <<*7572>>05950000
END;                                                           <<06768>>05955000
                                                               <<06768>>05960000
                                                               <<06768>>05965000
<<*********************************************************>>           05970000
                                                                        05975000
<<                  GETDISCREQ                                          05980000
                                                                        05985000
    CALLS      :                                                        05990000
                                                                        05995000
    CALLED BY  :                                                        06000000
                                                                        06005000
    INPUTS     :                                                        06010000
                                                                        06015000
    OUTPUTS    :                                                        06020000
                                                                        06025000
    MODIFIED   :  12/30/82  RK                                          06030000
                                                                        06035000
    PURPOSE    :  THIS PROCEDURE GETS AN I/O TABLE ENTRY FROM           06040000
                  A PRIMARY OR SECONDARY TABLE.  IF THE TABLE           06045000
                  IS EMPTY THE CALLER MAY BE IMPEEDED IF HE             06050000
                  SO SPECIFIES.  A SYSDB RELATIVE POINTER IS            06055000
                  RETURNED TO THE BUFFER RETRIEVED.                     06060000
                                                           >>           06065000
                                                                        06070000
<<*********************************************************>>           06075000
                                                                        06080000
INTEGER PROCEDURE GETDISCREQ(TYPE);                            <<06768>>06085000
   VALUE TYPE;                                                 <<06768>>06090000
   INTEGER TYPE;                                               <<06768>>06095000
   OPTION UNCALLABLE,PRIVILEGED;                               <<06768>>06100000
                                                               <<06768>>06105000
   << TYPE  -  0 - IMPEDE IF PRIMARY TABLE IS EMPTY                     06110000
               1 - GET FROM PRIMARY ONLY,IF EMPTY RETURN 0              06115000
               2 - GET FROM PRIMARY OR SECONDARY, RETURN 0              06120000
                   IF BOTH TABLES ARE EMPTY  >>                         06125000
                                                               <<06768>>06130000
                                                               <<06768>>06135000
BEGIN                                                          <<06768>>06140000
                                                               <<06768>>06145000
                                                               <<06768>>06150000
                                                               <<06768>>06155000
   INTEGER DRQ'ENTRY'INDEX;                                    <<07410>>06160000
   DOUBLE DBSAVE;                                              <<07410>>06165000
   DOUBLE AQH'DREQCOUNT = AQH'REQCOUNT; << TOTAL 2 WORD CNT >> <<*7698>>06170000
                                                               <<07410>>06175000
                                                               <<07410>>06180000
   EQUATE DISC'TABLE    = 3;                                   <<07410>>06185000
   DISABLE;                                                    <<07410>>06190000
L3:                                                            <<07410>>06195000
   PDISABLE;   << PROTECT AGAINST IOMESSPROC >>                <<*7572>>06200000
   DBTODRQ;                                                    <<07410>>06205000
                                                               <<07410>>06210000
                                                               <<*7698>>06215000
                                                               <<*7698>>06220000
                                                               <<06768>>06225000
                                                               <<*7698>>06230000
                                                               <<07410>>06235000
                                                               <<07410>>06240000
   DRQ'ENTRY'INDEX :=  AQH'FREEHEAD;                           <<07410>>06245000
                                                               <<07410>>06250000
                                                               <<07410>>06255000
                                                               <<07410>>06260000
                                                               <<07410>>06265000
   << CHECK IF ENTRIES CURRENTLY IN USE ARE MORE THAN >>       <<07410>>06270000
   << THE PRIMARY ENTRIES AVAILABLE                   >>       <<07410>>06275000
                                                               <<07410>>06280000
   IF  AQH'CUR'NUSE >=  AQH'PRI'ENT                            <<07410>>06285000
      THEN                                                     <<07410>>06290000
         BEGIN  << IF TABLE OVERFLOWED FIRST TIME >>           <<07410>>06295000
                << THEN SEND A MESSAGE >>                      <<07410>>06300000
         IF  AQH'OVRFLOWS = 0                                  <<07410>>06305000
           THEN MPE'TABLE'FULL( DISC'TABLE);                   <<07410>>06310000
          AQH'OVRFLOWS :=  AQH'OVRFLOWS + 1; << BUMP>>         <<07410>>06315000
         IF TYPE = PRIMARY THEN GO EXIT;                       <<*7572>>06320000
         IF <          << IMPEDABLE       >>                   <<07410>>06325000
            THEN                                               <<07410>>06330000
               BEGIN                                           <<07410>>06335000
               TOS := DBSAVE;  <<  PUT DB BACK  >>             <<07410>>06340000
               ASSEMBLE( XCHD;  DDEL);  <<  DELETE DRQ DB  >>  <<07410>>06345000
               IOIMPEDE(   DISC'TABLE     ); << WILL PENABLE >><<*7572>>06350000
               GOTO L3;                                        <<07410>>06355000
               END;                                            <<07410>>06360000
         END;                                                  <<07410>>06365000
                                                               <<07410>>06370000
   IF  AQH'FREEHEAD = 0                                        <<07410>>06375000
      THEN GO EXIT;          << SEC. TAB. EMPTY>>              <<07410>>06380000
                                                               <<07410>>06385000
                                                               <<07410>>06390000
                             << PT. TO LINK >>                 <<07410>>06395000
   CHECKINDEX( DRQ'ENTRY'INDEX, DISC'TABLE);                   <<07410>>06400000
   IF NOT ARQX'ON'FREELIST THEN SUDDENDEATH(249)               <<07410>>06405000
                      << ZERO FREELIST BIT AND PCB # >>        <<*9545>>06409100
                      ELSE ARQX'PCB := 0;                      <<*9545>>06410000
   GETDISCREQ := DRQ'ENTRY'INDEX;                              <<07410>>06415000
    AQH'FREEHEAD := ARQX'FREELINK;         << RELINK LIST>>    <<07410>>06420000
   IF ARQX'FREELINK = 0                   << TABLE EMP.>>      <<07410>>06425000
                                                               <<f9326>>06429010
       << the -1 below is so that the header acts as an      >><<f9326>>06429020
       << drq entry on the first return after all drq's are  >><<f9326>>06429030
       << in use.  The index points to the free tail and the >><<f9326>>06429040
       << free head is used as the link word by RETURNDRQ.   >><<f9326>>06429050
                                                               <<f9326>>06429060
      THEN  AQH'FREETAIL :=  AQH'FREEHEAD'INDEX - 1            <<f9326>>06430000
      ELSE ARQX'FREELINK := 0;            << CLEAR LINK>>      <<07410>>06435000
    AQH'CUR'NUSE  :=  AQH'CUR'NUSE + 1;                        <<07410>>06440000
   AQH'DREQCOUNT := AQH'DREQCOUNT + 1D;  << TOTAL # OF REQS >> <<*7698>>06445000
   IF  AQH'MAX'NUSE <  AQH'CUR'NUSE                            <<07410>>06450000
      THEN                       << MAX < CUR. USE>>           <<07410>>06455000
          AQH'MAX'NUSE :=  AQH'CUR'NUSE;     << BUMP >>        <<07410>>06460000
                                                               <<07410>>06465000
EXIT:                                                          <<07410>>06470000
   TOS := DBSAVE;                                              <<07410>>06475000
   ASSEMBLE( XCHD );                                           <<07410>>06480000
   PENABLE;                                                    <<*7572>>06485000
END;                                                           <<07410>>06490000
$PAGE "RETURN T/SYS BUF"                                       <<JB.19>>06495000
<<*********************************************************>>           06500000
                                                                        06505000
<<                 RETURNSBUF                                           06510000
                                                                        06515000
   CALLS    :                                                           06520000
                                                                        06525000
   CALLED BY:                                                           06530000
                                                                        06535000
   INPUTS   :                                                           06540000
                                                                        06545000
   OUTPUTS  :                                                           06550000
                                                                        06555000
   MODIFIED : 1/5/83  RK                                                06560000
                                                                        06565000
   PURPOSE  : THIS PROCEDURE RETURNS THE ELEMENT POINTED                06570000
              TO BY PNTR AND IT UNIMPEDES ANY WAITING                   06575000
              PROCESSES                                                 06580000
                                                            >>          06585000
                                                                        06590000
<<**********************************************************>>          06595000
                                                                        06600000
PROCEDURE RETURNSBUF(PNTR);                                    <<06768>>06605000
  VALUE PNTR;                                                  <<06768>>06610000
  INTEGER PNTR;                                                <<06768>>06615000
  OPTION PRIVILEGED, UNCALLABLE;                               <<06768>>06620000
                                                               <<06768>>06625000
BEGIN                                                          <<06768>>06630000
                                                               <<06768>>06635000
                                                               <<06768>>06640000
                                                               <<06768>>06645000
                                                               <<06768>>06650000
   INTEGER SBF'ENTRY'INDEX;                                    <<06768>>06655000
   INTEGER TAILINDEX;                                          <<06768>>06660000
                                                               <<06768>>06665000
                                                               <<06768>>06670000
                                                               <<06768>>06675000
                                                               <<06768>>06680000
                                                               <<06768>>06685000
                                                               <<06768>>06690000
   SBF'ENTRY'INDEX := PNTR;         << FORM ELEMENT INDEX >>   <<06768>>06695000
   DISABLE;                                                    <<06768>>06700000
   SBH'CUR'NUSE := SBH'CUR'NUSE - 1;                           <<06768>>06705000
                                                               <<06768>>06710000
   CHECKINDEX( SBF'ENTRY'INDEX, SBUF'TABLE);                   <<07410>>06715000
   SBF'LINK := 0;   << ZERO LINK OF ONE BEING RETURNED >>      <<06768>>06720000
   TAILINDEX := SBH'FREETAIL;                                  <<06768>>06725000
   SBH'FREETAIL := SBF'ENTRY'INDEX;                            <<06768>>06730000
   SBF'ENTRY'INDEX := TAILINDEX;                               <<06768>>06735000
   SBF'LINK     := SBH'FREETAIL;                               <<06768>>06740000
                                                               <<06768>>06745000
                                                               <<06768>>06750000
   IF SBH'IMP'PCB <> 0 AND      << GET IMPEEDED LINK >>        <<06768>>06755000
      SBH'CUR'NUSE < SBH'PRI'ENT                               <<06768>>06760000
      THEN IOUNIMPEDE( SBUF'TABLE);                            <<07410>>06765000
END;              << PROC. RETURNIOQ >>                        <<06768>>06770000
<<*********************************************************>>           06775000
                                                                        06780000
<<                 RETURNIOQ                                            06785000
                                                                        06790000
   CALLS    :                                                           06795000
                                                                        06800000
   CALLED BY:                                                           06805000
                                                                        06810000
   INPUTS   :                                                           06815000
                                                                        06820000
   OUTPUTS  :                                                           06825000
                                                                        06830000
   MODIFIED : 1/5/83  RK                                                06835000
                                                                        06840000
   PURPOSE  : THIS PROCEDURE RETURNS THE ELEMENT POINTED                06845000
              TO BY PNTR AND IT UNIMPEDES ANY WAITING                   06850000
              PROCESSES                                                 06855000
                                                            >>          06860000
                                                                        06865000
<<**********************************************************>>          06870000
                                                                        06875000
PROCEDURE RETURNIOQ(PNTR);                                     <<06768>>06880000
  VALUE PNTR;                                                  <<06768>>06885000
  INTEGER PNTR;                                               <<*IO5*>> 06890000
  OPTION PRIVILEGED, UNCALLABLE;                               <<06768>>06895000
                                                               <<06768>>06900000
BEGIN                                                          <<06768>>06905000
                                                               <<06768>>06910000
   INTEGER IOQ'ENTRY'INDEX;                                    <<06768>>06915000
    INTEGER TAILINDEX;                                         <<06768>>06920000
                                                               <<06768>>06925000
   IOQ'ENTRY'INDEX := PNTR;         << FORM ELEMENT INDEX >>   <<06768>>06930000
   IF  IOSTATSENBLD   THEN  STORE'IOQ(PNTR,TRUE);              <<07410>>06935000
   DISABLE;                                                    <<06768>>06940000
   IQH'CUR'NUSE := IQH'CUR'NUSE - 1;                           <<06768>>06945000
   CHECKINDEX( IOQ'ENTRY'INDEX, IOQQ'TABLE);                   <<07410>>06950000
   IF IOQ'ON'FREELIST THEN SUDDENDEATH(249)                    <<06768>>06955000
                      ELSE IOQ'ON'FREELIST := 1;               <<06768>>06960000
   IOQ'QLINK := 0;   << ZERO LINK OF ONE BEING RETURNED >>     <<06768>>06965000
   TAILINDEX := IQH'FREETAIL;                                  <<06768>>06970000
   IQH'FREETAIL := IOQ'ENTRY'INDEX;                            <<06768>>06975000
   IOQ'ENTRY'INDEX := TAILINDEX;                               <<06768>>06980000
   IOQ'QLINK := IQH'FREETAIL;                                  <<06768>>06985000
   IF IQH'IMP'PCB <> 0 AND      << GET IMPEEDED LINK >>        <<06768>>06990000
      IQH'CUR'NUSE < IQH'PRI'ENT                               <<06768>>06995000
      THEN IOUNIMPEDE( IOQQ'TABLE);                            <<07410>>07000000
END;              << PROC. RETURNIOQ >>                        <<06768>>07005000
                                                                        07010000
<<*********************************************************>>           07015000
                                                                        07020000
<<                 RETURNDRQ                                            07025000
                                                                        07030000
   CALLS    :                                                           07035000
                                                                        07040000
   CALLED BY:                                                           07045000
                                                                        07050000
   INPUTS   :                                                           07055000
                                                                        07060000
   OUTPUTS  :                                                           07065000
                                                                        07070000
   MODIFIED : 1/5/83  RK                                                07075000
                                                                        07080000
   PURPOSE  : THIS PROCEDURE RETURNS THE ELEMENT POINTED                07085000
              TO BY PNTR AND IT UNIMPEDES ANY WAITING                   07090000
              PROCESSES                                                 07095000
                                                            >>          07100000
                                                                        07105000
<<**********************************************************>>          07110000
                                                                        07115000
PROCEDURE RETURNDRQ(PNTR);                                     <<06768>>07120000
  VALUE PNTR;                                                  <<06768>>07125000
  INTEGER PNTR;                                                <<06768>>07130000
  OPTION PRIVILEGED, UNCALLABLE;                               <<06768>>07135000
                                                               <<06768>>07140000
BEGIN                                                          <<06768>>07145000
   ENTRY RETURNDISCREQ;                                        <<07410>>07150000
   DOUBLE DBSAVE;                                              <<07410>>07155000
   INTEGER DRQ'ENTRY'INDEX;                                    <<07410>>07160000
   INTEGER TAILINDEX;                                          <<07410>>07165000
RETURNDISCREQ:                                                 <<07410>>07170000
                                                               <<07410>>07175000
<<                                                           >><<*9889>>07179000
<< A call to STORE'IOQ which was used by the Measurement     >><<*9889>>07179010
<< Interface to keep track of all DRQ's was remove from      >><<*9889>>07179020
<< line 7180 and move to line 18934.9 in SIODM and also      >><<*9889>>07179030
<< put in Cachseg for LDR'S. The reason for this is that     >><<*9889>>07179040
<< Caching sometimes multiply uses DRQ's without returning   >><<*9889>>07179050
<< them so some info on DRQ useage was not available to the  >><<*9889>>07179060
<< Measurement Interface. Also Caching sometimes gets LDR's  >><<*9889>>07179070
<< and doesn't use them, which is false info. for the        >><<*9889>>07179080
<< Measurement Interface.                                    >><<*9889>>07179090
<<                                                           >><<*9889>>07179100
$EDIT                                                          <<*9889>>07180000
   DRQ'ENTRY'INDEX := PNTR;          << FORM ELEMENT INDEX >>  <<07410>>07185000
   DISABLE;                                                    <<07410>>07190000
   DBTODRQ;                                                    <<07410>>07195000
    AQH'CUR'NUSE :=  AQH'CUR'NUSE - 1;                         <<07410>>07200000
   IF ARQX'ON'FREELIST THEN SUDDENDEATH(249)                   <<07410>>07205000
                      ELSE ARQX'ON'FREELIST := 1;              <<07410>>07210000
   CHECKINDEX(DRQ'ENTRY'INDEX,DISC'TABLE);                     <<07410>>07215000
   ARQX'FREELINK := 0;   << ZERO LINK OF ONE BEING RETURNED >> <<07410>>07220000
   TAILINDEX :=  AQH'FREETAIL;                                 <<07410>>07225000
    AQH'FREETAIL := DRQ'ENTRY'INDEX;                           <<07410>>07230000
   DRQ'ENTRY'INDEX := TAILINDEX;                               <<07410>>07235000
   ARQX'FREELINK :=  AQH'FREETAIL;                             <<07410>>07240000
   IF  AQH'IMP'PCB <> 0 AND     << GET IMPEEDED LINK >>        <<07410>>07245000
       AQH'CUR'NUSE <  AQH'PRI'ENT                             <<07410>>07250000
      THEN IOUNIMPEDE( DISC'TABLE);                            <<07410>>07255000
                                                               <<07410>>07260000
   TOS := DBSAVE;                                              <<07410>>07265000
   ASMB( XCHD );                                               <<07410>>07270000
END;              << PROC. RETURNDRQ >>                        <<07410>>07275000
$PAGE "CLEAR WAKE"                                             <<JB.19>>07280000
<<*********************************************************>>           07285000
<<                                                                      07290000
                  CLEARWAKE                                             07295000
                                                                        07300000
    CALLS      : TESTBIT COMPLETED                                      07305000
                                                                        07310000
    CALLED BY  :                                                        07315000
                                                                        07320000
    INPUTS     : IOQX - INDEX RELATIVE TO THE BASE OF TABLE             07325000
                                                                        07330000
    OUTPUTS    : CCE - WAKE FLAG CLEARED                                07335000
                 CCL - REQUEST HAS ALREADY COMPLETED                    07340000
                                                                        07345000
    MODIFIED   : 1/24/83 RK                                             07350000
                                                                        07355000
    PURPOSE    : THIS PROCEDURE SETS/CLEARS THE IOWAKE BIT              07360000
                 IT CHECKS THE COMPLETED FLAG BEFORE                    07365000
                 PERFORMING REQUEST.  IF THE REQUEST HAS                07370000
                  COMPLETED A CCL IS RETURNED TO THE CALLER             07375000
                 OTHERWISE IOWAKE IS SET AS REQUESTED AND               07380000
                 A CCE IS RETURNED.  INTERRUPT DISABLED                 07385000
                 STATUS IS MAINTAINED OVER THE CALL.        >>          07390000
                                                                        07395000
<<**********************************************************>>          07400000
                                                                        07405000
PROCEDURE CLEARWAKE(IOQX);                                     <<06768>>07410000
                                                               <<06768>>07415000
VALUE IOQX;                                                    <<06768>>07420000
INTEGER IOQX;                                                  <<06768>>07425000
OPTION UNCALLABLE,PRIVILEGED;                                  <<06768>>07430000
                                                               <<06768>>07435000
BEGIN                                                          <<06768>>07440000
   DEFINE DISC'REQ = LIOQX.(1:1) = 1#;                         <<06768>>07445000
   LOGICAL FLAG;                                               <<*7572>>07450000
   ENTRY SETWAKE;                                              <<06768>>07455000
   INTEGER DRQ'ENTRY'INDEX;                                    <<06768>>07460000
   INTEGER IOQ'ENTRY'INDEX;                                    <<06768>>07465000
   LOGICAL RETURNCC := CCE;                                    <<06768>>07470000
   LOGICAL LIOQX = IOQX;                                       <<06768>>07475000
   LOGICAL DRQX  = IOQX;                                       <<06768>>07480000
   INTEGER DSTNUM;                                             <<*7572>>07485000
                                                               <<*7572>>07490000
   DOUBLE SEGID;                                               <<*7572>>07495000
   LOGICAL ARRAY SEGID'(*)=SEGID;                              <<*7572>>07500000
$PAGE                                                          <<*7572>>07505000
                                                               <<06768>>07510000
   FLAG := 0;     << SET FLAG TO CLEAR IOWAKE >>               <<06768>>07515000
   GOTO L1;                                                    <<06768>>07520000
SETWAKE:                                                       <<06768>>07525000
   FLAG := 1;     << SET FLAG TO IOWAKE >>                     <<06768>>07530000
L1:                                                            <<06768>>07535000
   TOS := RSTATUS;                                             <<06768>>07540000
   DISABLE;                                                    <<06768>>07545000
   IF DISC'REQ    << CHECK IF DISC REQUEST >>                  <<06768>>07550000
      THEN                                                     <<06768>>07555000
         BEGIN                                                 <<06768>>07560000
         DRQ'ENTRY'INDEX := DRQX.(2:14);                       <<06768>>07565000
                                                               <<06768>>07570000
         IF DRQ'DONE  << REQUEST COMPLETED >>                  <<06768>>07575000
             THEN RETURNCC := CCL                              <<06768>>07580000
          ELSE                                                 <<*7572>>07585000
          IF     FLAG   <>  DRQ'IOWAKE    THEN                 <<*7572>>07590000
           BEGIN                                               <<*7572>>07595000
           DRQ'IOWAKE := FLAG;                                 <<*7572>>07600000
           PDISABLE;                                           <<*7572>>07605000
           DSTNUM := DRQ'BUF'DSTN;                             <<*7572>>07610000
           DST(DSTNUM&LSL(2)).REFERENCEDFLAG := 1;             <<*7572>>07615000
           DRQ'PCB  := (CURPRC)/PCBSIZE;                       <<*7572>>07620000
                                                               <<*7572>>07625000
           IF NOT(DRQ'DBREL)                                   <<*7572>>07630000
            THEN                                               <<*7572>>07635000
            BEGIN                                              <<*7572>>07640000
            TOS := %1000D;                                     <<*7572>>07645000
            ASMB(XCHD);                                        <<*7572>>07650000
            SEGID'(OBJIDTYPEFIELD) := OBJIDDATATYPE;           <<*7572>>07655000
            SEGID'(OBJIDPBXFIELD)  := 0;                       <<*7572>>07660000
            SEGID'(OBJIDNUMFIELD)  := DSTNUM;                  <<*7572>>07665000
            IF FLAG                     << MUST ADD TO LOCAL>> <<*7572>>07670000
             THEN   << IT WAS A SETWAKE.   PUT ON SLL >>       <<*7572>>07675000
              BEGIN                                            <<*7572>>07680000
              IF NOT DRQ'INLOCAL OR DRQ'IS'LDRQ THEN           <<*7572>>07685000
                BEGIN                                          <<*7572>>07690000
                IF NOT DRQ'IS'LDRQ THEN DRQ'INLOCAL := 1;      <<*7572>>07695000
                TOS := LPCB(CURPRC + SLLIXWORDNUM);            <<*7572>>07700000
                TOS := SEGID;                                  <<*7572>>07705000
                TOS := 0;                                      <<*7572>>07710000
                TOS.SETDISCIOSEGFLAG := 1;                     <<*7572>>07715000
                ADDTOLOCALITY(*,*,*);                          <<*7572>>07720000
                END;                                           <<*7572>>07725000
              END                                              <<*7572>>07730000
             ELSE  IF DRQ'INLOCAL OR DRQ'IS'LDRQ THEN          <<*7572>>07735000
              BEGIN                                            <<*7572>>07740000
              IF NOT DRQ'IS'LDRQ THEN DRQ'INLOCAL := 0;        <<*7572>>07745000
              TOS := CURPRC;                                   <<*7572>>07750000
              TOS := SEGID;                                    <<*7572>>07755000
              TOS := 0D;                                       <<*7572>>07760000
              TOS.(CLEARDISCIOSEGBIT:1) := 1;                  <<*7572>>07765000
              ADJUSTLOCALITY(*,*,*,*);                         <<*7572>>07770000
              END;                                             <<*7572>>07775000
            ASMB(XCHD;DDEL);                                   <<*7572>>07780000
            END;                                               <<*7572>>07785000
           PENABLE;                                            <<*7572>>07790000
           END;                                                <<*7572>>07795000
                                                               <<*7572>>07800000
                                                               <<06768>>07805000
                                                               <<06768>>07810000
                                                               <<06768>>07815000
                                                               <<06768>>07820000
         END                                                   <<06768>>07825000
      ELSE                                                     <<06768>>07830000
         BEGIN                                                 <<06768>>07835000
         IOQ'ENTRY'INDEX := IOQX;                              <<06768>>07840000
                                                               <<06768>>07845000
         IF IOQ'DONE         << REQUEST COMPLETED >>           <<06768>>07850000
            THEN RETURNCC := CCL    << CCL IS RETURNED >>      <<06768>>07855000
            ELSE IOQ'IOWAKE := FLAG; << SET/CLEAR IOWAKE >>    <<06768>>07860000
                                                               <<06768>>07865000
                                                               <<06768>>07870000
                                                               <<06768>>07875000
                                                               <<06768>>07880000
         END;                                                  <<06768>>07885000
   RSTATUS.CC := RETURNCC;           << SET NEW RETURN CC >>   <<06768>>07890000
END;                                 << CLEARWAKE/SETWAKE >>   <<06768>>07895000
                                                               <<06768>>07900000
                                                               <<06768>>07905000
                                                               <<06768>>07910000
                                                               <<06768>>07915000
                                                               <<06768>>07920000
                                                               <<06768>>07925000
                                                               <<06768>>07930000
                                                                        07935000
$PAGE "PROCEDURE: P'ATTACHIO"                                  <<04317>>07940000
DOUBLE PROCEDURE P'ATTACHIO(LDEV, QMISC, DSTX, ADDR, FNCT,     <<04317>>07945000
                            CNT, P1, P2, FLAGS,                <<04500>>07950000
                            EXTBASE, EXTSIZE);                 <<04500>>07955000
                                                               <<04317>>07960000
VALUE                       LDEV, QMISC, DSTX, ADDR, FNCT,     <<04317>>07965000
                            EXTBASE, EXTSIZE,                  <<04500>>07970000
                            CNT, P1, P2, FLAGS;                <<04317>>07975000
                                                               <<04317>>07980000
INTEGER                     LDEV, QMISC, DSTX, ADDR, FNCT,     <<04317>>07985000
                            CNT, P1, P2, FLAGS;                <<04317>>07990000
                                                               <<04317>>07995000
DOUBLE                      EXTBASE;                           <<04500>>08000000
                                                               <<04500>>08005000
LOGICAL                     EXTSIZE;                           <<04500>>08010000
                                                               <<04500>>08015000
OPTION PRIVILEGED, UNCALLABLE, VARIABLE;                       <<04500>>08020000
  BEGIN                                                                 08025000
comment                                                        <<02801>>08030000
<<*****************************************************>>      <<02801>>08035000
LDEV   - Logical device number                                 <<02801>>08040000
QMISC  - Misc parameter specified for device                   <<02801>>08045000
DSTX   - DST number of data segment.  If zero, then            <<02801>>08050000
         specifies that ADDR is DB relative to the caller's    <<02801>>08055000
         stack.  Must be zero if system buffers is specified.  <<02801>>08060000
ADDR   - Depending on FLAGS.(14:1) and DSTX, this may be:      <<02801>>08065000
         1)Offset to data in DST.                              <<02801>>08070000
         2)Offset to data from DB in callers stack.            <<02801>>08075000
         3)Index to a system buffer.                           <<02801>>08080000
FUNC   - Function code.  Device defined, but usually:          <<02801>>08085000
         0 - Read.                                             <<02801>>08090000
         1 - Write.                                            <<02801>>08095000
         2 - Open file.                                        <<02801>>08100000
         3 - Close file.                                       <<02801>>08105000
         4 - Close device.                                     <<02801>>08110000
CNT    - Data transfer count, + words or - bytes.              <<02801>>08115000
P1     - Parameter 1.  Device dependant.                       <<02801>>08120000
P2     - Parameter 2.  Device dependant.                       <<02801>>08125000
FLAGS  - Control and specification flags.                      <<02801>>08130000
         (0:4) - Caller is unknown(0), file system(1), or      <<02801>>08135000
                 spooler(2).                                   <<02801>>08140000
         (4:3) - Available                                     <<02801>>08145000
         (7:2) - Premption flags, soft(1) or hard(2).          <<02801>>08150000
         (9:1) - 0.                                            <<02801>>08155000
         (10:1)- Special request, device defined.  Usually     <<02801>>08160000
                 memory management.                            <<02801>>08165000
         (11:1)- If set, this is a diagnostic request.         <<02801>>08170000
         (12:1)- System buffer flag.  If set, ADDR is an index <<02801>>08175000
                 relative to the SBUF table.  For devices      <<02801>>08180000
                 that support chaining, the data is trans-     <<02801>>08185000
                 ferred to and from a set of chained buffers,  <<02801>>08190000
                 up to a maximum of 1024 words.                <<02801>>08195000
         (13:3)- Request type:                                 <<02801>>08200000
                 0)Unblocked, no wake.  Impede if no IOQ.      <<02801>>08205000
                 1)Blocked (caller is waited until done).      <<02801>>08210000
                 2)Unblocked, wake caller, impede if no IOQ.   <<02801>>08215000
                 3)Unblocked & no PIN is to be associated      <<02801>>08220000
                   with this I/O.  Impede if no IOQ.           <<02801>>08225000
                 4)Unblocked, no wake, no impede if no IOQ.    <<02801>>08230000
                 5)Reserved.                                   <<02801>>08235000
                 6)Unblocked, wake, no impede if no IOQ.       <<02801>>08240000
                 7)Same as 3 but no impede & get secondary     <<02801>>08245000
                   IOQ if necessary.                           <<02801>>08250000
                                                               <<02801>>08255000
RETURN:                                                        <<02801>>08260000
                                                               <<02801>>08265000
Blocked-                                                       <<02801>>08270000
                                                               <<02801>>08275000
S-1    -  (0:8) LEFT BYTE OF STATUS WORD (DEV SPEC. STATUS)    <<06768>>08280000
         (8:5) - Qualifying status.                            <<02801>>08285000
         (13:3)- General status.                               <<02801>>08290000
S-0    - Transmission log (+words or -bytes).                  <<02801>>08295000
                                                               <<02801>>08300000
Unblocked-                                                     <<02801>>08305000
                                                               <<02801>>08310000
S-1    - TABLE index of request  (1 if no PCB I/O)             <<06768>>08315000
S-0    - 0                                                     <<02801>>08320000
                                                               <<02801>>08325000
<<************************************************************><<02801>>08330000
;                                                              <<02801>>08335000
    INTEGER PCBNUM;                                            <<06768>>08340000
    INTEGER DBSAVE;                                            <<06768>>08345000
    INTEGER POINTER DITP;                                      <<06768>>08350000
    LOGICAL POINTER DITPL = DITP;                              <<06768>>08355000
    INTEGER SAVECRIT;                                          <<06768>>08360000
   DEFINE << LOCAL DEFS FOR NEW IOQ/DRQ ACCESS >>              <<06768>>08365000
                                                               <<07410>>08370000
               SETDB'SYS = BEGIN                               <<07410>>08375000
                            TOS := %1000D;                     <<07410>>08380000
                            ASSEMBLE(XCHD;DDEL);               <<07410>>08385000
                           END#,                               <<07410>>08390000
                                                               <<07410>>08395000
               SETDB'QUE = BEGIN                               <<07410>>08400000
                            ASSEMBLE(LDD ABS'Q'ADDR;           <<07410>>08405000
                                     ADDM Q'ENTRY'INDEX;);     <<07410>>08410000
                            ASSEMBLE(XCHD;DDEL);               <<07410>>08415000
                           END#;                               <<07410>>08420000
                                                               <<07410>>08425000
                                                               <<06768>>08430000
                                                               <<06768>>08435000
                                                               <<06768>>08440000
                                                               <<06768>>08445000
   INTEGER I; << FOR LOOP INDEX >>                             <<06768>>08450000
   INTEGER IOQ'X, << FOR SEARCH DIT IOQ >>                     <<06768>>08455000
           IOQ'NEXT;                                           <<06768>>08460000
   LOGICAL L; << SCRATCH        >>                             <<06768>>08465000
   INTEGER POINTER Q'PTR; << FOR RETURNIOQ >>                  <<06768>>08470000
<<>>                                                           <<03031>>08475000
    ARRAY QARRAY(*)=Q+0;                                       <<03031>>08480000
                                                               <<03031>>08485000
equate TERMINAL   = 16,    << Device type 16 is terminal >>    <<03686>>08490000
       DTYPE      = 5;     << Device type word in DLT    >>    <<03686>>08495000
                                                               <<03686>>08500000
define DDTYPE     = (8:8)#;<< Device type field in DLT   >>    <<03686>>08505000
                                                               <<03686>>08510000
INTEGER PROCPRI; <<CPU PRIORITY FROM PCB ENTRY>>               <<Q9366>>08512000
                                                               <<Q9366>>08513000
EQUATE ICS'CSCHEDBASECELL = %43;                               <<Q9366>>08514000
    INTEGER POINTER DLTP;                                      <<06768>>08515000
    INTEGER Q'ENTRY'INDEX, << POINTS TO CURRENT ENTRY >>       <<06768>>08520000
       DRQ'ENTRY'INDEX=Q'ENTRY'INDEX,                          <<06768>>08525000
       IOQ'ENTRY'INDEX=Q'ENTRY'INDEX;                          <<06768>>08530000
   DOUBLE SEGID;                                               <<06768>>08535000
     DOUBLE ABS'Q'ADDR;                                        <<07410>>08540000
     INTEGER Q'ADDR'BANK = ABS'Q'ADDR,                         <<07410>>08545000
             Q'ADDR'OFFSET=ABS'Q'ADDR+1;                       <<07410>>08550000
   LOGICAL ARRAY SEGID'(*)=SEGID;                              <<06768>>08555000
                                                                        08560000
    LOGICAL PFLAG;  << SET IF PREMPTIVE REQUEST QUEUE          <<06768>>08565000
    LOGICAL ENTRY'IS'DRQ;    <<  WHETHER LDEV IS DISC=TRUE >>  <<07410>>08570000
    LOGICAL ADISC = ENTRY'IS'DRQ;  <<  USED BY DEFINES >>      <<07410>>08575000
    INTEGER STACKDST;  << HOLDS STACK DST IF A STACK           <<06768>>08580000
                                                                        08585000
                                                               <<*7572>>08590000
     ARRAY PARAMS(*) = LDEV;   << FOR MOVE TO IOQ >>           <<06768>>08595000
    LOGICAL LFLAGS = FLAGS;                                             08600000
INTEGER LPDT'INDEX;                                            <<06768>>08605000
                                                                        08610000
       TRAPSOFF;                                               <<*7917>>08615000
    << FORCE STACK OVERFLOWS >>                                <<06768>>08620000
    ASMB(ADDS 255;SUBS 255);                                   <<06768>>08625000
                                                               <<02074>>08630000
    PUSH(DB); << CHECK IF DB => SYSDB >>                       <<06768>>08635000
    DBSAVE := IF TOS = %1000 D THEN 0 ELSE SETSYSDB;           <<06768>>08640000
LPDT'INDEX := LDEV * INTEGER(LPDT'ENTRY'SIZE);                 <<06768>>08645000
@DITP := LPDT'DIT'PTR;                                         <<06768>>08650000
ENTRY'IS'DRQ := DITPL.TDFLAGS = 1;  << SET DISC  - NONDISC  >> <<07410>>08655000
                                                               <<*1771>>08655010
   <<                                                       >> <<*1771>>08655020
   << THE FOLLOWING IS A BUG CATCHER FOR ILLEGAL CALLS TO   >> <<*1771>>08655030
   << ATTACHIO/P'ATTACHIO. THE CALLS ARE DOING NO PCB,      >> <<*1771>>08655040
   << NO WAIT I/O AND NOT USING SYSTEM BUFFERS. SYSTEM      >> <<*1771>>08655050
   << BUFFERS MUST BE USED FOR THIS TYPE OF I/O.            >> <<*1771>>08655060
   <<                                                       >> <<*1771>>08655070
                                                               <<*1771>>08655080
   IF ADISC AND FLAGS.RTYPE = 3 AND NOT LFLAGS.SYSBUFRS        <<*1771>>08655090
      THEN SUDDENDEATH(661);                                   <<*1771>>08655100
                                                               <<*1771>>08655110
   Q'ADDR'BANK := ABSOLUTE(IF ADISC THEN SYSDISCREQTAB         <<07410>>08660000
                                    ELSE SYSIOQREQTAB);        <<07410>>08665000
   Q'ADDR'OFFSET := LOGICAL(Q'ADDR'BANK + %1000) LAND %177740; <<07410>>08670000
   Q'ADDR'BANK := LOGICAL(Q'ADDR'BANK) LAND %37;               <<07410>>08675000
                                                                        08680000
    X := DBSAVE;   << TEST IF I/O SYSTEM CALL >>                        08685000
    IF <> THEN SAVECRIT:=SETCRITICAL; <<SET SAVECRIT>>         <<06768>>08690000
                                                                        08695000
     FLAGS.(0:4) := 0;                                         <<00.04>>08700000
    @DLTP := DITP(DDLTP);                                      <<06768>>08705000
    Q'ENTRY'INDEX := IF ENTRY'IS'DRQ                           <<06768>>08710000
      THEN GETDISCREQ(FLAGS.NOTIMPEDABLE)                      <<06768>>08715000
          << IF REQ TYPE 7, GET IOQ FROM SEC. AREA, >>         <<06768>>08720000
          << ELSE GET IOQ FROM PRI. & IMPEDE IF 13:1 >>        <<06768>>08725000
          << IN FLAGS OFF (I.E. ZERO)                >>        <<06768>>08730000
      ELSE GETIOQ(IF FLAGS.(13:3)=7                            <<06768>>08735000
                     THEN 2                                    <<06768>>08740000
                     ELSE FLAGS.NOTIMPEDABLE);                 <<06768>>08745000
                                                               <<06768>>08750000
    PFLAG := STACKDST := 0;                                    <<06768>>08755000
    IF Q'ENTRY'INDEX = 0 THEN GOTO OUT;                        <<06768>>08760000
                                                               <<06768>>08765000
    IF LFLAGS.SYSBUFRS THEN DSTX := 8;  << DST # OF SYS BUFS >>         08770000
                                                                        08775000
    X := DSTX;                                                          08780000
    IF = THEN   << A STACK RELATIVE ADDRESS >>                          08785000
      BEGIN                                                             08790000
        STACKDST := LPCB(CURPRC + STKINFOWORDNUM).STKDSTFIELD; <<06768>>08795000
        TOS := STACKDST;  TOS.STACKFLAG := 1;  DSTX := TOS;    <<00.05>>08800000
      END                                                      <<MPEIV>>08805000
   ELSE IF ENTRY'IS'DRQ AND FLAGS.RTYPE=1                      <<06768>>08810000
                                                               <<*7572>>08815000
  THEN                                                         <<06768>>08820000
      BEGIN <<BLOCKED DISC I/O,NOT TO STACK OR DB SEG>>        <<MPEIV>>08825000
      SEGID'(OBJIDTYPEFIELD) := OBJIDDATATYPE; << BUILD >>     <<06768>>08830000
      SEGID'(OBJIDPBXFIELD)  := 0;  << 2 WORD SEGID OF  >>     <<06768>>08835000
      SEGID'(OBJIDNUMFIELD)  := DSTX; << TYPE DST >>           <<06768>>08840000
      IF DST(DSTX&LSL(2)) < 0 THEN QUEUEONSEGMENT(SEGID);      <<06768>>08845000
      DST(X).REFERENCEDFLAG := 1;                              <<06768>>08850000
      END;                                                     <<MPEIV>>08855000
                                                                        08860000
                                                               <<07410>>08865000
                                                               <<07410>>08870000
                                                               <<07410>>08875000
                                                               <<07410>>08880000
                                                               <<07410>>08885000
                                                               <<07410>>08890000
                                                               <<07410>>08895000
                                                               <<07410>>08900000
                                                               <<07410>>08905000
                                                               <<07410>>08910000
     PDISABLE;                                                 <<07410>>08915000
     SETDB'QUE;                                                <<07410>>08920000
     ASSEMBLE(                                                 <<07410>>08925000
     LDD  LDEV;  STD  ARQ'LDEV;    <<  ARQ'LDEV := LDEV;     >><<07410>>08930000
                                   <<  ARQ'QMISC:= QMISC;    >><<07410>>08935000
     LDD  DSTX;  STD  ARQ'BUFDST;  <<  ARQ'BUFDST  := DSTX;  >><<07410>>08940000
                                   <<  ARQ'BUFADR := ADDR;   >><<07410>>08945000
     LDD  FNCT;  STD  ARQ'UNITFNC; <<  ARQ'FUNC  :=  FNCT;   >><<07410>>08950000
                                   <<  ARQ'COUNT :=  CNT;    >><<07410>>08955000
     LDD  P1;  STD  ARQ'PARM1;     <<  ARQ'PARM1 :=  P1;     >><<07410>>08960000
     DZRO;     STD  ARQ'STAT;      <<   ARQ'STATPCB := 0D;   >><<07410>>08965000
              );                   <<  CLOSE  ASSEMBLE(      >><<07410>>08970000
    IF ADISC  THEN  ARQ'UNITFNC.(0:8) := LFLAGS.(0:4);         <<*7572>>08975000
     SETDB'SYS;                                                <<07410>>08980000
     PENABLE;                                                  <<07410>>08985000
                                                               <<07410>>08990000
                                                               <<07410>>08995000
                                                               <<07410>>09000000
                                                               <<07410>>09005000
                                                               <<07410>>09010000
                                                               <<06768>>09015000
                                                                        09020000
    TOS := 0;   TOS.(1:3) := FLAGS.(10:3);  << SPEC,DIAG,SYSBUF >>      09025000
                                                                        09030000
    X := FLAGS.RTYPE;   << SWITCH ON REQUEST TYPE >>                    09035000
    ASMB( BR *+1,X ;                                                    09040000
      br RT0;  br RT1;  br RT2;  br RT3 );                     <<03655>>09045000
                                                               <<03655>>09050000
RT1:  << Blocked I/O - must clear WWS bit in PCB >>            <<03655>>09055000
    tos.BLOCKED := 1;  << Turn on blocked bit in FLAGS >>      <<03655>>09060000
    DISABLE;                                                   <<03655>>09065000
    CLEARWWS;                                                  <<03655>>09070000
                                                                        09075000
RT2:                                                                    09080000
    TOS.IOWAKE := 1;                                                    09085000
RT0:                                                                    09090000
    IF ENTRY'IS'DRQ                                            <<06768>>09095000
       THEN DRQ'PCB := ((CURPRC)/PCBSIZE)                      <<06768>>09100000
       ELSE IOQ'PCB := ((CURPRC)/PCBSIZE);                     <<06768>>09105000
RT3:                                                                    09110000
   PCBNUM := IF ENTRY'IS'DRQ                                   <<06768>>09115000
                THEN DRQ'PCB                                   <<06768>>09120000
                ELSE IOQ'PCB;                                  <<06768>>09125000
    TOS := FLAGS.PREMPTFIELD;                                           09130000
    DISABLE;                                                            09135000
    IF <> OR DITP<0 AND DITPL(DMODEM).CMODE AND                         09140000
     ((CURPRC) = PROGENPCBP) THEN                              <<06768>>09145000
      BEGIN << PREMPTIVE OR TERMINAL IN CONSOLE MODE >>                 09150000
        PFLAG := TRUE;     << SET SO AWAKEIO CALLED >>                  09155000
        if PCBNUM <> 0 then CLEARWWS; << May be on ICS >>      <<03686>>09160000
        X := DITP;                                                      09165000
        IF < THEN    << A TERMINAL >>                                   09170000
          BEGIN                                                         09175000
            TOS := TOS + 2;  << FORM HARD/SOFT/CONSMODE PREMPT CODE >>  09180000
            DITP(DMODEM).PREMPT := 1;                                   09185000
          END                                                           09190000
        ELSE                                                            09195000
          BEGIN                                                         09200000
            TOS := TOS&LSL(2);  << POSITION TO (12:2) >>                09205000
            DITP.SIOPREMPT := 1;                                        09210000
          END;                                                          09215000
      END;                                                              09220000
                                                                        09225000
    L := TOS LOR TOS; << MERG RPLEVEL WITH FLAGS >>            <<06768>>09230000
    IF ENTRY'IS'DRQ                                            <<06768>>09235000
       THEN DRQ'FLAGS := L                                     <<06768>>09240000
       ELSE IOQ'FLAGS := L;                                    <<06768>>09245000
IF ENTRY'IS'DRQ THEN                                           <<06768>>09250000
   BEGIN <<DISC REQUEST>>                                      <<MPEIV>>09255000
   PROCPRI := LPCB(CURPRC + QUEUEINGINFOWORDNUM).PRIFIELD;     <<Q9366>>09260000
   IF LPCB(CURPRC + RESABORTINFOWORDNUM).HASSIRFLAG AND        <<Q9366>>09261000
      PROCPRI > ICS(-ICS'CSCHEDBASECELL) THEN                  <<Q9366>>09262000
      PROCPRI := ICS(-ICS'CSCHEDBASECELL); <<IF THE PROCESS>>  <<Q9366>>09263000
      <<IS RUNNING IN NON-LINEAR QUEUE AND HOLDING A SIR >>    <<Q9366>>09264000
      <<THEN ITS PRIORITY WILL BE AT THE PRIORITY OF C BASE>>  <<Q9366>>09264100
   DRQ'URGCLAS := PROCPRI;                                     <<Q9366>>09265000
                                                               <<D1987>>09265010
<<THIS WILL ACCOUNT FOR ALL NON-CACHE DISC IOS. SEE COMMENT >> <<D1987>>09265100
<<IN SIODM AT THE OLD PLACE FOR MORE EXPLAINATION>>            <<D1987>>09265200
   IF GCLASSENABLEDMASK.CLASS15 THEN                           <<D1987>>09265300
   BEGIN                                                       <<D1987>>09265400
      IF (DRQ'FUNC <= 1) OR (DRQ'FUNC = 5) OR (DRQ'FUNC = 6)   <<W2191>>09265500
         OR (DRQ'FUNC = 11) THEN                               <<W2191>>09265510
      BEGIN                                                    <<D1987>>09265600
         TOS := MEASPROCXDSBANK;                               <<D1987>>09265700
         TOS := MEASPROCXDSBASE + DRQ'PCB * CLASS15'SUB0SIZE;  <<D1987>>09265800
         IF DRQ'FUNC = 0 THEN                                  <<D1987>>09265900
            TOS := TOS + CP'DISCREAD                           <<D1987>>09266000
         ELSE                                                  <<D1987>>09266100
            TOS := TOS + CP'DISCWRITE;                         <<D1987>>09266200
         ASMB (LSEA);                                          <<D1987>>09266300
         TOS := TOS + 1;                                       <<D1987>>09266400
         ASMB (SSEA);                                          <<D1987>>09266500
         <<NOW BUMP TRANSFER COUNT>>                           <<D1987>>09266600
         IF DRQ'FUNC = 0 THEN                                  <<D1987>>09266700
            TOS := TOS - CP'DISCREAD + CP'WORDSTRANS           <<D1987>>09266800
         ELSE                                                  <<D1987>>09266900
            TOS := TOS - CP'DISCWRITE + CP'WORDSTRANS;         <<D1987>>09267000
         ASMB (LDEA;ZERO);  <<OLD COUNT, ZERO FOR DOUBLE ADD>> <<D1987>>09267100
         IF INTEGER (DRQ'COUNT) < 0 THEN                       <<D1987>>09267200
            TOS := - DRQ'COUNT / 2                             <<D1987>>09267300
         ELSE                                                  <<D1987>>09267400
            TOS := DRQ'COUNT;                                  <<D1987>>09267500
         ASMB (DADD;SDEA;DDEL);                                <<D1987>>09267600
      END;                                                     <<D1987>>09267700
   END;                                                        <<D1987>>09267800
                                                               <<D1987>>09267900
   QUEUEDISCREQ(Q'ENTRY'INDEX,2,@DITP);                        <<06768>>09270000
   <<DISCQMANAGER AWOKE DEVICE IF NOT ACTIVE SO NO PFLAG>>     <<MPEIV>>09275000
   END                                                         <<MPEIV>>09280000
ELSE                                                           <<MPEIV>>09285000
   BEGIN                                                       <<MPEIV>>09290000
                                                                        09295000
                                                               <<06768>>09300000
   IF DITP(DIOQP) = 0 THEN                                     <<06768>>09305000
      BEGIN                                                             09310000
        DITP(DIOQP) := Q'ENTRY'INDEX;                          <<06768>>09315000
        PFLAG := TRUE;  << FORCE AWAKEIO >>                             09320000
        << WE MUST NOT ENTER SIODM IF IT IS BUSY BUT DOES NOT>><<06768>>09325000
        << CURRENTLY HAVE A REQUEST.  THE FOLLOWING FIX MUST >><<06768>>09330000
        <<   RUN DISABLED..   IT FIXES LOST MAG TAPE IOQ'S   >><<06768>>09335000
        <<   INCLHARD FIX # 6                 WEO          >>  <<06768>>09340000
          IF DLTP(DMNTR)=@SIODM   AND  DITP.STATEF > %10 THEN  <<06768>>09345000
          << IF MONITOR IS SIODM AND STATE > 10 THEN   >>      <<06768>>09350000
            BEGIN                                              <<06768>>09355000
            DITP.REQUEST := 1;  << TELL SIODM THERE IS WORK  >><<06768>>09360000
            PFLAG := 0;         << TELL PATTIO NOT TO CALL MON <<06768>>09365000
            END                                                <<06768>>09370000
      END                                                               09375000
    ELSE                                                                09380000
      BEGIN  << FIND END OF IOQ LIST >>                                 09385000
      IOQ'NEXT := DITP(DIOQP);                                 <<06768>>09390000
      WHILE IOQ'NEXT <> 0 DO                                   <<06768>>09395000
         BEGIN << FIND END OF QUEUE >>                         <<06768>>09400000
         IOQ'X := IOQ'NEXT;                                    <<06768>>09405000
         IOQ'NEXT := IOQ(IOQ'X+IOQ'QLINK'INDEX);               <<06768>>09410000
         END;                                                  <<06768>>09415000
      << AT END, LINK IN NEW ELEMENT >>                        <<06768>>09420000
      IOQ(IOQ'X+IOQ'QLINK'INDEX) :=                            <<06768>>09425000
                   Q'ENTRY'INDEX;                              <<06768>>09430000
      END;                                                              09435000
   END;                                                        <<MPEIV>>09440000
$PAGE                                                                   09445000
                                                                        09450000
    IF PFLAG THEN  << PREMPTIVE OR FIRST REQUEST >>                     09455000
      BEGIN   << CALL MONITOR/DRIVER >>                                 09460000
                                                               <<03655>>09465000
CALLMONITOR:                                                   <<03655>>09470000
                                                               <<03655>>09475000
        TOS := @DITP;     TOS := STACKDST&LSL(6);                       09480000
        IF NOT LFLAGS.NOTIMPEDABLE THEN TOS.IMPEDEOK := 1;              09485000
        <<PDISABLE IF DISC>>                                 <<01.02>>  09490000
        IF ENTRY'IS'DRQ THEN PDISABLE;                         <<06768>>09495000
        ENABLE;                                                         09500000
        AWAKEIO( *, * );    << CALL MONITOR >>                          09505000
        <<PENABLE IF DISC>>                                  <<01.02>>  09510000
        IF ENTRY'IS'DRQ THEN PENABLE;                          <<06768>>09515000
      end                                                      <<03655>>09520000
    else                                                       <<03655>>09525000
      ENABLE;  << Disc I/O may finish by now (if real fast) >> <<03655>>09530000
                                                               <<03655>>09535000
    IF PCBNUM = 0 THEN    <<NO PCBIO, RETURN WITH COMPLETION>><<<01.03>>09540000
      BEGIN                                                    <<01.03>>09545000
      TOS := 1;                                                <<01.03>>09550000
      TOS := 0;                                                <<01.03>>09555000
      GO TO OUT1;                                              <<01.03>>09560000
      END                                                      <<01.03>>09565000
    ELSE                                                       <<01.03>>09570000
      BEGIN                                                    <<01.03>>09575000
    DISABLE;                                                            09580000
    TOS := IF ENTRY'IS'DRQ THEN DRQ'FLAGS ELSE IOQ'FLAGS;      <<06768>>09585000
    IF FLAGS.RTYPE=1 THEN   << BLOCKED I/O >>                           09590000
      BEGIN                                                             09595000
        IF NOT TOS.COMPLETED THEN  << NOT COMPLETED SO WAIT >>          09600000
          BEGIN                                                         09605000
          IF GCLASSENABLEDMASK.CLASS0 THEN                     <<MPEIV>>09610000
             BEGIN  <<MEASURE STOP ON BLOCKED I/O EVENT>>      <<MPEIV>>09615000
             TOS:=MEASSTATXDSBANK;                             <<MPEIV>>09620000
             TOS:=MEASSTATXDSBASE;                             <<MPEIV>>09625000
             TOS:=TOS+C0SUB0'SEGRELOFF;                        <<MPEIV>>09630000
             IF ENTRY'IS'DRQ THEN TOS:=TOS+1<<DISC I/O>>       <<06768>>09635000
             ELSE IF (DITP.(0:1)=1 LAND FNCT.FUNC=0)<<TERM READ<<MPEIV>>09640000
             THEN TOS:=TOS+9 ELSE IF DITP.(0:1)=1<<TERM I/O>>  <<MPEIV>>09645000
             THEN TOS:=TOS+10 ELSE TOS:=TOS+24;<<MISC BIO>>    <<MPEIV>>09650000
             ASMB(LSEA);                                       <<MPEIV>>09655000
             TOS:=TOS+1;                                       <<MPEIV>>09660000
             ASMB(SSEA;DDEL);                                  <<MPEIV>>09665000
             END;                                              <<MPEIV>>09670000
          IF GCLASSENABLEDMASK.CLASS15 THEN                    <<01805>>09675000
             BEGIN <<PROCESS LEVEL BLOCKED IO>>                <<01805>>09680000
             TOS:=MEASPROCXDSBANK;                             <<01805>>09685000
             TOS:=MEASPROCXDSBASE;                             <<01805>>09690000
             TOS:=TOS+(IF ENTRY'IS'DRQ                         <<06768>>09695000
                          THEN DRQ'PCB ELSE IOQ'PCB)*          <<06768>>09700000
                      CLASS15'SUB0SIZE;                       <<<06768>>09705000
             IF ENTRY'IS'DRQ THEN                              <<06768>>09710000
                TOS:=TOS+CP'STOPBLOCKDISC ELSE                 <<01805>>09715000
             IF (DITP.(0:1)=1 LAND FNCT.FUNC=0) THEN           <<01805>>09720000
                TOS:=TOS+CP'STOPTERMREAD ELSE                  <<01805>>09725000
             IF DITP.(0:1) <> 1 THEN                           <<01805>>09730000
                TOS:=TOS+CP'STOPBLOCKEDIO                      <<01805>>09735000
             ELSE  <<DON'T WANT TO COUNT IT NOW>>              <<01805>>09740000
                GO TO SKIPIT;                                  <<01805>>09745000
             ASMB(LSEA);                                       <<01805>>09750000
             TOS:=TOS+1;                                       <<01805>>09755000
             ASMB(SSEA);                                       <<01805>>09760000
     SKIPIT: ASMB(DDEL);                                       <<01805>>09765000
             END;                                              <<01805>>09770000
          <<STUFF AWAY REASON STOPPED IN PROCESSES PCBX>>      <<01805>>09775000
          <<DONE UNCONDITIONALLY FOR HISTORY FOR MEAS INTF>>   <<01805>>09780000
          TOS:=ICS(-ICSSTKBANK);                               <<01805>>09785000
          TOS:=ICS(-ICSSTKBASE)+PXGLOBSIZE+MEASSTOPREASON'IDX; <<01805>>09790000
          IF ENTRY'IS'DRQ THEN                                 <<06768>>09795000
             TOS:=STOPDISCWAIT ELSE                            <<01805>>09800000
          IF (DITP.(0:1)=1 LAND FNCT.FUNC=0) THEN              <<01805>>09805000
             TOS:=STOPTERMREAD ELSE                            <<01805>>09810000
          IF DITP.(0:1) <> 1 THEN                              <<01805>>09815000
             TOS:=STOPBLKIONONTERM ELSE                        <<01805>>09820000
             TOS:=0;                                           <<01805>>09825000
          ASMB(SSEA;DDEL);                                     <<01805>>09830000
          TOS:=-%200;                                          <<MPEIV>>09835000
          TOS:=0; <<FOR WAIT'S SPECIAL INFORMATION PARAMETER>> <<MPEIV>>09840000
          IF ENTRY'IS'DRQ THEN                                 <<06768>>09845000
            begin   << DISC I/O >>                             <<03686>>09850000
            ASMB(tsbc SWBIT);  << Turn on short-wait bit >>    <<03686>>09855000
            absolute(SYSWAITTODISPMSG).DISCWAITFLAG := 1;      <<03686>>09860000
            end    << of special DISC processing >>            <<03686>>09865000
                                                               <<03686>>09870000
          else                                                 <<03686>>09875000
                                                               <<03686>>09880000
            if FNCT.FUNC = 0 then  << This is a read >>        <<03686>>09885000
              if DITP.(0:1) = 1 or << is a terminal  >>        <<03686>>09890000
                 DLTP(DTYPE).DDTYPE = TERMINAL then << MTS >>  <<03686>>09895000
                begin                                          <<03686>>09900000
                ASMB(tsbc 15);   << Tell DISP this is TRW >>   <<03686>>09905000
                absolute(SYSWAITTODISPMSG).TERMREADFLAG := 1;  <<03686>>09910000
                end;  << of special Terminal Read handling >>  <<03686>>09915000
                                                               <<03686>>09920000
            WAIT( *, * );                                      <<MPEIV>>09925000
                                                               <<MPEIV>>09930000
            IF ENTRY'IS'DRQ                                    <<06768>>09935000
               THEN BEGIN                                      <<06768>>09940000
                    IF NOT DRQ'DONE THEN GOTO CALLMONITOR;     <<06768>>09945000
                    END                                        <<06768>>09950000
               ELSE BEGIN                                      <<06768>>09955000
                    IF NOT IOQ'DONE THEN GOTO CALLMONITOR;     <<06768>>09960000
                    END;                                       <<06768>>09965000
          END;                                                 <<MPEIV>>09970000
                                                               <<MPEIV>>09975000
        ENABLE;                                                <<MPEIV>>09980000
        IF ENTRY'IS'DRQ                                        <<06768>>09985000
           THEN                                                <<06768>>09990000
              BEGIN                                            <<06768>>09995000
              TOS := DRQ'STAT;                                 <<06768>>10000000
              TOS := DRQ'COUNT;                                <<06768>>10005000
              RETURNDISCREQ(Q'ENTRY'INDEX);                    <<06768>>10010000
              END                                              <<06768>>10015000
           ELSE                                                <<06768>>10020000
              BEGIN                                            <<06768>>10025000
                                                               <<06768>>10030000
              TOS := IOQ'STAT;                                 <<06768>>10035000
              TOS := IOQ'COUNT;                                <<06768>>10040000
              RETURNIOQ(Q'ENTRY'INDEX);                        <<06768>>10045000
              END;                                             <<06768>>10050000
                                                               <<06768>>10055000
                                                               <<06768>>10060000
      END                                                      <<MPEIV>>10065000
    ELSE                                                       <<MPEIV>>10070000
      BEGIN << UNBLOCKED REQUEST, RETURN IOQ INDEX >>          <<MPEIV>>10075000
        ENABLE;                                                <<MPEIV>>10080000
        TOS := Q'ENTRY'INDEX;                                  <<06768>>10085000
        IF ENTRY'IS'DRQ                                        <<06768>>10090000
           THEN TOS.(1:1) := 1;                                <<06768>>10095000
                                                               <<06768>>10100000
                                                               <<06768>>10105000
                                                               <<06768>>10110000
                                                               <<06768>>10115000
OUT:                                                                    10120000
        TOS := 0;  << FOR P'ATTACHIO RETURN >>                 <<04317>>10125000
      END;                                                              10130000
      END;                                                     <<01.03>>10135000
                                                                        10140000
OUT1:  P'ATTACHIO := TOS;                                      <<04317>>10145000
                                                                        10150000
    TOS := DBSAVE;    IF = THEN RETURN;  << NOT SET HERE >>             10155000
    RESETCRITICAL(SAVECRIT);                                            10160000
    RESETDB( * );                                                       10165000
  END;      <<  P'ATTACHIO >>                                  <<04317>>10170000
$PAGE "PROCEDURE: ATTACHIO"                                    <<04317>>10175000
DOUBLE PROCEDURE ATTACHIO(LDEV, QMISC, DSTX, ADDR, FNCT,       <<04317>>10180000
                          CNT, P1, P2, FLAGS);                 <<04317>>10185000
                                                               <<04317>>10190000
VALUE                     LDEV, QMISC, DSTX, ADDR, FNCT,       <<04317>>10195000
                          CNT, P1, P2, FLAGS;                  <<04317>>10200000
                                                               <<04317>>10205000
INTEGER                   LDEV, QMISC, DSTX, ADDR, FNCT,       <<04317>>10210000
                          CNT, P1, P2, FLAGS;                  <<04317>>10215000
                                                               <<04317>>10220000
OPTION PRIVILEGED, UNCALLABLE;                                 <<04317>>10225000
                                                               <<04317>>10230000
BEGIN                                                          <<04317>>10235000
                                                               <<04317>>10240000
COMMENT                                                        <<04317>>10245000
                                                               <<04317>>10250000
     WHO:  Allan Walthers/Boise Division CIPER/3000 software.  <<04317>>10255000
Modified 4/20/82 for possible inclusion in BFD or CUB MITS.    <<04317>>10260000
                                                               <<04317>>10265000
     WHAT:  The old ATTACHIO is now known as P'ATTACHIO.       <<04317>>10270000
This procedure known as ATTACHIO is essentially a new module.  <<04317>>10275000
                                                               <<04317>>10280000
     PURPOSE:  This  procedure  determines the  type of device <<04317>>10285000
the  request  is  destined for, and routes  the request to the <<04317>>10290000
appropriate  device handling procedure,  if any.  For example, <<04317>>10295000
if  the  device is a CIPER device,   a logical driver for that <<04317>>10300000
class of device is called.                                     <<04317>>10305000
                                                               <<04317>>10310000
     INPUT:                                                    <<04317>>10315000
                                                               <<04317>>10320000
LDEV      Logical device number to which the IO is destined.   <<04317>>10325000
                                                               <<04317>>10330000
QMISC     Miscellaneous  parameter  specified for  the device. <<04317>>10335000
          If not specified must be zero.                       <<04317>>10340000
                                                               <<04317>>10345000
DSTX      DST  number of data segment.  If zero then specifies <<04317>>10350000
          that addr is DB relative to the callers stack.  Must <<04317>>10355000
          be zero if system buffers is specified.              <<04317>>10360000
                                                               <<04317>>10365000
ADDR      If  FLAGS.(12:1)  =  1  then  this is an  index to a <<04317>>10370000
          system  buffer.  If FLAGS.(12:1) =  0 then ADDR is a <<04317>>10375000
          relative address within data segment DSTX.           <<04317>>10380000
                                                               <<04317>>10385000
FNCT      Function code:  device defined but usually:          <<04317>>10390000
                                                               <<04317>>10395000
          0 = Read                                             <<04317>>10400000
          1 = Write                                            <<04317>>10405000
          2 = Open file                                        <<04317>>10410000
          3 = Close file                                       <<04317>>10415000
          4 = Close device                                     <<04317>>10420000
                                                               <<04317>>10425000
CNT       Data transfer count:                                 <<04317>>10430000
                                                               <<04317>>10435000
          If CNT > 0 then CNT value is a word count.  If CNT < <<04317>>10440000
          0 then CNT value is a byte count.                    <<04317>>10445000
                                                               <<04317>>10450000
P1        Parameter 1,  device dependent.                      <<04317>>10455000
                                                               <<04317>>10460000
P2        Parameter 2,  device dependent.                      <<04317>>10465000
                                                               <<04317>>10470000
FLAGS     Bit word.  Definitions are:                          <<04317>>10475000
                                                               <<04317>>10480000
.( 0:4)   Control and specification flags:                     <<04317>>10485000
                                                               <<04317>>10490000
          0 = unknown                                          <<04317>>10495000
          1 = file system                                      <<04317>>10500000
          2 = spooler                                          <<04317>>10505000
          10 = File system, NOBUF, sequential                  <<04500>>10510000
          11 = File system, NOBUF, direct access               <<04500>>10515000
          12 = File system, BUF, sequential                    <<04500>>10520000
          13 = File system, BUF, direct access                 <<04500>>10525000
          14 = File system, KSAM access (determined)           <<04500>>10530000
          15 = File system, IMAGE access (determined)          <<04500>>10535000
           9 = File system, BUF, FQUIESCEIO                    <<04500>>10540000
           8 = GENMESSAGE, msg set base, msg set size          <<04500>>10545000
          << * * See IOMOVE and FQUIESCEIO * * >>              <<04500>>10550000
                                                               <<04317>>10555000
.( 4:3)   0   Reserved. Not used.                              <<04317>>10560000
                                                               <<04317>>10565000
.( 7:2)   Premption flags.                                     <<04317>>10570000
                                                               <<04317>>10575000
          1 = soft premption                                   <<04317>>10580000
          2 = hard premption                                   <<04317>>10585000
                                                               <<04317>>10590000
.( 9:1)   0   Reserved. Not used.                              <<04317>>10595000
                                                               <<04317>>10600000
.(10:1)   Special  request.   Device  defined.   If  set  then <<04317>>10605000
          handling is to be applied to this request.           <<04317>>10610000
                                                               <<04317>>10615000
.(11:1)   If set then this is a diagnostic request.            <<04317>>10620000
                                                               <<04317>>10625000
.(12:1)   System  buffer  flag.   If set the  ADDR is an index <<04317>>10630000
          relative  to  the  SBUF  table.   For  devices which <<04317>>10635000
          support chaining the data is transferred to and from <<04317>>10640000
          a  set  of chained buffers, up  to a maximum of 1024 <<04317>>10645000
          words.   IF  clear  then  ADDR  is  a  data  segment <<04317>>10650000
          relative address.                                    <<04317>>10655000
                                                               <<04317>>10660000
.(13:3)   Request type:                                        <<04317>>10665000
                                                               <<04317>>10670000
          0  = Unblocked, no wake on completion.  Impede if no <<04317>>10675000
              LIOQ element is available.                       <<04317>>10680000
                                                               <<04317>>10685000
          1  = Blocked.  Caller is  to be waited until request <<04317>>10690000
              is completed.                                    <<04317>>10695000
                                                               <<04317>>10700000
          2   =   Unblocked,   wake  caller  when  request  is <<04317>>10705000
              completed.  impede if no LIOQ available.         <<04317>>10710000
                                                               <<04317>>10715000
          3  =  Unblocked  and no process  is to be associated <<04317>>10720000
              with this request.  Impede if no LIOQ available. <<04317>>10725000
                                                               <<04317>>10730000
          4  =  Unblocked,  no  wake on completion  but do not <<04317>>10735000
              impede if no LIOQ available.                     <<04317>>10740000
                                                               <<04317>>10745000
          5 = Reserved.                                        <<04317>>10750000
                                                               <<04317>>10755000
          6  = Unblocked, wake on completion but do not impede <<04317>>10760000
              if no LIOQ is available.                         <<04317>>10765000
                                                               <<04317>>10770000
          7  =  Unblocked  and no process  is to be associated <<04317>>10775000
              with  this request but do  not impede if no LIOQ <<04317>>10780000
              available.                                       <<04317>>10785000
                                                               <<04317>>10790000
$PAGE                                                          <<04317>>10795000
     OUTPUT:                                                   <<04317>>10800000
                           Blocked                             <<04317>>10805000
                           -------                             <<04317>>10810000
                                                               <<04317>>10815000
        0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15         <<04317>>10820000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>10825000
 S-1  |    Zero execpt for    |  Qualifying  |General |        <<04317>>10830000
      |    DISC routines      |    Status    | Status |        <<04317>>10835000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>10840000
 S-0  |               Transmission Log                |        <<04317>>10845000
      |               /Control Returns                |        <<04317>>10850000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>10855000
                                                               <<04317>>10860000
                    Unblocked (IO system)                      <<04317>>10865000
                    ---------------------                      <<04317>>10870000
                                                               <<04317>>10875000
        0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15         <<04317>>10880000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>10885000
 S-1  | 0| 0| 0|         IOQ Index of request         |        <<04317>>10890000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>10895000
 S-0  |                       0                       |        <<04317>>10900000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>10905000
                                                               <<04317>>10910000
                     Unblocked (DISC IO)                       <<04317>>10915000
                     -------------------                       <<04317>>10920000
                                                               <<04317>>10925000
        0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15         <<04317>>10930000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>10935000
 S-1  | 1| 0| 0|      Disk Request Table Pointer      |        <<04317>>10940000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>10945000
 S-0  |                       0                       |        <<04317>>10950000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>10955000
                                                               <<04317>>10960000
                    Unblocked (CS devices)                     <<04317>>10965000
                    ----------------------                     <<04317>>10970000
                                                               <<04317>>10975000
        0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15         <<04317>>10980000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>10985000
 S-1  | 0| 1| 0|         ?????????????????????        |        <<04317>>10990000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>10995000
 S-0  |                       0                       |        <<04317>>11000000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>11005000
                                                               <<04317>>11010000
                    Unblocked (CIPER IO)                       <<04317>>11015000
                    --------------------                       <<04317>>11020000
                                                               <<04317>>11025000
Note  that  CIPER  logical IOQ is  included here for reference <<04317>>11030000
only.   The first implementation of CIPER does not include the <<04317>>11035000
use of LIOQ's.  The second release of CIPER will, however, use <<04317>>11040000
this structure.                                                <<04317>>11045000
        0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15         <<04317>>11050000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>11055000
 S-1  | 0| 0| 1|    Logical IOQ number of request     |        <<04317>>11060000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>11065000
 S-0  |                       0                       |        <<04317>>11070000
      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+        <<04317>>11075000
                                                               <<04317>>11080000
$PAGE                                                          <<04317>>11085000
Discussion:                                                    <<04317>>11090000
                                                               <<04317>>11095000
  Control Returns:                                             <<04317>>11100000
                                                               <<04317>>11105000
  Disk Request Table Pointer:                                  <<04317>>11110000
                                                               <<04317>>11115000
  General Status:                                              <<04317>>11120000
                                                               <<04317>>11125000
  IOQ index of request:                                        <<04317>>11130000
                                                               <<04317>>11135000
  Logical IOQ Number of request:                               <<04317>>11140000
                                                               <<04317>>11145000
  PCB Number:                                                  <<04317>>11150000
                                                               <<04317>>11155000
  Qualifing Status:                                            <<04317>>11160000
                                                               <<04317>>11165000
  Transmission log:                                            <<04317>>11170000
     If CNT > 0 then CNT value is a word count.                <<04317>>11175000
                If CNT < 0 then CNT value is a byte count.     <<04317>>11180000
     This is the same as the CNT parameter of ATTACHIO.        <<04317>>11185000
                                                               <<04317>>11190000
The  IOQ index/number returned above  is used as the parameter <<04317>>11195000
to IOSTATUS to determine the completion status of the request. <<04317>>11200000
If  the  request type in FLAGS  specified that this request is <<04317>>11205000
not  impedable  then the IOQ index/LIOQ  number return will be <<04317>>11210000
zero if no IOQ/LIOQ elements are available.                    <<04317>>11215000
                                                               <<04317>>11220000
For type 3 requests, if ADDR is not zero then it is assumed to <<04317>>11225000
be a system buffer index.  At the completion of a request, the <<04317>>11230000
system  buffer(s) pointed to by ADDR  are returned to the free <<04317>>11235000
list by the I/O system.                                        <<04317>>11240000
                                                               <<04317>>11245000
The second part, P'ATTACHIO, consists of what is now the       <<04317>>11250000
bulk of ATTACHIO's code.  It will perform all the same         <<04317>>11255000
functions as the prior ATTACHIO which you all have come        <<04317>>11260000
to know and to ---------------.                                <<04317>>11265000
               Love                                            <<04317>>11270000
               Hate                                            <<04317>>11275000
               Care less about                                 <<04317>>11280000
               Huh?                                            <<04317>>11285000
                                                               <<04317>>11290000
;   <<END OF COMMENT>>                                         <<04317>>11295000
$PAGE                                                          <<04317>>11300000
<<Declaration of Variables>>                                   <<04317>>11305000
                                                               <<04317>>11310000
Equate                                                         <<04317>>11315000
  PRINTER'TYPE     = 32     <<First check for CIPER>>          <<04317>>11320000
 ,CIPER'09'SUBTYPE = 9      <<First check for CIPER subtype>>  <<04317>>11325000
 ,CIPER'13'SUBTYPE = 13     <<2nd check for CIPER subtype  >>  <<04317>>11330000
;                                                              <<04317>>11335000
                                                               <<04317>>11340000
<<Supported Serial Disc Types.  See ALLOCATE>>                 <<04317>>11345000
                                                               <<04317>>11350000
Equate                                                         <<04317>>11355000
  SIO'SDISC'TYP0   = 0      <<Series II/III types>>            <<04317>>11360000
 ,HPIB'SDISC'TYP2  = 2      <<Floppy on Series 30/33/44/64>>   <<04317>>11365000
 ,HPIB'SDISC'TYP3  = 3      <<7935 on Series 30/33/44/64>>     <<04317>>11370000
;                                                              <<04317>>11375000
                                                               <<04317>>11380000
<<Supported Serial Disc Subtypes.  See ALLOCATE>>              <<04317>>11385000
                                                               <<04317>>11390000
Equate                                                         <<04317>>11395000
  MH7920'7935      = 8    <<7920 Type 0 or 7935 type 3>>       <<04317>>11400000
 ,MH7905R          = 4    <<7905R Serial/removable only>>      <<04317>>11405000
 ,MH7906R          = 10   <<7906R Serial/removable only>>      <<04317>>11410000
 ,MH7925           = 9    <<7925 Serial Disc>>                 <<04317>>11415000
 ,MH7902'linus     = 0    <<7902 Type 2 dbl sided floppy>>     <<04317>>11420000
                          <<or 9140A type 3 Cartridge tape>>   <<04317>>11425000
;                                                              <<04317>>11430000
                                                               <<04317>>11435000
<<Definitions to access the LPDT entry specified by LDEV>>     <<04317>>11440000
                                                               <<04317>>11445000
Equate                                                         <<04317>>11450000
  LPDT'BASE        = %10                                       <<04317>>11455000
;                                                              <<04317>>11460000
                                                               <<04317>>11465000
Logical                                                        <<04317>>11470000
  LPDT'0                                                       <<04317>>11475000
                                                               <<06768>>11480000
 ,PREG             = Q-2  << Caller's P-register >>            <<06768>>11485000
;                                                              <<04317>>11490000
                                                               <<04317>>11495000
INTEGER                                                        <<06768>>11500000
   LPDT'INDEX                                                  <<06768>>11505000
;                                                              <<04317>>11510000
                                                               <<04317>>11515000
INTEGER                                                        <<06768>>11520000
  DLTP                                                         <<04317>>11525000
;                                                              <<04317>>11530000
                                                               <<04317>>11535000
Define                                                         <<04317>>11540000
  DITP             = LPDT'0 #                                  <<04317>>11545000
                                                               <<06768>>11550000
 ,F'OR'S           = (11:1)#                                   <<04317>>11555000
 ,DEV'SUB'TYPE     = (12:4)#                                   <<04317>>11560000
 ,DEVICE'IS'DISC   = (0 <= DEV'TYPE <= 7)#                     <<04317>>11565000
;                                                              <<04500>>11570000
<< Disc type/subtypes that are supported as SERIAL DISC >>     <<04500>>11575000
equate MAX'SUPPORTED = 9;                                      <<*1326>>11580000
integer array DEV'TYPE'ARR(0:MAX'SUPPORTED-1) = PB :=          <<04500>>11585000
                           0,  << 7920 >>                      <<04500>>11590000
                           0,  << 7925 >>                      <<04500>>11595000
                           3,  << 7933 >>                      <<04500>>11600000
                           2,  << 7902 >>                      <<04500>>11605000
                           0,  << 7905R>>                      <<04500>>11610000
                           0,  << 7906R>>                      <<04500>>11615000
                           3,  << LINUS>>                      <<06768>>11620000
                           3,  << BUFFALO >>                   <<*1326>>11625000
                           3;  << MERLIN  >>                   <<*1326>>11625100
integer array DEV'SUBTYPE'ARR(0:MAX'SUPPORTED-1) = PB :=       <<04500>>11630000
                           8,  << 7920 >>                      <<04500>>11635000
                           9,  << 7925 >>                      <<04500>>11640000
                           8,  << 7933 >>                      <<04500>>11645000
                           0,  << 7902 >>                      <<04500>>11650000
                           4,  << 7905R>>                      <<04500>>11655000
                           10, << 7906R>>                      <<04500>>11660000
                           0,  << LINUS>>                      <<06768>>11665000
                           3,  << BUFFALO >>                   <<*1326>>11670000
                           6;  << MERLIN  >>                   <<*1326>>11670100
                                                               <<04500>>11675000
                                                               <<04500>>11680000
                                                               <<04500>>11685000
                                                               <<04500>>11690000
                                                               <<04317>>11695000
<<Local/miscellaneous variables required>>                     <<04317>>11700000
                                                               <<04317>>11705000
Define                                                         <<04317>>11710000
  SPECIAL'SDISC'REQ     = (10:1)#                              <<04317>>11715000
;                                                              <<04317>>11720000
                                                               <<04317>>11725000
Integer                                                        <<04317>>11730000
  DEV'TYPE, SUBTYPE    << Device TYPE and SUBTYPE >>           <<04500>>11735000
;                                                              <<04317>>11740000
Double EXTBASE;                 << File system EXTENT base (sec<<04500>>11745000
Logical EXTSIZE;               << File system current EXTENT si<<04500>>11750000
double DQM17  = Q - 17;    << Loc file sys places EXTENT base ><<04500>>11755000
logical LQM15 = Q - 15;   << Loc file sys places EXTENT size >><<04500>>11760000
$PAGE                                                          <<04500>>11765000
LOGICAL SUBROUTINE CHECK'IF'SDISC;                             <<*7572>>11770000
                                                               <<*7572>>11775000
<<---------------------------------------------------------->> <<*7572>>11780000
<<  This subroutine returns TRUE if this disc is a serial   >> <<*7572>>11785000
<< disc and is to be processed by SDISCIO.                  >> <<*7572>>11790000
<<---------------------------------------------------------->> <<*7572>>11795000
                                                               <<*7572>>11800000
BEGIN                                                          <<*7572>>11805000
IF LPDT'SERIAL'OR'FOREIGN=LPDT'SERIAL AND                      <<*7572>>11810000
   LPDT'SERIAL'DISC THEN                                       <<*7572>>11815000
   BEGIN                                                       <<*7572>>11820000
   X := -1;    << X is used to index through device arrays >>  <<*7572>>11825000
   WHILE (X:=X+1) < MAX'SUPPORTED DO                           <<*7572>>11830000
     IF DEV'TYPE'ARR(X) = DEV'TYPE THEN                        <<*7572>>11835000
        IF DEV'SUBTYPE'ARR(X) = SUBTYPE THEN                   <<*7572>>11840000
           BEGIN                                               <<*7572>>11845000
           CHECK'IF'SDISC := true;                             <<*7572>>11850000
           RETURN;                                             <<*7572>>11855000
           END;                                                <<*7572>>11860000
                                                               <<*7572>>11865000
   END;                                                        <<*7572>>11870000
CHECK'IF'SDISC := FALSE;                                       <<*7572>>11875000
END;  << of subroutine CHECK'IF'SDISC >>                       <<*7572>>11880000
$PAGE "PROCEDURE: ATTACHIO"                                    <<04500>>11885000
                                                               <<04317>>11890000
                                                               <<04317>>11895000
<<Turn off internal traps.  Expand stack>>                     <<04317>>11900000
                                                               <<04317>>11905000
TRAPSOFF;                                                      <<04317>>11910000
                                                               <<04317>>11915000
ASMB(ADDS 255; SUBS 255);                                      <<04317>>11920000
                                                               <<04317>>11925000
<< Must have valid LDEV to continue.                        >> <<04317>>11930000
                                                               <<04317>>11935000
CHECKLDEV (LDEV);                                              <<04317>>11940000
IF < THEN SUDDENDEATH (206);                                   <<04317>>11945000
                                                               <<04317>>11950000
<<Get visiting LPDT entry for this LDEV>>                      <<04317>>11955000
LPDT'INDEX := LDEV * INTEGER(LPDT'ENTRY'SIZE);                 <<06768>>11960000
                                                               <<04317>>11965000
                                                               <<04317>>11970000
<<The first word is DIT pointer.  Make it absolute>>           <<04317>>11975000
                                                               <<04317>>11980000
LPDT'0 := LPDT'DIT'PTR + %1000;                                <<06768>>11985000
                                                               <<04317>>11990000
                                                               <<06768>>11995000
                                                               <<04317>>12000000
                                                               <<04317>>12005000
<<Now, Get DLT pointer from DIT and make it absolute>>         <<04317>>12010000
                                                               <<04317>>12015000
DLTP := %1000 + ABS(DITP+4);                                   <<04317>>12020000
                                                               <<04317>>12025000
                                                               <<04317>>12030000
<<Finally, get the device type from the absolute DLT entry>>   <<04317>>12035000
                                                               <<04317>>12040000
DEV'TYPE := ABS(DLTP+5).(8:8);                                 <<04317>>12045000
SUBTYPE := LPDT'SUBTYPE;                                       <<06768>>12050000
                                                               <<04317>>12055000
<<Check for CIPER device/sub-type. If CIPER, call LDVR>>       <<04317>>12060000
                                                               <<04317>>12065000
If DEV'TYPE = PRINTER'TYPE and                                 <<04317>>12070000
            ( SUBTYPE = CIPER'09'SUBTYPE or                    <<04500>>12075000
              SUBTYPE = CIPER'13'SUBTYPE )                     <<04500>>12080000
            then                                               <<04317>>12085000
                                                               <<04317>>12090000
  Begin <<Begin CIPER device processing>>                      <<04317>>12095000
                                                               <<04317>>12100000
  ATTACHIO := B08'LOGICAL'DVR(LDEV, QMISC, DSTX, ADDR, FNCT,   <<04317>>12105000
                              CNT, P1, P2, FLAGS);             <<04317>>12110000
  RETURN;                                                      <<04317>>12115000
                                                               <<04317>>12120000
  End;  <<CIPER device processing>>                            <<04317>>12125000
                                                               <<04317>>12130000
<<Check for serial disc>>                                      <<04317>>12135000
                                                               <<04317>>12140000
                                                               <<06768>>12145000
                                                               <<06768>>12150000
                                                               <<06768>>12155000
  if FLAGS.SPECIAL'SDISC'REQ = 0 and LDEV <> 1 Then            <<*7572>>12160000
                                                               <<*7572>>12165000
      << Not a special request, check for serial disc.      >> <<*7572>>12170000
                                                               <<*7572>>12175000
    If CHECK'IF'SDISC Then                                     <<*7572>>12180000
                                                               <<*7572>>12185000
      Begin << Not special and a serial disc, call SDISCIO  >> <<*7572>>12190000
                                                               <<04317>>12195000
      <<Note that we do not have to be concerned about where>> <<04317>>12200000
      <<the stack is at this point.  SDISCIO says that the  >> <<04317>>12205000
      <<stack can be anywhere on entry.  Lets hope so, since>> <<04317>>12210000
      <<at this point, we do not know or care where it is.  >> <<04317>>12215000
                                                               <<04317>>12220000
      ATTACHIO := SDISCIO(LDEV, QMISC, DSTX, ADDR, FNCT,       <<04317>>12225000
                          CNT, P1, P2, FLAGS);                 <<04317>>12230000
      RETURN;                                                  <<04317>>12235000
                                                               <<04317>>12240000
      End; <<End of Call SDISCIO>>                             <<*7572>>12245000
                                                               <<*7572>>12250000
                                                               <<06768>>12255000
if ABS(DITP).TDFLAGS = 1 then  << DIT says it's a disc >>      <<06768>>12260000
  begin                                                        <<06768>>12265000
                                                               <<06768>>12270000
  << If FILESYSTEM called ATTACHIO, as indicated by the >>     <<04500>>12275000
  << setting of FLAGS.(0:4) greater than 9, the EXTENT  >>     <<04500>>12280000
  << base and extent size will have been placed on the  >>     <<04500>>12285000
  << stack prior to the ATTACHIO double return value.   >>     <<04500>>12290000
  if FLAGS.(0:4) >= 8  then                                    <<04500>>12295000
    begin                                                      <<04500>>12300000
                                                               <<04317>>12305000
<<All other calls are normal I/O.  So, call P'ATTACHIO>>       <<04317>>12310000
                                                               <<04317>>12315000
    EXTBASE := DQM17; << Double EXTENT base sector # >>        <<04500>>12320000
    EXTSIZE := LQM15; << Logical EXTENT size in sectors >>     <<04500>>12325000
    end    << of processing TYPED disc I/O >>                  <<04500>>12330000
  else                                                         <<04500>>12335000
    begin  << Non-typed disc I/O >>                            <<04500>>12340000
    EXTBASE := 0D;                                             <<04500>>12345000
    EXTSIZE := 0;                                              <<04500>>12350000
    end;                                                       <<04500>>12355000
  end;  << of special DISC processing >>                       <<04500>>12360000
  << At this point, we have determined that a "physical" >>    <<06768>>12365000
  << disc I/O was intended.                              >>    <<06768>>12370000
                                                               <<06768>>12375000
  << If monitoring enabled, log this request's info >>         <<06768>>12380000
  IF ABS(SYSMON) THEN IF ABS(DITP).TDFLAGS=1 THEN      <<CAC1>><<06768>>12385000
    BEGIN                                                      <<06768>>12390000
    PDISABLE;   << To protect MMSTAT sequence >>               <<06768>>12395000
    MMSTAT'(-98,CNT,FLAGS.(0:4),FNCT,0,0,0);                   <<06768>>12400000
    MMSTAT'(-130,LDEV,PREG,RSTATUS,0,0,0);                     <<06768>>12405000
    TOS := -131;                                               <<06768>>12410000
    TOS := EXTBASE;                                            <<06768>>12415000
    MMSTAT'(*,*,*,EXTSIZE,0,0,0);                              <<06768>>12420000
    MMSTAT'(-132,P1,P2,FLAGS,0,0,0);                           <<06768>>12425000
    PENABLE;                                                   <<06768>>12430000
    END;                                                       <<06768>>12435000
                                                               <<06768>>12440000
  << If this a "cached" disc, call cache executor >>           <<06768>>12445000
  <<PDISABLE;>>  << In case we get QUIESCED after check >>     <<06768>>12450000
  IF (CACHE'DST <> 0) and ABS(DITP).CACHED                     <<*8111>>12455000
     and ABS(DITP).TDFLAGS=1   THEN                            <<*8111>>12460000
    BEGIN                                                      <<06768>>12465000
    ATTACHIO := CDT'ATTACHIO(LDEV,QMISC,DSTX,ADDR,FNCT,        <<06768>>12470000
                CNT,P1,P2,FLAGS,EXTBASE,EXTSIZE);              <<06768>>12475000
    <<PENABLE;>>                                               <<06768>>12480000
    END                                                        <<06768>>12485000
  ELSE                                                         <<06768>>12490000
    BEGIN                                                      <<06768>>12495000
    <<PENABLE;>>                                               <<06768>>12500000
ATTACHIO := P'ATTACHIO(LDEV, QMISC, DSTX, ADDR, FNCT,          <<04500>>12505000
                       CNT, P1, P2, FLAGS, EXTBASE, EXTSIZE);  <<04500>>12510000
                                                               <<04317>>12515000
  END;                                                         <<06768>>12520000
END;  <<ATTACHIO>>                                             <<04317>>12525000
$PAGE "PROCEDURE: IOSTATUS"                                    <<04317>>12530000
COMMENT                                                        <<06768>>12535000
<<***********************************************************>><<06768>>12540000
                                                               <<06768>>12545000
<<                 I O S T A T U S                           >><<06768>>12550000
                                                               <<06768>>12555000
<<   CALLS      :  RETURNDISCREQ                               <<06768>>12560000
                   RETURNIOQ                                   <<06768>>12565000
                                                               <<06768>>12570000
     CALLED BY  :                                              <<06768>>12575000
                                                               <<06768>>12580000
     INPUTS     :  IOQX                                        <<06768>>12585000
                                                               <<06768>>12590000
     OUTPUTS    :  STATUS                                      <<06768>>12595000
                   TRANSMISSION LOG/CONTROL                    <<06768>>12600000
                   IOQ'QMISC    IF ENTRY = IOSTATUSX           <<06768>>12605000
                   DRQ'QMISC    "     "     "                  <<06768>>12610000
                                                               <<06768>>12615000
     MODIFIED   :  12/10/82  RK                                <<06768>>12620000
                                                               <<06768>>12625000
     PURPOSE    : THIS PROCEDURE RETURNS THE STATUS            <<06768>>12630000
                  AND TRANSMISSION LOG/CONTROL OF THE          <<06768>>12635000
                  REQUEST IDENTIFIED BY IOQX.                  <<06768>>12640000
                  IF ENTERED VIA IOSTATUSX THEN RETURN         <<06768>>12645000
                  THE CONTENTS OF QMISC (IOQ OR DRQ)           <<06768>>12650000
                  IN THE X REGISTER.                         >><<06768>>12655000
                                                               <<06768>>12660000
<<***********************************************************>><<06768>>12665000
;                                                              <<06768>>12670000
                                                               <<06768>>12675000
DOUBLE PROCEDURE IOSTATUS(IOQX);                               <<06768>>12680000
   VALUE IOQX;                                                 <<06768>>12685000
   INTEGER IOQX;                                               <<06768>>12690000
   OPTION UNCALLABLE,PRIVILEGED;                               <<06768>>12695000
                                                               <<06768>>12700000
BEGIN                                                          <<06768>>12705000
   DEFINE   SETDBSYSGLOBAL =                                   <<06768>>12710000
               TOS := 0;                                       <<06768>>12715000
               TOS := SYSDB;                                   <<06768>>12720000
               XCHDB;                                          <<06768>>12725000
               OLDDB := TOS; #,                                <<06768>>12730000
                                                               <<06768>>12735000
            RESET'OLDDB =                                      <<06768>>12740000
               TOS := OLDDB;                                   <<06768>>12745000
               XCHDB;#,                                        <<06768>>12750000
                                                               <<06768>>12755000
            DISC'REQ = LIOQX.(1:1) = 1 #;                      <<06768>>12760000
                                                               <<06768>>12765000
                                                               <<06768>>12770000
                                                               <<06768>>12775000
   LOGICAL RETURNCC;                                           <<*7572>>12780000
   LOGICAL REQ'DONE;                                           <<06768>>12785000
   LOGICAL DRQX = IOQX;                                        <<06768>>12790000
   LOGICAL LIOQX = IOQX;                                       <<06768>>12795000
   LOGICAL XFLAG;                                              <<06768>>12800000
   DOUBLE D'FUNC'STATUS;                                       <<06768>>12805000
   DOUBLE OLDDB;                                               <<06768>>12810000
   INTEGER Q'ENTRY'INDEX;                                      <<06768>>12815000
   INTEGER IOQ'ENTRY'INDEX = Q'ENTRY'INDEX;                    <<06768>>12820000
   INTEGER DRQ'ENTRY'INDEX = Q'ENTRY'INDEX;                    <<06768>>12825000
   INTEGER ARRAY FUNC'STAT'CNT(*) = D'FUNC'STATUS;             <<06768>>12830000
   INTEGER OLDXREG = Q - 3;                                    <<06768>>12835000
   ENTRY IOSTATUSX;                                            <<06768>>12840000
                                                               <<06768>>12845000
                                                               <<06768>>12850000
   XFLAG := FALSE;                                             <<06768>>12855000
   GOTO L1;                                                    <<P8984>>12860000
IOSTATUSX:                                                     <<06768>>12865000
   XFLAG := TRUE;     << INITIALIZE FLAGS IF ENTRY TO IOSTATU>><<06768>>12870000
L1:                                                            <<06768>>12875000
   TRAPSOFF;               << TURN OFF TRAPS >>                <<P8984>>12880000
   PDISABLE ;                                                  <<06768>>12885000
                                                               <<06768>>12890000
   SETDBSYSGLOBAL;                                             <<06768>>12895000
                                                               <<06768>>12900000
Q'ENTRY'INDEX := IOQX.(2:14);              <<*IO5*>>           <<06768>>12905000
                                                               <<06768>>12910000
REQ'DONE := IF DISC'REQ<< DETERMINE WHETHER THE REQUEST IS CO>><<06768>>12915000
               THEN DRQ'DONE                                   <<06768>>12920000
               ELSE IOQ'DONE;                                  <<06768>>12925000
                                                               <<06768>>12930000
IF REQ'DONE                                                    <<06768>>12935000
   THEN                                                        <<06768>>12940000
      BEGIN                                                    <<06768>>12945000
      IF DISC'REQ                                              <<06768>>12950000
         THEN                                                  <<06768>>12955000
            BEGIN                                              <<06768>>12960000
                                                               <<06768>>12965000
                                                               <<*7572>>12970000
            FUNC'STAT'CNT := DRQ'STAT;   << PUT STATUS>>       <<*7572>>12975000
            FUNC'STAT'CNT(1) := DRQ'COUNT; <<TRANSFER COUNT I>><<06768>>12980000
            IF XFLAG                                           <<06768>>12985000
               THEN OLDXREG := DRQ'QMISC; << QMISC RETURNED I>><<06768>>12990000
            TOS := DRQ'ENTRY'INDEX;                           <<<06768>>12995000
            RETURNDISCREQ(*);                                  <<06768>>13000000
            END                                                <<06768>>13005000
         ELSE                                                  <<06768>>13010000
            BEGIN                                              <<06768>>13015000
                                                               <<06768>>13020000
                                                               <<06768>>13025000
            FUNC'STAT'CNT(0)    := IOQ'STAT;<<STATUS IN RETRN>><<06768>>13030000
            FUNC'STAT'CNT(1) := IOQ'COUNT;  <<TRANSFER COUNT>> <<06768>>13035000
            IF XFLAG                                           <<06768>>13040000
               THEN OLDXREG := IOQ'QMISC; <<QMISC RETURNED X >><<06768>>13045000
            TOS :=  IOQ'ENTRY'INDEX;                << C4MPE4>><<06768>>13050000
            RETURNIOQ(*);                                      <<06768>>13055000
                                                               <<06768>>13060000
            END;                                               <<06768>>13065000
                                                               <<06768>>13070000
      IOSTATUS := D'FUNC'STATUS;                               <<06768>>13075000
      RETURNCC := CCE;                           << CCE >>     <<*7572>>13080000
      END                                                      <<06768>>13085000
   ELSE                                                        <<06768>>13090000
      RETURNCC := CCG;                          << CCG >>      <<*7572>>13095000
                                                               <<06768>>13100000
RESET'OLDDB;                                                   <<06768>>13105000
PENABLE;                                                       <<06768>>13110000
RSTATUS.CC := RETURNCC;                                        <<06768>>13115000
END;        <<  I/O STATUS  >>                                 <<06768>>13120000
                                                               <<06768>>13125000
                                                               <<06768>>13130000
                                                               <<06768>>13135000
                                                               <<06768>>13140000
                                                               <<06768>>13145000
                                                               <<06768>>13150000
                                                               <<06768>>13155000
                                                               <<06768>>13160000
                                                               <<06768>>13165000
                                                               <<06768>>13170000
                                                               <<06768>>13175000
                                                               <<06768>>13180000
                                                               <<06768>>13185000
                                                                        13190000
                                                                        13195000
                                                                        13200000
$PAGE "WAIT FOR I/O"                                           <<JB.19>>13205000
<<************************************************************>>        13210000
                                                                        13215000
<<                  WAIT FOR IO                                         13220000
                                                                        13225000
                                                                        13230000
    CALLS     :   WAIT                                                  13235000
                  SETWAKE                                               13240000
                                                                        13245000
    CALLED BY :                                                         13250000
                                                                        13255000
    INPUTS    :   IOQX                                                  13260000
                                                                        13265000
    OUTPUTS   :   STATUS                                                13270000
                  TRANSMISSION LOG                                      13275000
                  QMISC                                                 13280000
                                                                        13285000
    MODIFIED  :   12/21/82   RK                                         13290000
                                                                        13295000
    PURPOSE   :   THIS PROCEDURE CHECKS TO SEE IF THE IO IS             13300000
                  DONE.  IF IT IS DONE THEN STATUS AND                  13305000
                  TRANSMISSION LOG ARE RETURNED.  IF NOT                13310000
                  THE CALLER HAS TO WAIT UNTIL THE IO IS                13315000
                  DONE.  THE PCB NUMBER IN THE REQUEST IS               13320000
                  SET TO THE PCB NUMBER OF THE CALLER                   13325000
                                                                        13330000
                  AND THE WAKE BIT IS SET IN THE IO REQUEST             13335000
                  RETURN SAME AS ATTACHIO.  ALSO QMISC IS               13340000
                  RETURNED IN THE X REGISTER.                 >>        13345000
                                                                        13350000
<<************************************************************>>        13355000
                                                               <<06768>>13360000
                                                               <<06768>>13365000
DOUBLE PROCEDURE WAITFORIO(IOQX);                              <<06768>>13370000
   VALUE IOQX;                                                 <<06768>>13375000
   INTEGER IOQX;                                               <<06768>>13380000
   OPTION PRIVILEGED,UNCALLABLE;                               <<06768>>13385000
                                                               <<06768>>13390000
BEGIN                                                          <<06768>>13395000
   DEFINE  DISC'REQ = LIOQX.(1:1) = 1 #,                       <<06768>>13400000
                                                               <<06768>>13405000
                                                               <<06768>>13410000
                                                               <<06768>>13415000
                                                               <<06768>>13420000
                                                               <<06768>>13425000
                                                               <<06768>>13430000
                                                               <<06768>>13435000
                                                               <<06768>>13440000
                                                               <<06768>>13445000
                                                               <<06768>>13450000
                                                               <<06768>>13455000
                                                               <<06768>>13460000
                                                               <<06768>>13465000
                                                               <<06768>>13470000
                                                               <<06768>>13475000
                                                               <<06768>>13480000
                                                               <<06768>>13485000
                                                               <<06768>>13490000
                                                               <<06768>>13495000
                                                               <<06768>>13500000
                                                               <<06768>>13505000
                                                               <<06768>>13510000
                                                               <<06768>>13515000
                                                               <<06768>>13520000
                                                               <<06768>>13525000
            DISCWAIT =                                         <<06768>>13530000
                                                               <<06768>>13535000
               ABSOLUTE(SYSWAITTODISPMSG).DISCWAITFLAG := 1;   <<06768>>13540000
               TOS := IOWAIT;                                  <<06768>>13545000
               TOS := 0;                                       <<06768>>13550000
               ASMB(TSBC SWBIT);                               <<06768>>13555000
               WAIT(*,*); #,                                   <<06768>>13560000
                                                               <<06768>>13565000
            MEASURE'UNBLOCKED'DISC'IO =                        <<06768>>13570000
               IF GCLASSENABLEDMASK.CLASS0                     <<06768>>13575000
                  THEN                                         <<06768>>13580000
                     begin                                      <<meas>>13585000
                     <<check if stopped from blocked or >>      <<meas>>13590000
                     << unblocked disc IO >>                    <<meas>>13595000
                     if DRQ'IS'LDRQ land LDR'IOWAKE THEN        <<meas>>13600000
                        STOP'INDEX := C'STOPBLOCKDISC           <<meas>>13605000
                     else                                       <<meas>>13610000
                        STOP'INDEX := C'STOPUNBLOCKDISC;        <<meas>>13615000
                                                                <<meas>>13620000
                     TOS := MEASSTATXDSBANK;                   <<06768>>13625000
                     TOS := MEASSTATXDSBASE;                   <<06768>>13630000
                     TOS := TOS + C0SUB0'SEGRELOFF +           <<06768>>13635000
                           STOP'INDEX;                          <<meas>>13640000
                     ASMB(LSEA);                               <<06768>>13645000
                     TOS := TOS + 1;                           <<06768>>13650000
                     ASMB(SSEA;DDEL);                          <<06768>>13655000
                     END;  #,                                  <<06768>>13660000
                                                               <<06768>>13665000
            PROCESS'UNBLOCKED'DISC'IO =                        <<06768>>13670000
               IF GCLASSENABLEDMASK.CLASS15                    <<06768>>13675000
                  THEN                                         <<06768>>13680000
                     begin                                      <<meas>>13685000
                     <<check if stopped from blocked or >>      <<meas>>13690000
                     << unblocked disc IO >>                    <<meas>>13695000
                     if DRQ'IS'LDRQ land LDR'IOWAKE THEN        <<meas>>13700000
                        STOP'INDEX := CP'STOPBLOCKDISC          <<meas>>13705000
                     else                                       <<meas>>13710000
                        STOP'INDEX := CP'STOPUNBLOCKDISC;       <<meas>>13715000
                                                                <<meas>>13720000
                     TOS := MEASPROCXDSBANK;                   <<06768>>13725000
                     TOS := MEASPROCXDSBASE;                   <<06768>>13730000
                     TOS := TOS + WAITINGPIN * CLASS15'SUB0SIZE<<06768>>13735000
                                                  << C4MPE4 >> <<06768>>13740000
                           + STOP'INDEX;                        <<meas>>13745000
                     ASMB(LSEA);                               <<06768>>13750000
                     TOS := TOS + 1 ;                          <<06768>>13755000
                     ASMB(SSEA;DDEL);                          <<06768>>13760000
                     end; #;                                    <<meas>>13765000
                                                               <<06768>>13770000
   ENTRY WAITFORIOX;                                           <<06768>>13775000
   INTEGER ARRAY WAITTYPE(0:3) = PB := 0,%100000,1,1;          <<06768>>13780000
                                                               <<06768>>13785000
INTEGER LPDT'INDEX;                                            <<06768>>13790000
   LOGICAL XFLAG;                                              <<06768>>13795000
   INTEGER WAITINGPIN,                                         <<06768>>13800000
           REQINX,                                             <<06768>>13805000
           DSTNUM;                                             <<06768>>13810000
   LOGICAL DRQX = IOQX;                                        <<06768>>13815000
   LOGICAL LIOQX = IOQX;                                       <<06768>>13820000
   INTEGER Q'ENTRY'INDEX;                                      <<06768>>13825000
   INTEGER IOQ'ENTRY'INDEX = Q'ENTRY'INDEX;                    <<06768>>13830000
   INTEGER DRQ'ENTRY'INDEX = Q'ENTRY'INDEX;                    <<06768>>13835000
   INTEGER POINTER ST = 2; << DST DECLARED DB REL UP FRONT >>  <<06768>>13840000
   INTEGER OLDXREG = Q - 3; << TO RETURN QMISC IN WAITFORIOX >><<06768>>13845000
   INTEGER RSTATUSC;                                           <<06768>>13850000
   INTEGER DIT'ADDR;                                           <<06768>>13855000
   INTEGER LDR'ENTRY'INDEX = Q'ENTRY'INDEX;                    <<06768>>13860000
   INTEGER STOP'INDEX ;                                         <<meas>>13865000
                                                               <<06768>>13870000
   DOUBLE SEGID;                                               <<06768>>13875000
   LOGICAL ARRAY SEGID'(*)=SEGID;                              <<06768>>13880000
$PAGE                                                          <<06768>>13885000
                                                               <<06768>>13890000
   XFLAG := FALSE;                                             <<06768>>13895000
   GOTO L1;                                                    <<06768>>13900000
                                                               <<06768>>13905000
WAITFORIOX:                                                    <<06768>>13910000
   XFLAG := TRUE;                                              <<06768>>13915000
                                                               <<06768>>13920000
L1:                                                            <<06768>>13925000
  DISABLE;                                                     <<06768>>13930000
  Q'ENTRY'INDEX := IOQX;                                       <<06768>>13935000
  WAITFORIO := IOSTATUSX(Q'ENTRY'INDEX);                       <<06768>>13940000
  IF =                                                         <<06768>>13945000
     THEN   << REQUEST COMPLETE>>                              <<06768>>13950000
        BEGIN                                                  <<06768>>13955000
        IF XFLAG                                               <<06768>>13960000
           THEN OLDXREG := X;                                  <<06768>>13965000
        RSTATUSC := CCE;                                       <<06768>>13970000
        GOTO OUT;                                              <<06768>>13975000
        END;                                                   <<06768>>13980000
                                                               <<06768>>13985000
  IF >      << NOT COMPLETED >>                                <<06768>>13990000
     THEN                                                      <<06768>>13995000
        BEGIN                                                  <<06768>>14000000
      WAITINGPIN := (CURPRC)/PCBSIZE;                          <<06768>>14005000
                                                               <<06768>>14010000
        IF DISC'REQ                 << SEE IF DISC REQUEST >>  <<06768>>14015000
           THEN                                                <<06768>>14020000
              BEGIN    << DISC IO WAIT >>                      <<06768>>14025000
              DRQ'ENTRY'INDEX := DRQX.(2:14);                  <<06768>>14030000
LPDT'INDEX := INTEGER(DRQ'LDEV) * INTEGER(LPDT'ENTRY'SIZE);    <<06768>>14035000
                                                               <<06768>>14040000
<< IF THIS IS A LOGICAL DISC REQUEST, WE MUST MAKE >>          <<06768>>14045000
<< SURE THAT IT IS CURRENTLY IN A STATE WHERE      >>          <<06768>>14050000
<< IT CAN BE COMPLETED.                            >>          <<06768>>14055000
              IF CACHE'DST <> 0 AND    << CACHING IS ENABLED >><<06768>>14060000
                 LDR'LDREQ THEN        << IT'S A LOGICAL REQ >><<06768>>14065000
                 CDT'FORCE'LDR'COMPLETION(LDR'ENTRY'INDEX);    <<06768>>14070000
                                                               <<06768>>14075000
              DSTNUM := DRQ'BUF'DSTN;                          <<06768>>14080000
              IF ST(DSTNUM&LSL(2)) < 0                         <<06768>>14085000
                 THEN                                          <<06768>>14090000
                    BEGIN                                      <<06768>>14095000
      SEGID'(OBJIDTYPEFIELD) := OBJIDDATATYPE; << BUILD >>     <<06768>>14100000
      SEGID'(OBJIDPBXFIELD)  := 0;  << 2 WORD SEGID     >>     <<06768>>14105000
      SEGID'(OBJIDNUMFIELD)  := DSTNUM;                        <<06768>>14110000
      QUEUEONSEGMENT(SEGID);                                   <<06768>>14115000
                    GOTO L1;                                   <<06768>>14120000
                    END;                                       <<06768>>14125000
              PDISABLE;                                        <<*7572>>14130000
              SETWAKE(IOQX);                                   <<*7572>>14135000
              IF  <                                            <<*7572>>14140000
               THEN                                            <<*7572>>14145000
                BEGIN                                          <<*7572>>14150000
                PENABLE;                                       <<*7572>>14155000
                GO TO L1;                                      <<*7572>>14160000
                END;                                           <<*7572>>14165000
              <<  THE  WAIT IN DISCWAIT WILL PENABLE  >>       <<*7572>>14170000
              MEASURE'UNBLOCKED'DISC'IO;                       <<06768>>14175000
              PROCESS'UNBLOCKED'DISC'IO;                       <<06768>>14180000
              <<stuff away reason stopped in pcbx of impeded >> <<meas>>14185000
              <<process. done unconditionally for history for>> <<meas>>14190000
              <<measurement interface.  >>                      <<meas>>14195000
              TOS := ICS(-ICSSTKBANK);                          <<meas>>14200000
              TOS := ICS(-ICSSTKBASE);                          <<meas>>14205000
              TOS := TOS + PXGLOBSIZE+MEASSTOPREASON'IDX;       <<meas>>14210000
              TOS := STOPDISCWAIT;                              <<meas>>14215000
              ASMB(SSEA;DDEL);                                  <<meas>>14220000
               DISCWAIT ;                                       <<meas>>14225000
              END                                              <<06768>>14230000
           ELSE                                                <<06768>>14235000
              BEGIN    << NON DISC IO >>                       <<06768>>14240000
LPDT'INDEX := INTEGER(IOQ'LDEV) * INTEGER(LPDT'ENTRY'SIZE);    <<06768>>14245000
              IOQ'PCB := WAITINGPIN;                           <<06768>>14250000
              SETWAKE(IOQ'ENTRY'INDEX);     << DIT ADDR. >>    <<06768>>14255000
              DIT'ADDR := LPDT'DIT'PTR + SYSDB;                <<06768>>14260000
              WAIT(IOWAIT,WAITTYPE(ABS(DIT'ADDR).TDFLAGS));    <<06768>>14265000
              END;                                             <<06768>>14270000
        GOTO L1;                                               <<06768>>14275000
        END;                                                   <<06768>>14280000
     RSTATUSC := CCL; << REQUEST DOES NOT BELONG TO ANYBODY >> <<06768>>14285000
OUT:                                                           <<06768>>14290000
     RSTATUS.CC := RSTATUSC;  << SET RETURN CC >>              <<06768>>14295000
END;   << WAIT FOR IO >>                                       <<06768>>14300000
                                                               <<06768>>14305000
                                                               <<06768>>14310000
                                                               <<06768>>14315000
                                                               <<06768>>14320000
                                                               <<06768>>14325000
                                                               <<06768>>14330000
                                                               <<06768>>14335000
                                                               <<06768>>14340000
                                                               <<06768>>14345000
                                                               <<06768>>14350000
                                                               <<06768>>14355000
                                                               <<06768>>14360000
                                                               <<06768>>14365000
                                                               <<06768>>14370000
                                                               <<06768>>14375000
                                                               <<06768>>14380000
                                                               <<06768>>14385000
                                                               <<06768>>14390000
                                                               <<06768>>14395000
                                                               <<06768>>14400000
                                                               <<06768>>14405000
                                                               <<06768>>14410000
                                                               <<06768>>14415000
                                                               <<06768>>14420000
                                                               <<06768>>14425000
                                                               <<06768>>14430000
                                                               <<06768>>14435000
                                                               <<06768>>14440000
                                                               <<06768>>14445000
                                                               <<06768>>14450000
                                                               <<06768>>14455000
                                                               <<06768>>14460000
                                                               <<06768>>14465000
                                                               <<06768>>14470000
                                                               <<06768>>14475000
                                                               <<06768>>14480000
                                                               <<06768>>14485000
                                                               <<06768>>14490000
                                                               <<06768>>14495000
$PAGE "CHECK'FOR'DEVREC;checks devices that should be AVR'd."  <<s9286>>14497000
logical procedure CHECK'FOR'DEVREC(LDEV, PARM);                <<s9286>>14498000
                                                               <<s9286>>14499000
value   LDEV,        << logical device              >>         <<s9286>>14500000
        PARM;        << DEVREC invocation parameter >>         <<s9286>>14501000
logical LDEV,                                                  <<s9286>>14502000
        PARM;                                                  <<s9286>>14503000
option  PRIVILEGED, UNCALLABLE;                                <<s9286>>14504000
begin                                                          <<s9286>>14505000
                                                               <<s9286>>14506000
COMMENT                                                        <<s9286>>14507000
                                                               <<s9286>>14508000
   CHECK'FOR'DEVREC is called to determine whether a particular<<s9286>>14509000
logical device (LDEV) should be AVR'd or already has been      <<s9286>>14510000
AVR'd.                                                         <<s9286>>14511000
                                                               <<s9286>>14512000
   CHECK'FOR'DEVREC returns TRUE if the device should be AVR'd.<<s9286>>14513000
FALSE is returned if the device cannot be AVR'd or already has <<s9286>>14514000
been AVR'd.                                                    <<s9286>>14515000
                                                               <<s9286>>14516000
   CHECK'FOR'DEVREC will perform an AWAKE on DEVREC if         <<s9286>>14517000
PARM.(15:1) = 1.                                               <<s9286>>14518000
                                                               <<s9286>>14519000
   RECOGNIZE'DEVICE is an entry point used by SIODM calls      <<s9286>>14520000
to CHECK'FOR'DEVREC. Note that DB is not changed for entry     <<s9286>>14521000
point RECOGNIZE'DEVICE.                                        <<s9286>>14521010
                                                               <<s9286>>14522000
   If primary entry point CHECK'FOR'DEVREC is used then DB     <<s9286>>14523000
will be set to SYSDB upon entry then reset back to the         <<s9286>>14524000
Callers' DB and DB Bank before exiting.                        <<s9286>>14524010
                                                               <<s9286>>14525000
   Procedures called are AWAKE, SETSYSDB & RESETDB.            <<s9286>>14526000
                                                               <<s9286>>14527000
                                                               <<s9286>>14528000
   LDEV  -  logical device to check for AVR capability.        <<s9286>>14529000
   PARM  -  notifies CHECK'FOR'DEVREC whether to do an AWAKE   <<s9286>>14530000
            on DEVREC.                                         <<s9286>>14531000
                                                               <<s9286>>14532000
TABLES referenced:                                             <<s9286>>14533000
                                                               <<s9286>>14534000
   LPDT  -  contains device subtype, device recognition state  <<s9286>>14535000
            and the pointer to the Device Information Table.   <<s9286>>14536000
   DIT   -  contains pointer to Driver Linkage Table.          <<s9286>>14537000
   DLT   -  contains device type.                              <<s9286>>14538000
                                                               <<s9286>>14539000
;  << end of comment >>                                        <<s9286>>14540000
                                                               <<s9286>>14541000
                                                               <<s9286>>14542000
                                                               <<s9286>>14543000
                                                               <<s9286>>14544000
                                                               <<s9286>>14545000
define                                                         <<s9286>>14546000
   WAKE'DEVREC = PARM.(15:1)#; << if set and have an AVR   >>  <<s9286>>14547000
                               << device that hasn't been  >>  <<s9286>>14548000
                               << AVR'd then AWAKE DEVREC. >>  <<s9286>>14549000
                                                               <<s9286>>14550000
logical                                                        <<s9286>>14551000
   LPDT'INDEX,                 << used to peg the LPDT     >>  <<s9286>>14552000
   CALL'FROM'SIODM,            << SIODM entry point flag   >>  <<s9286>>14553000
   RET'VALUE;                  << value to return          >>  <<s9286>>14554000
                                                               <<s9286>>14555000
integer                                                        <<s9286>>14556000
   TYPE,                       << device type              >>  <<s9286>>14557000
   SUBTYPE,                    << device subtype           >>  <<s9286>>14558000
   OLDDB;                      << callers' return DB parm  >>  <<s9286>>14559000
                                                               <<s9286>>14560000
logical pointer                                                <<s9286>>14561000
   DITP,                       << Device Information Table >>  <<s9286>>14562000
   DLTP;                       << Driver Linkage Table     >>  <<s9286>>14563000
                                                               <<s9286>>14564000
entry                                                          <<s9286>>14565000
   RECOGNIZE'DEVICE;           << entry for SIODM          >>  <<s9286>>14566000
                                                               <<s9286>>14567000
                                                               <<s9286>>14568000
                                                               <<s9286>>14569000
                                                               <<s9286>>14570000
<<*********************************************************>>  <<s9286>>14570010
<<                                                         >>  <<s9286>>14570020
<< Note that DB only gets changed to SYSDB and reset back  >>  <<s9286>>14570030
<< to the callers' DB and DB Bank if this procedure is     >>  <<s9286>>14570040
<< entered through primary entry point CHECK'FOR'DEVREC.   >>  <<s9286>>14570050
<<                                                         >>  <<s9286>>14570060
<<*********************************************************>>  <<s9286>>14570070
                                                               <<s9286>>14571000
OLDDB := SETSYSDB;             << save callers environment >>  <<s9286>>14572000
CALL'FROM'SIODM := FALSE;      << set SIODM entry flag     >>  <<s9286>>14573000
goto COMMON'START;             << primary entry point      >>  <<s9286>>14574000
                                                               <<s9286>>14575000
RECOGNIZE'DEVICE:              << SIODM's entry point      >>  <<s9286>>14576000
                                                               <<s9286>>14577000
CALL'FROM'SIODM := TRUE;       << set entry point flag     >>  <<s9286>>14578000
                                                               <<s9286>>14579000
COMMON'START:                  << back to common code      >>  <<s9286>>14580000
                                                               <<s9286>>14581000
                                                               <<s9286>>14582000
<< peg the LPDT and set up pointers, variables >>              <<s9286>>14583000
                                                               <<s9286>>14584000
LPDT'INDEX := LDEV * LPDT'ENTRY'SIZE;                          <<s9286>>14585000
@DITP := LPDT'DIT'PTR;             << set DIT from LPDT >>     <<s9286>>14586000
@DLTP := DITP(DDLTP);              << set DLT from DIT  >>     <<s9286>>14587000
TYPE := DLTP(DSIZE).DEVTYPE;       << device type       >>     <<s9286>>14588000
SUBTYPE := LPDT'SUBTYPE;           << device subtype    >>     <<s9286>>14589000
RET'VALUE := FALSE;                << set return value  >>     <<s9286>>14590000
                                                               <<s9286>>14591000
<<                                                      >>     <<s9286>>14592000
<< Don't bother DEVREC if the device is "mounted" or    >>     <<s9286>>14593000
<< the System isn't UP yet or PVPROC is making this     >>     <<s9286>>14594000
<< request. Only if SIODM didn't make this call.        >>     <<s9286>>14595000
<<                                                      >>     <<s9286>>14596000
                                                               <<s9286>>14597000
if not CALL'FROM'SIODM and                                     <<s9286>>14598000
   (LPDT'RDY'SER'FRN'DISC or not SYSUP or (CURPRC=PVPROCPCBP)) <<s9286>>14599000
   then goto FORGET'IT;                                        <<s9286>>14600000
                                                               <<s9286>>14601000
if (LPDT'DATA'ACCEPT or LPDT'JOB'ACCEPT) and                   <<s9286>>14602000
   (LPDT'DEV'OWN'STATE = LPDT'NOT'OWNED) then RET'VALUE:=TRUE  <<s9286>>14603000
                                                               <<s9286>>14604000
else if (LPDT'DEV'OWN'STATE = LPDT'NOT'OWNED) and              <<s9286>>14605000
   AVR and MAGTAPE then RET'VALUE := TRUE                      <<s9286>>14606000
                                                               <<s9286>>14607000
else if 0 <= TYPE <= 3 then                                    <<s9286>>14608000
   case *TYPE of                                               <<s9286>>14609000
      begin << TYPE cases >>                                   <<s9286>>14610000
                                                               <<s9286>>14611000
      <<0>> begin  << 13037 disc family >>                     <<s9286>>14612000
            if LPDT'NON'SYS'DOMAIN = 1 then RET'VALUE := TRUE  <<s9286>>14613000
            else if (SUBTYPE = 5) or (SUBTYPE = 11)            <<s9286>>14614000
               then RET'VALUE := TRUE;                         <<s9286>>14615000
            end;   << 13037 disc family >>                     <<s9286>>14616000
                                                               <<s9286>>14617000
      <<1>> begin  << 2660 disc drive   >>                     <<s9286>>14618000
            end;   << 2660 disc drive   >>                     <<s9286>>14619000
                                                               <<s9286>>14620000
      <<2>> begin  << Floppy disc drive >>                     <<s9286>>14621000
            RET'VALUE := TRUE;                                 <<s9286>>14622000
            end;   << Floppy disc drive >>                     <<s9286>>14623000
                                                               <<s9286>>14624000
      <<3>> begin  << CS 80 devices     >>                     <<s9286>>14625000
            if LPDT'NON'SYS'DOMAIN = 1 then RET'VALUE := TRUE; <<s9286>>14626000
            end;   << CS 80 devices     >>                     <<s9286>>14627000
                                                               <<s9286>>14628000
      end;  << case of *TYPE >>                                <<s9286>>14629000
                                                               <<s9286>>14630000
if RET'VALUE and                                               <<s9286>>14631000
   (  (LPDT'DEV'OWN'STATE = LPDT'NOT'OWNED)                    <<s9286>>14632000
                    or                                         <<s9286>>14633000
   (LPDT'DEV'OWN'STATE = LPDT'OWNED)  ) then                   <<s9286>>14634000
   begin                                                       <<s9286>>14635000
   if WAKE'DEVREC then                                         <<s9286>>14636000
      begin                                                    <<s9286>>14637000
      DISABLE;        << disable interrupts >>                 <<s9286>>14638000
                                                               <<s9286>>14639000
      <<                                               >>      <<s9286>>14640000
      << set service requested & bump serv. req. count >>      <<s9286>>14641000
      << reset interrupt ack. if request from SIODM    >>      <<s9286>>14642000
      <<                                               >>      <<s9286>>14643000
                                                               <<s9286>>14644000
      LPDT'DEV'OWN'STATE := LPDT'SERVICE'REQ;                  <<s9286>>14645000
      LPDT'SERV'REQ'COUNT := LPDT'SERV'REQ'COUNT + 1;          <<s9286>>14646000
      if CALL'FROM'SIODM then DITP.IAK := 0;                   <<s9286>>14647000
                                                               <<s9286>>14648000
      ENABLE;         << enable interrupts >>                  <<s9286>>14649000
      AWAKE(DEVRECPCBP, JUNKWAIT, NOWAIT); << wake DEVREC >>   <<s9286>>14650000
      end;  << if WAKE'DEVREC >>                               <<s9286>>14651000
   end   << if RET'VALUE, etc. >>                              <<s9286>>14652000
else RET'VALUE := FALSE;                                       <<s9286>>14653000
                                                               <<s9286>>14654000
FORGET'IT:                                                     <<s9286>>14655000
                                                               <<s9286>>14656000
CHECK'FOR'DEVREC := RET'VALUE; << give caller return value >>  <<s9286>>14657000
                                                               <<s9286>>14658000
if not CALL'FROM'SIODM then RESETDB(OLDDB);  << restore DB >>  <<s9286>>14659000
end;  << CHECK'FOR'DEVREC >>                                   <<s9286>>14660000
$PAGE "SIODM - SIO DEVICE MONITOR PROCEDURE"                            14665000
PROCEDURE SIODM(DITP,FLAGS);                                            14670000
VALUE DITP,FLAGS;                                                       14675000
INTEGER POINTER DITP;                                                   14680000
LOGICAL FLAGS;                                                          14685000
OPTION PRIVILEGED,UNCALLABLE;                                           14690000
BEGIN                                                                   14695000
<<                                                                      14700000
   STATE DISCRIPTION:                                                   14705000
        0 - START REQUEST                                               14710000
        1 - UNUSED                                                      14715000
        2 - CALL DRIVER INITIATOR                                       14720000
        3 - CALL DRIVER COMPLETOR                                       14725000
        4 - UNUSED                                                      14730000
        5 - COMPLETE REQUEST                                            14735000
        6 - UNEXPECTED INTERRUPT                                        14740000
        7 - START OPERATOR INTERVENTION WAIT                            14745000
      %10 - WAIT FOR OPERATOR INTERVENTION (RESTART AT STATE 0)         14750000
      %11 - WAIT FOR DATA MAKEPRESENT                                   14755000
      %12 - WAIT FOR INITIATOR CODE MAKEPRESENT (FREEZE)                14760000
      %13 - WAIT FOR I/O COMPLETION                                     14765000
      %14 - WAIT FOR DEVICE CONTROLLER                                  14770000
      %15 - WAITING FOR ATTN INTERRUPT FROM ANOTHER UNIT        RK0PV   14775000
      %16 - WAIT FOR INITIATOR MAKEPRESENT                              14780000
      %17 - WAIT FOR COMPLETOR MAKEPRESENT                              14785000
>>                                                                      14790000
DEFINE                                                         <<MPEIV>>14795000
   SEGF     = (8:8)#; << CST FIELD OF LABELS IN DLT >>                  14800000
DEFINE CAUSEFULLSWAP=(0:1)#;  <<FLAGPROC SPECIALINST >><<CAC1>><<06768>>14805000
DEFINE  CACHE'REQUEST = DRQ'SEGID1.ObjIDType = ObjIDCdType#;    <<meas>>14810000
DEFINE                                                         <<09419>>14811000
   DRIVER'CONTROLS'AVR = LOGICAL (DITP(DUNIT).(3:1)) #;        <<09419>>14812000
                                                               <<*7572>>14815000
                                                               <<*7572>>14820000
DOUBLE                                                                  14825000
   DISCADR  = DB + %331;      << LAST DISC ERROR LDEV & ADRESS>>        14830000
INTEGER                                                                 14835000
   DISCERR  = DB + %330;      << LAST DISC ERROR STATUS >>              14840000
                                                                        14845000
<< THE FOLLOWING VARIABLES ARE INITIALIZED AS NEEDED >>        <<06768>>14850000
                                                               <<06768>>14855000
INTEGER                                                        <<06768>>14860000
   PC    ;                    << PREMPTIVE REQUEST COUNTER >>  <<06768>>14865000
INTEGER                                                        <<06768>>14870000
   PL    ;                    << HIGEST PREMPTIVE LEVEL >>     <<06768>>14875000
INTEGER                                                        <<06768>>14880000
   CSTN  ;                    << DRIVER SEGMENT NUMBER >>      <<06768>>14885000
                                                               <<06768>>14890000
   << VARIABLES USED IN PREEMPTIVE QUEUE REORDERING  >>        <<06768>>14895000
                                                               <<06768>>14900000
INTEGER                                                        <<06768>>14905000
   THIS'ENTRY'INDEX;          << CURRENT SCAN POINTER >>       <<06768>>14910000
INTEGER                                                        <<06768>>14915000
   LAST'ENTRY'INDEX;          << LAST SCAN POINTER >>          <<06768>>14920000
DOUBLE                                                         <<06768>>14925000
   THESEPTRS= THIS'ENTRY'INDEX;                                <<06768>>14930000
INTEGER                                                        <<06768>>14935000
   STP'ENTRY'INDEX;           << CURRENT SAVE PTR >>           <<06768>>14940000
INTEGER                                                        <<06768>>14945000
   SLP'ENTRY'INDEX;           << LAST SAVE PTR >>              <<06768>>14950000
DOUBLE                                                         <<06768>>14955000
   SAVEPTRS = STP'ENTRY'INDEX;                                 <<06768>>14960000
LOGICAL XL  = X;              << LOGICAL X >>                  <<06768>>14965000
                                                               <<06768>>14970000
<< THE FOLLOWING VARIABLES ARE INITIALIZED AT ENTRY >>                  14975000
                                                               <<06768>>14980000
LOGICAL                                                        <<06768>>14985000
   FRZFLAG ;                << INTERNAL INITIATOR FRZN FLAG >> <<06768>>14990000
INTEGER POINTER                                                <<06768>>14995000
   DLTP    ,                  << DRIVER LINKAGE TABLE >>       <<06768>>15000000
   ILTP    ;                  << INTERRUPT LINKAGE TABLE >>    <<06768>>15005000
INTEGER                                                        <<06768>>15010000
   CONTROLLER ,               << CONTROLLER QUEUE NUMBER >>    <<06768>>15015000
   STATE      ;               << CURRENT MONITOR STATE >>      <<06768>>15020000
                                                               <<06768>>15025000
   << IOQP IS NOW A SUBROUTINE:  I/O REQUEST QUEUE POINTER >>  <<06768>>15030000
LOGICAL THISDEVPRI;                                            <<06768>>15035000
INTEGER DISCQLENGTH;                                           <<06768>>15040000
INTEGER POINTER HEADDIT,                                       <<06768>>15045000
                NEXTDIT;                                       <<06768>>15050000
                                                               <<06768>>15055000
   DOUBLE SEGID;                                               <<06768>>15060000
   LOGICAL ARRAY SEGID'(*)=SEGID;                              <<06768>>15065000
$EDIT VOID = 15090000                                          <<s9286>>15070000
                                                               <<03686>>15095000
LOGICAL POINTER                                                         15100000
   DITPL    = DITP,                                                     15105000
   DLTPL    = DLTP;                                            <<06768>>15110000
<< IOQP0    = IOQP;   >>                                       <<06768>>15115000
                                                                        15120000
DEFINE                                                         <<03031>>15125000
   LDEV     = DITP(DLDEV)#,                                    <<s9286>>15125100
   TYPE     = DLTP(DSIZE).DEVTYPE#,                            <<03031>>15130000
   LPDT1    = LS0#;                                            <<03031>>15135000
                                                                        15140000
                                                               <<06768>>15145000
<<      DECLARATIONS ADDED IN MPE V     >>                     <<06768>>15150000
     INTEGER Q'ENTRY'INDEX;                                    <<06768>>15155000
     INTEGER DRQ'ENTRY'INDEX = Q'ENTRY'INDEX;                  <<06768>>15160000
     INTEGER IOQ'ENTRY'INDEX = Q'ENTRY'INDEX;                  <<06768>>15165000
     INTEGER LPDT'INDEX;                                       <<06768>>15170000
                                                               <<06768>>15175000
     DOUBLE D1000D := %1000D;                                  <<07410>>15180000
     DOUBLE ABS'Q'ADDR;                                        <<07410>>15185000
     INTEGER Q'ADDR'BANK = ABS'Q'ADDR,                         <<07410>>15190000
             Q'ADDR'OFFSET=ABS'Q'ADDR+1;                       <<07410>>15195000
     LOGICAL  ADISC;                                           <<07410>>15200000
     DEFINE                                                    <<07410>>15205000
               SETDB'SYS = BEGIN                               <<07410>>15210000
                            TOS := D1000D;                     <<07410>>15215000
                            ASSEMBLE(XCHD;DDEL);               <<07410>>15220000
                           END#,                               <<07410>>15225000
                                                               <<07410>>15230000
               SETDB'QUE = BEGIN                               <<07410>>15235000
                            ASSEMBLE(LDD ABS'Q'ADDR;           <<07410>>15240000
                                     ADDM Q'ENTRY'INDEX;);     <<07410>>15245000
                            ASSEMBLE(XCHD;DDEL);               <<07410>>15250000
                           END#,                               <<07410>>15255000
                                                               <<07410>>15260000
            NO'Q'ENTRY = (Q'ENTRY'INDEX=0)#,                   <<06768>>15265000
            IOQP0 = IOQP(0)#;                                  <<06768>>15270000
                                                               <<06768>>15275000
COMMENT                                                        <<06768>>15280000
    SUBROUTINE:  IOQP                                          <<06768>>15285000
    PURPOSE:  TO EMULATE THE POINTER IOQP ON THE RHS           <<06768>>15290000
              OF ASSIGNMENTS.                                  <<06768>>15295000
              ADDED AS PART OF MPEV                            <<06768>>15300000
 ;                                                             <<06768>>15305000
LOGICAL SUBROUTINE IOQP(ENTRY'WORD'OFFSET);                    <<06768>>15310000
  VALUE ENTRY'WORD'OFFSET;                                     <<06768>>15315000
  INTEGER ENTRY'WORD'OFFSET;                                   <<06768>>15320000
    BEGIN                                                      <<06768>>15325000
    ASSEMBLE(                                                  <<07410>>15330000
               LDD ABS'Q'ADDR;                                 <<07410>>15335000
               ADDM S-3;                                       <<07410>>15340000
               ADDM Q'ENTRY'INDEX;                             <<07410>>15345000
               LSEA;                                           <<07410>>15350000
               DELB,DELB;                                      <<07410>>15355000
               STOR S-3;                                       <<07410>>15360000
             );                                                <<07410>>15365000
                                                               <<07410>>15370000
    END;                                                       <<06768>>15375000
$EDIT VOID = 15740000                                          <<s9286>>15380000
                                                               <<03686>>15745000
   SUBROUTINE CHECKPOLL;                                       <<01496>>15750000
      BEGIN                                                    <<01496>>15755000
      DISABLE;                                                 <<01496>>15760000
      X := BUSY(CONTROLLER);                                   <<01496>>15765000
      IF <> AND WA0(X).STATEF = %15 THEN                       <<01496>>15770000
         BEGIN                                                 <<01496>>15775000
         WA0(X).STATEF := 5;                                   <<01496>>15780000
         WA0(X).IOPROG := 0;       << IT RAN POLL SIOPROG >>   <<01496>>15785000
         SIOCOUNT := SIOCOUNT - 1; << AND GOT NO INTERRUPT >>  <<01496>>15790000
         TOS := X;                                             <<01496>>15795000
         ENABLE;                                               <<01496>>15800000
         MMSTAT'(191,@DITP,X,DITP,0,0,0);                      <<06768>>15805000
         TOS := ILTP(ICNTRL);                                  <<07341>>15810000
         IF < THEN                                             <<01496>>15815000
            BEGIN                                              <<01496>>15820000
            TOS := BUSY(CONTROLLER);                           <<07341>>15825000
            CHKCHANNELQUE(*,*);                                <<01496>>15830000
            END                                                <<01496>>15835000
         ELSE DEL;                                             <<01496>>15840000
         AWAKEIO(*,0);                                         <<01496>>15845000
         END;                                                  <<01496>>15850000
      ENABLE;                                                  <<01496>>15855000
      END;                                                     <<01496>>15860000
                                                                        15865000
SUBROUTINE RELCONTROLLER;                                      <<01496>>15870000
BEGIN                                                          <<01496>>15875000
                                                               <<01496>>15880000
<< THIS ROUTINE RELEASES THE CONTROLLER RESOURCE >>            <<01496>>15885000
<< AND GIVES IT TO THE NEXT WAITER >>                          <<01496>>15890000
                                                               <<01496>>15895000
   DISABLE;                                                    <<01496>>15900000
   IF DITPL.MUNIT AND BUSY(CONTROLLER) = @DITP THEN            <<01496>>15905000
   BEGIN << I'VE GOT IT, GIVE IT BACK >>                       <<01496>>15910000
      BUSY(X) := 0;                                            <<01496>>15915000
      X := DEQUEUE(DLINK,X);                                   <<01496>>15920000
      IF X <> -1 THEN                                          <<C9352>>15925000
      BEGIN << SOMEONE IS WAITING, GIVE THEM CONTROLLER >>     <<01496>>15930000
         ASMB(LDXA,DUP);                                       <<JB.19>>15935000
         BUSY(CONTROLLER) := TOS; << SET RESOURCE BUSY >>      <<01496>>15940000
         ENABLE;                                               <<01496>>15945000
      IF BUSY(X) = @DITP THEN ASMB(DEL) ELSE AWAKEIO(*,0);     <<JB.19>>15950000
      END;                                                     <<01496>>15955000
   END;                                                        <<01496>>15960000
   ENABLE;                                                     <<01496>>15965000
END;                                                           <<01496>>15970000
                                                               <<01496>>15975000
                                                               <<01496>>15980000
                                                               <<01496>>15985000
SUBROUTINE UNFREEZEDATASEG;                                    <<01496>>15990000
IF IOQP0.DATAFRZN   THEN        <<  UNFREEZE DATA SEGMENT  >>  <<06768>>15995000
BEGIN                                                          <<01496>>16000000
                                                               <<01496>>16005000
<< THIS ROUTINE UNFREEZES THE CALLER'S DATA SEGMENT >>         <<01496>>16010000
                                                               <<01496>>16015000
   IF ADISC THEN DRQ'DATAFRZN:=0 ELSE IOQ'DATAFRZN := 0;       <<06768>>16020000
                                                               <<06768>>16025000
   BEGIN << SEG IS FROZEN, UNFREEZE IT >>                      <<01496>>16030000
      SEGID'(OBJIDTYPEFIELD) := OBJIDDATATYPE; << BUILD >>     <<06768>>16035000
      SEGID'(OBJIDPBXFIELD)  := 0;  << 2 WORD SEGID     >>     <<06768>>16040000
      SEGID'(OBJIDNUMFIELD)  := IOQP(QDSTN).DSTN;              <<06768>>16045000
      IOUNFREEZE'(SEGID);                                      <<06768>>16050000
      IF < THEN SUDDENDEATH(299);                              <<01496>>16055000
   END;                                                        <<01496>>16060000
END;                                                           <<01496>>16065000
                                                                        16070000
<< Log SIODM events in MMSTAT table >>                         <<03660>>16075000
subroutine LOG'MMSTAT(EVENT);                                  <<03660>>16080000
value EVENT;                                                   <<03660>>16085000
integer EVENT;                                                 <<03660>>16090000
begin                                                          <<06768>>16095000
                                                               <<06768>>16100000
<< log event to MMSTAT >>                                      <<06768>>16105000
  << Word 0 - MMSTAT event NUMBER                >>            <<06768>>16110000
  <<      1 - LDEV                               >>            <<06768>>16115000
  <<      2 - QUEUE ENTRY INDEX            >>                  <<06768>>16120000
  <<      3 - DIT  WORD 0:  DIT FLAGS WORD >>                  <<06768>>16125000
  <<      4 - CURRENT STATE OF SIODM        >>                 <<06768>>16130000
  <<      5 - CONTROLLER STATUS            >>                  <<06768>>16135000
  <<      6 - LSW of timer                 >>                  <<06768>>16140000
tos := EVENT;    << Event number for MMSTAT >>                 <<06768>>16145000
TOS := DITP(DLDEV);  << LDEV >>                                <<06768>>16150000
  COMMENT                                                      <<06768>>16155000
                                                               <<06768>>16160000
      Q'ENTRY'INDEX IS ALREADY TABLE RELATIVE                  <<06768>>16165000
                                                               <<06768>>16170000
  ;                                                            <<06768>>16175000
tos := Q'ENTRY'INDEX;                                          <<06768>>16180000
tos := DITP;     << DIT pointer on tos >>                      <<06768>>16185000
tos := STATE;  << Exit state >>                                <<06768>>16190000
tos := 0;                                                      <<06768>>16195000
tos := TIMER;  ASMB(delb);  << Timer LSW >>                    <<06768>>16200000
MMSTAT'(*,*,*,*,*,*,*);                                        <<06768>>16205000
                                                               <<03660>>16210000
end;   << of subroutine LOG'MMSTAT >>                          <<03660>>16215000
                                                                        16220000
$PAGE "SIODM - PROCEDURE MAINLINE"                             <<03660>>16225000
    << SET UP LOCAL VARIABLES >>                               <<06768>>16230000
LPDT'INDEX := DITP(DLDEV) * INTEGER(LPDT'ENTRY'SIZE);          <<06768>>16235000
   FRZFLAG := 0;                                               <<06768>>16240000
   @DLTP := DITP(DDLTP);                                       <<06768>>16245000
   @ILTP := DITP(DILTP);                                       <<06768>>16250000
   CONTROLLER := ILTP(IQUEUE).CQUEN;                           <<06768>>16255000
   DISABLE;                                                    <<06768>>16260000
   STATE := DITP.STATEF;                                       <<06768>>16265000
   ADISC := DITP.(0:2)=DISC';                                  <<07410>>16270000
   Q'ENTRY'INDEX := DITP(DIOQP);                               <<06768>>16275000
 << IOQP IS NOW A SUBROUTINE >>                                <<06768>>16280000
   Q'ADDR'BANK := ABSOLUTE(IF ADISC THEN SYSDISCREQTAB         <<07410>>16285000
                                    ELSE SYSIOQREQTAB);        <<07410>>16290000
   Q'ADDR'OFFSET := LOGICAL(Q'ADDR'BANK + %1000) LAND %177740; <<07410>>16295000
   Q'ADDR'BANK := LOGICAL(Q'ADDR'BANK) LAND %37;               <<07410>>16300000
                                                               <<07410>>16305000
                                                               <<07410>>16310000
  << Log SIODM entry in MMSTAT table >>                        <<03660>>16315000
  LOG'MMSTAT(194);   << %302=Event number >>                   <<03660>>16320000
                                                               <<03660>>16325000
   PDISABLE;                                                   <<01496>>16330000
                                                               <<09419>>16330100
COMMENT --                                                     <<09419>>16330200
  Usually an interrupt of an idle CP means a device  has  gone <<09419>>16330300
on  or  off line.  For non-system domain discs, PVPROC manages <<09419>>16330400
the table entries associated with these  events.  Trouble  is, <<09419>>16330500
CS80 devices can interrupt the idle CP for other reasons (such <<09419>>16330600
as a release request for internal maintenance or operator  un- <<09419>>16330700
load).  Until now, these interrupts also caused PVPROC to run, <<09419>>16330800
and it was up to PVPROC and the driver to make sure these  in- <<09419>>16330900
terrupts  were  ignored.  With  this change, drivers which are <<09419>>16331000
smart enough to know the difference between  on/off  line  and <<09419>>16331100
internal  interrupts  can cause SIODM to bypass State 6 (unex- <<09419>>16331200
pected interrupt) and go directly to State 0 (Start  Request). <<09419>>16331300
This  implies  that the driver will return to State 6 when PV- <<09419>>16331400
PROC should be scheduled, and to some other  state  (typically <<09419>>16331500
State 5 (Request Complete)) at other times.                    <<09419>>16331600
;                                                              <<09419>>16331700
IF STATE = 6 AND DRIVER'CONTROLS'AVR THEN                      <<09419>>16331800
   DITP.STATEF := STATE := 0;                                  <<09419>>16331900
                                                               <<01496>>16335000
AGAIN:                                                                  16340000
   TOS := DITP;                                                         16345000
   TOS.ACTIVE := 1; << SET THIS DIT ACTIVE AND WORK ON REQUEST >>       16350000
   IF <> THEN                                                           16355000
   BEGIN << ALREADY ACTIVE, SET REQUEST AND EXIT >>                     16360000
      TOS.REQUEST := 1;                                                 16365000
      DITP := TOS;                                                      16370000
      PENABLE;                                                 <<01496>>16375000
      RETURN;                                                           16380000
   END;                                                                 16385000
   TOS.REQUEST := 0;                                           <<01496>>16390000
   DITP := TOS;                                                         16395000
   ENABLE;                                                     <<01496>>16400000
STAY:                                                                   16405000
   X := STATE;                                                          16410000
ASMB(LOAD SWT,X; ADAX; BR SWT,X; << FAST SWITCH >>                      16415000
SWT:                                                                    16420000
CON STATE0;  CON STATE1;  CON STATE2;  CON STATE3;                      16425000
CON STATE4;  CON STATE5;  CON STATE6;  CON STATE7;                      16430000
CON STATE10; CON STATE11; CON STATE12; CON STATE13;                     16435000
CON STATE14; CON STATE15; CON STATE16; CON STATE17);                    16440000
<<>>                                                                    16445000
   HELP;                                                                16450000
<<>>                                                                    16455000
STATE0:                                                                 16460000
    Q'ENTRY'INDEX := DITP(DIOQP);                              <<06768>>16465000
      IF DITPL.SIOPREMPT AND  NOT  ADISC   THEN                <<07410>>16470000
   BEGIN << SERVICE PREMTIVE REQUEST >>                                 16475000
      PC := 0;                                                          16480000
      PL := 0;                                                          16485000
      THIS'ENTRY'INDEX := IOQ'ENTRY'INDEX;                     <<06768>>16490000
      WHILE <> DO                                                       16495000
      BEGIN << SEARCH IOQ LIST FOR HIGHEST PREMPTION >>                 16500000
         THIS'ENTRY'INDEX := THIS'ENTRY'INDEX;                 <<06768>>16505000
         TOS := IOQ(THIS'ENTRY'INDEX).PREMPTFLD; << PREMPT >>  <<06768>>16510000
         IF <> THEN PC := PC + 1; << FOUND ONE, INCREMENT COUNT >>      16515000
         IF TOS > PL THEN                                               16520000
         BEGIN << FOUND HIGHER PREMPT CODE, REMEMBER THIS ONE >>        16525000
            PL := IOQ(THIS'ENTRY'INDEX).PREMPTFLD;             <<06768>>16530000
            SAVEPTRS := THESEPTRS;                             <<06768>>16535000
         END;                                                           16540000
         LAST'ENTRY'INDEX := THIS'ENTRY'INDEX;                 <<06768>>16545000
         THIS'ENTRY'INDEX :=                                   <<06768>>16550000
            IOQ(THIS'ENTRY'INDEX+IOQ'QLINK'INDEX);             <<06768>>16555000
      END;                                                              16560000
      DISABLE;                                                 <<01496>>16565000
      IF PC <= 1 THEN DITP.SIOPREMPT := 0;                              16570000
      IF PC > 0 AND IOQ'ENTRY'INDEX <> STP'ENTRY'INDEX THEN    <<06768>>16575000
      BEGIN << REORDER REQUESTS, BRING PREMPTIVE REQUEST TO HEAD >>     16580000
         IOQ(SLP'ENTRY'INDEX+IOQ'QLINK'INDEX) := <<DELINK REQ>><<06768>>16585000
            IOQ(STP'ENTRY'INDEX+IOQ'QLINK'INDEX);<<FROM CUR>>  <<06768>>16590000
         << ADD REQUEST TO FRONT OF LIST>>                     <<06768>>16595000
         IOQ(STP'ENTRY'INDEX+IOQ'QLINK'INDEX) :=               <<06768>>16600000
            IOQ'ENTRY'INDEX ;                                  <<06768>>16605000
         DITP(DIOQP) := STP'ENTRY'INDEX;                       <<06768>>16610000
         Q'ENTRY'INDEX := STP'ENTRY'INDEX;                     <<06768>>16615000
      END;                                                              16620000
      ENABLE;                                                  <<01496>>16625000
   END;                                                                 16630000
   IF   NO'Q'ENTRY  THEN                                       <<06768>>16635000
   BEGIN << CHECK FOR WAIT START >>                            <<01496>>16640000
CHECKWAIT:                                                     <<01496>>16645000
      X := ILTP(IFLAG);                                        <<01496>>16650000
      IF < AND NOT LOGICAL(X).WAITPROG THEN                             16655000
      BEGIN << WAIT PROG IS NOT RUNNING >>                     <<01496>>16660000
         DISABLE;                                              <<01496>>16665000
         TOS := DITP;                                          <<01496>>16670000
         TOS.STWAIT := 1;                                      <<01496>>16675000
         IF STATE = %10 THEN TOS.NOTRDY := 1;                  <<01496>>16680000
         <<REMEMBER STATE %10>>                                <<01496>>16685000
         DITP := TOS;                                          <<01496>>16690000
         ENABLE;                                               <<01496>>16695000
         GO TO STATE2;                                         <<01496>>16700000
      END;                                                     <<01496>>16705000
IF   NO'Q'ENTRY                                                <<06768>>16710000
      THEN IF NOT DITPL.MUNIT OR BUSY(CONTROLLER)<>@DITP       <<06768>>16715000
THEN GO TO OUT ELSE GO TO CONT7;                               <<MPEIV>>16720000
      GO OUT;                                                  <<01496>>16725000
   END;                                                        <<01496>>16730000
DISABLE;                                                       <<*7572>>16735000
 SETDB'QUE;                                                    <<07410>>16740000
      SEGID'(OBJIDTYPEFIELD) := OBJIDDATATYPE; << BUILD >>     <<*7572>>16745000
      SEGID'(OBJIDPBXFIELD)  := 0;  << 2 WORD SEGID     >>     <<*7572>>16750000
      SEGID'(OBJIDNUMFIELD)  := ARQ'BUF'DSTN;                  <<*7572>>16755000
              IF ADISC AND ARQ'IOWAKE AND NOT ARQ'DBREL        <<*7572>>16760000
                 AND NOT ARQ'INLOCAL                           <<*7572>>16765000
                 THEN                                          <<*7572>>16770000
                 BEGIN << MUST ADD  OBJECT  TO  SLL  >>        <<*7572>>16775000
                 ARQ'INLOCAL:=1;  << INDICATE DISCIO BIT ON >> <<*7572>>16780000
                 IF ARQ'PCB = 0 THEN SUDDENDEATH(662);         <<*7572>>16785000
                 TOS := LPCB(ARQ'PCB*PCBSIZE + SLLIXWORDNUM);  <<*7572>>16790000
                 TOS := SEGID;                                 <<*7572>>16795000
                 TOS := 0;                                     <<*7572>>16800000
                 TOS.SETDISCIOSEGFLAG := 1;                    <<*7572>>16805000
                 SETDB'SYS;                                    <<*7572>>16810000
                 ADDTOLOCALITY(*,*,*);                         <<*7572>>16815000
                 SETDB'QUE;                                    <<*7572>>16820000
                 END;                                          <<*7572>>16825000
 IF  ARQ'SBUF     THEN        << ITS FROZEN >>                 <<07410>>16830000
                                                               <<07410>>16835000
     ARQ'DATAFRZN := 1;                                        <<07410>>16840000
   IF   ( ARQ'COUNT <> 0 )                                     <<*7572>>16845000
   AND NOT ARQ'DATAFRZN  THEN                                  <<07410>>16850000
     BEGIN                                                     <<06768>>16855000
     IF   NOT ADISC OR NOT ARQ'MMREQ  THEN                     <<07410>>16860000
        BEGIN <<FREEZE THE DATA SEGMENT>>                      <<MPEIV>>16865000
                                                               <<07410>>16870000
                                                               <<*7572>>16875000
                                                               <<*7572>>16880000
                                                               <<*7572>>16885000
                                                               <<*7572>>16890000
        SETDB'SYS;                                             <<07410>>16895000
        IOFREEZE'(SEGID);                                      <<06768>>16900000
        IF <>   THEN                                           <<07410>>16905000
                                                               <<07410>>16910000
                                                               <<07410>>16915000
                                                               <<07410>>16920000
           BEGIN <<SEND MSG TO SCHEDULER AND RETURN>>          <<MPEIV>>16925000
           IF ADISC  THEN                                      <<07410>>16930000
              BEGIN <<TOSS THIS REQUEST>>                      <<MPEIV>>16935000
              LOG'MMSTAT(%125);                                <<06768>>16940000
              SETDB'QUE;                                       <<07410>>16945000
              IF GCLASSENABLEDMASK.CLASS0 THEN                 <<MPEIV>>16950000
                 BEGIN  <<MEASURE DISC BUFFER TRAP>>           <<MPEIV>>16955000
                 TOS:=MEASSTATXDSBANK;                         <<MPEIV>>16960000
                 TOS:=MEASSTATXDSBASE;                         <<MPEIV>>16965000
                 TOS := TOS + ARQ'LDEV;                        <<*7572>>16970000
                 ASMB(LSEA); <<SEG REL OFFSET OF ITEM 0>>      <<MPEIV>>16975000
                  IF <> THEN << MI CAN RECOGNIZE THE DISC >>   <<N2297>>16976000
                  BEGIN                                        <<N2297>>16977000
                 TOS := TOS - ARQ'LDEV;  << SUB IDX TO TBL>>   <<*7572>>16980000
                 TOS:=TOS+C'BUFFERTRAP;                        <<MPEIV>>16985000
                 ASMB(LADD;LSEA;INCA;SSEA;DDEL);               <<MPEIV>>16990000
                  END                                          <<N2297>>16991000
                  ELSE  << MI CAN'T RECOGNIZE THE DISC >>      <<N2297>>16992000
                     ASMB(DEL,DDEL);                           <<N2297>>16993000
                 END;                                          <<MPEIV>>16995000
         <<   X:= DRQ'ENTRY'INDEX                       >>     <<06768>>17000000
              TOS:=ARQ'FLAGS;                                  <<07410>>17005000
                                                       <<CAC1>><<06768>>17010000
              TOS.DITSCURRREQFLAG:=0;                          <<06768>>17015000
              TOS.REQQUEUEDFLAG:=0;                            <<06768>>17020000
              ARQ'FLAGS:=TOS;                                  <<07410>>17025000
                                                               <<MPEIV>>17030000
                                                               <<*7572>>17035000
                                                               <<*7572>>17040000
                                                               <<*7572>>17045000
                                                               <<*7572>>17050000
                                                               <<*7572>>17055000
                                                               <<*7572>>17060000
                                                               <<*7572>>17065000
                                                               <<*7572>>17070000
                                                               <<*7572>>17075000
                                                               <<*7572>>17080000
                 SETDB'SYS;                                    <<07410>>17085000
                                                               <<*7572>>17090000
                 IF DRQ'BLOCKED                                <<*7572>>17095000
                  THEN                                         <<*7572>>17100000
                   FLAGPROCABSENT(DRQ'PCB,SEGID,%100000)       <<*7572>>17105000
                  ELSE   <<  %40000 TELLS KC ITS ADISC  >>     <<*7572>>17110000
                   FETCHIOSEG(SEGID,DITP(DLDEV),               <<*7572>>17115000
                       Q'ENTRY'INDEX+%40000,%100000);          <<*7572>>17120000
                                                               <<*7572>>17125000
                                                               <<06768>>17130000
                                                               <<*7572>>17135000
                                                               <<*7572>>17140000
              DITP(DIOQP):=0;                                  <<MPEIV>>17145000
              << Place on deferred disc request queue >>       <<06768>>17150000
              QueueDiscReq(DRQ'ENTRY'INDEX,0,0);               <<06768>>17155000
              STATE:=0;                                        <<MPEIV>>17160000
              GO TO CONT7; <<GET NEXT REQUEST>>                <<MPEIV>>17165000
            END                                                <<MPEIV>>17170000
         ELSE    <<   NOT   A   DISC   >>                      <<*7572>>17175000
      BEGIN                                                    <<MPEIV>>17180000
          <<ASK FOR BUFFER TO BE FETCHED AND FROZEN>>          <<06768>>17185000
                                                               <<*7572>>17190000
                                                               <<*7572>>17195000
                                                               <<*7572>>17200000
      FETCHIOSEG(SEGID,DITP(DLDEV),Q'ENTRY'INDEX,%100000);     <<06768>>17205000
      IF = THEN SUDDENDEATH(29);                               <<04302>>17210000
           <<WAIT FOR DATA SEGMENT MAKE PRESENT>>              <<MPEIV>>17215000
            TOS := %11;                                                 17220000
OUTTOS:                                                                 17225000
            STATE := TOS;                                               17230000
STATE1:                                                                 17235000
STATE4:                                                                 17240000
OUT:                                                                    17245000
            DISABLE;                                                    17250000
                                                               <<01782>>17255000
            <<MAKE AN MMSTAT RECORD OF LEAVING SIODM>>         <<01782>>17260000
            LOG'MMSTAT(195);  << %303=Event number >>          <<03660>>17265000
            TOS := DITP;                                                17270000
            TOS.STATEF := STATE; << INSERT NEW STATE FIELD >>           17275000
            TOS.ACTIVE := 0;                                            17280000
            TOS.REQUEST := 0;                                           17285000
            DITP := TOS;                                                17290000
            IF <> THEN GO TO AGAIN; << ANOTHER REQUEST PENDING >>       17295000
            PENABLE;                                           <<01496>>17300000
            END;                                               <<MPEIV>>17305000
            RETURN;                                                     17310000
         END;                                                           17315000
         IF ADISC THEN DRQ'DATAFRZN := 1 ELSE IOQ'DATAFRZN:= 1;<<06768>>17320000
      END;                                                              17325000
   END;                                                                 17330000
<<>>                                                                    17335000
STATE2:                                                                 17340000
   SETDB'SYS;                                                  <<07410>>17345000
   STATE := 2;                                                          17350000
   IF NOT DITPL.MUNIT THEN GO TO CONT3;                                 17355000
   IF NOT DLTPL.CORERES THEN                                            17360000
      BEGIN << NOT CORE RESIDENT, SO FREEZE DRIVER >>          <<MPEIV>>17365000
      CSTN := DLTP(DINIT).SEGF; FRZFLAG:=TRUE;                 <<MPEIV>>17370000
      SEGID'(OBJIDTYPEFIELD) := OBJIDSLTYPE;   << BUILD >>     <<06768>>17375000
      SEGID'(OBJIDPBXFIELD)  := 0;  << 2 WORD SEGID     >>     <<06768>>17380000
      SEGID'(OBJIDNUMFIELD)  := CSTN;                          <<06768>>17385000
      FETCHIOSEG(SEGID,DITP(DLDEV),Q'ENTRY'INDEX,%100000);     <<06768>>17390000
      IF = THEN DLTP.DVRFRZN:=1 <<ALL OK>> ELSE                <<01772>>17395000
         BEGIN <<COME BACK WHEN SEG SHOWS UP>>                 <<01772>>17400000
         TOS := %12;                                           <<MPEIV>>17405000
         GO TO OUTTOS;                                         <<MPEIV>>17410000
         END;                                                  <<MPEIV>>17415000
      END;                                                     <<MPEIV>>17420000
CONT12:                                                                 17425000
   DISABLE;                                                             17430000
   IF BUSY(CONTROLLER) <> 0 AND BUSY(X) <> @DITP THEN                   17435000
   BEGIN << DEVICE CONTROLLER BUSY, QUE REQUEST >>                      17440000
      IF DITPL.STWAIT THEN                                     <<01496>>17445000
      BEGIN << SOMEONE HAS RESOURCE, DON'T START WAIT >>       <<01496>>17450000
         IF NOT DLTPL.CORERES THEN FRZFLAG := TRUE;            <<01496>>17455000
         TOS := 5; << RETURN STATE >>                          <<01496>>17460000
         GO TO RETURNDVR; << COMPLETE REQ W/O CALLING DVR >>   <<01496>>17465000
      END;                                                     <<01496>>17470000
      IF GCLASSENABLEDMASK.CLASS0  THEN                        <<MPEIV>>17475000
         BEGIN  <<MEAS BUSY CONTROLLER EVENT>>                 <<MPEIV>>17480000
         TOS:=MEASSTATXDSBANK;                                 <<MPEIV>>17485000
         TOS:=MEASSTATXDSBASE;                                 <<MPEIV>>17490000
      TOS := TOS + DITPL(DLDEV) ;                              <<06768>>17495000
         ASMB(LSEA); <<ENTRY OF LDEVTAB IN MEASXDS>>           <<MPEIV>>17500000
      IF <> THEN << MI CAN RECOGNIZE THE DISC >>               <<N2297>>17501000
      BEGIN                                                    <<N2297>>17502000
      TOS := TOS - DITPL(DLDEV) ;                              <<06768>>17505000
         TOS:=TOS+C'BUSYCONTROLLER;                            <<MPEIV>>17510000
         ASMB(LADD;LSEA;INCA;SSEA;DDEL);                       <<MPEIV>>17515000
      END                                                      <<N2297>>17516000
      ELSE << MI CAN'T RECOGNIZE THE DISC >>                   <<N2297>>17517000
         ASMB(DEL,DDEL);                                       <<N2297>>17518000
         END;                                                  <<MPEIV>>17520000
      ADDTAIL(DITP,DLINK,CONTROLLER);  << QUEUE ON CONTROLLER >>        17525000
      TOS := %14;                                                       17530000
      GO TO OUTTOS;                                                     17535000
   END;                                                                 17540000
CONT14:                                                                 17545000
   BUSY(X) := @DITP; << SET CONTROLLER BUSY >>                          17550000
   ENABLE;                                                              17555000
   IF NOT DLTPL.CORERES THEN FRZFLAG := TRUE; <<INITIATOR CODE IS FRZN>>17560000
   STATE := 2;                                                          17565000
   GO TO CALLDVR;                                                       17570000
<<>>                                                                    17575000
STATE3: << STATE 3 AND NON-MULTIUNIT STATE 2 >>                         17580000
   STATE := 3;                                                          17585000
CONT3:                                                                  17590000
   IF NOT DLTPL.CORERES THEN                                   <<MPEIV>>17595000
      BEGIN << DRIVER NOT CORE RES., SO CHECK FOR ABSENCE >>   <<MPEIV>>17600000
      CSTN := DLTP(STATE).SEGF; << GET PCAL LABEL>>            <<MPEIV>>17605000
      IF ABSOLUTE(ABSOLUTE(0)+CSTN&LSL(2))<0 THEN              <<MPEIV>>17610000
         BEGIN <<NOT FROZEN>>                                  <<MPEIV>>17615000
         SEGID'(OBJIDTYPEFIELD) := OBJIDSLTYPE;<< BUILD >>     <<06768>>17620000
         SEGID'(OBJIDPBXFIELD)  := 0;  << 2 WORD SEGID  >>     <<06768>>17625000
         SEGID'(OBJIDNUMFIELD)  := CSTN;                       <<06768>>17630000
         FETCHIOSEG(SEGID,DITP(DLDEV),Q'ENTRY'INDEX,0);        <<06768>>17635000
         IF = THEN SUDDENDEATH(29);                            <<04302>>17640000
         TOS:=STATE+%14;                                       <<MPEIV>>17645000
         GO TO OUTTOS;                                         <<MPEIV>>17650000
         END;                                                  <<MPEIV>>17655000
      END;                                                     <<MPEIV>>17660000
CALLDVR:                                                                17665000
   ENABLE;             <<ALLOW INTERRUPTS IN THE DRIVER>>      <<I9053>>17670000
   IF ABS(SYSMON) AND STATE = 2 THEN                           <<01496>>17675000
   BEGIN << I/O START MMSTAT CALL >>                           <<01496>>17680000
      SETDB'QUE;                                               <<07410>>17685000
      TOS := -110;                                             <<01496>>17690000
      << THIS LINE MUST BE CHANGED FOR MPEV >>                 <<06329>>17695000
      TOS := ARQ'LDEV;                                         <<07410>>17700000
      TOS := ARQ'COUNT;                                        <<07410>>17705000
      TOS :=  ARQ'FUNC;                                        <<07410>>17710000
      IF S0 > 2 THEN                                           <<01496>>17715000
      BEGIN                                                    <<01496>>17720000
         DEL;                                                  <<01496>>17725000
         TOS := 2;                                             <<01496>>17730000
      END;                                                     <<01496>>17735000
      <<  THIS LINE MUST CHANGE FOR MPEV >>                    <<06768>>17740000
      TOS := TOS&LSL(14) + ARQ'BUFDST.DSTN;                    <<07410>>17745000
     SETDB'SYS;                                                <<07410>>17750000
      MMSTAT'(*,*,*,*,0,0,0);                                  <<06768>>17755000
   END;                                                        <<01496>>17760000
   TOS := STATE; << MONITOR STATE FOR DRIVER >>                         17765000
   IF DITPL.STWAIT THEN                                        <<01496>>17770000
   BEGIN << START WAIT PROG, NO IOQ >>                         <<01496>>17775000
      TOS := 0; << IOQP >>                                     <<01496>>17780000
      TOS := @DITP;  << DIT POINTER >>                         <<01496>>17785000
      TOS := 0D; << BUFFER ADRESS >>                           <<01496>>17790000
   END ELSE                                                    <<01496>>17795000
   BEGIN << NORMAL PROG START >>                               <<01496>>17800000
                                                               <<01496>>17805000
   TOS := Q'ENTRY'INDEX;                                       <<06768>>17810000
      TOS := @DITP;  << DIT POINTER >>                         <<01496>>17815000
   SETDB'QUE;                                                  <<07410>>17820000
   TOS := ARQ'BUFDST.DSTN;                                     <<07410>>17825000
   IF      (ARQ'COUNT=0)            << INCLHARD C #3 >>        <<07410>>17830000
    OR (ARQ'DATAFRZN=0) OR ARQ'MMREQ THEN TOS:=0  ELSE         <<07410>>17835000
   BEGIN      << FIND DB OFFSET IN SEGMENT >>                  <<04351>>17840000
      X :=  TOS&LSL(2)+2;   << ADDR OF DST ENTRY ADDR >>       <<07410>>17845000
      ASSEMBLE(LST 2;  INCX;  LST 2;);  << ADDR OF DSEG >>     <<07410>>17850000
      IF INTEGER(ARQ'BUFDST) < 0 THEN << STACK OFFSET>>        <<07410>>17855000
     ASMB(LDI 1; LADD; LSEA; LADD; LDI 1; LSUB); <<ABS BUFADR>><<01496>>17860000
   END;                                                        <<01496>>17865000
   TOS := TOS + LOGICAL(ARQ'BUFADR); << ADD DST/BANK OFFSET >> <<07410>>17870000
   IF ARQ'FUNC = 0 THEN                                        <<07410>>17875000
   BEGIN << CHECK FOR BANK WRAP-AROUND ON READS >>                      17880000
      ASMB(DUP,DUP); << CHECK FOR BANK WRAP - AROUND >>                 17885000
      TOS := ARQ'COUNT;                                        <<07410>>17890000
      IF S0<0 THEN TOS := -(TOS&ASR(1)); << POS. XFER CNT >>   <<06768>>17895000
      ASMB(LADD,LCMP); << (S-1) > (S) MEANS WRAP-AROUND >>              17900000
      IF > THEN SUDDENDEATH(260);                                       17905000
   END;                                                                 17910000
                                                               <<01496>>17915000
   END;                                                        <<01496>>17920000
   SETDB'SYS;                                                  <<07410>>17925000
   TOS := ILTP(ISIOP); << SIO PROG AREA PTR >>                          17930000
   TOS := ILTP(ICNTRL).(7:9);  << GET DRT # OUT OF ILT >>      <<03014>>17935000
   TOS := DLTP(STATE); << PCAL LABEL >>                                 17940000
   ASSEMBLE(PCAL 0);                                                    17945000
   IF DITP(DSERR) <> 0 THEN                                    <<02801>>17950000
   BEGIN << LOG I/O ERROR >>                                   <<02801>>17955000
      TOS := @DITP;                                            <<06768>>17960000
      TOS := Q'ENTRY'INDEX;                                    <<06768>>17965000
      LOGERROR( *  ,           *              ,DITP(DSERR));   <<06768>>17970000
      IF DITPL.DISC AND IOQP(QSTAT).STATUS <> 1 THEN           <<06768>>17975000
      BEGIN << DISC REQUEST FAILED, ENTER INFO IN SYSDB >>     <<02801>>17980000
      DISCERR := DITP(DITP(DSERR) );                           <<06768>>17985000
                                                               <<06768>>17990000
   TOS := DITPL(DLDEV)  + IOQP(QPAR1);                         <<06768>>17995000
         TOS := IOQP(QPAR2);                                   <<06768>>18000000
         DISCADR := TOS;                                       <<02801>>18005000
      END;                                                     <<02801>>18010000
      DITP(DSERR) := 0;                                        <<02801>>18015000
   END;                                                        <<02801>>18020000
RETURNDVR:                                                     <<01496>>18025000
   STATE := TOS; << SAVE DRIVER RETURN STATE >>                         18030000
   IF FRZFLAG THEN                                             <<MPEIV>>18035000
      BEGIN << UNFREEZE INIATIOR IF NEEDED >>                  <<MPEIV>>18040000
      FRZFLAG := FALSE;                                        <<MPEIV>>18045000
      SEGID'(OBJIDTYPEFIELD) := OBJIDSLTYPE;   << BUILD >>     <<06768>>18050000
      SEGID'(OBJIDPBXFIELD)  := 0;  << 2 WORD SEGID     >>     <<06768>>18055000
      SEGID'(OBJIDNUMFIELD)  := DLTP(DINIT).SEGF;              <<06768>>18060000
      IOUNFREEZE'(SEGID);                                      <<06768>>18065000
      IF < THEN SUDDENDEATH(299);                              <<MPEIV>>18070000
      IF = THEN DLTP.DVRFRZN := 0;                             <<MPEIV>>18075000
      END;                                                     <<MPEIV>>18080000
   GO TO STAY;                                                          18085000
<<>>                                                                    18090000
MAMERR:                                                                 18095000
   IF NOT DITPL.STWAIT THEN << LOG ERROR IN IOQ >>             <<01496>>18100000
   IF ADISC THEN DRQ'STAT := %124 ELSE IOQ'STAT := %124;       <<06768>>18105000
<<>>                                                                    18110000
STATE5:                                                                 18115000
   DISABLE;                                                    <<01496>>18120000
   DITP.STWAIT := 0;                                           <<01496>>18125000
   IF <> THEN                                                  <<01496>>18130000
   BEGIN << WAIT PROG STARTED, FINISH HERE >>                  <<01496>>18135000
      DITP.NOTRDY := 0;                                        <<01496>>18140000
      IF <> THEN TOS := %10 ELSE TOS := 0; <<RECOVER STATE>>   <<01496>>18145000
      RELCONTROLLER;                                           <<01496>>18150000
      GO TO OUTTOS;                                            <<01496>>18155000
   END;                                                        <<01496>>18160000
   ENABLE;                                                     <<01496>>18165000
   IF ABS(SYSMON) THEN                                         <<01496>>18170000
   BEGIN << LOG I/O COMPLETION >>                              <<01496>>18175000
      TOS := -111;                                             <<01496>>18180000
      TOS := IOQP(QLDEV);                                      <<06768>>18185000
      IF DITPL.DISC THEN                                       <<01496>>18190000
      BEGIN                                                    <<01496>>18195000
         TOS := IOQP(QPAR1);                                   <<06768>>18200000
         TOS := IOQP(QPAR2);                                   <<06768>>18205000
      END ELSE TOS := 0D;                                      <<01496>>18210000
      MMSTAT'(*,*,*,*,0,0,0);                                  <<06768>>18215000
   END;                                                        <<01496>>18220000
IF GCLASSENABLEDMASK.CLASS0 THEN                               <<MPEIV>>18225000
   BEGIN  <<MEASUREMENT ENABLED>>                              <<MPEIV>>18230000
   TOS:=MEASSTATXDSBANK;                                       <<MPEIV>>18235000
   TOS:=MEASSTATXDSBASE;                                       <<MPEIV>>18240000
   IF DITP.(0:2)=DISC' THEN                                    <<MPEIV>>18245000
      BEGIN <<UPDATE DISC COUNTER>>                            <<MPEIV>>18250000
    TOS := TOS + DITPL(DLDEV) ;                                <<06768>>18255000
      ASMB(LSEA); <<TOS HAS SEG REL OFFSET OF ITEM 0>>         <<MPEIV>>18260000
   IF <> THEN                                                  <<N2297>>18261000
   BEGIN  << WE KEEP COUNTERS FOR THE DEVICE WE RECOGNIZED >> <<FNDICS>>18262000
    TOS := TOS - DITPL(DLDEV) ;                                <<06768>>18265000
      IF DRQ'MMREQ  THEN                                       <<06768>>18270000
         BEGIN <<SEGMENT TRANSFER>>                            <<MPEIV>>18275000
         IF NOT DRQ'FUNC THEN                                  <<06768>>18280000
            BEGIN <<SEGMENT READ>>                             <<MPEIV>>18285000
            << MAKE SURE Q'ENTRY'INDEX IS PEGGED >>            <<06768>>18290000
            IF DRQ'SEGID'TYPE =  OBJIDDATATYPE         <<CAC1>><<*8396>>18295000
            THEN TOS:=TOS+C'DSEGREAD                   <<CAC1>><<*8396>>18300000
            ELSE IF DRQ'SEGID'TYPE =  OBJIDCDTYPE      <<CAC1>><<*8396>>18305000
                 THEN TOS:=TOS+C'CACHEREADACCESS       <<CAC1>><<*8396>>18310000
                 ELSE TOS:=TOS+C'CODEREAD;             <<CAC1>><<*8396>>18315000
            END                                        <<CAC1>><<06768>>18320000
         ELSE                                          <<CAC1>><<06768>>18325000
            BEGIN <<OBJECT WRITE>>                     <<CAC1>><<06768>>18330000
            << MAKE SURE Q'ENTRY'INDEX IS PEGGED >>            <<06768>>18335000
            IF DRQ'URGCLAS <> BKGRNDPRI THEN           <<CAC1>><<06768>>18340000
               BEGIN <<FORCED DATA OBJECT WRITE>>      <<CAC1>><<06768>>18345000
               IF   DRQ'SEGID'TYPE <> OBJIDCDTYPE      <<CAC1>><<07341>>18350000
               THEN TOS:=TOS+C'DSEGWRITEFORCED         <<CAC1>><<06768>>18355000
               ELSE TOS:=TOS+C'CACHEFORCEDWRITES;      <<CAC1>><<06768>>18360000
               END                                     <<CAC1>><<06768>>18365000
            ELSE                                       <<CAC1>><<06768>>18370000
               BEGIN <<BACKGROUND DATA OBJECT WRITE>>  <<CAC1>><<06768>>18375000
               IF   DRQ'SEGID'TYPE <> OBJIDCDTYPE      <<CAC1>><<07341>>18380000
               THEN TOS:=TOS+C'DSEGWRITEBKGRD          <<CAC1>><<06768>>18385000
               ELSE TOS:=TOS+C'CACHEBKGRNDWRITES;      <<CAC1>><<06768>>18390000
               END;                                    <<CAC1>><<06768>>18395000
            END;                                       <<CAC1>><<06768>>18400000
         END                                           <<CAC1>><<06768>>18405000
      ELSE                                                     <<MPEIV>>18410000
         BEGIN <<PROCESS INITIATED DISC TRANSFER>>             <<MPEIV>>18415000
         IF ((TOS := DRQ'FUNC) <= 1) OR (S0 = 5) OR (S0 = 6)   <<W2191>>18415100
            OR (S0 = 11) THEN   << IF FUNC = 5, 6, 11 THEN >>  <<W2191>>18415200
            BEGIN               << TREAT IT AS A WRITE FUNC>>  <<W2191>>18415300
            IF (S0 > 1) THEN                                   <<W2191>>18415400
               BEGIN                                           <<W2191>>18415500
               DEL;                                            <<W2191>>18415600
               TOS := 1;                                       <<W2191>>18415700
               END;                                            <<W2191>>18415800
            IF DRQ'BLOCKED THEN  << BLOCKED DISC I/O >>        <<W2191>>18415900
               CASE TOS OF                                     <<W2191>>18416000
                  BEGIN                                        <<W2191>>18416100
                  TOS := TOS + C'BLKREAD;                      <<W2191>>18416200
                  TOS := TOS + C'BLKWRITE;                     <<W2191>>18416300
                  END                                          <<W2191>>18416400
            ELSE IF DRQ'IOWAKE THEN  << UNBLOCKED DISC I/O >>  <<W2191>>18416500
               CASE TOS OF           << AWAKE SET >>           <<W2191>>18416600
                  BEGIN                                        <<W2191>>18416700
                  TOS := TOS + C'UNBLKREADAWAKE;               <<W2191>>18416800
                  TOS := TOS + C'UNBLKWRITEAWAKE;              <<W2191>>18416900
                  END                                          <<W2191>>18417000
            ELSE    << UNBLOCKED DISC IO, AWAKE NOT YET SET >> <<W2191>>18417100
               CASE TOS OF                                     <<W2191>>18417200
                  BEGIN                                        <<W2191>>18417300
                  TOS := TOS + C'UNBLKREAD;                    <<W2191>>18417400
                  TOS := TOS + C'UNBLKWRITE;                   <<W2191>>18417500
                  END;                                         <<W2191>>18417600
            END                                                <<W2191>>18417700
         ELSE       << CASE OF CONTROL FUNCTIONS >>            <<W2191>>18417800
            BEGIN                                              <<W2191>>18417900
            DEL;                                               <<W2191>>18418000
            TOS := TOS + C'DISCCONTROL;                        <<W2191>>18418100
            END;                                               <<W2191>>18418200
$EDIT VOID = 18640000                                          <<W2191>>18420000
         END;                                                  <<MPEIV>>18645000
      ASMB(LADD;LSEA;INCA;SSEA;DDEL);                          <<MPEIV>>18650000
   END     << END FOR WE CAN RECOGNIZE THE DISC DRIVE >>       <<N2297>>18650500
   ELSE   << IF WE DO NOT RECOGNIZE THIS DEVICE >>             <<N2297>>18651000
      ASMB(DEL,DDEL);  << DELETE BANK, BASE AND SEGRELOFF >>   <<N2297>>18652000
      END                                                      <<MPEIV>>18655000
   ELSE                                                        <<MPEIV>>18660000
      BEGIN <<POSSIBLY UPDATE NON-DISC DEVICE COUNTER>>        <<MPEIV>>18665000
    TOS := TOS + DITPL(DLDEV) ;                                <<06768>>18670000
      ASMB(LSEA); <<SEGRELOFF FOR ITEM0 OF THIS DEVICE>>       <<MPEIV>>18675000
      IF <> THEN                                               <<MPEIV>>18680000
         BEGIN <<WE ARE KEEPING COUNTERS FOR THIS DEVICE>>     <<MPEIV>>18685000
    TOS := TOS - DITPL(DLDEV) ;                                <<06768>>18690000
         IF (TOS:=IOQ'FUNC) > 1 THEN                           <<06768>>18695000
            BEGIN                                              <<MPEIV>>18700000
            DEL;                                               <<MPEIV>>18705000
            TOS:=2; <<TURN ANY NON READ/WRITE INTO CONTROLL>>  <<MPEIV>>18710000
            END;                                               <<MPEIV>>18715000
         CASE TOS OF                                           <<MPEIV>>18720000
            BEGIN                                              <<MPEIV>>18725000
            TOS:=TOS+C'DEVREAD; <<0>>                          <<MPEIV>>18730000
            TOS:=TOS+C'DEVWRITE; <<1>>                         <<MPEIV>>18735000
            TOS:=TOS+C'DEVCONTROL; <<2>>                       <<MPEIV>>18740000
            END; <<CASE>>                                      <<MPEIV>>18745000
         ASMB(LADD;LSEA;INCA;SSEA;DDEL);                       <<MPEIV>>18750000
         END  <<NON-DISC COUNTER UPDATE>>                      <<MPEIV>>18755000
      ELSE                                                     <<MPEIV>>18760000
         <<WE ARE NOT KEEPING COUNTER FOR THIS DEVICE>>        <<MPEIV>>18765000
         ASMB(DEL,DDEL); <<BANK, ADDR, SEGRELOFF>>             <<MPEIV>>18770000
      END;                                                     <<MPEIV>>18775000
   END; <<UPDATING CODE>>                                      <<MPEIV>>18780000
                                                               <<D1987>>18780010
<<IF THE IO GOES THROUGH DISC CACHING, BY THE TIME WE GET    >><<D1987>>18780100
<<HERE WE LOSE THE PCBNUM, THUS UNABLE TO ACCOUNT CORRECTLY  >><<D1987>>18780200
<<THE IO COUNTERS TO THE RIGHT PROCESS. PREVIOUS EFFORTS     >><<D1987>>18780300
<<TRIED TO RESTORE BACK INTO THE DRQ THE PCBNUM THAT GOT     >><<D1987>>18780400
<<ZEROED OUT WHILE GOING THROUGH MEMORY MANAGEMENT. THIS     >><<D1987>>18780500
<<APPROACH DID NOT SEEM TO MAKE GOOD RESULT. THE APPROACH    >><<D1987>>18780600
<<THAT I'M TAKING IS TO REMOVE THIS PIECE OF CODE AND MOVE   >><<D1987>>18780700
<<IT TO P'ATTACHIO TO HANDLE NON-CACHE DISC IOS. FOR DISC    >><<D1987>>18780800
<<CACHE IOS, SINCE STARTOBJECTWRITE AND FETCHOBJECT ARE THE  >><<D1987>>18780900
<<ONLY TWO PLACES IN MEMORY MANAGEMENT THAT BUILD THE DRQ    >><<D1987>>18781000
<<ENTRY FOR A CACHE IO, I WILL BUMP THE IO COUNTERS FOR THE  >><<D1987>>18781100
<<DRQ AT THE TIME IT GETS BUILT - AT THAT TIME THE PCB STILL >><<D1987>>18781200
<<AROUND. H. NGUYEN                                          >><<D1987>>18781300
                                                               <<D1987>>18781400
$EDIT VOID = 18915000                                          <<D1987>>18785000
   STATE := 0;                                                          18920000
   IF ADISC  THEN                                              <<07410>>18925000
   BEGIN                                                       <<MPEIV>>18930000
<<                                                           >><<*9889>>18934010
<< The following STORE'IOQ is used by the Measurement        >><<*9889>>18934020
<< Interface to keep track of all DRQ's.                     >><<*9889>>18934030
<<                                                           >><<*9889>>18934040
<< Previously, this was only done in RETURNDRQ, but Caching  >><<*9889>>18934050
<< sometimes multiply uses DRQ's which don't get stored.     >><<*9889>>18934060
<<                                                           >><<*9889>>18934070
      IF IOSTATSENBLD THEN STORE'IOQ(DRQ'ENTRY'INDEX,FALSE);   <<*9889>>18934080
      SETDB'QUE;                                               <<07410>>18935000
            IF  ARQ'FLAGS.SERWQFLAG                            <<07410>>18940000
            THEN dqh'flags.dqh'actserwrflag:=FALSE;<<not act.>><<06768>>18945000
   IF ARQ'MMREQ  THEN                                          <<07410>>18950000
      BEGIN                                                    <<MPEIV>>18955000
      IF ARQ'DONE = 1 THEN  SUDDENDEATH(261)                   <<07410>>18960000
                      ELSE  ARQ'DONE := 1;                     <<07410>>18965000
      SETDB'SYS;                                               <<07410>>18970000
      IF DRQ'FUNC                                              <<06768>>18975000
      THEN OBJWRITECOMPLETOR(DRQ'ENTRY'INDEX)                  <<06768>>18980000
      ELSE OBJREADCOMPLETOR(DRQ'ENTRY'INDEX);                  <<06768>>18985000
      GO TO CONT7;                                             <<MPEIV>>18990000
      END                                                      <<MPEIV>>18995000
   ELSE                                                        <<MPEIV>>19000000
      BEGIN <<PROCESS DISC I/O>>                               <<MPEIV>>19005000
      TOS:=ARQ'PCB*PCBSIZE;         <<C4MPEV>>                 <<07410>>19010000
      IF = THEN                                                <<MPEIV>>19015000
         BEGIN <<BETTER BE SYS BUF I/O>>                       <<MPEIV>>19020000
         ASMB(DEL);                                            <<MPEIV>>19025000
         IF NOT ARQ'SBUF THEN SUDDENDEATH(661);                <<07410>>19030000
         END                                                   <<MPEIV>>19035000
      ELSE IF ARQ'DBREL=0 LAND (ARQ'BLOCKED                    <<07410>>19040000
       LOR ARQ'IOWAKE)  AND  ARQ'INLOCAL THEN                  <<*7572>>19045000
         BEGIN <<CLEAR DISC IO SEG FOR NON-STACK, WAITING>>    <<MPEIV>>19050000
      ARQ'INLOCAL := 0;    <<  INDICATE DISCIO BIT IS OFF >>   <<*7572>>19055000
      DST(ARQ'BUF'DSTN&LSL(2)).REFERENCEDFLAG := 1;            <<*7572>>19060000
      SEGID'(OBJIDTYPEFIELD) := OBJIDDATATYPE; << BUILD >>     <<06768>>19065000
      SEGID'(OBJIDPBXFIELD)  := 0;  << 2 WORD SEGID     >>     <<06768>>19070000
      SEGID'(OBJIDNUMFIELD)  := ARQ'BUF'DSTN; << SEGIDENT >>   <<07410>>19075000
      TOS := SEGID;                                            <<06768>>19080000
            TOS:=0D;                                           <<MPEIV>>19085000
            ASMB(TSBC CLEARDISCIOSEGBIT);                      <<MPEIV>>19090000
            SETDB'SYS;                                         <<07410>>19095000
            ADJUSTLOCALITY(*,*,*,*);                           <<06768>>19100000
         END;                                                  <<MPEIV>>19105000
      END;                                                     <<MPEIV>>19110000
   END;                                                        <<MPEIV>>19115000
   SETDB'SYS;                                                  <<07410>>19120000
   UNFREEZEDATASEG;                                            <<01496>>19125000
DD3:                                                                    19130000
   DISABLE;                                                    <<MPEIV>>19135000
   IF NOT  ADISC THEN                                          <<07410>>19140000
   DITP(DIOQP) := IOQ'QLINK;  << DELINK IOQ >>                 <<06768>>19145000
   << Mark the request completed and awaken caller >>          <<06768>>19150000
 <<         INLINE   SIODM'REQUEST'DONE         >>             <<07410>>19155000
                                                               <<07410>>19160000
   SETDB'QUE;                                                  <<07410>>19165000
   IF ARQ'DONE                                                 <<07410>>19170000
     THEN  SUDDENDEATH(261)  << SHOULDN'T BE ALREAD DONE >>    <<07410>>19175000
     ELSE  ARQ'DONE := 1;       << MARK REQUEST AS DONE     >> <<07410>>19180000
                                                               <<07410>>19185000
<< Place caller's PIN on tos >>                                <<07410>>19190000
tos := ARQ'PCB;                                                <<07410>>19195000
                                                               <<07410>>19200000
<< If the request has the wake bit set,waken calling process >><<07410>>19205000
if ARQ'IOWAKE  then                                            <<07410>>19210000
  BEGIN                                                        <<07410>>19215000
  TOS := S0 * PCBSIZE;                                         <<07410>>19220000
  TOS := if ARQ'BLOCKED then  BLKDIO  else  IOWAIT;            <<07410>>19225000
  TOS := NOWAIT;                                               <<07410>>19230000
  SETDB'SYS;                                                   <<07410>>19235000
  AWAKE(*,*,*);                                                <<07410>>19240000
  END;                                                         <<07410>>19245000
<< If there was no PCB associated with this I/O, >>            <<07410>>19250000
<< it might be SYSBUF I/O.                       >>            <<07410>>19255000
if tos = 0 then   << Yep, no PCB >>                            <<07410>>19260000
  begin                                                        <<07410>>19265000
  SETDB'QUE;                                                   <<07410>>19270000
  if ARQ'FLAGS.SYSBUFR then  << Yep, this is SYSBUF I/O >>     <<07410>>19275000
    if ARQ'BUFADR <> 0 then  << and there was really a bufr >> <<07410>>19280000
      BEGIN                                                    <<07410>>19285000
      TOS := ARQ'BUFADR;                                       <<07410>>19290000
      SETDB'SYS;                                               <<07410>>19295000
      RETURNSYSBUF(*);                                         <<07410>>19300000
      END;                                                     <<07410>>19305000
  TOS := Q'ENTRY'INDEX;                                        <<07410>>19310000
  IF ADISC THEN RETURNDISCREQ(*) ELSE RETURNIOQ(*);            <<07410>>19315000
  end;                                                         <<07410>>19320000
                                                               <<07410>>19325000
                                                               <<07410>>19330000
CONT7:                                                         <<MPEIV>>19335000
SETDB'SYS;                                                     <<07410>>19340000
IF ADISC   THEN                                                <<07410>>19345000
   BEGIN  <<SELECT NEXT REQUEST FOR DEVICE, Q FOR CONTROLLER>> <<MPEIV>>19350000
   DISABLE;                                                    <<MPEIV>>19355000
   X:=@DITP;                                                   <<MPEIV>>19360000
   DITP(DIOQP):=DITQHEADP;                                     <<06768>>19365000
   IF dqh'serwqhead <> 0                                       <<06768>>19370000
   AND dqh'flags.dqh'actserwrflag=0 THEN                       <<06768>>19375000
      BEGIN <<maybe take from there>>                          <<06768>>19380000
      TOS := drq(dqh'serwqhead+drq'ldev'index);                <<06768>>19385000
      IF  ditp(dldev)     <>   S0 THEN                         <<06768>>19390000
         BEGIN <<ser wr head for other dev>>                   <<06768>>19395000
         pc :=lpdt(tos*size'of'lpdt'entry+2); << ditp >>       <<06768>>19400000
         IF ABS(sysbase+pc+dioqp)=0 <<that dev idle>> THEN     <<06768>>19405000
            BEGIN <<queue swq head to that device>>            <<06768>>19410000
            dqh'flags.dqh'actserwrflag:=1;                     <<06768>>19415000
            DRQ'ENTRY'INDEX := DQH'SERWQHEAD;                  <<07341>>19420000
            IF SerialWriteQMgr(dqh'serwqhead,                  <<07341>>19425000
                               serwqdequeuecode,0)             <<07341>>19430000
           <>serwqerrallok THEN SuddenDeath(SFKernCacheIntBad);<<07341>>19435000
            QueueDiscReq(DRQ'ENTRY'INDEX,                      <<07341>>19440000
                         ditreqq, pc <<ditp of that dev>>);    <<07341>>19445000
            END                                                <<06768>>19450000
         END                                                   <<06768>>19455000
      ELSE                                                     <<06768>>19460000
         BEGIN <<serwq head for this dev>>                     <<07341>>19465000
         DEL;   << DELETE LDEV PUT ON TOS:= ABOVE >>           <<07341>>19470000
         dqh'flags.dqh'actserwrflag:=1;                        <<07341>>19475000
         IF ditp(dioqp) = 0 <<ditq empty>>                     <<07341>>19480000
         THEN ditp(dioqp) := dqh'serwqhead                     <<07341>>19485000
         ELSE                                                  <<07341>>19490000
            BEGIN <<pick next req for this dev based on pri>>  <<07341>>19495000
            DRQ'ENTRY'INDEX := DITP(DIOQP); << FROM DITQHEAD >><<07341>>19500000
            IF drq(dqh'serwqhead + drq'urgclas'index)          <<07341>>19505000
                   <  drq'urgclas                              <<07341>>19510000
            THEN ditp(dioqp):=dqh'serwqhead                    <<07341>>19515000
            ELSE dqh'flags.dqh'actserwrflag:=0;                <<06768>>19520000
            END;                                               <<06768>>19525000
         END;                                                  <<06768>>19530000
      END;                                                     <<06768>>19535000
   Q'ENTRY'INDEX:=DITP(DIOQP);               <<UPDATE DRQP>>   <<06768>>19540000
   <<UPDATE DISC'S NEW CURRENT REQUEST>>                       <<MPEIV>>19545000
   IF GCLASSENABLEDMASK.CLASS0  THEN                           <<MPEIV>>19550000
      BEGIN  <<UPDATE Q LENGTH HISTOGRAM>>                     <<MPEIV>>19555000
      TOS:=MEASSTATXDSBANK;                                    <<MPEIV>>19560000
      TOS:=MEASSTATXDSBASE;                                    <<MPEIV>>19565000
    TOS := TOS + DITPL(DLDEV) ;                                <<06768>>19570000
      ASMB(LSEA); <<TOS HAS SEG REL OFFSET OF ITEM 0 >>        <<MPEIV>>19575000
   IF <> THEN << MI CAN RECOGNIZE THE DISC >>                  <<N2297>>19576000
   BEGIN                                                       <<N2297>>19577000
    TOS := TOS - DITPL(DLDEV) ;                                <<06768>>19580000
                 << SUB LDEV IDX TO SEG >>                     <<06768>>19585000
      DISCQLENGTH:=0;                                          <<MPEIV>>19590000
      X:=@DITP;                                                <<MPEIV>>19595000
      Q'ENTRY'INDEX := DITQHEADP;                              <<07341>>19600000
      WHILE Q'ENTRY'INDEX <> 0  DO                             <<07341>>19605000
         BEGIN                                                 <<07341>>19610000
         DISCQLENGTH:=DISCQLENGTH+1;                           <<07341>>19615000
         Q'ENTRY'INDEX := DRQ'NEXTQ;                           <<07341>>19620000
         END;                                                  <<07341>>19625000
      Q'ENTRY'INDEX := DITP(DIOQP); << RESET Q'ENTRY'INDEX >>  <<07341>>19630000
      TOS:=DISCQLENGTH;                                        <<07341>>19635000
      IF (TOS:=TOS) > 6 THEN                                   <<MPEIV>>19640000
         BEGIN                                                 <<MPEIV>>19645000
         ASMB(DEL);                                            <<MPEIV>>19650000
         TOS:=6;                                               <<MPEIV>>19655000
         END;                                                  <<MPEIV>>19660000
      CASE TOS OF                                              <<MPEIV>>19665000
         BEGIN                                                 <<MPEIV>>19670000
         TOS:=TOS+C'DISCQUEUE0;                                <<MPEIV>>19675000
         TOS:=TOS+C'DISCQUEUE1;                                <<MPEIV>>19680000
         TOS:=TOS+C'DISCQUEUE2;                                <<MPEIV>>19685000
         TOS:=TOS+C'DISCQUEUE3;                                <<MPEIV>>19690000
         TOS:=TOS+C'DISCQUEUE4;                                <<MPEIV>>19695000
         TOS:=TOS+C'DISCQUEUE5;                                <<MPEIV>>19700000
         TOS:=TOS+C'DISCQUEUE6;                                <<MPEIV>>19705000
         END; <<CASE>>                                         <<MPEIV>>19710000
      ASMB(LADD;LSEA;INCA;SSEA;DDEL);                          <<MPEIV>>19715000
   END                                                         <<N2297>>19716000
   ELSE                                                        <<N2297>>19717000
      ASMB(DEL,DDEL); << MI CAN'T RECOGNIZE THE DISC >>        <<N2297>>19718000
      END;                                                     <<MPEIV>>19720000
   <<DEQUEUE THAT REQUEST, AND Q DISC FOR CONTROLLER>>         <<MPEIV>>19725000
   X:=Q'ENTRY'INDEX;                                           <<07410>>19730000
   IF <> THEN                                                  <<MPEIV>>19735000
      BEGIN <<DEQUEUE DISC REQ, QUEUE DISC FOR CONTRL>>        <<MPEIV>>19740000
      IF LOGICAL(Q'ENTRY'INDEX) = dqh'serwqhead                <<07410>>19745000
       THEN                                                    <<06768>>19750000
         BEGIN  <<take next req from ser wq>>                  <<06768>>19755000
         IF SerialWriteQMgr(Q'ENTRY'INDEX,                     <<07410>>19760000
                               serwqdequeuecode,0)             <<06768>>19765000
         <> serwqerrallok THEN SuddenDeath(SFKernCacheIntBad); <<06768>>19770000
         END                                                   <<06768>>19775000
      ELSE DequeueDiscReq(Q'ENTRY'INDEX,2,@ditp);              <<07410>>19780000
      SETDB'QUE;                                               <<07410>>19785000
      ARQ'CUR'REQ := 1;                                        <<*7572>>19790000
      IF <>                                                    <<*7572>>19795000
         AND  (ABSOLUTE(@DITP+%1000).REQUEST = 0)              <<*7572>>19800000
         THEN  SUDDENDEATH(663);                               <<*7572>>19805000
                                                               <<*7572>>19810000
      IF NOT ARQ'SBUF AND NOT ARQ'MMREQ  AND (ARQ'COUNT <> 0)  <<*7572>>19815000
          AND  NOT  ARQ'DATAFRZN   THEN                        <<*7572>>19820000
         BEGIN  <<FREEZE BUFFER BEFORE SEEK-AHEAD>>            <<01782>>19825000
         SEGID'(OBJIDTYPEFIELD) := OBJIDDATATYPE; << BUILD >>  <<06768>>19830000
         SEGID'(OBJIDPBXFIELD)  := 0;  << 2 WORD SEGID  >>     <<06768>>19835000
         SEGID'(OBJIDNUMFIELD)  := ARQ'BUF'DSTN;               <<07410>>19840000
         SETDB'SYS;                                            <<07410>>19845000
         IOFREEZE'(SEGID);                                     <<06768>>19850000
         IF = THEN DRQ'DATAFRZN:=1;                            <<06768>>19855000
         END                                                   <<07410>>19860000
      ELSE  SETDB'SYS;                                         <<07410>>19865000
COMMENT                                                        <<04899>>19870000
   CODE 3599000 TO 3611000 REMOVED TO PERMIT SOFTWARE          <<04899>>19875000
   CHANNELIZING TO WORK PROPERLY. DEVICE WON'T BE ON           <<04899>>19880000
   CONTROLLER QUEUE WHILE OWNING QUEUE RESOURCE.  ;            <<04899>>19885000
      END;                                                     <<MPEIV>>19890000
   END;                                                        <<MPEIV>>19895000
   RELCONTROLLER;                                              <<01496>>19900000
   GO TO STAY;                                                          19905000
<<>>                                                                    19910000
STATE6:                                                                 19915000
   IF DITPL.MUNIT AND   ADISC      THEN CHECKPOLL;             <<07410>>19920000
   IF   NO'Q'ENTRY AND SYSUP THEN                              <<06768>>19925000
   BEGIN                                                                19930000
DO'DEVREC:                                                     <<01496>>19935000
                                                               <<03686>>19940000
   << check if valid device to AVR and if it is then >>        <<s9286>>19945000
   << wake up DEVREC to do the work.                 >>        <<s9286>>19950000
                                                               <<s9286>>19955000
   RECOGNIZE'DEVICE(LDEV, DEVREC'WAKE);                        <<s9286>>19960000
$EDIT VOID = 20015000                                          <<s9286>>19965000
                                                               <<03686>>20020000
   END;                                                                 20025000
   STATE := 0;                                                          20030000
   GO TO STATE0;                                                        20035000
<<>>                                                                    20040000
STATE7:                                                                 20045000
   UNFREEZEDATASEG;                                            <<01496>>20050000
   STATE := STATE + 1;                                                  20055000
   RELCONTROLLER;                                              <<01496>>20060000
   GO TO STAY;                                                 <<01496>>20065000
<<>>                                                                    20070000
STATE10:                                                                20075000
   IF DITPL.MUNIT AND   ADISC      THEN CHECKPOLL;             <<07410>>20080000
   DISABLE;                                                             20085000
   DITP.IAK:=0;                                                <<01496>>20090000
   IF <> THEN                                                  <<01496>>20095000
      BEGIN                                                    <<01496>>20100000
      IF     ADISC        THEN GOTO DO'DEVREC                  <<07410>>20105000
         ELSE BEGIN                                            <<01496>>20110000
              STATE:=0;                                        <<01496>>20115000
              GOTO STAY;                                       <<01496>>20120000
              END;                                             <<01496>>20125000
      END;                                                     <<01496>>20130000
   IF DITPL.SIOPREMPT THEN DITP.IAK := 1  << RESTART ON PREEMPTION >>   20135000
    ELSE GO TO CHECKWAIT;  << CHECK TO START IDLE CPGM >>      <<01496>>20140000
<<>>                                                                    20145000
STATE13:                                                                20150000
   DISABLE;                                                             20155000
   DITP.IAK := 0;                                                       20160000
   IF = THEN GO TO OUT;                                                 20165000
CONT10:                                                        <<01496>>20170000
   ENABLE;                                                              20175000
   STATE := STATE - %10;                                                20180000
   GO TO STAY;                                                          20185000
<<>>                                                                    20190000
STATE11:                                                                20195000
   IF DITPL.MUNIT AND   ADISC      THEN CHECKPOLL;             <<07410>>20200000
   << UPDATE IOQ PTR IF COMING FROM STATE  5   >>              <<06768>>20205000
   Q'ENTRY'INDEX := DITP(DIOQP);                               <<06768>>20210000
    << RESET PRIOR REQUEST >>                                  <<06768>>20215000
   IF ADISC THEN DRQ'PREQ := 0 ELSE IOQ'PREQ := 0;             <<06768>>20220000
   IF IOQP0.DATAFRZN THEN GO TO STATE2; << DATA SEG FROZEN ? >><<06768>>20225000
   IF IOQP0.MAMERRORD THEN GO TO MAMERR; << MAKEPRESENT ERROR>><<06768>>20230000
   GO TO OUT;                                                           20235000
<<>>                                                                    20240000
STATE12:                                                                20245000
   IF  Q'ENTRY'INDEX <> 0 THEN DITPL.STWAIT := 0;              <<*7983>>20250000
   IF DLTPL.DVRFRZN THEN GO TO CONT12; << INITIATOR CODE FROZEN >>      20255000
   IF DLTPL.MAMERRORC THEN GO TO MAMERR; << MAKEPRESENT ERROR ON CS >>  20260000
   GO TO OUT;                                                           20265000
<<>>                                                                    20270000
STATE14:                                                                20275000
   IF DITPL.MUNIT AND   ADISC      THEN CHECKPOLL;             <<07410>>20280000
   DISABLE;                                                             20285000
   IF BUSY(CONTROLLER) = 0 OR BUSY(X) = @DITP THEN GO TO CONT14;        20290000
   ADDTAIL(DITP,DLINK,X);                                               20295000
   GO TO OUT; << STILL BUSY,WAIT >>                                     20300000
<<>>                                                           <<01496>>20305000
STATE15:                                                       <<01496>>20310000
   DISABLE;                                                    <<01496>>20315000
   DITP.IAK:=0;        << DID GIP CALL SIODM TO GET US HERE? >><<01496>>20320000
   IF = THEN GOTO OUT;<< OR ARE WE JUST LEAVING FROM STATE 3?>><<01496>>20325000
   STATE:=5;    << WE WERE DOING A RQST AND THE UNIT WE WERE >><<01496>>20330000
                           << RQST'ING HAPPENED TO INTERRUPT >><<01496>>20335000
                                                               <<06768>>20340000
LPDT'DEV'OWN'STATE := LPDT'SERVICE'REQ;                        <<06768>>20345000
                                                               <<06768>>20350000
LPDT'SERV'REQ'COUNT := LPDT'SERV'REQ'COUNT + 1;                <<06768>>20355000
   ENABLE;                                                     <<01496>>20360000
   AWAKE(DEVRECPCBP,JUNKWAIT,NOWAIT);    << AWAKEN DEVREC >>   <<01496>>20365000
   GOTO STAY;                                                  <<01496>>20370000
<<>>                                                                    20375000
STATE16:                                                                20380000
STATE17:                                                                20385000
   IF  Q'ENTRY'INDEX <> 0 THEN DITPL.STWAIT := 0;              <<*7983>>20390000
   IF DLTPL.MAMERRORC THEN GO TO MAMERR; << MAKPRESENT ERROR >>         20395000
   STATE := IF STATE = %16 THEN 0 ELSE 3;                      <<I9166>>20400000
   GO TO STAY;                                                 <<01496>>20405000
                                                                        20410000
END;                                                                    20415000
                                                               <<02664>>20420000
                                                               <<02664>>20425000
$PAGE  "REPORT'IOERROR"                                        <<02664>>20430000
INTEGER PROCEDURE GENMSG(SETNO,MSGNO,MASK,PARM1,PARM2,         <<02664>>20435000
      PARM3,PARM4,PARM5,DEST,REPLY,OFFSET,DST,CONTROL);        <<02664>>20440000
   VALUE   SETNO,MSGNO,MASK,PARM1,PARM2,PARM3,PARM4,PARM5,     <<02664>>20445000
           DEST,REPLY,OFFSET,DST,CONTROL;                      <<02664>>20450000
   INTEGER SETNO,MSGNO,DEST,DST;                               <<02664>>20455000
   LOGICAL MASK,PARM1,PARM2,PARM3,PARM4,PARM5,REPLY,OFFSET,    <<02664>>20460000
      CONTROL;                                                 <<02664>>20465000
   OPTION VARIABLE,EXTERNAL;                                   <<02664>>20470000
                                                               <<02664>>20475000
                                                               <<02664>>20480000
                                                               <<02664>>20485000
PROCEDURE REPORT'IOERROR(LDEV,IOSTATUS);                       <<02664>>20490000
   VALUE LDEV,IOSTATUS;                                        <<02664>>20495000
   INTEGER LDEV,IOSTATUS;                                      <<02664>>20500000
   OPTION PRIVILEGED,UNCALLABLE;                               <<02664>>20505000
                                                               <<02664>>20510000
COMMENT                                                        <<02664>>20515000
                                                               <<02664>>20520000
   Procedures doing device recognition call REPORT'IOERROR to  <<02664>>20525000
print a message on the console when it is important that the   <<02664>>20530000
operator know immediately that an IO error has occured on a    <<02664>>20535000
device.  This could be of use to the entire operating system.  <<02664>>20540000
                                                               <<02664>>20545000
   INPUTS:                                                     <<02664>>20550000
      LDEV - the device on which the error occured.            <<02664>>20555000
      IOSTATUS - the low order 8-bits of the PCB/STATUS word   <<02664>>20560000
                 returned by ATTACHIO.                         <<02664>>20565000
   CALLERS:                                                    <<02664>>20570000
      DEVREC, and RECOGNIZE (in LABSEG).                       <<02664>>20575000
                                                               <<02664>>20580000
   DB:                                                         <<02664>>20585000
      DB must be at the stack when calling this procedure.     <<02664>>20590000
                                                               <<02664>>20595000
;     << end of comment >>                                     <<02664>>20600000
                                                               <<02664>>20605000
BEGIN                                                          <<02664>>20610000
   INTEGER                                                     <<02664>>20615000
      LENGTH,       << Return from ASCII >>                    <<02664>>20620000
      ERRNUM,       << Set 1 error message number >>           <<02664>>20625000
      I;            << Loop variable >>                        <<02664>>20630000
   BYTE ARRAY                                                  <<02664>>20635000
      RESULT(0:6);  << Array for ASCII >>                      <<02664>>20640000
   EQUATE                                                      <<02664>>20645000
      << Error message number equates >>                       <<02664>>20650000
      EXTERNAL'ABORT    = 305,  << % 33 >>                     <<02664>>20655000
      NOT'ONLINE        = 401,  << % 53 >>                     <<02664>>20660000
      PFAIL'ABORT       = 306,  << % 63 >>                     <<02664>>20665000
      POWER'UP          = 402,  << %213 >>                     <<02664>>20670000
      INVALID'FUNC      = 307,  << %  4 >>                     <<02664>>20675000
      TRANSFER'ERROR    = 309,  << % 14 >>                     <<02664>>20680000
      IO'TIMEOUT        = 308,  << % 24 >>                     <<02664>>20685000
      TIMING'ERROR      = 403,  << % 34 >>                     <<02664>>20690000
      SIO'FAILURE       = 281,  << % 44 >>                     <<02664>>20695000
      UNIT'FAILURE      = 404,  << % 54 >>                     <<02664>>20700000
      PARITY'ERROR      = 405,  << % 74 >>                     <<02664>>20705000
      SYSTEM'ERROR      = 406,  << %124 >>                     <<02664>>20710000
      CHANNEL'FAILURE   = 407,  << %144 >>                     <<02664>>20715000
      END'OF'FILE       = 408,  << % X2 >>                     <<02664>>20720000
      LEFT'OVERS        = 400,  << % XX >>                     <<02664>>20725000
      END'OF'EQUATES    =   0;                                 <<02664>>20730000
                                                               <<02664>>20735000
   INTEGER ARRAY                                               <<02664>>20740000
      STATUS'TABLE(*) = PB :=                                  <<02664>>20745000
         << Each pair is (status return, errnum).  The table >><<02664>>20750000
         << ends with a zero pair. >>                          <<02664>>20755000
                                                               <<02664>>20760000
       %33, EXTERNAL'ABORT,                                    <<02664>>20765000
       %53, NOT'ONLINE,                                        <<02664>>20770000
       %63, PFAIL'ABORT,                                       <<02664>>20775000
      %213, POWER'UP,                                          <<02664>>20780000
                                                               <<02664>>20785000
        %4, INVALID'FUNC,                                      <<02664>>20790000
       %14, TRANSFER'ERROR,                                    <<02664>>20795000
       %24, IO'TIMEOUT,                                        <<02664>>20800000
       %34, TIMING'ERROR,                                      <<02664>>20805000
       %44, SIO'FAILURE,                                       <<02664>>20810000
       %54, UNIT'FAILURE,                                      <<02664>>20815000
       %74, PARITY'ERROR,                                      <<02664>>20820000
      %124, SYSTEM'ERROR,                                      <<02664>>20825000
      %144, CHANNEL'FAILURE,                                   <<02664>>20830000
                                                               <<02664>>20835000
         0, 0;     << End of table >>                          <<02664>>20840000
                                                               <<02664>>20845000
   INTRINSIC ASCII;                                            <<02664>>20850000
                                                               <<02664>>20855000
                                                               <<02664>>20860000
   LENGTH := ASCII(IOSTATUS,8,RESULT);                         <<02664>>20865000
   MOVE RESULT := RESULT(6 - LENGTH),(LENGTH);  << Justify >>  <<02664>>20870000
   RESULT(LENGTH) := 0;   << GENMSG needs zero terminator. >>  <<02664>>20875000
                                                               <<02664>>20880000
   << Search the table for the appropriate error message. >>   <<02664>>20885000
   ERRNUM := 0;                                                <<02664>>20890000
   I := 0;                                                     <<02664>>20895000
   DO BEGIN                                                    <<02664>>20900000
      IF IOSTATUS = STATUS'TABLE(I) THEN                       <<02664>>20905000
         ERRNUM := STATUS'TABLE(I+1);                          <<02664>>20910000
      END                                                      <<02664>>20915000
   UNTIL (ERRNUM <> 0) OR (STATUS'TABLE(I:=I+2) = 0);          <<02664>>20920000
                                                               <<02664>>20925000
   << If no specific message, then report end-of-file >>       <<02664>>20930000
   << or use the general error message. >>                     <<02664>>20935000
   IF ERRNUM = 0 THEN                                          <<02664>>20940000
      ERRNUM := IF IOSTATUS.(13:3) = 2 THEN END'OF'FILE        <<02664>>20945000
                                       ELSE LEFT'OVERS;        <<02664>>20950000
                                                               <<02664>>20955000
   GENMSG(1,ERRNUM,%10000,LDEV,@RESULT,,,,0);                  <<02664>>20960000
                                                               <<02664>>20965000
END;    << of REPORT'IOERROR >>                                <<02664>>20970000
$EDIT VOID = 20971685                                          <<s9286>>20971000
$PAGE "REQUEST STATUS FROM DISC DEVICES"                                20975000
<<===========REQSTATUS=============>><< SPLIT STACK CALLS OK >><<03031>>20980000
                                                               <<03031>>20985000
DOUBLE PROCEDURE REQSTATUS(LDN);                               <<03031>>20990000
VALUE LDN; INTEGER LDN;                                        <<03031>>20995000
OPTION PRIVILEGED,UNCALLABLE;                                  <<*7866>>21000000
BEGIN                                                          <<03031>>21005000
  << request status from "DISC DEVICE" and return 2-WORDS >>   <<03031>>21010000
  << of DISC INFO in approximately the same format as the >>   <<03031>>21015000
  << 2-Word Status Returned by the 13037 Disc Controller  >>   <<03031>>21020000
                                                               <<03031>>21025000
  ARRAY   QARRAY (*)  = Q+0,   << USED TO LOAD VAL @ DL-1 >>   <<03031>>21030000
          RQSTAT(0:11)= Q;     <<  BIG ENOUGH FOR DCS'80  >>   <<03031>>21035000
  LOGICAL RQSTAT0     = RQSTAT,                                <<03031>>21040000
          RQSTAT1     = RQSTAT0+1,                             <<03031>>21045000
          STATWORD1   = REQSTATUS,                             <<03031>>21050000
          STATWORD2   = STATWORD1+1;                           <<03031>>21055000
  INTEGER TYPE        = RQSTAT+10,                             <<03031>>21060000
          OFSET       = TYPE+1;                                <<03031>>21065000
                                                               <<03031>>21070000
  DOUBLE  DRQSTAT     = RQSTAT;                                <<03031>>21075000
                                                               <<03031>>21080000
DEFINE LPDT'INDEX = LDN*INTEGER(LPDT'ENTRY'SIZE)#,             <<07341>>21085000
        STK = LPCB(CURPRC + STKINFOWORDNUM).STKDSTFIELD#,      <<06768>>21090000
          FLG  =  1#,                                          <<*7572>>21095000
                                                               <<03031>>21100000
          NOTREADY    = ( 3:1)#,                               <<03031>>21105000
          READONLY    = ( 4:1)#,                               <<03031>>21110000
          ANYERRORBIT = ( 0:1)#,                               <<03031>>21115000
          VSFLD       = ( 3:5)#,                               <<03031>>21120000
          READONLYBIT = ( 9:1)#,                               <<03031>>21125000
          FORMATSWBIT = (10:1)#,                               <<03031>>21130000
          NOTREADYBIT = (14:1)#,                               <<03031>>21135000
                                                               <<03031>>21140000
          VS7911      = 109823D#,   << %000001, %126377 >>     <<03031>>21145000
          VS7912      = 256255D#,   << %000003, %164377 >>     <<03031>>21150000
          VS7935      = 1579915D#,  << %000030, %015613 >>     <<03031>>21155000
          LIN16M      = 16351D#,    << %000000, %037737 >>     <<03031>>21160000
          LIN65M      = 65407D#;    << %000000, %177577 >>     <<03031>>21165000
                                                               <<03031>>21170000
                                                               <<03031>>21175000
  RSTATUS.CC := CCL;     <<** ASSUME LDN NOT VALID DISC **>>   <<03031>>21180000
  REQSTATUS:=0D;           <<**  CLEAR OUT RETURN VALUE **>>   <<03031>>21185000
  TYPE:=LDEVTOTYPE(LDN);                                       <<03031>>21190000
  IF = AND  DISCDEVICE THEN                                    <<06768>>21195000
  BEGIN  << VALID LDN AND DISC >>                              <<03031>>21200000
    RSTATUS.CC := CCG;   <<** ASSUME AN ERROR CONDITION **>>   <<03031>>21205000
    PUSH(Q,DL);                                                <<03031>>21210000
    ASMB(XCH,SUB);                     << COMPUTE DL TO Q >>   <<03031>>21215000
    X:=S0-1;                                                   <<03031>>21220000
    TOS:=QARRAY(X);             << DL OFFSET IN STACK DST >>   <<03031>>21225000
    ASMB(XCH,SUB);              << Q  OFFSET IN STACK DST >>   <<03031>>21230000
    OFSET:=TOS+1;               <<    DST OFFSET TO Q+1   >>   <<03031>>21235000
             << -- FUNCT =  7  REQST STATUS FOR ALL DISCS >>   <<03031>>21240000
    TOS:=P'ATTACHIO(LDN,0,STK,OFSET,7,10,0,0,FLG);             <<*7572>>21245000
             << -- WCNT  = 10 DISC DVR MAY TRIM THIS TO 4 >>   <<03031>>21250000
    IF LS1.STATUS<>1 THEN << ATTACHIO RETURNED ERROR COND >>   <<03031>>21255000
      REQSTATUS:=TOS            << RETURN ERROR CONDITION >>   <<03031>>21260000
    ELSE                                                       <<03031>>21265000
    BEGIN  << GOOD STATUS >>                                   <<03031>>21270000
      DDEL;                        << POP ATTACHIO RETURN >>   <<03031>>21275000
      IF TYPE<>3 THEN REQSTATUS:=DRQSTAT                       <<03031>>21280000
      ELSE                                                     <<03031>>21285000
      BEGIN  << CS'80 DEV >>   << MUST MASAGE RETURN BITS >>   <<03031>>21290000
                                                               <<s9286>>21291000
        STATWORD2.NOTREADYBIT:=RQSTAT(3).NOTREADY;             <<03031>>21295000
        IF STATWORD2<>0 THEN STATWORD2.ANYERRORBIT:=TRUE;      <<03031>>21300000
        STATWORD2.READONLYBIT:=RQSTAT(3).READONLY;             <<03031>>21305000
        STATWORD2.FORMATSWBIT:=TRUE;                           <<03031>>21310000
        <<>>                                                   <<03031>>21315000
        << MAYBE MORE LATER >>                                 <<03031>>21320000
        <<>>                                                   <<03031>>21325000
             << -- FUNCT = 13  RET VOL SIZE FOR ALL CS'80 >>   <<03031>>21330000
      IF NOT STATWORD2.NOTREADYBIT THEN                        <<03686>>21335000
        << YOU CAN ONLY DO A DESCRIBE  IF DISC IS READY  >>    <<03686>>21340000
        << ELSE IT WILL EAT THE ONLINE INTERRUPT..WEO    >>    <<03686>>21345000
       BEGIN  <<  GOOD STATUS.... GET DESCRIPTION  >>          <<03686>>21350000
        TOS:=P'ATTACHIO(LDN,0,STK,OFSET,13,2,0,0,FLG);         <<*7572>>21355000
        IF LS1.STATUS=1 THEN                                   <<03031>>21360000
        BEGIN                                                  <<03031>>21365000
          IF DRQSTAT=VS7911 THEN STATWORD2.VSFLD:=%11;         <<03031>>21370000
          IF DRQSTAT=VS7912 THEN STATWORD2.VSFLD:=%12;         <<03031>>21375000
          IF DRQSTAT=VS7935 THEN STATWORD2.VSFLD:=%13;         <<03031>>21380000
          IF DRQSTAT=LIN16M THEN STATWORD2.VSFLD:=%14;         <<03031>>21385000
          IF DRQSTAT=LIN65M THEN STATWORD2.VSFLD:=%15;         <<03031>>21390000
        END;                                                   <<03031>>21395000
       END;  << GOOD STATUS DESCRIBE >>                        <<03686>>21400000
      END;   << CS'80 DEV >>                                   <<03031>>21405000
      RSTATUS.CC:=CCE;  <<** SET COND-CODE TO NON ERROR **>>   <<03031>>21410000
    END;   << GOOD STATUS >>                                   <<03031>>21415000
  END;   << VALID LDN AND DISC >>                              <<03031>>21420000
END;   << REQSTATUS >>                                         <<03031>>21425000
$PAGE "PROCEDURE TO SCHEDULE I/O ERRORS TO BE LOGGED"          <<02801>>21430000
procedure LOGERROR(DITP,IOQP,DEVSTAT);                         <<02801>>21435000
value DITP,IOQP,DEVSTAT;                                       <<02801>>21440000
integer DEVSTAT;                                               <<02801>>21445000
integer IOQP;                                                  <<06768>>21450000
integer pointer DITP;                                          <<06768>>21455000
option privileged,uncallable;                                  <<02801>>21460000
begin                                                          <<02801>>21465000
<<***********************************************************>><<02801>>21470000
<< I/O Error Logging Message Format                          >><<02801>>21475000
<<***********************************************************>><<02801>>21480000
<< Word | Desciption                                         >><<02801>>21485000
<<***********************************************************>><<02801>>21490000
<< 0    | DEVSTAT: (0:8)-Len of area/(8:8)-DIT rel start addr>><<02801>>21495000
<< 1    | IOQ pointer                                        >><<02801>>21500000
<< 2-11 | 10 words of IOQ (2-11)                             >><<06768>>21505000
<< 12   | (0:8)-Subtype / (8:8)-Device Type                  >><<06768>>21510000
<< 13   | Hardware Unit Number                               >><<06768>>21515000
<< 14   | DRT                                                >><<06768>>21520000
<< 15-n | Variable len logged info (len of word 2 (0:8)      >><<06768>>21525000
<< n+1  | Length of variable logged info in prior line       >><<06768>>21530000
<< n+2  | The integer constant 11 for I/O error logging      >><<06768>>21535000
<<***********************************************************>><<02801>>21540000
                                                               <<02801>>21545000
                                                               <<02801>>21550000
equate IOLOGQX = %63,                                          <<02801>>21555000
       IOMSGPINDEX = %152;                                     <<02801>>21560000
equate LOG'BUF'STAT = 0;                                       <<06768>>21565000
define ADISC = (DITP.(0:2) = DISC')#;                          <<06768>>21570000
integer IOMSGPROC = db + IOMSGPINDEX, <<pin of IOMESSAGEPROC>> <<02801>>21575000
        IOLOG     = db + IOLOGQX;     <<error flags word    >> <<02801>>21580000
integer pointer SBUFX;                                         <<02801>>21585000
INTEGER SBF'ENTRY'INDEX;                                       <<06768>>21590000
INTEGER IOQ'ENTRY'INDEX;                                       <<06768>>21595000
INTEGER DRQ'ENTRY'INDEX;                                       <<06768>>21600000
INTEGER DITSTAT'OFFSET;                                        <<06768>>21605000
integer LEN;   <<length of data in SYSBUF>>                    <<02801>>21610000
INTEGER LOOP;                                                  <<06768>>21615000
                                                               <<06768>>21620000
LOGICAL  TYPE;                                                 <<06768>>21625000
INTEGER LPDT'INDEX;                                            <<06768>>21630000
                                                               <<02801>>21635000
<<  IF THE SYSTEM IS NOT UP THE LOGGING PROCESS WILL  >>       <<04393>>21640000
<<  NOT BE INITIALIZED OR EXECUTING AND THIS SYSTEM   >>       <<04393>>21645000
<<  BUFFER MAY BE LOST OR THE LOGGING PROCESS MAY     >>       <<04393>>21650000
<<  GET A SF 16 TRYING TO ACCESS ITS DATA SEGMENTS    >>       <<04393>>21655000
<<  WHICH HAVE NOT BEEN OBTAINED BY ITS INITIALIZATION>>       <<04393>>21660000
<<  CALL SO........                  CHANGE# C# 1     >>       <<04393>>21665000
                                                               <<04393>>21670000
 LPDT'INDEX := DITP(DLDEV) * INTEGER(LPDT'ENTRY'SIZE);         <<06768>>21675000
IF NOT SYSUP THEN RETURN;                                      <<04393>>21680000
                                                               <<04393>>21685000
<<first, attempt to obtain a system buffer to log this error.>><<02801>>21690000
<<We will obtain this SYSBUF from primary area only          >><<02801>>21695000
<<with NO impedes.                                           >><<02801>>21700000
SBF'ENTRY'INDEX := GETSBUF(1);                                 <<06768>>21705000
IF SBF'ENTRY'INDEX = 0 THEN                                    <<06768>>21710000
  begin   <<we failed to obtain a SYSTEM BUFFER!>>             <<02801>>21715000
  DISABLE;                                                     <<02801>>21720000
  IOLOG.(0:1) := 1; <<log fact that there was no SYSBUF>>      <<02801>>21725000
  return;                                                      <<02801>>21730000
  end;                                                         <<02801>>21735000
                                                               <<06768>>21740000
<<now that we have system buffer, move info to it>>            <<02801>>21745000
                                                               <<02801>>21750000
SBF(SBF'ENTRY'INDEX) := DEVSTAT;                               <<06768>>21755000
                                                               <<02801>>21760000
<< if there is no IOQ, move zeros into logging >>              <<02801>>21765000
IOQ'ENTRY'INDEX := IOQP;                                       <<06768>>21770000
IF IOQ'ENTRY'INDEX = 0 THEN                                    <<06768>>21775000
  begin        << no IOQ exists >>                             <<02801>>21780000
                                                               <<06768>>21785000
   LOOP := 1;                                                  <<06768>>21790000
   WHILE LOOP <= 11 DO                                         <<06768>>21795000
     BEGIN                                                     <<06768>>21800000
     SBF(SBF'ENTRY'INDEX + LOOP )   :=  0;                     <<06768>>21805000
     LOOP := LOOP + 1;                                         <<06768>>21810000
      END;                                                     <<06768>>21815000
  end                                                          <<02801>>21820000
else                                                           <<02801>>21825000
  begin        << do log IOQ information >>                    <<02801>>21830000
   DRQ'ENTRY'INDEX := IOQP.(2:14);                             <<06768>>21835000
   SBF(SBF'ENTRY'INDEX + 1) :=                                 <<06768>>21840000
      IF  ADISC THEN  DRQ'FLAGS   ELSE   IOQ'FLAGS;            <<06768>>21845000
   LOOP := 2;                                                  <<06768>>21850000
   WHILE LOOP <= 11 DO                                         <<06768>>21855000
      BEGIN                                                    <<06768>>21860000
        SBF(SBF'ENTRY'INDEX + LOOP) := IF ADISC                <<06768>>21865000
         THEN DRQ(DRQ'ENTRY'INDEX + LOOP )                     <<06768>>21870000
         ELSE IOQ(IOQ'ENTRY'INDEX + LOOP );                    <<06768>>21875000
       LOOP := LOOP + 1;                                       <<06768>>21880000
      END;                                                     <<06768>>21885000
   END;                                                        <<06768>>21890000
                                                               <<02801>>21895000
                                                               <<06768>>21900000
tos := DITP(DDLTP);         <<pointer to DLT on tos-temp>>     <<06768>>21905000
tos := PS0(DTYPEDLT).DEVTYPE;  <<dev type on tos>>             <<06768>>21910000
assemble(delb);             <<remove temporary pointer to DLT>><<06768>>21915000
                                                               <<06768>>21920000
                                                               <<06768>>21925000
  TYPE := TOS;     << SAVE TYPE >>                             <<06768>>21930000
                                                               <<06768>>21935000
                                                               <<06768>>21940000
SBF(SBF'ENTRY'INDEX + 12) := LPDT'SUBTYPE&LSL(8) LOR TYPE;     <<06768>>21945000
                                                               <<06768>>21950000
                                                               <<06768>>21955000
<< NEED DEV TYPE/SUBTYPE >>                                    <<06768>>21960000
                                                               <<06768>>21965000
SBF(SBF'ENTRY'INDEX + 13) := LOGICAL(DITP(DUNIT)) LAND %377;   <<06768>>21970000
tos := DITP(DILTP);         <<ILT pointer on tos>>             <<06768>>21975000
tos := logical(PS0(ICNTRL)) land %1777;<<extract DRT number>>  <<06768>>21980000
assemble(delb);             <<remove pointer to ILT>>          <<06768>>21985000
                                                               <<06768>>21990000
                                                               <<06768>>21995000
SBF(SBF'ENTRY'INDEX + 14) := TOS;  << STORE DRT# IN LOG BUF >> <<06768>>22000000
                                                               <<06768>>22005000
                                                               <<06768>>22010000
<<now, store off the variable info>>                           <<06768>>22015000
<<if length of variable info is greater than the remainder of t<<06768>>22020000
<<System Buffer size (128-15), then truncate the length to the <<06768>>22025000
<<length  we CAN handle.      >>                               <<06768>>22030000
LEN := DEVSTAT.(0:8);   <<LEN requested of info to log>>       <<06768>>22035000
if LEN > 113 then                                              <<06768>>22040000
  begin  <<we must truncate info to 113 words>>                <<06768>>22045000
  LEN := 113;                                                  <<06768>>22050000
   SBF(SBF'ENTRY'INDEX).(0:8) := 113;                          <<06768>>22055000
  end;                                                         <<06768>>22060000
   DITSTAT'OFFSET := DEVSTAT.(8:8);                            <<06768>>22065000
   LOOP := 0;                                                  <<06768>>22070000
   WHILE LOOP <= LEN - 1 DO                                    <<06768>>22075000
      BEGIN                                                    <<06768>>22080000
SBF(SBF'ENTRY'INDEX + 15 + LOOP):= DITP(DITSTAT'OFFSET+LOOP);  <<06768>>22085000
      LOOP := LOOP + 1;                                        <<06768>>22090000
      END;                                                     <<06768>>22095000
<<now, inform IOMESSAGEPROC that I/O error exists to process>> <<06768>>22100000
tos := 0;    <<message type 0 to IOMESSAGEPROC>>               <<06768>>22105000
tos := sbf'entry'index;                                        <<06768>>22110000
<< system buffer index with info >>                            <<06768>>22115000
tos := LEN + 15;  <<length of message>>                        <<06768>>22120000
tos := 0;         <<filler, not used as of yet>>               <<06768>>22125000
SENDMSG(IOMSGPROC/PCBSIZE,0,4,%40000);  <<wake up IOMESSPROC>> <<02801>>22130000
end;   <<of procedure LOGERROR>>                               <<02801>>22135000
$PAGE "IOMESSAGE - SEND GENMSG MESSAGES FROM ICS"              <<02801>>22140000
LOGICAL PROCEDURE IOMESSAGE(SETNO,MSGNO,MASK,P1,P2,P3,P4,P5,   <<02801>>22145000
   DEST,REPLY,OFFSET,DITP,IOTYPE);                             <<02801>>22150000
VALUE SETNO,MSGNO,MASK,P1,P2,P3,P4,P5,DEST,REPLY,OFFSET,DITP,  <<02801>>22155000
   IOTYPE;                                                     <<02801>>22160000
INTEGER SETNO,MSGNO,MASK,P1,P2,P3,P4,P5,DEST,REPLY,OFFSET,     <<02801>>22165000
   IOTYPE;                                                     <<02801>>22170000
INTEGER POINTER DITP;                                          <<02801>>22175000
OPTION VARIABLE,PRIVILEGED,UNCALLABLE;                         <<02801>>22180000
BEGIN                                                          <<02801>>22185000
EQUATE                                                         <<02801>>22190000
   IOMSGPINDEX = %152,                                         <<02801>>22195000
   IOLOGINDEX  = %63;                                          <<02801>>22200000
ARRAY                                                          <<02801>>22205000
   PARM(*)     = Q-18;  << ONE BELOW FIRST PARM >>             <<02801>>22210000
INTEGER SBF'ENTRY'INDEX;                                       <<06768>>22215000
INTEGER SBUF'WORD'INDEX;                                       <<06768>>22220000
INTEGER                                                        <<02801>>22225000
   IOMSGPROC   = DB + IOMSGPINDEX,                             <<02801>>22230000
   IOLOG       = DB + IOLOGINDEX;                              <<02801>>22235000
INTEGER                                                        <<02801>>22240000
   CHEKINT=Q-1;                                                <<02801>>22245000
INTEGER POINTER                                                <<02801>>22250000
   SBUFX;                                                      <<02801>>22255000
                                                               <<02801>>22260000
<<  IF THE SYSTEM IS NOT UP THE LOG/MSG PROCESS WILL  >>       <<04466>>22265000
<<  NOT BE INITIALIZED OR EXECUTING AND THIS SYSTEM   >>       <<04466>>22270000
<<  BUFFER MAY BE LOST OR THE LOGGING PROCESS MAY     >>       <<04466>>22275000
<<  GET A SF 16 TRYING TO ACCESS ITS DATA SEGMENTS    >>       <<04466>>22280000
<<  WHICH HAVE NOT BEEN OBTAINED BY ITS INITIALIZATION>>       <<04466>>22285000
<<  CALL SO........              A8: CHANGE# C# 2     >>       <<04466>>22290000
                                                               <<04466>>22295000
IF NOT SYSUP THEN RETURN;                                      <<04466>>22300000
                                                               <<04466>>22305000
<<get a system buffer to send message>>                        <<02801>>22310000
SBF'ENTRY'INDEX := GETSBUF(1);                                 <<06768>>22315000
IF SBF'ENTRY'INDEX = 0 THEN                                    <<06768>>22320000
  begin                                                        <<02801>>22325000
  DISABLE;                                                     <<02801>>22330000
  IOLOG.(1:1) := 1; <<IOMESSAGE could not get a system buffer>><<02801>>22335000
  return;                                                      <<02801>>22340000
  end;                                                         <<02801>>22345000
                                                               <<06768>>22350000
<<now, move GENMSG parms to SBUF>>                             <<02801>>22355000
                                                               <<06768>>22360000
SBUF'WORD'INDEX := 0;                                          <<06768>>22365000
WHILE (SBUF'WORD'INDEX := SBUF'WORD'INDEX + 1)  <= 14 DO       <<06768>>22370000
   SBF(SBF'ENTRY'INDEX + SBUF'WORD'INDEX) :=                   <<06768>>22375000
   PARM(SBUF'WORD'INDEX);                                      <<06768>>22380000
                                                               <<02801>>22385000
<<send message to IOMESSAGEPROC>>                              <<02801>>22390000
tos := 3;           <<message type 3>>                         <<02801>>22395000
TOS := SBF'ENTRY'INDEX;                                        <<06768>>22400000
tos := 0D;          <<double word dummy>>                      <<02801>>22405000
SENDMSG(IOMSGPROC/PCBSIZE,0,4,%40000); <<waken IOMSGPROC>>     <<02801>>22410000
IOMESSAGE := true;  <<successfully sent message>>              <<02801>>22415000
end;                                                           <<02801>>22420000
$PAGE "ISSUE'HARD'MSG MEMORY-RESIDENT MESSAGES"                <<03686>>22425000
procedure ISSUE'HARD'MSG(MSGNO,PARM,FLAGS);                    <<03686>>22430000
value MSGNO,PARM,FLAGS;                                        <<03686>>22435000
integer MSGNO,PARM;                                            <<03686>>22440000
logical FLAGS;                                                 <<03686>>22445000
option uncallable,privileged;                                  <<03686>>22450000
begin                                                          <<03686>>22455000
<<*********************************************************>>  <<03686>>22460000
<< This procedure attempts to send a message to the system >>  <<03686>>22465000
<< console.  If normal mechanism won't work, the MPE I/O   >>  <<03686>>22470000
<< message system will be bypassed and direct I/O to the   >>  <<03686>>22475000
<< system console will be attempted.                       >>  <<03686>>22480000
<<*********************************************************>>  <<03686>>22485000
<< The parameters are currently:                           >>  <<03686>>22490000
<< MSGNO      - A message number index into a PB-relative  >>  <<03686>>22495000
<<              array that contains the message that is to >>  <<03686>>22500000
<<              be printed at the system console.          >>  <<03686>>22505000
<<              To add a message, the EQUATE for HIGHEST'  >>  <<03686>>22510000
<<              MSGNO must be incremented and the actual   >>  <<03686>>22515000
<<              message added to the CASE statement.       >>  <<03686>>22520000
<< PARM       - An integer parm that is to be converted to >>  <<03686>>22525000
<<              decimal and placed in the message text.    >>  <<03686>>22530000
<< FLAGS      - Control information with the following     >>  <<03686>>22535000
<<              meaning:                                   >>  <<03686>>22540000
<<      (15:1)- If writing message in a non-destructive    >>  <<03686>>22545000
<<              manner fails, attempt methods that may     >>  <<03686>>22550000
<<              destroy the environment of the CONSOLE.    >>  <<03686>>22555000
<<      (14:1)- Set locally if write was successful        >>  <<03691>>22560000
<<      (13:1)- Do potentially destructive I/O to the      >>  <<03686>>22565000
<<              CONSOLE & don't attempt a non-destructive  >>  <<03686>>22570000
<<              write.  If bit 15 is set and non-destruc-  >>  <<03686>>22575000
<<              tive I/O fails, bit 13 will be turned-on by>>  <<03686>>22580000
<<              this procedure.                            >>  <<03686>>22585000
<<                                                         >>  <<03686>>22590000
<<  DB can be anywhere, can be called from anywhere.       >>  <<03694>>22595000
<<                                                         >>  <<03686>>22600000
<<*********************************************************>>  <<03686>>22605000
<< This procedure returns:                                 >>  <<03686>>22610000
<<            CCE if something got out                     >>  <<03686>>22615000
<<            CCL if nothing got out                       >>  <<03686>>22620000
<<*********************************************************>>  <<03686>>22625000
                                                               <<03686>>22630000
equate HIGHEST'MSGNO = 6,   << Currently, only 6 msgs >>       <<03686>>22635000
       SERIES'III    = 2,   << CPU number of S/III SPU >>      <<03691>>22640000
       MAX'WORDS     = 40;  << Maximum of 40 words text >>     <<03686>>22645000
                                                               <<03686>>22650000
define CONSLDEV = ABS(%1074)#; << SYSGLOB console ldev cell >> <<03694>>22655000
                                                               <<03694>>22660000
<< Stack required to perform an ATTACHIO is calculated by   >> <<03694>>22665000
<< MAX'WORDS+PCAL'OVRHD(14)+LOCAL'OVRHD(16)+ATTIO'OVHD(255) >> <<03694>>22670000
equate STACK'REQD = MAX'WORDS + 285;                           <<03694>>22675000
                                                               <<03694>>22680000
integer CPUNUM,          << CPU type executing on >>           <<03686>>22685000
        LENGTH,          << Length of message to display >>    <<03686>>22690000
        I,LOC;           << Utility integer for DCONVERT >>    <<03686>>22695000
INTEGER LPDT'INDEX;                                            <<06768>>22700000
                                                               <<03686>>22705000
logical LDEV'IS'LYNX,    << True if LYNX console  >>           <<03686>>22710000
        CONS'WAS'UP;     << Whether console is allocated >>    <<03686>>22715000
                                                               <<03686>>22720000
<< Q-relative variables to save stack environment >>           <<03691>>22725000
double DBBANK'DB;                                              <<03691>>22730000
integer DBBANK=DBBANK'DB,                                      <<03691>>22735000
        DBREGISTER=DBBANK+1,                                   <<03691>>22740000
        Q'REGISTER,                                            <<03691>>22745000
        Z'REGISTER,                                            <<03691>>22750000
        SBANK;                                                 <<03691>>22755000
                                                               <<03691>>22760000
integer LDEV,                                                  <<03686>>22765000
        DRTN;                                                  <<03686>>22770000
integer pointer DITP,                                          <<03686>>22775000
                DLTP;                                          <<03686>>22780000
pointer MSG;   << Dynamically allocated array to hold MSG >>   <<03691>>22785000
                                                               <<03691>>22790000
$PAGE "ISSUE'HARD'MSG SUPPORT SUBROUTINES"                     <<03686>>22795000
<< save a byte in B'MSG >>                                     <<03686>>22800000
subroutine SAVE'BYTE(VAL);                                     <<03691>>22805000
value VAL; integer VAL;                                        <<03691>>22810000
begin                                                          <<03691>>22815000
if logical(LOC) then  << Odd byte >>                           <<03691>>22820000
  MSG(LOC/2).(8:8) := VAL + "0"                                <<03691>>22825000
else                                                           <<03691>>22830000
  MSG(LOC/2).(0:8) := VAL + "0";                               <<03691>>22835000
LOC := LOC + 1;                                                <<03691>>22840000
end;                                                           <<03686>>22845000
                                                               <<03686>>22850000
<< Convert parameter to decimal and place in MSG array >>      <<03686>>22855000
<< at byte location LOC.                               >>      <<03686>>22860000
subroutine DCONVERT;                                           <<03686>>22865000
begin                                                          <<03686>>22870000
                                                               <<03686>>22875000
tos := PARM;  tos := 1000;                                     <<03686>>22880000
ASMB(div, xch);                                                <<03686>>22885000
                                                               <<03691>>22890000
if <> or PARM > 999 then                                       <<03691>>22895000
  SAVE'BYTE(*) else DEL;                                       <<03691>>22900000
tos := 100;                                                    <<03686>>22905000
ASMB(div, xch);                                                <<03686>>22910000
                                                               <<03691>>22915000
if <> or PARM > 99 then                                        <<03686>>22920000
  SAVE'BYTE(*) else DEL;                                       <<03691>>22925000
tos := 10;                                                     <<03686>>22930000
ASMB(div, xch);                                                <<03686>>22935000
                                                               <<03691>>22940000
if <> or PARM > 9 then                                         <<03691>>22945000
  SAVE'BYTE(*) else DEL;                                       <<03691>>22950000
                                                               <<03691>>22955000
SAVE'BYTE(*);                                                  <<03691>>22960000
end;   << of subroutine DCONVERT >>                            <<03686>>22965000
                                                               <<03686>>22970000
<< Convert a parameter at byte location LOC in array B'MSG >>  <<03686>>22975000
<< to OCTAL.                                               >>  <<03686>>22980000
subroutine OCONVERT;                                           <<03686>>22985000
begin                                                          <<03686>>22990000
                                                               <<03686>>22995000
tos := PARM;         << PARM to convert on tos >>              <<03691>>23000000
tos := 0;            << Shift word on tos      >>              <<03691>>23005000
tos := tos & dlsr(2);<< Set up for shift in loop >>            <<03691>>23010000
I := 6;                                                        <<03691>>23015000
do                                                             <<03691>>23020000
  begin                                                        <<03691>>23025000
  tos := tos & dcsl(3); << Move high-order 3-bits to tos >>    <<03691>>23030000
  SAVE'BYTE(*);                                                <<03691>>23035000
  tos := 0;             << Replace shift-in word >>            <<03691>>23040000
  I := I - 1;                                                  <<03691>>23045000
  end until =;          << Perform 6 times       >>            <<03691>>23050000
DDEL;                   << Remove stacked parms  >>            <<03691>>23055000
end;   << of subroutine OCONVERT >>                            <<03686>>23060000
                                                               <<03686>>23065000
<< This subroutine returns TRUE if the CST pointed to  >>      <<03686>>23070000
<< is non-existant OR is present in memory.            >>      <<03686>>23075000
logical subroutine CHECK'CST(CST'NUM);                         <<03686>>23080000
value CST'NUM;                                                 <<03686>>23085000
integer CST'NUM;                                               <<03686>>23090000
begin                                                          <<03686>>23095000
                                                               <<03686>>23100000
if CST'NUM = 0 then                                            <<03686>>23105000
  CHECK'CST := true                                            <<03686>>23110000
                                                               <<03686>>23115000
else                                                           <<03686>>23120000
                                                               <<03686>>23125000
  begin    << Extract CST number from LABEL and examine >>     <<03686>>23130000
  if LOGICALMAPPING and CST'NUM < 0 or                         <<06111>>23135000
    not LOGICALMAPPING and CST'NUM.(8:8) <= 192 then           <<06111>>23140000
    begin                                                      <<06111>>23145000
    CST'NUM := CST'NUM.(8:8);                                  <<06111>>23150000
    if integer(ABS(ABS(0) + (CST'NUM*4))) > 0 then             <<03686>>23155000
      CHECK'CST := true;   << Is in main memory >>             <<03686>>23160000
    end;                                                       <<06111>>23165000
  end;                                                         <<03686>>23170000
end;   << of subroutine CHECK'CST >>                           <<03686>>23175000
                                                               <<03691>>23180000
<< See if SYSIOPROC's stack is present in memory >>            <<03691>>23185000
logical subroutine CHECK'SYSIO'STACK;                          <<03691>>23190000
begin                                                          <<03691>>23195000
                                                               <<03691>>23200000
X := LPCB(SYSIOPCBP + STKINFOWORDNUM).STKDSTFIELD & LSL(2);    <<06768>>23205000
if DST(X) > 0 then                                             <<03691>>23210000
  CHECK'SYSIO'STACK := true;  << Stack is present >>           <<03691>>23215000
end;                                                           <<03691>>23220000
                                                               <<03691>>23225000
<< Subroutine to set HARD'IO bit if SOFT'IO failed >>          <<03691>>23230000
subroutine SOFT'IO'FAILED;                                     <<03691>>23235000
begin                                                          <<03691>>23240000
if FLAGS then      << If HARD I/O permitted >>                 <<03691>>23245000
  FLAGS.(13:1) := 1;  << Do HARD I/O >>                        <<03691>>23250000
end;                                                           <<03691>>23255000
                                                               <<03691>>23260000
<< Subroutine to set DBBANK to SBANK >>                        <<03691>>23265000
subroutine SETDBBANK'TO'SBANK;                                 <<03691>>23270000
begin                                                          <<03691>>23275000
                                                               <<03691>>23280000
tos := SBANK;                                                  <<03691>>23285000
tos := DBREGISTER;   << Old DB register value >>               <<03694>>23290000
set(db);                                                       <<03691>>23295000
end;                                                           <<03691>>23300000
                                                               <<03691>>23305000
<< Subroutine to set DBBANK back to original >>                <<03691>>23310000
subroutine SETDBBANK'TO'ORIGINAL;                              <<03691>>23315000
begin                                                          <<03691>>23320000
                                                               <<03691>>23325000
tos := DBBANK'DB;                                              <<03691>>23330000
set(db);                                                       <<03691>>23335000
                                                               <<03691>>23340000
end;                                                           <<03691>>23345000
<< subroutine to set SYSDB >>                                  <<03691>>23350000
subroutine SETSYSDB;                                           <<03691>>23355000
begin                                                          <<03691>>23360000
                                                               <<03691>>23365000
tos := 0;                                                      <<03691>>23370000
tos := SYSDB;                                                  <<03691>>23375000
set(db);                                                       <<03691>>23380000
                                                               <<03691>>23385000
end;                                                           <<03691>>23390000
                                                               <<03691>>23395000
$PAGE                                                          <<03686>>23400000
<< Save old DB/DBBANK/SBANK >>                                 <<03691>>23405000
TRAPSOFF;                                                      <<03691>>23410000
PDISABLE;   << in case we're running on user's stack >>        <<03691>>23415000
push(sbank,db,z,q);                                            <<03691>>23420000
SBANK := tos;                                                  <<03691>>23425000
DBBANK'DB := tos;                                              <<03691>>23430000
Z'REGISTER := tos;                                             <<03691>>23435000
Q'REGISTER := tos;                                             <<03691>>23440000
                                                               <<03691>>23445000
<< Put DBBANK to SBANK for local storage allocation >>         <<03691>>23450000
SETDBBANK'TO'SBANK;                                            <<03691>>23455000
                                                               <<03691>>23460000
<< allocate local storage >>                                   <<03691>>23465000
@MSG := @S0 + 1;                                               <<03691>>23470000
tos := MAX'WORDS;                                              <<03691>>23475000
ASMB(adds 0);                                                  <<03691>>23480000
                                                               <<03691>>23485000
<< See if message number is valid >>                           <<03686>>23490000
FLAGS.(14:1) := 0;    << Set to return bad status >>           <<03691>>23495000
if not (0<=MSGNO<=HIGHEST'MSGNO) then                          <<03686>>23500000
  begin   << Invalid message number >>                         <<03686>>23505000
                                                               <<03691>>23510000
  go to EXIT;                                                  <<03686>>23515000
  end;                                                         <<03686>>23520000
                                                               <<03686>>23525000
<< Save CPU number >>                                          <<03686>>23530000
ASMB(pcn);                                                     <<03686>>23535000
CPUNUM := tos;                                                 <<03686>>23540000
                                                               <<03686>>23545000
<< Turn-on flag if LYNX >>                                     <<03686>>23550000
if CPUNUM > SERIES'III and   << This is a HP-IB system >>      <<03691>>23555000
   CHANNEL'ID(CONSLDEV) = LYNX'TYPE then                       <<03686>>23560000
  LDEV'IS'LYNX := true                                         <<03686>>23565000
else                                                           <<03686>>23570000
  LDEV'IS'LYNX := false;                                       <<03686>>23575000
                                                               <<03686>>23580000
<<***************************************************>>        <<03686>>23585000
<< This section of code is always executed.  If flags>>        <<03686>>23590000
<< 15:1 is set, section III will be executed if sec. >>        <<03686>>23595000
<< II's ATTACHIO fails.                              >>        <<03686>>23600000
<<                                                   >>        <<03686>>23605000
<<      S E C T I O N   I                            >>        <<03686>>23610000
<<                                                   >>        <<03686>>23615000
<<***************************************************>>        <<03686>>23620000
<< move message to DB array & format it >>                     <<03686>>23625000
case *MSGNO of                                                 <<03686>>23630000
  begin                                                        <<03686>>23635000
                                                               <<03686>>23640000
<< 0 >> begin    << Not ready message >>                       <<03686>>23645000
        move MSG := (CRLF,"LDEV #     NOT READY",CRLF,%3407),2;<<03686>>23650000
        LENGTH := tos - @MSG;  << Length of text >>            <<03686>>23655000
        LOC := 8;              << Byte loc of number >>        <<03686>>23660000
        DCONVERT;              << Put in LDEV number >>        <<03686>>23665000
        end;                                                   <<03686>>23670000
                                                               <<03686>>23675000
<< 1 >> begin    << Disc not responding message >>             <<03686>>23680000
        move MSG := (CRLF,                                     <<03686>>23685000
        "DISC LDEV #    NOT RESPONDING TO I/O",CRLF,%3407),2;  <<03686>>23690000
        LENGTH := tos - @MSG;                                  <<03686>>23695000
        LOC := 13;         << Byte loc of number in B'MSG >>   <<03686>>23700000
        DCONVERT;          << Put in LDEV number >>            <<03686>>23705000
        end;                                                   <<03686>>23710000
                                                               <<03686>>23715000
<< 2 >> begin    << Powerfail message >>                       <<03686>>23720000
        move MSG := (CRLF,"*** POWERFAIL ***",CRLF,%3407),2;   <<03686>>23725000
        LENGTH := tos - @MSG;                                  <<03686>>23730000
        end;                                                   <<03686>>23735000
                                                               <<03686>>23740000
<< 3 >> begin   << Non-responding DRT >>                       <<03686>>23745000
        move MSG:=(CRLF,"NON-RESPONDING DRT #   ",CRLF),2;     <<03686>>23750000
        LENGTH := tos-@MSG;                                    <<03686>>23755000
        LOC := 22;                                             <<03686>>23760000
        DCONVERT;                                              <<03686>>23765000
        end;                                                   <<03686>>23770000
                                                               <<03686>>23775000
<< 4 >> begin   << SUDDENDEATH >>                              <<03686>>23780000
        move MSG:=(CRLF,CRLF,"**** SYSTEM FAILURE #    "),2;   <<03686>>23785000
        LENGTH := tos-@MSG;                                    <<03686>>23790000
        LOC := 25;                                             <<03686>>23795000
        DCONVERT;                                              <<03686>>23800000
        end;                                                   <<03686>>23805000
                                                               <<03686>>23810000
<< 5 >> begin   << SUDDENDEATH >>                              <<03686>>23815000
        move MSG:=(CRLF,"STATUS %      "),2;                   <<03686>>23820000
        LENGTH := tos - @MSG;                                  <<03686>>23825000
        LOC := 10;                                             <<03686>>23830000
        OCONVERT;                                              <<03686>>23835000
        end;                                                   <<03686>>23840000
                                                               <<03686>>23845000
<< 6 >> begin   << SUDDENDEATH >>                              <<03686>>23850000
        move MSG := (CRLF,"DELTA-P %       "),2;               <<03686>>23855000
        LENGTH := tos - @MSG;                                  <<03686>>23860000
        LOC := 11;                                             <<03686>>23865000
        OCONVERT;                                              <<03686>>23870000
        end;                                                   <<03686>>23875000
                                                               <<03686>>23880000
  end;   << of case on MSGNO >>                                <<03686>>23885000
                                                               <<03686>>23890000
                                                               <<03691>>23895000
                                                               <<03686>>23900000
                                                               <<03686>>23905000
<<***************************************************>>        <<03686>>23910000
<< This section is performed only if FLAGS.(13:1) is >>        <<03686>>23915000
<< NOT true.  This is the normal "SOFT" type I/O done>>        <<03686>>23920000
<< to the console via ATTACHIO which hopefully will  >>        <<03686>>23925000
<< NOT lock up the console port.                     >>        <<03686>>23930000
<<              S E C T I O N   I I                  >>        <<03686>>23935000
<<                                                   >>        <<03686>>23940000
<<***************************************************>>        <<03686>>23945000
                                                               <<03686>>23950000
if not FLAGS.(13:1) and  << HARD I/O not requested >>          <<03691>>23955000
                                                               <<03686>>23960000
   (Z'REGISTER-Q'REGISTER) > STACK'REQD then <<ATTIO space >>  <<03694>>23965000
  << At this point, we will try to write a non-destructive >>  <<03686>>23970000
  << message if at all possible.                           >>  <<03686>>23975000
                                                               <<03686>>23980000
  begin                                                        <<03686>>23985000
                                                               <<03686>>23990000
  SETSYSDB;   << Point DB to I/O system >>                     <<03691>>23995000
                                                               <<03691>>24000000
LPDT'INDEX := CONSLDEV * INTEGER(LPDT'ENTRY'SIZE);             <<06768>>24005000
@DITP := LPDT'DIT'PTR;                                         <<06768>>24010000
  @DLTP := DITP(DDLTP);       << Driver linkage table  >>      <<03686>>24015000
                                                               <<03686>>24020000
  if LDEV'IS'LYNX or          << LYNX is always resident >>    <<03686>>24025000
     << See if console's monitor and initiator are present >>  <<03686>>24030000
     CHECK'CST(DLTP(DMNTR)) and CHECK'CST(DLTP(DINIT)) and     <<03691>>24035000
     CHECK'SYSIO'STACK then    << SYSIOPROC stack is present >><<03691>>24040000
    begin                                                      <<03686>>24045000
    I := GETSBUF(2);                                           <<03686>>24050000
    if I = 0 then                                              <<03686>>24055000
      begin   << Failed to get a system buffer >>              <<03686>>24060000
      SOFT'IO'FAILED;                                          <<03691>>24065000
                                                               <<03691>>24070000
      end                                                      <<03686>>24075000
    else                                                       <<03686>>24080000
      begin  << Got a system buffer, move data to it >>        <<03686>>24085000
   LOC := I; << DST OFFSET IN SYSTEM BUFS>>                    <<06768>>24090000
                                                               <<03694>>24095000
      SETDBBANK'TO'SBANK;                                      <<03691>>24100000
      tos := 8;            << SBUF DST number >>               <<03691>>24105000
      tos := LOC;   << SYSBUF DST offset >>                    <<03694>>24110000
      tos := @MSG;         << Source DB address >>             <<03691>>24115000
      tos := LENGTH;                                           <<03691>>24120000
      ASMB(mtds 4);   << Move data to system buffer >>         <<03691>>24125000
      SETSYSDB;                                                <<03691>>24130000
                                                               <<03691>>24135000
      << * * Do the ATTACHIO * * >>                            <<03694>>24140000
                                                               <<03686>>24145000
      << See if console isn't allocated >>                     <<03686>>24150000
      if DITP.(1:1) <> 0 then                                  <<03686>>24155000
        CONS'WAS'UP := true  << DIT is allocated >>            <<03686>>24160000
      else                                                     <<03686>>24165000
        begin   << We must allocate DIT >>                     <<03686>>24170000
        CONS'WAS'UP := false;                                  <<03686>>24175000
        ATTACHIO(CONSLDEV,0,0,0,24,0,0,0,%407);                <<03686>>24180000
        end;                                                   <<03686>>24185000
                                                               <<03686>>24190000
      tos := ATTACHIO(CONSLDEV,0,0,LOC,1,LENGTH,0,0,           <<03686>>24195000
             %417);  << Hard-preempt,SBUF,no impede,sec IOQ >> <<03686>>24200000
      if tos = 0D then                                         <<03686>>24205000
        begin   << ATTACHIO failed >>                          <<03686>>24210000
        SOFT'IO'FAILED;                                        <<03691>>24215000
                                                               <<03691>>24220000
        RETURNSBUF(I);  << Return system buffer >>             <<03686>>24225000
        end                                                    <<03691>>24230000
      else                                                     <<03691>>24235000
        FLAGS.(14:1) := 1;  << I/O succeeded >>                <<03691>>24240000
                                                               <<03686>>24245000
      << If we allocated console, we must now UNDO it. >>      <<03686>>24250000
      if not CONS'WAS'UP then                                  <<03686>>24255000
        ATTACHIO(CONSLDEV,0,0,0,4,0,0,0,%407);                 <<03686>>24260000
                                                               <<03686>>24265000
      end;  << ATTACHIO was successful >>                      <<03686>>24270000
    end                                                        <<03686>>24275000
  else                                                         <<03686>>24280000
    SOFT'IO'FAILED;                                            <<03691>>24285000
                                                               <<03691>>24290000
  SETDBBANK'TO'SBANK;                                          <<03691>>24295000
  end                                                          <<03691>>24300000
else                                                           <<03691>>24305000
  SOFT'IO'FAILED;  << Not enough tos for ATTACHIO >>           <<03691>>24310000
                                                               <<03686>>24315000
<<*********************************************************>>  <<03686>>24320000
<< This section is done only if FLAGS.(13:1) is set. LYNX  >>  <<03686>>24325000
<< is currently the only type of device where we have to   >>  <<03686>>24330000
<< worry about destroying the environment.                 >>  <<03686>>24335000
<<                                                         >>  <<03686>>24340000
<<            S E C T I O N   I I I                        >>  <<03686>>24345000
<<                                                         >>  <<03686>>24350000
<<*********************************************************>>  <<03686>>24355000
                                                               <<03686>>24360000
<< Now, see if ATTACHIO failed to LYNX.  If so and flags >>    <<03686>>24365000
<< permit, cram info out to LYNX console.                >>    <<03686>>24370000
if FLAGS.(13:1) then   << Forced I/O is permitted        >>    <<03686>>24375000
    begin                                                      <<03686>>24380000
    for I := 0 until LENGTH-1 do                               <<03758>>24385000
      begin                                                    <<03758>>24390000
      tos := MSG(I);                                           <<03758>>24395000
      SETSYSDB;                                                <<03758>>24400000
      WRITE2(*);                                               <<03758>>24405000
      SETDBBANK'TO'SBANK;                                      <<03758>>24410000
      end;                                                     <<03758>>24415000
                                                               <<03758>>24420000
    FLAGS.(14:1) := 1;  << I/O succeeded >>                    <<03691>>24425000
    end;                                                       <<03686>>24430000
                                                               <<03686>>24435000
                                                               <<03691>>24440000
                                                               <<03686>>24445000
EXIT:                                                          <<03686>>24450000
                                                               <<03686>>24455000
RSTATUS.CC := if FLAGS.(14:1) then CCE else CCL;               <<03691>>24460000
                                                               <<03691>>24465000
SETDBBANK'TO'ORIGINAL;                                         <<03691>>24470000
                                                               <<03691>>24475000
PENABLE;                                                       <<03691>>24480000
end;   << of procedure >>                                      <<03686>>24485000
$PAGE "LDEVNOTRDY"                                             <<03686>>24490000
procedure LDEVNOTRDY(DITP);                                    <<03686>>24495000
integer array DITP;                                            <<03686>>24500000
option uncallable,privileged;                                  <<03686>>24505000
                                                               <<03686>>24510000
<< DB must be at SYSDB >>                                      <<03686>>24515000
<<*************************************************>>          <<03730>>24520000
<< This procedure sends a message to IOMSGPROC to  >>          <<03730>>24525000
<< print the LDEV #  NOT READY on the system cons. >>          <<03730>>24530000
<< DB must be pointing to SYSDB when calling this  >>          <<03730>>24535000
<< procedure.  The condition codes returned are:   >>          <<03730>>24540000
<<         CCE - MSG has been scheduled            >>          <<03730>>24545000
<<         CCL - MSG could not be scheduled        >>          <<03730>>24550000
<< If this device is disc, an optional message will>>          <<03730>>24555000
<< be printed on the console in case the device    >>          <<03730>>24560000
<< that is not ready is the system disc.           >>          <<03730>>24565000
<<*************************************************>>          <<03730>>24570000
                                                               <<03730>>24575000
begin                                                          <<03730>>24580000
                                                               <<03686>>24585000
integer ENTRY'TYPE    = q+1;                                   <<03686>>24590000
integer pointer IOQP  = q+2;                                   <<03686>>24595000
integer LDEV          = q+3;                                   <<03686>>24600000
logical FLAGS         = q+4;                                   <<03686>>24605000
                                                               <<03686>>24610000
entry DISC'NOT'RESP;                                           <<03686>>24615000
                                                               <<03686>>24620000
<< Normal entry, device not ready >>                           <<03686>>24625000
tos := 0;          << MSG type 0 - device not ready >>         <<03686>>24630000
go to START;                                                   <<03686>>24635000
                                                               <<03686>>24640000
DISC'NOT'RESP:                                                 <<03686>>24645000
                                                               <<03686>>24650000
tos := 1;          << MSG type 1 - disc device not responding ><<03686>>24655000
                                                               <<03686>>24660000
START:                                                         <<03686>>24665000
                                                               <<03686>>24670000
<< Get IOQ pointer from DIT >>                                 <<03686>>24675000
tos := DITP(DIOQP);                                            <<03686>>24680000
                                                               <<03686>>24685000
<< If no IOQ, get the LDEV from the DIT >>                     <<03686>>24690000
TOS := DITP(DLDEV);                                            <<06768>>24695000
                                                               <<06768>>24700000
                                                               <<06768>>24705000
                                                               <<03686>>24710000
<< Initialize FLAGS word >>                                    <<03686>>24715000
tos := 0;   << Only try ATTACHIO >>                            <<03691>>24720000
                                                               <<03686>>24725000
<< Now, put the message on the console >>                      <<03686>>24730000
if DITP.TDFLAGS = 1 then   << If this is a DISC >>             <<03730>>24735000
ISSUE'HARD'MSG(ENTRY'TYPE,LDEV,FLAGS);                         <<03694>>24740000
                                                               <<03686>>24745000
<< Call GENMESSAGE to log the information >>                   <<03691>>24750000
if                                                             <<03730>>24755000
IOMESSAGE(1,NOTRDYMSG,%10000,LDEV,,,,,OPCONSOLE) then          <<03730>>24760000
  RSTATUS.CC := CCE                                            <<03730>>24765000
else                                                           <<03730>>24770000
  RSTATUS.CC := CCL;                                           <<03730>>24775000
                                                               <<03730>>24780000
end;   << of procedure >>                                      <<03686>>24785000
$PAGE  "CORE RESIDENT I/O SERVICE ROUTINES"                             24790000
                                                                        24795000
PROCEDURE ADDTAIL(NEW,LINKINDEX,QUEUENUMBER);                           24800000
  VALUE   LINKINDEX, QUEUENUMBER;                                       24805000
  INTEGER LINKINDEX, QUEUENUMBER;                                       24810000
  INTEGER ARRAY NEW;                                                    24815000
  OPTION UNCALLABLE, PRIVILEGED;                                        24820000
                                                                        24825000
  <<                                                                    24830000
    ADDS ELEMENT NEW TO THE END OF THE I/O RESOURCE QUEUE. IF THE       24835000
    ELEMENT IS ALREADY IN A QUEUE, IT IS NOT ADDED.                     24840000
  >>                                                                    24845000
  BEGIN                                                                 24850000
    DISABLE;                                                            24855000
    IF NEW(LINKINDEX) = 0 THEN                                 <<07341>>24860000
       << NOT IN QUEUE >>                                      <<07341>>24865000
      BEGIN                                                             24870000
        NEW(LINKINDEX) := -1;   << INDICATE IN A QUEUE >>               24875000
       IF HEAD(QUEUENUMBER) = -1 THEN  << EMPTY QUEUE >>       <<07341>>24880000
          HEAD(QUEUENUMBER) := @NEW                            <<07341>>24885000
          ELSE WA0(TAIL(QUEUENUMBER)+LINKINDEX) := @NEW;                24890000
        TAIL(QUEUENUMBER) := @NEW;                                      24895000
      END;                                                              24900000
  END;    <<  ADD TAIL >>                                               24905000
                                                                        24910000
PROCEDURE ADDHEAD(NEW,LINKINDEX,QUEUENUMBER);                           24915000
  VALUE   LINKINDEX, QUEUENUMBER;                                       24920000
  INTEGER LINKINDEX, QUEUENUMBER;                                       24925000
  INTEGER ARRAY NEW;                                                    24930000
  OPTION UNCALLABLE, PRIVILEGED;                                        24935000
                                                                        24940000
  <<                                                                    24945000
    ADDS ELEMENT NEW TO THE BEGINING OF THE I/O RESOURCE QUEUE. IF THE  24950000
    ELEMENT IS ALREADY IN A QUEUE, IT IS NOT ADDED.                     24955000
  >>                                                                    24960000
  BEGIN                                                                 24965000
    DISABLE;                                                            24970000
    IF NEW(LINKINDEX) = 0 THEN                                 <<07341>>24975000
       << NOT IN QUEUE >>                                      <<07341>>24980000
      BEGIN                                                             24985000
    IF HEAD(QUEUENUMBER) = -1 THEN  << EMPTY QUEUE >>          <<07341>>24990000
       TAIL(QUEUENUMBER) := @NEW;                              <<07341>>24995000
        NEW(LINKINDEX) := TOS;   << LINK REST OF LIST TO THIS >>        25000000
        HEAD(QUEUENUMBER) := @NEW;  << LINK IN THIS >>                  25005000
      END;                                                              25010000
  END;   << ADD HEAD >>                                                 25015000
                                                                        25020000
INTEGER PROCEDURE DEQUEUE(LINKINDEX,QUEUENUMBER);                       25025000
  VALUE LINKINDEX, QUEUENUMBER;   INTEGER LINKINDEX, QUEUENUMBER;       25030000
  OPTION UNCALLABLE, PRIVILEGED;                                        25035000
                                                                        25040000
  <<                                                                    25045000
      REMOVES THE FIRST ELEMENT IN AN I/O RESOUCE QUEUE AND RETURNS     25050000
      RETURNS THE DIT POINTER.  IF QUEUE IS EMPTY -1 IS RETURNED.       25055000
  >>                                                                    25060000
  BEGIN                                                                 25065000
    DISABLE;                                                            25070000
    TOS := HEAD(QUEUENUMBER);                                           25075000
    X := S0;    DEQUEUE := TOS;                                         25080000
  IF X <> -1 THEN << QUEUE NON-EMPTY >>                        <<07341>>25085000
      BEGIN                                                             25090000
        X := LINKINDEX + X;                                             25095000
        TOS := WA0(X);   << GET LINK TO NEXT ELEMENT >>                 25100000
        WA0(X) := 0;   << CLEAR LINK OF GOTTEN ELEMENT >>               25105000
        HEAD(QUEUENUMBER) := TOS;     << LINK IN REST OF LIST >>        25110000
      END;                                                              25115000
  END;    << DEQUEUE >>                                                 25120000
$PAGE " PROCEDURE CHECKLDEV  .... IN INCLHARD "                         25125000
<<===========CHECKLDEV=============>><< SPLIT STACK CALLS OK >><<03031>>25130000
                                                               <<03031>>25135000
PROCEDURE CHECKLDEV(LDEV);                                     <<03031>>25140000
VALUE LDEV;INTEGER LDEV;                                       <<03031>>25145000
OPTION PRIVILEGED,UNCALLABLE;                                  <<03031>>25150000
                                                               <<03031>>25155000
<< THIS PROCEDURE CHECKS THAT LDEV IS A VALID LOGICAL DEVICE >><<03031>>25160000
<< ( I.E. LDEV < LPDT MAXENTRY AND LPDT DITP > 0 AND LDEV IN >><<03031>>25165000
<< DIT MATCHES LDEV ).  ALSO INDICATES IF DEVICE IS A DISC   >><<03031>>25170000
<< ( I.E. DIT0.(0:2)=1 ) OR A TERMINAL ( I.E. DIT0.(0:1)=1 ) >><<03031>>25175000
                                                               <<03031>>25180000
<<   RETURNS:  CCL - INVALID LDEV                            >><<03031>>25185000
<<             CCG - VALID TERMINAL                          >><<03031>>25190000
<<             CCE - VALID LDEV - IF CARRY THEN A DISC       >><<03031>>25195000
                                                               <<03031>>25200000
BEGIN                                                          <<03031>>25205000
INTEGER LPDT'INDEX;                                            <<06768>>25210000
                                                               <<03031>>25215000
DEFINE MAXLDEV = INTEGER(LPDT'MAX'ENTRIES)#,                   <<06768>>25220000
                                                               <<06768>>25225000
                                                               <<06768>>25230000
          DITTDFLD     = ABS(LPDT'DIT'PTR + SYSDB).TDFLAGS#;   <<06768>>25235000
                                                               <<06768>>25240000
                                                               <<06768>>25245000
LPDT'INDEX := LDEV * INTEGER(LPDT'ENTRY'SIZE);                 <<06768>>25250000
   IF (1 <= LDEV <= MAXLDEV) AND (NOT LPDT'VIRTUAL'DEVICE) AND <<*8611>>25255000
      (LPDT'DIT'PTR > 0) THEN                                  <<*8611>>25260000
    IF (X:=DITTDFLD)>1 THEN RSTATUS.CCC:=CCG                   <<03031>>25265000
    ELSE RSTATUS.CCC:=X&LSL(2)+CCE                             <<03031>>25270000
  ELSE RSTATUS.CCC:=CCL;    << RETURN INVALID LDEV CONDITION >><<03031>>25275000
                                                               <<03031>>25280000
END;    << CHECK LDEV >>                                       <<03031>>25285000
$PAGE  "    PROCEDURE IOFAILURE   ....   IN INCLHARD  "                 25290000
                                                                        25295000
PROCEDURE IOFAILURE(DRTN,DITP);                                         25300000
  VALUE DRTN;  INTEGER DRTN;                                            25305000
  ARRAY DITP;  OPTION UNCALLABLE, PRIVILEGED;                           25310000
  <<                                                                    25315000
    THIS PROCEDURE OUTPUTS THE MESSAGE "NON RESPONDING DEVICE           25320000
    DRT XXX, LDEV YYY" AND CALL SUDDENDEATH 201                         25325000
    IF THE FAILURE OCCURED ON THE CONSOLE, A HALT %15 IS DONE.          25330000
  >>                                                                    25335000
  BEGIN                                                                 25340000
    INTEGER LDEV;                                                       25345000
                                                                        25350000
    DISABLE;                                                            25355000
    X := @DITP;                                                         25360000
      LDEV := IF <> THEN WA0(X:=X+DLDEV) ELSE 0;               <<06768>>25365000
    TOS := DOUBLE(SYSDB);    XCHDB;   << SET TO SYSDB >>                25370000
                                                                        25375000
    IF LDEV=CONSLDEV THEN ASMB(HALT %15);  << IO FAILURE ON CONSOLE >>  25380000
                                                                        25385000
  ISSUE'HARD'MSG(3,DRTN,%4); << NON-RESP DRT MSG >>            <<03686>>25390000
                                                                        25395000
    SUDDENDEATH(201);                                                   25400000
  END;     << I/O FAILURE >>                                            25405000
$PAGE   "     PROCEDURE LDEVTOTYPE   ... IN INCLHARD  "                 25410000
                                                                        25415000
<<==========LDEVTOTYPE=============>><< SPLIT STACK CALLS OK >><<03031>>25420000
                                                               <<03031>>25425000
INTEGER PROCEDURE LDEVTOTYPE(LDEV);                            <<03031>>25430000
VALUE LDEV;  INTEGER LDEV;                                     <<03031>>25435000
OPTION PRIVILEGED,UNCALLABLE;                                  <<03031>>25440000
                                                               <<03031>>25445000
<< THIS PROCEDURE CHECKS THAT LDEV IS A VALID LOGICAL DEVICE >><<03031>>25450000
<< CHECKS FOR VALID LDEV AND RETURNS DEVICE TYPE LDT2.(10:6) >><<03031>>25455000
<< IF BIT 0 OF LDEV IS SET / THEN RETURNS.(0:8) = LDT3.(0:8) >><<03031>>25460000
                                                               <<03031>>25465000
<<   RETURNS  CCL   = INVALID LDEV PSEUDO DEVICE             >><<03031>>25470000
<<            CCE   = VALID REAL DEVICE                      >><<03031>>25475000
<<            CARRY = DEVICE IS A DISC                       >><<03031>>25480000
BEGIN                                                          <<03031>>25485000
                                                               <<03031>>25490000
   INTEGER LDT'INDEX;                                          <<06768>>25495000
  INTEGER TYPEWORD,LDTFLAGS,OLDDB;                             <<03031>>25500000
   LOGICAL ARRAY LDT(0:SIZE'OF'LDT'ENTRY)=Q;                   <<07341>>25505000
  EQUATE  LDTDST   = 14,                                       <<03031>>25510000
          LDTSIZE  =  5,                                       <<03031>>25515000
          TOFFSET  =  2;                                       <<03031>>25520000
  DEFINE  FLAGFLD  = ( 0:8)#,                                  <<03031>>25525000
          SPECLREQ =LOGICAL(LDEV.(0:1))#,                      <<03031>>25530000
          DEV      =INTEGER(LDEV.(1:15))#;                     <<03031>>25535000
                                                               <<03031>>25540000
  CHECKDB;                                                     <<03031>>25545000
  IF <> THEN OLDDB:=EXCHANGEDB(0)                              <<03031>>25550000
        ELSE OLDDB:=0;                                         <<03031>>25555000
  CHECKLDEV(DEV);               << CHECK LDEV IS VALID & REAL>><<03031>>25560000
  IF < THEN                                                    <<03031>>25565000
  RSTATUS.CCC:=CCL              << CCL   = LDEV IS NOT VALID >><<03031>>25570000
  ELSE                          << CCE   = VALID RETURN DATA >><<03031>>25575000
  BEGIN                         << CARRY = DEVICE IS A DISC  >><<03031>>25580000
    RSTATUS.CCC:=(IF CARRY THEN 6 ELSE CCE);                   <<03031>>25585000
<< MOVE ENTRY FOR SPECIFIC DRIVE TO LOCAL ARRAY>>              <<06768>>25590000
   LDT'INDEX := DEV * SIZE'OF'LDT'ENTRY;                       <<06768>>25595000
   TOS := @LDT;                                                <<06768>>25600000
   TOS := LDT'DST;                                             <<06768>>25605000
   TOS := LDT'INDEX;                                           <<06768>>25610000
   TOS := SIZE'OF'LDT'ENTRY;                                   <<06768>>25615000
    ASSEMBLE(MFDS 4);                                          <<03031>>25620000
   LDT'INDEX := 0;                                             <<06768>>25625000
   LDEVTOTYPE := LDT'DEVICE'TYPE;                              <<06768>>25630000
    IF SPECLREQ THEN                       <<FOR SPECIAL REQ.>><<03031>>25635000
   LDEVTOTYPE.FLAGFLD := LDT(3).(0:8);                         <<06768>>25640000
  END;                                                         <<03031>>25645000
  IF OLDDB<>0 THEN EXCHANGEDB(OLDDB);                          <<03031>>25650000
END;    << LDEVTOTYPE >>                                       <<03031>>25655000
                                                               <<03031>>25660000
<<=========LDEVTOSUBTYPE===========>><< SPLIT STACK CALLS OK >><<03031>>25665000
                                                               <<03031>>25670000
INTEGER PROCEDURE LDEVTOSUBTYPE(LDEV);                         <<03031>>25675000
VALUE LDEV; INTEGER LDEV;                                      <<03031>>25680000
OPTION PRIVILEGED,UNCALLABLE;                                  <<03031>>25685000
BEGIN                                                          <<03031>>25690000
INTEGER LPDT'INDEX;                                            <<06768>>25695000
                                                               <<03031>>25700000
LPDT'INDEX := LDEV * INTEGER(LPDT'ENTRY'SIZE);                 <<06768>>25705000
  CHECKLDEV(LDEV);              << CHECK LDEV IS VALID & REAL>><<03031>>25710000
  IF < THEN                                                    <<03031>>25715000
  RSTATUS.CCC:=CCL              << CCL   = LDEV IS NOT VALID >><<03031>>25720000
  ELSE                          << CCE   = VALID RETURN DATA >><<03031>>25725000
  BEGIN                         << CARRY = DEVICE IS A DISC  >><<03031>>25730000
    RSTATUS.CCC:=(IF CARRY THEN 6 ELSE CCE);                   <<03031>>25735000
   LDEVTOSUBTYPE := LPDT'SUBTYPE;                              <<06768>>25740000
  END;                                                         <<03031>>25745000
END;                                                           <<03031>>25750000
                                                               <<03031>>25755000
INTEGER PROCEDURE LDEVTODRT(LDEV);                             <<03031>>25760000
  VALUE LDEV;                                                  <<03031>>25765000
  INTEGER LDEV;                                                <<03031>>25770000
 option privileged,uncallable;                                 <<03031>>25775000
  BEGIN                                                        <<03031>>25780000
   INTEGER LPDT'INDEX;                                         <<06768>>25785000
                                                               <<03031>>25790000
  COMMENT - THIS PROCEDURE ACCEPTS LDEV AND RETURNS:           <<03031>>25795000
          (0:7) -- UNIT                                        <<03031>>25800000
          (7:9) -- DRT NUMBER ;                                <<03031>>25805000
                                                               <<03031>>25810000
LPDT'INDEX := LDEV * INTEGER(LPDT'ENTRY'SIZE);                 <<06768>>25815000
   IF (1 <= LDEV <= LPDT'INDEX) AND                            <<06768>>25820000
      <<  CHECK TO SEE IF THIS DEVICE HAS A DS PSEUDO DRT >>   <<04302>>25825000
      <<  0 MEANS NOT A DS DEVICE, -2 MEANS NO DS ON SYSTEM >> <<04302>>25830000
      <<  HOPEFULLY SOME DAY GET'DSDEVICE WILL BECOME       >> <<04302>>25835000
      <<  GET'DATACOM'DEVICE AND CHECK FOR ALL DATACOM      >> <<04302>>25840000
      <<  PSEUDO DEVICES.                          >>          <<04302>>25845000
                                                               <<04302>>25850000
      ((0 = GET'DSDEVICE(LDEV)) OR (GET'DSDEVICE(LDEV) = -2))  <<04302>>25855000
       AND                                                     <<04302>>25860000
       NOT LPDT'VIRTUAL'DEVICE   THEN                          <<06768>>25865000
                                        << SPOOLED IF <= 0 >>  <<03031>>25870000
      BEGIN                                                    <<03031>>25875000
   TOS := ABS(LPDT'DIT'PTR + SYSDB + DUNIT);    <<UNIT>>       <<06768>>25880000
   TOS := TOS&LSL(9); << SHIFT LEFT 8 FOR DUNIT & 1 FOR DRT >> <<06768>>25885000
TOS.DRTNUMBER :=                                               <<06768>>25890000
     ABS(ABS(LPDT'DIT'PTR + SYSDB + DILTP)+ SYSDB +ICNTRL);    <<06768>>25895000
                                      <<DRT NUMBER>>           <<03031>>25900000
      END                                                      <<03031>>25905000
   ELSE TOS := 0;  << ILLEGAL LDEV OR VIRTUAL DEVICE >>        <<03031>>25910000
   LDEVTODRT := TOS;                                           <<03031>>25915000
   END;                                                        <<03031>>25920000
$PAGE                                                                   25925000
                                                                        25930000
$PAGE "SOFT'DEATH"                                                      25935000
PROCEDURE SOFT'DEATH (ID'NUMBER);                                       25940000
   VALUE ID'NUMBER;                                                     25945000
   INTEGER ID'NUMBER;                                                   25950000
                                                                        25955000
   OPTION PRIVILEGED,UNCALLABLE;                                        25960000
                                                                        25965000
<<=======================================================               25970000
                                                                        25975000
      This procedure is an interface to SUDDENDEATH.                    25980000
   There is a flag in SYSGLOB, word %350 (absolute %1350),              25985000
   bit 15, which, if set to one, will tell SOFT'DEATH to call           25990000
   crash the system.  If the flag is zero, the id'number passed         25995000
   along with the status and delta-P from the stack marker will         26000000
   be logged with MMSTAT.                                               26005000
                                                                        26010000
   Parameters:                                                          26015000
      ID'NUMBER - Number to be passed to SUDDENDEATH or MMSTAT.         26020000
                                                                        26025000
   Assumptions on entry:                                                26030000
      None, DB can be anywhere.                                         26035000
                                                                        26040000
   Exit conditions:                                                     26045000
      DB is unchanged.                                                  26050000
                                                                        26055000
   Fix i.d.                                                             26060000
      The fix i.d. on the procedure header applies to the entire        26065000
      procedure.                                                        26070000
                                                                        26075000
=======================================================>>               26080000
                                                                        26085000
BEGIN                                                          <<03526>>26090000
                                                               <<03526>>26095000
   << Low core flag, if 1 then call SUDDENDEATH >>             <<03526>>26100000
                                                               <<03526>>26105000
   DEFINE CRASH'ON'SOFT'DEATH = ABSOLUTE (%1350).(15:1)#;      <<03526>>26110000
                                                               <<03526>>26115000
   << Info from stack marker >>                                <<03526>>26120000
                                                               <<03526>>26125000
   INTEGER DELTA'P = Q-2;                                      <<03526>>26130000
   INTEGER STATUS'REG  = Q-1;                                  <<03526>>26135000
                                                               <<03526>>26140000
   << Event number for MMSTAT >>                               <<03526>>26145000
                                                               <<03526>>26150000
   EQUATE SOFT'DEATH'EVENT = 120;                              <<03526>>26155000
                                                               <<03526>>26160000
   << - - - - - - - - - >>                                     <<03526>>26165000
                                                               <<03526>>26170000
   IF CRASH'ON'SOFT'DEATH THEN                                 <<03526>>26175000
      SUDDENDEATH (ID'NUMBER)                                  <<03526>>26180000
   ELSE                                                        <<03526>>26185000
     MMSTAT'(SOFT'DEATH'EVENT, ID'NUMBER, STATUS'REG, DELTA'P, <<06768>>26190000
               0,0,0);                                         <<06768>>26195000
                                                               <<03526>>26200000
END;   << SOFT'DEATH >>                                        <<03526>>26205000
                                                               <<03526>>26210000
                                                               <<03526>>26215000
                                                               <<03526>>26220000
$PAGE "  PROCEDURE SUDDENDEATH .... IN INCLHARD   "            <<03526>>26225000
PROCEDURE SUDDENDEATH( N);                                              26230000
  VALUE N;  INTEGER N;                                                  26235000
  OPTION UNCALLABLE, PRIVILEGED;                                        26240000
  <<                                                                    26245000
     OUTPUTS THE SYSTEM HALT MESSAGE WITH THE DECIMAL NUMBER N          26250000
  >>                                                                    26255000
<<***********************************************>>            <<03694>>26260000
<< SUDDENDEATH will attempt to save the environ- >>            <<03694>>26265000
<< ment of the CONSOLE DRT by saving it on TOS   >>            <<03694>>26270000
<< before PRINTCHAR gets hold of it.  When read- >>            <<03694>>26275000
<< ing dumps, the locations in this procedure    >>            <<03694>>26280000
<< will be:                                      >>            <<03694>>26285000
<<           Q+1       - DRT number of console   >>            <<03694>>26290000
<<           Q+2/5     - 4 words of console DRT  >>            <<03694>>26295000
<<***********************************************>>            <<03694>>26300000
  BEGIN                                                                 26305000
    INTEGER DELTAP = Q-2;     << DELTA P IN STACK MARKER >>             26310000
    INTEGER DRTN;       << DRT # OF CONSOLE >>                 <<06768>>26315000
                                                               <<03694>>26320000
    INTEGER LPDT'INDEX;                                        <<06768>>26325000
                                                               <<03694>>26330000
  define CONSLDEV = ABS(%1074)#; << Console LDEV # >>          <<03694>>26335000
                                                                        26340000
    TRAPSOFF;  << TURN OFF TRAPS >>                            <<03526>>26345000
    DISABLE;                                                            26350000
                                                               <<03694>>26355000
    << We will now save the 4 DRT words of the console. >>     <<03694>>26360000
    << PRINTCHAR will destroy these values, so we must  >>     <<03694>>26365000
    << save them here.                                  >>     <<03694>>26370000
LPDT'INDEX := CONSLDEV * INTEGER(LPDT'ENTRY'SIZE);             <<06768>>26375000
                                                               <<06768>>26380000
     TOS := ABS(LPDT'DIT'PTR + SYSDB + DILTP);  << ILT >>      <<06768>>26385000
     DRTN := ABS(TOS + SYSDB + ICNTRL).DRTNUMBER;  <<DRT>>     <<06768>>26390000
    X := -1;                                                   <<03694>>26395000
    while (X:=X+1) < 4 do                                      <<03694>>26400000
      tos := GETDRT(DRTN,X);                                   <<03694>>26405000
                                                               <<03694>>26410000
    ASMB(ZROX,ZERO);  << FOR DELAY AND SETTING SYSDB >>                 26415000
    TOS := SYSDB;    XCHDB;                                             26420000
    WHILE DXBZ DO N := N;  << DELAY TO LET ANY I/O FINISH >>            26425000
                                                                        26430000
  ISSUE'HARD'MSG(4,N,%4);  << SYSTEM FAILURE # >>              <<03686>>26435000
  ISSUE'HARD'MSG(5,RSTATUS,%4);  << STATUS =   >>              <<03686>>26440000
  ISSUE'HARD'MSG(6,DELTAP,%4);                                 <<03686>>26445000
    XCHDB;    << RESTORE DB >>                                          26450000
                                                                        26455000
L3:                                                                     26460000
    ASMB( HALT %17 );                                                   26465000
    HELP;                                                               26470000
    GOTO L3;                                                            26475000
                                                                        26480000
  END;        <<  SUDDEN  DEATH  >>                                     26485000
$PAGE                                                                   26490000
                                                                        26495000
PROCEDURE AWAKEIO( DITP,FLAGS);                                         26500000
  VALUE DITP, FLAGS;                                                    26505000
  INTEGER POINTER DITP;  INTEGER FLAGS;                                 26510000
  OPTION UNCALLABLE, PRIVILEGED;                                        26515000
  <<                                                                    26520000
     FLAGS.(0:10) = 0 OR STACK DST NUMBER                               26525000
          .(13:1) = IF SET THEN PROCESS IS IMPEDABLE                    26530000
                                                                        26535000
     THIS PROCEDURE CALLS THE MONITOR OR AWAKES AN I/O PROCESS.         26540000
     TYPE 1 MONITORS (CAN BE RUN ON ANY STACK) ARE CALLED. TYPE 2       26545000
     MONITORS (CAN BE RUN IN ANY PROCESS) ARE CALLED IF IMPEDABLE       26550000
     OR A REQUEST IS QUEUED AND THE I/O PROCESS IS AWAKENED IF NOT      26555000
     IMPEDABLE. THE ASSOCIATED PROCESS IS AWAKENED FOR TYPE 3           26560000
     MONITORS (RUN ONLY IN OWN PROCESS).                                26565000
  >>                                                                    26570000
  BEGIN                                                                 26575000
    INTEGER POINTER DLTP = Q+1;                                         26580000
                                                                        26585000
    TRAPSOFF;              << TURN OFF TRAPS >>                <<*8741>>26590000
    TOS := DITP(DDLTP);    <<  SET DLTP >>                              26595000
                                                                        26600000
    X := (DLTP+FLAGS).(13:3);                                           26605000
    TOS := 0;   << SET IFLAG TO FALSE >>                                26610000
    << SWITCH CODES 0,4     - NOT USED, IGNORED NOT RESIDENT            26615000
                    1,5,6   - CALL MONITOR                              26620000
                    2       - QUEUE REQUEST AND WAKE UP                 26625000
                    3,7     - WAKE UP TO RUN IN OWN PROCESS             26630000
    >>                                                                  26635000
    ASMB( BR * +1, X  ;                                                 26640000
      BR CHK'SEG; BR CALLMNTR;  BR QUEUE;     BR WAKEUP;       <<03031>>26645000
      BR CALLMNTR;BR CALLMNTR;  BR CALLMNTR);                  <<03031>>26650000
                                                                        26655000
WAKEUP:                                                                 26660000
    TOS := DITP(DPCBN)*PCBSIZE; << PCBs are now 16 bits >>     <<06768>>26665000
    GOTO WAKE;                                                          26670000
                                                                        26675000
QUEUE:                                                                  26680000
    X := DLTP&LSR(8);  << GET I/O PROCESS QUEUE NUMBER >>               26685000
    ADDTAIL(DITP,DLINK,X);                                              26690000
    TOS := BUSY(X);  << GET I/O PROCESS PCB INDEX >>                    26695000
                                                                        26700000
WAKE:                                                                   26705000
    AWAKE( *, JUNKWAIT,NOWAIT);                                         26710000
    RETURN;                                                             26715000
                                                               <<03031>>26720000
CHK'SEG:                                                       <<03031>>26725000
    PDISABLE;                                                  <<03031>>26730000
    IF CST (DLTP(DMNTR).(8:8)*4) < 0 THEN                      <<03031>>26735000
      BEGIN   << ABSENT >>                                     <<03031>>26740000
        PENABLE;                                               <<03031>>26745000
        GO QUEUE;                                              <<03031>>26750000
      END;                                                     <<03031>>26755000
                                                               <<03031>>26760000
    TOS := @DITP;                                              <<03031>>26765000
    TOS := FLAGS;                                              <<03031>>26770000
    TOS := DLTP(DMNTR);                                        <<03031>>26775000
    ASMB(PCAL 0);     << RUN DRIVER HERE >>                    <<03031>>26780000
    PENABLE;                                                   <<03031>>26785000
    RETURN;                                                    <<03031>>26790000
                                                               <<03031>>26795000
CALLMNTR:                                                               26800000
    TOS := @DITP;                                                       26805000
    TOS := FLAGS;  << TO SATISFY CALLING SEQUENCE >>                    26810000
    TOS := DLTP(DMNTR);    << MONITOR PLABEL >>                         26815000
    ASMB( PCAL 0 );                                                     26820000
  END;    <<        AWAKEIO   >>                                        26825000
$PAGE   "  SYSTEM IO PROCESS "                                          26830000
                                                                        26835000
PROCEDURE SYSIOPROC;                                                    26840000
  OPTION PRIVILEGED, UNCALLABLE;                                        26845000
  BEGIN                                                                 26850000
    INTEGER POINTER DITP;                                               26855000
    INTEGER IOPROCQN = DITP + 1;   << SYS IO PROCESS QUEUE NUMBER >>    26860000
                                                                        26865000
    TOS := X;    << SET IOPROCQN >>                                     26870000
                                                                        26875000
LOOP:                                                                   26880000
    DISABLE;                                                            26885000
    TOS := %1000D;              <<  PUT DB TO SYSDB IN CASE  >><<*8235>>26890000
    ASSEMBLE( XCHD;  DDEL);     <<  MONITOR BLEW IT          >><<*8235>>26895000
    @DITP := DEQUEUE(DLINK,IOPROCQN);                                   26900000
    X := @DITP;   << SEE IF ANYTHING QUEUED >>                          26905000
IF @DITP <> -1 THEN << IS A REAL DEVICE >>                     <<07341>>26910000
      BEGIN                                                             26915000
        ENABLE;                                                         26920000
        AWAKEIO(DITP,IMPEDABLE);      << CALL MONITOR >>                26925000
      END                                                               26930000
    << THE NEGATIVE WAITFIELD IS USED TO ALLOW TEPE/3000 >>    <<03031>>26935000
    << TO ABORT. IF THE WWS (WORD 3, BIT 0 OF THE PCB)   >>    <<03031>>26940000
    << IS SET,AN AWAKE IS MISSING SO RETURN TO SYSIOPROC >>    <<03031>>26945000
    << WITHOUT WAITING.                                  >>    <<03031>>26950000
                                                               <<03031>>26955000
    ELSE WAIT(-JUNKWAIT,NULL);   << NOTHING TO DO >>           <<03031>>26960000
    GOTO LOOP;   << CHECK FOR MORE TO DO >>                             26965000
  END;   << SYS I/O PROC >>                                             26970000
                                                                        26975000
INTEGER PROCEDURE GETDRT(DRT,OFFSET);                          <<03031>>26980000
<<=================================>>                          <<03031>>26985000
    VALUE DRT,OFFSET;                                          <<03031>>26990000
    INTEGER DRT,OFFSET;                                        <<03031>>26995000
    OPTION PRIVILEGED,UNCALLABLE;                              <<*7866>>27000000
                                                               <<03031>>27005000
    COMMENT: USE FIXED LOW CORE CELLS "DRTBANK","DRTADDR"      <<03031>>27010000
      TO GET DEVICE REF TABLE START ADDRESS, THEN INDEX        <<03031>>27015000
      TO THE DESIRED "DRT" ENTRY (4 WORD), AND USE             <<03031>>27020000
      "OFFSET" TO SPECIFY THE DESIRED WORD IN THE TABLE;       <<03031>>27025000
                                                               <<03031>>27030000
BEGIN                                                          <<03031>>27035000
                                                               <<03694>>27040000
define HSYSDRT = ABS(%1071)#; << Highest conf'd DRT >>         <<03694>>27045000
                                                               <<03694>>27050000
  if not (3 <= DRT <= HSYSDRT) then SUDDENDEATH(278);          <<03694>>27055000
  TOS:=ABSOLUTE(DRTBANK);                                      <<03031>>27060000
  TOS:=ABSOLUTE(DRTADDR)+DRT&LSL(2)+OFFSET;                    <<03031>>27065000
  ASSEMBLE(LSEA);                                              <<03031>>27070000
  PUSH(STATUS);                                                <<03031>>27075000
  TOS:=TOS.CC;                                                 <<03031>>27080000
  RSTATUS.CC:=TOS;  <<SET CC FOR FUTURE TEST>>                 <<03031>>27085000
    <<ORIGINAL CODE ASSIGNMENT SET THE CC>>                    <<03031>>27090000
  GETDRT:=TOS;                                                 <<03031>>27095000
END;                                                           <<03031>>27100000
                                                               <<03031>>27105000
PROCEDURE PUTDRT(DRT,OFFSET,NUM);                              <<03031>>27110000
<<=============================>>                              <<03031>>27115000
    VALUE DRT,OFFSET,NUM;                                      <<03031>>27120000
    INTEGER DRT,OFFSET,NUM;                                    <<03031>>27125000
    OPTION PRIVILEGED,UNCALLABLE;                              <<*7866>>27130000
                                                               <<03031>>27135000
    COMMENT: USE FIXED LOW CORE CELLS "DRTBANK","DRTADDR"      <<03031>>27140000
      TO GET DEVICE REF TABLE START ADDRESS, THEN INDEX        <<03031>>27145000
      TO THE DESIRED "DRT" ENTRY (4 WORD), AND USE             <<03031>>27150000
      "OFFSET" TO SPECIFY THE DESIRED WORD.                    <<03031>>27155000
      LOAD THE VALUE "NUM" INTO THAT WORD IN THE TABLE;        <<03031>>27160000
                                                               <<03031>>27165000
BEGIN                                                          <<03031>>27170000
                                                               <<03694>>27175000
define HSYSDRT = ABS(%1071)#; << Highest conf'd DRT >>         <<03694>>27180000
                                                               <<03694>>27185000
  if not (3 <= DRT <= HSYSDRT) then SUDDENDEATH(278);          <<03694>>27190000
  TOS:=ABSOLUTE(DRTBANK);                                      <<03031>>27195000
  TOS:=ABSOLUTE(DRTADDR) + DRT&LSL(2) + OFFSET;                <<03031>>27200000
  TOS:=NUM;                                                    <<03031>>27205000
  ASSEMBLE(SSEA);                                              <<03031>>27210000
END;                                                           <<03031>>27215000
                                                               <<03031>>27220000
$PAGE "EOFCHECK - CHECK FOR END OF FILE COND."                          27225000
PROCEDURE EOFCHECK(IOQP,BUF,CNT,HARDCHK);                               27230000
VALUE IOQP,BUF,CNT,HARDCHK;                                             27235000
INTEGER IOQP;                                                  <<06768>>27240000
DOUBLE BUF;                                                             27245000
LOGICAL CNT,HARDCHK;                                                    27250000
OPTION PRIVILEGED,UNCALLABLE;                                           27255000
BEGIN                                                                   27260000
INTEGER IOQ'ENTRY'INDEX = IOQP;                                <<06768>>27265000
EQUATE                                                                  27270000
   READ        = 0,                                                     27275000
   HARDWAREOF  = 1,                                                     27280000
   DATA        = 2,                                                     27285000
   EOD         = 3,                                                     27290000
   HELLO       = 4,                                                     27295000
   BYE         = 5,                                                     27300000
   JOB         = 6,                                                     27305000
   EOJ         = 7,                                                     27310000
   SESSIONRD   = 3,                                                     27315000
   DATARD      = 2,                                                     27320000
   JOBRD       = 4,                                                     27325000
   NOEOF       = 0;                                                     27330000
DEFINE                                                                  27335000
   CEOF        = (13:3)#,  << EOF CHECK FIELD OF QPAR1 >>               27340000
   FUNCT       = (8:8)#;  << FUNCTION FIELD OF IOQ >>                   27345000
BYTE                                                                    27350000
   B2          = Q+2,                                          <<03031>>27355000
   B4          = Q+3;                                                   27360000
BYTE ARRAY                                                              27365000
   BA(*)       = Q+1;                                                   27370000
DOUBLE                                                                  27375000
   DWORD0      = Q+1,                                                   27380000
   DWORD1      = Q+2,                                                   27385000
   DWORD2      = Q+3,                                          <<03031>>27390000
   DWORD4      = Q+5;                                          <<03031>>27395000
DOUBLE ARRAY                                                            27400000
   DA(*)       = Q+1;                                                   27405000
INTEGER                                                                 27410000
   LPDT'INDEX  = Q + 7,                                        <<06768>>27415000
   TYPE        = Q + 9,                                        <<06768>>27420000
   LAST        = Q + 10,                                       <<06768>>27425000
   WORD0       = Q+1;                                                   27430000
                                                               <<06768>>27435000
                                                               <<06768>>27440000
                                                                        27445000
                                                                        27450000
   << INITIALIZE LOCAL VARIABLES >>                                     27455000
ASMB(ADDS 7); << LOCAL CHECK BUFFER & LPDT >>                  <<06768>>27460000
   LPDT'INDEX := INTEGER(IOQ'LDEV) * INTEGER(LPDT'ENTRY'SIZE); <<06768>>27465000
   TOS := LPDT(LPDT'INDEX + LFLAGS);                           <<06768>>27470000
   TOS := IOQ'PARM1.CEOF;<< TYPE OF EOF CHECK >>               <<06768>>27475000
   IF S0 > JOBRD THEN GO TO SETCCE; << SKIP ANY CHECKING >>             27480000
   TOS := LPDT'EOF'TYPE; << EOF FROM LAST READ >>              <<06768>>27485000
   TOS := BUF;                                                          27490000
   IF = THEN                                                            27495000
   BEGIN << PRE READ CHECK >>                                           27500000
      IF LAST = NOEOF THEN GO TO SETCCE;                                27505000
      IF TYPE = NOEOF OR TYPE = HARDWAREOF AND LAST > HARDWAREOF THEN   27510000
      BEGIN << NO EOF - NONE ON LAST READ OR CHK LEVEL TOO LOW >>       27515000
RESETEOF:                                                               27520000
   LPDT'EOF'TYPE := 0;  << RESET EOF IN LPDT >>                <<06768>>27525000
SETCCE:                                                                 27530000
         TOS := CCE;                                                    27535000
SETRSTAT:                                                               27540000
         RSTATUS.CC := TOS; << SET CALLER'S CONDITION CODE >>           27545000
         RETURN;                                                        27550000
      END;                                                              27555000
SETLAST:                                                                27560000
      TOS := CCG;                                                       27565000
      TOS := LAST;                                                      27570000
SETRETURN:                                                              27575000
      IOQ'COUNT := 0;                                          <<06768>>27580000
      TOS := TOS&LSL(3) + 2;                                            27585000
      IOQ'STAT := TOS;                                         <<06768>>27590000
      GO TO SETRSTAT;                                                   27595000
   END;                                                                 27600000
   IF LAST = HARDWAREOF THEN GO TO SETLAST;                             27605000
   << ALWAYS RETURN HARDWARE EOF ON POST READ CHECK >>                  27610000
      IF IOQ'FUNC <> READ THEN GOTO SETCCE;                    <<06768>>27615000
   << CAN'T CHECK DATA IF NO READ >>                           <<03031>>27620000
   TOS := CNT;                                                          27625000
   IF < THEN TOS := -TOS ELSE TOS := TOS&LSL(1);                        27630000
   CNT := TOS; << POS BYTE COUNT >>                                     27635000
   IF = THEN GO TO RESETEOF; << ZERO READ LENGTH >>                     27640000
   X := 0;                                                              27645000
   DO                                                                   27650000
   BEGIN << GET FIRST SIX WORDS OF DATA >>                              27655000
      ASMB(LDEA);                                                       27660000
      DA(X) := TOS;                                                     27665000
      TOS := TOS + 2;                                                   27670000
   END UNTIL (X:=X+1) > 2;                                              27675000
   TOS := HARDCHK;                                                      27680000
   DDEL;                                                                27685000
   DEL;                                                                 27690000
   IF < THEN                                                            27695000
   BEGIN << COLUMN BINARY ":EOF:" CHECK >>                              27700000
      IF DWORD0 = [16/%202,16/%4020]D AND DWORD2 = [16/%2010,16/%4010]D 27705000
      AND DWORD4 = [16/%202,16/%0]D THEN                                27710000
      BEGIN << HARDWARE EOF >>                                          27715000
SETHARD:                                                                27720000
         TOS := CCG;                                                    27725000
         TOS := HARDWAREOF;                                             27730000
SETEOF:                                                                 27735000
         ASMB(DUP);                                                     27740000
LPDT'EOF'TYPE := TOS;                                          <<06768>>27745000
         GO TO SETRETURN;                                               27750000
      END ELSE GO TO RESETEOF;                                          27755000
   END;                                                                 27760000
   FOR * X := 0 UNTIL 5 DO                                              27765000
   BEGIN << UPSHIFT ASCII DATA FOR DATA CHECK >>                        27770000
      TOS := BA(X);                                                     27775000
      IF = THEN TOS := TOS LAND %337; << ALPHA CHARECTER >>             27780000
      BA(X) := TOS;                                                     27785000
   END;                                                                 27790000
   IF CNT < 6 THEN BA(CNT) := " ";                                      27795000
   << BLANK ODD BYTE SO CHECK MAY BE DONE ON WORDS >>                   27800000
   TOS := HARDCHK;                                                      27805000
   DEL;                                                                 27810000
   IF > AND WORD0 = ":E" AND DWORD1 = "OF: " THEN GO TO SETHARD;        27815000
   IF TYPE <= HARDWAREOF THEN GO TO RESETEOF; << NO DATA CHECKS >>      27820000
   TOS := CCL;                                                          27825000
   IF TYPE = SESSIONRD THEN                                             27830000
   BEGIN << SESSION READ TESTS - NO LEADING COLON >>                    27835000
      IF DWORD0 = "HELL" AND B4 = "O" AND BA(5) <> ALPHA THEN  <<03031>>27840000
      BEGIN << HELLO >>                                                 27845000
         TOS := HELLO;                                                  27850000
         GO SETEOF;                                                     27855000
      END;                                                              27860000
      IF DWORD0 = "DATA" AND B4 <> ALPHA THEN GO TO DATACMD;   <<03031>>27865000
      IF WORD0 = "JO" AND B2 = "B" AND BA(3) <> ALPHA THEN     <<03031>>27870000
                                                GO TO JOBCMD;  <<03031>>27875000
      IF WORD0 = "BY" AND B2 = "E" AND BA(3) <> ALPHA THEN     <<03031>>27880000
      BEGIN                                                             27885000
         TOS := CCG; << DON'T BACKSPACE BYE >>                          27890000
         TOS := BYE;                                                    27895000
         GO SETEOF;                                                     27900000
      END;                                                              27905000
      GO RESETEOF;                                                      27910000
   END;                                                                 27915000
   IF BA <> ":" THEN GO TO RESETEOF;                                    27920000
   IF WORD0 = ":D" AND DWORD1 = "ATA " THEN                             27925000
   BEGIN << DATA >>                                                     27930000
DATACMD:                                                                27935000
      TOS := DATA;                                                      27940000
      GO SETEOF;                                                        27945000
   END;                                                                 27950000
   IF B4 <> " " THEN GO RESETEOF;                                       27955000
   IF DWORD0 = ":JOB" THEN                                              27960000
   BEGIN                                                                27965000
JOBCMD:                                                                 27970000
      TOS := JOB;                                                       27975000
      GO SETEOF;                                                        27980000
   END;                                                                 27985000
   DEL;                                                                 27990000
   TOS := CCG;                                                          27995000
   IF TYPE = DATARD AND DWORD0 = ":EOD" THEN                            28000000
   BEGIN                                                                28005000
      TOS := EOD;                                                       28010000
      GO SETEOF;                                                        28015000
   END;                                                                 28020000
   IF TYPE = JOBRD AND DWORD0 = ":EOJ" THEN                             28025000
   BEGIN                                                                28030000
      TOS := EOJ;                                                       28035000
      GO SETEOF;                                                        28040000
   END;                                                                 28045000
   GO RESETEOF;                                                         28050000
END;                                                                    28055000
$PAGE "CHANNEL QUEUE CHECKER"                                           28060000
PROCEDURE CHKCHANNELQUE(CHANNEL,DITP);                                  28065000
VALUE CHANNEL,DITP;                                                     28070000
INTEGER CHANNEL;                                                        28075000
POINTER DITP;                                                           28080000
OPTION PRIVILEGED,UNCALLABLE;                                           28085000
BEGIN << CONTROLLER IS ON A CHANNEL >>                                  28090000
LOGICAL POINTER                                                         28095000
   DLTPL   = Q+1;                                                       28100000
                                                                        28105000
   TOS := DITP(DDLTP);   << SET DLTPL >>                                28110000
   TOS := CHANNEL; << IS THERE REALLY A CHANNEL? >>                     28115000
   IF < THEN                                                            28120000
   BEGIN << MULTI-CONTROLLER CHANNEL >>                                 28125000
      CHANNEL := TOS.CHANQUE; << SET CHANNEL QUEUE # >>                 28130000
      DISABLE;                                                          28135000
      WHILE BUSY(CHANNEL) = 0 OR BUSY(CHANNEL) = @DITP DO               28140000
      BEGIN                                                             28145000
         BUSY(CHANNEL) := 0; << RESET CHANNEL BUSY >>                   28150000
         X := DEQUEUE(DLINK,CHANNEL);                                   28155000
         IF X <> -1 THEN                                       <<C9352>>28160000
         BEGIN << ANOTHER CONTROLLER IS WAITING >>                      28165000
            ENABLE;                                                     28170000
            TOS := X;   TOS := S0;    << GET  AND DUPLICATE DITP >>     28175000
            TOS := PS0(DILTP); << ILT POINTER >>                        28180000
            TOS := PS0(ICPGM); << SIO PROGRAM POINTER >>       <<03086>>28185000
            DELB;                                                       28190000
            STARTIO(*,*,0);    << START THE I/O FOR THIS DIT >><<03031>>28195000
            IF <> THEN IF DLTPL.QABORTS THEN  << SEND FAILURE REQUEST >>28200000
        ATTACHIO(DITP(DLDEV),0,0,0,SIOFAIL,0,0,0,NOPCB)        <<06768>>28205000
            ELSE  << SET BITS TO INDICATE FAILURE >>                    28210000
            BEGIN << I/O FAILED TO START >>                             28215000
               PS0.IAK := 1;                                            28220000
               TOS := PS0(DIOQP);                                       28225000
               IF > THEN PS0.SFAIL := 1; << SET SIO FAIL >>             28230000
               DEL;                                                     28235000
               AWAKEIO(*,NOIMPEDE); << INFORM DRIVER >>                 28240000
            END ELSE DEL;                                               28245000
         END ELSE RETURN;                                               28250000
         DISABLE;                                                       28255000
      END;                                                              28260000
   END;                                                                 28265000
END;                                                                    28270000
                                                                        28275000
                                                                        28280000
PROCEDURE IOIMPEDE( TBLNUM);                                   <<07410>>28285000
   VALUE TBLNUM;                                               <<07410>>28290000
   INTEGER TBLNUM;                                             <<07410>>28295000
   OPTION PRIVILEGED, UNCALLABLE;                              <<07410>>28300000
BEGIN                                                          <<07410>>28305000
                                                               <<07410>>28310000
INTEGER                                                        <<07410>>28315000
   NEXT    := 0,                                               <<07410>>28320000
   MYPCBPT := 0,                                               <<07410>>28325000
   PREVIOUS'IMP := 0;                                          <<07410>>28330000
                                                               <<07410>>28335000
   MYPCBPT := CURPRC;                                          <<07410>>28340000
                                                               <<07410>>28345000
   IF NOT( 1 <= TBLNUM <= 3 ) THEN SUDDENDEATH( 249);          <<07410>>28350000
   DISABLE;                                                    <<07410>>28355000
                                                               <<07410>>28360000
   CASE *X OF                                                  <<07410>>28365000
      BEGIN                                                    <<07410>>28370000
<<0>> ;                                                        <<07410>>28375000
<<1>> IF SBH'IMP'PCB = 0 THEN                                  <<07410>>28380000
         SBH'IMP'PCB := MYPCBPT                                <<07410>>28385000
      ELSE                                                     <<07410>>28390000
         PREVIOUS'IMP := SBH'IMP'PCB;                          <<07410>>28395000
<<2>> IF IQH'IMP'PCB = 0 THEN                                  <<07410>>28400000
         IQH'IMP'PCB := MYPCBPT                                <<07410>>28405000
      ELSE                                                     <<07410>>28410000
         PREVIOUS'IMP := IQH'IMP'PCB;                          <<07410>>28415000
<<3>> IF DQH'IMP'PCB = 0 THEN                                  <<07410>>28420000
         DQH'IMP'PCB := MYPCBPT                                <<07410>>28425000
      ELSE                                                     <<07410>>28430000
         PREVIOUS'IMP := DQH'IMP'PCB;                          <<07410>>28435000
      END;                                                     <<07410>>28440000
                                                               <<07410>>28445000
                                                               <<07410>>28450000
   IF PREVIOUS'IMP <> 0 THEN                                   <<07410>>28455000
      BEGIN << APPEND THIS PROCESS TO THE LIST >>              <<07410>>28460000
      NEXT := PREVIOUS'IMP;                                    <<07410>>28465000
      DO                                                       <<07410>>28470000
         NEXT := LPCB(NEXT + NIMPPINWORDNUM)                   <<07410>>28475000
      UNTIL = ;                                                <<07410>>28480000
      LPCB(X) := MYPCBPT;                                      <<07410>>28485000
      END;                                                     <<07410>>28490000
   LPCB(MYPCBPT + NIMPPINWORDNUM) := 0;                        <<07410>>28495000
                                                               <<07410>>28500000
   IMPEDE( 0 );      <<  IMPEDE  CURRENT PROCESS   >>          <<07410>>28505000
END;                                                           <<07410>>28510000
                                                                        28515000
PROCEDURE IOUNIMPEDE( TBLNUM);                                 <<07410>>28520000
   VALUE TBLNUM;                                               <<07410>>28525000
   INTEGER TBLNUM;                                             <<07410>>28530000
   OPTION PRIVILEGED, UNCALLABLE;                              <<07410>>28535000
BEGIN                                                          <<07410>>28540000
   INTEGER IMPPCBPT; << HEAD OF IMPEDED LIST >>                <<07410>>28545000
                                                               <<07410>>28550000
   IF NOT( 1 <= TBLNUM <= 3 ) THEN SUDDENDEATH( 249);          <<07410>>28555000
                                                               <<07410>>28560000
   DISABLE;                                                    <<07410>>28565000
                                                               <<07410>>28570000
   CASE *X OF                                                  <<07410>>28575000
      BEGIN                                                    <<07410>>28580000
<<0>> ;                                                        <<07410>>28585000
<<1>> TOS := SBH'IMP'PCB;                                      <<07410>>28590000
<<2>> TOS := IQH'IMP'PCB;                                      <<07410>>28595000
<<3>> TOS := DQH'IMP'PCB;                                      <<07410>>28600000
      END;                                                     <<07410>>28605000
                                                               <<07410>>28610000
   IF = THEN RETURN;                                           <<07410>>28615000
                                                               <<07410>>28620000
   IMPPCBPT := TOS;                                            <<07410>>28625000
   TOS := LPCB( IMPPCBPT + NIMPPINWORDNUM); << NEXT ENTRY >>   <<07410>>28630000
   LPCB(X) := 0;                                               <<07410>>28635000
                                                               <<07410>>28640000
   CASE *TBLNUM OF                                             <<07410>>28645000
      BEGIN  << DELINK ENTRY >>                                <<07410>>28650000
<<0>> ;                                                        <<07410>>28655000
<<1>> SBH'IMP'PCB := TOS;                                      <<07410>>28660000
<<2>> IQH'IMP'PCB := TOS;                                      <<07410>>28665000
<<3>> DQH'IMP'PCB := TOS;                                      <<07410>>28670000
      END;                                                     <<07410>>28675000
                                                               <<07410>>28680000
   UNIMPEDE( IMPPCBPT);  << RUN HEAD PROCESS >>                <<07410>>28685000
                                                               <<07410>>28690000
END;  << IOUNIMPEDE >>                                         <<07410>>28695000
$PAGE "SYSTEM BUFFER ROUTINES"                                          28700000
PROCEDURE RETURNSYSBUF(INDEX);                                          28705000
VALUE INDEX;                                                            28710000
INTEGER INDEX;                                                          28715000
OPTION PRIVILEGED,UNCALLABLE;                                           28720000
BEGIN                                                                   28725000
                                                                        28730000
INTEGER                                                                 28735000
   NUM           = Q+1,                                                 28740000
   SIZE          = Q+2; << BUFFER SIZE >>                               28745000
                                                                        28750000
INTEGER POINTER                                                         28755000
   SYSBUF      = SYSSBUF;                                               28760000
                                                                        28765000
   TOS := 0;                                                            28770000
   TOS := SBH'ENT'SIZE;                                        <<06768>>28775000
   DISABLE;                                                             28780000
   TOS := FIRSTINDEX;                                                   28785000
        TOS := INTEGER(SBH'TOT'ENT - 1) * SIZE + FIRSTINDEX;   <<06768>>28790000
   TOS := INDEX;                                                        28795000
   DUPLICATE;                                                           28800000
   SBH(SBH'FREETAIL - 1) := TOS;                               <<06768>>28805000
   << ABOVE - APPEND RETURNED LIST >>                          <<06768>>28810000
   DO                                                                   28815000
   BEGIN << FIND END OF LIST >>                                         28820000
      X := TOS;                                                         28825000
      ASMB(DDUP,DECX);                                                  28830000
      IF NOT(TOS <= X <= TOS) THEN SUDDENDEATH(251);                    28835000
      TOS := X - FIRSTINDEX; << CHECK THAT INDEX IS MODULO >>           28840000
      TOS := SIZE;                                                      28845000
      ASMB(DIV,TEST; DDEL);                                             28850000
      IF <> THEN SUDDENDEATH(251);                                      28855000
      NUM := NUM + 1;                                                   28860000
      TOS := SYSBUF(X);                                                 28865000
   END UNTIL =;                                                         28870000
   SBH'FREETAIL := X + 1; << POINT TAIL AT LAST BUF>>          <<06768>>28875000
                                                               <<06768>>28880000
   TOS := INTEGER(SBH'CUR'NUSE) - NUM;                         <<06768>>28885000
   IF < THEN SUDDENDEATH(252);                                          28890000
   SBH'CUR'NUSE := TOS;                                        <<06768>>28895000
   IOUNIMPEDE( SBUF'TABLE);                                    <<07410>>28900000
   << WAKE UP ANYONE WAITING FOR BUFFERS >>                             28905000
END;                                                                    28910000
