$CONTROL USLINIT,MAP,CODE                                               00010000
<<  hiocdrd0, module 28 - hp2893a card reader driver series 33     >>   00015000
<<  hp32033c mpe source c.00.00 >>                                      00020000
<<  copyright     (c) copyright hewlett-packard co. 1981.,         >>   00025000
<<    this program may be used with one computer system at a,      >>   00030000
<<    time and shall not otherwise be recorded, transmitted or,    >>   00035000
<<    stored in a retrieval system.  copying or other reproduction,>>   00040000
<<    of this program except for archival purposes is prohibited,  >>   00045000
<<    without the prior written consent of hewlett-packard company.>>   00050000
<<****note - dollar copyright cannot be used with this module ***  >>   00055000
$title "CARD READER DRIVER  -  HIOCDRD0(28)"                            00060000
$control privileged,uncallable,main=hiocdrd0                            00065000
$tp                                                                     00070000
                                                                        00075000
comment                                                                 00080000
                                                                        00085000
            3000 series 33 card reader driver   - hiocdrd0              00090000
            ---------------------------------------------               00095000
                                                                        00100000
                                                                        00105000
structure of hiocdrd0:                                                  00110000
                                                                        00115000
hiocdrd0, together with the sio device monitor (siodm) constitute a     00120000
standard mpe type 1 i/o driver/monitor.  this means that it does not    00125000
run in its own process, but executes on any stack and therefore must    00130000
run to completion.  during initialization it executes on progen's       00135000
stack, during request initiation it executes on the caller's stack      00140000
or the ics, and during interrupt processing it always executes          00145000
on the ics (interrupt control stack).                                   00150000
                                                                        00155000
HIOCDRD0 consists of a global area, two procedures, and an "outer       00160000
block" which is really a linkage area for INITIAL.  The global area     00165000
contains an array called initial which is comprised of three parts.     00170000
the first part specifies the size of the other two, the unit extract    00175000
instruction, and various parameters which are used by initial.  this    00180000
section is deleted after initial is through with it.  the other two     00185000
parts are the device information table (dit) and the channel program    00190000
area, which is part of the interrupt linkage table (ilt).  initial      00195000
will put each of these items in the area of memory where it belongs.    00200000
the linkage area specifies the procedure labels (p-labels) of the       00205000
associated monitor (siodm), the request initiator (crdrvr), the         00210000
request completor (crdrvr), the initialization procedure (crinit,       00215000
called by progen at system startup), and the interrupt handler (gip).   00220000
                                                                        00225000
$page                                                                   00230000
operation of hiocdrd0:                                                  00235000
                                                                        00240000
the primary working code of hiocdrd0 is a procedure crdrvr.  crdrvr is  00245000
called with five parameters.  two of these parameters, bank and         00250000
buffaddr, are the absolute buffer address of the data to be processed.  00255000
the other three, ditp, ioqp, and siop are pointers to three arrays.     00260000
ditp is a pointer to the device information table which contains        00265000
information about its associated card reader unit.  there is one dit for00270000
unit on the controller (for the card reader there is only one unit      00275000
per controller.) and they contain information which must be             00280000
saved between i/o requests to the driver.  ioqp is a pointer to the     00285000
input/output queue element.  ioq elements contain information relevent  00290000
to the current request.  siop is a pointer to the first element of the  00295000
channel program which is actually part of the interrupt linkage table.  00300000
these three elements are described in more detail elsewhere in this     00305000
document.                                                               00310000
                                                                        00315000
crdrvr is always called by the sio device monitor (siodm).  the driver  00320000
then determines the reason for the call by examining the mstate, which  00325000
contains the state of the monitor, the ioq and the dit.                 00330000
when a new request is initiated, crdrvr examines the function code      00335000
and parameter fields contained in the ioq element to determine the      00340000
task that is desired.  the proper command codes and program branches    00345000
are then placed in the channel program and its execution is begun.      00350000
                                                                        00355000
upon completion of the channel program, an interrupt is                 00360000
generated and crdrvr is again called.  the code checks for              00365000
a request in progress (an ioqp that is nonzero) and if this             00370000
is the case, branches to the completion section of the                  00375000
driver.  here several status words are examined for errors or special   00380000
conditions which might have occurred during the execution of the        00385000
channel program, during the data transfer, or during the operation of   00390000
the card reader unit.  these condition can cause special status         00395000
returns to be returned to the caller.  a list of the conditions         00400000
and the return codes is provided in this document.                      00405000
if the driver is called with an ioqp of zero then it will start         00410000
an idle channel program.                                                00415000
                                                                        00420000
the initialization procedure crinit starts an idle channel              00425000
program which consists of a wait, a dsj (to clear the power             00430000
up interrupt from the device) and an interrupt halt.                    00435000
                                                                        00440000
                                                                        00445000
                                                                        00450000
                                                                        00455000
        development and fix history                                     00460000
        ---------------------------                                     00465000
                                                                        00470000
development engineer: dave cassafer                                     00475000
8-4-82 dave cassafer - fixed problem where bank portion of     <<04623>>00480000
       auxbufaddrd was being set to -1.  solution is to convert<<04623>>00485000
       an expression to logical before converting it to double.<<04623>>00490000
4-11-82 david sm chang -mpev initial                           <<06720>>00495000
$page                                                                   00500000
                device information table (dit)                          00505000
                ------------------------------                          00510000
                                                                        00515000
                                                                        00520000
there is one dit per physical device.  if a physical device represents  00525000
more than one logical device, the logical device number is obtained     00530000
from the ioq element.  the following diagram shows the dit used for     00535000
the card reader driver.                                                 00540000
                                                                        00545000
     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15   mnemonic          00550000
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+                    00555000
  0| 0| 0|ac|rq| 0|mu| 0|io|ia|no|st| 0|   state   |   dflag            00560000
   +--+--+--+--+--+--+--+--+--+--+--+--+-----------+                    00565000
  1| sysdb relative pointer to the dit for the next|   dlink            00570000
   | device requesting this resource or service    |                    00575000
   +-----------------------------------------------+                    00580000
  2| sysdb relative pointer to the first ioq in    |   dioqp            00585000
   | request list for this device                  |                    00590000
   +--------+--------------+-----------------------+                    00595000
  3|           logical device number               |   dldev   <<06720>>00600000
   +--------+--------------+-----------------------+                    00605000
  4| sysdb relative pointer to device linkage table|   ddltp            00610000
   +-----------------------------------------------+                    00615000
  5| sysdb relative pntr to interrupt linkage table|   diltp            00620000
   +-----------------------------------------------+                    00625000
  6|rd|af|                                         |   dsave            00630000
   +-----------------------------------------------+                    00635000
  7| hardware error status.  set when the driver   |   dserr            00640000
   | detects an error.  whenever <>0, the driver   |                    00645000
   | monitor logs an i/o error and clears this word|                    00650000
   +--+--+--+--+--+--------------------------------+                    00655000
%10| not used                                      |   dtime            00660000
   +--+--+--+--+--+--------------------------------+                    00665000
%11|           request word count                  |   dwcnt            00670000
   +-----------------------------------------------+                    00675000
%12| iot |     physical unit number                |   dunit   <<06720>>00680000
   +--+--+-----------------------------------------+           <<06720>>00685000
%13| device status.  read from device during       |   dstat   <<06720>>00690000
   | each execution of the channel program.        |                    00695000
   +-----------------------------------------------+                    00700000
%14| logging will be done from here.               |  dlogerror<<06720>>00705000
   +-----------------------------------------------+                    00710000
                                                                        00715000
$page                                                                   00720000
dflag - flags and request state                                         00725000
  ac  active  - a monitor is currently servicing this device.           00730000
  rq  request - a service request is pending while the monitor is       00735000
                active.                                                 00740000
  mu  munit   - this device is on a multi-unit controller.              00745000
  io  ioprog  - an i/o channel program is running for this device.      00750000
  ia  iak     - an interrupt or response has occurred for this device.  00755000
  no  notrdy  - go to state %10 after idle channel program is started.  00760000
  st  stwait  - the device monitor is starting an idle channel program  00765000
                for this device.  there is no ioq associated with this  00770000
                type of request.                                        00775000
  state       - state of the device monitor.  specifies the next action 00780000
                to be taken in siodm in servicing the request:          00785000
                  0 - start new request                                 00790000
                  1 - not used                                          00795000
                  2 - call driver initiator procedure                   00800000
                  3 - call driver completor procedure                   00805000
                  4 - not used                                          00810000
                  5 - process request completed                         00815000
                  6 - initiate device recognition sequence              00820000
                  7 - start operator intervention wait                  00825000
                %10 - wait for interrupt (operator intervention)        00830000
                      restart at state 0                                00835000
                %11 - wait for data segment freeze, then state 2        00840000
                %12 - wait for driver initiator to be frozen, then      00845000
                      allocate controller (state 2)                     00850000
                %13 - wait for i/o completion interrupt, then state 3   00855000
                %14 - wait for controller, then call driver initiator   00860000
                %15 - not used                                          00865000
                %16 - wait for initiator make present, then state 2     00870000
                %17 - wait for completor make present, then state 3     00875000
                                                                        00880000
dldev - device logical device number                                    00885000
  iot  i/o type  -  i/o system type                                     00890000
                    0 = series ii / iii  i/o system                     00895000
                    1 = hp-ib                                           00900000
                    2 = unused                                          00905000
                    3 = unused                                          00910000
                                                                        00915000
dsave - device processing flags                                         00920000
  rd  readdone    - a card has already been read.                       00925000
  af  abortflag   - a device clear has already been sent for            00930000
                    this series of aborted ioqs                         00935000
                                                                        00940000
$page                                                                   00945000
                interrupt linkage table (ilt)                           00950000
                -----------------------------                           00955000
                                                                        00960000
                                                                        00965000
there is one ilt for each device controller configured on the system.   00970000
the card reader controller will support only one unit per controller.   00975000
                                                                        00980000
     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15   mnemonic          00985000
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+                    00990000
  0|         channel                               |   icpva0           00995000
  1|              program                          |   icpva1           01000000
  2|                  variable                     |   icpva2           01005000
  3|                       area (icpva)            |   icpva3           01010000
   +-----------------------------------------------+                    01015000
  4|         dma abort                             |   icpva4           01020000
  5|              address                          |   icpva5           01025000
   +-----------------------------------------------+                    01030000
  6|                      0                        |   isrql            01035000
   +--+-----------------+-----+-----------+--------+                    01040000
  7|li|     chanque     |     |   chan    |  dev   |   icntrl           01045000
   +--+-----------------+-----+-----------+--------+                    01050000
%10| sysdb relative pointer to channel program area|   isiop            01055000
   +-----------------------------------------------+                    01060000
%11| sysdb relative pointer to status return area. |   istap            01065000
   +-----------------------------------------------+                    01070000
%12| single instruction that is executed to extract|   iunit            01075000
   | the device unit number from the status pointed|                    01080000
   | to by istap.                                  |                    01085000
   +-----------------------------------------------+                    01090000
%13| sysdb relative dit pointer of the device      |   icdp             01095000
   | currently using the channel to perform a      |                    01100000
   | data operation.                               |                    01105000
   +-----------------------+-----------------------+                    01110000
%14|       siopsize        |        cquen          |   iqueue           01115000
   +--+--+--+--------------+-----------+-----------+                    01120000
%15|rw|wp|ig|                          |  hcunit   |   iflag            01125000
   +--+--+--+--------------------------+-----------+                    01130000
%16| sysdb relative dit pointer for unit 0         |   iditp0           01135000
   +-----------------------------------------------+                    01140000
%20|             card reader                       |                    01145000
   .               channel                         .                    01150000
   |                 program                       |                    01155000
   +-----------------------------------------------+                    01160000
                                                                        01165000
$page                                                                   01170000
icpva0 - channel program variable area                                  01175000
                                                                        01180000
  the first word is used by the channel program processor to store      01185000
  status information after i/o channel aborts.  the next word is used   01190000
  by the driver to indicate if status should be examined for special    01195000
  conditions or errors.  the other two words are not used.              01200000
                                                                        01205000
                                                                        01210000
icpva4 - dma abort address                                              01215000
                                                                        01220000
  if a dma abort occurs, the absolute address where the abort occurred  01225000
  is stored in this area.                                               01230000
                                                                        01235000
                                                                        01240000
icntrl - contains controller information                                01245000
                                                                        01250000
  lim     - if this bit is set, the controller is sharing a software    01255000
            channel resource in order to limit bandwidth.               01260000
  chanque - the software channel resource number.                       01265000
  chan    - channel number (four most significant bits of drtn).        01270000
  dev     - device number (three least significant bits of drtn).       01275000
                                                                        01280000
                                                                        01285000
iqueue -                                                                01290000
                                                                        01295000
  siopsize - (number of words + 1)/2 in the channel program area.       01300000
  cquen    - for a multi-unit controller this field contains the        01305000
             software controller resource number.                       01310000
                                                                        01315000
                                                                        01320000
iflag - controller and channel program state flags                      01325000
                                                                        01330000
  runwait  - an idle channel program should be started when there       01335000
             are no active requests to process.                         01340000
  waitprog - an idle channel program has been started for this          01345000
             controller.  this bit is reset by an interrupt.            01350000
  ignorehi - an hiop instruction has been issued against this	          01355000
             controller but the channel program was not in a wait       01360000
             statement.  therefore ignore the interrupt generated by    01365000
             the channel code when this program halts.                  01370000
  hcunit   - highest configured unit number for this controller.        01375000
$page                                                                   01380000
            i/o queue element (ioq)                                     01385000
            -----------------------                                     01390000
                                                                        01395000
                                                                        01400000
     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15   mnemonic          01405000
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+                    01410000
  0|      request dependent flags (see below)      |   qflag            01415000
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+                    01420000
  1| sysdb relative pointer to next ioq element.   |   qlink            01425000
   | points to first word of element.              |                    01430000
   +-----------------------+-----------------------+                    01435000
  2|                       | logical device number |   qldev            01440000
   +--+--+--+--+--+-----+--+-----+--------+--------+                    01445000
  3|       auxillary buffer flag.                  |   qmisc            01450000
   +--+--+--+--+--+-----+--------+--------+--------+                    01455000
  4| s| if qflag.(3:1) is clear then this is the   |   qdstn            01460000
   |  | dst number of the target data segment.  if |                    01465000
   |  | s is set, qaddr is db relative.            |                    01470000
   +--+--------------------------------------------+                    01475000
  5| offset in the data segment or system buffer   |   qaddr            01480000
   | table to the target data buffer.              |                    01485000
   +-----------------------+-----------------------+                    01490000
  6|                       | function code for     |   qfunc            01495000
   |                       | this request.  (see   |                    01500000
   |                       | next section.)        |                    01505000
   +-----------------------+-----------------------+                    01510000
  7| on initiation, specifies the word count (>0)  |   qwbct            01515000
   | or byte count (<0).  at completion of the     |                    01520000
   | request this location contains the actual     |                    01525000
   | transmission count in the same units (bytes   |                    01530000
   | or words) as in the request.                  |                    01535000
   +-----------------------------------------------+                    01540000
%10| parameter 1.  contains the eof specification  |   qpar1            01545000
   +-----------------------------------------------+                    01550000
%11| parameter 2.  contains the data mode          |   qpar2            01555000
   | specification in bits (11:2). (see below card |                    01560000
   | reader request codes for detail information)  |                    01565000
   +-----------------------+--------------+--------+                    01570000
%12|         pcbn          |  qualifier   | status |   qstat            01575000
   +-----------------------+--------------+--------+                    01580000
                                                                        01585000
$page                                                                   01590000
qflag - request dependent flags                                         01595000
                                                                        01600000
  bit 0  abort     - abort this request and return an error indication  01605000
                     to the caller.                                     01610000
  bit 1  special   - apply special handling to this request.  (not used)01615000
  bit 2  diag      - this is a request from the diagnostic subsystem.   01620000
  bit 3  sysbuff   - target is an index relative to the sbuf table of   01625000
                     the data buffer.                                   01630000
  bit 4  iowake    - wake caller on completion of request.              01635000
  bit 5  blocked   - blocked i/o.  the caller is waited in attachio     01640000
                     until the request is completed.  implies iowake.   01645000
  bit 6  completed - the request has been completed and the caller      01650000
                     awakened if he had requested (with iowake).        01655000
  bit 7  datafrzn  - set by the memory management routines (mam) when a 01660000
                     makepresent request is successfully completed and  01665000
                     indicates the data segment is frozen in memory.    01670000
  bit 8  mamerrord - an error has occurred while mam was trying to      01675000
                     make the target data segment present and freeze    01680000
                     it in memory.                                      01685000
  bit 9  preq      - (not used)                                         01690000
  bit 10 sfail     - delayed failure of sio instruction.  if a call to  01695000
                     startio resulted in the request being added to     01700000
                     the channel queue, this bit indicates that the sio 01705000
                     instruction failed when the request was selected   01710000
                     for execution.                                     01715000
  bit 11 pfail     - the request was aborted because of a system power  01720000
                     failure.                                           01725000
                                                                        01730000
                                                                        01735000
qmisc - auxillary buffer flag  used to indicated a read into the        01740000
        driver's buffer and not the user's buffer.                      01745000
                                                                        01750000
                                                                        01755000
qstat - pcb number and request completion status.                       01760000
                                                                        01765000
  pcbn    - the process control block (pcb) number of the process       01770000
            which made this request.  if zero, the request is not       01775000
            associated with any process and the ioq element is to       01780000
            be returned by the system when the request has completed.   01785000
  status  - general status indicating the final state of the request.   01790000
            the following codes are used:                               01795000
              0 - not started or awaiting completion.                   01800000
              1 - successful completion.                                01805000
              2 - end-of-file detected.                                 01810000
              3 - unusual, but recoverable, condition detected.         01815000
              4 - irrecoverable error has occurred.                     01820000
  qualifier - a code which further defines or qualifies the general     01825000
              status.  (see the section driver return status codes.)    01830000
                                                                        01835000
$page                                                                   01840000
           card reader request codes                                    01845000
           ----------------------                                       01850000
                                                                        01855000
                                                                        01860000
   0 - read                                                             01865000
         p1       - end of file specification                           01870000
         p2(11:2) - data mode                                           01875000
                    0 =  packed ascii. count truncated to 80 bytes      01880000
                         maximum                                        01885000
                    1 =  column binary. count truncated to 160 bytes    01890000
                         maximum                                        01895000
                    2 =  unassigned                                     01900000
                    3 =  unassigned                                     01905000
         ***note: odd byte counts are rounded up as they were           01910000
                  in the series iii driver.                             01915000
   1 - unused   (invalid opcode for this device)                        01920000
   2 - open file (no operation)                                         01925000
   3 - close file (no operation)                                        01930000
   4 - close device (clear eof status in lpdt)                          01935000
   5 - 14   - unused  (invalid opcode for this device)                  01940000
 %17 - read status                                                      01945000
%110 - get identity                                                     01950000
%111 - initiate self test                                               01955000
%113 - write loopback data                                              01960000
%114 - read loopback data                                               01965000
%275 - device clear                                                     01970000
                                                                        01975000
                       driver return status codes                       01980000
                       --------------------------                       01985000
                                                                        01990000
                                                                        01995000
 general status (13:3)       qualifying status (8:5)      overall (8:8) 02000000
  0 - pending               1 - waiting for completion         %10      02005000
                            3 - not ready wait                 %30      02010000
                                                                        02015000
  1 - successful            0 - no errors                        1      02020000
                                                                        02025000
  2 - end of file           [not used]                                  02030000
                                                                        02035000
  3 - unusual condition     3 - request aborted                %33      02040000
                            6 - powerfail abort                %63      02045000
                          %21 - device powered up             %213      02050000
                                                                        02055000
  4 - irrecoverable error   0 - invalid request                  4      02060000
                            3 - timing error                   %34      02065000
                            4 - sio failure                    %44      02070000
                            5 - unit failure                   %54      02075000
                          %12 - system error                  %124      02080000
                          %14 - channel failure               %144      02085000
                                                                        02090000
                                                                        02095000
endcomment;                                                             02100000
$page                                                                   02105000
begin                                                                   02110000
$include inclioq                                               <<06720>>02115000
$include incllpdt                                              <<06720>>02120000
equate                                                                  02125000
                                                                        02130000
               << function codes >>                                     02135000
                                                                        02140000
    dclear          = %275,       <<device clear>>                      02145000
    dclose          = 4,          <<device close function code>>        02150000
    fclose          = 3,          <<file close function code>>          02155000
    fopen           = 2,          <<fopen function code>>               02160000
    identity        = %110,       <<"GET IDENTITY" function code>>      02165000
    inittest        = %111,       <<initiate self test function>>       02170000
    read            = 0,                                                02175000
    readstat        = %17,        <<return status function code>>       02180000
    readloop        = %114,       <<read loopback data function>>       02185000
    writeloop       = %113,       <<write loopback data function>>      02190000
                                                                        02195000
               << card reader channel program commands >>               02200000
                                                                        02205000
    clear           = %4400,                                            02210000
    init'selftest   = %4017,                                            02215000
    jump            = 0,                                                02220000
    pickascii       = %2001,                                            02225000
    pickbinary      = %2000,                                            02230000
    readcommand     = %1400,                                            02235000
    read'selftest   = %3417,      <<read selftest results>>             02240000
    readstatcommand = %1401,                                            02245000
    wait            = %1000,                                            02250000
                                                                        02255000
               << qstat status returns >>                               02260000
                                                                        02265000
    aborted         = %33,        <<request aborted return status>>     02270000
    chanfail        = %144,       <<channel failure>>                   02275000
    goodio          = 1,          <<successful i/o status return>>      02280000
    invalidop       = 4,          <<invalid operation requested>>       02285000
    offlinestat     = %30,        <<device is not ready or offline>>    02290000
    pending         = %10,        <<pending/waiting for completion>>    02295000
    pfabort         = %63,        <<powerfail abort>>                   02300000
    powerupstat     = %213,       <<device has been powered up>>        02305000
    siofail         = %44,        <<start sio failure>>                 02310000
    syserror        = %124,       <<system error request status code>>  02315000
    timing'error    =  %34,       <<error returned after read check>>   02320000
    xfer'error      =  %14,       <<error returned after bus error>>    02325000
$page                                                                   02330000
               << channel program array pointers >>                     02335000
                                                                        02340000
    devclear        = 28,         <<clear command>>                     02345000
    readbank        = 16,         <<bank where data is to go>>          02350000
    readaddr        = 17,         <<address where data is to go>>       02355000
    dsjgood         = 11,         <<address where control tranfers      02360000
                                  if previous operation successfull>>   02365000
    identify        = 32,         <<addr of identify instr>>            02370000
    identstore      = 33,         <<channel stores identity here>>      02375000
    jmpaddr         = 1,          <<address in channel program of       02380000
                                    function to be done>>               02385000
    jump'or'wait    = 18,         <<jump or wait goes here>>            02390000
    jmpaddr2        = 19,         <<jmp addr if jump'or'wait=jump>>     02395000
    pickcount       = 43,         <<8/bytes,8/burst>>                   02400000
    readorder       = 13,         <<read order in sio program>>         02405000
    readburst       = 15,         <<burst length in read command>>      02410000
    readbytes       = 14,         <<number of bytes to read>>           02415000
    rorder2         = 20,                                               02420000
    rbytes2         = 21,         <<number of bytes in 2nd read>>       02425000
    rburst2         = 22,                                               02430000
    rbank2          = 23,                                               02435000
    raddr2          = 24,                                               02440000
    readstatbyte    = 26,         <<number of status bytes to read>>    02445000
    readstatdest    = 29,         <<addr of where status to go>>        02450000
    startidle       = 36,         <<start of idle channel prog>>        02455000
    tempstore       = 44, <<type of selftest or byte of loopback data>> 02460000
    writeaddr       = 6,          <<address in write command>>          02465000
    writebank       = 5,          <<bank in write command>>             02470000
    writeburst      = 4,          <<burst length in write command>>     02475000
    writebytes      = 3,          <<number of bytes to write>>          02480000
    writeorder      = 2,          <<command to be done>>                02485000
                                                                        02490000
               << program constants >>                                  02495000
                                                                        02500000
    call'completor  = %13,                                              02505000
    chanprogsize    = 46,         <<does not include aux read buffer>>  02510000
    crditsize       = 13,         <<card reader dit size>>     <<06720>>02515000
    crsiosize       = chanprogsize+40,<<includes auxillary read buffer>>02520000
    crsiosized2     = (crsiosize+1)/2,                                  02525000
                        <<adding 1 to crsiosize before dividing         02530000
                          by 2 insures that sufficient space            02535000
                          will be allocated for a channel               02540000
                          program of odd length>>                       02545000
    opconsole       = 0,          <<output message to operator>>        02550000
    hoppermtmsg     = 384,        <<hopper empty message>>              02555000
    logtrouble      = %100000,    <<trouble worth logging>>             02560000
    motpicmsg       = 385,        <<motion or pick check>>              02565000
    notrdymsg       = 11,         <<not ready message # to mess proc>>  02570000
    notready        = 7,          <<not ready driver return code>>      02575000
    rdchkmsg        = 17,         <<read check message>>                02580000
    requestdone     = 5,          <<request completed driver return>>   02585000
    start'request   = 2,          <<siodm state for new request>>       02590000
    stkfullmsg      = 383,        <<stacker full message>>              02595000
    sub             = %32,        <<ascii sub-indicates bad hollerith>> 02600000
    sysdb           = %1000,                                            02605000
    syslpdt         = %10,        <<logical physical device table>>     02610000
    troublebits     = %177000,    <<mask for hardware status>>          02615000
    ufailmsg        = 208,        <<unit failure msg. no.>>             02620000
               << table array pointers >>                               02625000
    ddltp           = 4,          <<dit driver linkage table>> <<06720>>02630000
    dflag           = 0,          <<dit flag word>>            <<06720>>02635000
    diltp           = 5,          <<interrupt linkage table ptr>>       02640000
    dioqp           = 2,          <<dit ioq pointer>>          <<06720>>02645000
    dldev           = 3,          <<logical device numbers>>   <<06720>>02650000
    dlink           = 1,          <<dit next dit req service>> <<06720>>02655000
    dlogerror       = %14,        <<log be done from here>>    <<06720>>02660000
    dsave           = 6,          <<driver temp storage>>               02665000
    dstat           = %13,        <<device status read>>       <<06720>>02670000
    dserr           = 7,          <<hardware i/o error status in dit>>  02675000
    dtime           = %10,        <<timer request>>                     02680000
    dunit           = %12,        <<dit unit # >>              <<06720>>02685000
    dwcnt           = 9,          <<holds requested word count>>        02690000
    icntrl          = %7,         <<drt number>>               <<06720>>02695000
    isiop           = %10;        <<ilt pointer to siop>>      <<06720>>02700000
<<  ioq specify by incl5   >>                                  <<06720>>02705000
                                                               <<06720>>02710000
                                                               <<06720>>02715000
                                                               <<06720>>02720000
                                                               <<06720>>02725000
                                                               <<06720>>02730000
                                                               <<06720>>02735000
$page                                                                   02740000
define                                                                  02745000
                                                                        02750000
             <<dstat bit definitions>>                                  02755000
                                                                        02760000
    badhollerith = (3:1)#,     <<invaild hollerith status>>             02765000
    buserror     = (0:1)#,     <<buss error>>                           02770000
    rdchk        = (2:1)#,     <<read check>>                           02775000
    eofbit       = (10:1)#,    <<end of file status bit>>               02780000
    hoppermt     = (5:1)#,     <<hopper empty>>                         02785000
    mpchk        = (7:1)#,     <<motion or pick check>>                 02790000
    nrdy         = (1:1)#,     <<not ready or offline>>                 02795000
    offline      = (6:1)#,                                              02800000
    powerup      = (11:1)#,                                             02805000
    stackerfull  = (4:1)#,     <<stacker full>>                         02810000
                                                                        02815000
               << dsave bit definitions >>                              02820000
                                                                        02825000
    readdone     = (0:1)#,     <<aux buf for card after eof returned>>  02830000
    abortflag    = (1:1)#,     <<device clear already sent>>            02835000
                                                                        02840000
               << miscellaneous bit definitions >>                      02845000
                                                                        02850000
    ascii        = not logical(datamode)#, <<ascii read mode requested>>02855000
    binary       = logical(datamode)#,  <<binary read mode requested>>  02860000
    diag         = (2:1)#,     <<this bit signifies diagnostic>>        02865000
    drtnumber     = (7:9)#,       << drt define >>             <<06720>>02870000
    dldevn       = (8:8)#,     <<logical device number of dit>>         02875000
    eof          = (7:3)#,     <<eof state in lpdt>>                    02880000
    errorcode    = (0:3)#,     <<cpvap, error code>>                    02885000
    func         = (8:8)#,     <<qfunc, function code>>                 02890000
    iostat       = (8:8)#,     <<total request status returned>>        02895000
    pfail        = (11:1)#,    <<abort set because of power fail>>      02900000
    sfail        = (10:1)#,    <<failure on delayed start sio>>         02905000
    status       = ditpl(dstat)#,  <<status word in dit>>               02910000
    subtype      = (12:4)#;       <<type of selftest>>                  02915000
$page                                                                   02920000
logical ls0 = s-0,                                                      02925000
        lx  = x;                                                        02930000
                                                                        02935000
integer s0 = s-0,                                                       02940000
        s1 = s-1,                                                       02945000
        x  = x;                                                         02950000
                                                                        02955000
                                                               <<06720>>02960000
                                                                        02965000
                                                                        02970000
                                                                        02975000
                                                                        02980000
     << dit definition and driver linkage area  >>                      02985000
                                                                        02990000
array  initial(0:3) = db :=                                             02995000
   [8/crditsize, 8/%21],   <<ditsize/run idle chanp,monitor type>>      03000000
   0,                      <<not used>>                                 03005000
   0,                      <<unit extract instruction>>                 03010000
   [8/crsiosize, 8/1];     <<chanprogsize/2, status length >>  <<06720>>03015000
                                                                        03020000
array dit(1:crditsize) = db :=                                          03025000
  0,    <<dflag>>                                                       03030000
  0,    <<dlink>>                                                       03035000
  0,    <<dioqp>>                                                       03040000
  0,    <<dldev - hpib device>>                                <<06720>>03045000
  0,    <<ddltp>>                                                       03050000
  0,    <<diltp>>                                                       03055000
  0,    <<drqst>>                                                       03060000
  0,    <<dserr>>                                                       03065000
  0,    <<dsave>>                                                       03070000
  0,    <<dwcnt>>                                                       03075000
%40000, <<dunit>>                                              <<06720>>03080000
  0,    <<dstat>>                                                       03085000
  0;    <<dlogerror>>                                                   03090000
$page                                                                   03095000
array sioa(1:crsiosize) = db :=                                         03100000
<< channel program>>                                                    03105000
<< 0>>                    0, <<jump to appropriate starting point>>     03110000
<< 1>><<jmpaddr>>         0, <<fill in address>>                        03115000
                                                                        03120000
<< 2>><<writeorder>>      0, <<fill in command>>                        03125000
<< 3>><<writebytes>>      0, <<byte count>>                             03130000
<< 4>>                    0, <<burst length>>                           03135000
<< 5>><<writebank>>       0, <<bank>>                                   03140000
<< 6>><<writeaddr>>       0, <<address>>                                03145000
                                                                        03150000
<< 7>>                %1000, <<wait>>                                   03155000
<< 8>>                    0,                                            03160000
                                                                        03165000
<< 9>>                %2401, <<dsj>>                                    03170000
<<10>>                    0, <<dsj byte>>                               03175000
<<11>><<dsjgood   >>      0, <<fill in address>>                        03180000
<<12>>                   12, <<goto read status>>                       03185000
                                                                        03190000
<<this is the read command>>                                            03195000
                                                                        03200000
<<13>><<readorder>>       0, <<fill in command>>                        03205000
<<14>><<readbytes>>       0, <<byte count>>                             03210000
<<15>>                    0, <<burst length>>                           03215000
<<16>><<readbank>>        0, <<bank >>                                  03220000
<<17>><<readaddr>>        0, <<address>>                                03225000
                                                                        03230000
<<18>><<jump'or'wait>> %1000,<<jump or wait>>                           03235000
<<19>>                    0,                                            03240000
                                                                        03245000
<<this is the second read if binary card>>                              03250000
  <<or readstatus direct to users buffer>>                              03255000
                                                                        03260000
<<20>><<rorder2>>     %1400,                                            03265000
<<21>><<rbytes2>>         0,                                            03270000
<<22>>                    0, <<burst length>>                           03275000
<<23>><<rbank2>>          0, <<bank>>                                   03280000
<<24>><<raddr2 >>         0,                                            03285000
                                                                        03290000
<<this is a status read for the driver, or the clear command>>          03295000
                                                                        03300000
<<25>><<readstatus>>  %1401,                                            03305000
<<26>>                    2, <<byte count>>                             03310000
<<27>>                    0, <<burst>>                                  03315000
<<28>><<devclear>>    %2000,<<bank 0,bit 5 means dont update >>         03320000
<<29>><<readstatdest>>    0, <<address>>          <<the count>>         03325000
                                                                        03330000
                                                                        03335000
<<30>>                 %601, <<interrupt/halt>>                         03340000
<<31>>                    1, <<code of 1 in cpva(1)>>                   03345000
                                                                        03350000
<<32>><<identify>>    %3000, <<get identity>>                           03355000
<<33>><<identstore>>      0, <<identity will be put here>>              03360000
                                                                        03365000
<<34>>                    0, <<jump to read status>>                    03370000
<<35>>                  -11,                                            03375000
$page                                                                   03380000
<<36>><<startidle>>   %1000, <<wait>>                                   03385000
<<37>>                    0,                                            03390000
                                                                        03395000
<<38>>                %2400, <<dsj to clear powerup interrupt>>         03400000
<<39>>                    0,                                            03405000
<<40>>                    0, <<vector addr for dsj= 0>>                 03410000
                             <<fall thru if dsj=1 or 2>>                03415000
<<41>>                 %601, <<interrupt/halt>>                         03420000
<<42>>                    2, <<code of 2 in cpva(1)>>                   03425000
                                                                        03430000
<<43>><<pickcount>>       0, <<8/bytes,8/burst>>                        03435000
<<44>><<tempstore>>       0; <<subtest for self test or loopback data>> 03440000
                                                                        03445000
                                                                        03450000
<<*** 40 words for auxillary buffer ***>>                               03455000
$page                                                                   03460000
    <<------------ external procedure declarations -------------->>     03465000
                                                                        03470000
procedure debug;                                                        03475000
   option external;                                                     03480000
                                                                        03485000
                                                                        03490000
procedure eofcheck (ioq'entry'index,bufr,count,blank);         <<06720>>03495000
   value ioq'entry'index,bufr,count,blank;                     <<06720>>03500000
   integer ioq'entry'index;                                    <<06720>>03505000
   integer count;                                                       03510000
   logical blank;                                                       03515000
   double  bufr;                                                        03520000
   option external;                                                     03525000
                                                                        03530000
procedure  gip;                                                         03535000
   option external;                                                     03540000
                                                                        03545000
procedure help;                                                         03550000
   option external;                                                     03555000
                                                                        03560000
logical procedure iomessage (setno,msgno,mask,p1,p2,p3,p4,p5,           03565000
                               dest,reply,offset,ditp,iotype);          03570000
   value setno,msgno,mask,p1,p2,p3,p4,p5,dest,reply,offset,ditp,        03575000
         iotype;                                                        03580000
   integer setno,msgno,mask,p1,p2,p3,p4,p5,dest,reply,offset,           03585000
           iotype;                                                      03590000
   integer pointer ditp;                                                03595000
   option variable,external;                                            03600000
                                                                        03605000
procedure masterclear (ditp);                                           03610000
   array ditp;                                                          03615000
   option external;                                                     03620000
                                                                        03625000
procedure siodm (ditp,flags);                                           03630000
   value ditp, flags;                                                   03635000
   logical flags;                                                       03640000
   pointer ditp;                                                        03645000
   option external;                                                     03650000
                                                                        03655000
procedure startio (ditp,siop,qflag);                                    03660000
   value  ditp, siop, qflag;                                            03665000
   logical qflag;                                                       03670000
   pointer ditp, siop;                                                  03675000
   option external;                                                     03680000
                                                                        03685000
procedure putdrt(drt,offset,num);                              <<06720>>03690000
   value drt,offset,num;                                       <<06720>>03695000
   integer drt,offset,num;                                     <<06720>>03700000
   option external;                                            <<06720>>03705000
$page  "CARD READER INITIALIZATION PROCEDURE - CRINIT"                  03710000
<<******************************************************                03715000
  **    card reader initialization procedure          **                03720000
  ******************************************************>>              03725000
                                                                        03730000
<<this procedure starts an idle channel program when called>>           03735000
                                                                        03740000
procedure crinit(ditp);                                                 03745000
  integer array ditp;                                                   03750000
  option privileged, uncallable;                                        03755000
                                                                        03760000
  begin                                                                 03765000
    integer pointer iltp;                                               03770000
    integer pointer siop;                                               03775000
                                                                        03780000
    @iltp:=ditp(diltp);                                                 03785000
    @siop:=iltp(isiop);                                                 03790000
                                                                        03795000
    siop(jmpaddr):=startidle-2;                                         03800000
    startio(ditp,siop,false);                                           03805000
                                                                        03810000
  putdrt(iltp(icntrl).drtnumber,3,0);                          <<06720>>03815000
  end;                                                                  03820000
$page  "CARD READER DRIVER PROCEDURE - CRDRVR"                          03825000
integer procedure crdrvr                                       <<06720>>03830000
       (ioq'entry'index,ditp,bank,bufaddr,siop,drtnumb);       <<06720>>03835000
   value ioq'entry'index,bank,bufaddr,drtnumb;                 <<06720>>03840000
   integer ioq'entry'index;                                    <<06720>>03845000
   integer  bank, bufaddr, drtnumb;                                     03850000
   integer array ditp,siop;                                    <<06720>>03855000
   option privileged, uncallable;                                       03860000
begin                                                                   03865000
                                                                        03870000
  <<                                                                    03875000
     this procedure initiates and completes i/o for card readers        03880000
                                                                        03885000
    mode returns in crdrvr -                                            03890000
                                                                        03895000
        5  - request completed                                          03900000
        7  - not ready wait                                             03905000
      %13  - interrupt wait or wait for completion                      03910000
  >>                                                                    03915000
                                                                        03920000
                                                                        03925000
integer ldev           ;           <<logical device number>>   <<06720>>03930000
integer datamode;          <<holds data read mode>>            <<06720>>03935000
double  auxbufaddrd;       <<card saving buffer address>>      <<06720>>03940000
integer wcnt;              <<word count for convert>>          <<06720>>03945000
integer msgtype;           <<type of error message>>           <<06720>>03950000
integer pointer cpvap;     <<holds channel i/o status>>        <<06720>>03955000
integer badcolumn;         <<column where bad hollerith found>><<06720>>03960000
integer subtest;           <<this will be set to test type>>   <<06720>>03965000
integer mstate    = crdrvr;        <<current request state>>            03970000
integer lpdt'index;   <<logical physical device table index>>  <<06720>>03975000
logical array   ditpl(*)  =  ditp;                             <<06720>>03980000
                                                               <<06720>>03985000
                                                                        03990000
double bufaddrd  =  q-7;              <<bank and offset>>               03995000
                                                                        04000000
array maxcount(0:1) = pb := 40,80;    <<max transfer allowed>>          04005000
$page                                                                   04010000
integer array kardin(0:255)= pb :=    <<kard to jis8 conversion table>> 04015000
      %000,%001,%002,%003,%004,%005,%006,%007,                          04020000
      %010,%011,%012,%013,%014,%015,%016,%017,                          04025000
      %020,%021,%022,%023,%024,%025,%026,%027,                          04030000
      %030,%031,%032,%033,%034,%035,%036,%037,                          04035000
      %040,%041,%042,%043,%044,%045,%046,%047,                          04040000
      %050,%051,%052,%053,%054,%055,%056,%057,                          04045000
      %060,%061,%062,%063,%064,%065,%066,%067,                          04050000
      %070,%071,%072,%073,%074,%075,%076,%077,                          04055000
      %100,%101,%102,%103,%104,%105,%106,%107,                          04060000
      %110,%111,%112,%113,%114,%115,%116,%117,                          04065000
      %120,%121,%122,%123,%124,%125,%126,%127,                          04070000
      %130,%131,%132,%133,%134,%135,%136,%137,                          04075000
      %140,%261,%262,%263,%264,%265,%266,%267,                          04080000
      %270,%271,%300,%301,%302,%303,%304,%305,                          04085000
      %306,%307,%310,%315,%316,%317,%320,%321,                          04090000
      %322,%323,%324,%173,%174,%175,%176,%177,                          04095000
      %200,%201,%202,%203,%204,%205,%206,%207,                          04100000
      %210,%211,%212,%213,%214,%215,%216,%217,                          04105000
      %220,%221,%222,%223,%224,%225,%226,%227,                          04110000
      %230,%231,%232,%233,%234,%235,%236,%237,                          04115000
      %241,%242,%243,%244,%245,%246,%247,%250,                          04120000
      %251,%252,%253,%254,%255,%256,%257,%240,                          04125000
      %260,%141,%142,%143,%144,%145,%146,%147,                          04130000
      %150,%151,%156,%160,%161,%162,%165,%164,                          04135000
      %152,%153,%154,%155,%272,%157,%273,%274,                          04140000
      %275,%276,%277,%311,%166,%163,%312,%313,                          04145000
      %314,%167,%325,%171,%326,%327,%330,%331,                          04150000
      %172,%170,%342,%343,%344,%345,%346,%347,                          04155000
      %340,%341,%332,%333,%334,%335,%336,%337,                          04160000
      %350,%351,%352,%353,%354,%355,%356,%357,                          04165000
      %360,%361,%362,%363,%364,%365,%366,%367,                          04170000
      %370,%371,%372,%373,%374,%375,%376,%377;                          04175000
                                                                        04180000
                                                                        04185000
                                                                        04190000
$page                                                                   04195000
subroutine form'katakana;                                               04200000
                                                                        04205000
<<  converts from ascii to katakana character set for jis8  >>          04210000
                                                                        04215000
begin                                                                   04220000
wcnt:= 0;                      <<wcnt initialize>>                      04225000
while wcnt < integer (ditp(dwcnt)) do                                   04230000
    begin                      <<start convert and move>>               04235000
    tos:= bufaddrd;            <<load bufaddrd>>                        04240000
    tos:= tos+wcnt;            <<addrress of convert data>>             04245000
    assemble(lsea);            <<load data>>                            04250000
    assemble(delb,delb);       <<clear addrress on stack>>              04255000
    assemble(dup);                                                      04260000
    assemble(andi 255);        <<right byte>>                           04265000
    x:= tos;                                                            04270000
    tos:= kardin(x);           <<convert to jis8>>                      04275000
    assemble(xch);             <<next byte>>                            04280000
    tos:= tos & lsr(8);        <<left byte>>                            04285000
    x:= tos;                                                            04290000
    tos:= kardin(x);           <<convert to jis8>>                      04295000
    tos:= tos & lsl(8);        <<shift to left>>                        04300000
    assemble(or);              <<merge right and left byte>>            04305000
    tos:= bufaddrd;                                                     04310000
    tos:= tos+wcnt;            <<converted data adrress>>               04315000
    assemble(cab;ssea;ddel);   <<move and clear addrress>>              04320000
    wcnt:= wcnt+1;             <<update word counter>>                  04325000
    end;                                                                04330000
end;                                                                    04335000
$page  "DRIVER INITIATOR AND COMPLETOR COMMON AREA"                     04340000
   <<------------ begin card reader driver -------------->>             04345000
   <<---- driver initiator and completor common area ---->>             04350000
                                                                        04355000
ldev := ditp(dldev);                      <<set ldev>>         <<06720>>04360000
lpdt'index := ldev * integer(lpdt'entry'size);                 <<06720>>04365000
datamode := ioq'parm2.(11:2);             <<set data mode>>    <<06720>>04370000
auxbufaddrd := double(logical(@siop(chanprogsize)+sysdb));     <<06720>>04375000
      <<auxbufaddrd is now initialized with the bank word set>><<04623>>04380000
      <<to zero and the offset word set to the address of the>><<04623>>04385000
      <<first location following the channel program         >><<04623>>04390000
wcnt := 0;                                <<set word count>>   <<06720>>04395000
msgtype := 0;       <<save place for msgtype>>                 <<06720>>04400000
@cpvap := ditp(diltp);                    <<cpvap>>            <<06720>>04405000
badcolumn := 0;     <<save place for badcolumn>>               <<06720>>04410000
subtest := 0;       <<save place for subtest>>                 <<06720>>04415000
                                                                        04420000
if ioq'entry'index=0 then   <<start idle channel prog>>        <<06720>>04425000
begin                                                                   04430000
  siop(jmpaddr):=startidle-2;             <<displacement=addr-2>>       04435000
  startio(ditp,siop,false);                                             04440000
  cpvap:=0;                                                             04445000
  crdrvr:=requestdone;                                                  04450000
  return;                                                               04455000
end;                                                                    04460000
                                                                        04465000
                                                               <<06720>>04470000
if ioq'abort then                         <<request aborted>>  <<06720>>04475000
begin                                                                   04480000
   masterclear (ditp);                                                  04485000
   ioq'count := 0;                        <<clear word count>> <<06720>>04490000
   <<if i/o is aborted we will do a clear to put the device>>           04495000
   <<in a known state.  we will keep a flag(abortflag) so  >>           04500000
   <<that we will only do 1 clear for each series of       >>           04505000
   <<aborted ioqs.  this flag will be reset after the first>>           04510000
   <<ioq which does not have the abort bit set.            >>           04515000
                                                                        04520000
   if ditp(dsave).abortflag=1 then                                      04525000
   begin                                                                04530000
       tos := if ioq'pfail then pfabort else aborted;          <<06720>>04535000
       goto setstatus;                                                  04540000
     end                                                                04545000
   else                                                                 04550000
     begin                                                              04555000
       ditpl(dsave).abortflag:=1;                                       04560000
       goto deviceclear;                                                04565000
     end                                                                04570000
end                                                                     04575000
else ditp(dsave).abortflag:=0;                                          04580000
$page "DRIVER INITIATOR"                                                04585000
if mstate = start'request  then                                         04590000
begin   <<this begin end pair encloses the initiator>>                  04595000
   siop(devclear):=%2000; <<restore part of readstatus>>                04600000
                       <<also used for clear command>>                  04605000
   if ioq'func = read then goto readreq                        <<06720>>04610000
      else if ioq'func = fopen then goto convertdone           <<06720>>04615000
      else if ioq'func = fclose then goto convertdone          <<06720>>04620000
      else if ioq'func = dclose then goto deviceclose          <<06720>>04625000
      else if ioq'func = readstat then goto readstatus         <<06720>>04630000
      else if ioq'func = identity then goto get'identity       <<06720>>04635000
      else if ioq'func = writeloop then goto wrtloopback       <<06720>>04640000
      else if ioq'func = readloop then goto readloopback       <<06720>>04645000
      else if ioq'func = inittest then goto initselftest       <<06720>>04650000
      else if ioq'func = dclear then goto clearcommand         <<06720>>04655000
      else go to badcall;                                               04660000
   help;                                  <<for linkage>>               04665000
                                                                        04670000
deviceclose:                                                            04675000
                                                               <<06720>>04680000
      lpdt'eof'type := 0;                                      <<06720>>04685000
                           <<clear eof state in lpdt>>         <<06720>>04690000
      go to convertdone;                                                04695000
                                                                        04700000
clearcommand:                                                           04705000
      if ioq'diag = 0 then goto badcall;                       <<06720>>04710000
deviceclear:                                                            04715000
      siop(devclear):=clear;       <<clear command>>                    04720000
      siop(devclear+1):=0;                                              04725000
      siop(jmpaddr):=devclear-2;                                        04730000
      goto beginio;                                                     04735000
                                                                        04740000
initselftest:                                                           04745000
      if ioq'diag = 0 then goto badcall;<<not diag req>>       <<06720>>04750000
      tos:=bufaddrd;                      <<user bank&addr>>            04755000
      assemble (lsea;delb,delb);          <<get contents of bank&addr>> 04760000
      subtest:=tos;                                                     04765000
      if subtest<0 or subtest>5 then goto badcall;  <<invalid test>>    04770000
      siop(jmpaddr):=0;                                                 04775000
      siop(writeorder):=init'selftest;    <<initiate self test>>        04780000
      siop(writebytes):=1;                                              04785000
      siop(writebank):=0;                                               04790000
      siop(writeaddr):=@siop(tempstore)+sysdb;                          04795000
      siop(tempstore):=subtest&lsl(8);                                  04800000
      siop(dsjgood):=0;                   <<go on to read results>>     04805000
      siop(readorder):=read'selftest;     <<send results>>              04810000
      siop(readbytes):=1;                                               04815000
      siop(readbank):=bank;                                             04820000
      siop(readbank).(1:1):=1;  <<bit 1 means read into the             04825000
                                  right, not left byte of the           04830000
                                  destination address>>                 04835000
      siop(readaddr):=bufaddr;                                          04840000
      siop(jump'or'wait):=jump;                                         04845000
      siop(jmpaddr2):=5;                  <<jump around read2>>         04850000
      goto beginio;                                                     04855000
$page                                                                   04860000
wrtloopback:                                                            04865000
      if ioq'diag = 0 then goto badcall;                       <<06720>>04870000
      tos:=bufaddrd;                                                    04875000
      assemble (lsea;delb,delb);          <<get byte for loopback>>     04880000
      siop(tempstore):=tos;                                             04885000
      if siop(tempstore).(0:8)<>0 then goto badcall;                    04890000
                                          <<value must be < 256 >>      04895000
      siop(tempstore).(0:8):=6;   <<6 in high byte is code to device    04900000
                                    to accept byte of loopback data>>   04905000
      siop(jmpaddr):=0;                                                 04910000
      siop(writeorder):=init'selftest;                                  04915000
      siop(writebytes):=2;                                              04920000
      siop(writebank):=0;                                               04925000
      siop(writeaddr):=@siop(tempstore)+sysdb;                          04930000
      siop(dsjgood):=12;                  <<go to read status >>        04935000
      goto beginio;                                                     04940000
                                                                        04945000
readloopback:                                                           04950000
      if ioq'diag =0 then goto badcall;                        <<06720>>04955000
      siop(jmpaddr):=readorder-2;                                       04960000
      siop(readorder):=read'selftest;     <<send results>>              04965000
      siop(readbytes):=1;                                               04970000
      siop(readbank):=bank;                                             04975000
      siop(readbank).(1:1):=1;  <<bit 1 means read into the             04980000
                                  right, not left byte of the           04985000
                                  destination address>>                 04990000
      siop(readaddr):=bufaddr;                                          04995000
      siop(jump'or'wait):=jump;                                         05000000
      siop(jmpaddr2):=5;                  <<jump around read2>>         05005000
      goto beginio;                                                     05010000
                                                                        05015000
get'identity:                                                           05020000
      if ioq'diag = 0 then goto badcall;<<not diag req>>       <<06720>>05025000
      siop(jmpaddr):=identify-2;          <<jump to get identity>>      05030000
      siop(identstore):=0;                <<initialize storage>>        05035000
      goto beginio;                                                     05040000
                                                                        05045000
                                                                        05050000
readstatus:                                                             05055000
      siop(jmpaddr):=rorder2-2;           <<jump to command>>           05060000
      siop(rorder2):=readstatcommand;     <<readstatus command>>        05065000
      siop(raddr2):=bufaddr;                                            05070000
      siop(rbank2):=bank;          <<bank & addr passed to us>>         05075000
      siop(rbytes2):=2;                                                 05080000
      goto beginio;                                                     05085000
$page                                                                   05090000
readreq:                                                                05095000
      eofcheck (ioq'entry'index,0d,0,0);                       <<06720>>05100000
      if <> then  go to iodone;           <<end of file>>               05105000
                                                                        05110000
      if datamode>1 or datamode<0 then                                  05115000
      begin                               <<invalid mode specification>>05120000
badcall:                                                                05125000
            ioq'count := 0;               <<clear word count>> <<06720>>05130000
            tos:=invalidop;                                             05135000
            go to setstatus;                                            05140000
      end;                                                              05145000
                                                                        05150000
      tos := ioq'count;                                        <<06720>>05155000
      if < then begin                                                   05160000
                  tos:=  -(tos & asr(1)); <<convert to words, if>>      05165000
                end;                      <<byte count is odd round up>>05170000
      if ls0 > maxcount(datamode) then    <<requested > maximum >>      05175000
      begin                                                             05180000
            del;                                                        05185000
            tos:= maxcount(datamode);     <<truncate to maxcount>>      05190000
            ioq'count :=                                       <<06720>>05195000
             if integer(ioq'count)<0  then (-(s0*2)) else s0;  <<06720>>05200000
              <<qwbct must remain a byte count or word count            05205000
                depending on its original value>>                       05210000
      end;                                                              05215000
      ditp(dwcnt):= s0;                   <<save requested word count>> 05220000
                                                                        05225000
      ditp(dsave).readdone:= 0;                                         05230000
      if <> then                <<card already read & ascii requested>> 05235000
      begin                                                             05240000
            if binary then      <<binary & card read in ascii>>         05245000
                  goto badcall;                                         05250000
            tos:= 1;            <<to indicate aux buffer read>>         05255000
            goto checkdata;     <<move data to user from aux. buffer>>  05260000
      end;                                                              05265000
                                                                        05270000
      if s0< 40 then                                                    05275000
      begin                     <<read 40 words into aux. for backup>>  05280000
           del;                           <<delete word count>>         05285000
           ioq'qmisc := 1;      <<set auxillary buffer flag>>  <<06720>>05290000
           tos:= 40;                      <<new word count >>           05295000
           tos:= auxbufaddrd;             <<auxillary bank and address>>05300000
      end                                                               05305000
      else tos:= bufaddrd;                <<user bank and address>>     05310000
                                                                        05315000
      siop(readaddr):= tos;               <<buffer address>>            05320000
      siop(readbank):=tos;                                              05325000
      tos:=tos*2;               <<change wordcount to byte count>>      05330000
      siop(readbytes):=tos;                                             05335000
      siop(readorder):=readcommand;                                     05340000
                                                                        05345000
<<now form pick command>>                                               05350000
                                                                        05355000
      siop(writeorder):=if ascii then pickascii else pickbinary;        05360000
                                <<pick ascii or binary>>                05365000
      siop(writebytes):=2;                                              05370000
      siop(writebank):=0;                                               05375000
      siop(writeaddr):=@siop(pickcount)+sysdb;                          05380000
                                                                        05385000
      tos:=80;                                                          05390000
      tos:=tos cat siop(readbytes)(0:8:8);                              05395000
      siop(pickcount):=tos; <<high byte=byte count,low byte=burst of80>>05400000
      siop(jmpaddr):=0;         <<start channel prog with pick command>>05405000
      siop(dsjgood):=0;         <<if pick was good then read buffer>>   05410000
                                                                        05415000
<< if bytecount is greater than 80, as in a binary read then            05420000
   the read must be done in two steps>>                                 05425000
                                                                        05430000
      if siop(readbytes)>80 then begin                                  05435000
        siop(rorder2):=readcommand;                                     05440000
        siop(rbytes2):=siop(readbytes)-80;                              05445000
        siop(readbytes):=80;                                            05450000
        siop(rbank2):=siop(readbank);                                   05455000
        siop(raddr2):=siop(readaddr)+40;                                05460000
        siop(jump'or'wait):=wait;                                       05465000
        siop(jmpaddr2):=0;                                              05470000
      end else begin                                                    05475000
        siop(jump'or'wait):=jump;                                       05480000
        siop(jmpaddr2):=5;                                              05485000
      end;                                                              05490000
                                                                        05495000
beginio:                                                                05500000
      siop(readstatdest):=@ditp(dstat)+sysdb;                           05505000
      cpvap:=0;                                                         05510000
      startio (ditp,siop,true);                                         05515000
      if < then                                                         05520000
siofailure:                                                             05525000
      begin                               <<sio failure>>               05530000
         ditp(dlogerror):=cpvap;                                        05535000
         ditp(dserr):=[8/1,8/dlogerror];                                05540000
         tos:= siofail;                                                 05545000
         goto badio;                                                    05550000
      end;                                                              05555000
      ioq'stat := pending;                                     <<06720>>05560000
      crdrvr:= call'completor;                                          05565000
      return;                                                           05570000
end;   <<end of initiator>>                                             05575000
$page  "DRIVER COMPLETOR"                                               05580000
completor:                                                              05585000
    if tos.sfail then goto siofailure;    <<sio failure bit in ioq>>    05590000
    if (cpvap.errorcode=6) lor            <<dma abort>>                 05595000
       (cpvap.errorcode=7) then  goto chanerror;<<channel error>>       05600000
                                                                        05605000
    if status.powerup then                                              05610000
    begin                                                               05615000
       tos:=powerupstat;                                                05620000
       goto setstatus;                                                  05625000
    end;                                                                05630000
                                                                        05635000
    if ioq'func = identity then                                <<06720>>05640000
    begin                                                               05645000
      tos:=bufaddrd;                                                    05650000
      tos:=siop(identstore);                                            05655000
      assemble(ssea;ddel);<<store identity in user buffer,delete addr>> 05660000
      goto convertdone;                                                 05665000
    end;                                                                05670000
                                                                        05675000
    if ioq'func <> 0 then goto convertdone;                    <<06720>>05680000
<<following code only applies when reading a card, not for              05685000
  reading status,selftest,write&readloopback,getidentity,               05690000
  or device open>>                                                      05695000
    if (status land logtrouble) <> 0 then                               05700000
    begin      <<log the error>>                                        05705000
      ditp(dlogerror):=ditp(dstat);  <<move data to logging buffer>>    05710000
      ditp(dserr):= [8/1,8/dlogerror];    <<log error>>                 05715000
    end;                                                                05720000
                                                                        05725000
    if (status land troublebits) <> 0 then                              05730000
    begin                                                               05735000
      if status.buserror=1 then                                         05740000
      begin                                                             05745000
        tos:=xfer'error;     <<the most probable cause of this          05750000
                      is an unrecognized secondary address>>            05755000
        goto setstatus;                                                 05760000
      end;                                                              05765000
      if status.badhollerith then                                       05770000
      begin                                                             05775000
            tos:=if ioq'qmisc=1 then auxbufaddrd else bufaddrd;<<06720>>05780000
            <<bank&addr of data>>                                       05785000
            x:= 0;                                                      05790000
            badcolumn:=81;                                              05795000
            <<if message invalid hollerith in column 81 is              05800000
              ever sent to console this means that hardware             05805000
              status indicated an invalid hollerith, but                05810000
              the hardware failed to replace that char with             05815000
              an ascii sub (%32)>>                                      05820000
            while (x:=x+1)<=80 do                                       05825000
            begin                                                       05830000
              assemble( lsea );                  <<loadmemory>>         05835000
              if lx then tos:= tos&lsr(8)        <<get left byte>>      05840000
                    else assemble( incb );       <<bump word address>>  05845000
              if tos.(8:8)=sub then badcolumn:=x;<<invalid code found>> 05850000
            end;                                                        05855000
            if iomessage (1,12,%11000,ldev,badcolumn,,,,opconsole)      05860000
               then goto nrwait  <<invalid hollerith mess sent>>        05865000
               else goto syserr;                                        05870000
      end;                                                              05875000
$page                                                                   05880000
                                                                        05885000
      <<the next statement checks for hardware eof by checking          05890000
        if the eof lamp is on and the hopper is empty.                  05895000
        however if there was a motion check on the last                 05900000
        card, we must not return eof because the card                   05905000
        must be re-read.>>                                              05910000
                                                                        05915000
      if (status.eofbit) land (status.hoppermt) land                    05920000
         (not(status.mpchk)) then                                       05925000
      begin                               <<hardware eof>>              05930000
            lpdt'eof'type := 1;                                <<06720>>05935000
                                                               <<06720>>05940000
                                                               <<06720>>05945000
            eofcheck (ioq'entry'index,0d,0,0);                 <<06720>>05950000
            if <> then  go to iodone;     <<end of file>>               05955000
      end;                                                              05960000
                                                                        05965000
      if status.mpchk=1 then msgtype:=motpicmsg                         05970000
      else if status.rdchk=1 then msgtype:=rdchkmsg                     05975000
      else if status.stackerfull=1 then msgtype:=stkfullmsg             05980000
      else if status.hoppermt=1 then msgtype:=hoppermtmsg               05985000
      else                                                              05990000
notrdy:    msgtype:= notrdymsg;                                         05995000
                                                                        06000000
           if iomessage (1,msgtype,%10000,ldev,,,,,opconsole)           06005000
           then  begin                                                  06010000
nrwait:             siop(jmpaddr):=startidle-2;                         06015000
                    cpvap:=0;                                           06020000
                    startio(ditp,siop,false);                           06025000
                    if < then                                           06030000
                    begin                                               06035000
                      tos:=siofail;                                     06040000
                      goto badio;                                       06045000
                    end;                                                06050000
                    ioq'stat := offlinestat;                   <<06720>>06055000
                    tos:= notready;                                     06060000
                    goto out;                                           06065000
                 end;                                                   06070000
                                                                        06075000
syserr:    tos:= syserror;                <<no message link buffers>>   06080000
           goto badio;                                                  06085000
                                                                        06090000
chanerror:                                                              06095000
           ditp(dlogerror):=cpvap;                                      06100000
           ditp(dserr):=[8/1,8/dlogerror];                              06105000
           tos:=chanfail;                                               06110000
$page                                                                   06115000
badio:     masterclear (ditp);            <<clear word count>>          06120000
           ioq'count := 0;                                     <<06720>>06125000
           goto setstatus;                                              06130000
    end; <<of "IF STATUS LAND TROUBLEBITS"  statment>>                  06135000
$page                                                                   06140000
    tos := ioq'qmisc;            <<auxillary buffer flag>>     <<06720>>06145000
                                                                        06150000
checkdata:                                                              06155000
    eofcheck(ioq'entry'index, if ls0 then auxbufaddrd          <<06720>>06160000
             else bufaddrd,40,                                 <<06720>>06165000
                  if ascii then 1 else -1);                             06170000
                                                                        06175000
    if tos then                 <<read into auxillary buffer>>          06180000
    begin                                                               06185000
         if = then begin        <<no eof, move data to user buffer>>    06190000
                   tos:= bufaddrd;                                      06195000
                   tos:= auxbufaddrd;                                   06200000
                   tos:= ditp(dwcnt);     <<word count to move>>        06205000
                   assemble( mabs );                                    06210000
                   goto gooddone;                                       06215000
                   end;                                                 06220000
         if < then goto setreaddone;      <<back up card>>              06225000
    end                                                                 06230000
                                                                        06235000
    else if < then              <<data was read into user buffer and>>  06240000
         begin                  <<must be moved to aux buffer>>         06245000
              tos:= auxbufaddrd;                                        06250000
              tos:= bufaddrd;                                           06255000
              tos:= 40;                                                 06260000
              assemble( mabs 1 );     <<leave source address on tos>>   06265000
              x:= ditp(dwcnt);                                          06270000
              do begin                <<blank user's buffer>>           06275000
                 tos:= tos-1;   tos:= 0;                                06280000
                 assemble( ssea );                                      06285000
                 end                                                    06290000
              until dxbz;                                               06295000
setreaddone:  if ascii then ditp(dsave).readdone:= 1;                   06300000
         end                                                            06305000
                                                                        06310000
         else if = then         <<read into user buffer and no back up>>06315000
              begin             <<no eof>>                              06320000
gooddone:          x := ioq'func;    <<i/o request type>>      <<06720>>06325000
                   if <> then goto convertdone;   <<not read request>>  06330000
                                                               <<06720>>06335000
                                                               <<06720>>06340000
                  if lpdt'subtype=1 and ascii                  <<06720>>06345000
                   then form'katakana;    <<katakana character set>>    06350000
                                                                        06355000
convertdone:       tos:= goodio;                                        06360000
                                                                        06365000
setstatus:         ioq'stat := tos;                            <<06720>>06370000
              end;                                                      06375000
                                                                        06380000
iodone:                                                                 06385000
    tos:= requestdone;                                                  06390000
                                                                        06395000
out:                                                                    06400000
    crdrvr:= tos;                                                       06405000
                                                                        06410000
                                                                        06415000
    end;      <<----  c r d r v r ------->>                             06420000
$page                                                                   06425000
  <<*************** driver linkage area ******************>>            06430000
                                                                        06435000
assemble(                                                               06440000
    pcal siodm;    << monitor >>                                        06445000
    pcal crdrvr;   << initiator >>                                      06450000
    pcal crdrvr;   << completor >>                                      06455000
    con  0;        << no i/o process >>                                 06460000
    pcal crinit;   << initialization >>                                 06465000
    con  1;        << one interrupt handler >>                          06470000
    pcal gip);     << interrupt handler >>                              06475000
                                                                        06480000
end.   << card reader driver - hiocdrd0 >>                              06485000
