$CONTROL MAP,CODE,USLINIT                                               00010000
  <<    HIOMDSC1,MODULE 37 - 7905/7906/7920/7925 DISC DRIVER   <<17513>>00015000
<< HP32002C MPE SOURCE C.00.00 BASE SOURCE FOR MPE V >>        <<17513>>00020000
<< COPYRIGHT     "(C) COPYRIGHT HEWLETT-PACKARD CO. 1980.           >>  00025000
<<     THIS PROGRAM MAY BE USED WITH ONE COMPUTER SYSTEM AT A       >>  00030000
<<     TIME AND SHALL NOT OTHERWISE BE RECORDED, TRANSMITTED OR     >>  00035000
<<     STORED IN A RETRIEVAL SYSTEM.  COPYING OR OTHER REPRODUCTION >>  00040000
<<     OF THIS PROGRAM EXCEPT FOR ARCHIVAL PURPOSES IS PROHIBITED   >>  00045000
<<     WITHOUT THE PRIOR WRITTEN CONSENT OF HEWLETT-PACKARD COMPANY.>>  00050000
<< **** Note - Dollar Copyright cannot be used with this module *** >>  00055000
$CONTROL PRIVILEGED,UNCALLABLE,MAIN=IOMDISC1                            00060000
$TP                                                                     00065000
$TITLE "7905/7906/7920/7925 MOVING HEAD DISC DRIVER"           <<03069>>00070000
                                                                        00075000
DRIVER CALLING SEQUENCE                                                 00080000
                                                                        00085000
   DRIVER REQUEST CODES                                                 00090000
     0 - READ                                                           00095000
     1 - WRITE                                                          00100000
     2 - FILE OPEN                                                      00105000
     3 - FILE CLOSE                                                     00110000
     4 - DEVICE CLOSE                                                   00115000
     5 - FILL WITH ZEROS                                                00120000
     6 - FILL WITH BLANKS                                               00125000
     7 - REQUEST STATUS                                                 00130000
           TO BE COMPATIBLE WITH SERIES III, STATUS REQUEST WILL        00135000
           CHECK TO SEE IF LAST TRANSFER TO THE UNIT FOR WHICH          00140000
           THIS REQUEST IS FOR, ENDED IN AN ERROR. IF LAST TRANSFER     00145000
           DID END IN AN ERROR, THEN THE STATUS FROM THAT TRANSFER      00150000
           WILL BE TRANSFERRED, OTHERWISE A NEW STATUS REQUEST WILL     00155000
           BE GENERATED AND THAT STATUS RETURNED.                       00160000
     8 - FORMAT TRACK                                                   00165000
     9 - INITIALIZE TRACK                                               00170000
    10 - READ FULL SECTOR                                               00175000
    11 - WRITE LABEL (SECTOR 0)                                         00180000
    12 - READ (WITH SPARING DISABLED)                                   00185000
    15 - REQUEST STATUS (SAME AS FUNCTION CODE 7)                       00190000
                                                                        00195000
   COUNT - WORD/BYTE COUNT. ODD BYTE COUNT WILL BE ROUNDED UP.          00200000
                                                                        00205000
   PARAMETERS P1 AND P2 FORM A DOUBLE WORD DISC ADRESS FOR ALL XFERS.   00210000
                                                                        00215000
DRIVER RETURN CODES                                                     00220000
                                                                        00225000
   GENERAL(13:3)        QUALIFYING(8:5)               OVERALL(8:8)      00230000
   0 - PENDING          1 - WAIT FOR COMPLETION       %10               00235000
   1 - SUCCESSFUL                                     %01               00240000
   4 - IRRECOVERABLE    0 - INVALID FUNCTION          %04               00245000
       ERROR            1 - TRACK ERROR               %14               00250000
                        3 - XMISSION ERROR            %34               00255000
                        4 - SIO FAILURE               %44               00260000
                        5 - UNIT FAILURE              %54               00265000
                        6 - INVALID DISC ADRESS       %64               00270000
                        %12 - SYSTEM ERROR            %124              00275000
                        %14 - CHANNEL ERROR           %144              00280000
                                                                        00285000
DISC CONTROLLER HARDWARE STATUS RETURNS                                 00290000
                                                                        00295000
   STATUS 1                                                             00300000
   BITS     USE                                                         00305000
      0      SPARE TRACK                                                00310000
      1      PROTECTED TRACK                                            00315000
      2      DEFECTIVE TRACK                                            00320000
   3-7      TERMINATION STATUS                                          00325000
               0 - NORMAL COMPLETION                                    00330000
               1 - ILLEGAL COMMAND                                      00335000
               7 - CYL COMPARE ERROR                                    00340000
             %10 - UNCORRECTABLE DATA ERROR                             00345000
             %11 - HEAD-SECTOR COMPARE ERROR                            00350000
             %12 - SIO PROGRAM ERROR                                    00355000
             %14 - END OF CYLINDER                                      00360000
             %16 - OVERRUN                                              00365000
             %17 - POSSIBLY CORRECTABLE DATA ERROR                      00370000
             %20 - ILLEGAL ACCESS TO SPARE TRACK                        00375000
             %21 -  ATTEMPT TO ACCESS DEFECTIVE TRACK                   00380000
             %22 - HEAD MOVEMENT DURING DATA OPERATION                  00385000
             %23 - DISC DRIVE (STATUS-2) ERROR                          00390000
             %26 - ATTEMPT TO WRITE ON PROTECTED TRACK                  00395000
             %27 - DRIVE UNAVAILABLE                                    00400000
             %37 - DRIVE ATTENTION                                      00405000
   8-12      UNUSED                                                     00410000
  13-15      UNIT NUMBER                                                00415000
                                                                        00420000
                                                                        00425000
                                                                        00430000
   STATUS 2 WORD                                                        00435000
      0      DRIVE ERROR                                                00440000
    6-9      DRIVE TYPE                                                 00445000
      8      ATTENTION                                                  00450000
      9      PROTECTED                                                  00455000
     10      FORMAT                                                     00460000
     11      FAULT                                                      00465000
     12      FIRST STATUS                                               00470000
     13      SEEK CHECK                                                 00475000
     14      DRIVE NOT READY                                            00480000
     15      DRIVE BUSY                                                 00485000
                                                                        00490000
***********************************************************    <<03069>>00495000
*         D I T   L A Y O U T                             *    <<03069>>00500000
***********************************************************    <<03069>>00505000
* Word * Variable Name * Description                      *    <<03069>>00510000
***********************************************************    <<03069>>00515000
* 0    * DFLAG         * (0:2) = 1 for disc               *    <<03069>>00520000
*      *               * (3:1) Set if SIODM is svcing     *    <<03069>>00525000
*      *               * (5:1) Set because this is multi  *    <<03069>>00530000
*      *               *       unit controller            *    <<03069>>00535000
*      *               * (7:1) SIOP active for this device*    <<03069>>00540000
*      *               * (8:1) Interrupt occured for dev  *    <<03069>>00545000
*      *               * (9:1) Set because moving head    *    <<03069>>00550000
*      *               * (12:4) SIODM state               *    <<03069>>00555000
* 1    * DLINK         * SYSDB pntr to next DIT in        *    <<03069>>00560000
*      *               * controller queue                 *    <<03069>>00565000
* 2    * DIOQP         * Current (active) disc request    *    <<03069>>00570000
* 3    * DLDEV         * (0:3) = 2 for HP-IB              *    <<03069>>00575000
*      *               * (8:8) = logical device number    *    <<03069>>00580000
* 4    * DDLTP         * SYSDB ptr to Driver Linkage Tbl  *    <<03069>>00585000
* 5    * DILTP         * SYSDB ptr to Interrupt Lnk Tbl   *    <<03069>>00590000
* 6    * DRQST         * Set to -1 when powerfail         :    <<03069>>00595000
* 7    * DSERR         * (0:8)-# of words to log          *    <<03069>>00600000
*      *               * (8:8)-DIT relative address to log*    <<03069>>00605000
* 8    * DMAMQ         * Ptr to head of disc requests     *    <<03069>>00610000
* 9    * DMAMQT        * Ptr to tail of disc requests     *    <<03069>>00615000
* 10   * DUNIT         * (0:3)= 2 HPIB, (8:8) unit        *    <<06837>>00620000
* 11   * DLOGSIOP      * SIO program-relative abort addr  *    <<06837>>00625000
* 12-13* CPDA          * Current physical disc adr (C/H/S)*    <<03069>>00630000
* 14   * CDBA          * Current buffer address           *    <<03069>>00635000
* 15   * WCR           * Word cnt remaining to XFER       *    <<03069>>00640000
* 16   * CWC           * Word cnt to xfer                 *    <<03069>>00645000
* 17   * SYSBUFA       * Sys buffer address used to pro-  *    <<03069>>00650000
*      *               * cess defective track             *    <<03069>>00655000
* 18   * STAT1         * Status-1 return                  *    <<03069>>00660000
* 19   * STAT2         * Status-2 return                  *    <<03069>>00665000
* 20-21* CEDA          * Phys address of error on disc    *    <<03069>>00670000
* 22-28* REQSYN        * Request syndrome area            :    <<03069>>00675000
* 29   * SCOUNT        * Sector count to transfer         *    <<03069>>00680000
* 30-31* INITADR       * Phys adr to init track to        *    <<03069>>00685000
* 32   * DMISC         * (15:1)=L'STAT'ERR (last err stat)*    <<03069>>00690000
* 33-34* SEEKSTAT      * Cntlr status after seek in chanp *    <<03069>>00695000
* 35   * DLOGERROR     * CPVA word 0 upon channel abort   *    <<03069>>00700000
* 36   * CLDA          * Current logical sector address   *    <<06837>>00705000
***********************************************************    <<03069>>00710000
                                                               <<03069>>00715000
IOQ (Disc Request) element QMISC-                              <<03069>>00720000
                                                               <<03069>>00725000
DBIT    (0:1)   Retry is in progress                           <<03069>>00730000
SBIT    (1:1)   Request syndrome is in progress                <<03069>>00735000
EBIT    (2:1)   Error bit (err has occurred)                   <<03069>>00740000
MBIT    (3:1)   Reading defective track table into SYSBUF      <<03069>>00745000
WBIT    (4:1)   Writing defective track table to disc          <<03069>>00750000
TIM'WT  (5:1)   Waiting for disc controller to power-up        <<03685>>00755000
CBIT    (7:1)   Recalibrate in progress                        <<03069>>00760000
CLBIT   (8:1)   Clear in progress                              <<03069>>00765000
RETRY   (13:3)  Retry count (7 max except for overrun)         <<03069>>00770000
                                                               <<03069>>00775000
***********************************************************    <<03069>>00780000
*           I L T   F O R M A T                           *    <<03069>>00785000
***********************************************************    <<03069>>00790000
* Word * Variable * Description                           *    <<03069>>00795000
***********************************************************    <<03069>>00800000
* 0-3  * CPVAx    * Channel program variable area         *    <<03069>>00805000
*      * ICPVA0   * 0 - Channel abort status              *    <<03069>>00810000
*      * ICPVA1   * 1 - Unusual termination error codes   *    <<03069>>00815000
*      * ICPVA2   * 2 - Normal termination codes          *    <<03069>>00820000
*      * ICPVA3   * 3 - Clear issued successfully         *    <<03069>>00825000
* 4-5  * ??       * DMA abort address                     *    <<03069>>00830000
* 6    * ICPGM    * Startio address to use on deferred    *    <<03069>>00835000
*      *          * START'HPIB.  Used when HIOP cannot be *    <<03069>>00840000
*      *          * completed immediatly.                 *    <<03069>>00845000
* 7    * ICNTRL   * (0:1) Software channel is being used  :    <<03069>>00850000
*      *          * (1:6) Channel queue number            *    <<03069>>00855000
*      *          * (7:2) IMB number                      *    <<03069>>00860000
*      *          * (9:4) Channel number                  *    <<03069>>00865000
*      *          * (13:3) Device number                  *    <<03069>>00870000
* 8    * ISIOP    * SYSDB ptr to channel pgm area         *    <<03069>>00875000
* 9    * ISTATP   * SYSDB ptr to 2-word status area       *    <<03069>>00880000
* 10   * IUNIT    * Unit extract instruction (ANDI 7)     *    <<03069>>00885000
* 11   * ICDP     * SYSDB ptr to currently active DIT     *    <<03069>>00890000
* 12   * IQUEUE   * (0:8) SIOP size/2                     *    <<03069>>00895000
*      *          * (8:8) Queue number                    *    <<03069>>00900000
* 13   * IFLAG    * (0:1) This device should have idle    *    <<03069>>00905000
*      *          *       chanp when there are no requests*    <<03069>>00910000
*      *          * (1:1) An idle chanp is active         *    <<03069>>00915000
*      *          * (2:1) Ignore interrupt from HIOP inst.*    <<03069>>00920000
*      *          * (3:1) Re-start chanp on HIOP interrupt*    <<03069>>00925000
*      *          * (10:1) Attention from another unit    *    <<03069>>00930000
*      *          * (11:5) Highest configured unit for   *     <<03074>>00935000
*      *          *        this device.                   *    <<03069>>00940000
* 14-21* IDITPx   * SYSDB ptrs to DITS, by unit number    *    <<03069>>00945000
* 22-23* ??       * Status area pnted to by word 9        *    <<03069>>00950000
* 24   *          * Seek mask (not used currently)        *    <<03069>>00955000
* 25-n * CHANP    * Channel program area pnted to by wd 8 *    <<03069>>00960000
***********************************************************    <<03069>>00965000
                                                               <<03069>>00970000
**************************************************************          00975000
            W  A  R  N  I  N  G                                         00980000
**************************************************************          00985000
                                                                        00990000
     The 7910 has a "feature" which                                     00995000
can cause errors to be incorrectly diagnosed.                           01000000
This "feature" is automatic address verication                          01005000
when a seek is issued.  The result is that a status                     01010000
returned after a seek completion(caused by either                       01015000
issuance of a seek command or by an automatic seek                      01020000
following a transfer at the end of a track) to a track                  01025000
which is defective,protected,or spared will indicate an                 01030000
error even if no data is transfered (the 7905/06/20/25                  01035000
interface                                                               01040000
will only return an error if a data transfer is attempted).             01045000
                                                                        01050000
     What this means is that whenever an error is returned,             01055000
some check should be made to be sure that the error                     01060000
did in fact occur in the area of the disc that the                      01065000
caller is transferring to(from).  It seems that to be                   01070000
absolutely sure that the error occured within the area                  01075000
of immediate concern, the disc address of the error                     01080000
should be obtained and compared with where the transfer                 01085000
should have ended.  However, in most cases, the byte                    01090000
count in the channel program can be checked to see if it                01095000
is zero(NOTE: this method may be used iff the channel program           01100000
allows this count to be updated by the I/O processor).                  01105000
                                                                        01110000
     This problem is made a little more cumbersome by                   01115000
the fact that the error returned depends on the type                    01120000
of seek which occurred (whether a seek was issued or                    01125000
an automatic seek by the controller).In the case of seeking             01130000
to a spare track, if the status is following a seek                     01135000
command, then the error returned is illegal access to a                 01140000
spare track.  However, if the status is following an                    01145000
automatic seek as a result of a transfer at the end of a                01150000
track, the error returned is different.  In the latter case             01155000
I think the error returned depends on the address field                 01160000
of the track to which the seek is done.  Since the cases                01165000
that I have encountered have zero in the address field for              01170000
spare tracks which are not assigned as alternates, the error I have     01175000
seen is cylinder miscompare error for this condition.                   01180000
                                                                        01185000
     Note that the HPIB interface for the 7905/06/20/25 disc            01190000
has a similar problem                                                   01195000
on buffered reads.  It does seem that the cases are more                01200000
limit than with the 7910.  The problem seems only to occur              01205000
on reads that would terminate within two                                01210000
sectors of a defective                                                  01215000
area or spare track.  Because data is buffered in advance of            01220000
the actual transfer, an error will be returned even                     01225000
though the error was not in the area of the disc of                     01230000
the requested transfer.  In this situation, it seems to                 01235000
be sufficient to check for a byte residue count of zero.                01240000
The addresses could also be compared to determine if the                01245000
error occured beyond the area of concern.                               01250000
                                                                        01255000
                                                                        01260000
**************************************************************          01265000
$PAGE                                                                   01270000
BEGIN                                                                   01275000
$INCLUDE INCLLPDT                                              <<06837>>01280000
$PAGE                                                          <<06837>>01285000
$INCLUDE INCLSBH                                               <<06837>>01290000
$PAGE                                                          <<06837>>01295000
$INCLUDE INCLDRQ                                               <<06837>>01300000
$PAGE                                                          <<06837>>01305000
EQUATE                                                                  01310000
   ADRREC      = %006000, << ADRESS RECORD CMD >>                       01315000
   BADSIO      = %44,     << SIO FAILURE RETURN >>                      01320000
   CBIT'       = 7,       << RECALIBRATE BIT OF QMISC >>                01325000
   CDBA        = 14,      << CURRENT DATA BUF INDEX >>                  01330000
   CDERR       = %17,     << CORRECTABLE DATA ERROR CODE >>             01335000
   CDSJ        = %2400,   << DEVICE SPECIFIED JUMP>>                    01340000
   CDSJ2       = CDSJ+2,                                                01345000
   CEDA        = 10,      << CURRENT ERROR DISC ADR. INDEX >>           01350000
   CEDA1       = 20,      << CEDA INDEX (SINGLE) >>                     01355000
   CHANERR     = %144,    << CHANNEL PROGRAM ABORT ERROR >>             01360000
   CINTHLT    = %600,     <<CHANNEL INTERRUPT AND HALT>>                01365000
   CINTHLT1   = CINTHLT+1,                                              01370000
   CINTHLT2   = CINTHLT+2,                                              01375000
   CINTHLT3   = CINTHLT+3,                                              01380000
   CINTNHLT2  = %402,      << Interrupt with NO halt >>        <<03069>>01385000
   CLBIT'     = 8,        << CHANNEL CLEAR BIT >>                       01390000
   CLDA       = 18,      << current logical disc addr index >> <<06837>>01395000
   CLEARC      = %4400,   << CHANNEL CLEAR COMMAND >>                   01400000
   CLEARISSUED = %100001, << VALUE PUT IN CPVA ON DSJ 2 >>              01405000
   CLRP        = 149,     << OFFSE TO CLEAR PROGRAM >>         <<03069>>01410000
   CJUMP       = %000000, << CHANNEL JUMP COMMAND >>                    01415000
   CMD         = 156,     <<OFFSET OF DISC COMMANDS            <<03069>>01420000
                         <<!!!!NOTE: CMD SHOULD ALWAYS>>       <<03069>>01425000
                         <<          BE AN EVEN NUMBER>>       <<03069>>01430000
   CMD1        = CMD+1,                                                 01435000
   CMD2        = CMD+2,                                                 01440000
   CMD2'       = CMD2/2,                                                01445000
   CMD4        = CMD+4,                                                 01450000
   CMD5        = CMD+5,                                                 01455000
   CMD6        = CMD+6,     << Not currently used         >>   <<03069>>01460000
   CMD6'       = CMD6/2,                                                01465000
   CMD8        = CMD+8,                                                 01470000
   CMD9        = CMD+9,                                                 01475000
   CMD10       = CMD+10,                                                01480000
   CMD10'      = CMD10/2,                                               01485000
   CMD12       = CMD+12,                                                01490000
   CMD13       = CMD+13,                                                01495000
   CMD14       = CMD+14,                                                01500000
   CMD15       = CMD+15,                                                01505000
   CMD16       = CMD+16,                                                01510000
   CMD17       = CMD+17,                                                01515000
   CMD18       = CMD+18,                                                01520000
   CMD19       = CMD+19,                                                01525000
   CMD20       = CMD+20,                                                01530000
   CNOUPD      = %002000, << NO UPDATE CHANNEL ORDERS>>                 01535000
   CPDA        = 6,       << CURRENT PHYSICAL DISC ADR. dbl inx<<03069>>01540000
   CREADD      = %001400, << CHANNEL READ DATA>>                        01545000
   CREADC      = %001410, << CHANNEL READ COMMAND DATA>>                01550000
   CURCYL      = 12,      << CURRENT CYLINDER INDEX >>                  01555000
   CWAIT       = %001000, <<CHANNEL WAIT>>                              01560000
   CWRITED     = %002000, << CHANNEL WRITE DATA>>                       01565000
   CWRITEC     = %002010, << CHANNEL WRITE COMMAND>>                    01570000
   CWC         = 16,      << CURRENT WORD COUNT INDEX >>                01575000
   DADR        = 4,       << DISC ADRESS INDEX IN IOQ >>                01580000
   DATAOVRRUN  = %16,     << DATA OVERRUN ERROR >>                      01585000
   DILTP       = 5,       << ILT POINTER >>                             01590000
   DLDEV       = 3,       << LOGICAL DEVICE INDEX OF DIT >>             01595000
   DUNIT       = 10,      << Device unit number >>             <<06837>>01600000
   DLOGERROR   = 35,    <<HARDWARE LOGGED ERROR STATUS>>       <<01347>>01605000
   DLOGSIOP    = 11,      << SIOP relative abort location >>   <<06837>>01610000
   DMISC       = 32,      << DIT MISC >>                                01615000
   DSCXFRERR   = %14,     << DISC XFER ERROR STATUS RETURN >>           01620000
   DSERR       = 7,     <<ERROR STATUS COUNT & INDEX>>         <<01347>>01625000
   DSTAT       = 6,       << DEVICE STATUS RETURN INDEX >>              01630000
   DSTAT1      = 18,      << STATUS 1 RETURN INDEX >>                   01635000
   DSTAT2      = 19,      << STATUS 2 RETURN INDEX >>                   01640000
   DXFP        = 26,      << OFFSET OF DATA XFER I/O PROG >>   <<02043>>01645000
                                                               <<03069>>01650000
   DXFP0       = DXFP+0,      << Start of DXFER program >>     <<03069>>01655000
   DXFP11      = DXFP+11,     << Seek command location >>      <<03069>>01660000
   DXFP18      = DXFP+18,     << Req status cmd location >>    <<03069>>01665000
   DXFP23      = DXFP+23,     << Read status buffer location>> <<03069>>01670000
                                                               <<03069>>01675000
                                                               <<03069>>01680000
   DXFP4       = DXFP+4,      << Set filemask cmd location >>  <<03069>>01685000
                                                               <<03069>>01690000
   DXFP25      = DXFP+25,      << SIOP rel jump location >>    <<03069>>01695000
   DXFP30      = DXFP+30,      << Verify  record-1 cmd loc >>  <<03069>>01700000
   DXFP35      = DXFP+35,      << Address record-2 cmd loc >>  <<03069>>01705000
   DXFP42      = DXFP+42,      << Transfer cmd location    >>  <<03069>>01710000
   DXFP43      = DXFP+43,      << DMA HP-IB cmd start loc  >>  <<03069>>01715000
   DXFP44      = DXFP+44,                                      <<03069>>01720000
   DXFP46      = DXFP+46,  << bank number of XFER bufr >>      <<03089>>01725000
   DXFP52      = DXFP+52,  << DSJ branch on good return >>     <<03069>>01730000
   DXFP59      = DXFP+59,  << Seek cmd loc after INIT >>       <<03069>>01735000
   DXFP66      = DXFP+66,  << Verify after init >>             <<03069>>01740000
   ENDOP       = %012400, << DISC END ORDER >>                          01745000
   FILLB       = 6,       << FILL WITH BLANK CMD >>                     01750000
   FILLZ       = 5,       << FILL WITH ZERO CMD >>                      01755000
   FOPEN       = 2,       << FILE OPEN FUNCTION >>                      01760000
   FORMAT      = 8,       << FORMAT FUNCTION >>                         01765000
   ICDP        = 11,       << ILT current DIT pointer >>       <<03074>>01770000
   ICNTRL      = 7,       << CONTROLLER INFO IN ILT >>                  01775000
   ICPVA0      = 0,       << FIRST WORD OF CPVA >>                      01780000
   ICPVA1      = 1,       << WORD ONE OF CPVA >>                        01785000
   ICPVA2      = 2,       << WORD two OF CPVA >>               <<03069>>01790000
   ICPVA3      = 3,       << WORD THREE OF CPVA >>                      01795000
   IDITPA      = 14,      << DITP array in ILT >>              <<03685>>01800000
   IDLEP       = 2,       << START OF IDLE CHANNEL PROG >>              01805000
   IFLAG       = 13,      << FLAGS WORD OF ILT >>                       01810000
   IMASK     = 7,         << INTERRUPT MASK WORD>>                      01815000
   INITFLAG    = CMD20,   << I/O PROGRAM INITIALIZED FLAG >>            01820000
   INITIALIZE  = 9,       << INITIALIZE FUNCTION >>                     01825000
   INITOP      = %005400, << INITIALIZE COMMAND >>                      01830000
   INITADR     = 30,      << INITIALIZE ADDRESS INDEX >>                01835000
   INITADDR    = 15,      << INITIALIZE ADDRESS INDEX (DBL) >>          01840000
   INTERRUPT'2 = %100002, << Interrupt-2 code >>               <<03069>>01845000
   INVDSKADR   = %64,     << INVALID DISC ADRESS RETURN >>              01850000
   INVFUNC     = 4,       << INVALID FUNCTION RETURN >>                 01855000
   ISIOP       = 8,       << CHAN PROG POINTER >>                       01860000
   ISTAP       = 9,       << STATUS AREA PTR IN ILT >>                  01865000
   JUMPOFFSET  = 2,       << OFFSET OF JUMP ORDER AT START OF PROGRAM >>01870000
   MAXTRANSFER = 32767,   << MAXIMUM TRANSFER >>                        01875000
   MBIT'       = 3,       << TRACK MAP BIT OF QMISC >>                  01880000
   POWERFAIL'  = %72,     << SYSDB REL LOCATION OF POWER FAIL WORD >>   01885000
   QFUNC       = 6,       << FUNCTION CODE INDEX OF IOQ >>              01890000
   QLDEV       = 2,       << LDEV INDEX OF IOQ >>                       01895000
   QMISC       = 3,       << DRIVER WORD INDEX OF IOQ >>                01900000
   QSTAT       = 10,      << STATUS RETURN INDEX OF IOQ >>              01905000
   QWBCT       = 7,       << COUNT INDEX >>                             01910000
   READ        = 0,       << READ FUNCTION >>                           01915000
   READOP      = %002400, << DISC READ COMMAND >>                       01920000
   READFS      = 10,      << READ FULL SECTOR FUNCTION >>               01925000
   READFSOP    = %003000, << READ FULL SECTOR COMMAND >>                01930000
   READSPD     = 12,      << READ WITH SPARING DISABLED >>              01935000
   RECALP      = 142,     << OFFSET OF RECALIBRATE I/O PROG >> <<03069>>01940000
   RECALP4     = RECALP+4,                                              01945000
   RECALIBRATE = %000600, << DISC RECALIBRATE ORDER >>                  01950000
   REQDADR     = %012000, << REQUEST DISC ADDRESS>>                     01955000
   REQSTAT     = %001400, << REQUEST STATUS CMD >>                      01960000
   REQSYNOP    = %006400, << REQUEST SYNDROME>>                         01965000
   RDAP        = 114,     <<OFFSET OF DISC ADDRESS PROG>>      <<03069>>01970000
   RDAP4       = RDAP+4,                                                01975000
   RDAP9       = RDAP+9,                                                01980000
   RSTAP       = 104,     << OFFSET TO REQUEST STATUS I/O PROG <<03069>>01985000
   RSTAP4      = RSTAP+4,                                               01990000
   RSTAP9      = RSTAP+9,                                               01995000
   RSTAT       = 7,       << REQUEST STATUS FUNCTION >>                 02000000
   RSYNP       = 128,     << OFFSET TO REQUEST SYMDROME I/O PRO<<03069>>02005000
   RSYNP4      = RSYNP+4,                                               02010000
   RSYNP9      = RSYNP+9,                                               02015000
   SCOUNT      = 29,      << SECTOR COUNT >>                            02020000
   SEEK        = %001200, << SEEK CMD >>                                02025000
   SEEKSTAT1   = 33,      << STATUS FOLLOWING SEEK COMPLETION >>        02030000
   SETWAKE     = %013000, << SET WAKEUP WHEN DRIVE AVAILABLE CMD >>     02035000
   SPEC'IDLEP  = 17,      << OFFSET TO INTERRUPT COMMAND OF ILDEP >>    02040000
   SUCCESSFUL  = 1,       << SUCCESSFUL COMPLETION STATUS RETURN >>     02045000
   SYNDRET     = 22,      << SYNDROME RETURN AREA>>                     02050000
   SYNDRET1    = SYNDRET+1,                                             02055000
   SYNDRET2    = SYNDRET+2,                                             02060000
   SYNDRET3    = SYNDRET+3,                                             02065000
   SYNDRET4    = SYNDRET+4,                                             02070000
   SYSBUFA     = 17,      << SYSBUF INDEX OF DIT >>                     02075000
   SYSDB       = %1000,                                                 02080000
   SYSERROR    = %124,    << SYSTEM ERROR CODE RETURN >>                02085000
   SYSLPDT     = 8,       << DB INDEX OF LPDT POINTER >>                02090000
   SYSSBUF     = 6,       << DB INDEX OF SBUF TABLE >>                  02095000
   SYSUP'      = %73,     << DB INDEX OF SYSTEM UP FLAG >>              02100000
   TIMEOUT'IDLE'CHANP=5,  << Location where WAIT in IDLE is >> <<03685>>02105000
   UNITFAILURE = %54,     << UNIT FAIL STATUS RETURN >>                 02110000
   VERIFYOP    = %003400, << VERIFY COMMAND >>                          02115000
   WAIT        = %10,     << WAIT FOR COMP. STATUS RETURN >>            02120000
   WCR         = 15,      << WORD COUNT REMAINING INDEX >>              02125000
   WRITE       = 1,       << WRITE FUNCTION >>                          02130000
   WRITEL      = 11,      << WRITE LABEL FUNCTION >>                    02135000
   WRITEOP     = %004000, << DISC WRITE COMMAND >>                      02140000
   XFERERROR   = %34;     << XFER ERROR STATUS RETURN >>                02145000
                                                                        02150000
DEFINE                                                                  02155000
   ABORT      = (0:4)#,    << ABORT FIELD OF CPVA0 >>                   02160000
   ABS        = ABSOLUTE#,                                              02165000
   ASMB       = ASSEMBLE#,                                              02170000
   CBIT       = (CBIT':1)#,                                             02175000
   CLBIT      = (CLBIT':1)#,                                            02180000
   CPVAEFIELD = (4:12)#,  << ERROR FIELD OF CPVA WORDS >>               02185000
   DBIT       = (0:1)#,    << RETRY DETERMINATION BIT OF QMISC >>       02190000
   DISABLE    = ASMB(SED 0)#,                                           02195000
   DRVNOTRDY  = (14:1)#,   << DRIVE NOT READY BIT OF QSTAT2 >>          02200000
   DSTBANKFIELD= (8:8)#, << HIGH ORDER MEM ADDRESS IN DST >>   <<01754>>02205000
   EBIT       = (2:1)#,    << ERROR BIT OF QMISC >>                     02210000
   ENABLE     = ASMB(SED 1)#,                                           02215000
   ERRCODE    = (3:5)#,    << ENCODED ERROR STATUS >>                   02220000
   FUNCTION   = (8:8)#,    << REQUEST FUNCTION CODE >>                  02225000
   FINISH     = %(2)1000#, << CHANNEL PROGRAM FINISH WITHOUT ABORT>>    02230000
   HCUNIT      = (13:3)#, << field of IFLAG in ILT >>          <<03685>>02235000
   HEAD       = LSR(8)#,   << HEAD FIELD OF DISC ADRESS >>              02240000
   IAK         = (8:1)#,  << Interrupt acknowledge bit >>      <<03685>>02245000
   INIT       = CON %20302;CON 6#,                                      02250000
   IOPROG      = (7:1)#,  << I/O pgm in-progress bit >>        <<03685>>02255000
   L'STAT'ERR = (15:1)#,   << LAST TRANSFER STATUS                      02260000
                              - TRUE IF LAST TRANSFER ENDED WITH ERROR  02265000
                              - OTHERWISE FALSE                         02270000
                            >>                                          02275000
   MBIT       = (MBIT':1)#,                                             02280000
   MISSEDINT  = (10:1)#,   << MISSED INTERUPT FIELD OF ILFAG OF ILT >>  02285000
   QLDEVN     = (8:8)#,    << LDEV FIELD IN IOQ >>                      02290000
   RETRY      = (13:3)#,   << RETRY COUNT FIELD OF QMISC >>             02295000
   SBIT       = (1:1)#,    << REQUEST SYNDROME BIT OF QMISC >>          02300000
   SECTOR     = (8:8)#,    << SECTOR FIELD OF DISC ADRESS >>            02305000
   SEEKCHECK  = (13:1)#,   << INVALID SEEK BIT OF STATUS-2 >>           02310000
   SEM        = (1:3)#,    << S,E, AND M BITS OF QMISC >>               02315000
   SFAIL      = (10:1)#,   << SIO FIALED TO START IN GIP >>             02320000
   SIOP       = CON %20302;CON 0#, <<SIOP INSTRUCTION>>                 02325000
   SPARE      = (0:1)#,    << SPARE BIT OF STATUS-1 >>                  02330000
   SPEC       = (1:1)#,    << SPECIAL REQ. BIT OF IOQ >>                02335000
   STAT       = (8:8)#,    << I/O STATUS RETURN FIELD OF IOQ >>         02340000
   STATEF      = (12:4)#, << SIODM state field in DIT(0) >>    <<03685>>02345000
   SUBT       = (12:4)#,   << SUBTYPE FIELD OF LPDT >>                  02350000
   SYSBUFR    = (3:1)#,    << SYSTEM BUFFER BIT OF IOQ >>               02355000
   TIMEOUT'WAIT= (5:1)#,    << Bit in QMISC for powered-down >><<03685>>02360000
   UNITN      = LSR(8)#,   << UNIT FIELD OF DIT >>                      02365000
   WAITPROG   = (1:1)#,    << IDLE CHANNEL PROG STARTED OF IFLAG >>     02370000
   WBIT       = (4:1)#;    << WRITING BAD TRACK BIT OF QMISC >>         02375000
                                                                        02380000
INTEGER POINTER                                                         02385000
   SBUF        = DB + SYSSBUF;                                          02390000
                                                                        02395000
LOGICAL SYSUP = DB+SYSUP';                                              02400000
                                                                        02405000
LOGICAL POWERFAIL = DB+POWERFAIL';                                      02410000
                                                                        02415000
DOUBLE POINTER                                                          02420000
   DLPDT       = DB + SYSLPDT;                                          02425000
                                                               <<03685>>02430000
integer array WA0(*) = DB + 0; << Direct array at SYSDB >>     <<03685>>02435000
                                                               <<03685>>02440000
ARRAY INITIAL(0:219)= DB:=                                     <<06837>>02445000
   [8/38,8/%61],     << DIT SIZE= 38, CORE RES., TYPE= 1 >>    <<06837>>02450000
         0,                                                             02455000
   %037407,          << UNIT EXTRACT INSTRUCTION (ANDI 7) >>            02460000
   [8/89,8/2],       << 178 WORD SIO PROGRAM AREA,2 WORD STATUS<<03069>>02465000
   << DIT >>                                                            02470000
     %040000,        << DFLAG; DISC >>                                  02475000
           0,        << DLINK >>                                        02480000
           0,        << DIOQP >>                                        02485000
           0,        << DLDEV >>                               <<06837>>02490000
           0,        << DDLTP >>                                        02495000
           0,        << DILTP >>                                        02500000
           0,        << DRQST >>                                        02505000
           0,        << DSERR >>                                        02510000
           0,        << DMAMQ >>                                        02515000
           0,        << DMAMQT >>                                       02520000
     %040000,        << HP-IB DEVICE - DUNIT >>                <<06837>>02525000
           0,        << SIOP RELATIVE ABORT ADDRESS >>         <<06837>>02530000
         0,0,        << CPDA - CURRENT PHYSICAL DISC ADR >>             02535000
           0,        << CDBA - CURRENT DATA BUFFER ADR >>               02540000
           0,        << WCR - WORD COUNT REMAINING >>                   02545000
           0,        << CWC - CURRENT TRANSFER COUNT >>                 02550000
           0,        << SYSBUFA - SYSTEM BUFFER ADR >>                  02555000
           0,        << STAT1 - FIRST DISC STATUS >>                    02560000
           0,        << STAT2 - SECOND DISC STATUS >>                   02565000
         0,0,        << CEDA - CURRENT ERROR DISC ADR >>                02570000
0,0,0,0,0,0,0,       << REQUEST SYNDROME AREA >>                        02575000
           0,        << SCOUNT - SECTOR COUNT >>                        02580000
         0,0,        << INITIALIZE ADDRESS >>                           02585000
           0,        << DMISC >>                                        02590000
         0,0,        << SEEKSTAT >>                                     02595000
           0,        << DLOGERROR >>                           <<01347>>02600000
         0,0,        << CLDA - CURRENT LOGICAL DISC ADDR >>    <<06837>>02605000
                                                                        02610000
        <<-----------------                                             02615000
          CHANNEL PROGRAM                                               02620000
        ----------------->>                                             02625000
                                                                        02630000
        CJUMP,0,                                                        02635000
                                                                        02640000
        <<----------------------                                        02645000
          IDLE CHANNEL PROGRAM                                          02650000
        ---------------------->>                                        02655000
                                                                        02660000
        CWRITEC,2,0,CNOUPD,0,     <<ISSUE END>>                         02665000
        CWAIT,0,                                                        02670000
        CWRITEC,2,0,CNOUPD,0,     <<REQUEST STATUS>>                    02675000
        CREADC,4,0,CNOUPD,0,      <<READ STATUS>>                       02680000
        CDSJ2,0,                  <<CHECK POWER UP >>          <<02043>>02685000
        0,                                                     <<02043>>02690000
        0,                                                     <<02043>>02695000
        125,                      << ISSUE CLESR >>            <<03069>>02700000
        CINTHLT2,1,               <<HALT WITH INTERUPT>>                02705000
                                                                        02710000
        <<-------------------                                           02715000
          DATA XFER PROGRAM                                             02720000
        ------------------->>                                           02725000
                                                                        02730000
  <<DXFP0>>  CWRITEC,2,0,CNOUPD,0, << Set filemask >>          <<03069>>02735000
  <<DXFP5>>  CWAIT,0,                                          <<03069>>02740000
                                                               <<03069>>02745000
  <<DXFP7>>  CWRITEC,6,0,CNOUPD,0, << Write Seek Command    >> <<03069>>02750000
 <<DXFP12>>  CWAIT,0,             << Wait for // poll       >> <<03069>>02755000
                                                               <<03069>>02760000
 <<DXFP14>>  CWRITEC,2,0,CNOUPD,0, << Write Req Status cmd  >> <<03069>>02765000
 <<DXFP19>>  CREADC,4,0,CNOUPD,0,  << Read status           >> <<03069>>02770000
                                                               <<03069>>02775000
 <<DXFP24>>  CJUMP,12,            << Jump if READ/WRITE     >> <<03069>>02780000
                                                               <<03069>>02785000
 <<DXFP26>>  CWRITEC,4,0,CNOUPD,0, << Verify:Init alternate >> <<03069>>02790000
 <<DXFP31>>  CWRITEC,6,0,CNOUPD,0, << Address Record 2      >> <<03069>>02795000
 <<DXFP36>>  CWAIT,0,              << Wait for // poll      >> <<03069>>02800000
                                                               <<03069>>02805000
 << Do actual transfer.  First, send XFER order to disc     >> <<03069>>02810000
 << controller, then do DMA to send/receive data.           >> <<03069>>02815000
                                                               <<03069>>02820000
 <<DXFP38>>  CWRITEC,2,0,CNOUPD,0, <<TRANSFER ORDER>>          <<03069>>02825000
 <<DXFP43>>  0,0,0,0,0,            <<ACTUAL TRANSFER>>         <<03069>>02830000
 <<DXFP48>>  CWAIT,0,                                          <<03069>>02835000
                                                               <<03069>>02840000
 <<DXFP50>>  CDSJ2,0,              <<ERROR CHECK>>             <<03069>>02845000
 <<DXFP52>>  19,                   << NO ERROR >>              <<03069>>02850000
 <<DXFP53>>  23,                   << ERROR OCCURED >>         <<03069>>02855000
 <<DXFP54>>  68,                   << CLEAR REQUIRED >>        <<03069>>02860000
                                                               <<03069>>02865000
 <<DXFP55>>  CWRITEC,6,0,CNOUPD,0, << SEEK FOR VERIFY IN FORMAT<<03069>>02870000
 <<DXFP60>>  CWAIT,0,                                          <<03069>>02875000
                                                               <<03069>>02880000
 <<DXFP62>>  CWRITEC,4,0,CNOUPD,0, <<VERIFY>>                  <<03069>>02885000
 <<DXFP67>>  CWAIT,0,                                          <<03069>>02890000
                                                               <<03069>>02895000
 <<DXFP69>>  CDSJ2,0,                                          <<03069>>02900000
 <<DXFP71>>  0,                    << NO ERROR >>              <<03069>>02905000
 <<DXFP72>>  4,                    << ERROR OCCURED >>         <<03069>>02910000
 <<DXFP73>>  49,                   << CLEAR REQUIRED >>        <<03069>>02915000
                                                               <<03069>>02920000
 <<DXFP74>>  CINTNHLT2,2,          << Interrupt, but continue ><<03069>>02925000
                                                               <<03069>>02930000
 << Jump to idle channel pgm if all is OK                  >>  <<03069>>02935000
 <<DXFP76>>  CJUMP,-102,  << Jump to ISSUE END             >>  <<03069>>02940000
                                                                        02945000
        <<------------------------                                      02950000
          REQUEST STATUS PROGRAM                                        02955000
        ------------------------>>                                      02960000
                                                                        02965000
 <<RSTP00>>  CWRITEC,2,0,CNOUPD,0, <<REQUEST STATUS>>                   02970000
 <<RSTP05>>  CREADC,4,0,CNOUPD,0,  <<READ STATUS>>                      02975000
                                                                        02980000
        <<------------------------------                                02985000
          REQUEST DISC ADDRESS PROGRAM                                  02990000
        ------------------------------>>                                02995000
                                                                        03000000
 <<RDAP00>>  CWRITEC,2,0,CNOUPD,0, <<REQUEST DISC ADDRESS>>             03005000
 <<RDAP05>>  CREADC,4,0,CNOUPD,0,  <<READ DISC ADDRESS>>                03010000
 <<RDAP10>>  CWAIT,0,                                                   03015000
 <<RDAP17>>  CINTHLT1,1,           <<ERROR HALT>>                       03020000
                                                                        03025000
        <<--------------------------                                    03030000
          REQUEST SYNDROME PROGRAM                                      03035000
        -------------------------->>                                    03040000
                                                                        03045000
 <<RSYNP00>> CWRITEC,2,0,CNOUPD,0, <<REQUEST SYNDROME>>                 03050000
 <<RSYNP05>> CREADC,14,0,CNOUPD,0, <<SYNDROME RETURN>>                  03055000
 <<RSYNP10>> CWAIT,0,                                                   03060000
 <<RSYNP17>> CINTHLT2,3,                                                03065000
                                                                        03070000
        <<---------------------                                         03075000
          RECALIBRATE PROGRAM                                           03080000
        --------------------->>                                         03085000
                                                                        03090000
 <<RECALP>>  CWRITEC,2,0,CNOUPD,0, <<ISSUE RECALIBRATE>>                03095000
 <<RECALP5>> CINTHLT2,4,                                                03100000
                                                                        03105000
        <<-------------------                                           03110000
          ISSUE AMIGO CLEAR                                             03115000
        ------------------->>                                           03120000
                                                                        03125000
 <<CLRP>>    CLEARC,0,                                                  03130000
 <<CLRP2>>   CWAIT,0,                                                   03135000
 <<CLRP4>>   CINTHLT3,1,                                                03140000
             0,          <<TO MAKE CMD START ON EVEN BOUNDARY ><<02043>>03145000
        <<----------                                                    03150000
          COMMANDS                                                      03155000
        ---------->>                                                    03160000
                                                                        03165000
<<CMD00>>   REQSTAT,    << Request status for IDLE chanp >>    <<03074>>03170000
 <<CMD01>>   0,0,0,      <<SEEK>>                                       03175000
<<CMD04>>   ENDOP,      << Disc END order >>                   <<03074>>03180000
 <<CMD05>>   ADRREC,     << Address Record 1 (not used) >>     <<03069>>03185000
 <<CMD06>>   0,          << Cylinder number        >>          <<03069>>03190000
 <<CMD07>>   0,          << Head/Sector number     >>          <<03069>>03195000
<<CMD08>>   REQSYNOP,   << Request syndrome order >>           <<03074>>03200000
 <<CMD09>>   ADRREC,0,0, <<ADDRESS RECORD 2>>                           03205000
 <<CMD12>>   0,          <<REQUEST STATUS>>                             03210000
 <<CMD13>>   REQDADR,    <<REQUEST DISC ADDRESS>>                       03215000
 <<CMD14>>   0,          <<SET FILEMASK>>                               03220000
 <<CMD15>>   0,0,        <<VERIFY>>                                     03225000
 <<CMD17>>   0,          <<DISC XFER ORDER>>                            03230000
 <<CMD18>>   0,          << FILL WORD >>                                03235000
 <<CMD19>>   REQSTAT,    << Seek Status req for a specific unit<<03069>>03240000
 <<CMD20>>   FALSE;      << FLAG INDICATES IF I/O PROGRAM               03245000
                            HAS BEEN INITIALIZED BY DRIVER              03250000
                            INITIALIZATION ROUTIN          >>           03255000
                                                                        03260000
$PAGE                                                                   03265000
integer procedure GETDRT(DRTN,OFFSET);                         <<03069>>03270000
value DRTN,OFFSET;                                             <<03069>>03275000
integer DRTN,OFFSET;                                           <<03069>>03280000
option external;                                               <<03069>>03285000
                                                               <<03069>>03290000
procedure AWAKEIO(DITP,IMPEDE);                                <<03685>>03295000
value DITP,IMPEDE;                                             <<03685>>03300000
pointer DITP;                                                  <<03685>>03305000
logical IMPEDE;                                                <<03685>>03310000
option external;                                               <<03685>>03315000
                                                                        03320000
PROCEDURE DCONVERT(WORD);                                               03325000
VALUE WORD;                                                             03330000
INTEGER WORD;                                                           03335000
OPTION EXTERNAL;                                                        03340000
                                                                        03345000
INTEGER PROCEDURE GETSBUF(TYPE);                                        03350000
VALUE TYPE;                                                             03355000
INTEGER TYPE;                                                           03360000
OPTION EXTERNAL;                                                        03365000
                                                                        03370000
PROCEDURE GIP'HPIB;                                            <<01301>>03375000
OPTION EXTERNAL;                                                        03380000
                                                                        03385000
PROCEDURE HELP;                                                         03390000
OPTION EXTERNAL;                                                        03395000
                                                                        03400000
PROCEDURE LDEVNOTRDY(DITP);                                             03405000
VALUE DITP;                                                             03410000
POINTER DITP;                                                           03415000
OPTION EXTERNAL;                                                        03420000
                                                                        03425000
PROCEDURE MASTERCLEARHPIB(DITP);                               <<01301>>03430000
INTEGER ARRAY DITP;                                                     03435000
OPTION EXTERNAL;                                                        03440000
                                                                        03445000
procedure MMSTAT(EVENT,P1,P2,P3);                              <<03085>>03450000
value EVENT,P1,P2,P3;                                          <<03085>>03455000
integer EVENT,P1,P2,P3;                                        <<03085>>03460000
option external;                                               <<03085>>03465000
                                                               <<03085>>03470000
PROCEDURE SIODM(DITP,FLAGS);                                            03475000
VALUE DITP,FLAGS;                                                       03480000
POINTER DITP;                                                           03485000
LOGICAL FLAGS;                                                          03490000
OPTION EXTERNAL;                                                        03495000
                                                                        03500000
PROCEDURE RETURNSBUF(SBUFP);                                            03505000
VALUE SBUFP;                                                            03510000
INTEGER SBUFP;                                                          03515000
OPTION EXTERNAL;                                                        03520000
                                                                        03525000
PROCEDURE START'HPIB(DITP,CHANP,QUEUE);                        <<01301>>03530000
VALUE DITP,CHANP,QUEUE;                                                 03535000
POINTER DITP,CHANP;                                                     03540000
LOGICAL QUEUE;                                                          03545000
OPTION EXTERNAL;                                                        03550000
                                                                        03555000
PROCEDURE SUDDENDEATH(N);                                               03560000
VALUE N; INTEGER N;                                                     03565000
OPTION EXTERNAL;                                                        03570000
                                                                        03575000
procedure DISC'NOT'RESP(DITP);                                 <<03685>>03580000
integer array DITP;                                            <<03685>>03585000
option external;                                               <<03685>>03590000
                                                               <<03685>>03595000
$PAGE                                                                   03600000
INTEGER PROCEDURE DISCINIT(DITP);                                       03605000
  INTEGER ARRAY DITP;                                                   03610000
  <<INITIALIZATION ROUTINE FOR IOMDISC1:                                03615000
    IT SETS UP IDLE CHANNEL PROGRAM,                                    03620000
    STARTS IT TO RUN,                                                   03625000
    SETS BIT FIEDLS TO INDICATE IT IS RUNNING                           03630000
  >>                                                                    03635000
    BEGIN                                                               03640000
    INTEGER POINTER ILTP=Q+1,                                           03645000
                    CHANP=Q+2;                                          03650000
    LOGICAL ABSCHANP=Q+3;                                               03655000
    LOGICAL POINTER ILTPL=ILTP;                                         03660000
    integer X = X;   << Index register >>                      <<03085>>03665000
                                                                        03670000
      <<----------------------                                          03675000
        INITIALIZE VARIABLES                                            03680000
      ---------------------->>                                          03685000
                                                                        03690000
      IF POWERFAIL<>0 THEN RETURN;                                      03695000
      TOS := DITP(DILTP);   << ILT POINTER >>                           03700000
      TOS := ILTP(ISIOP);   << CHANNEL PROGRAM POINTER >>               03705000
      TOS := @CHANP+SYSDB;  <<ABSOLUTE ADDRESS OF CHANP>>               03710000
      <<-------------------------                                       03715000
        INITIALIZE IDLE PROGRAM                                         03720000
      ------------------------->>                                       03725000
      IF NOT LOGICAL(CHANP(INITFLAG)) THEN                              03730000
        BEGIN <<FIRST UNIT FOR CONTROLLER>>                             03735000
        CHANP(X) := true;  << flag pgm is initialized >>       <<03085>>03740000
        CHANP(6) := ABSCHANP+CMD4;  << END ORDER >>                     03745000
        CHANP(13) := ABSCHANP+CMD;  << Unit 0 request status >><<03069>>03750000
        CHANP(CMD12) := REQSTAT;                                        03755000
        CHANP(18) := ILTP(ISTAP)+SYSDB;                                 03760000
                                                               <<03069>>03765000
                                                               <<03069>>03770000
        << Initialize SEEK command >>                          <<03069>>03775000
        CHANP(DXFP11) := CHANP(DXFP59) := ABSCHANP+CMD1;       <<03069>>03780000
        CHANP(DXFP18) := ABSCHANP+CMD19; << REQUEST STATUS >>  <<03069>>03785000
        CHANP(DXFP4 ) := ABSCHANP+CMD14;<< FILEMASK COMMAND >> <<03069>>03790000
                                                               <<03069>>03795000
        CHANP(DXFP35) := ABSCHANP+CMD9; << Add record-2 >>     <<03069>>03800000
                                                               <<03069>>03805000
        << Initialize disc transfer order >>                   <<03069>>03810000
        CHANP(DXFP42) := CHANP(RECALP4) := ABSCHANP+CMD17;     <<03069>>03815000
                                                               <<03069>>03820000
        << Initialize VERIFY commands >>                       <<03069>>03825000
        CHANP(DXFP66) := CHANP(DXFP30) := ABSCHANP+CMD15;      <<03069>>03830000
        CHANP(RSYNP4) := ABSCHANP+CMD8; << SYNDROME COMMAND >>          03835000
        CHANP(RSTAP4) := ABSCHANP+CMD12;<< STATUS COMMAND >>            03840000
        CHANP(RDAP4) := ABSCHANP+CMD13; << DISC ADDR COMMAND >>         03845000
                                                               <<03069>>03850000
                                                               <<03069>>03855000
                                                               <<03069>>03860000
                                                               <<03069>>03865000
                                                               <<03069>>03870000
        << load SEEKSTAT address into channel pgm >>           <<03069>>03875000
        CHANP(DXFP23) := @DITP + SEEKSTAT1 + SYSDB;            <<03069>>03880000
        <<------------                                                  03885000
          UPDATE ILT                                                    03890000
        ------------>>                                                  03895000
        CHANP(1) := 0;                                                  03900000
        START'HPIB(DITP,CHANP,FALSE);                          <<01301>>03905000
        END;                                                            03910000
      END;                                                              03915000
                                                                        03920000
$PAGE                                                                   03925000
INTEGER PROCEDURE MHDDVR(IOQP,DITP,BANK,BUFFER,CHANP,DRTN);    <<01301>>03930000
VALUE IOQP,DITP,BANK,BUFFER,CHANP,DRTN;                        <<01301>>03935000
INTEGER BANK,BUFFER,DRTN,IOQP;                                 <<06837>>03940000
INTEGER POINTER DITP,CHANP;                                    <<06837>>03945000
OPTION PRIVILEGED,UNCALLABLE;                                           03950000
BEGIN                                                                   03955000
                                                                        03960000
INTEGER                                                                 03965000
   ABSCHANP     = Q+21, << ABSOLUTE ADDRESS OF CHANP >>        <<06837>>03970000
   AD           = Q+1,  << ADRESS DELTA >>                              03975000
   BUFADR       = Q+5,  << ABSOLUTE BUFFER ADRESS >>                    03980000
   BUFCNT       = Q+1,  << COUNT CHECK FOR REQUEST SYND. >>             03985000
   CXFER        = Q+4,  << CHAINED XFER ORDER >>                        03990000
   DISCOP       = Q+3,  << DISC XFER ORDER>>                            03995000
   DXFPINDEX    = Q+10, <<INDEX INTO XFER PROGRAM>>                     04000000
   ERR          = Q+6,  << DISC ENCODED ERROR STATUS >>                 04005000
   FUNCT        = Q+18, << REQUEST FUNCTION CODE >>            <<06837>>04010000
   I            = Q+8,                                                  04015000
   INDEX        = Q+23, << INDEX INTO DISCINFO >>              <<06837>>04020000
   MSTATE       = MHDDVR,                                               04025000
   S0           = S-0,                                                  04030000
   S1           = S-1,                                         <<03685>>04035000
   S2           = S-2,                                                  04040000
   SUBTYPE      = Q+17, << DEVICE SUBTYPE >>                   <<06837>>04045000
   UNIT         = Q+20, << DEVICE UNIT # >>                    <<06837>>04050000
   X            = X,                                                    04055000
   XCNT         = Q+7,  << XFER COUNT >>                                04060000
   XD           = Q+2;  << XFER DELTA >>                                04065000
                                                                        04070000
DOUBLE                                                                  04075000
   DXFERORDER   = CXFER;                                                04080000
                                                                        04085000
DOUBLE POINTER                                                          04090000
   DDITP        = DITP,                                                 04095000
   DIOQP        = IOQP,                                                 04100000
   DCHANP       = CHANP;                                                04105000
                                                                        04110000
LOGICAL                                                                 04115000
   CHANQFLG     = Q+11, << CHANNEL QUEUE FLAG FOR STARTIO >>            04120000
   SBFLG        = Q+19, << SYSTEM BUFFER FLAG >>               <<06837>>04125000
   LS0          = S-0,                                                  04130000
   LSM1         = S-1;                                                  04135000
                                                                        04140000
LOGICAL POINTER                                                         04145000
   LDITP        = DITP,                                                 04150000
   LIOQP        = IOQP,                                                 04155000
   LCHANP       = CHANP,                                       <<01115>>04160000
   LPDTP        = 8;                                           <<01115>>04165000
                                                                        04170000
INTEGER POINTER                                                         04175000
   BADTRACK     = Q+9,                                                  04180000
   ILTP         = Q+22,                                        <<06837>>04185000
   PS0          = S-0,                                                  04190000
   PS1          = S-1;                                                  04195000
                                                                        04200000
EQUATE                                                                  04205000
   HSTYPE      =    12,   << HIGHEST SUBTYPE >>                <<03069>>04210000
   NENTRIES    =    5,    << NUMBER OF TABLE ENTRIES/SUBTYPE >>         04215000
   SECPERTRK   =    0,    << OFFSET TO SEC/TRACK ENTRIES >>             04220000
   SECPERCYL   =    1,    << OFFSET TO SEC/CYLINDER ENTRIES >>          04225000
   MAXCYL      =    2,    << OFFSET TO MAX CYLINDER FOR STYPE >>        04230000
   FILEMASK    =    3,    << OFFSET TO FILEMASK >>                      04235000
   HEADOFFSET  =    4;    << OFFSET TO FIRST SURFACE >>        <<03069>>04240000
                                                               <<03069>>04245000
                                                                        04250000
INTEGER ARRAY                                                           04255000
   DISCINFO(4*NENTRIES:HSTYPE*NENTRIES+4) = PB :=              <<03069>>04260000
     48,  96, 410, %7406, 0,     <<STYPE 4, 7905, REMOVE CART >>        04265000
     48,  48, 410, %7405, 2,     <<STYPE 5, 7905, FIXED PLATTER >>      04270000
     48, 144, 410, %7407, 0,     <<STYPE 6, 7905, BOTH PLATTERS >>      04275000
     48, 144, 410, %7407, 0,     <<STYPE 7, 7905, FH DISC REPLCMNT >>   04280000
     48, 240, 822, %7407, 0,     <<STYPE 8, 7920 >>                     04285000
     64, 576, 822, %7407, 0,     <<STYPE 9, 7925 >>                     04290000
     48,  96, 410, %7406, 0,     <<STYPE 10, 7906,REMOVABLE CART. >>    04295000
     48,  96, 410, %7407, 2,     <<STYPE 11, 7906,FIXED PLATTER >>      04300000
     48, 192, 410, %7407, 0;     <<SYTPE 12, 7906, BOTH PLATTER<<03069>>04305000
                                                               <<03069>>04310000
                                                                        04315000
DEFINE DIT'UNIT= LDITP(DUNIT).(7:9)#;                          <<06837>>04320000
DEFINE FOREIGN= LPDT(LPDT'INDEX+1).(10:2)#;                    <<06837>>04325000
                                                               <<01115>>04330000
INTEGER ARRAY                                                           04335000
   CHANRW(0:12)=PB:=CREADD,CWRITED,0,0,0,CWRITED,CWRITED,               04340000
   0,CWRITED,CWRITED,CREADD,CWRITED,CREADD;                             04345000
                                                                        04350000
INTEGER ARRAY                                                           04355000
   XFEROP(0:12)=PB:=READOP,WRITEOP,0,0,0,WRITEOP,WRITEOP,               04360000
   0,WRITEOP,0,READFSOP,WRITEOP,READOP;                                 04365000
                                                               <<06837>>04370000
LOGICAL LPDT'INDEX       = Q+12;                               <<06837>>04375000
                                                               <<06837>>04380000
EQUATE SBUF'DSTN = %10;                                        <<06837>>04385000
EQUATE SBUF'DTRK'ENTRY= 0;                                     <<06837>>04390000
EQUATE SBUF'BANK = SBUF'DSTN* 4+ 2;                            <<06837>>04395000
EQUATE SBUF'ADDR = SBUF'DSTN* 4+ 3;                            <<06837>>04400000
LOGICAL LOOP             = Q+13;                               <<06837>>04405000
LOGICAL SBUF'ENTRY'INDEX = Q+14;                               <<06837>>04410000
LOGICAL TRK'NUM          = Q+15;                               <<06837>>04415000
DEFINE SBUF'NUM'DTRK = SBF(SBUF'ENTRY'INDEX+ SBUF'DTRK'ENTRY)#;<<06837>>04420000
                                                               <<06837>>04425000
EQUATE DRQ'DSTN  = %70;                                        <<06837>>04430000
EQUATE DRQ'ADDR  = DRQ'DSTN* 4+ 3;                             <<06837>>04435000
LOGICAL DRQ'ENTRY'INDEX  = Q+16;                               <<06837>>04440000
                                                               <<06837>>04445000
LOGICAL POINTER DST = 2;                                       <<06837>>04450000
$PAGE                                                          <<06837>>04455000
                                                                        04460000
  << Set up request status for this DIT/UNIT >>                <<03069>>04465000
  subroutine REQSTATSIO;                                       <<03069>>04470000
  begin                                                        <<03069>>04475000
      CHANP(CMD12) := REQSTAT+UNIT;                                     04480000
      CHANP(RSTAP9) := @DITP(DSTAT1)+SYSDB;<< STATUS RETURN >>          04485000
      CHANP(RDAP9) := @DITP(CEDA1)+SYSDB;<< DISC ADDR RETURN >><<03069>>04490000
  end;                                                         <<03069>>04495000
                                                               <<03069>>04500000
  << Check for attention from another unit >>                  <<03069>>04505000
  subroutine CHECK'SEEKSTATUS;                                 <<03069>>04510000
  begin                                                        <<03069>>04515000
                                                               <<03685>>04520000
   << We will first check for an ATTENTION from a disc >>      <<03685>>04525000
   << by examining the status area in the ILT.  An IDLE>>      <<03685>>04530000
   << may have written status into this area, and by   >>      <<03685>>04535000
   << reading status, the ATTENTION condition may be   >>      <<03685>>04540000
   << cleared.  If there is no status in the ILT, we   >>      <<03685>>04545000
   << will then check the SEEK STATUS from the data    >>      <<03685>>04550000
   << transfer channel program.  This status should    >>      <<03685>>04555000
   << re-appear since the controller is polling.       >>      <<03685>>04560000
                                                               <<03069>>04565000
  << if non-zero, then status request was performed >>         <<03069>>04570000
  << in channel program.                            >>         <<03069>>04575000
   tos := WA0(ILTP(ISTAP));  << Status from IDLE chanp >>      <<03685>>04580000
   if = then   << No status >>                                 <<03685>>04585000
    begin << No idle status was performed >>                   <<03685>>04590000
    DEL; << remove prior unit number >>                        <<03685>>04595000
    tos := DITP(SEEKSTAT1);  << Seek status from IDLE >>       <<03685>>04600000
    if <> then                                                 <<03685>>04605000
      begin    << There is a status here >>                    <<03685>>04610000
      DITP(X) := 0;  << Zero-out status >>                     <<03685>>04615000
      go to CHECK'UNIT'NUMBER;                                 <<03685>>04620000
      end                                                      <<03685>>04625000
    else                                                       <<03685>>04630000
      DEL;  << remove unit number >>                           <<03685>>04635000
    end                                                        <<03685>>04640000
  else                                                         <<03685>>04645000
    begin   << Attention status in ILT >>                      <<03685>>04650000
    WA0(X) := 0;   << Zero out status in ILT >>                <<03685>>04655000
                                                               <<03685>>04660000
CHECK'UNIT'NUMBER:                                             <<03685>>04665000
                                                               <<03685>>04670000
    tos := tos land 7;   << extract unit number     >>         <<03069>>04675000
    << S-1 is the unit number, S-0 is the DIT pointer >>       <<03685>>04680000
    tos := 0;    << DIT pointer >>                             <<03685>>04685000
    if S1 <> UNIT then                                         <<03685>>04690000
      if S1 <= ILTP(IFLAG).HCUNIT then << Unit in range >>     <<03685>>04695000
                                                               <<03685>>04700000
        if (S0:=ILTP(S1+IDITPA)) > 0 then << config'd >>       <<03685>>04705000
          << If no activity or awaiting OPERATOR INTERVENTION>><<03736>>04710000
          if PS0.STATEF=0 or PS0.STATEF=%10 then               <<03736>>04715000
            begin  << Do an AWAKEIO on this unit >>            <<03685>>04720000
            tos := PS0;   << Word 0 of DIT on tos >>           <<03685>>04725000
            if S0.STATEF=0 then tos.STATEF := 6; <<DEVREC>>    <<03736>>04730000
            tos.IAK := 1;      << Interrupt ACK  >>            <<03685>>04735000
            tos.IOPROG := 0;   << No channel pgm >>            <<03685>>04740000
            PS1 := tos;   << Store word 0 of DIT >>            <<03685>>04745000
            AWAKEIO(PS0,0);                                    <<03685>>04750000
            end;                                               <<03685>>04755000
    ASMB(ddel);   << Remove UNIT and DIT pointer >>            <<03685>>04760000
                                                               <<03685>>04765000
    end;                                                       <<03685>>04770000
                                                               <<03685>>04775000
end;  << of subroutine CHECK'SEEKSTATUS >>                     <<03685>>04780000
                                                                        04785000
  DOUBLE SUBROUTINE CONVERTADR;                                         04790000
      BEGIN << THIS ROUTINE CONVERTS A PHYSICAL TO LOGICAL DISC ADR. >> 04795000
     TOS := DDITP(X); << DIT INDEX PASSED IN X REG. >>                  04800000
     TOS := S0&HEAD;                                                    04805000
     TOS := TOS-DISCINFO(INDEX+HEADOFFSET);                             04810000
     TOS := TOS * DISCINFO(INDEX+SECPERTRK);                            04815000
     ASMB(XCH);                                                         04820000
     TOS := TOS.SECTOR;                                                 04825000
     ASMB(ADD,ZERO;XCH,CAB);                                            04830000
     TOS := DISCINFO(INDEX+SECPERCYL);                                  04835000
     ASMB(LMPY,DADD; STD S-4);                                          04840000
    END;                                                                04845000
                                                                        04850000
$PAGE "DRIVER COMMON ENTRY POINT"                              <<03069>>04855000
                                                                        04860000
        <<----------------------------                                  04865000
          INITIALIZE LOCAL VARIABLES                                    04870000
          ---------------------------->>                                04875000
                                                                        04880000
        ASMB(ADDS 16);                                         <<06837>>04885000
        DRQ'ENTRY'INDEX:= LOGICAL(IOQP);                       <<06837>>04890000
        LPDT'INDEX:= DITP(DLDEV)* SIZE'OF'LPDT'ENTRY;          <<06837>>04895000
        TOS:= LPDT'SUBTYPE;                                    <<06837>>04900000
        TOS:= DRQ'FUNC;                                        <<06837>>04905000
        TOS:= DRQ'SBUF;                                        <<06837>>04910000
        TOS:= DIT'UNIT;                                        <<06837>>04915000
        TOS := @CHANP+SYSDB;                                            04920000
        TOS := DITP(DILTP);                                             04925000
        TOS := SUBTYPE*NENTRIES; << INDEX >>                            04930000
        IF NOT LOGICAL(CHANP(INITFLAG))   << IF NOT INIT'ED >> <<01926>>04935000
          THEN DISCINIT(DITP);   << CALL DISC INITIALIZATION>> <<01926>>04940000
$PAGE "NEW REQUEST - INITIATOR"                                <<03069>>04945000
                                                                        04950000
        IF MSTATE = 2 THEN                                              04955000
          BEGIN                                                         04960000
          <<-------------                                               04965000
            NEW REQUEST                                                 04970000
          ------------->>                                               04975000
                                                               <<03069>>04980000
          << WITH OUT THE NEXT LINE WE'LL AVR A LOT >>         <<07099>>04985000
          DITP(SEEKSTAT1) := 0;                                <<07099>>04990000
          ILTP<<(ICPVA0)>> := 0;                               <<03069>>04995000
          ILTP(ICPVA2) := 0;                                   <<03069>>05000000
          ASMB(incx,zero);                                     <<03069>>05005000
          ILTP(X) := tos;   << ICPVA3 >>                       <<03069>>05010000
                                                               <<03069>>05015000
            COMMENT: **************************************    <<02043>>05020000
              ABOVE STATEMENT IS NECESSARY BECAUSE CLEAR MAY   <<02043>>05025000
            BE ISSUED WHILE IN THE IDLE CHANNEL PROGRAM. IF    <<02043>>05030000
            SO, CPVA WORD WILL NOT GET CLEARED UNTIL DRIVER    <<02043>>05035000
            IS CALLED. IN WHICH CASE, ON COMPLETION OF THIS    <<02043>>05040000
            I/O, IT WOULD APPEAR THAT THE POWER UP OCCURRED    <<02043>>05045000
            ON THIS TRANSFER AND THE TRANSFER WOULD BE REDONE  <<02043>>05050000
            UNNECESSARILY;                                     <<02043>>05055000
                                                               <<03069>>05060000
          IF DRQ'ENTRY'INDEX= 0 THEN                           <<06837>>05065000
            BEGIN                                                       05070000
            <<----------------------------                              05075000
              START IDLE CHANNEL PROGRAM                                05080000
            ---------------------------->>                              05085000
           tos := @DITP;                                       <<03085>>05090000
            ILTP(IFLAG).MISSEDINT := 0;                                 05095000
            IF <> THEN TOS := SPEC'IDLEP + 2 << ATTN  FROM DISC<<03098>>05100000
                               << WHILE OTHER DRIVE DOING A SEEK >>     05105000
            ELSE                                                        05110000
              BEGIN << NORMAL IDLE CHANNEL PROGRAM >>                   05115000
                                                               <<03069>>05120000
              TOS := 2;                                        <<03098>>05125000
              END;                                                      05130000
                                                               <<03085>>05135000
           << Start Channel Program here >>                    <<03085>>05140000
           tos := tos + @CHANP;                                <<03085>>05145000
           START'HPIB(*,*,false);                              <<03085>>05150000
           MSTATE := 5;                                        <<03085>>05155000
           return;                                             <<03085>>05160000
                                                               <<03085>>05165000
            END;                                                        05170000
                                                               <<03069>>05175000
          TOS:= DRQ'COUNT; << DETERMINE XFER COUNT >>          <<06837>>05180000
          IF < THEN                                                     05185000
            BEGIN << COUNT IN BYTES >>                                  05190000
            ASMB(DUP);                                                  05195000
            IF TOS THEN DRQ'COUNT:= DRQ'COUNT- 1;              <<06837>>05200000
            TOS := -(TOS&ASR(1)); << CONVERT TO WORDS >>                05205000
            END;                                                        05210000
          DITP(WCR) := TOS; << XFER COUNT >>                            05215000
          TOS:= DRQ'PARM1;                                     <<06837>>05220000
          TOS:= DRQ'PARM2;                                     <<06837>>05225000
          DDITP(CLDA):= TOS;   << DISC ADDRESS >>              <<06837>>05230000
          DITP(CDBA) := BUFFER; << SET CURRENT BUFFER ADRESS >>         05235000
                                                               <<03069>>05240000
          << map function 15 to function 7 >>                  <<03069>>05245000
          if FUNCT = 15 then                                   <<03069>>05250000
            begin                                              <<03069>>05255000
            FUNCT := RSTAT;                                    <<03069>>05260000
            DRQ'FUNC:= RSTAT;                                  <<06837>>05265000
            end;                                               <<03069>>05270000
                                                               <<03069>>05275000
          IF FUNCT > READSPD THEN                                       05280000
            BEGIN                                                       05285000
INVALIDFUNC:                                                            05290000
            TOS := INVFUNC;                                             05295000
            GO TO BADEND;                                               05300000
                                                               <<03069>>05305000
            END;                                                        05310000
          IF SBFLG AND DITP(WCR) > 128 THEN GO TO INVALIDFUNC;          05315000
          TOS := 0; << RESET QMISC >>                                   05320000
          X := FUNCT; << SWITCH ON REQUEST TYPE >>                      05325000
          ASMB(LOAD SWT,X; ADAX; BR SWT,X;                              05330000
SWT:      CON DOXFER;    CON DOXFER;    CON GOODEND;   CON GOODEND;     05335000
          CON GOODEND;   CON FILLZERO;  CON FILLBLANK;                  05340000
          CON REQSTATUS; CON DOXFER;    CON DOXFER;                     05345000
          CON DOXFER;    CON DOXFER;    CON DOXFER);                    05350000
          HELP; << HELP CALL NEEDED FOR BREAKPOINTS >>                  05355000
          END;                                                          05360000
$PAGE "COMPLETOR SECTION (INTERUPT HANDLER)"                   <<03069>>05365000
        <<---------------------                                         05370000
          CONTINUATOR SECTION                                           05375000
        --------------------->>                                         05380000
        << check for attention from another unit >>            <<03069>>05385000
        CHECK'SEEKSTATUS;                                      <<03069>>05390000
                                                               <<03069>>05395000
        << If all looks OK, bypass error checking code >>      <<03069>>05400000
                                                                        05405000
        TOS:= DRQ'QMISC;                                       <<06837>>05410000
        if = and                    << no retries, etc >>      <<03069>>05415000
           ILTP(ICPVA2) = INTERRUPT'2 and << norm EOP >>       <<03069>>05420000
           DITP(DSTAT) <> -1 then   << no PFAIL >>             <<03069>>05425000
        go to CONTXFER;                                        <<03074>>05430000
                                                               <<03069>>05435000
        IF DITP(DSTAT)=-1 THEN                                          05440000
          BEGIN << POWER FIAL >>                                        05445000
          DITP(X) := 0;                                                 05450000
          IF FUNCT=RSTAT THEN GO REQSTATUS ELSE GO DOXFER;              05455000
          END;                                                          05460000
                                                               <<03069>>05465000
        IF DRQ'SFAIL THEN GOTO SIOFAILURE;                     <<06837>>05470000
                                                               <<03069>>05475000
        IF ILTP(ICPVA0)<>0 THEN                                         05480000
          BEGIN << CHANNEL ERROR >>                                     05485000
          DITP(DSERR):= [8/2,8/DLOGERROR];                     <<03069>>05490000
          DITP(DLOGERROR):= ILTP(ICPVA0); <<LOG CHANNEL ERROR>><<01347>>05495000
          << log SIOP-relative location of failure >>          <<03069>>05500000
          DITP(DLOGSIOP) := GETDRT(DRTN,0) - ABSCHANP;         <<03069>>05505000
          ILTP(ICPVA0) := 0;                                            05510000
          IF LS0.RETRY<3  THEN   << Only allow 3 retries >>    <<03685>>05515000
            BEGIN                                                       05520000
            TOS.DBIT := 1;  << SET RETRY INDICATOR >>                   05525000
            TOS := TOS+1;   <<INCREASE RETRY COUNT>>                    05530000
            if FUNCT = RSTAT then                              <<03069>>05535000
              go to REQSTATUS                                  <<03069>>05540000
            else                                               <<03069>>05545000
              go to DOXFER;                                    <<03069>>05550000
                                                               <<03069>>05555000
            end                                                <<03685>>05560000
          else                                                 <<03685>>05565000
            begin                                              <<03685>>05570000
                                                               <<03685>>05575000
            << If the error is GIC timeout, we may have a  >>  <<03685>>05580000
            << powered-down disc controller.  At this point>>  <<03685>>05585000
            << we will print a "disaster" message on the   >>  <<03685>>05590000
            << console and launch a "special" idle channel >>  <<03685>>05595000
            << program that starts with a "WAIT" rather    >>  <<03685>>05600000
            << than issuing an "END" command to the disc   >>  <<03685>>05605000
            << controller.                                 >>  <<03685>>05610000
                                                               <<03685>>05615000
            if DITP(DLOGERROR) = %160004 then                  <<03685>>05620000
              begin  << Yep, it's a GIC timeout >>             <<03685>>05625000
              LS0.RETRY := 0;  << Zero retry counter >>        <<03685>>05630000
              LS0.TIMEOUT'WAIT := 1;                           <<03685>>05635000
              DISC'NOT'RESP(DITP);                             <<03685>>05640000
              tos := TIMEOUT'IDLE'CHANP;                       <<03685>>05645000
              go to STARTIOPROG;                               <<03685>>05650000
              end;                                             <<03685>>05655000
                                                               <<03685>>05660000
            end;                                               <<03685>>05665000
                                                               <<03685>>05670000
          TOS := CHANERR;                                               05675000
          GOTO BADEND;                                                  05680000
          END;                                                          05685000
                                                               <<03069>>05690000
        IF ILTP(ICPVA3) = CLEARISSUED THEN                              05695000
          BEGIN  << POWER UP DSJ SO ISSUE CLEAR >>                      05700000
          TOS.CLBIT := 1;                                               05705000
          ILTP(ICPVA3) := 0;                                            05710000
          END;                                                          05715000
                                                               <<03685>>05720000
        << Check if disc controller was powered-up >>          <<03685>>05725000
        tos.TIMEOUT'WAIT := 0;                                 <<03685>>05730000
        if <> then    << Yep, it was >>                        <<03685>>05735000
          tos.CLBIT := 1;                                      <<03685>>05740000
                                                               <<03069>>05745000
        << Check Recalibrate Bit >>                            <<03069>>05750000
        TOS.CBIT := 0;                                                  05755000
        IF <> THEN GO DOXFER;                                           05760000
                                                               <<03069>>05765000
        << Check Clear bit >>                                  <<03069>>05770000
        TOS.CLBIT := 0;                                                 05775000
        if <> then                                             <<03685>>05780000
          if FUNCT = RSTAT then                                <<03685>>05785000
            go to REQSTATUS                                    <<03685>>05790000
          else                                                 <<03685>>05795000
            go to DOXFER;                                      <<03685>>05800000
        IF FUNCT=RSTAT OR ILTP(ICPVA1)=0 THEN ERR:=0                    05805000
        ELSE                                                            05810000
          BEGIN << ERROR RETURN >>                                      05815000
          ERR := DITP(DSTAT1).ERRCODE;                                  05820000
          ILTP(ICPVA1) := 0;                                            05825000
          IF NOT DRQ'QMISC.EBIT LAND NOT DRQ'QMISC.SBIT THEN   <<06837>>05830000
            BEGIN                                                       05835000
          <<------------------------------------                        05840000
            HAD AN ERROR--CHECK IF CORRECTABLE                          05845000
          ------------------------------------>>                        05850000
            IF ERR=CDERR THEN                                           05855000
              BEGIN <<DO REQ SYNDROME ON CORRECTABLE ERROR>>            05860000
              CHANP(RSYNP9) := @DITP(SYNDRET)+SYSDB;                    05865000
              TOS.SBIT := 1;                                            05870000
              CHANP(CMD8) := REQSYNOP+UNIT;                             05875000
                                                               <<06837>>05880000
              << Log the correctable data error >>             <<06837>>05885000
              DITP(DSERR) := [8/17,8/DSTAT1];                  <<06837>>05890000
                                                               <<06837>>05895000
              TOS := RSYNP-JUMPOFFSET; <<RELATIVE JUMP ADDRESS>>        05900000
              GO STARTIOPROG;                                           05905000
              END;                                                      05910000
            TOS.EBIT := 1;                                              05915000
            END;                                                        05920000
          END;  << ERROR RETURN >>                                      05925000
                                                                        05930000
        << Check Request Syndrome Bit >>                       <<03069>>05935000
        TOS.SBIT := 0;                                                  05940000
        IF <> THEN                                                      05945000
          BEGIN                                                         05950000
          <<----------------------------                                05955000
            COMPLETED REQUEST SYNDROME                                  05960000
          ---------------------------->>                                05965000
          TOS := DITP(SYNDRET).ERRCODE;                                 05970000
          TOS := DITP(SYNDRET1);                                        05975000
          TOS := DITP(SYNDRET2);                                        05980000
          DDITP(CEDA) := TOS; << PHYSICAL DISC ADRESS OF ERROR >>       05985000
          IF TOS = CDERR THEN                                           05990000
            BEGIN << ERROR IS CORRECTABLE >>                            05995000
            TOS := CONVERTADR - DDITP(CLDA); << RELATIVE SECTOR CNT >>  06000000
            XCNT := TOS&LSL(7); << RELATIVE XFER COUNT >>               06005000
            I := TOS; << ZERO I >>                                      06010000
            IF SBFLG THEN BUFADR:= DITP(CDBA)       <<SYSTEM BU<<03069>>06015000
            ELSE BUFADR := DITP(CDBA) + XCNT; << DATA SEG >>            06020000
            BUFADR:=BUFADR+DITP(SYNDRET3); << DATA OFFSET IN SECTOR >>  06025000
            BUFCNT:=DITP(CWC)-XCNT-DITP(SYNDRET3); << ADRESS FENCE >>   06030000
            DO << CORRECT THE DATA ERROR IN MEMORY AND CONTINUE XFER >> 06035000
            IF 0<=(DITP(SYNDRET3)+I)<=127 AND (BUFCNT-I)>0 THEN         06040000
              BEGIN                                                     06045000
              TOS := BANK;                                              06050000
              TOS := BUFADR + I;                                        06055000
              ASMB(LSEA);                                               06060000
              TOS := TOS XOR LDITP(SYNDRET4+I);                         06065000
              ASMB(SSEA);                                               06070000
              DDEL;                                                     06075000
              END                                                       06080000
            UNTIL (I:=I+1) >= 3;                                        06085000
            DITP(CWC) := XCNT + 128;                                    06090000
            GO TO CONTXFER;                                             06095000
            END;                                                        06100000
          DITP(DSTAT1) := DITP(SYNDRET); << SET ERROR STATUS FOR EXAM >>06105000
          TOS.EBIT := 1; << SET E BIT TO GET INTO ERROR ANALYSIS >>     06110000
          END;                                                          06115000
                                                                        06120000
        TOS.EBIT := 0;                                                  06125000
        IF <> THEN                                                      06130000
          BEGIN                                                         06135000
          <<-------------------------                                   06140000
            ERROR STATUS COMPLETION                                     06145000
          ------------------------->>                                   06150000
          ERR := DITP(DSTAT1).ERRCODE;                                  06155000
         if ERR=%23 and LDITP(DSTAT2).SEEKCHECK or ERR=%20 then<<02631>>06160000
           if FUNCT=READ and CHANP(DXFP44)=0 then              <<03069>>06165000
                   <<                                                   06170000
                     NOT REALLY AN ERROR - DISC BUFFERING CAUSED        06175000
                     ATTEMPT TO TRANSFER FROM DEFECTIVE TRACK           06180000
                     WHICH FOLLOWED AREA FROM WHICH TRANSFER            06185000
                     WAS DESIRED                                        06190000
                  >>                                                    06195000
            GOTO GOODEND;                                               06200000
          DITP(DMISC).L'STAT'ERR:=1; << SAVE ERROR INDICATION >>        06205000
          DITP(DSERR):= [8/17,8/DSTAT1];<<SET ERROR INDICATOR>><<01347>>06210000
          IF ERR = %23 AND LDITP(DSTAT2).DRVNOTRDY THEN                 06215000
            BEGIN << DRIVE NOT READY >>                                 06220000
            IF NOT SYSUP THEN GO DOXFER;                                06225000
                                                                        06230000
              COMMENT:  **************************************          06235000
                SINCE IT IS SO DIFFICULT TO TO DIRECT I/O, IT           06240000
              IS MUCH SIMPLER TO LOOP HERE IN THE DRIVER UNTIL          06245000
              THE DISC BECOMES READY                                    06250000
              ************************************************;         06255000
            << If NOT SYSUP then SIODM will not fire >>        <<03069>>06260000
            << off idle channel program.             >>        <<03069>>06265000
                                                                        06270000
            LDEVNOTRDY(DITP); << SEND NOT READY MESSAGE TO CONSOLE >>   06275000
            TOS := WAIT;                                                06280000
            TOS := 7;                                                   06285000
            GO TO CHECKSBUF;                                            06290000
            END;                                                        06295000
                                                               <<03782>>06300000
          << INCREMENT RETRY COUNTER >>                        <<03782>>06305000
          TOS := TOS + 1;                                      <<03782>>06310000
                                                               <<03782>>06315000
          IF ERR = 7 THEN                                               06320000
            BEGIN                                                       06325000
            <<----------------------------                              06330000
              CYCLINDER MISCOMPARE ERROR                                06335000
            ---------------------------->>                              06340000
            IF S0.RETRY<7 THEN                                 <<03069>>06345000
              BEGIN                                                     06350000
                                                                        06355000
              <<-------------------                                     06360000
                TRY A RECALIBRATE                                       06365000
              ------------------->>                                     06370000
                                                                        06375000
              TOS.CBIT := 1;                                            06380000
                                                               <<03782>>06385000
              DITP(CURCYL) := 0; << CYL # IS 0 >>                       06390000
              CHANP(CMD17) := RECALIBRATE + UNIT;                       06395000
              TOS := RECALP-JUMPOFFSET; <<RELATIVE JUMP ADDRESS>>       06400000
              GO TO STARTIOPROG;                                        06405000
              END;                                                      06410000
            END;                                                        06415000
                                                               <<03782>>06420000
          TOS.DBIT := 1;  << SET RETRY INDICATOR >>                     06425000
                                                               <<03782>>06430000
                                                               <<03069>>06435000
          << If this is a DATAOVERRUN, we will log only >>     <<03069>>06440000
          << every seventh attempt, as not to fill log  >>     <<03069>>06445000
          << files.                                     >>     <<03069>>06450000
          if ERR = DATAOVRRUN then                             <<03069>>06455000
            if LS0.RETRY < 7 then                              <<03069>>06460000
              DITP(DSERR) := 0  << Don't log the error >>      <<03069>>06465000
            else                                               <<03069>>06470000
              tos.RETRY := 0;   << Don't expire count >>       <<03069>>06475000
                                                               <<03069>>06480000
          IF LS0.RETRY<7 THEN                                  <<03069>>06485000
          IF ERR=DATAOVRRUN OR FUNCT<>FORMAT THEN                       06490000
            GO DOXFER; << RETRY FORMAT ONLY ON DATA OVERRUN >>          06495000
                                                                        06500000
          <<---------------------------                                 06505000
            ERROR CONNAT BE RECOVERED                                   06510000
          --------------------------->>                                 06515000
                                                                        06520000
          IF FUNCT = READSPD OR FUNCT=FORMAT THEN                       06525000
          IF (%7<=ERR<=%11) OR (%17<=ERR<=%21) THEN                     06530000
          BEGIN                                                         06535000
            DITP(DSERR) := 0;  << DON'T LOG AS ERROR >>                 06540000
            TOS := (ERR & LSL(3)) + 4;  << RETURN ERROR >>              06545000
            GO TO BADEND;                                               06550000
            END;                                                        06555000
                                                                        06560000
          IF 7 <= ERR <= %11 THEN                                       06565000
          IF FOREIGN THEN GO TO DISCXFER                       <<01115>>06570000
          ELSE                                                 <<01115>>06575000
            BEGIN << TRACK SPECIFIC ERROR >>                            06580000
            TOS.RETRY := 0; << CLEAR RETRY CNT FOR TRACK MAP >>         06585000
            TOS.MBIT := 1;                                              06590000
            IF <> THEN GO TO DISCXFER; << ERROR ON MAP XFER >>          06595000
            TOS := DITP(SYSBUFA);                                       06600000
            IF = THEN                                                   06605000
              BEGIN << GET A SYSTEM BUFFER >>                           06610000
              TOS := GETSBUF(2); << GET A BUFFER, pri or second<<03069>>06615000
              ASMB(DELB,DUP);                                           06620000
              IF = THEN GO TO DISCXFER; << NO MORE BUFFERS >>           06625000
              DITP(SYSBUFA):= TOS;                             <<06837>>06630000
              END;                                                      06635000
            DITP(CDBA):= TOS+ DST(SBUF'ADDR); << GET BUF ADR >><<06837>>06640000
            ASMB(DZRO,INCA); << DOUBLE ONE >>                           06645000
            DDITP(CLDA) := TOS;                                         06650000
            DITP(WCR) := 128;                                           06655000
            FUNCT := READ; << SET UP XFER OF TRK MAP >>                 06660000
            BANK:= DST(SBUF'BANK);                             <<06837>>06665000
            GO TO DOXFER;                                               06670000
            END;                                                        06675000
          IF ERR = %23 AND LDITP(DSTAT2).SEEKCHECK                      06680000
            OR ERR = %20 THEN                                           06685000
            BEGIN                                                       06690000
            <<----------------------                                    06695000
              INVALID DISC ADDRESS                                      06700000
            ---------------------->>                                    06705000
BADDISCADR:                                                             06710000
            TOS := INVDSKADR;                                           06715000
BADEND:                                                                 06720000
            DRQ'COUNT:= 0;                                     <<06837>>06725000
            TOS := 5;                                                   06730000
            GO TO CHECKSBUF;                                            06735000
            END;                                                        06740000
          IF ERR = %12 OR ERR = %16 THEN                                06745000
            BEGIN << TRANSFER ERROR >>                                  06750000
            TOS := XFERERROR;                                           06755000
            GO TO BADEND;                                               06760000
            END;                                                        06765000
UNITFAIL:                                                               06770000
          TOS := UNITFAILURE;                                           06775000
          GO TO BADEND;                                                 06780000
          END;                                                          06785000
                                                                        06790000
        ASMB(TBC MBIT');                                                06795000
        IF <> THEN                                                      06800000
          BEGIN << ENTRING BAD TRACK INTO BAD TRACK TABLE >>            06805000
          <<-----------------------------------------                   06810000
            ENTERING BAD TRACK INTO BAD TRACK TABLE                     06815000
          ----------------------------------------->>                   06820000
          TOS.WBIT := 1;                                                06825000
          IF <> THEN                                                    06830000
            BEGIN                                                       06835000
            <<---------------------                                     06840000
              TRACK MAP COMPLETED                                       06845000
            --------------------->>                                     06850000
DISCXFER:                                                               06855000
            TOS := DSCXFRERR;                                           06860000
            GO TO BADEND;                                               06865000
            END;                                                        06870000
          SBUF'ENTRY'INDEX:=LDITP(SYSBUFA);                    <<06837>>06875000
          IF SBUF'NUM'DTRK >= 120 THEN GOTO DISCXFER;          <<06837>>06880000
          X := CEDA;                                                    06885000
          TOS := CONVERTADR;                                            06890000
          TOS := DISCINFO(INDEX+SECPERTRK);                             06895000
          ASMB(LDIV,DEL);                                               06900000
          TRK'NUM:= TOS & LSL(2);                              <<06837>>06905000
          IF LDITP(DSTAT1).SPARE THEN TRK'NUM:= TRK'NUM+ 1;    <<06837>>06910000
          << SET ALTERNATE TRACK BIT >>                                 06915000
          LOOP:= 0;                                            <<06837>>06920000
          WHILE LOOP < SBUF'NUM'DTRK DO                        <<06837>>06925000
                                                               <<06837>>06930000
            BEGIN                                              <<06837>>06935000
            LOOP:= LOOP+ 1;                                    <<06837>>06940000
            IF TRK'NUM = SBF(SBUF'ENTRY'INDEX+ LOOP) THEN      <<06837>>06945000
              GOTO DISCXFER;                                   <<06837>>06950000
            << ITS ALREADY IN THE TABLE >>                              06955000
            END;                                               <<06837>>06960000
                                                               <<06837>>06965000
          SBUF'NUM'DTRK:= SBUF'NUM'DTRK+ 1;                    <<06837>>06970000
          SBF(SBUF'ENTRY'INDEX+ LOOP+ 1):= TRK'NUM;            <<06837>>06975000
          FUNCT := WRITE;                                               06980000
          BANK := DST(SBUF'BANK);                              <<17513>>06985000
          GO TO DOXFER;                                                 06990000
          END;                                                          06995000
                                                                        07000000
        IF FUNCT=RSTAT THEN                                             07005000
          BEGIN << MOVE STATUS TO USER STACK >>                         07010000
          ILTP(ICPVA1) := 0;  << CLEAR WORD 1 OF CPVA>>                 07015000
RSTATRET:                                                               07020000
          TOS := BANK;                                                  07025000
          TOS := DITP(CDBA);                                            07030000
          TOS := 0;                                                     07035000
          TOS := @DITP(DSTAT1)+SYSDB;                                   07040000
          TOS := DITP(WCR);                                             07045000
          IF S0>4 THEN                                                  07050000
            BEGIN                                                       07055000
            DEL;                                                        07060000
            TOS := 4;                                                   07065000
            END;                                                        07070000
          ASMB(MABS 5);                                                 07075000
          GO TO GOODEND;                                                07080000
          END;                                                          07085000
                                                                        07090000
CONTXFER:                                                               07095000
        TOS := DITP(WCR) - DITP(CWC);                                   07100000
        IF <= THEN                                                      07105000
          BEGIN << XFER COMPLETE >>                                     07110000
GOODEND:                                                                07115000
                                                               <<03685>>07120000
          << If normal channel program end, IDLE channel >>    <<03685>>07125000
          << program was started, so don't let SIODM     >>    <<03685>>07130000
          << start it all over again.                    >>    <<03685>>07135000
          if ILTP(ICPVA2) = INTERRUPT'2 then                   <<03685>>07140000
            begin                                              <<03685>>07145000
                                                               <<03685>>07150000
            << Set flag that IDLE channel program is running >><<03685>>07155000
            ILTP(IFLAG).WAITPROG := 1;                         <<03685>>07160000
                                                               <<03685>>07165000
            << Zero current DIT pointer in ILT >>              <<03685>>07170000
            ILTP(ICDP) := 0;                                   <<03685>>07175000
                                                               <<03685>>07180000
            end;                                               <<03685>>07185000
                                                               <<03685>>07190000
          TOS := SUCCESSFUL;                                            07195000
          TOS := %5;                                                    07200000
CHECKSBUF:                                                              07205000
          TOS := DITP(SYSBUFA);                                         07210000
          IF <> THEN                                                    07215000
            BEGIN                                                       07220000
            RETURNSBUF(*);                                              07225000
            DITP(X) := 0;                                               07230000
            END ELSE DEL;                                               07235000
          GO TO EXIT;                                                   07240000
          END;                                                          07245000
        DITP(WCR) := TOS; << SET REMAINING WORD COUNT >>                07250000
        IF FUNCT <= WRITE THEN                                          07255000
                                                               <<03069>>07260000
             DITP(X) := DITP(CWC) + DITP(CDBA); << DATA SEG >> <<03069>>07265000
        TOS := DITP(CWC)&LSR(7);                                        07270000
        ASMB(ZERO,XCH); << UPDATE DISC ADRESS >>                        07275000
        DDITP(X) := TOS + DDITP(CLDA);                                  07280000
$PAGE "DATA TRANSFER SIOP-BUILD AREA"                          <<03069>>07285000
        <<-----------------------------                                 07290000
          NOTE!!!!!                                                     07295000
            QMISC MUST BE ON TOS HERE                                   07300000
        ----------------------------->>                                 07305000
                                                                        07310000
        <<---------------------------------                             07315000
          BUILD AND START THE I/O PROGRAM                               07320000
        --------------------------------->>                             07325000
                                                                        07330000
DOXFER:                                                                 07335000
        << Perform old status return housekeeping >>           <<03069>>07340000
                                                               <<03069>>07345000
        << Last status is no longer valid >>                   <<03069>>07350000
        DITP(DMISC).L'STAT'ERR := 0;                           <<03069>>07355000
        << Clear SEEK status >>                                <<03069>>07360000
        DITP(SEEKSTAT1) := 0;                                  <<03069>>07365000
                                                               <<03069>>07370000
        << Check if write to sector "0" is permitted >>        <<03069>>07375000
        tos := DDITP(CLDA); << Logical disc address >>         <<03069>>07380000
        if = and       << if sector "0" >>                     <<03069>>07385000
           (WRITE<=FUNCT<=RSTAT) and << not a read >>          <<03069>>07390000
           not FOREIGN then   << not a FOREIGN disc >>         <<03069>>07395000
          go to BADDISCADR;                                    <<03069>>07400000
                                                               <<03069>>07405000
        << Compute physical disc address >>                    <<03069>>07410000
        tos := DISCINFO(INDEX + SECPERCYL);                    <<03069>>07415000
        asmb(ldiv);           << Compute address >>            <<03069>>07420000
                                                               <<03069>>07425000
        << Check if address is valid for this disc >>          <<03069>>07430000
        if OVERFLOW or        << Divide gave strange result >> <<03069>>07435000
           LSM1 > logical(DISCINFO(INDEX + MAXCYL)) then       <<03069>>07440000
          go to BADDISCADR;                                    <<03069>>07445000
                                                               <<03069>>07450000
        << Compute head/sector >>                              <<03069>>07455000
        tos := DISCINFO(INDEX + SECPERTRK);                    <<03069>>07460000
        asmb(div,xch);                                         <<03069>>07465000
                                                               <<03069>>07470000
        << Combine C/H/S and save in DIT >>                    <<03069>>07475000
        tos := tos + DISCINFO(INDEX + HEADOFFSET);             <<03069>>07480000
        tos := tos & lsl(8) + tos;   << head/sector >>         <<03069>>07485000
                                                               <<03069>>07490000
        << Set up channel program >>                           <<03069>>07495000
                                                               <<03069>>07500000
        << Move transfer parameters to CMD area of channel pgm <<03069>>07505000
                                                               <<03069>>07510000
        << Save physical disc address in DIT & seek area >>    <<03069>>07515000
        DDITP(CPDA) := DCHANP(CMD2') := tos;                   <<03069>>07520000
                                                               <<03069>>07525000
        CHANP(CMD1) := SEEK + UNIT;      << SEEK command >>    <<03069>>07530000
        << SEEK and ADDRESS RECORD are the same >>             <<03069>>07535000
                                                               <<03069>>07540000
        << if the function is READSPD, we do not want the >>   <<03069>>07545000
        << auto-seek to alternate track to occur. >>           <<03069>>07550000
        CHANP(CMD14) := DISCINFO(INDEX + FILEMASK);            <<03069>>07555000
                                         << store file mask  >><<03069>>07560000
                                                               <<03069>>07565000
        << Modify channel instructions >>                      <<03069>>07570000
                                                               <<03069>>07575000
        << normally, we will jump to transfer immediatly >>    <<03069>>07580000
        << after the SEEK has completed.                 >>    <<03069>>07585000
        CHANP(DXFP25) := 12;                                   <<03069>>07590000
                                                               <<03069>>07595000
        << Store channel R/W command Q-relative          >>    <<03069>>07600000
        CXFER := CHANRW(FUNCT);                                <<03069>>07605000
                                                               <<03069>>07610000
        << Store disc transfer order                     >>    <<03069>>07615000
        DISCOP := XFEROP(FUNCT) + UNIT;                        <<03069>>07620000
                                                               <<03069>>07625000
        << Limit maximum transfer size >>                      <<03069>>07630000
        if DITP(WCR) < MAXTRANSFER then                        <<03069>>07635000
          tos := DITP(X)     << use requested length    >>     <<03069>>07640000
        else                                                   <<03069>>07645000
          tos := MAXTRANSFER; << use max possible length>>     <<03069>>07650000
                                                               <<03069>>07655000
        << if zero transfer count, complete transfer >>        <<03069>>07660000
        if = then                                              <<03069>>07665000
          go to GOODEND;                                       <<03069>>07670000
                                                               <<03069>>07675000
        << * * XFER length is left on TOS * *           >>     <<03069>>07680000
                                                               <<03069>>07685000
        << if split disc, we must see if there is       >>     <<03069>>07690000
        << possible platter wrap-around.                >>     <<03069>>07695000
        if 10 <= SUBTYPE <= 11 or                              <<03069>>07700000
           SUBTYPE = 4 then                                    <<03069>>07705000
          begin                                                <<03069>>07710000
          tos := DISCINFO(INDEX + SECPERCYL);                  <<03069>>07715000
          tos := DDITP(CLDA);                                  <<03069>>07720000
          tos := S2;                                           <<03069>>07725000
          asmb(ldiv,delb,sub);                                 <<03069>>07730000
                                                               <<03069>>07735000
          << transfer count to end of cylinder >>              <<03069>>07740000
          tos := tos & lsl(7);                                 <<03069>>07745000
          << compare transfer limit >>                         <<03069>>07750000
          asmb(ddup,lcmp);                                     <<03069>>07755000
          if < then  << must use this new XFER length >>       <<03069>>07760000
            asmb(xch);                                         <<03069>>07765000
          DELB;      << delete larger of 2 lengths    >>       <<03069>>07770000
          end;                                                 <<03069>>07775000
                                                               <<03069>>07780000
        << triplicate word count on tos >>                     <<03069>>07785000
        asmb(dup,dup);                                         <<03069>>07790000
                                                               <<03069>>07795000
        << store word and sector count in DIT >>               <<03069>>07800000
        DITP(CWC) := tos;                                      <<03069>>07805000
        DITP(SCOUNT) := tos & lsr(7);                          <<03069>>07810000
        BUFADR := DITP(CDBA);                                  <<03069>>07815000
                                                               <<03069>>07820000
        << if this is not a read or write, we will perform >>  <<03069>>07825000
        << exception processing, as Reads and Writes account>> <<03069>>07830000
        << for a majority of the driver requests.          >>  <<03069>>07835000
        CHANP(CMD17) := DISCOP;                                <<03069>>07840000
        CHANP(DXFP52) := 19;     << DSJ-0, go to INT-HALT2 >>  <<03069>>07845000
                                                               <<03069>>07850000
        <<  word count of XFER should be on tos here >>        <<03069>>07855000
        CHANP(DXFP43) := CXFER;    << 1st word of XFER order >><<03069>>07860000
        CHANP(X:=X+1) := tos & lsl(1); << byte count >>        <<03069>>07865000
        CHANP(X:=X+1) := 0;                                    <<03069>>07870000
        CHANP(X:=X+1) := BANK.DSTBANKFIELD; <<bank, allow upd>><<03069>>07875000
        CHANP(X:=X+1) := BUFADR;   << buffer address     >>    <<03069>>07880000
                                                               <<03069>>07885000
        << now, perform all the conditional funtion processing <<03069>>07890000
        if FUNCT > 1 then                                      <<03069>>07895000
          begin   << this is a low-usage function >>           <<03069>>07900000
                                                               <<03069>>07905000
          << Turn off SBUF flag if not really used >>          <<03069>>07910000
          if FOPEN <= FUNCT <= RSTAT then                      <<03069>>07915000
            SBFLG := false;                                    <<03069>>07920000
                                                               <<03069>>07925000
          << if function is zero or blank fill, mod BANK >>    <<03069>>07930000
          << number of transfer                          >>    <<03069>>07935000
          if FILLZ <= FUNCT <= FILLB then                      <<03069>>07940000
            CHANP(DXFP46) := %4000; << bank zero >>            <<03069>>07945000
                                                               <<03069>>07950000
          if FUNCT = INITIALIZE then                           <<03069>>07955000
            begin                                              <<03069>>07960000
            tos := BANK;                                       <<03069>>07965000
            tos := BUFADR - 2;                                 <<03069>>07970000
                                                               <<03069>>07975000
            << load initize address from buffer >>             <<03069>>07980000
            asmb(ldea);                                        <<03069>>07985000
            DCHANP(CMD10') := DDITP(INITADDR) := tos;          <<03069>>07990000
                                                               <<03069>>07995000
            << load alternate info from BUFADR - 3 >>          <<03069>>08000000
            asmb(deca;lsea;delb,delb);                         <<03069>>08005000
            tos.(15:1) := 0;                                   <<03069>>08010000
            if <> then                                         <<03069>>08015000
              begin                                            <<03069>>08020000
                                                               <<03069>>08025000
              << find alternate track >>                       <<03069>>08030000
              CHANP(DXFP25) := 0; << do ADDREC, VERIFY >>      <<03069>>08035000
              CHANP(CMD15) := VERIFYOP + UNIT;                 <<03069>>08040000
              CHANP(CMD16) := 1;                               <<03069>>08045000
              DCHANP(CMD10') := DDITP(INITADDR);               <<03069>>08050000
              end                                              <<03069>>08055000
            else                                               <<03069>>08060000
              begin                                            <<03069>>08065000
                                                               <<03069>>08070000
              << jump to INIT command >>                       <<03069>>08075000
              CHANP(CMD14) := %7402;     << FILEMASK        >> <<03069>>08080000
              CHANP(DXFP25) := 5; << Jump around verify >>     <<03069>>08085000
              end;                                             <<03069>>08090000
                                                               <<03069>>08095000
            CHANP(CMD17) := tos & lsl(12) + INITOP + UNIT;     <<03069>>08100000
            end;   << of INITIALIZE function >>                <<03069>>08105000
                                                               <<03069>>08110000
          if FUNCT = FORMAT then                               <<03069>>08115000
            begin                                              <<03069>>08120000
            CHANP(DXFP52) := 0;  << to execute verify >>       <<03069>>08125000
            CHANP(CMD14) := %7402;   << filemask      >>       <<03069>>08130000
            CHANP(X:=X+1) := VERIFYOP + UNIT; << verify >>     <<03069>>08135000
            CHANP(CMD16) := DITP(SCOUNT); << sector cnt >>     <<03069>>08140000
            CHANP(X:=X+1) := INITOP + UNIT; << initialize >>   <<03069>>08145000
            end;  << of FORMAT special case >>                 <<03069>>08150000
                                                               <<03069>>08155000
          << turn-off auto-spare function if READSPD >>        <<03069>>08160000
          if FUNCT = READSPD then                              <<03069>>08165000
            CHANP(CMD14).(13:1) := 0;                          <<03069>>08170000
                                                               <<03069>>08175000
          end;  << of  special case function code >>           <<03069>>08180000
                                                               <<03069>>08185000
        << continue with common function code >>               <<03069>>08190000
        REQSTATSIO;                                            <<03069>>08195000
                                                               <<03069>>08200000
        << channel pgm start address >>                        <<03069>>08205000
        tos := DXFP0- JUMPOFFSET;                              <<03069>>08210000
                                                                        08215000
        <<-----------------------                                       08220000
          START THE I/O PROGRAM                                         08225000
        ----------------------->>                                       08230000
                                                                        08235000
STARTIOPROG:                                                            08240000
        CHANP(1) := TOS; << SET THE JUMP ADRESS >>                      08245000
        CHANQFLG := true;  << no IDLE Chanp. here >>           <<03685>>08250000
                                                               <<03069>>08255000
        << We must assume that a normal SIO program  >>        <<03069>>08260000
        << termination will not occur, so we must    >>        <<03069>>08265000
        << tell SIODM to fire-off the IDLE channel   >>        <<03069>>08270000
        << program (just in case!).                  >>        <<03069>>08275000
        ILTP(ICPVA2) := 0;  << Flag non-std termination >>     <<03069>>08280000
                                                               <<03069>>08285000
        START'HPIB(DITP,CHANP,CHANQFLG);                       <<01301>>08290000
        IF > THEN                                                       08295000
          BEGIN                                                         08300000
          <<----------                                                  08305000
            NO START                                                    08310000
          ---------->>                                                  08315000
SIOFAILURE:                                                             08320000
          TOS := BADSIO;                                                08325000
          GO TO BADEND;                                                 08330000
          END;                                                          08335000
        DRQ'QMISC:= TOS;                                       <<06837>>08340000
        TOS := WAIT;                                                    08345000
        TOS := %13;                                                     08350000
EXIT:                                                                   08355000
        MSTATE := TOS;                                                  08360000
        DRQ'STAT:= TOS;                                        <<06837>>08365000
        RETURN;                                                         08370000
                                                                        08375000
FILLBLANK:                                                              08380000
        TOS := "  ";                                                    08385000
        GO TO FC;                                                       08390000
FILLZERO:                                                               08395000
        TOS := 0;                                                       08400000
FC:                                                                     08405000
        CHANP(CMD18) := TOS;                                            08410000
        DITP(CDBA) := ABSCHANP+CMD18;                                   08415000
        GO TO DOXFER;                                                   08420000
                                                                        08425000
        <<---------------------------                                   08430000
          INITIALIZE STATUS PROGRAM                                     08435000
        --------------------------->>                                   08440000
                                                                        08445000
REQSTATUS:                                                              08450000
        IF LDITP(DMISC).L'STAT'ERR THEN GOTO RSTATRET;                  08455000
        REQSTATSIO;                                                     08460000
        TOS := RSTAP-JUMPOFFSET;  <<RELATIVE JUMP ADDRESS>>             08465000
        GO STARTIOPROG;                                                 08470000
                                                               <<03069>>08475000
        END;                                                            08480000
ASMB(                                                                   08485000
   PCAL SIODM;    << MONITOR >>                                         08490000
   PCAL MHDDVR;   << INITIATOR >>                                       08495000
   PCAL MHDDVR;   << COMPLETOR >>                                       08500000
   CON 0;         << I/O PROCESS PROCEDURE >>                           08505000
   PCAL DISCINIT; << INITIALIZATION PROCEDURE >>                        08510000
   CON 1;         << # OF INTERRUPT PROCEDURES >>                       08515000
   PCAL GIP'HPIB);<< INTERRPUT HANDLER >>                      <<01301>>08520000
END.                                                                    08525000
