$CONTROL USLINIT,MAP,CODE                                               00010000
$control privileged,uncallable,main=hiocipr0                            00015000
                                                                        00020000
     << last modified by doug winterrowd at 12:30 on 03/04/82   >>      00025000
                                                                        00030000
     <<*********************************************************>>      00035000
     <<                                                         >>      00040000
     <<  hiocipr0 [module  1] -- hp-ib ciper physical driver    >>      00045000
     <<                                                         >>      00050000
     <<  copyright (c) 1981, hewlett packard co.  this program  >>      00055000
     <<  may be used with one computer system at at time and    >>      00060000
     <<  shall not otherwise be recorded, transmitted or stored >>      00065000
     <<  in a retrieval system.  copying or other reproduction  >>      00070000
     <<  of this program except for archival purposes is pro-   >>      00075000
     <<  hibited without the prior written consent of hewlett-  >>      00080000
     <<  packard company.                                       >>      00085000
     <<                                                         >>      00090000
     <<*********************************************************>>      00095000
$tp                                                                     00100000
$page "DESCRIPTION"                                                     00105000
comment                                                        <<06834>>00110000
                                                                        00115000
                                                                        00120000
           hp-ib ciper physical driver 3000 series - hiocipr0           00125000
           --------------------------------------------------           00130000
                                                                        00135000
                                                                        00140000
structure of hiocipr0:                                                  00145000
                                                                        00150000
hiocipr0, together with the sio device monitor (siodm) constitute a     00155000
standard mpe type 1 i/o driver/monitor.  this means that it does not    00160000
run in its own process, but executes on any stack and therefore must    00165000
run to completion.  during initialization it executes on progen's       00170000
stack, during request initiation it executes on attachio's stack, and   00175000
during interrupt processing it executes on the interrupt control        00180000
stack (ics).                                                            00185000
                                                                        00190000
HIOCIPR0 consists of a global area, two procedures, and an "outer       00195000
block" which is really a linkage area for INITIAL.  The global area     00200000
contains an array called initial which is comprised of three parts.     00205000
the first part specifies the size of the other two, the unit extract    00210000
instruction, and various parameters which are used by initial.  this    00215000
section is deleted after initial is through with it.  the other two     00220000
parts are the device information table (dit) and the channel program    00225000
area, which is part of the interrupt linkage table (ilt).  initial      00230000
will put each of these items in the area of memory where it belongs.    00235000
the linkage area specifies the procedure labels (p-labels) of the       00240000
associated monitor (siodm), the request initiator (cpdrvr), the         00245000
request completor (cpdrvr), the initialization procedure (cpinit,       00250000
called by progen at system startup), and the interrupt handler (gip).   00255000
                                                                        00260000
$page                                                                   00265000
operation of hiocipr0:                                                  00270000
                                                                        00275000
the primary working code of hiocipr0 is a procedure cpdrvr.  cpdrvr     00280000
is called with six parameters.   two of these parameters, bank and      00285000
buffaddr, are the absolute buffer address of the data to be processed.  00290000
the other three, ditp, ioqp, and siop are pointers to three arrays.     00295000
ditp is a pointer to the device information table which contains        00300000
information about its associated device.  there is one dit for          00305000
each unit on the controller and they contain information which must     00310000
be saved between i/o requests to the driver.  ioqp is a pointer to the  00315000
input/output table which contains information relevent to the current   00320000
request.  siop is a pointer to the first element of the channel pro-    00325000
gram which is actually part of the interrupt linkage table.  the last   00330000
parameter drtn is the device reference table (drt) number of the        00335000
device.  these three elements are described in more detail elsewhere    00340000
in this listing.                                                        00345000
                                                                        00350000
cpdrvr is always called by the sio device monitor (siodm) and it        00355000
determines the reason for the call by examining the ioq and the dit.    00360000
when a new request is initiated, cpdrvr examines the function code      00365000
and parameter fields contained in the ioq element to determine the      00370000
task that is desired.  the proper command codes and program branches    00375000
are then placed in the channel program and its execution is begun.      00380000
                                                                        00385000
upon completion of the request, an interrupt is generated and cpdrvr    00390000
is again called.  the code checks for current activity in progress,     00395000
and this being the case, branches to the completion section of the      00400000
driver.  here several status words are examined for errors or special   00405000
conditions which might have occurred during the execution of the        00410000
channel program, during the data transfer, or during the operation of   00415000
the device.  these conditions can cause error retries and/or            00420000
special notation back to the caller.  a list of the conditions and      00425000
the return codes is provided in this listing.                           00430000
$page                                                                   00435000
                device information table (dit)                          00440000
                ------------------------------                          00445000
                                                                        00450000
                                                                        00455000
there is one dit per physical device.  if a physical device represents  00460000
more than one logical device, the logical device number is obtained     00465000
from the ioq element (however, this driver only supports one device per 00470000
controller.)  the following diagram shows the dit used for the hp-ib    00475000
ciper physical driver.                                                  00480000
                                                                        00485000
     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15   mnemonic          00490000
   +--+--+--+--+--+--+--+--+--+--+--+--+-----------+                    00495000
  0| 0| 0|ac|rq| 0| 0| 0|io|ia|no|st| 0|   state   |   dflag            00500000
   +--+--+--+--+--+--+--+--+--+--+--+--+-----------+                    00505000
  1| sysdb relative pointer to the dit for the next|   dlink            00510000
   | device requesting this resource or service    |                    00515000
   +-----------------------------------------------+                    00520000
  2| ioq table index to the first ioq in           |   dioqp   <<06834>>00525000
   | request list for this device                  |                    00530000
   +-----+-----------------+-----------------------+                    00535000
  3| iot |    phys. unit # | logical device number |   dldev            00540000
   +-----+-----------------+-----------------------+                    00545000
  4| sysdb relative pointer to device linkage table|   ddltp            00550000
   +-----------------------------------------------+                    00555000
  5| sysdb relative pointer to intrp linkage table |   diltp            00560000
   +--+--+--+--+--+--------+-----------------------+                    00565000
  6|vs|ab|re|tp|nr| nr cnt |     device status     |   dsave            00570000
   +--+--+--+--+--+--------+-----------------------+                    00575000
  7| hardware error status.  set when the driver   |   dserr            00580000
   | detects an error.  whenever <>0, the driver   |                    00585000
   | monitor logs an i/o error and clears this word|                    00590000
   +-----------------------------------------------+                    00595000
%10| bit 0 is set at completion of timer           |   dtime            00600000
   +-----------------------------------------------+                    00605000
%11| holds the time out request entry index while  |   drqst            00610000
   | a timer is active.                            |                    00615000
   +--+--+--+--+--------+--------+--------+--------+                    00620000
%12|rf|ue|de|to|unit cnt|data cnt| to cnt |prty cnt|  dcounts           00625000
   +--+--+--+--+--------+--------+--------+--------+                    00630000
%13|           error logging location #1           | dlogerror          00635000
   +-----------------------------------------------+                    00640000
%14|           error logging location #2           | dlogcount          00645000
   +-----------------------------------------------+                    00650000
                                                                        00655000
                                                                        00660000
dflag - flags and request state                                         00665000
  ac  active  - a monitor is currently servicing this device.           00670000
  rq  request - a service request is pending while the monitor is       00675000
                active.                                                 00680000
  io  ioprog  - an i/o channel program is running for this device.      00685000
  ia  iak     - an interrupt or response has occurred for this device.  00690000
  no  notrdy  - go to state %10 after idle channel program is started.  00695000
  st  stwait  - the device monitor is starting an idle channel program  00700000
                for this device.  there is no ioq associated with this  00705000
                type of request.                                        00710000
$page                                                                   00715000
  state       - state of the device monitor.  specifies the next action 00720000
                to be taken in siodm in servicing the request:          00725000
                  0 - start new request                                 00730000
                  1 - not used                                          00735000
                  2 - call driver initiator procedure                   00740000
                  3 - call driver completor procedure                   00745000
                  4 - not used                                          00750000
                  5 - process request completed                         00755000
                  6 - initiate device recognition sequence              00760000
                  7 - start operator intervention wait                  00765000
                %10 - wait for interrupt (operator intervention)        00770000
                      restart at state 0                                00775000
                %11 - wait for data segment freeze, then state 2        00780000
                %12 - wait for driver initiator to be frozen, then      00785000
                      allocate controller (state 2)                     00790000
                %13 - wait for i/o completion interrupt, then state 3   00795000
                %14 - wait for controller, then call driver initiator   00800000
                %15 - not used                                          00805000
                %16 - wait for initiator make present, then state 2     00810000
                %17 - wait for completor make present, then state 3     00815000
                                                                        00820000
dldev - i/o system type, unit and logical device number                 00825000
    0 - hp3000 series 2/3                                               00830000
    1 - hp3000 series 33 (hpib)                                         00835000
    2 - unused                                                          00840000
    3 - unused                                                          00845000
                                                                        00850000
dsave - device processing flags                                         00855000
  vs - valid status - set to indicate device status has been updated.   00860000
  ab - dvrabflag    - sequence abort in progress due to abort request.  00865000
  re - retryflag    - sequence abort in progress due to an error.       00870000
  tp - timerpopped  - current error is due to software timer popping.   00875000
  nr - notrdyflag   - not ready wait in progress.                       00880000
  nr cnt            - number of not ready waits during this request.    00885000
  device status     - device status returned during a sequence abort.   00890000
       bit  8       -   crc available and enabled.                      00895000
        "   9       -   Reserved.                                       00900000
        "  10       -   Reserved.                                       00905000
        "  11       -   Reserved.                                       00910000
        "  12       -   Power fail or reset has occurred.               00915000
        "  13       -   A protocol error has been detected.             00920000
        "  14       -   A parity error has been detected.               00925000
        "  15       -   The peripheral has data to send.                00930000
                                                                        00935000
dserr - pointer to status to be logged.                                 00940000
        bits(0:8)   - number of words to be logged.                     00945000
        bits(8:8)   - offset relative to ditp(0).                       00950000
                                                                        00955000
dcounts             - error flags and error counts (4).                 00960000
   rf - req failed  - an error has forced this request to be aborted.   00965000
   ue - unit error  - the current error is a unit error.                00970000
   de - data error  - the current error is a data error.                00975000
   to - time out    - the current error is a gic time out error.        00980000
   unit cnt         - number of unit errors during this request.        00985000
   data cnt         - number of data errors during this request.        00990000
   to cnt           - number of gic time outs during this request.      00995000
   prty cnt         - number of hp-ib parity errors during this request.01000000
$page                                                                   01005000
                interrupt linkage table (ilt)                           01010000
                -----------------------------                           01015000
                                                                        01020000
                                                                        01025000
there is one ilt for each device controller configured on the system.   01030000
a controller may support more than one unit, however the hp-ib ciper    01035000
physical driver currently only supports one unit.                       01040000
                                                                        01045000
     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15   mnemonic          01050000
   +-----------------------------------------------+                    01055000
  0|         channel                               |   icpva0           01060000
  1|              program                          |   icpva1           01065000
  2|                  variable                     |   icpva2           01070000
  3|                       area (icpva)            |   icpva3           01075000
   +-----------------------------------------------+                    01080000
  4|         dma abort                             |   icpva4           01085000
  5|              address                          |   icpva5           01090000
   +-----------------------------------------------+                    01095000
  6|                      0                        |   isrql            01100000
   +--+-----------------+-----+-----------+--------+                    01105000
  7|li|     chanque     |     |   chan    |  dev   |   icntrl           01110000
   +--+-----------------+-----+-----------+--------+                    01115000
%10| sysdb relative pointer to channel program area|   isiop            01120000
   +-----------------------------------------------+                    01125000
%11| sysdb relative pointer to status return area. |   istap            01130000
   | (always zero for this driver.)                |                    01135000
   +-----------------------------------------------+                    01140000
%12| single instruction that is executed to extract|   iunit            01145000
   | the device unit number from the status pointed|                    01150000
   | to by istap.  (since there is only one unit   |                    01155000
   | on the controller, this entry is not used.)   |                    01160000
   +-----------------------------------------------+                    01165000
%13| sysdb relative dit pointer of the device      |   icdp             01170000
   | currently using the channel to perform a      |                    01175000
   | data operation.                               |                    01180000
   +-----------------------+-----------------------+                    01185000
%14|       siopsize        |        cquen          |   iqueue           01190000
   +--+--+--+--------------+-----------+-----------+                    01195000
%15|rw|wp|ig|                          |  hcunit   |   iflag            01200000
   +--+--+--+--------------------------+-----------+                    01205000
%16| sysdb relative dit pointer for unit 0         |   iditp0           01210000
   +-----------------------------------------------+                    01215000
%17|             peripheral                        |                    01220000
   .               channel                         .                    01225000
   |                 program                       |                    01230000
   +-----------------------------------------------+                    01235000
                                                                        01240000
                                                                        01245000
icpva0 - channel program variable area                                  01250000
                                                                        01255000
  the first word is used by the channel program processor to store      01260000
  status information after i/o channel aborts.  the next word is used   01265000
  by the driver to indicate if status should be examined for special    01270000
  conditions or errors.  the other two words are not used.              01275000
                                                                        01280000
$page                                                                   01285000
icpva4/5 - dma abort address                                            01290000
                                                                        01295000
  if a dma abort occurs, the absolute address where the abort occurred  01300000
  is stored in this area.                                               01305000
                                                                        01310000
                                                                        01315000
icntrl - contains controller information                                01320000
                                                                        01325000
  lim     - if this bit is set, the controller is sharing a software    01330000
            channel resource in order to limit bandwidth.               01335000
  chanque - the software channel resource number.                       01340000
  chan    - channel number (four most significant bits of drtn).        01345000
  dev     - device number (three least significant bits of drtn).       01350000
                                                                        01355000
                                                                        01360000
iqueue -                                                                01365000
                                                                        01370000
  siopsize - (number of words + 1)/2 in the channel program area.       01375000
  cquen    - for a multi-unit controller this field contains the        01380000
             software controller resource number.                       01385000
                                                                        01390000
                                                                        01395000
iflag - controller and channel program state flags                      01400000
                                                                        01405000
  runwait  - an idle channel program should be started when there       01410000
             are no active requests to process.  this flag is always    01415000
             0 for this version of the driver.                          01420000
  waitprog - an idle channel program has been started for this          01425000
             controller.  this bit is reset by an interrupt.            01430000
  ignorehi - an hiop instruction has been issued against this con-      01435000
             troller but the channel program was not in a wait          01440000
             statement.  therefore ignore the interrupt generated by    01445000
             the channel code when this program halts.                  01450000
  hcunit   - highest configured unit number for this controller.        01455000
                                                                        01460000
                                                                        01465000
$page                                                                   01470000
            i/o queue element (ioq)                                     01475000
            -----------------------                                     01480000
                                                                        01485000
                                                                        01490000
     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15   mnemonic          01495000
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+                    01500000
  0|      request dependent flags (see below)      |   qflag            01505000
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+                    01510000
  1| ioq table index to the next ioq element.      |   qlink   <<06834>>01515000
   | points to first word of element.              |                    01520000
   +-----------------------+-----------------------+                    01525000
  2|                         logical device number |   qldev   <<06834>>01530000
   +-----------------------+-----------------------+                    01535000
  3|                                               |   qmisc            01540000
   +--+--------------------------------------------+                    01545000
  4|  | if qflag.(3:1) is clear then this is the   |   qdstn            01550000
   | s| dst number of the target data segment.  if |                    01555000
   |  | s is set, qaddr is db relative.            |                    01560000
   +--+--------------------------------------------+                    01565000
  5| offset in the data segment or system buffer   |   qaddr            01570000
   | table to the target data buffer.              |                    01575000
   +-----------------------+-----------------------+                    01580000
  6|                       | function code for     |   qfunc            01585000
   |                       | this request.  (see   |                    01590000
   |                       | next section.)        |                    01595000
   +-----------------------+-----------------------+                    01600000
  7| on initiation, specifies the word count (>0)  |   qwbct            01605000
   | or byte count (<0).  at completion of the     |                    01610000
   | request this location contains the actual     |                    01615000
   | transmission count in the same units (bytes   |                    01620000
   | or words) as in the request.                  |                    01625000
   +-----------------------------------------------+                    01630000
%10| parameter 1.                                  |   qpar1            01635000
   +-----------------------------------------------+                    01640000
%11| parameter 2.                                  |   qpar2            01645000
   +-----------------------+--------------+--------+                    01650000
%12|                       |  qualifier   |rstatus |   qstat   <<06834>>01655000
   +-----------------------+--------------+--------+                    01660000
%13|                                         pcbn  |   qpcb    <<06834>>01665000
   +-----------------------------------------------+           <<06834>>01670000
                                                                        01675000
                                                                        01680000
qflag - request dependent flags                                         01685000
                                                                        01690000
  bit 0  abort     - abort this request and return an error indication  01695000
                     to the caller.                                     01700000
  bit 1  special   - apply special handling to this request.  (not used)01705000
  bit 2  diag      - this is a request from the diagnostic subsystem.   01710000
  bit 3  sysbuff   - target is an index relative to the sbuf table of   01715000
                     the data buffer.                                   01720000
  bit 4  iowake    - wake caller on completion of request.              01725000
  bit 5  blocked   - blocked i/o.  the caller is waited in attachio     01730000
                     until the request is completed.  implies iowake.   01735000
  bit 6  completed - the request has been completed and the caller      01740000
                     awakened if he had requested (with iowake).        01745000
  bit 7  datafrzn  - set by the memory management routines (mam) when a 01750000
                     makepresent request is successfully completed and  01755000
                     indicates the data segment is frozen in memory.    01760000
  bit 8  mamerrord - an error has occurred while mam was trying to      01765000
                     make the target data segment present and freeze    01770000
                     it in memory.                                      01775000
  bit 9  preq      - (not used)                                         01780000
  bit 10 sfail     - delayed failure of sio instruction.  if a call to  01785000
                     startio resulted in the request being added to     01790000
                     the channel queue, this bit indicates that the sio 01795000
                     instruction failed when the request was selected   01800000
                     for execution.                                     01805000
  bit 11 pfail     - the request was aborted because of a system power  01810000
                     failure.                                           01815000
                                                                        01820000
                                                                        01825000
qstat - pcb number and request completion status.                       01830000
                                                                        01835000
  pcbn      - the process control block (pcb) number of the process     01840000
              which made this request.  if zero, the request is not     01845000
              associated with any process and the ioq element is to     01850000
              be returned by the system when the request has completed. 01855000
  rstatus   - general status indicating the final state of the request. 01860000
              the following codes are used:                             01865000
                                                                        01870000
                0 - not started or awaiting completion.                 01875000
                1 - successful completion.                              01880000
                2 - end-of-file detected.                               01885000
                3 - unusual, but recoverable, condition detected.       01890000
                4 - irrecoverable error has occurred.                   01895000
                                                                        01900000
  qualifier - a code which further defines or qualifies the general     01905000
              status.  (see the section driver return status codes.)    01910000
                                                                        01915000
$page                                                                   01920000
            device reference table drt                                  01925000
            --------------------------                                  01930000
                                                                        01935000
there is one drt per device controller.  the the contents of this       01940000
table are used for processing interrupts.                               01945000
                                                                        01950000
     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15   mnemonic          01955000
   +-----------------------------------------------+                    01960000
  0|      channel program pointer (siop)           |   drt0             01965000
   +-----------------------------------------------+                    01970000
  1|  channel program variable area pointer (cpva) |   drt1             01975000
   +-----------------------------------------------+                    01980000
  2|      interrupt handler program label          |   drt2             01985000
   +--+--+--+--------------------------+--+--+--+--+                    01990000
  3|st|sh|pf|      ( status )          |ws|gf|dt|wt|   drt3             01995000
   +--+--+--+--------------------------+--+--+--+--+                    02000000
                                                                        02005000
 channel program status:                                                02010000
                                                                        02015000
   bit  0 - st, channel program status; 0 - halted, 1 - running         02020000
        1 - sh, siop or hiop instruction pending                        02025000
        2 - pf, power fail recovery in progress                         02030000
       12 - ws, waiting for device status request                       02035000
       13 - gf, gic fifo buffer not empty                               02040000
       14 - dt, dma transfer active                                     02045000
       15 - wt, channel program in wait state                           02050000
                                                                        02055000
                                                                        02060000
                                                                        02065000
                                                                        02070000
                                                                        02075000
                                                                        02080000
                                                                        02085000
                                                                        02090000
                                                                        02095000
                                                                        02100000
                  logging considerations                                02105000
                  ----------------------                                02110000
                                                                        02115000
 dma and channel program aborts log cpva(0).                            02120000
                                                                        02125000
 each type of sio failure logs a different type of information.         02130000
 if the failure occurs in gip, then a '%201' is logged.  if the         02135000
 failure occurs in start'hpib, then a '%202' is logged.  if an          02140000
 error occurs in the driver itself, then a '%203' is logged.  if        02145000
 an illegal haltcode is found in the cpva, then the haltcode is         02150000
 logged.                                                                02155000
                                                                        02160000
 unit, data, timeout, and parity errors log device status.              02165000
                                                                        02170000
 in all cases, the error flags and counters are also logged.            02175000
$page                                                                   02180000
    hp-ib ciper physical driver request codes                           02185000
    -----------------------------------------                           02190000
                                                                        02195000
         operation  function  parameters                                02200000
         ---------  --------  ----------                                02205000
                                                                        02210000
          read           0    none                                      02215000
                                                                        02220000
          write          1    none                                      02225000
                                                                        02230000
          file open      2    none                                      02235000
                                                                        02240000
          file close     3    none                                      02245000
                                                                        02250000
          device close   4    none                                      02255000
                                                                        02260000
          ciper init   184    none                                      02265000
                                                                        02270000
                                                                        02275000
                                                                        02280000
                                                                        02285000
                                                                        02290000
                                                                        02295000
                hp-ib ciper secondary commands                          02300000
                ------------------------------                          02305000
                                                                        02310000
   secondary    mode           definition         # bytes               02315000
   ---------    -----    ---------------------    -------               02320000
                                                                        02325000
    p1100001    write    request to write            0                  02330000
    p1100010    write    enable read                 0                  02335000
    p1100011    write    sequence complete           0                  02340000
    p1100100    write    write data               < 32768               02345000
  * p1101111    write    not defined                 0                  02350000
    p1110001    write    clear crc remainder         0                  02355000
                                                                        02360000
    p1100011    read     sequence abort              1                  02365000
    p1100100    read     read data                < 32768               02370000
    p1110000    read     device specified jump       1                  02375000
    p1110001    read     read crc remainder          2                  02380000
                                                                        02385000
                                                                        02390000
                   where p => odd parity                                02395000
                                                                        02400000
  * - this secondary is not defined for use by the ciper                02405000
      protocol.  however, it is used by this driver to force            02410000
      the peripheral into the protocol error state.  this               02415000
      in turn causes the peripheral to respond affirmatively            02420000
      to a parallel poll.  this method of determining the               02425000
      presence of the peripheral is used during the not ready           02430000
      wait state.                                                       02435000
$page                                                                   02440000
                       driver return status codes                       02445000
                       --------------------------                       02450000
                                                                        02455000
                                                                        02460000
 general status (13:3)       qualifying status (8:5)      overall (8:8) 02465000
                                                                        02470000
 0 - pending                1 - waiting for completion         %10      02475000
                            3 - not ready wait                 %30      02480000
                                                                        02485000
 1 - successful             0 - no errors                       %1      02490000
                                                                        02495000
 2 - end of file            (not used)                                  02500000
                                                                        02505000
 3 - unusual condition      3 - request aborted                %33      02510000
                            6 - powerfail abort                %63      02515000
                          %21 - device powered up             %213      02520000
                                                                        02525000
 4 - irrecoverable error    0 - invalid request                 %4      02530000
                            1 - transfer error                 %14      02535000
                            2 - i/o timed out before complete  %24      02540000
                            4 - sio failure                    %44      02545000
                            5 - unit failure                   %54      02550000
                          %12 - system error                  %124      02555000
                          %14 - channel failure               %144      02560000
                          %21 - parity error                  %214      02565000
                                                                        02570000
                                                                        02575000
;                                                              <<06834>>02580000
$page "TABLE PARAMETERS"                                                02585000
begin                                                                   02590000
$include inclioq                                               <<06834>>02595000
  equate                                                                02600000
                                                                        02605000
       << ditp parameters >>                                            02610000
                                                                        02615000
    dcounts   = 10,  << error flags and counters >>                     02620000
    diltp     =  5,  << interrupt linkage table pointer >>              02625000
    dldev     =  3,  << logical device and unit numbers >>              02630000
    dlogcount = 12,  << dit hardware logged error counters >>           02635000
    dlogerror = 11,  << dit hardware logged error status >>             02640000
    drqst     =  9,  << driver request flags >>                         02645000
    dsave     =  6,  << driver flags >>                                 02650000
    dserr     =  7,  << dit hardware count & index >>                   02655000
    dtime     =  8,  << time-out request entry index >>                 02660000
                                                                        02665000
       << ioqp parameters >>                                            02670000
                                                                        02675000
    qflag     =  0,  << request flags >>                                02680000
                                                               <<06834>>02685000
                                                               <<06834>>02690000
                                                               <<06834>>02695000
                                                               <<06834>>02700000
                                                                        02705000
$page "CHANNEL PROGRAM VALUES"                                          02710000
       << channel program addresses >>                                  02715000
                                                                        02720000
    addr1      =   3,  << address channel to talk & device to listen >> 02725000
    addr2      =  25,  << address channel to talk & device to listen >> 02730000
    addr3      =  32,  << address channel to talk & device to listen >> 02735000
    bankno     =  12,  << bank number address >>                        02740000
    bufad      =  13,  << buffer address address >>                     02745000
    bytcnt     =  10,  << read / write instruction byte count >>        02750000
    cmnd1      =   4,  << request to write / enable read address >>     02755000
    cmnd2      =   9,  << read / write data address >>                  02760000
    dsaveadd   =  44,  << address of word 6 of dit >>                   02765000
    jmprel     =   1,  << channel program entry jump address >>         02770000
                                                                        02775000
    siobase    =   2,  << address of 0 rel jump >>                      02780000
    siodata    =   2 - siobase,                                         02785000
    sionotrdy  =  31 - siobase,                                         02790000
    sioabort   =  38 - siobase,                                         02795000
                                                                        02800000
       << channel program instructions >>                               02805000
                                                                        02810000
    req2wr     = %60477,  << request to write >>                        02815000
    enabrd     = %61077,  << enable read >>                             02820000
    wrdata     =  %2004,  << write data >>                              02825000
    rddata     =  %1404,  << read data >>                               02830000
    addcmd     = %57040,  << add channel to talk & device to listen >>  02835000
$page "STATES AND STATUS"                                               02840000
       << completion statuses >>                                        02845000
                                                                        02850000
    chanfail  = %144,  << i/o channel error >>                          02855000
    datafail  =  %14,  << data transfer error >>                        02860000
    goodio    =    1,  << successful i/o completion >>                  02865000
    invalidop =    4,  << invalid operation requested >>                02870000
    parity    = %214,  << parity error >>                               02875000
    pending   =  %10,  << waiting for completion >>                     02880000
    pfabort   =  %63,  << request aborted due to power failure >>       02885000
    siofail   =  %44,  << sio failure >>                                02890000
    sysfail   = %124,  << system failure >>                             02895000
    timeout   =  %24,  << timed out error >>                            02900000
    unitfail  =  %54,  << unit failure >>                               02905000
    userabort =  %33,  << request aborted >>                            02910000
                                                                        02915000
       << siodm states >>                                               02920000
                                                                        02925000
    call'completor =  3,  << monitor state = 3 >>                       02930000
    call'initiator =  2,  << monitor state = 2 >>                       02935000
    intrptwait     =%13,  << wait for i/o completion >>                 02940000
    requestdone    =  5,  << request done >>                            02945000
                                                                        02950000
       << miscellaneous equates >>                                      02955000
                                                                        02960000
    ciper'init  =   184,  << ciper initialize function >>               02965000
    clear       =     0,  << flag clear value >>                        02970000
    dclose      =     4,  << device close function >>                   02975000
    fclose      =     3,  << file close function >>                     02980000
    fopen       =     2,  << file open function >>                      02985000
    icntrl      =     7,  << ilt control information >>                 02990000
    iotimer     =   %20,  << i/o timer parameter >>                     02995000
    isiop       =     8,  << ilt channel program area pointer >>        03000000
    log2bytes   =  [8/2,8/dlogerror],  << log dlogerror & dlogcount >>  03005000
    maxnotredy  =     2,  << # of not ready waits before abort >>       03010000
    maxtimeout  =     2,  << # of timeout errors before abort >>        03015000
    maxuniterr  =     2,  << # of unit errors before abort >>           03020000
    maxdataerr  =     2,  << # of crc errors before abort >>            03025000
    nrdymsg     =    11,  << not ready message number >>                03030000
    read        =     0,  << read file function >>                      03035000
    set'        =     1,  << flag set value >>                          03040000
    sysdb       = %1000,  << address of sysdb area >>                   03045000
    sysmset     =     1,  << system message set in catalog >>           03050000
    write       =     1,  << write file function >>                     03055000
  endeq         =     0;                                                03060000
$page "DEFINITIONS"                                                     03065000
                                                                        03070000
       << i/o status bit definitions >>                                 03075000
                                                                        03080000
     define                                                             03085000
       dvrabflag      = ditpl(dsave).( 1:1)#,     << abort request >>   03090000
       notrdyflag     = ditpl(dsave).( 4:1)#,     << not ready flag >>  03095000
       notredycount   = ditpl(dsave).( 5:3)#,     << not rdy counter >> 03100000
       paritybit      = ditpl(dsave).(14:1)#,     << parity error bit >>03105000
       ponbit         = ditpl(dsave).(12:1)#,     << power up/reset >>  03110000
       poppedflag     = ditpl(dsave).( 3:1)#,     << sw timer popped >> 03115000
       protobit       = ditpl(dsave).(13:1)#,     << protocol error >>  03120000
       retryflag      = ditpl(dsave).( 2:1)#,     << error detected >>  03125000
       validstatus    = ditpl(dsave).( 0:1)#,     << status updated >>  03130000
                                                                        03135000
       << qflag bit definitions >>                                      03140000
                                                                        03145000
       abort      = ioq'abort#,           << abort request >>  <<06834>>03150000
       diag       = ioq'diag#,            << diagnostic bit >> <<06834>>03155000
       pfail      = ioq'pfail#,           << abort due to pwr f<<06834>>03160000
       sfail      = ioq'sfail#,           << delayed start sio <<06834>>03165000
                                                                        03170000
       << dcounts field definitions >>                                  03175000
                                                                        03180000
       requestfailed  = ditpl(dcounts).( 0:1)#,  << request failed >>   03185000
       uniterrflag    = ditpl(dcounts).( 1:1)#,  << unit error >>       03190000
       dataerrflag    = ditpl(dcounts).( 2:1)#,  << data error >>       03195000
       gictoflag      = ditpl(dcounts).( 3:1)#,  << gic timeout >>      03200000
       uniterrcount   = ditp (dcounts).( 4:3)#,  << unit error >>       03205000
       dataerrcount   = ditp (dcounts).( 7:3)#,  << data error >>       03210000
       timeoutcount   = ditp (dcounts).(10:3)#,  << gic time out >>     03215000
       paritycount    = ditp (dcounts).(13:3)#,  << hp-ib parity >>     03220000
                                                                        03225000
       << miscellaneous definitions >>                                  03230000
                                                                        03235000
       devadd     = (13:3)#,              << device address on hp-ib >> 03240000
       errorcode  = cpvap.( 0:3)#,        << hardware error code >>     03245000
       func       = ( 8:8)#,              << function code >>           03250000
       haltcode   = cpvap(1).(4:12)#,     << chanp halt code >>         03255000
       iostat     = ioq'stat#,            << request status ret<<06834>>03260000
       ldev       = ditpl(dldev).( 8:8)#, << logical device # >>        03265000
       timedout   = cpvap.(13:1)#,        << xfer aborted-timed out >>  03270000
     enddef       = 0#;                                                 03275000
$page "DIT INITIALIZATION"                                              03280000
<<                                                                      03285000
        *********************************                               03290000
        *                               *                               03295000
        *   driver db area definition   *                               03300000
        *                               *                               03305000
        *********************************                               03310000
>>                                                                      03315000
                                                                        03320000
        equate stat'size = 1;                                  <<06834>>03325000
        array initial(0:142) = db :=                                    03330000
        [8/13,8/1],   << dit size, not core resident >>                 03335000
                      << no idle channel program, driver type >>        03340000
                 0,   << not used >>                                    03345000
                 0,   << unit extract instruction - not used >>         03350000
        [8/24,8/stat'size],   << channel program size/2 >>     <<06834>>03355000
                                                                        03360000
        << dit >>                                                       03365000
                 0,   << dflag >>                                       03370000
                 0,   << dlink >>                                       03375000
                 0,   << dioqp >>                                       03380000
           %040000,   << dldev - hpib device >>                         03385000
                 0,   << ddltp >>                                       03390000
                 0,   << diltp >>                                       03395000
                 0,   << dsave >>                                       03400000
                 0,   << dserr >>                                       03405000
                 0,   << dtime >>                                       03410000
                 0,   << drqst >>                                       03415000
                 0,   << dcounts >>                                     03420000
                 0,   << dlogerror >>                                   03425000
                 0,   << dlogcount >>                                   03430000
                                                                        03435000
$page "CHANNEL PROGRAM"                                                 03440000
<<*******************************************************************>> 03445000
<<*******************************************************************>> 03450000
<<                                                                   >> 03455000
<<                         channel program                           >> 03460000
<<                                                                   >> 03465000
<<*******************************************************************>> 03470000
<<*******************************************************************>> 03475000
<< 0>>  << jump >>              0,  << branch point to cp section >>    03480000
<< 1>>                          0,  << +0:r/w  29:not rdy  36:seq ab >> 03485000
                                                                        03490000
<< 2>>  << cmd hp-ib >>     %6404,                                      03495000
<< 3>>                     %57040,  << chan talk; dev listen >>         03500000
<< 4>>                          0,  << req to wrt/enab rd; unlisten >>  03505000
<< 5>>                          0,                                      03510000
<< 6>>                          0,                                      03515000
                                                                        03520000
<< 7>>  << wait >>          %1100,  << includes crc initialize >>       03525000
<< 8>>                          0,                                      03530000
                                                                        03535000
<< 9>>  << read/write >>        0,  << read/write data >>               03540000
<<10>>                          0,  << byte count >>                    03545000
<<11>>                          0,                                      03550000
<<12>>                          0,  << flags & bank number >>           03555000
<<13>>                          0,  << address >>                       03560000
                                                                        03565000
<<14>>  << dsj >>           %2401,  << check peripheral's response >>   03570000
<<15>>                          0,  << return byte >>                   03575000
<<16>>                          4,  << affirmative response >>          03580000
<<17>>                          0,  << negative response >>             03585000
                                                                        03590000
<<*******************************************************************>> 03595000
<<                                                                   >> 03600000
<<           negative and illegal dsj response handling              >> 03605000
<<                                                                   >> 03610000
<<*******************************************************************>> 03615000
<<18>>  << crc compare >>  %10601,  << check the crc remainders >>      03620000
<<19>>                      %7774,  << halt code = 3 >>                 03625000
                                                                        03630000
<<20>>  << interrupt halt >> %601,  << negative or illegal dsj >>       03635000
<<21>>                          2,                                      03640000
                                                                        03645000
<<*******************************************************************>> 03650000
<<                                                                   >> 03655000
<<                 continue with good dsj response                   >> 03660000
<<                                                                   >> 03665000
<<*******************************************************************>> 03670000
<<22>>  << crc compare >>  %10601,  << check the crc remainders >>      03675000
<<23>>                      %7774,  << halt code = 3 >>                 03680000
                                                                        03685000
<<24>>  << cmd hp-ib >>     %6404,                                      03690000
<<25>>                     %57040,  << chan talk; dev listen >>         03695000
<<26>>                     %61477,  << sequence complete; unlisten >>   03700000
<<27>>                          0,                                      03705000
<<28>>                          0,                                      03710000
                                                                        03715000
<<29>>  << interrupt halt >> %601,  << transmission successful >>       03720000
<<30>>                          1,                                      03725000
                                                                        03730000
<<*******************************************************************>> 03735000
<<                                                                   >> 03740000
<<                          not ready wait                           >> 03745000
<<                                                                   >> 03750000
<<*******************************************************************>> 03755000
<<31>>  << cmd hp-ib >>     %6404,                                      03760000
<<32>>                     %57040,  << chan talk; dev listen >>         03765000
<<33>>                     %67477,  << illegal secondary; unlisten >>   03770000
<<34>>                          0,                                      03775000
<<35>>                          0,                                      03780000
                                                                        03785000
<<36>>  << wait >>          %1000,  << wait for peripheral to wake up >>03790000
<<37>>                          0,                                      03795000
                                                                        03800000
<<*******************************************************************>> 03805000
<<                                                                   >> 03810000
<<                          sequence abort                           >> 03815000
<<                                                                   >> 03820000
<<*******************************************************************>> 03825000
<<38>>  << init crc >>     %10000,  << clear crc remainders >>          03830000
<<39>>                          0,                                      03835000
                                                                        03840000
<<40>>  << read data >>     %1403,  << sequence abort >>                03845000
<<41>>                          1,  << 1 byte >>                        03850000
<<42>>                          0,                                      03855000
<<43>>                     %42000,  << right byte; non-update >>        03860000
<<44>>                          0,  << add of word 6 of dit >>          03865000
                                                                        03870000
<<45>>  << jump >>              0,  << continue execution with >>       03875000
<<46>>                        -25;  << crc compare instruction >>       03880000
$page "EXTERNAL PROCEDURES"                                             03885000
<<                                                                      03890000
         ***************************************                        03895000
         *                                     *                        03900000
         *   external procedure declarations   *                        03905000
         *                                     *                        03910000
         ***************************************                        03915000
>>                                                                      03920000
                                                                        03925000
   procedure aborttimereq(trlx);                                        03930000
     value trlx;                                                        03935000
     integer trlx;                                                      03940000
     option external;                                                   03945000
                                                                        03950000
   procedure gip'hpib;                                                  03955000
     option external;                                                   03960000
                                                                        03965000
   logical procedure iomessage(setno,msgno,mask,p1,p2,p3,p4,p5,         03970000
                               dest,reply,offset,ditp,iotype);          03975000
     value setno,msgno,mask,p1,p2,p3,p4,p5,dest,reply,offset,iotype;    03980000
     integer setno,msgno,mask,p1,p2,p3,p4,p5,dest,reply,offset,iotype;  03985000
     integer pointer ditp;                                              03990000
     option external, variable;                                         03995000
                                                                        04000000
   procedure logerror(ditp,ioqp,errstat);                      <<06834>>04005000
      value ditp,ioqp,errstat;                                 <<06834>>04010000
      integer pointer ditp;                                    <<06834>>04015000
      integer ioqp;                                            <<06834>>04020000
      integer errstat;                                                  04025000
      option external;                                                  04030000
                                                                        04035000
   procedure masterclearhpib(ditp);                                     04040000
     integer array ditp;                                                04045000
     option external;                                                   04050000
                                                                        04055000
   procedure siodm(ditp,flags);                                         04060000
     value ditp,flags;                                                  04065000
     logical flags;                                                     04070000
     pointer ditp;                                                      04075000
     option external;                                                   04080000
                                                                        04085000
   procedure start'hpib(ditp,siop,qflag);                               04090000
     value ditp,siop,qflag;                                             04095000
     logical qflag;                                                     04100000
     pointer ditp,siop;                                                 04105000
     option external;                                                   04110000
                                                                        04115000
   integer procedure timereq(code,req,time);                            04120000
     value code,req,time;                                               04125000
     integer code,req;                                                  04130000
     double time;                                                       04135000
     option external;                                                   04140000
$page "DRIVER INITIALIZATION"                                           04145000
<<        ******************************************                    04150000
          *                                        *                    04155000
          *   driver initialization procedure      *                    04160000
          *                                        *                    04165000
          ******************************************                    04170000
>>                                                                      04175000
                                                                        04180000
                                                                        04185000
   procedure cpinit(ditp);                                              04190000
     integer array ditp;                                                04195000
                                                                        04200000
<<---------------------------------------------------->>                04205000
<<                                                    >>                04210000
<<   this procedure initializes the restricted mode   >>                04215000
<<   addresses and the status buffer addresses in     >>                04220000
<<   the channel program.                             >>                04225000
<<                                                    >>                04230000
<<---------------------------------------------------->>                04235000
                                                                        04240000
     begin                                                              04245000
       integer pointer iltp   = q+1;                                    04250000
       integer pointer siop   = q+2;                                    04255000
                                                                        04260000
       tos := ditp(diltp);      << iltp    >>                           04265000
       tos := iltp(isiop);      << siop    >>                           04270000
                                                                        04275000
       siop(addr1) := siop(addr2) := siop(addr3) :=                     04280000
             addcmd + iltp(icntrl).devadd;     << chan tlk; dev lst >>  04285000
       siop(dsaveadd) := @ditp + sysdb + dsave;<< keep status in dit >> 04290000
                                                                        04295000
     end;                                                               04300000
$page "CIPER DRIVER"                                                    04305000
<<    ******************************************************            04310000
      *                                                    *            04315000
      *   ciper hp-ib physical driver procedure - cpdrvr   *            04320000
      *                                                    *            04325000
      ******************************************************            04330000
>>                                                                      04335000
                                                                        04340000
   integer procedure cpdrvr(ioqp,ditp,bank,buffaddr,siop,drtn);         04345000
                                                                        04350000
<<--------------------------------------------------------->>           04355000
<<                                                         >>           04360000
<<   this procedure initiates and completes i/o requests   >>           04365000
<<   for the device connected to the ciper hp-ib physical  >>           04370000
<<   driver.                                               >>           04375000
<<                                                         >>           04380000
<<   mode returns in cpdrvr -                              >>           04385000
<<     5 - request completed                               >>           04390000
<<   %13 - wait for completion                             >>           04395000
<<                                                         >>           04400000
<<--------------------------------------------------------->>           04405000
                                                                        04410000
   value ditp,ioqp,bank,buffaddr,siop,drtn;                             04415000
   integer bank,buffaddr,drtn;                                          04420000
   integer pointer ditp,siop;                                  <<06834>>04425000
   integer ioqp;                                               <<06834>>04430000
   option privileged,uncallable;                                        04435000
                                                                        04440000
   begin                                                                04445000
     logical array                                                      04450000
                                                               <<06834>>04455000
       ditpl(*)   = ditp;                                               04460000
                                                                        04465000
     integer pointer                                                    04470000
       cpvap;              << holds channel i/o status >>      <<06834>>04475000
                                                                        04480000
     integer                                                            04485000
       fcode,              << function code >>                 <<06834>>04490000
       count,              << buffer byte count >>             <<06834>>04495000
       ioq'entry'index,     << replaces ioqp >>                <<06834>>04500000
       mstate     = cpdrvr;<< monitor state return >>                   04505000
$page "INTERNAL PROCEDURES"                                             04510000
<<                                                                      04515000
         ***************************************                        04520000
         *                                     *                        04525000
         *   internal procedure declarations   *                        04530000
         *                                     *                        04535000
         ***************************************                        04540000
>>                                                                      04545000
                                                                        04550000
   subroutine logstatus;                                                04555000
                                                                        04560000
   << called to log device status and error counts >>                   04565000
                                                                        04570000
     begin                                                              04575000
       ditp(dlogerror) := ditp(dsave);                                  04580000
       ditp(dlogcount) := ditp(dcounts);                                04585000
       logerror(ditp,ioq'entry'index,log2bytes);               <<06834>>04590000
     end;                                                               04595000
$page "INITIATOR AND CONTINUATOR COMMON AREA"                           04600000
<<---------------------------------------------------->>                04605000
<<                                                    >>                04610000
<<   initialize local pointers and variables          >>                04615000
<<                                                    >>                04620000
<<---------------------------------------------------->>                04625000
     ioq'entry'index := ioqp; << must be set 1st >>            <<06834>>04630000
    @cpvap := ditp(diltp);       << cpvap >>                   <<06834>>04635000
     fcode := ioq'func;  << fcode >>                           <<06834>>04640000
     count := ioq'count;       << count >>                     <<06834>>04645000
     if count < 0  << change to positive byte cnt >>           <<06834>>04650000
        then count := -count                                   <<06834>>04655000
        else count := count & lsl(1);                          <<06834>>04660000
                                                                        04665000
     if mstate = call'initiator then                                    04670000
       begin                   << this is an initiator call >>          04675000
         ditp(dcounts) :=                                               04680000
         ditp(dsave) := 0;     << clear flags & counts >>               04685000
         if ioq'entry'index = 0 then                           <<06834>>04690000
           begin               << nothing to do >>                      04695000
             tos := goodio;                                             04700000
             goto iodone;                                               04705000
           end;                                                         04710000
       end;                                                             04715000
                                                                        04720000
     if mstate = call'completor then                                    04725000
       aborttimereq(ditp(drqst)); << abort timer >>                     04730000
                                                                        04735000
     << check for power fail or abort request >>                        04740000
                                                                        04745000
  retry:                                                                04750000
     if abort then             << abort request >>                      04755000
       if pfail then           << power fail abort >>                   04760000
         begin                                                          04765000
           masterclearhpib(ditp);                                       04770000
           tos := pfabort;                                              04775000
           goto errorexit;                                              04780000
         end                                                            04785000
       else                    << user abort >>                         04790000
         if dvrabflag then     << seq abort already in progress >>      04795000
           begin                                                        04800000
             tos := userabort;                                          04805000
             goto errorexit;                                            04810000
           end                                                          04815000
         else                  << need to start seq abort >>            04820000
           begin                                                        04825000
             masterclearhpib(ditp);                                     04830000
             ditp(dsave) := 0; << clear flags >>                        04835000
             dvrabflag := set';                                         04840000
             goto seqabort;                                             04845000
           end;                                                         04850000
                                                                        04855000
     if mstate = call'completor then                                    04860000
       goto cpcont;            << completion interrupt >>               04865000
                                                                        04870000
$page "DRIVER INITIATOR"                                                04875000
<<****************************************************>>                04880000
<<                                                    >>                04885000
<<                initialization section              >>                04890000
<<                                                    >>                04895000
<<****************************************************>>                04900000
                                                                        04905000
  << set up read/write cp variables >>                                  04910000
                                                                        04915000
     siop(jmprel) := siodata;  << cp jump to read/write >>              04920000
     siop(bytcnt) := count;                                             04925000
     siop(bankno) := bank;                                              04930000
     siop(bufad)  := buffaddr;                                          04935000
                                                                        04940000
                                                                        04945000
                                                                        04950000
                                                                        04955000
                                                                        04960000
<<---------------------------------------------------->>                04965000
<<                                                    >>                04970000
<<   file read [function = 0]                         >>                04975000
<<                                                    >>                04980000
<<---------------------------------------------------->>                04985000
                                                                        04990000
     if fcode = read then                                               04995000
       begin                     << read processing >>                  05000000
         if count < 1 then                                              05005000
           goto reqdone;         << no data to xfer >>                  05010000
         siop(cmnd1) := enabrd;  << enable read     >>                  05015000
         siop(cmnd2) := rddata;  << read data sec   >>                  05020000
         goto startcp;                                                  05025000
       end                       << read processing >>                  05030000
                                                                        05035000
                                                                        05040000
                                                                        05045000
                                                                        05050000
                                                                        05055000
                                                                        05060000
<<---------------------------------------------------->>                05065000
<<                                                    >>                05070000
<<   file write [function = 1]                        >>                05075000
<<                                                    >>                05080000
<<---------------------------------------------------->>                05085000
                                                                        05090000
     else if fcode = write then                                         05095000
       begin                     << write processing >>                 05100000
         if count < 1 then                                              05105000
           goto reqdone;         << no data to xfer >>                  05110000
         siop(cmnd1) := req2wr;  << request to write >>                 05115000
         siop(cmnd2) := wrdata;  << write data sec   >>                 05120000
         goto startcp;                                                  05125000
       end                       << write processing >>                 05130000
                                                                        05135000
$page                                                                   05140000
<<---------------------------------------------------->>                05145000
<<                                                    >>                05150000
<<   file open    [function = 2]                      >>                05155000
<<   file close   [function = 3]                      >>                05160000
<<   device close [function = 4]                      >>                05165000
<<                                                    >>                05170000
<<---------------------------------------------------->>                05175000
                                                                        05180000
     else if (fcode = fopen)                                            05185000
          or (fcode = fclose)                                           05190000
          or (fcode = dclose) then                                      05195000
            begin                                                       05200000
              count := 0;      << no data xferred >>                    05205000
              goto reqdone     << good completion >>                    05210000
            end                                                         05215000
                                                                        05220000
                                                                        05225000
                                                                        05230000
                                                                        05235000
                                                                        05240000
<<---------------------------------------------------->>                05245000
<<                                                    >>                05250000
<<   ciper initialize [function = 184]                >>                05255000
<<                                                    >>                05260000
<<---------------------------------------------------->>                05265000
                                                                        05270000
     else if fcode = ciper'init then                                    05275000
       begin                                                            05280000
         if count < 6 then goto invalidfunc;                            05285000
                                                                        05290000
<<  return 3 words:  level2 header size (0)           >>                05295000
<<                   level 2 trailer size (0)         >>                05300000
<<                   max packet size (0 or no limit)  >>                05305000
                                                                        05310000
         tos := bank;                                                   05315000
         tos := buffaddr;                                               05320000
         assemble (ddup,       << duplicate address >>                  05325000
                   zero;       << level 2 header size >>                05330000
                   ssea;                                                05335000
                   inca,       << incr buffaddr >>                      05340000
                   dzro;       << level 2 trailer size >>               05345000
                   sdea);      << maximum packet size >>                05350000
         count := 6;           << 6 bytes xferred >>                    05355000
         goto reqdone          << good completion >>                    05360000
       end                                                              05365000
                                                                        05370000
                                                                        05375000
                                                                        05380000
                                                                        05385000
                                                                        05390000
<<---------------------------------------------------->>                05395000
<<                                                    >>                05400000
<<   all other functions                              >>                05405000
<<                                                    >>                05410000
<<---------------------------------------------------->>                05415000
                                                                        05420000
     else goto invalidfunc;                                             05425000
$page "SET UP AND START CHANNEL PROGRAM"                                05430000
<<---------------------------------------------------->>                05435000
<<                                                    >>                05440000
<<   start channel program                            >>                05445000
<<                                                    >>                05450000
<<---------------------------------------------------->>                05455000
                                                                        05460000
  startcp:                                                              05465000
     cpvap(0) := 0;                << clear channel status words >>     05470000
     cpvap(1) := 0;                                                     05475000
     cpvap(2) := 0;                                                     05480000
     cpvap(3) := 0;                                                     05485000
                                                                        05490000
     start'hpib(ditp,siop,true);   << start channel program >>          05495000
     if < then                                                          05500000
       begin                       << sio failure >>                    05505000
         tos := %201;                                                   05510000
         goto sioerror;                                                 05515000
       end;                                                             05520000
                                                                        05525000
     ditp(dtime) := 0;             << clear timer flag >>               05530000
     ditp(drqst) := timereq(iotimer,@ditp,10000d); << 10 sec >>         05535000
                                                                        05540000
     iostat := pending;                                                 05545000
     mstate := intrptwait;                                              05550000
     return;                                                            05555000
                                                                        05560000
$page "DRIVER CONTINUATOR"                                              05565000
<<****************************************************>>                05570000
<<                                                    >>                05575000
<<                continuator section                 >>                05580000
<<                                                    >>                05585000
<<****************************************************>>                05590000
                                                                        05595000
  cpcont:                                                               05600000
     if errorcode = 6 then           << dma abort >>                    05605000
       goto chanerror;                                                  05610000
                                                                        05615000
     if errorcode = 7 then           << channel abort >>                05620000
       if timedout <> 1 then                                            05625000
         goto chanerror              << not gic timeout >>              05630000
                                                                        05635000
       else                                                             05640000
         begin                       << gic timeout >>                  05645000
           timeoutcount := timeoutcount + 1;                            05650000
           if not gictoflag then                                        05655000
             begin                   << last error not gic to >>        05660000
               gictoflag := set';                                       05665000
               if retryflag and (timeoutcount > maxtimeout) then        05670000
                 goto timeouterror   << timed out during final retry >> 05675000
               else goto erroretry;                                     05680000
             end                                                        05685000
                                                                        05690000
           else                                                         05695000
             begin                   << two gic to's in a row >>        05700000
               if not iomessage(sysmset,nrdymsg,%10000,ldev,,,,,) then  05705000
                 goto syserr;                                           05710000
               notredycount := notredycount + 1;                        05715000
               if notredycount > maxnotredy then                        05720000
                 goto timeouterror;  << too many not ready waits >>     05725000
               poppedflag := clear;  << in case there was one >>        05730000
               gictoflag := clear;   << reset gic to info >>            05735000
               timeoutcount := 0;                                       05740000
               goto notrdywait;                                         05745000
             end;                                                       05750000
         end;                                                           05755000
                                                                        05760000
     if sfail then                                                      05765000
       begin                         << failure on delayed start i/o >> 05770000
         tos := %202;                                                   05775000
         goto sioerror;                                                 05780000
       end;                                                             05785000
                                                                        05790000
     ditp(dtime).(0:1) := 0;         << set cc on timer >>              05795000
     if <> then                                                         05800000
       begin                         << timer popped >>                 05805000
         masterclearhpib(ditp);      << abort channel program >>        05810000
         if notrdyflag then                                             05815000
           goto notrdywait;          << keep waiting >>                 05820000
         poppedflag := set';                                            05825000
         goto erroretry;                                                05830000
       end;                                                             05835000
$page                                                                   05840000
     if haltcode = 1 then            << normal completion >>            05845000
       goto cpendedaok                                                  05850000
                                                                        05855000
     else if haltcode = 2 then       << negative or illegal dsj >>      05860000
       begin                                                            05865000
         uniterrflag := set';                                           05870000
         uniterrcount := uniterrcount + 1;                              05875000
         goto erroretry;                                                05880000
       end                                                              05885000
                                                                        05890000
     else if haltcode = 3 then                                          05895000
       begin                         << bad crc >>                      05900000
         dataerrflag := set';                                           05905000
         dataerrcount := dataerrcount + 1;                              05910000
         if retryflag and (dataerrcount > maxdataerr) then              05915000
           goto dataerror            << data error during final retry >>05920000
         else goto erroretry;                                           05925000
       end                                                              05930000
                                                                        05935000
     else                                                               05940000
       begin                         << illegal cpva code >>            05945000
         tos := haltcode;                                               05950000
         goto sioerror;                                                 05955000
       end;                                                             05960000
$page "HANDLE SEQUENCE ABORT RETRIES"                                   05965000
  cpendedaok:                                                           05970000
     if not retryflag then                                              05975000
       begin                         << successful completion >>        05980000
         count := count - siop(bytcnt);  << # bytes xferred >>          05985000
         goto reqdone;                                                  05990000
       end                                                              05995000
                                                                        06000000
     else                            << status just read >>             06005000
       begin                                                            06010000
         retryflag := clear;                                            06015000
         validstatus := set';        << validate status >>              06020000
                                                                        06025000
         if uniterrflag then                                            06030000
           if uniterrcount > maxuniterr then                            06035000
             goto uniterror          << too many unit errors >>         06040000
           else if not ponbit then                                      06045000
             logstatus;              << only log if not pwr up/reset >> 06050000
                                                                        06055000
         if dataerrflag then                                            06060000
           if dataerrcount > maxdataerr then                            06065000
             goto dataerror          << too many data errors >>         06070000
           else if not ponbit then                                      06075000
             logstatus;              << only log if not pwr up/reset >> 06080000
                                                                        06085000
         if gictoflag then           << gic timed out >>                06090000
           begin                                                        06095000
             if paritybit then       << caused by hp-ib parity err >>   06100000
               paritycount := paritycount + 1;                          06105000
             if timeoutcount > maxtimeout then                          06110000
               goto timeouterror     << too many time outs >>           06115000
             else logstatus;         << log error status >>             06120000
           end;                                                         06125000
                                                                        06130000
         if poppedflag then          << software timer popped >>        06135000
           if protobit then                                             06140000
             logstatus;              << only log protocol errors >>     06145000
                                                                        06150000
         if uniterrflag or dataerrflag or gictoflag                     06155000
               or poppedflag or notrdyflag then                         06160000
                                                                        06165000
           begin                     << we're here for a reason >>      06170000
             validstatus := clear;   << clear flags >>                  06175000
             uniterrflag := clear;                                      06180000
             dataerrflag := clear;                                      06185000
             gictoflag   := clear;                                      06190000
             poppedflag  := clear;                                      06195000
             notrdyflag  := clear;                                      06200000
             mstate := call'initiator;  << change state for retry >>    06205000
             goto retry;                                                06210000
           end                                                          06215000
                                                                        06220000
         else                                                           06225000
           begin                     << should never occur >>           06230000
             tos := %203;                                               06235000
             goto sioerror;                                             06240000
           end;                                                         06245000
       end;                                                             06250000
$page "DRIVER EXITS"                                                    06255000
  chanerror:                      << channel failure >>                 06260000
     ditp(dserr) := log2bytes;                                          06265000
     ditp(dlogerror) := cpvap;    << log error codes >>                 06270000
     ditp(dlogcount) := ditp(dcounts);                                  06275000
     tos := chanfail;                                                   06280000
     goto errorexit;                                                    06285000
                                                                        06290000
  dataerror:                      << crc remainders disagreed >>        06295000
     tos := datafail;                                                   06300000
     goto stdlogging;                                                   06305000
                                                                        06310000
  invalidfunc:                    << illegal function code >>           06315000
     tos := invalidop;                                                  06320000
     goto errorexit;                                                    06325000
                                                                        06330000
  sioerror:                       << sio failure >>                     06335000
     ditp(dserr) := log2bytes;                                          06340000
     ditp(dlogerror) := tos;      << value logged depends on caller >>  06345000
     ditp(dlogcount) := ditp(dcounts);                                  06350000
     tos := siofail;                                                    06355000
     goto errorexit;                                                    06360000
                                                                        06365000
  syserr:                         << system error >>                    06370000
     tos := sysfail;                                                    06375000
     goto errorexit;                                                    06380000
                                                                        06385000
  timeouterror:                   << gic hardware time out >>           06390000
     if paritycount > 0 then                                            06395000
       tos := parity              << time outs caused by parity >>      06400000
     else                                                               06405000
       tos := timeout;                                                  06410000
     goto stdlogging;                                                   06415000
                                                                        06420000
  uniterror:                      << negative / illegal dsj responses >>06425000
     tos := unitfail;                                                   06430000
                                                                        06435000
  stdlogging:                                                           06440000
     requestfailed := set';       << indicate request aborted >>        06445000
     ditp(dserr) := log2bytes;                                          06450000
     ditp(dlogerror) := ditp(dsave);  << log device status & counts >>  06455000
     ditp(dlogcount) := ditp(dcounts);                                  06460000
                                                                        06465000
  errorexit:                                                            06470000
     ioq'count   := 0;            << indicate no data xferred ><<06834>>06475000
     goto iodone;                                                       06480000
                                                                        06485000
  reqdone:                                                              06490000
     if ioq'count.(0:1) << test if logical value is < 0 >>     <<06834>>06495000
        then ioq'count   := -count                             <<06834>>06500000
        else ioq'count   := (count + 1)&lsr(1);                <<06834>>06505000
     tos := goodio;                                                     06510000
                                                                        06515000
  iodone:                                                               06520000
     iostat := tos;               << store return status >>             06525000
     mstate := requestdone;                                             06530000
     return;                                                            06535000
$page "NOT READY WAIT & SEQUENCE ABORT"                                 06540000
<<---------------------------------------------------->>                06545000
<<                                                    >>                06550000
<<               not ready wait                       >>                06555000
<<                                                    >>                06560000
<<---------------------------------------------------->>                06565000
                                                                        06570000
  notrdywait:                                                           06575000
     notrdyflag := set';          << note not ready wait >>             06580000
     retryflag := set';           << also do retry >>                   06585000
     siop(jmprel) := sionotrdy;   << not ready cp entry >>              06590000
     goto startcp;                                                      06595000
                                                                        06600000
<<---------------------------------------------------->>                06605000
<<                                                    >>                06610000
<<               sequence abort                       >>                06615000
<<                                                    >>                06620000
<<---------------------------------------------------->>                06625000
                                                                        06630000
  erroretry:                                                            06635000
     retryflag := set';           << note retry in effect >>            06640000
                                                                        06645000
  seqabort:                                                             06650000
     siop(jmprel) := sioabort;    << sequence abort cp entry >>         06655000
     goto startcp;                                                      06660000
$page "TABLES"                                                          06665000
end;                                                                    06670000
$page "MAP"                                                             06675000
   assemble(                                                            06680000
     pcal siodm;     << monitor >>                                      06685000
     pcal cpdrvr;    << initiator >>                                    06690000
     pcal cpdrvr;    << continuator >>                                  06695000
     con  0;         << no io process >>                                06700000
     pcal cpinit;    << initialization >>                               06705000
     con  1;         << one interrupt handler >>                        06710000
     pcal gip'hpib); << interrupt handler >>                            06715000
   end.                                                                 06720000
