$CONTROL MAP,CODE,USLINIT                                               00010000
  <<    IOMDISC1,MODULE 27 - 7905/7906/7920/7925 DISC DRIVER    TP>>    00012000
<< HP32002C MPE SOURCE C.00.00 >>                                       00014000
<< COPYRIGHT     "(C) COPYRIGHT HEWLETT-PACKARD CO. 1980.           >>  00016000
<<     THIS PROGRAM MAY BE USED WITH ONE COMPUTER SYSTEM AT A       >>  00018000
<<     TIME AND SHALL NOT OTHERWISE BE RECORDED, TRANSMITTED OR     >>  00020000
<<     STORED IN A RETRIEVAL SYSTEM.  COPYING OR OTHER REPRODUCTION >>  00022000
<<     OF THIS PROGRAM EXCEPT FOR ARCHIVAL PURPOSES IS PROHIBITED   >>  00024000
<<     WITHOUT THE PRIOR WRITTEN CONSENT OF HEWLETT-PACKARD COMPANY.>>  00026000
<< **** Note - Dollar Copyright cannot be used with this module *** >>  00028000
$CONTROL PRIVILEGED,UNCALLABLE,MAIN=IOMDISC1                            00030000
$TP                                                                     00032000
$TITLE "7905/7906/7920/7925 MOVING HEAD DISC DRIVER"           <<03069>>00034000
                                                                        00036000
DRIVER CALLING SEQUENCE                                                 00038000
                                                                        00040000
   DRIVER REQUEST CODES                                                 00042000
     0 - READ                                                           00044000
     1 - WRITE                                                          00046000
     2 - FILE OPEN                                                      00048000
     3 - FILE CLOSE                                                     00050000
     4 - DEVICE CLOSE                                                   00052000
     5 - FILL WITH ZEROS                                                00054000
     6 - FILL WITH BLANKS                                               00056000
     7 - REQUEST STATUS                                                 00058000
           TO BE COMPATIBLE WITH SERIES III, STATUS REQUEST WILL        00060000
           CHECK TO SEE IF LAST TRANSFER TO THE UNIT FOR WHICH          00062000
           THIS REQUEST IS FOR, ENDED IN AN ERROR. IF LAST TRANSFER     00064000
           DID END IN AN ERROR, THEN THE STATUS FROM THAT TRANSFER      00066000
           WILL BE TRANSFERRED, OTHERWISE A NEW STATUS REQUEST WILL     00068000
           BE GENERATED AND THAT STATUS RETURNED.                       00070000
     8 - FORMAT TRACK                                                   00072000
     9 - INITIALIZE TRACK                                               00074000
    10 - READ FULL SECTOR                                               00076000
    11 - WRITE LABEL (SECTOR 0)                                         00078000
    12 - READ (WITH SPARING DISABLED)                                   00080000
    15 - REQUEST STATUS (SAME AS FUNCTION CODE 7)                       00082000
                                                                        00084000
   COUNT - WORD/BYTE COUNT. ODD BYTE COUNT WILL BE ROUNDED UP.          00086000
                                                                        00088000
   PARAMETERS P1 AND P2 FORM A DOUBLE WORD DISC ADRESS FOR ALL XFERS.   00090000
                                                                        00092000
DRIVER RETURN CODES                                                     00094000
                                                                        00096000
   GENERAL(13:3)        QUALIFYING(8:5)               OVERALL(8:8)      00098000
   0 - PENDING          1 - WAIT FOR COMPLETION       %10               00100000
   1 - SUCCESSFUL                                     %01               00102000
   4 - IRRECOVERABLE    0 - INVALID FUNCTION          %04               00104000
       ERROR            1 - TRACK ERROR               %14               00106000
                        3 - XMISSION ERROR            %34               00108000
                        4 - SIO FAILURE               %44               00110000
                        5 - UNIT FAILURE              %54               00112000
                        6 - INVALID DISC ADRESS       %64               00114000
                        %12 - SYSTEM ERROR            %124              00116000
                        %14 - CHANNEL ERROR           %144              00118000
                                                                        00120000
DISC CONTROLLER HARDWARE STATUS RETURNS                                 00122000
                                                                        00124000
   STATUS 1                                                             00126000
   BITS     USE                                                         00128000
      0      SPARE TRACK                                                00130000
      1      PROTECTED TRACK                                            00132000
      2      DEFECTIVE TRACK                                            00134000
   3-7      TERMINATION STATUS                                          00136000
               0 - NORMAL COMPLETION                                    00138000
               1 - ILLEGAL COMMAND                                      00140000
               7 - CYL COMPARE ERROR                                    00142000
             %10 - UNCORRECTABLE DATA ERROR                             00144000
             %11 - HEAD-SECTOR COMPARE ERROR                            00146000
             %12 - SIO PROGRAM ERROR                                    00148000
             %14 - END OF CYLINDER                                      00150000
             %16 - OVERRUN                                              00152000
             %17 - POSSIBLY CORRECTABLE DATA ERROR                      00154000
             %20 - ILLEGAL ACCESS TO SPARE TRACK                        00156000
             %21 -  ATTEMPT TO ACCESS DEFECTIVE TRACK                   00158000
             %22 - HEAD MOVEMENT DURING DATA OPERATION                  00160000
             %23 - DISC DRIVE (STATUS-2) ERROR                          00162000
             %26 - ATTEMPT TO WRITE ON PROTECTED TRACK                  00164000
             %27 - DRIVE UNAVAILABLE                                    00166000
             %37 - DRIVE ATTENTION                                      00168000
   8-12      UNUSED                                                     00170000
  13-15      UNIT NUMBER                                                00172000
                                                                        00174000
                                                                        00176000
                                                                        00178000
   STATUS 2 WORD                                                        00180000
      0      DRIVE ERROR                                                00182000
    6-9      DRIVE TYPE                                                 00184000
      8      ATTENTION                                                  00186000
      9      PROTECTED                                                  00188000
     10      FORMAT                                                     00190000
     11      FAULT                                                      00192000
     12      FIRST STATUS                                               00194000
     13      SEEK CHECK                                                 00196000
     14      DRIVE NOT READY                                            00198000
     15      DRIVE BUSY                                                 00200000
                                                                        00202000
***********************************************************    <<03069>>00204000
*         D I T   L A Y O U T                             *    <<03069>>00206000
***********************************************************    <<03069>>00208000
* Word * Variable Name * Description                      *    <<03069>>00210000
***********************************************************    <<03069>>00212000
* 0    * DFLAG         * (0:2) = 1 for disc               *    <<03069>>00214000
*      *               * (3:1) Set if SIODM is svcing     *    <<03069>>00216000
*      *               * (5:1) Set because this is multi  *    <<03069>>00218000
*      *               *       unit controller            *    <<03069>>00220000
*      *               * (7:1) SIOP active for this device*    <<03069>>00222000
*      *               * (8:1) Interrupt occured for dev  *    <<03069>>00224000
*      *               * (9:1) Set because moving head    *    <<03069>>00226000
*      *               * (12:4) SIODM state               *    <<03069>>00228000
* 1    * DLINK         * SYSDB pntr to next DIT in        *    <<03069>>00230000
*      *               * controller queue                 *    <<03069>>00232000
* 2    * DIOQP         * Current (active) disc request    *    <<03069>>00234000
* 3    * DLDEV         * (0:3) = 2 for HP-IB              *    <<03069>>00236000
*      *               * (8:8) = logical device number    *    <<03069>>00238000
* 4    * DDLTP         * SYSDB ptr to Driver Linkage Tbl  *    <<03069>>00240000
* 5    * DILTP         * SYSDB ptr to Interrupt Lnk Tbl   *    <<03069>>00242000
* 6    * DRQST         * Set to -1 when powerfail         :    <<03069>>00244000
* 7    * DSERR         * (0:8)-# of words to log          *    <<03069>>00246000
*      *               * (8:8)-DIT relative address to log*    <<03069>>00248000
* 8    * DMAMQ         * Ptr to head of disc requests     *    <<03069>>00250000
* 9    * DMAMQT        * Ptr to tail of disc requests     *    <<03069>>00252000
* 10-11* CLDA          * Current logical sector address   *    <<03069>>00254000
* 12-13* CPDA          * Current physical disc adr (C/H/S)*    <<03069>>00256000
* 14   * CDBA          * Current buffer address           *    <<03069>>00258000
* 15   * WCR           * Word cnt remaining to XFER       *    <<03069>>00260000
* 16   * CWC           * Word cnt to xfer                 *    <<03069>>00262000
* 17   * SYSBUFA       * Sys buffer address used to pro-  *    <<03069>>00264000
*      *               * cess defective track             *    <<03069>>00266000
* 18   * STAT1         * Status-1 return                  *    <<03069>>00268000
* 19   * STAT2         * Status-2 return                  *    <<03069>>00270000
* 20-21* CEDA          * Phys address of error on disc    *    <<03069>>00272000
* 22-28* REQSYN        * Request syndrome area            :    <<03069>>00274000
* 29   * SCOUNT        * Sector count to transfer         *    <<03069>>00276000
* 30-31* INITADR       * Phys adr to init track to        *    <<03069>>00278000
* 32   * DMISC         * (15:1)=L'STAT'ERR (last err stat)*    <<03069>>00280000
* 33-34* SEEKSTAT      * Cntlr status after seek in chanp *    <<03069>>00282000
* 35   * DLOGERROR     * CPVA word 0 upon channel abort   *    <<03069>>00284000
* 36   * DSIOP         * SIO program-relative abort addr  *    <<03069>>00286000
***********************************************************    <<03069>>00288000
                                                               <<03069>>00290000
IOQ (Disc Request) element QMISC-                              <<03069>>00292000
                                                               <<03069>>00294000
DBIT    (0:1)   Retry is in progress                           <<03069>>00296000
SBIT    (1:1)   Request syndrome is in progress                <<03069>>00298000
EBIT    (2:1)   Error bit (err has occurred)                   <<03069>>00300000
MBIT    (3:1)   Reading defective track table into SYSBUF      <<03069>>00302000
WBIT    (4:1)   Writing defective track table to disc          <<03069>>00304000
TIM'WT  (5:1)   Waiting for disc controller to power-up        <<03685>>00306000
CBIT    (7:1)   Recalibrate in progress                        <<03069>>00308000
CLBIT   (8:1)   Clear in progress                              <<03069>>00310000
RETRY   (13:3)  Retry count (7 max except for overrun)         <<03069>>00312000
                                                               <<03069>>00314000
***********************************************************    <<03069>>00316000
*           I L T   F O R M A T                           *    <<03069>>00318000
***********************************************************    <<03069>>00320000
* Word * Variable * Description                           *    <<03069>>00322000
***********************************************************    <<03069>>00324000
* 0-3  * CPVAx    * Channel program variable area         *    <<03069>>00326000
*      * ICPVA0   * 0 - Channel abort status              *    <<03069>>00328000
*      * ICPVA1   * 1 - Unusual termination error codes   *    <<03069>>00330000
*      * ICPVA2   * 2 - Normal termination codes          *    <<03069>>00332000
*      * ICPVA3   * 3 - Clear issued successfully         *    <<03069>>00334000
* 4-5  * ??       * DMA abort address                     *    <<03069>>00336000
* 6    * ICPGM    * Startio address to use on deferred    *    <<03069>>00338000
*      *          * START'HPIB.  Used when HIOP cannot be *    <<03069>>00340000
*      *          * completed immediatly.                 *    <<03069>>00342000
* 7    * ICNTRL   * (0:1) Software channel is being used  :    <<03069>>00344000
*      *          * (1:6) Channel queue number            *    <<03069>>00346000
*      *          * (7:2) IMB number                      *    <<03069>>00348000
*      *          * (9:4) Channel number                  *    <<03069>>00350000
*      *          * (13:3) Device number                  *    <<03069>>00352000
* 8    * ISIOP    * SYSDB ptr to channel pgm area         *    <<03069>>00354000
* 9    * ISTATP   * SYSDB ptr to 2-word status area       *    <<03069>>00356000
* 10   * IUNIT    * Unit extract instruction (ANDI 7)     *    <<03069>>00358000
* 11   * ICDP     * SYSDB ptr to currently active DIT     *    <<03069>>00360000
* 12   * IQUEUE   * (0:8) SIOP size/2                     *    <<03069>>00362000
*      *          * (8:8) Queue number                    *    <<03069>>00364000
* 13   * IFLAG    * (0:1) This device should have idle    *    <<03069>>00366000
*      *          *       chanp when there are no requests*    <<03069>>00368000
*      *          * (1:1) An idle chanp is active         *    <<03069>>00370000
*      *          * (2:1) Ignore interrupt from HIOP inst.*    <<03069>>00372000
*      *          * (3:1) Re-start chanp on HIOP interrupt*    <<03069>>00374000
*      *          * (10:1) Attention from another unit    *    <<03069>>00376000
*      *          * (11:5) Highest configured unit for   *     <<03074>>00378000
*      *          *        this device.                   *    <<03069>>00380000
* 14-21* IDITPx   * SYSDB ptrs to DITS, by unit number    *    <<03069>>00382000
* 22-23* ??       * Status area pnted to by word 9        *    <<03069>>00384000
* 24   *          * Seek mask (not used currently)        *    <<03069>>00386000
* 25-n * CHANP    * Channel program area pnted to by wd 8 *    <<03069>>00388000
***********************************************************    <<03069>>00390000
                                                               <<03069>>00392000
**************************************************************          00394000
            W  A  R  N  I  N  G                                         00396000
**************************************************************          00398000
                                                                        00400000
     The 7910 has a "feature" which                                     00402000
can cause errors to be incorrectly diagnosed.                           00404000
This "feature" is automatic address verication                          00406000
when a seek is issued.  The result is that a status                     00408000
returned after a seek completion(caused by either                       00410000
issuance of a seek command or by an automatic seek                      00412000
following a transfer at the end of a track) to a track                  00414000
which is defective,protected,or spared will indicate an                 00416000
error even if no data is transfered (the 7905/06/20/25                  00418000
interface                                                               00420000
will only return an error if a data transfer is attempted).             00422000
                                                                        00424000
     What this means is that whenever an error is returned,             00426000
some check should be made to be sure that the error                     00428000
did in fact occur in the area of the disc that the                      00430000
caller is transferring to(from).  It seems that to be                   00432000
absolutely sure that the error occured within the area                  00434000
of immediate concern, the disc address of the error                     00436000
should be obtained and compared with where the transfer                 00438000
should have ended.  However, in most cases, the byte                    00440000
count in the channel program can be checked to see if it                00442000
is zero(NOTE: this method may be used iff the channel program           00444000
allows this count to be updated by the I/O processor).                  00446000
                                                                        00448000
     This problem is made a little more cumbersome by                   00450000
the fact that the error returned depends on the type                    00452000
of seek which occurred (whether a seek was issued or                    00454000
an automatic seek by the controller).In the case of seeking             00456000
to a spare track, if the status is following a seek                     00458000
command, then the error returned is illegal access to a                 00460000
spare track.  However, if the status is following an                    00462000
automatic seek as a result of a transfer at the end of a                00464000
track, the error returned is different.  In the latter case             00466000
I think the error returned depends on the address field                 00468000
of the track to which the seek is done.  Since the cases                00470000
that I have encountered have zero in the address field for              00472000
spare tracks which are not assigned as alternates, the error I have     00474000
seen is cylinder miscompare error for this condition.                   00476000
                                                                        00478000
     Note that the HPIB interface for the 7905/06/20/25 disc            00480000
has a similar problem                                                   00482000
on buffered reads.  It does seem that the cases are more                00484000
limit than with the 7910.  The problem seems only to occur              00486000
on reads that would terminate within two                                00488000
sectors of a defective                                                  00490000
area or spare track.  Because data is buffered in advance of            00492000
the actual transfer, an error will be returned even                     00494000
though the error was not in the area of the disc of                     00496000
the requested transfer.  In this situation, it seems to                 00498000
be sufficient to check for a byte residue count of zero.                00500000
The addresses could also be compared to determine if the                00502000
error occured beyond the area of concern.                               00504000
                                                                        00506000
                                                                        00508000
**************************************************************          00510000
$PAGE                                                                   00512000
BEGIN                                                                   00514000
EQUATE                                                                  00516000
   ADRREC      = %006000, << ADRESS RECORD CMD >>                       00518000
   BADSIO      = %44,     << SIO FAILURE RETURN >>                      00520000
   CBIT'       = 7,       << RECALIBRATE BIT OF QMISC >>                00522000
   CDBA        = 14,      << CURRENT DATA BUF INDEX >>                  00524000
   CDERR       = %17,     << CORRECTABLE DATA ERROR CODE >>             00526000
   CDSJ        = %2400,   << DEVICE SPECIFIED JUMP>>                    00528000
   CDSJ2       = CDSJ+2,                                                00530000
   CEDA        = 10,      << CURRENT ERROR DISC ADR. INDEX >>           00532000
   CEDA1       = 20,      << CEDA INDEX (SINGLE) >>                     00534000
   CHANERR     = %144,    << CHANNEL PROGRAM ABORT ERROR >>             00536000
   CINTHLT    = %600,     <<CHANNEL INTERRUPT AND HALT>>                00538000
   CINTHLT1   = CINTHLT+1,                                              00540000
   CINTHLT2   = CINTHLT+2,                                              00542000
   CINTHLT3   = CINTHLT+3,                                              00544000
   CINTNHLT2  = %402,      << Interrupt with NO halt >>        <<03069>>00546000
   CLBIT'     = 8,        << CHANNEL CLEAR BIT >>                       00548000
   CLDA        = 5,       << CURRENT LOGICAL DISC ADR. INDEX >>         00550000
   CLEARC      = %4400,   << CHANNEL CLEAR COMMAND >>                   00552000
   CLEARISSUED = %100001, << VALUE PUT IN CPVA ON DSJ 2 >>              00554000
   CLRP        = 149,     << OFFSE TO CLEAR PROGRAM >>         <<03069>>00556000
   CJUMP       = %000000, << CHANNEL JUMP COMMAND >>                    00558000
   CMD         = 156,     <<OFFSET OF DISC COMMANDS            <<03069>>00560000
                         <<!!!!NOTE: CMD SHOULD ALWAYS>>       <<03069>>00562000
                         <<          BE AN EVEN NUMBER>>       <<03069>>00564000
   CMD1        = CMD+1,                                                 00566000
   CMD2        = CMD+2,                                                 00568000
   CMD2'       = CMD2/2,                                                00570000
   CMD4        = CMD+4,                                                 00572000
   CMD5        = CMD+5,                                                 00574000
   CMD6        = CMD+6,     << Not currently used         >>   <<03069>>00576000
   CMD6'       = CMD6/2,                                                00578000
   CMD8        = CMD+8,                                                 00580000
   CMD9        = CMD+9,                                                 00582000
   CMD10       = CMD+10,                                                00584000
   CMD10'      = CMD10/2,                                               00586000
   CMD12       = CMD+12,                                                00588000
   CMD13       = CMD+13,                                                00590000
   CMD14       = CMD+14,                                                00592000
   CMD15       = CMD+15,                                                00594000
   CMD16       = CMD+16,                                                00596000
   CMD17       = CMD+17,                                                00598000
   CMD18       = CMD+18,                                                00600000
   CMD19       = CMD+19,                                                00602000
   CMD20       = CMD+20,                                                00604000
   CNOUPD      = %002000, << NO UPDATE CHANNEL ORDERS>>                 00606000
   CPDA        = 6,       << CURRENT PHYSICAL DISC ADR. dbl inx<<03069>>00608000
   CREADD      = %001400, << CHANNEL READ DATA>>                        00610000
   CREADC      = %001410, << CHANNEL READ COMMAND DATA>>                00612000
   CURCYL      = 12,      << CURRENT CYLINDER INDEX >>                  00614000
   CWAIT       = %001000, <<CHANNEL WAIT>>                              00616000
   CWRITED     = %002000, << CHANNEL WRITE DATA>>                       00618000
   CWRITEC     = %002010, << CHANNEL WRITE COMMAND>>                    00620000
   CWC         = 16,      << CURRENT WORD COUNT INDEX >>                00622000
   DADR        = 4,       << DISC ADRESS INDEX IN IOQ >>                00624000
   DATAOVRRUN  = %16,     << DATA OVERRUN ERROR >>                      00626000
   DILTP       = 5,       << ILT POINTER >>                             00628000
   DLDEV       = 3,       << LOGICAL DEVICE INDEX OF DIT >>             00630000
   DLOGERROR   = 35,    <<HARDWARE LOGGED ERROR STATUS>>       <<01347>>00632000
   DLOGSIOP    = 36,    <<SIOP relative abort location >>      <<03069>>00634000
   DMISC       = 32,      << DIT MISC >>                                00636000
   DSCXFRERR   = %14,     << DISC XFER ERROR STATUS RETURN >>           00638000
   DSERR       = 7,     <<ERROR STATUS COUNT & INDEX>>         <<01347>>00640000
   DSTAT       = 6,       << DEVICE STATUS RETURN INDEX >>              00642000
   DSTAT1      = 18,      << STATUS 1 RETURN INDEX >>                   00644000
   DSTAT2      = 19,      << STATUS 2 RETURN INDEX >>                   00646000
   DXFP        = 26,      << OFFSET OF DATA XFER I/O PROG >>   <<02043>>00648000
                                                               <<03069>>00650000
   DXFP0       = DXFP+0,      << Start of DXFER program >>     <<03069>>00652000
   DXFP11      = DXFP+11,     << Seek command location >>      <<03069>>00654000
   DXFP18      = DXFP+18,     << Req status cmd location >>    <<03069>>00656000
   DXFP23      = DXFP+23,     << Read status buffer location>> <<03069>>00658000
                                                               <<03069>>00660000
                                                               <<03069>>00662000
   DXFP4       = DXFP+4,      << Set filemask cmd location >>  <<03069>>00664000
                                                               <<03069>>00666000
   DXFP25      = DXFP+25,      << SIOP rel jump location >>    <<03069>>00668000
   DXFP30      = DXFP+30,      << Verify  record-1 cmd loc >>  <<03069>>00670000
   DXFP35      = DXFP+35,      << Address record-2 cmd loc >>  <<03069>>00672000
   DXFP42      = DXFP+42,      << Transfer cmd location    >>  <<03069>>00674000
   DXFP43      = DXFP+43,      << DMA HP-IB cmd start loc  >>  <<03069>>00676000
   DXFP44      = DXFP+44,                                      <<03069>>00678000
   DXFP46      = DXFP+46,  << bank number of XFER bufr >>      <<03089>>00680000
   DXFP52      = DXFP+52,  << DSJ branch on good return >>     <<03069>>00682000
   DXFP59      = DXFP+59,  << Seek cmd loc after INIT >>       <<03069>>00684000
   DXFP66      = DXFP+66,  << Verify after init >>             <<03069>>00686000
   ENDOP       = %012400, << DISC END ORDER >>                          00688000
   FILLB       = 6,       << FILL WITH BLANK CMD >>                     00690000
   FILLZ       = 5,       << FILL WITH ZERO CMD >>                      00692000
   FOPEN       = 2,       << FILE OPEN FUNCTION >>                      00694000
   FORMAT      = 8,       << FORMAT FUNCTION >>                         00696000
   ICDP        = 11,       << ILT current DIT pointer >>       <<03074>>00698000
   ICNTRL      = 7,       << CONTROLLER INFO IN ILT >>                  00700000
   ICPVA0      = 0,       << FIRST WORD OF CPVA >>                      00702000
   ICPVA1      = 1,       << WORD ONE OF CPVA >>                        00704000
   ICPVA2      = 2,       << WORD two OF CPVA >>               <<03069>>00706000
   ICPVA3      = 3,       << WORD THREE OF CPVA >>                      00708000
   IDITPA      = 14,      << DITP array in ILT >>              <<03685>>00710000
   IDLEP       = 2,       << START OF IDLE CHANNEL PROG >>              00712000
   IFLAG       = 13,      << FLAGS WORD OF ILT >>                       00714000
   IMASK     = 7,         << INTERRUPT MASK WORD>>                      00716000
   INITFLAG    = CMD20,   << I/O PROGRAM INITIALIZED FLAG >>            00718000
   INITIALIZE  = 9,       << INITIALIZE FUNCTION >>                     00720000
   INITOP      = %005400, << INITIALIZE COMMAND >>                      00722000
   INITADR     = 30,      << INITIALIZE ADDRESS INDEX >>                00724000
   INITADDR    = 15,      << INITIALIZE ADDRESS INDEX (DBL) >>          00726000
   INTERRUPT'2 = %100002, << Interrupt-2 code >>               <<03069>>00728000
   INVDSKADR   = %64,     << INVALID DISC ADRESS RETURN >>              00730000
   INVFUNC     = 4,       << INVALID FUNCTION RETURN >>                 00732000
   ISIOP       = 8,       << CHAN PROG POINTER >>                       00734000
   ISTAP       = 9,       << STATUS AREA PTR IN ILT >>                  00736000
   JUMPOFFSET  = 2,       << OFFSET OF JUMP ORDER AT START OF PROGRAM >>00738000
   MAXTRANSFER = 32767,   << MAXIMUM TRANSFER >>                        00740000
   MBIT'       = 3,       << TRACK MAP BIT OF QMISC >>                  00742000
   POWERFAIL'  = %72,     << SYSDB REL LOCATION OF POWER FAIL WORD >>   00744000
   QFUNC       = 6,       << FUNCTION CODE INDEX OF IOQ >>              00746000
   QLDEV       = 2,       << LDEV INDEX OF IOQ >>                       00748000
   QMISC       = 3,       << DRIVER WORD INDEX OF IOQ >>                00750000
   QSTAT       = 10,      << STATUS RETURN INDEX OF IOQ >>              00752000
   QWBCT       = 7,       << COUNT INDEX >>                             00754000
   READ        = 0,       << READ FUNCTION >>                           00756000
   READOP      = %002400, << DISC READ COMMAND >>                       00758000
   READFS      = 10,      << READ FULL SECTOR FUNCTION >>               00760000
   READFSOP    = %003000, << READ FULL SECTOR COMMAND >>                00762000
   READSPD     = 12,      << READ WITH SPARING DISABLED >>              00764000
   RECALP      = 142,     << OFFSET OF RECALIBRATE I/O PROG >> <<03069>>00766000
   RECALP4     = RECALP+4,                                              00768000
   RECALIBRATE = %000600, << DISC RECALIBRATE ORDER >>                  00770000
   REQDADR     = %012000, << REQUEST DISC ADDRESS>>                     00772000
   REQSTAT     = %001400, << REQUEST STATUS CMD >>                      00774000
   REQSYNOP    = %006400, << REQUEST SYNDROME>>                         00776000
   RDAP        = 114,     <<OFFSET OF DISC ADDRESS PROG>>      <<03069>>00778000
   RDAP4       = RDAP+4,                                                00780000
   RDAP9       = RDAP+9,                                                00782000
   RSTAP       = 104,     << OFFSET TO REQUEST STATUS I/O PROG <<03069>>00784000
   RSTAP4      = RSTAP+4,                                               00786000
   RSTAP9      = RSTAP+9,                                               00788000
   RSTAT       = 7,       << REQUEST STATUS FUNCTION >>                 00790000
   RSYNP       = 128,     << OFFSET TO REQUEST SYMDROME I/O PRO<<03069>>00792000
   RSYNP4      = RSYNP+4,                                               00794000
   RSYNP9      = RSYNP+9,                                               00796000
   SCOUNT      = 29,      << SECTOR COUNT >>                            00798000
   SEEK        = %001200, << SEEK CMD >>                                00800000
   SEEKSTAT1   = 33,      << STATUS FOLLOWING SEEK COMPLETION >>        00802000
   SETWAKE     = %013000, << SET WAKEUP WHEN DRIVE AVAILABLE CMD >>     00804000
   SPEC'IDLEP  = 17,      << OFFSET TO INTERRUPT COMMAND OF ILDEP >>    00806000
   SUCCESSFUL  = 1,       << SUCCESSFUL COMPLETION STATUS RETURN >>     00808000
   SYNDRET     = 22,      << SYNDROME RETURN AREA>>                     00810000
   SYNDRET1    = SYNDRET+1,                                             00812000
   SYNDRET2    = SYNDRET+2,                                             00814000
   SYNDRET3    = SYNDRET+3,                                             00816000
   SYNDRET4    = SYNDRET+4,                                             00818000
   SYSBUFA     = 17,      << SYSBUF INDEX OF DIT >>                     00820000
   SYSDB       = %1000,                                                 00822000
   SYSERROR    = %124,    << SYSTEM ERROR CODE RETURN >>                00824000
   SYSLPDT     = 8,       << DB INDEX OF LPDT POINTER >>                00826000
   SYSSBUF     = 6,       << DB INDEX OF SBUF TABLE >>                  00828000
   SYSUP'      = %73,     << DB INDEX OF SYSTEM UP FLAG >>              00830000
   TIMEOUT'IDLE'CHANP=5,  << Location where WAIT in IDLE is >> <<03685>>00832000
   UNITFAILURE = %54,     << UNIT FAIL STATUS RETURN >>                 00834000
   VERIFYOP    = %003400, << VERIFY COMMAND >>                          00836000
   WAIT        = %10,     << WAIT FOR COMP. STATUS RETURN >>            00838000
   WCR         = 15,      << WORD COUNT REMAINING INDEX >>              00840000
   WRITE       = 1,       << WRITE FUNCTION >>                          00842000
   WRITEL      = 11,      << WRITE LABEL FUNCTION >>                    00844000
   WRITEOP     = %004000, << DISC WRITE COMMAND >>                      00846000
   XFERERROR   = %34;     << XFER ERROR STATUS RETURN >>                00848000
                                                                        00850000
DEFINE                                                                  00852000
   ABORT      = (0:4)#,    << ABORT FIELD OF CPVA0 >>                   00854000
   ABS        = ABSOLUTE#,                                              00856000
   ASMB       = ASSEMBLE#,                                              00858000
   CBIT       = (CBIT':1)#,                                             00860000
   CLBIT      = (CLBIT':1)#,                                            00862000
   CPVAEFIELD = (4:12)#,  << ERROR FIELD OF CPVA WORDS >>               00864000
   DBIT       = (0:1)#,    << RETRY DETERMINATION BIT OF QMISC >>       00866000
   DISABLE    = ASMB(SED 0)#,                                           00868000
   DRVNOTRDY  = (14:1)#,   << DRIVE NOT READY BIT OF QSTAT2 >>          00870000
   DSTBANKFIELD= (8:8)#, << HIGH ORDER MEM ADDRESS IN DST >>   <<01754>>00872000
   EBIT       = (2:1)#,    << ERROR BIT OF QMISC >>                     00874000
   ENABLE     = ASMB(SED 1)#,                                           00876000
   ERRCODE    = (3:5)#,    << ENCODED ERROR STATUS >>                   00878000
   FUNCTION   = (8:8)#,    << REQUEST FUNCTION CODE >>                  00880000
   FINISH     = %(2)1000#, << CHANNEL PROGRAM FINISH WITHOUT ABORT>>    00882000
   HCUNIT      = (13:3)#, << field of IFLAG in ILT >>          <<03685>>00884000
   HEAD       = LSR(8)#,   << HEAD FIELD OF DISC ADRESS >>              00886000
   IAK         = (8:1)#,  << Interrupt acknowledge bit >>      <<03685>>00888000
   INIT       = CON %20302;CON 6#,                                      00890000
   IOPROG      = (7:1)#,  << I/O pgm in-progress bit >>        <<03685>>00892000
   L'STAT'ERR = (15:1)#,   << LAST TRANSFER STATUS                      00894000
                              - TRUE IF LAST TRANSFER ENDED WITH ERROR  00896000
                              - OTHERWISE FALSE                         00898000
                            >>                                          00900000
   MBIT       = (MBIT':1)#,                                             00902000
   MISSEDINT  = (10:1)#,   << MISSED INTERUPT FIELD OF ILFAG OF ILT >>  00904000
   QLDEVN     = (8:8)#,    << LDEV FIELD IN IOQ >>                      00906000
   RETRY      = (13:3)#,   << RETRY COUNT FIELD OF QMISC >>             00908000
   SBIT       = (1:1)#,    << REQUEST SYNDROME BIT OF QMISC >>          00910000
   SECTOR     = (8:8)#,    << SECTOR FIELD OF DISC ADRESS >>            00912000
   SEEKCHECK  = (13:1)#,   << INVALID SEEK BIT OF STATUS-2 >>           00914000
   SEM        = (1:3)#,    << S,E, AND M BITS OF QMISC >>               00916000
   SFAIL      = (10:1)#,   << SIO FIALED TO START IN GIP >>             00918000
   SIOP       = CON %20302;CON 0#, <<SIOP INSTRUCTION>>                 00920000
   SPARE      = (0:1)#,    << SPARE BIT OF STATUS-1 >>                  00922000
   SPEC       = (1:1)#,    << SPECIAL REQ. BIT OF IOQ >>                00924000
   STAT       = (8:8)#,    << I/O STATUS RETURN FIELD OF IOQ >>         00926000
   STATEF      = (12:4)#, << SIODM state field in DIT(0) >>    <<03685>>00928000
   SUBT       = (12:4)#,   << SUBTYPE FIELD OF LPDT >>                  00930000
   SYSBUFR    = (3:1)#,    << SYSTEM BUFFER BIT OF IOQ >>               00932000
   TIMEOUT'WAIT= (5:1)#,    << Bit in QMISC for powered-down >><<03685>>00934000
   UNITN      = LSR(8)#,   << UNIT FIELD OF DIT >>                      00936000
   WAITPROG   = (1:1)#,    << IDLE CHANNEL PROG STARTED OF IFLAG >>     00938000
   WBIT       = (4:1)#;    << WRITING BAD TRACK BIT OF QMISC >>         00940000
                                                                        00942000
INTEGER POINTER                                                         00944000
   SBUF        = DB + SYSSBUF;                                          00946000
                                                                        00948000
LOGICAL SYSUP = DB+SYSUP';                                              00950000
                                                                        00952000
LOGICAL POWERFAIL = DB+POWERFAIL';                                      00954000
                                                                        00956000
DOUBLE POINTER                                                          00958000
   DLPDT       = DB + SYSLPDT;                                          00960000
                                                               <<03685>>00962000
integer array WA0(*) = DB + 0; << Direct array at SYSDB >>     <<03685>>00964000
                                                               <<03685>>00966000
ARRAY INITIAL(0:218)= DB:=                                     <<03069>>00968000
   [8/37,8/%61],  <<DIT SIZE= 42, CORE RES.,runwait , TYPE=1>> <<03069>>00970000
         0,                                                             00972000
   %037407,          << UNIT EXTRACT INSTRUCTION (ANDI 7) >>            00974000
   [8/89,8/2],       << 178 WORD SIO PROGRAM AREA,2 WORD STATUS<<03069>>00976000
   << DIT >>                                                            00978000
     %040000,        << DFLAG; DISC >>                                  00980000
           0,        << DLINK >>                                        00982000
           0,        << DIOQP >>                                        00984000
     %040000,        << DLDEV - HP-IB DEVICE >>                <<01301>>00986000
           0,        << DDLTP >>                                        00988000
           0,        << DILTP >>                                        00990000
           0,        << DRQST >>                                        00992000
           0,        << DSERR >>                                        00994000
           0,        << DMAMQ >>                                        00996000
           0,        << DMAMQT >>                                       00998000
         0,0,        << CLDA - CURRENT LOGICAL DISC ADR >>              01000000
         0,0,        << CPDA - CURRENT PHYSICAL DISC ADR >>             01002000
           0,        << CDBA - CURRENT DATA BUFFER ADR >>               01004000
           0,        << WCR - WORD COUNT REMAINING >>                   01006000
           0,        << CWC - CURRENT TRANSFER COUNT >>                 01008000
           0,        << SYSBUFA - SYSTEM BUFFER ADR >>                  01010000
           0,        << STAT1 - FIRST DISC STATUS >>                    01012000
           0,        << STAT2 - SECOND DISC STATUS >>                   01014000
         0,0,        << CEDA - CURRENT ERROR DISC ADR >>                01016000
0,0,0,0,0,0,0,       << REQUEST SYNDROME AREA >>                        01018000
           0,        << SCOUNT - SECTOR COUNT >>                        01020000
         0,0,        << INITIALIZE ADDRESS >>                           01022000
           0,        << DMISC >>                                        01024000
         0,0,        << SEEKSTAT >>                                     01026000
           0,        << DLOGERROR >>                           <<01347>>01028000
           0,        << SIOP relative abort address >>         <<03069>>01030000
                                                                        01032000
        <<-----------------                                             01034000
          CHANNEL PROGRAM                                               01036000
        ----------------->>                                             01038000
                                                                        01040000
        CJUMP,0,                                                        01042000
                                                                        01044000
        <<----------------------                                        01046000
          IDLE CHANNEL PROGRAM                                          01048000
        ---------------------->>                                        01050000
                                                                        01052000
        CWRITEC,2,0,CNOUPD,0,     <<ISSUE END>>                         01054000
        CWAIT,0,                                                        01056000
        CWRITEC,2,0,CNOUPD,0,     <<REQUEST STATUS>>                    01058000
        CREADC,4,0,CNOUPD,0,      <<READ STATUS>>                       01060000
        CDSJ2,0,                  <<CHECK POWER UP >>          <<02043>>01062000
        0,                                                     <<02043>>01064000
        0,                                                     <<02043>>01066000
        125,                      << ISSUE CLESR >>            <<03069>>01068000
        CINTHLT2,1,               <<HALT WITH INTERUPT>>                01070000
                                                                        01072000
        <<-------------------                                           01074000
          DATA XFER PROGRAM                                             01076000
        ------------------->>                                           01078000
                                                                        01080000
  <<DXFP0>>  CWRITEC,2,0,CNOUPD,0, << Set filemask >>          <<03069>>01082000
  <<DXFP5>>  CWAIT,0,                                          <<03069>>01084000
                                                               <<03069>>01086000
  <<DXFP7>>  CWRITEC,6,0,CNOUPD,0, << Write Seek Command    >> <<03069>>01088000
 <<DXFP12>>  CWAIT,0,             << Wait for // poll       >> <<03069>>01090000
                                                               <<03069>>01092000
 <<DXFP14>>  CWRITEC,2,0,CNOUPD,0, << Write Req Status cmd  >> <<03069>>01094000
 <<DXFP19>>  CREADC,4,0,CNOUPD,0,  << Read status           >> <<03069>>01096000
                                                               <<03069>>01098000
 <<DXFP24>>  CJUMP,12,            << Jump if READ/WRITE     >> <<03069>>01100000
                                                               <<03069>>01102000
 <<DXFP26>>  CWRITEC,4,0,CNOUPD,0, << Verify:Init alternate >> <<03069>>01104000
 <<DXFP31>>  CWRITEC,6,0,CNOUPD,0, << Address Record 2      >> <<03069>>01106000
 <<DXFP36>>  CWAIT,0,              << Wait for // poll      >> <<03069>>01108000
                                                               <<03069>>01110000
 << Do actual transfer.  First, send XFER order to disc     >> <<03069>>01112000
 << controller, then do DMA to send/receive data.           >> <<03069>>01114000
                                                               <<03069>>01116000
 <<DXFP38>>  CWRITEC,2,0,CNOUPD,0, <<TRANSFER ORDER>>          <<03069>>01118000
 <<DXFP43>>  0,0,0,0,0,            <<ACTUAL TRANSFER>>         <<03069>>01120000
 <<DXFP48>>  CWAIT,0,                                          <<03069>>01122000
                                                               <<03069>>01124000
 <<DXFP50>>  CDSJ2,0,              <<ERROR CHECK>>             <<03069>>01126000
 <<DXFP52>>  19,                   << NO ERROR >>              <<03069>>01128000
 <<DXFP53>>  23,                   << ERROR OCCURED >>         <<03069>>01130000
 <<DXFP54>>  68,                   << CLEAR REQUIRED >>        <<03069>>01132000
                                                               <<03069>>01134000
 <<DXFP55>>  CWRITEC,6,0,CNOUPD,0, << SEEK FOR VERIFY IN FORMAT<<03069>>01136000
 <<DXFP60>>  CWAIT,0,                                          <<03069>>01138000
                                                               <<03069>>01140000
 <<DXFP62>>  CWRITEC,4,0,CNOUPD,0, <<VERIFY>>                  <<03069>>01142000
 <<DXFP67>>  CWAIT,0,                                          <<03069>>01144000
                                                               <<03069>>01146000
 <<DXFP69>>  CDSJ2,0,                                          <<03069>>01148000
 <<DXFP71>>  0,                    << NO ERROR >>              <<03069>>01150000
 <<DXFP72>>  4,                    << ERROR OCCURED >>         <<03069>>01152000
 <<DXFP73>>  49,                   << CLEAR REQUIRED >>        <<03069>>01154000
                                                               <<03069>>01156000
 <<DXFP74>>  CINTNHLT2,2,          << Interrupt, but continue ><<03069>>01158000
                                                               <<03069>>01160000
 << Jump to idle channel pgm if all is OK                  >>  <<03069>>01162000
 <<DXFP76>>  CJUMP,-102,  << Jump to ISSUE END             >>  <<03069>>01164000
                                                                        01166000
        <<------------------------                                      01168000
          REQUEST STATUS PROGRAM                                        01170000
        ------------------------>>                                      01172000
                                                                        01174000
 <<RSTP00>>  CWRITEC,2,0,CNOUPD,0, <<REQUEST STATUS>>                   01176000
 <<RSTP05>>  CREADC,4,0,CNOUPD,0,  <<READ STATUS>>                      01178000
                                                                        01180000
        <<------------------------------                                01182000
          REQUEST DISC ADDRESS PROGRAM                                  01184000
        ------------------------------>>                                01186000
                                                                        01188000
 <<RDAP00>>  CWRITEC,2,0,CNOUPD,0, <<REQUEST DISC ADDRESS>>             01190000
 <<RDAP05>>  CREADC,4,0,CNOUPD,0,  <<READ DISC ADDRESS>>                01192000
 <<RDAP10>>  CWAIT,0,                                                   01194000
 <<RDAP17>>  CINTHLT1,1,           <<ERROR HALT>>                       01196000
                                                                        01198000
        <<--------------------------                                    01200000
          REQUEST SYNDROME PROGRAM                                      01202000
        -------------------------->>                                    01204000
                                                                        01206000
 <<RSYNP00>> CWRITEC,2,0,CNOUPD,0, <<REQUEST SYNDROME>>                 01208000
 <<RSYNP05>> CREADC,14,0,CNOUPD,0, <<SYNDROME RETURN>>                  01210000
 <<RSYNP10>> CWAIT,0,                                                   01212000
 <<RSYNP17>> CINTHLT2,3,                                                01214000
                                                                        01216000
        <<---------------------                                         01218000
          RECALIBRATE PROGRAM                                           01220000
        --------------------->>                                         01222000
                                                                        01224000
 <<RECALP>>  CWRITEC,2,0,CNOUPD,0, <<ISSUE RECALIBRATE>>                01226000
 <<RECALP5>> CINTHLT2,4,                                                01228000
                                                                        01230000
        <<-------------------                                           01232000
          ISSUE AMIGO CLEAR                                             01234000
        ------------------->>                                           01236000
                                                                        01238000
 <<CLRP>>    CLEARC,0,                                                  01240000
 <<CLRP2>>   CWAIT,0,                                                   01242000
 <<CLRP4>>   CINTHLT3,1,                                                01244000
             0,          <<TO MAKE CMD START ON EVEN BOUNDARY ><<02043>>01246000
        <<----------                                                    01248000
          COMMANDS                                                      01250000
        ---------->>                                                    01252000
                                                                        01254000
<<CMD00>>   REQSTAT,    << Request status for IDLE chanp >>    <<03074>>01256000
 <<CMD01>>   0,0,0,      <<SEEK>>                                       01258000
<<CMD04>>   ENDOP,      << Disc END order >>                   <<03074>>01260000
 <<CMD05>>   ADRREC,     << Address Record 1 (not used) >>     <<03069>>01262000
 <<CMD06>>   0,          << Cylinder number        >>          <<03069>>01264000
 <<CMD07>>   0,          << Head/Sector number     >>          <<03069>>01266000
<<CMD08>>   REQSYNOP,   << Request syndrome order >>           <<03074>>01268000
 <<CMD09>>   ADRREC,0,0, <<ADDRESS RECORD 2>>                           01270000
 <<CMD12>>   0,          <<REQUEST STATUS>>                             01272000
 <<CMD13>>   REQDADR,    <<REQUEST DISC ADDRESS>>                       01274000
 <<CMD14>>   0,          <<SET FILEMASK>>                               01276000
 <<CMD15>>   0,0,        <<VERIFY>>                                     01278000
 <<CMD17>>   0,          <<DISC XFER ORDER>>                            01280000
 <<CMD18>>   0,          << FILL WORD >>                                01282000
 <<CMD19>>   REQSTAT,    << Seek Status req for a specific unit<<03069>>01284000
 <<CMD20>>   FALSE;      << FLAG INDICATES IF I/O PROGRAM               01286000
                            HAS BEEN INITIALIZED BY DRIVER              01288000
                            INITIALIZATION ROUTIN          >>           01290000
                                                                        01292000
$PAGE                                                                   01294000
integer procedure GETDRT(DRTN,OFFSET);                         <<03069>>01296000
value DRTN,OFFSET;                                             <<03069>>01298000
integer DRTN,OFFSET;                                           <<03069>>01300000
option external;                                               <<03069>>01302000
                                                               <<03069>>01304000
procedure AWAKEIO(DITP,IMPEDE);                                <<03685>>01306000
value DITP,IMPEDE;                                             <<03685>>01308000
pointer DITP;                                                  <<03685>>01310000
logical IMPEDE;                                                <<03685>>01312000
option external;                                               <<03685>>01314000
                                                                        01316000
PROCEDURE DCONVERT(WORD);                                               01318000
VALUE WORD;                                                             01320000
INTEGER WORD;                                                           01322000
OPTION EXTERNAL;                                                        01324000
                                                                        01326000
INTEGER PROCEDURE GETSBUF(TYPE);                                        01328000
VALUE TYPE;                                                             01330000
INTEGER TYPE;                                                           01332000
OPTION EXTERNAL;                                                        01334000
                                                                        01336000
PROCEDURE GIP'HPIB;                                            <<01301>>01338000
OPTION EXTERNAL;                                                        01340000
                                                                        01342000
PROCEDURE HELP;                                                         01344000
OPTION EXTERNAL;                                                        01346000
                                                                        01348000
PROCEDURE LDEVNOTRDY(DITP);                                             01350000
VALUE DITP;                                                             01352000
POINTER DITP;                                                           01354000
OPTION EXTERNAL;                                                        01356000
                                                                        01358000
PROCEDURE MASTERCLEARHPIB(DITP);                               <<01301>>01360000
INTEGER ARRAY DITP;                                                     01362000
OPTION EXTERNAL;                                                        01364000
                                                                        01366000
procedure MMSTAT(EVENT,P1,P2,P3);                              <<03085>>01368000
value EVENT,P1,P2,P3;                                          <<03085>>01370000
integer EVENT,P1,P2,P3;                                        <<03085>>01372000
option external;                                               <<03085>>01374000
                                                               <<03085>>01376000
PROCEDURE SIODM(DITP,FLAGS);                                            01378000
VALUE DITP,FLAGS;                                                       01380000
POINTER DITP;                                                           01382000
LOGICAL FLAGS;                                                          01384000
OPTION EXTERNAL;                                                        01386000
                                                                        01388000
PROCEDURE RETURNSBUF(SBUFP);                                            01390000
VALUE SBUFP;                                                            01392000
INTEGER SBUFP;                                                          01394000
OPTION EXTERNAL;                                                        01396000
                                                                        01398000
PROCEDURE START'HPIB(DITP,CHANP,QUEUE);                        <<01301>>01400000
VALUE DITP,CHANP,QUEUE;                                                 01402000
POINTER DITP,CHANP;                                                     01404000
LOGICAL QUEUE;                                                          01406000
OPTION EXTERNAL;                                                        01408000
                                                                        01410000
PROCEDURE SUDDENDEATH(N);                                               01412000
VALUE N; INTEGER N;                                                     01414000
OPTION EXTERNAL;                                                        01416000
                                                                        01418000
procedure DISC'NOT'RESP(DITP);                                 <<03685>>01420000
integer array DITP;                                            <<03685>>01422000
option external;                                               <<03685>>01424000
                                                               <<03685>>01426000
$PAGE                                                                   01428000
INTEGER PROCEDURE DISCINIT(DITP);                                       01430000
  INTEGER ARRAY DITP;                                                   01432000
  <<INITIALIZATION ROUTINE FOR IOMDISC1:                                01434000
    IT SETS UP IDLE CHANNEL PROGRAM,                                    01436000
    STARTS IT TO RUN,                                                   01438000
    SETS BIT FIEDLS TO INDICATE IT IS RUNNING                           01440000
  >>                                                                    01442000
    BEGIN                                                               01444000
    INTEGER POINTER ILTP=Q+1,                                           01446000
                    CHANP=Q+2;                                          01448000
    LOGICAL ABSCHANP=Q+3;                                               01450000
    LOGICAL POINTER ILTPL=ILTP;                                         01452000
    integer X = X;   << Index register >>                      <<03085>>01454000
                                                                        01456000
      <<----------------------                                          01458000
        INITIALIZE VARIABLES                                            01460000
      ---------------------->>                                          01462000
                                                                        01464000
      IF POWERFAIL<>0 THEN RETURN;                                      01466000
      TOS := DITP(DILTP);   << ILT POINTER >>                           01468000
      TOS := ILTP(ISIOP);   << CHANNEL PROGRAM POINTER >>               01470000
      TOS := @CHANP+SYSDB;  <<ABSOLUTE ADDRESS OF CHANP>>               01472000
      <<-------------------------                                       01474000
        INITIALIZE IDLE PROGRAM                                         01476000
      ------------------------->>                                       01478000
      IF NOT LOGICAL(CHANP(INITFLAG)) THEN                              01480000
        BEGIN <<FIRST UNIT FOR CONTROLLER>>                             01482000
        CHANP(X) := true;  << flag pgm is initialized >>       <<03085>>01484000
        CHANP(6) := ABSCHANP+CMD4;  << END ORDER >>                     01486000
        CHANP(13) := ABSCHANP+CMD;  << Unit 0 request status >><<03069>>01488000
        CHANP(CMD12) := REQSTAT;                                        01490000
        CHANP(18) := ILTP(ISTAP)+SYSDB;                                 01492000
                                                               <<03069>>01494000
                                                               <<03069>>01496000
        << Initialize SEEK command >>                          <<03069>>01498000
        CHANP(DXFP11) := CHANP(DXFP59) := ABSCHANP+CMD1;       <<03069>>01500000
        CHANP(DXFP18) := ABSCHANP+CMD19; << REQUEST STATUS >>  <<03069>>01502000
        CHANP(DXFP4 ) := ABSCHANP+CMD14;<< FILEMASK COMMAND >> <<03069>>01504000
                                                               <<03069>>01506000
        CHANP(DXFP35) := ABSCHANP+CMD9; << Add record-2 >>     <<03069>>01508000
                                                               <<03069>>01510000
        << Initialize disc transfer order >>                   <<03069>>01512000
        CHANP(DXFP42) := CHANP(RECALP4) := ABSCHANP+CMD17;     <<03069>>01514000
                                                               <<03069>>01516000
        << Initialize VERIFY commands >>                       <<03069>>01518000
        CHANP(DXFP66) := CHANP(DXFP30) := ABSCHANP+CMD15;      <<03069>>01520000
        CHANP(RSYNP4) := ABSCHANP+CMD8; << SYNDROME COMMAND >>          01522000
        CHANP(RSTAP4) := ABSCHANP+CMD12;<< STATUS COMMAND >>            01524000
        CHANP(RDAP4) := ABSCHANP+CMD13; << DISC ADDR COMMAND >>         01526000
                                                               <<03069>>01528000
                                                               <<03069>>01530000
                                                               <<03069>>01532000
                                                               <<03069>>01534000
                                                               <<03069>>01536000
        << load SEEKSTAT address into channel pgm >>           <<03069>>01538000
        CHANP(DXFP23) := @DITP + SEEKSTAT1 + SYSDB;            <<03069>>01540000
        <<------------                                                  01542000
          UPDATE ILT                                                    01544000
        ------------>>                                                  01546000
        CHANP(1) := 0;                                                  01548000
        START'HPIB(DITP,CHANP,FALSE);                          <<01301>>01550000
        END;                                                            01552000
      END;                                                              01554000
                                                                        01556000
$PAGE                                                                   01558000
INTEGER PROCEDURE MHDDVR(IOQP,DITP,BANK,BUFFER,CHANP,DRTN);    <<01301>>01560000
VALUE IOQP,DITP,BANK,BUFFER,CHANP,DRTN;                        <<01301>>01562000
INTEGER BANK,BUFFER,DRTN;                                      <<01301>>01564000
INTEGER POINTER IOQP,DITP,CHANP;                                        01566000
OPTION PRIVILEGED,UNCALLABLE;                                           01568000
BEGIN                                                                   01570000
                                                                        01572000
INTEGER                                                                 01574000
   ABSCHANP     = Q+16, << ABSOLUTE ADDRESS OF CHANP>>                  01576000
   AD           = Q+1,  << ADRESS DELTA >>                              01578000
   BUFADR       = Q+5,  << ABSOLUTE BUFFER ADRESS >>                    01580000
   BUFCNT       = Q+1,  << COUNT CHECK FOR REQUEST SYND. >>             01582000
   CXFER        = Q+4,  << CHAINED XFER ORDER >>                        01584000
   DISCOP       = Q+3,  << DISC XFER ORDER>>                            01586000
   DXFPINDEX    = Q+10, <<INDEX INTO XFER PROGRAM>>                     01588000
   ERR          = Q+6,  << DISC ENCODED ERROR STATUS >>                 01590000
   FUNCT        = Q+13, << REQUEST FUNCTION CODE >>                     01592000
   I            = Q+8,                                                  01594000
   INDEX        = Q+18, <<INDEX INTO DISCINFO>>                         01596000
   MSTATE       = MHDDVR,                                               01598000
   S0           = S-0,                                                  01600000
   S1           = S-1,                                         <<03685>>01602000
   S2           = S-2,                                                  01604000
   SUBTYPE      = Q+12, << DEVICE SUBTYPE >>                            01606000
   UNIT         = Q+15, << DEVICE UNIT # >>                             01608000
   X            = X,                                                    01610000
   XCNT         = Q+7,  << XFER COUNT >>                                01612000
   XD           = Q+2;  << XFER DELTA >>                                01614000
                                                                        01616000
DOUBLE                                                                  01618000
   DXFERORDER   = CXFER;                                                01620000
                                                                        01622000
DOUBLE POINTER                                                          01624000
   DDITP        = DITP,                                                 01626000
   DIOQP        = IOQP,                                                 01628000
   DCHANP       = CHANP;                                                01630000
                                                                        01632000
LOGICAL                                                                 01634000
   CHANQFLG     = Q+11, << CHANNEL QUEUE FLAG FOR STARTIO >>            01636000
   SBFLG        = Q+14, << SYSTEM BUFFER FLAG >>                        01638000
   LS0          = S-0,                                                  01640000
   LSM1         = S-1;                                                  01642000
                                                                        01644000
LOGICAL POINTER                                                         01646000
   LDITP        = DITP,                                                 01648000
   LIOQP        = IOQP,                                                 01650000
   LCHANP       = CHANP,                                       <<01115>>01652000
   LPDTP        = 8;                                           <<01115>>01654000
                                                                        01656000
INTEGER POINTER                                                         01658000
   BADTRACK     = Q+9,                                                  01660000
   ILTP         = Q+17,                                                 01662000
   PS0          = S-0,                                                  01664000
   PS1          = S-1;                                                  01666000
                                                                        01668000
EQUATE                                                                  01670000
   HSTYPE      =    12,   << HIGHEST SUBTYPE >>                <<03069>>01672000
   NENTRIES    =    5,    << NUMBER OF TABLE ENTRIES/SUBTYPE >>         01674000
   SECPERTRK   =    0,    << OFFSET TO SEC/TRACK ENTRIES >>             01676000
   SECPERCYL   =    1,    << OFFSET TO SEC/CYLINDER ENTRIES >>          01678000
   MAXCYL      =    2,    << OFFSET TO MAX CYLINDER FOR STYPE >>        01680000
   FILEMASK    =    3,    << OFFSET TO FILEMASK >>                      01682000
   HEADOFFSET  =    4;    << OFFSET TO FIRST SURFACE >>        <<03069>>01684000
                                                               <<03069>>01686000
                                                                        01688000
INTEGER ARRAY                                                           01690000
   DISCINFO(4*NENTRIES:HSTYPE*NENTRIES+4) = PB :=              <<03069>>01692000
     48,  96, 410, %7406, 0,     <<STYPE 4, 7905, REMOVE CART >>        01694000
     48,  48, 410, %7405, 2,     <<STYPE 5, 7905, FIXED PLATTER >>      01696000
     48, 144, 410, %7407, 0,     <<STYPE 6, 7905, BOTH PLATTERS >>      01698000
     48, 144, 410, %7407, 0,     <<STYPE 7, 7905, FH DISC REPLCMNT >>   01700000
     48, 240, 822, %7407, 0,     <<STYPE 8, 7920 >>                     01702000
     64, 576, 822, %7407, 0,     <<STYPE 9, 7925 >>                     01704000
     48,  96, 410, %7406, 0,     <<STYPE 10, 7906,REMOVABLE CART. >>    01706000
     48,  96, 410, %7407, 2,     <<STYPE 11, 7906,FIXED PLATTER >>      01708000
     48, 192, 410, %7407, 0;     <<SYTPE 12, 7906, BOTH PLATTER<<03069>>01710000
                                                               <<03069>>01712000
                                                                        01714000
DEFINE DITLDEV=3).(8:8#;                                       <<01115>>01716000
DEFINE FOREIGN=(LPDTP(LDITP(DITLDEV)&LSL(1)+1).(10:2)=3)#;     <<01115>>01718000
                                                               <<01115>>01720000
INTEGER ARRAY                                                           01722000
   CHANRW(0:12)=PB:=CREADD,CWRITED,0,0,0,CWRITED,CWRITED,               01724000
   0,CWRITED,CWRITED,CREADD,CWRITED,CREADD;                             01726000
                                                                        01728000
INTEGER ARRAY                                                           01730000
   XFEROP(0:12)=PB:=READOP,WRITEOP,0,0,0,WRITEOP,WRITEOP,               01732000
   0,WRITEOP,0,READFSOP,WRITEOP,READOP;                                 01734000
                                                                        01736000
                                                                        01738000
  << Set up request status for this DIT/UNIT >>                <<03069>>01740000
  subroutine REQSTATSIO;                                       <<03069>>01742000
  begin                                                        <<03069>>01744000
      CHANP(CMD12) := REQSTAT+UNIT;                                     01746000
      CHANP(RSTAP9) := @DITP(DSTAT1)+SYSDB;<< STATUS RETURN >>          01748000
      CHANP(RDAP9) := @DITP(CEDA1)+SYSDB;<< DISC ADDR RETURN >><<03069>>01750000
  end;                                                         <<03069>>01752000
                                                               <<03069>>01754000
  << Check for attention from another unit >>                  <<03069>>01756000
  subroutine CHECK'SEEKSTATUS;                                 <<03069>>01758000
  begin                                                        <<03069>>01760000
                                                               <<03685>>01762000
   << We will first check for an ATTENTION from a disc >>      <<03685>>01764000
   << by examining the status area in the ILT.  An IDLE>>      <<03685>>01766000
   << may have written status into this area, and by   >>      <<03685>>01768000
   << reading status, the ATTENTION condition may be   >>      <<03685>>01770000
   << cleared.  If there is no status in the ILT, we   >>      <<03685>>01772000
   << will then check the SEEK STATUS from the data    >>      <<03685>>01774000
   << transfer channel program.  This status should    >>      <<03685>>01776000
   << re-appear since the controller is polling.       >>      <<03685>>01778000
                                                               <<03069>>01780000
  << if non-zero, then status request was performed >>         <<03069>>01782000
  << in channel program.                            >>         <<03069>>01784000
   tos := WA0(ILTP(ISTAP));  << Status from IDLE chanp >>      <<03685>>01786000
   if = then   << No status >>                                 <<03685>>01788000
    begin << No idle status was performed >>                   <<03685>>01790000
    DEL; << remove prior unit number >>                        <<03685>>01792000
    tos := DITP(SEEKSTAT1);  << Seek status from IDLE >>       <<03685>>01794000
    if <> then                                                 <<03685>>01796000
      begin    << There is a status here >>                    <<03685>>01798000
      DITP(X) := 0;  << Zero-out status >>                     <<03685>>01800000
      go to CHECK'UNIT'NUMBER;                                 <<03685>>01802000
      end                                                      <<03685>>01804000
    else                                                       <<03685>>01806000
      DEL;  << remove unit number >>                           <<03685>>01808000
    end                                                        <<03685>>01810000
  else                                                         <<03685>>01812000
    begin   << Attention status in ILT >>                      <<03685>>01814000
    WA0(X) := 0;   << Zero out status in ILT >>                <<03685>>01816000
                                                               <<03685>>01818000
CHECK'UNIT'NUMBER:                                             <<03685>>01820000
                                                               <<03685>>01822000
    tos := tos land 7;   << extract unit number     >>         <<03069>>01824000
    << S-1 is the unit number, S-0 is the DIT pointer >>       <<03685>>01826000
    tos := 0;    << DIT pointer >>                             <<03685>>01828000
    if S1 <> UNIT then                                         <<03685>>01830000
      if S1 <= ILTP(IFLAG).HCUNIT then << Unit in range >>     <<03685>>01832000
                                                               <<03685>>01834000
        if (S0:=ILTP(S1+IDITPA)) > 0 then << config'd >>       <<03685>>01836000
          << If no activity or awaiting OPERATOR INTERVENTION>><<03736>>01838000
          if PS0.STATEF=0 or PS0.STATEF=%10 then               <<03736>>01840000
            begin  << Do an AWAKEIO on this unit >>            <<03685>>01842000
            tos := PS0;   << Word 0 of DIT on tos >>           <<03685>>01844000
            if S0.STATEF=0 then tos.STATEF := 6; <<DEVREC>>    <<03736>>01846000
            tos.IAK := 1;      << Interrupt ACK  >>            <<03685>>01848000
            tos.IOPROG := 0;   << No channel pgm >>            <<03685>>01850000
            PS1 := tos;   << Store word 0 of DIT >>            <<03685>>01852000
            AWAKEIO(PS0,0);                                    <<03685>>01854000
            end;                                               <<03685>>01856000
    ASMB(ddel);   << Remove UNIT and DIT pointer >>            <<03685>>01858000
                                                               <<03685>>01860000
    end;                                                       <<03685>>01862000
                                                               <<03685>>01864000
end;  << of subroutine CHECK'SEEKSTATUS >>                     <<03685>>01866000
                                                                        01868000
  DOUBLE SUBROUTINE CONVERTADR;                                         01870000
      BEGIN << THIS ROUTINE CONVERTS A PHYSICAL TO LOGICAL DISC ADR. >> 01872000
     TOS := DDITP(X); << DIT INDEX PASSED IN X REG. >>                  01874000
     TOS := S0&HEAD;                                                    01876000
     TOS := TOS-DISCINFO(INDEX+HEADOFFSET);                             01878000
     TOS := TOS * DISCINFO(INDEX+SECPERTRK);                            01880000
     ASMB(XCH);                                                         01882000
     TOS := TOS.SECTOR;                                                 01884000
     ASMB(ADD,ZERO;XCH,CAB);                                            01886000
     TOS := DISCINFO(INDEX+SECPERCYL);                                  01888000
     ASMB(LMPY,DADD; STD S-4);                                          01890000
    END;                                                                01892000
                                                                        01894000
$PAGE "DRIVER COMMON ENTRY POINT"                              <<03069>>01898000
                                                                        01900000
        <<----------------------------                                  01902000
          INITIALIZE LOCAL VARIABLES                                    01904000
          ---------------------------->>                                01906000
                                                                        01908000
        ASMB(ADDS 11);                                                  01910000
        TOS := DLPDT(IOQP(QLDEV).QLDEVN);                               01912000
        DELB;                                                           01914000
        TOS := TOS.SUBT; << DEVICE SUBTYPE >>                           01916000
        TOS := IOQP(QFUNC).FUNCTION; << REQUEST FUNCTION >>             01918000
        TOS := IOQP.SYSBUFR;  << SYSBUF FLAG >>                         01920000
        TOS := LOGICAL(DITP(DLDEV)&UNITN) LAND %77; << UNIT #>><<01301>>01922000
        TOS := @CHANP+SYSDB;                                            01924000
        TOS := DITP(DILTP);                                             01926000
        TOS := SUBTYPE*NENTRIES; << INDEX >>                            01928000
        IF NOT LOGICAL(CHANP(INITFLAG))   << IF NOT INIT'ED >> <<01926>>01930000
          THEN DISCINIT(DITP);   << CALL DISC INITIALIZATION>> <<01926>>01932000
$PAGE "NEW REQUEST - INITIATOR"                                <<03069>>01934000
                                                                        01936000
        IF MSTATE = 2 THEN                                              01938000
          BEGIN                                                         01940000
          <<-------------                                               01942000
            NEW REQUEST                                                 01944000
          ------------->>                                               01946000
                                                               <<03069>>01948000
          ILTP<<(ICPVA0)>> := 0;                               <<03069>>01950000
          ILTP(ICPVA2) := 0;                                   <<03069>>01952000
          ASMB(incx,zero);                                     <<03069>>01954000
          ILTP(X) := tos;   << ICPVA3 >>                       <<03069>>01956000
                                                               <<03069>>01958000
            COMMENT: **************************************    <<02043>>01960000
              ABOVE STATEMENT IS NECESSARY BECAUSE CLEAR MAY   <<02043>>01962000
            BE ISSUED WHILE IN THE IDLE CHANNEL PROGRAM. IF    <<02043>>01964000
            SO, CPVA WORD WILL NOT GET CLEARED UNTIL DRIVER    <<02043>>01966000
            IS CALLED. IN WHICH CASE, ON COMPLETION OF THIS    <<02043>>01968000
            I/O, IT WOULD APPEAR THAT THE POWER UP OCCURRED    <<02043>>01970000
            ON THIS TRANSFER AND THE TRANSFER WOULD BE REDONE  <<02043>>01972000
            UNNECESSARILY;                                     <<02043>>01974000
                                                               <<03069>>01976000
          IF @IOQP=0 THEN                                               01978000
            BEGIN                                                       01980000
            <<----------------------------                              01982000
              START IDLE CHANNEL PROGRAM                                01984000
            ---------------------------->>                              01986000
           tos := @DITP;                                       <<03085>>01988000
            ILTP(IFLAG).MISSEDINT := 0;                                 01990000
            IF <> THEN TOS := SPEC'IDLEP + 2 << ATTN  FROM DISC<<03098>>01992000
                               << WHILE OTHER DRIVE DOING A SEEK >>     01994000
            ELSE                                                        01996000
              BEGIN << NORMAL IDLE CHANNEL PROGRAM >>                   01998000
                                                               <<03069>>02000000
              TOS := 2;                                        <<03098>>02002000
              END;                                                      02004000
                                                               <<03085>>02006000
           << Start Channel Program here >>                    <<03085>>02008000
           tos := tos + @CHANP;                                <<03085>>02010000
           START'HPIB(*,*,false);                              <<03085>>02012000
           MSTATE := 5;                                        <<03085>>02014000
           return;                                             <<03085>>02016000
                                                               <<03085>>02018000
            END;                                                        02020000
                                                               <<03069>>02022000
          TOS := IOQP(QWBCT); << DETERMINE XFER COUNT >>                02024000
          IF < THEN                                                     02026000
            BEGIN << COUNT IN BYTES >>                                  02028000
            ASMB(DUP);                                                  02030000
            IF TOS THEN IOQP(X):=IOQP(X)-1; << ROUND UP CNT IF ODD >>   02032000
            TOS := -(TOS&ASR(1)); << CONVERT TO WORDS >>                02034000
            END;                                                        02036000
          DITP(WCR) := TOS; << XFER COUNT >>                            02038000
          DDITP(CLDA) := DIOQP(DADR); << DISC ADRESS >>                 02040000
          DITP(CDBA) := BUFFER; << SET CURRENT BUFFER ADRESS >>         02042000
                                                               <<03069>>02044000
          << map function 15 to function 7 >>                  <<03069>>02046000
          if FUNCT = 15 then                                   <<03069>>02048000
            begin                                              <<03069>>02050000
            FUNCT := RSTAT;                                    <<03069>>02052000
            IOQP(QFUNC).FUNCTION := RSTAT;                     <<03069>>02054000
            end;                                               <<03069>>02056000
                                                               <<03069>>02058000
          IF FUNCT > READSPD THEN                                       02060000
            BEGIN                                                       02062000
INVALIDFUNC:                                                            02064000
            TOS := INVFUNC;                                             02066000
            GO TO BADEND;                                               02068000
                                                               <<03069>>02070000
            END;                                                        02072000
          IF SBFLG AND DITP(WCR) > 128 THEN GO TO INVALIDFUNC;          02074000
          TOS := 0; << RESET QMISC >>                                   02076000
          X := FUNCT; << SWITCH ON REQUEST TYPE >>                      02078000
          ASMB(LOAD SWT,X; ADAX; BR SWT,X;                              02080000
SWT:      CON DOXFER;    CON DOXFER;    CON GOODEND;   CON GOODEND;     02082000
          CON GOODEND;   CON FILLZERO;  CON FILLBLANK;                  02084000
          CON REQSTATUS; CON DOXFER;    CON DOXFER;                     02086000
          CON DOXFER;    CON DOXFER;    CON DOXFER);                    02088000
          HELP; << HELP CALL NEEDED FOR BREAKPOINTS >>                  02090000
          END;                                                          02092000
$PAGE "COMPLETOR SECTION (INTERUPT HANDLER)"                   <<03069>>02094000
        <<---------------------                                         02096000
          CONTINUATOR SECTION                                           02098000
        --------------------->>                                         02100000
        << check for attention from another unit >>            <<03069>>02102000
        CHECK'SEEKSTATUS;                                      <<03069>>02104000
                                                               <<03069>>02106000
        << If all looks OK, bypass error checking code >>      <<03069>>02108000
                                                                        02110000
        TOS := IOQP(QMISC); << QMISC STAYS ON TOS THROUGHOUT DRIVER >>  02112000
        if = and                    << no retries, etc >>      <<03069>>02114000
           ILTP(ICPVA2) = INTERRUPT'2 and << norm EOP >>       <<03069>>02116000
           DITP(DSTAT) <> -1 then   << no PFAIL >>             <<03069>>02118000
        go to CONTXFER;                                        <<03074>>02120000
                                                               <<03069>>02122000
        IF DITP(DSTAT)=-1 THEN                                          02124000
          BEGIN << POWER FIAL >>                                        02126000
          DITP(X) := 0;                                                 02128000
          IF FUNCT=RSTAT THEN GO REQSTATUS ELSE GO DOXFER;              02130000
          END;                                                          02132000
                                                               <<03069>>02134000
        IF LIOQP.SFAIL THEN GOTO SIOFAILURE; <<GIP FAILED TO START I/O>>02136000
                                                               <<03069>>02138000
        IF ILTP(ICPVA0)<>0 THEN                                         02140000
          BEGIN << CHANNEL ERROR >>                                     02142000
          DITP(DSERR):= [8/2,8/DLOGERROR];                     <<03069>>02144000
          DITP(DLOGERROR):= ILTP(ICPVA0); <<LOG CHANNEL ERROR>><<01347>>02146000
          << log SIOP-relative location of failure >>          <<03069>>02148000
          DITP(DLOGSIOP) := GETDRT(DRTN,0) - ABSCHANP;         <<03069>>02150000
          ILTP(ICPVA0) := 0;                                            02152000
          IF LS0.RETRY<3  THEN   << Only allow 3 retries >>    <<03685>>02154000
            BEGIN                                                       02156000
            TOS.DBIT := 1;  << SET RETRY INDICATOR >>                   02158000
            TOS := TOS+1;   <<INCREASE RETRY COUNT>>                    02160000
            if FUNCT = RSTAT then                              <<03069>>02162000
              go to REQSTATUS                                  <<03069>>02164000
            else                                               <<03069>>02166000
              go to DOXFER;                                    <<03069>>02168000
                                                               <<03069>>02170000
            end                                                <<03685>>02172000
          else                                                 <<03685>>02174000
            begin                                              <<03685>>02176000
                                                               <<03685>>02178000
            << If the error is GIC timeout, we may have a  >>  <<03685>>02180000
            << powered-down disc controller.  At this point>>  <<03685>>02182000
            << we will print a "disaster" message on the   >>  <<03685>>02184000
            << console and launch a "special" idle channel >>  <<03685>>02186000
            << program that starts with a "WAIT" rather    >>  <<03685>>02188000
            << than issuing an "END" command to the disc   >>  <<03685>>02190000
            << controller.                                 >>  <<03685>>02192000
                                                               <<03685>>02194000
            if DITP(DLOGERROR) = %160004 then                  <<03685>>02196000
              begin  << Yep, it's a GIC timeout >>             <<03685>>02198000
              LS0.RETRY := 0;  << Zero retry counter >>        <<03685>>02200000
              LS0.TIMEOUT'WAIT := 1;                           <<03685>>02202000
              DISC'NOT'RESP(DITP);                             <<03685>>02204000
              tos := TIMEOUT'IDLE'CHANP;                       <<03685>>02206000
              go to STARTIOPROG;                               <<03685>>02208000
              end;                                             <<03685>>02210000
                                                               <<03685>>02212000
            end;                                               <<03685>>02214000
                                                               <<03685>>02216000
          TOS := CHANERR;                                               02218000
          GOTO BADEND;                                                  02220000
          END;                                                          02222000
                                                               <<03069>>02224000
        IF ILTP(ICPVA3) = CLEARISSUED THEN                              02226000
          BEGIN  << POWER UP DSJ SO ISSUE CLEAR >>                      02228000
          TOS.CLBIT := 1;                                               02230000
          ILTP(ICPVA3) := 0;                                            02232000
          END;                                                          02234000
                                                               <<03685>>02236000
        << Check if disc controller was powered-up >>          <<03685>>02238000
        tos.TIMEOUT'WAIT := 0;                                 <<03685>>02240000
        if <> then    << Yep, it was >>                        <<03685>>02242000
          tos.CLBIT := 1;                                      <<03685>>02244000
                                                               <<03069>>02246000
        << Check Recalibrate Bit >>                            <<03069>>02248000
        TOS.CBIT := 0;                                                  02250000
        IF <> THEN GO DOXFER;                                           02252000
                                                               <<03069>>02254000
        << Check Clear bit >>                                  <<03069>>02256000
        TOS.CLBIT := 0;                                                 02258000
        if <> then                                             <<03685>>02260000
          if FUNCT = RSTAT then                                <<03685>>02262000
            go to REQSTATUS                                    <<03685>>02264000
          else                                                 <<03685>>02266000
            go to DOXFER;                                      <<03685>>02268000
        IF FUNCT=RSTAT OR ILTP(ICPVA1)=0 THEN ERR:=0                    02272000
        ELSE                                                            02274000
          BEGIN << ERROR RETURN >>                                      02276000
          ERR := DITP(DSTAT1).ERRCODE;                                  02278000
          ILTP(ICPVA1) := 0;                                            02280000
          IF NOT LIOQP(QMISC).EBIT LAND NOT LIOQP(QMISC).SBIT THEN      02282000
            BEGIN                                                       02284000
          <<------------------------------------                        02286000
            HAD AN ERROR--CHECK IF CORRECTABLE                          02288000
          ------------------------------------>>                        02290000
            IF ERR=CDERR THEN                                           02292000
              BEGIN <<DO REQ SYNDROME ON CORRECTABLE ERROR>>            02294000
              CHANP(RSYNP9) := @DITP(SYNDRET)+SYSDB;                    02296000
              TOS.SBIT := 1;                                            02298000
              CHANP(CMD8) := REQSYNOP+UNIT;                             02300000
                                                               <<03069>>02302000
              TOS := RSYNP-JUMPOFFSET; <<RELATIVE JUMP ADDRESS>>        02304000
              GO STARTIOPROG;                                           02306000
              END;                                                      02308000
            TOS.EBIT := 1;                                              02310000
            END;                                                        02312000
          END;  << ERROR RETURN >>                                      02314000
                                                                        02316000
        << Check Request Syndrome Bit >>                       <<03069>>02318000
        TOS.SBIT := 0;                                                  02320000
        IF <> THEN                                                      02322000
          BEGIN                                                         02324000
          <<----------------------------                                02326000
            COMPLETED REQUEST SYNDROME                                  02328000
          ---------------------------->>                                02330000
          TOS := DITP(SYNDRET).ERRCODE;                                 02332000
          TOS := DITP(SYNDRET1);                                        02334000
          TOS := DITP(SYNDRET2);                                        02336000
          DDITP(CEDA) := TOS; << PHYSICAL DISC ADRESS OF ERROR >>       02338000
          IF TOS = CDERR THEN                                           02340000
            BEGIN << ERROR IS CORRECTABLE >>                            02342000
            TOS := CONVERTADR - DDITP(CLDA); << RELATIVE SECTOR CNT >>  02344000
            XCNT := TOS&LSL(7); << RELATIVE XFER COUNT >>               02346000
            I := TOS; << ZERO I >>                                      02348000
            IF SBFLG THEN BUFADR:= DITP(CDBA)       <<SYSTEM BU<<03069>>02350000
            ELSE BUFADR := DITP(CDBA) + XCNT; << DATA SEG >>            02352000
            BUFADR:=BUFADR+DITP(SYNDRET3); << DATA OFFSET IN SECTOR >>  02354000
            BUFCNT:=DITP(CWC)-XCNT-DITP(SYNDRET3); << ADRESS FENCE >>   02356000
            DO << CORRECT THE DATA ERROR IN MEMORY AND CONTINUE XFER >> 02358000
            IF 0<=(DITP(SYNDRET3)+I)<=127 AND (BUFCNT-I)>0 THEN         02360000
              BEGIN                                                     02362000
              TOS := BANK;                                              02364000
              TOS := BUFADR + I;                                        02366000
              ASMB(LSEA);                                               02368000
              TOS := TOS XOR LDITP(SYNDRET4+I);                         02370000
              ASMB(SSEA);                                               02372000
              DDEL;                                                     02374000
              END                                                       02376000
            UNTIL (I:=I+1) >= 3;                                        02378000
            DITP(CWC) := XCNT + 128;                                    02380000
            GO TO CONTXFER;                                             02382000
            END;                                                        02384000
          DITP(DSTAT1) := DITP(SYNDRET); << SET ERROR STATUS FOR EXAM >>02386000
          TOS.EBIT := 1; << SET E BIT TO GET INTO ERROR ANALYSIS >>     02388000
          END;                                                          02390000
                                                                        02392000
        TOS.EBIT := 0;                                                  02394000
        IF <> THEN                                                      02396000
          BEGIN                                                         02398000
          <<-------------------------                                   02400000
            ERROR STATUS COMPLETION                                     02402000
          ------------------------->>                                   02404000
          ERR := DITP(DSTAT1).ERRCODE;                                  02406000
         if ERR=%23 and LDITP(DSTAT2).SEEKCHECK or ERR=%20 then<<02631>>02408000
           if FUNCT=READ and CHANP(DXFP44)=0 then              <<03069>>02410000
                   <<                                                   02412000
                     NOT REALLY AN ERROR - DISC BUFFERING CAUSED        02414000
                     ATTEMPT TO TRANSFER FROM DEFECTIVE TRACK           02416000
                     WHICH FOLLOWED AREA FROM WHICH TRANSFER            02418000
                     WAS DESIRED                                        02420000
                  >>                                                    02422000
            GOTO GOODEND;                                               02424000
          DITP(DMISC).L'STAT'ERR:=1; << SAVE ERROR INDICATION >>        02426000
          DITP(DSERR):= [8/17,8/DSTAT1];<<SET ERROR INDICATOR>><<01347>>02428000
          IF ERR = %23 AND LDITP(DSTAT2).DRVNOTRDY THEN                 02430000
            BEGIN << DRIVE NOT READY >>                                 02432000
            IF NOT SYSUP THEN GO DOXFER;                                02434000
                                                                        02436000
              COMMENT:  **************************************          02438000
                SINCE IT IS SO DIFFICULT TO TO DIRECT I/O, IT           02440000
              IS MUCH SIMPLER TO LOOP HERE IN THE DRIVER UNTIL          02442000
              THE DISC BECOMES READY                                    02444000
              ************************************************;         02446000
            << If NOT SYSUP then SIODM will not fire >>        <<03069>>02448000
            << off idle channel program.             >>        <<03069>>02450000
                                                                        02452000
            LDEVNOTRDY(DITP); << SEND NOT READY MESSAGE TO CONSOLE >>   02454000
            TOS := WAIT;                                                02456000
            TOS := 7;                                                   02458000
            GO TO CHECKSBUF;                                            02460000
            END;                                                        02462000
                                                               <<03782>>02464000
          << INCREMENT RETRY COUNTER >>                        <<03782>>02466000
          TOS := TOS + 1;                                      <<03782>>02468000
                                                               <<03782>>02470000
          IF ERR = 7 THEN                                               02472000
            BEGIN                                                       02474000
            <<----------------------------                              02476000
              CYCLINDER MISCOMPARE ERROR                                02478000
            ---------------------------->>                              02480000
            IF S0.RETRY<7 THEN                                 <<03069>>02482000
              BEGIN                                                     02484000
                                                                        02486000
              <<-------------------                                     02488000
                TRY A RECALIBRATE                                       02490000
              ------------------->>                                     02492000
                                                                        02494000
              TOS.CBIT := 1;                                            02496000
                                                               <<03782>>02498000
              DITP(CURCYL) := 0; << CYL # IS 0 >>                       02500000
              CHANP(CMD17) := RECALIBRATE + UNIT;                       02502000
              TOS := RECALP-JUMPOFFSET; <<RELATIVE JUMP ADDRESS>>       02504000
              GO TO STARTIOPROG;                                        02506000
              END;                                                      02508000
            END;                                                        02510000
                                                               <<03782>>02512000
          TOS.DBIT := 1;  << SET RETRY INDICATOR >>                     02514000
                                                               <<03782>>02516000
                                                               <<03069>>02518000
          << If this is a DATAOVERRUN, we will log only >>     <<03069>>02520000
          << every seventh attempt, as not to fill log  >>     <<03069>>02522000
          << files.                                     >>     <<03069>>02524000
          if ERR = DATAOVRRUN then                             <<03069>>02526000
            if LS0.RETRY < 7 then                              <<03069>>02528000
              DITP(DSERR) := 0  << Don't log the error >>      <<03069>>02530000
            else                                               <<03069>>02532000
              tos.RETRY := 0;   << Don't expire count >>       <<03069>>02534000
                                                               <<03069>>02536000
          IF LS0.RETRY<7 THEN                                  <<03069>>02538000
          IF ERR=DATAOVRRUN OR FUNCT<>FORMAT THEN                       02540000
            GO DOXFER; << RETRY FORMAT ONLY ON DATA OVERRUN >>          02542000
                                                                        02544000
          <<---------------------------                                 02546000
            ERROR CONNAT BE RECOVERED                                   02548000
          --------------------------->>                                 02550000
                                                                        02552000
          IF FUNCT = READSPD OR FUNCT=FORMAT THEN                       02554000
          IF (%7<=ERR<=%11) OR (%17<=ERR<=%21) THEN                     02556000
          BEGIN                                                         02558000
            DITP(DSERR) := 0;  << DON'T LOG AS ERROR >>                 02560000
            TOS := (ERR & LSL(3)) + 4;  << RETURN ERROR >>              02562000
            GO TO BADEND;                                               02564000
            END;                                                        02566000
                                                                        02568000
          IF 7 <= ERR <= %11 THEN                                       02570000
          IF FOREIGN THEN GO TO DISCXFER                       <<01115>>02572000
          ELSE                                                 <<01115>>02574000
            BEGIN << TRACK SPECIFIC ERROR >>                            02576000
            TOS.RETRY := 0; << CLEAR RETRY CNT FOR TRACK MAP >>         02578000
            TOS.MBIT := 1;                                              02580000
            IF <> THEN GO TO DISCXFER; << ERROR ON MAP XFER >>          02582000
            TOS := DITP(SYSBUFA);                                       02584000
            IF = THEN                                                   02586000
              BEGIN << GET A SYSTEM BUFFER >>                           02588000
              TOS := GETSBUF(2); << GET A BUFFER, pri or second<<03069>>02590000
              ASMB(DELB,DUP);                                           02592000
              IF = THEN GO TO DISCXFER; << NO MORE BUFFERS >>           02594000
              DITP(X) := TOS;                                           02596000
              END;                                                      02598000
            DITP(CDBA) := TOS + SYSDB; << SET BUFFER ADRESS >>          02600000
            ASMB(DZRO,INCA); << DOUBLE ONE >>                           02602000
            DDITP(CLDA) := TOS;                                         02604000
            DITP(WCR) := 128;                                           02606000
            FUNCT := READ; << SET UP XFER OF TRK MAP >>                 02608000
            BANK := 0; << ZERO BANK FOR SYSBUF XFER >>                  02610000
            GO TO DOXFER;                                               02612000
            END;                                                        02614000
          IF ERR = %23 AND LDITP(DSTAT2).SEEKCHECK                      02616000
            OR ERR = %20 THEN                                           02618000
            BEGIN                                                       02620000
            <<----------------------                                    02622000
              INVALID DISC ADDRESS                                      02624000
            ---------------------->>                                    02626000
BADDISCADR:                                                             02628000
            TOS := INVDSKADR;                                           02630000
BADEND:                                                                 02632000
            IOQP(QWBCT) := 0;                                           02634000
            TOS := 5;                                                   02636000
            GO TO CHECKSBUF;                                            02638000
            END;                                                        02640000
          IF ERR = %12 OR ERR = %16 THEN                                02642000
            BEGIN << TRANSFER ERROR >>                                  02644000
            TOS := XFERERROR;                                           02646000
            GO TO BADEND;                                               02648000
            END;                                                        02650000
UNITFAIL:                                                               02652000
          TOS := UNITFAILURE;                                           02654000
          GO TO BADEND;                                                 02656000
          END;                                                          02658000
                                                                        02660000
        ASMB(TBC MBIT');                                                02662000
        IF <> THEN                                                      02664000
          BEGIN << ENTRING BAD TRACK INTO BAD TRACK TABLE >>            02666000
          <<-----------------------------------------                   02668000
            ENTERING BAD TRACK INTO BAD TRACK TABLE                     02670000
          ----------------------------------------->>                   02672000
          TOS.WBIT := 1;                                                02674000
          IF <> THEN                                                    02676000
            BEGIN                                                       02678000
            <<---------------------                                     02680000
              TRACK MAP COMPLETED                                       02682000
            --------------------->>                                     02684000
DISCXFER:                                                               02686000
            TOS := DSCXFRERR;                                           02688000
            GO TO BADEND;                                               02690000
            END;                                                        02692000
          @BADTRACK := DITP(SYSBUFA);                                   02694000
          IF BADTRACK >= 120 THEN GO TO DISCXFER; << TABLE FULL >>      02696000
          X := CEDA;                                                    02698000
          TOS := CONVERTADR;                                            02700000
          TOS := DISCINFO(INDEX+SECPERTRK);                             02702000
          ASMB(LDIV,DEL);                                               02704000
          TOS := TOS&LSL(2);                                            02706000
          IF LDITP(DSTAT1).SPARE THEN TOS := TOS + 1;                   02708000
          << SET ALTERNATE TRACK BIT >>                                 02710000
          X := 0;                                                       02712000
          WHILE X < BADTRACK DO                                         02714000
           BEGIN << IS TRACK ALREADY IN THE TABLE >>                    02716000
            ASMB(DUP,INCX);                                             02718000
            IF TOS = BADTRACK(X) THEN GO TO DISCXFER;                   02720000
            << ITS ALREADY IN THE TABLE >>                              02722000
            END;                                                        02724000
          BADTRACK := BADTRACK + 1; << INC TRACK COUNT >>               02726000
          BADTRACK(X:=X+1) := TOS; << ENTER TRACK >>                    02728000
          FUNCT := WRITE;                                               02730000
          BANK := 0;                                                    02732000
          GO TO DOXFER;                                                 02734000
          END;                                                          02736000
                                                                        02738000
        IF FUNCT=RSTAT THEN                                             02740000
          BEGIN << MOVE STATUS TO USER STACK >>                         02742000
          ILTP(ICPVA1) := 0;  << CLEAR WORD 1 OF CPVA>>                 02744000
RSTATRET:                                                               02746000
          TOS := BANK;                                                  02748000
          TOS := DITP(CDBA);                                            02750000
          TOS := 0;                                                     02752000
          TOS := @DITP(DSTAT1)+SYSDB;                                   02754000
          TOS := DITP(WCR);                                             02756000
          IF S0>4 THEN                                                  02758000
            BEGIN                                                       02760000
            DEL;                                                        02762000
            TOS := 4;                                                   02764000
            END;                                                        02766000
          ASMB(MABS 5);                                                 02768000
          GO TO GOODEND;                                                02770000
          END;                                                          02772000
                                                                        02774000
CONTXFER:                                                               02776000
        TOS := DITP(WCR) - DITP(CWC);                                   02778000
        IF <= THEN                                                      02780000
          BEGIN << XFER COMPLETE >>                                     02782000
GOODEND:                                                                02784000
                                                               <<03685>>02786000
          << If normal channel program end, IDLE channel >>    <<03685>>02788000
          << program was started, so don't let SIODM     >>    <<03685>>02790000
          << start it all over again.                    >>    <<03685>>02792000
          if ILTP(ICPVA2) = INTERRUPT'2 then                   <<03685>>02794000
            begin                                              <<03685>>02796000
                                                               <<03685>>02798000
            << Set flag that IDLE channel program is running >><<03685>>02800000
            ILTP(IFLAG).WAITPROG := 1;                         <<03685>>02802000
                                                               <<03685>>02804000
            << Zero current DIT pointer in ILT >>              <<03685>>02806000
            ILTP(ICDP) := 0;                                   <<03685>>02808000
                                                               <<03685>>02810000
            end;                                               <<03685>>02812000
                                                               <<03685>>02814000
          TOS := SUCCESSFUL;                                            02816000
          TOS := %5;                                                    02818000
CHECKSBUF:                                                              02820000
          TOS := DITP(SYSBUFA);                                         02822000
          IF <> THEN                                                    02824000
            BEGIN                                                       02826000
            RETURNSBUF(*);                                              02828000
            DITP(X) := 0;                                               02830000
            END ELSE DEL;                                               02832000
          GO TO EXIT;                                                   02834000
          END;                                                          02836000
        DITP(WCR) := TOS; << SET REMAINING WORD COUNT >>                02838000
        IF FUNCT <= WRITE THEN                                          02840000
                                                               <<03069>>02842000
             DITP(X) := DITP(CWC) + DITP(CDBA); << DATA SEG >> <<03069>>02844000
        TOS := DITP(CWC)&LSR(7);                                        02846000
        ASMB(ZERO,XCH); << UPDATE DISC ADRESS >>                        02848000
        DDITP(X) := TOS + DDITP(CLDA);                                  02850000
$PAGE "DATA TRANSFER SIOP-BUILD AREA"                          <<03069>>02852000
        <<-----------------------------                                 02854000
          NOTE!!!!!                                                     02856000
            QMISC MUST BE ON TOS HERE                                   02858000
        ----------------------------->>                                 02860000
                                                                        02862000
        <<---------------------------------                             02864000
          BUILD AND START THE I/O PROGRAM                               02866000
        --------------------------------->>                             02868000
                                                                        02870000
DOXFER:                                                                 02872000
        << Perform old status return housekeeping >>           <<03069>>02876000
                                                               <<03069>>02878000
        << Last status is no longer valid >>                   <<03069>>02880000
        DITP(DMISC).L'STAT'ERR := 0;                           <<03069>>02882000
        << Clear SEEK status >>                                <<03069>>02884000
        DITP(SEEKSTAT1) := 0;                                  <<03069>>02886000
                                                               <<03069>>02888000
        << Check if write to sector "0" is permitted >>        <<03069>>02890000
        tos := DDITP(CLDA); << Logical disc address >>         <<03069>>02892000
        if = and       << if sector "0" >>                     <<03069>>02894000
           (WRITE<=FUNCT<=RSTAT) and << not a read >>          <<03069>>02896000
           not FOREIGN then   << not a FOREIGN disc >>         <<03069>>02898000
          go to BADDISCADR;                                    <<03069>>02900000
                                                               <<03069>>02902000
        << Compute physical disc address >>                    <<03069>>02904000
        tos := DISCINFO(INDEX + SECPERCYL);                    <<03069>>02906000
        asmb(ldiv);           << Compute address >>            <<03069>>02908000
                                                               <<03069>>02910000
        << Check if address is valid for this disc >>          <<03069>>02912000
        if OVERFLOW or        << Divide gave strange result >> <<03069>>02914000
           LSM1 > logical(DISCINFO(INDEX + MAXCYL)) then       <<03069>>02916000
          go to BADDISCADR;                                    <<03069>>02918000
                                                               <<03069>>02920000
        << Compute head/sector >>                              <<03069>>02922000
        tos := DISCINFO(INDEX + SECPERTRK);                    <<03069>>02924000
        asmb(div,xch);                                         <<03069>>02926000
                                                               <<03069>>02928000
        << Combine C/H/S and save in DIT >>                    <<03069>>02930000
        tos := tos + DISCINFO(INDEX + HEADOFFSET);             <<03069>>02932000
        tos := tos & lsl(8) + tos;   << head/sector >>         <<03069>>02934000
                                                               <<03069>>02936000
        << Set up channel program >>                           <<03069>>02938000
                                                               <<03069>>02940000
        << Move transfer parameters to CMD area of channel pgm <<03069>>02942000
                                                               <<03069>>02944000
        << Save physical disc address in DIT & seek area >>    <<03069>>02946000
        DDITP(CPDA) := DCHANP(CMD2') := tos;                   <<03069>>02948000
                                                               <<03069>>02950000
        CHANP(CMD1) := SEEK + UNIT;      << SEEK command >>    <<03069>>02952000
        << SEEK and ADDRESS RECORD are the same >>             <<03069>>02954000
                                                               <<03069>>02956000
        << if the function is READSPD, we do not want the >>   <<03069>>02958000
        << auto-seek to alternate track to occur. >>           <<03069>>02960000
        CHANP(CMD14) := DISCINFO(INDEX + FILEMASK);            <<03069>>02962000
                                         << store file mask  >><<03069>>02964000
                                                               <<03069>>02966000
        << Modify channel instructions >>                      <<03069>>02968000
                                                               <<03069>>02970000
        << normally, we will jump to transfer immediatly >>    <<03069>>02972000
        << after the SEEK has completed.                 >>    <<03069>>02974000
        CHANP(DXFP25) := 12;                                   <<03069>>02976000
                                                               <<03069>>02978000
        << Store channel R/W command Q-relative          >>    <<03069>>02980000
        CXFER := CHANRW(FUNCT);                                <<03069>>02982000
                                                               <<03069>>02984000
        << Store disc transfer order                     >>    <<03069>>02986000
        DISCOP := XFEROP(FUNCT) + UNIT;                        <<03069>>02988000
                                                               <<03069>>02990000
        << Limit maximum transfer size >>                      <<03069>>02992000
        if DITP(WCR) < MAXTRANSFER then                        <<03069>>02994000
          tos := DITP(X)     << use requested length    >>     <<03069>>02996000
        else                                                   <<03069>>02998000
          tos := MAXTRANSFER; << use max possible length>>     <<03069>>03000000
                                                               <<03069>>03002000
        << if zero transfer count, complete transfer >>        <<03069>>03004000
        if = then                                              <<03069>>03006000
          go to GOODEND;                                       <<03069>>03008000
                                                               <<03069>>03010000
        << * * XFER length is left on TOS * *           >>     <<03069>>03012000
                                                               <<03069>>03014000
        << if split disc, we must see if there is       >>     <<03069>>03016000
        << possible platter wrap-around.                >>     <<03069>>03018000
        if 10 <= SUBTYPE <= 11 or                              <<03069>>03020000
           SUBTYPE = 4 then                                    <<03069>>03022000
          begin                                                <<03069>>03024000
          tos := DISCINFO(INDEX + SECPERCYL);                  <<03069>>03026000
          tos := DDITP(CLDA);                                  <<03069>>03028000
          tos := S2;                                           <<03069>>03030000
          asmb(ldiv,delb,sub);                                 <<03069>>03032000
                                                               <<03069>>03034000
          << transfer count to end of cylinder >>              <<03069>>03036000
          tos := tos & lsl(7);                                 <<03069>>03038000
          << compare transfer limit >>                         <<03069>>03040000
          asmb(ddup,lcmp);                                     <<03069>>03042000
          if < then  << must use this new XFER length >>       <<03069>>03044000
            asmb(xch);                                         <<03069>>03046000
          DELB;      << delete larger of 2 lengths    >>       <<03069>>03048000
          end;                                                 <<03069>>03050000
                                                               <<03069>>03052000
        << triplicate word count on tos >>                     <<03069>>03054000
        asmb(dup,dup);                                         <<03069>>03056000
                                                               <<03069>>03058000
        << store word and sector count in DIT >>               <<03069>>03060000
        DITP(CWC) := tos;                                      <<03069>>03062000
        DITP(SCOUNT) := tos & lsr(7);                          <<03069>>03064000
        BUFADR := DITP(CDBA);                                  <<03069>>03066000
                                                               <<03069>>03068000
        << if this is not a read or write, we will perform >>  <<03069>>03070000
        << exception processing, as Reads and Writes account>> <<03069>>03072000
        << for a majority of the driver requests.          >>  <<03069>>03074000
        CHANP(CMD17) := DISCOP;                                <<03069>>03076000
        CHANP(DXFP52) := 19;     << DSJ-0, go to INT-HALT2 >>  <<03069>>03078000
                                                               <<03069>>03080000
        <<  word count of XFER should be on tos here >>        <<03069>>03082000
        CHANP(DXFP43) := CXFER;    << 1st word of XFER order >><<03069>>03084000
        CHANP(X:=X+1) := tos & lsl(1); << byte count >>        <<03069>>03086000
        CHANP(X:=X+1) := 0;                                    <<03069>>03088000
        CHANP(X:=X+1) := BANK.DSTBANKFIELD; <<bank, allow upd>><<03069>>03090000
        CHANP(X:=X+1) := BUFADR;   << buffer address     >>    <<03069>>03092000
                                                               <<03069>>03094000
        << now, perform all the conditional funtion processing <<03069>>03096000
        if FUNCT > 1 then                                      <<03069>>03098000
          begin   << this is a low-usage function >>           <<03069>>03100000
                                                               <<03069>>03102000
          << Turn off SBUF flag if not really used >>          <<03069>>03104000
          if FOPEN <= FUNCT <= RSTAT then                      <<03069>>03106000
            SBFLG := false;                                    <<03069>>03108000
                                                               <<03069>>03110000
          << if function is zero or blank fill, mod BANK >>    <<03069>>03112000
          << number of transfer                          >>    <<03069>>03114000
          if FILLZ <= FUNCT <= FILLB then                      <<03069>>03116000
            CHANP(DXFP46) := %4000; << bank zero >>            <<03069>>03118000
                                                               <<03069>>03120000
          if FUNCT = INITIALIZE then                           <<03069>>03122000
            begin                                              <<03069>>03124000
            tos := BANK;                                       <<03069>>03126000
            tos := BUFADR - 2;                                 <<03069>>03128000
                                                               <<03069>>03130000
            << load initize address from buffer >>             <<03069>>03132000
            asmb(ldea);                                        <<03069>>03134000
            DCHANP(CMD10') := DDITP(INITADDR) := tos;          <<03069>>03136000
                                                               <<03069>>03138000
            << load alternate info from BUFADR - 3 >>          <<03069>>03140000
            asmb(deca;lsea;delb,delb);                         <<03069>>03142000
            tos.(15:1) := 0;                                   <<03069>>03144000
            if <> then                                         <<03069>>03146000
              begin                                            <<03069>>03148000
                                                               <<03069>>03150000
              << find alternate track >>                       <<03069>>03152000
              CHANP(DXFP25) := 0; << do ADDREC, VERIFY >>      <<03069>>03154000
              CHANP(CMD15) := VERIFYOP + UNIT;                 <<03069>>03156000
              CHANP(CMD16) := 1;                               <<03069>>03158000
              DCHANP(CMD10') := DDITP(INITADDR);               <<03069>>03160000
              end                                              <<03069>>03162000
            else                                               <<03069>>03164000
              begin                                            <<03069>>03166000
                                                               <<03069>>03168000
              << jump to INIT command >>                       <<03069>>03170000
              CHANP(CMD14) := %7402;     << FILEMASK        >> <<03069>>03172000
              CHANP(DXFP25) := 5; << Jump around verify >>     <<03069>>03174000
              end;                                             <<03069>>03176000
                                                               <<03069>>03178000
            CHANP(CMD17) := tos & lsl(12) + INITOP + UNIT;     <<03069>>03180000
            end;   << of INITIALIZE function >>                <<03069>>03182000
                                                               <<03069>>03184000
          if FUNCT = FORMAT then                               <<03069>>03186000
            begin                                              <<03069>>03188000
            CHANP(DXFP52) := 0;  << to execute verify >>       <<03069>>03190000
            CHANP(CMD14) := %7402;   << filemask      >>       <<03069>>03192000
            CHANP(X:=X+1) := VERIFYOP + UNIT; << verify >>     <<03069>>03194000
            CHANP(CMD16) := DITP(SCOUNT); << sector cnt >>     <<03069>>03196000
            CHANP(X:=X+1) := INITOP + UNIT; << initialize >>   <<03069>>03198000
            end;  << of FORMAT special case >>                 <<03069>>03200000
                                                               <<03069>>03202000
          << turn-off auto-spare function if READSPD >>        <<03069>>03204000
          if FUNCT = READSPD then                              <<03069>>03206000
            CHANP(CMD14).(13:1) := 0;                          <<03069>>03208000
                                                               <<03069>>03210000
          end;  << of  special case function code >>           <<03069>>03212000
                                                               <<03069>>03214000
        << continue with common function code >>               <<03069>>03216000
        REQSTATSIO;                                            <<03069>>03218000
                                                               <<03069>>03220000
        << channel pgm start address >>                        <<03069>>03222000
        tos := DXFP0- JUMPOFFSET;                              <<03069>>03224000
                                                                        03226000
        <<-----------------------                                       03228000
          START THE I/O PROGRAM                                         03230000
        ----------------------->>                                       03232000
                                                                        03234000
STARTIOPROG:                                                            03236000
        CHANP(1) := TOS; << SET THE JUMP ADRESS >>                      03238000
        CHANQFLG := true;  << no IDLE Chanp. here >>           <<03685>>03240000
                                                               <<03069>>03242000
        << We must assume that a normal SIO program  >>        <<03069>>03244000
        << termination will not occur, so we must    >>        <<03069>>03246000
        << tell SIODM to fire-off the IDLE channel   >>        <<03069>>03248000
        << program (just in case!).                  >>        <<03069>>03250000
        ILTP(ICPVA2) := 0;  << Flag non-std termination >>     <<03069>>03252000
                                                               <<03069>>03254000
        START'HPIB(DITP,CHANP,CHANQFLG);                       <<01301>>03256000
        IF > THEN                                                       03258000
          BEGIN                                                         03260000
          <<----------                                                  03262000
            NO START                                                    03264000
          ---------->>                                                  03266000
SIOFAILURE:                                                             03268000
          TOS := BADSIO;                                                03270000
          GO TO BADEND;                                                 03272000
          END;                                                          03274000
        IOQP(QMISC) := TOS;                                             03278000
        TOS := WAIT;                                                    03280000
        TOS := %13;                                                     03282000
EXIT:                                                                   03284000
        MSTATE := TOS;                                                  03286000
        IOQP(QSTAT).STAT := TOS;                                        03288000
        RETURN;                                                         03292000
                                                                        03294000
FILLBLANK:                                                              03296000
        TOS := "  ";                                                    03298000
        GO TO FC;                                                       03300000
FILLZERO:                                                               03302000
        TOS := 0;                                                       03304000
FC:                                                                     03306000
        CHANP(CMD18) := TOS;                                            03308000
        DITP(CDBA) := ABSCHANP+CMD18;                                   03310000
        GO TO DOXFER;                                                   03312000
                                                                        03314000
        <<---------------------------                                   03316000
          INITIALIZE STATUS PROGRAM                                     03318000
        --------------------------->>                                   03320000
                                                                        03322000
REQSTATUS:                                                              03324000
        IF LDITP(DMISC).L'STAT'ERR THEN GOTO RSTATRET;                  03326000
        REQSTATSIO;                                                     03328000
        TOS := RSTAP-JUMPOFFSET;  <<RELATIVE JUMP ADDRESS>>             03330000
        GO STARTIOPROG;                                                 03332000
                                                               <<03069>>03334000
        END;                                                            03336000
ASMB(                                                                   03338000
   PCAL SIODM;    << MONITOR >>                                         03340000
   PCAL MHDDVR;   << INITIATOR >>                                       03342000
   PCAL MHDDVR;   << COMPLETOR >>                                       03344000
   CON 0;         << I/O PROCESS PROCEDURE >>                           03346000
   PCAL DISCINIT; << INITIALIZATION PROCEDURE >>                        03348000
   CON 1;         << # OF INTERRUPT PROCEDURES >>                       03350000
   PCAL GIP'HPIB);<< INTERRPUT HANDLER >>                      <<01301>>03352000
END.                                                                    03354000
