$CONTROL MAP,CODE,USLINIT                                               00010000
<<IOFDISC0 - MODULE 17>>                                                00015000
<< HP32002C MPE SOURCE C.00.00 >>                                       00020000
<< COPYRIGHT     "(C) COPYRIGHT HEWLETT-PACKARD CO. 1980.           >>  00025000
<<     THIS PROGRAM MAY BE USED WITH ONE COMPUTER SYSTEM AT A       >>  00030000
<<     TIME AND SHALL NOT OTHERWISE BE RECORDED, TRANSMITTED OR     >>  00035000
<<     STORED IN A RETRIEVAL SYSTEM.  COPYING OR OTHER REPRODUCTION >>  00040000
<<     OF THIS PROGRAM EXCEPT FOR ARCHIVAL PURPOSES IS PROHIBITED   >>  00045000
<<     WITHOUT THE PRIOR WRITTEN CONSENT OF HEWLETT-PACKARD COMPANY.>>  00050000
<< **** Note - Dollar Copyright cannot be used with this module *** >>  00055000
$CONTROL MAIN=IOFDISC0                                                  00060000
$CONTROL PRIVILEGED,UNCALLABLE                                          00065000
$TITLE "2660A FIXED HEAD DISC DRIVER"                                   00070000
$THIRTY                                                                 00075000
                                                                        00080000
DRIVER CALLING SEQUENCE                                                 00085000
                                                                        00090000
                                                                        00095000
DRIVER REQUEST CODES:                                                   00100000
                                                                        00105000
   0 - READ                                                             00110000
   1 - WRITE                                                            00115000
   2 - FILE OPEN                                                        00120000
   3 - FILE CLOSE                                                       00125000
   4 - DEVICE CLOSE                                                     00130000
   5 - FILL WITH ZEROS                                                  00135000
   6 - FILL WITH BLANKS                                                 00140000
  11 - WRITE DISC LABEL                                                 00145000
                                                                        00150000
                                                                        00155000
COUNT - WORD/BYTE COUNT. BYTE COUNT WILL BE ROUNDED UP TO AN EVEN #     00160000
                                                                        00165000
                                                                        00170000
PARAMETERS P1 AND P2 FORM A DOUBLE WORD DISC ADRESS. P1 MUST ALWAYS     00175000
BE ZERO.                                                                00180000
                                                                        00185000
                                                                        00190000
NOTE THAT THE BUFFER ADRESS WORD IN THE IOQ IS USED AS THE              00195000
BUFFER FOR ALL FILL OPERATIONS.                                         00200000
                                                                        00205000
                                                                        00210000
DRIVER RETURN CODES:                                                    00215000
                                                                        00220000
   GENERAL STATUS             QUALIFYING STATUS          OVERALL        00225000
   0 - PENDING                1 - WAIT FOR COMPLETION    %10            00230000
                                                                        00235000
   1 - SUCCESSFUL             0 - NORMAL COMPLETION      %01            00240000
                                                                        00245000
   4 - IRRECOVERABLE ERROR    0 - INVALID FUNCTION       %04            00250000
                              1 - DISC TRANSMISSION ERR  %14            00255000
                              3 - I/O TRANSMISSION ERROR %34            00260000
                              5 - DISC UNIT FAILURE      %54            00265000
                              6 - INVALID DISC ADRESS    %64            00270000
$PAGE                                                                   00275000
BEGIN                                                                   00280000
EQUATE                                                                  00285000
   CHAINFILL   = %167777,                                               00290000
   CHAINRD     = %170000,                                               00295000
   CHAINWRT    = %160000,                                               00300000
   CONTROL     = %040000,                                               00305000
   CONTROL1    = %040001, << SELECT SECTOR ONE >>                       00310000
   DATAOVERUN  = %34, << STATUS RETURN, I/O XFER TOO SLOW >>            00315000
   DDADR       = 11, << DISC ADRESS OF FILL IN DIT >>                   00320000
   DLOGERROR   = 13,  << ERROR LOG STATUS>>                    <<01337>>00325000
   DSERR       = 7, << ERROR DEVICE STATUS WORD IN DIT >>               00330000
   DSTAT       = 6, << HARDWARE DEVICE STATUS WORD IN DIT >>            00335000
   DSYSBA      = 12, << SYSTEM BUFFER ADRESS IN DIT >>                  00340000
   DXFER       = 10, << FILL TRANSFER COUNT IN DIT >>                   00345000
   ENDINT      = %034000,                                               00350000
   FILL        = %067777,                                               00355000
   INVDISCADR  = %64, << STATUS RETURN, BAD DISC ADRESS >>              00360000
   INVALIDFUNC = 4, << STATUS RETURN, INVALID OPERATION REQUESTED >>    00365000
   PENDING     = %10, << STATUS RETURN, I/O STARTED BUT NOT FINISHED >> 00370000
   QADDR       = 5, << BUFFER ADRESS WORD OF IOQ >>                     00375000
   QFUNC       = 6, <<FUNCTION CODE WORD OF IOQ >>                      00380000
   QLDEV       = 2, << LOGICAL DEVICE NUMBER WORD OF IOQ >>             00385000
   QMISC       = 3, << DRIVER WORD OF IOQ >>                            00390000
   QPAR1       = 8, << HIGH ORDER DISC ADRESS WORD OF IOQ >>            00395000
   QPAR2       = 9, << LSW DISC ADRESS OF IOQ >>                        00400000
   QSTAT       = 10, <<RETURN STATUS WORD OF IOQ >>                     00405000
   QWBCT       = 7,  << XFER COUNT WORD OF IOQ >>                       00410000
   READ128     = %077600,                                               00415000
   SIORD       = %070000,                                               00420000
   SIOWRT      = %060000,                                               00425000
   SYSDB       = %1000,                                                 00430000
   SYSSBUF     = 6, << DB INDEX OF SYSTEM BUFFER TABLE POINTER >>       00435000
   TRANSERR    = %14, << STATUS RETURN, DISC TRACK XFER ERROR >>        00440000
   UNITFAIL    = %54, << STATUS RETURN, DISC DEVICE PROBLEMS >>         00445000
   WRITE128    = %067600,                                               00450000
   XFER128     = %007600,                                               00455000
   SUCCESS     = 1; << STATUS RETURN, SUCCESSFUL XFER >>                00460000
DEFINE                                                                  00465000
   BN          = (14:2)#, << BANK NUM. BITS OF MEM. MANAGEMENT I/O REQ>>00470000
   BADTRK      = (0:1)#,<< BAD TRACK TABLE USE BIT IN QMISC >>          00475000
   CRCERR      = (4:1)#, << CRC ERROR BIT OF DEVICE STATUS >>           00480000
   DISABLE     = ASSEMBLE(SED 0)#,                                      00485000
   DISCERR     = (3:7)#, << HARDWARE ERROR STATUS BITS OF QSTAT >>      00490000
   DUPLICATE   = ASSEMBLE(DUP)#,                                        00495000
   ENABLE      = ASSEMBLE(SED 1)#,                                      00500000
   FUNC        = (8:8)#, << FUNCTION FIELD OF QFUNC >>                  00505000
   INDEXF      = (3:13)#, << DST INDEX FIELD OF MEM. LINK >>            00510000
   LIMIT       = (10:1)#, << RESTRICT I/O ACTIVITY BIT IN DIT >>        00515000
   QLDEVN      = (8:8)#, << LOGICAL DEVICE NUM. FIELD OF IOQ >>         00520000
   RETRYCNT    = (12:4)#, << RETRY COUNTER FIELD OF QMISC >>            00525000
   SECTOR      = (11:5)#, << SECTOR FIELD OF DISC ADRESS >>             00530000
   SFAIL       = (10:1)#, << GIP FAILED TO START I/O >>                 00535000
   SPEC        = (1:1)#, << IOQ BIT INDICATING A MEMORY MAN. REQ. >>    00540000
   STAT        = (8:8)#,  << I/O STATUS RETURN FIELD OF IOQ >>          00545000
   SYSBUFR     = (3:1)#,  << IOQ BIT. DATA IS IN SYSTEM BUFFERS >>      00550000
   TRACK       = LSR(5)#,                                               00555000
   WRITEBIT    = (1:1)#,<< BAD TRACK HAS BEEN RETURNED TO DISC (QMISC)>>00560000
   XFERERR     = (6:1)#; << HARDWARE STATUS BIT IN DSTAT >>             00565000
INTEGER POINTER                                                         00570000
   SBUF = DB+ SYSSBUF; << SYSBUF TABLE POINTER >>                       00575000
ARRAY INITIAL(0:39) = DB := << INITIAL CONFIGURATION DATA >>   <<01337>>00580000
   %007041, << DIT SIZE = 14, CORE RES., DVR TYPE = 1 >>       <<01337>>00585000
         0,                                                             00590000
         0, << UNIT EXTRACT INSTRUCTION >>                              00595000
   [8/%13,8/0],  <<I/O PROG AREA = 22 >>                       <<01300>>00600000
   %040000,   <<DFLAG>> <<DIT WORD 0 - DEVICE IS A DISC>>      <<01337>>00605000
        0,    <<DLINK>>                                        <<01337>>00610000
        0,    <<DIOQP>>                                        <<01337>>00615000
        0,    <<DLDEV>>                                        <<01337>>00620000
        0,    <<DLTP>>                                         <<01337>>00625000
        0,    <<DILTP>>                                        <<01337>>00630000
        0,    <<DSTAT>>                                        <<01337>>00635000
        0,    <<DSERR>> <<INDEX & COUNT OF HARWARE STATUS>>    <<01337>>00640000
        0,    <<DMAMQT>>                                       <<01337>>00645000
        0,    <<DMAMQT>>                                       <<01337>>00650000
        0,    <<DXFER>>                                        <<01337>>00655000
        0,    <<DDADR>>                                        <<01337>>00660000
        0,    <<DSYSBA>>                                       <<01337>>00665000
        0,    <<DLOGERROR>>                                    <<01337>>00670000
   %014000, << I/O PROG AREA - SET BANK >>                              00675000
         0,                                                             00680000
     20(0); << REST OF I/O PROG AREA >>                                 00685000
$PAGE                                                                   00690000
PROCEDURE CHECKINDEX(INDEX,TABLE);                                      00695000
VALUE INDEX,TABLE;                                                      00700000
INTEGER INDEX;                                                          00705000
INTEGER POINTER TABLE;                                                  00710000
OPTION EXTERNAL;                                                        00715000
                                                                        00720000
PROCEDURE DCONVERT(WORD); VALUE WORD; INTEGER WORD;                     00725000
   OPTION EXTERNAL;                                                     00730000
                                                                        00735000
INTEGER PROCEDURE GETSBUF(TYPE); VALUE TYPE; INTEGER TYPE;              00740000
   OPTION EXTERNAL;                                                     00745000
                                                                        00750000
PROCEDURE GIP; OPTION EXTERNAL;                                         00755000
                                                                        00760000
PROCEDURE HELP; OPTION EXTERNAL;                                        00765000
                                                                        00770000
PROCEDURE IOFAILURE(DRTN,DITP);                                         00775000
VALUE DRTN,DITP;                                                        00780000
LOGICAL DRTN;                                                           00785000
POINTER DITP;                                                           00790000
OPTION EXTERNAL;                                                        00795000
                                                                        00800000
PROCEDURE LDEVNOTRDY(DITP);  VALUE DITP; POINTER DITP;                  00805000
OPTION EXTERNAL;                                                        00810000
                                                                        00815000
PROCEDURE MMSTAT(E,P1,P2,P3);                                           00820000
   VALUE E,P1,P2,P3;                                                    00825000
   INTEGER E,P1,P2,P3;                                                  00830000
   OPTION EXTERNAL;                                                     00835000
                                                                        00840000
PROCEDURE RETURNSBUF(SBUFP); VALUE SBUFP; INTEGER SBUFP;                00845000
   OPTION EXTERNAL;                                                     00850000
                                                                        00855000
PROCEDURE SIODM(A,B); VALUE A,B; INTEGER POINTER A; LOGICAL B;          00860000
OPTION EXTERNAL;                                                        00865000
                                                                        00870000
PROCEDURE STARTIO(DITP,SIOP,QUEUE); VALUE DITP,SIOP,QUEUE;              00875000
   INTEGER POINTER DITP,SIOP; LOGICAL QUEUE;                            00880000
   OPTION EXTERNAL;                                                     00885000
                                                                        00890000
PROCEDURE WRITE2(WORD); VALUE WORD; INTEGER WORD;                       00895000
   OPTION EXTERNAL;                                                     00900000
$PAGE                                                                   00905000
INTEGER PROCEDURE FHDDVR(IOQP,DITP,BANK,BUFADR,SIOP,DRTN);              00910000
VALUE IOQP,DITP,BANK,BUFADR,SIOP,DRTN;                                  00915000
INTEGER BANK,BUFADR,DRTN;                                               00920000
INTEGER POINTER IOQP,DITP,SIOP;                                         00925000
OPTION PRIVILEGED,UNCALLABLE;                                           00930000
BEGIN                                                                   00935000
DOUBLE POINTER                                                          00940000
   DSIOP = SIOP;                                                        00945000
INTEGER POINTER                                                         00950000
   BADTRACK = Q+1;                                                      00955000
LOGICAL                                                                 00960000
   CONC = Q+3,                                                          00965000
   SIOCOUNT = DB+%60;                                                   00970000
INTEGER                                                                 00975000
   I = Q+2,                                                             00980000
   X = X,                                                               00985000
   MSTATE = FHDDVR,                                                     00990000
   S0 = S-0;                                                            00995000
LOGICAL POINTER                                                         01000000
   DITPL = DITP,                                                        01005000
   IOQPL = IOQP;                                                        01010000
                                                                        01015000
                                                                        01020000
   TOS := 0; << BADTRACK >>                                             01025000
   TOS := 2; << I >>                                                    01030000
   IF MSTATE = 2 THEN                                                   01035000
   BEGIN << START NEW REQUEST, INITIATON SECTION >>                     01040000
      IOQP(QMISC) := 0;                                                 01045000
      TOS := IOQP(QWBCT); << SET XFER COUNT >>                          01050000
      IF < THEN                                                         01055000
      BEGIN << BYTE COUNT >>                                            01060000
         DUPLICATE;                                                     01065000
         IF TOS THEN IOQP(X) := IOQP(X) - 1; <<ROUND UP COUNT >>        01070000
         TOS := -(TOS&ASR(1)); << CONVERT TO POS. WORD COUNT >>         01075000
      END;                                                              01080000
      DITP(DXFER) := TOS;                                               01085000
      IF IOQP(QPAR1) <> 0 THEN                                          01090000
      BEGIN << DISC ADRESS TOO LARGE >>                                 01095000
BADDADR:                                                                01100000
         TOS := INVDISCADR;                                             01105000
         GO TO BADEND;                                                  01110000
      END;                                                              01115000
      TOS := BANK;                                                      01120000
      SIOP(1) := TOS; << DO SET BANK I/O INST. >>                       01125000
      IF IOQP(QFUNC).FUNC = 7 THEN GO TO INVALID;              <<02870>>01130000
      TOS := IF IOQP(QFUNC).FUNC = 11 THEN 7                   <<02870>>01135000
        ELSE IOQP(QFUNC).FUNC;                                 <<02870>>01140000
      ASSEMBLE(DUP,STAX);                                               01145000
      IF TOS > 7 THEN                                          <<02870>>01150000
      BEGIN << INVALID FUNCTION >>                                      01155000
INVALID:                                                                01160000
         TOS := INVALIDFUNC;                                            01165000
         GO TO BADEND;                                                  01170000
      END;                                                              01175000
      ASSEMBLE(LOAD SWT,X; ADAX; BR SWT,X;                              01180000
SWT:                                                                    01185000
      CON READ; CON WRITE; CON GOODEND; CON GOODEND; CON GOODEND;       01190000
      CON FILLZERO; CON FILLBLANK; CON WRITE);                 <<02870>>01195000
                                                                        01200000
      HELP;                                                             01205000
                                                                        01210000
WRITE:                                                                  01215000
      TOS := CHAINWRT; << SET WRITE CONSTANTS >>                        01220000
      GO TO WRITECONT;                                                  01225000
                                                                        01230000
READ:                                                                   01235000
      TOS := CHAINRD;                                                   01240000
WRITECONT:                                                              01245000
      TOS := IOQP(QPAR2);                                               01250000
      IF = AND (1 <= IOQP(QFUNC) <= 6) THEN GO TO BADDADR;     <<02870>>01255000
      TOS := TOS.SECTOR LOR CONTROL;                                    01260000
      TOS := IOQP(QPAR2)&TRACK;                                         01265000
      DSIOP(1) := TOS; << SET DISC ADRESS >>                            01270000
      TOS := DITP(DXFER);                                               01275000
      IF = THEN GO TO GOODEND; << ZERO XFER CNT IS A NO OP >>           01280000
      DUPLICATE;                                                        01285000
      IF IOQPL.SYSBUFR THEN                                             01290000
      BEGIN << DATA IS IN SYSTEM BUFFERS >>                             01295000
         IF S0 > 1024 THEN GO TO INVALID; << XFER TOO BIG >>            01300000
         CONC := CONC LOR XFER128; << AJUST XFER ORDERS >>              01305000
         CHECKINDEX(@SBUF + SYSDB - BUFADR,SBUF);                       01310000
         WHILE TOS > 128 DO                                             01315000
         BEGIN << BUILD SERIES OF CHAINED ORDERS >>                     01320000
            TOS := TOS - 128;                                           01325000
            TOS := CONC;                                                01330000
            TOS := BUFADR;                                              01335000
            DSIOP(I) := TOS;                                            01340000
            I := I + 1;                                                 01345000
            CHECKINDEX(ABSOLUTE(BUFADR-1),SBUF);                        01350000
            BUFADR := ABSOLUTE(X) + @SBUF + SYSDB;                      01355000
            DUPLICATE;                                                  01360000
         END;                                                           01365000
      END ELSE                                                          01370000
      BEGIN                                                             01375000
         X := I;                                                        01380000
         WHILE TOS > 4096 DO                                            01385000
         BEGIN << DATA IN DST, BUILD SERIES OF CHAINED ORDERS >>        01390000
            TOS := TOS - 4096;                                          01395000
            TOS := CONC;                                                01400000
            TOS := BUFADR;                                              01405000
            DSIOP(X) := TOS;                                            01410000
            ASSEMBLE(INCX,DUP);                                         01415000
            BUFADR := BUFADR + 4096;                                    01420000
         END;                                                           01425000
         I := X;                                                        01430000
      END;                                                              01435000
      TOS := ((-TOS) LAND %7777) LOR (CONC LAND %070000);               01440000
      TOS := BUFADR;                                                    01445000
      DSIOP(I) := TOS;                                                  01450000
ENDIO:                                                                  01455000
      I := I + 1;                                                       01460000
      TOS := ENDINT; << APPEND END I/O ORDER >>                         01465000
      TOS := -1;                                                        01470000
      DSIOP(I) := TOS;                                                  01475000
EXECIO:                                                                 01480000
      STARTIO(DITP,SIOP,TRUE);                                          01485000
      IF > THEN                                                         01490000
      BEGIN << DEVICE NOT READY    >>                                   01495000
NOTREADY:                                                               01500000
         LDEVNOTRDY(DITP); << SENT NOT READY MSG TO CONSOLE >>          01505000
         TOS := DRTN;                                                   01510000
         TOS := %100000;                                                01515000
         ASSEMBLE(CIO 1); << CLEAR INTERFACE >>                         01520000
         IF <> THEN GO TO IOFAIL;                                       01525000
WAIT:                                                                   01530000
         ASSEMBLE(TIO 0);                                               01535000
         IF <> THEN GO TO IOFAIL;                                       01540000
         ASSEMBLE(TEST,DEL);                                            01545000
         IF >= THEN GO TO WAIT;                                         01550000
         DEL;                                                           01555000
         GO TO EXECIO; << TRY AGAIN WHEN DISC IS READY >>               01560000
      END;                                                              01565000
      MSTATE := %13;                                                    01570000
      TOS := PENDING;                                                   01575000
      GO TO DONE;                                                       01580000
                                                                        01585000
FILLBLANK:                                                              01590000
      TOS := "  ";                                                      01595000
      GO TO FC;                                                         01600000
                                                                        01605000
FILLZERO:                                                               01610000
      TOS := 0;                                                         01615000
FC:                                                                     01620000
      IOQP(QADDR) := TOS; << SAVE FILL WORD IN ADRESS WORD OF IOQ >>    01625000
      DITP(DDADR) := IOQP(QPAR2); << PUT DISC ADR. INTO DIT >>          01630000
FILLCONT:                                                               01635000
      TOS := DITP(DXFER);                                               01640000
      DUPLICATE;                                                        01645000
      IF <= THEN GO TO GOODEND; << ALL DONE >>                          01650000
      TOS := DITPL(DDADR).SECTOR LOR CONTROL;                           01655000
      TOS := DITP(X)&TRACK;                                             01660000
      DITP(X) := DITP(X) + 8; << UPDATE DISC ADRESS >>                  01665000
      DSIOP(1) := TOS; << ENTER DISC ADRESS >>                          01670000
      BUFADR := @IOQP(QADDR) + SYSDB; << SET FILL ADRESS >>             01675000
      X := I;                                                           01680000
      WHILE X < 9 AND TOS > 128 DO                                      01685000
      BEGIN << BUILD SERIES OF CHAINED FILL ORDERS >>                   01690000
         TOS := TOS - 128;                                              01695000
         TOS := CHAINFILL;                                              01700000
         TOS := BUFADR;                                                 01705000
         DSIOP(X) := TOS;                                               01710000
         ASSEMBLE(INCX,DUP);                                            01715000
      END;                                                              01720000
      TOS := FILL;                                                      01725000
      TOS := BUFADR;                                                    01730000
      DSIOP(X) := TOS;                                                  01735000
      I := X;                                                           01740000
      DITP(DXFER) := TOS - 128;                                         01745000
      GO TO ENDIO;                                                      01750000
   END ELSE                                                             01755000
   BEGIN << CONTINUATOR SECTION >>                                      01760000
      IOQP.SFAIL := 0;                                                  01765000
      IF <> THEN GO TO NOTREADY;                                        01770000
      IF DITP(DSTAT).DISCERR = 0 THEN                                   01775000
      BEGIN << NO ERROR >>                                              01780000
         IF IOQPL(QMISC).BADTRK THEN                                    01785000
         BEGIN << GOT THE BAD TRACK TABLE IN A SYSBUF >>                01790000
            IOQP(X).WRITEBIT := 1;                                      01795000
            IF <> THEN                                                  01800000
            BEGIN << HAVE COMPLETED RETURN OF BTT TO DISC >>            01805000
RETURNSB:                                                               01810000
               RETURNSBUF(DITP(DSYSBA));                                01815000
BADRETRY:                                                               01820000
               TOS:= DITP(DLOGERROR)&LSL(4);<<EXAMINE STATUS>> <<01408>>01825000
               IF < THEN                                                01830000
               BEGIN << DISC CRC ERROR >>                               01835000
                  TOS := TRANSERR;                                      01840000
BADEND:                                                                 01845000
                  IOQP(QWBCT) := 0;  << ZERO TRANSFER COUNT >>          01850000
                  GO TO BADCONT;                                        01855000
               END;                                                     01860000
               TOS := TOS&LSL(2);                                       01865000
               IF < THEN                                                01870000
               BEGIN << I/O TRANSFER ERROR >>                           01875000
                  TOS := DATAOVERUN;                                    01880000
                  GO TO BADEND;                                         01885000
               END;                                                     01890000
               TOS := TOS&LSL(1);                                       01895000
               IF < THEN                                                01900000
               BEGIN << TRACK ADRESS TO BIG >>                          01905000
                  TOS := INVDISCADR;                                    01910000
                   GO TO BADEND;                                        01915000
               END;                                                     01920000
               TOS := UNITFAIL;                                         01925000
               GO TO BADEND;                                            01930000
            END ELSE                                                    01935000
            BEGIN << HAVE READ BTT, UPDATE AND RETURN >>                01940000
               TOS := DITP(DDADR)&LSL(2); << BAD TRACK # >>             01945000
               I := 0;                                                  01950000
               @BADTRACK := DITP(DSYSBA);                               01955000
               WHILE I < BADTRACK DO                                    01960000
               BEGIN << SEE IF BAD TRACK IS ALREADY IN THE TABLE >>     01965000
                  DUPLICATE;                                            01970000
                  IF TOS = BADTRACK(I := I + 1) THEN GO TO RETURNSB;    01975000
               END;                                                     01980000
               IF BADTRACK > 120 THEN GO TO RETURNSB;                   01985000
               TOS := BADTRACK;                                         01990000
               ASSEMBLE(INCA,DUP; STAX);                                01995000
               BADTRACK := TOS;                                         02000000
               BADTRACK(X) := TOS; <<ENTER BAD TRACK INTO TABLE >>      02005000
               SIOP(4) := WRITE128;                                     02010000
               GO TO EXECIO;                                            02015000
            END;                                                        02020000
         END ELSE                                                       02025000
         BEGIN << NO BAD TRACK, NORMAL COMPLETION >>                    02030000
            IF IOQP(QFUNC).FUNC >= 5 AND                       <<02870>>02035000
              IOQP(QFUNC).FUNC <> 11 THEN GO TO FILLCONT;      <<02870>>02040000
GOODEND:                                                                02045000
            TOS := SUCCESS;                                             02050000
BADCONT:                                                                02055000
            MSTATE := 5;                                                02060000
DONE:                                                                   02065000
            IOQP(QSTAT).STAT := TOS; << SET RETURN STATUS >>            02070000
            RETURN;                                                     02075000
         END;                                                           02080000
      END ELSE                                                          02085000
      BEGIN << HAD A DISC ERROR, RETRY XFER >>                          02090000
         DITP(DSERR):= [8/1,8/DLOGERROR];<<LOG COUNT & INDEX>> <<01337>>02095000
         DITP(DLOGERROR):= DITP(DSTAT);   <<LOG ERROR>>        <<01337>>02100000
         TOS := IOQP(QMISC); << INC RETRY CNT >>                        02105000
         ASSEMBLE(INCA,DUP);                                            02110000
         MMSTAT(100,DITP(DSTAT),S0,                                     02115000
         IOQPL(QLDEV).QLDEVN LOR SIOCOUNT&LSL(8));                      02120000
         IOQP(QMISC) := TOS;                                            02125000
         IF TOS.RETRYCNT < 10 THEN GO TO EXECIO;                        02130000
         IF NOT DITPL(DLOGERROR).CRCERR THEN GO TO BADRETRY;   <<01408>>02135000
         << DO BAD TRACK ONLY ON CRC ERROR >>                           02140000
         TOS := IOQP(QMISC); << DO BAD TRACK STUFF >>                   02145000
         TOS := TOS LAND -16; << ZERO RETRY CNT FIELD >>                02150000
         TOS.BADTRK := 1;                                               02155000
         IOQP(X) := TOS;                                                02160000
         IF <> THEN GO TO BADRETRY; << FAILED ON BTT >>                 02165000
         SIOP(1) := 0; << ZERO BANK # >>                                02170000
         TOS := CONTROL1;                                               02175000
         TOS := 0;                                                      02180000
         DSIOP(1) := TOS; << READ IN THE BAD TRACK TABLE >>             02185000
         TOS := READ128;                                                02190000
         TOS := GETSBUF(1);                                             02195000
         DUPLICATE;                                                     02200000
         IF = THEN GO TO BADRETRY;                                      02205000
         DITP(DSYSBA) := TOS;                                           02210000
         TOS := TOS + SYSDB;                                            02215000
         DSIOP(2) := TOS;                                               02220000
         TOS := DRTN;                                                   02225000
         TOS := 2;                                                      02230000
         ASSEMBLE(CIO 1; BL *-1; TIO 0; BL *-1);                        02235000
         DITP(DDADR) := TOS; << SAVE THE BAD TRACK # >>                 02240000
         TOS := 0;                                                      02245000
         ASSEMBLE(CIO 1); << RESET STATUS TO STAT 0 >>                  02250000
         GO TO ENDIO;                                                   02255000
      END;                                                              02260000
   END;                                                                 02265000
IOFAIL:                                                                 02270000
   IOFAILURE(DRTN,DITP); << SENT FAILURE MESSAGE AND DIE >>             02275000
END;                                                                    02280000
   ASSEMBLE(                                                            02285000
      PCAL SIODM; << MONITOR >>                                         02290000
      PCAL FHDDVR; << INITIATOR >>                                      02295000
      PCAL FHDDVR; << COMPLETOR >>                                      02300000
      CON 0; << I/O PROCESS PROCEDURE >>                                02305000
      CON 0; << INITIALIZATION PROCEDURE >>                             02310000
      CON 1; << # OF INTERRUPT HANDLERS >>                              02315000
      PCAL GIP); << INTERRUPT HANDLER >>                                02320000
END.                                                                    02325000
