$CONTROL MAP,CODE,USLINIT                                               00010000
  <<   hiolprt1, module 38 - hp2631 lp driver hpib   >>                 00015000
<< hp32002c mpe source c.00.00 >>                                       00020000
<< COPYRIGHT     "(C) COPYRIGHT HEWLETT-PACKARD CO. 1980.           >>  00025000
<<     this program may be used with one computer system at a       >>  00030000
<<     time and shall not otherwise be recorded, transmitted or     >>  00035000
<<     stored in a retrieval system.  copying or other reproduction >>  00040000
<<     of this program except for archival purposes is prohibited   >>  00045000
<<     without the prior written consent of hewlett-packard company.>>  00050000
<< **** note - dollar copyright cannot be used with this module *** >>  00055000
$title "HP2631 LINE PRINTER DRIVER - HPIB"                              00060000
$control privileged,uncallable                                          00065000
$tp                                                                     00070000
                                                                        00075000
<<                                                                      00080000
                                                                        00085000
                                                                        00090000
        hp2631 [hp3000-hpib] line printer driver - hiolprt1             00095000
        ---------------------------------------------------             00100000
                                                                        00105000
                                                                        00110000
structure of hiolprt1:                                                  00115000
                                                                        00120000
hiolprt1, together with the sio device monitor (siodm) constitute a     00125000
standard mpe type 1 i/o driver/monitor.  this means that it does not    00130000
run in its own process, but executes on any stack and therefore must    00135000
run to completion.  during initialization it executes on progen's       00140000
stack, during request initiation it executes on attachio's stack, and   00145000
during interrupt processing it executes on the interrupt control        00150000
stack (ics).                                                            00155000
                                                                        00160000
HIOLPRT1 consists of a global area, two procedures, and an "outer       00165000
block" which is really a linkage area for INITIAL.  The global area     00170000
contains an array called initial which is comprised of three parts.     00175000
the first part specifies the size of the other two, the unit extract    00180000
instruction, and various parameters which are used by initial.  this    00185000
section is deleted after initial is through with it.  the other two     00190000
parts are the device information table (dit) and the channel program    00195000
area, which is part of the interrupt linkage table (ilt).  initial      00200000
will put each of these items in the area of memory where it belongs.    00205000
the linkage area specifies the procedure labels (p-labels) of the       00210000
associated monitor (siodm), the request initiator (lpdrvr), the         00215000
request completor (lpdrvr), the initialization procedure (lpinit,       00220000
called by progen at system startup), and the interrupt handler (gip).   00225000
                                                                        00230000
                                                                        00235000
operation of hiolprt1:                                                  00240000
                                                                        00245000
the primary working code of hiolprt1 is a procedure lpdrvr.  lpdrvr is  00250000
called with five parameters.  two of these parameters, bank and         00255000
buffaddr, are the absolute buffer address of the data to be processed.  00260000
the other three, ditp, ioqp, and siop are pointers to three arrays.     00265000
ditp is a pointer to the device information table which contains        00270000
information about its associated line printer.  there is one dit for    00275000
unit on the 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
listing.                                                                00310000
                                                                        00315000
lpdrvr is always called by the sio device monitor (siodm) and it        00320000
determines the reason for the call by examining the ioq and the dit.    00325000
when a new request is initiated, lpdrvr examines the function code      00330000
and parameter fields contained in the ioq element to determine the      00335000
task that is desired.  the proper command codes and program branches    00340000
are then placed in the channel program and its execution is begun.      00345000
                                                                        00350000
upon completion of the request, an interrupt is generated and lpdrvr    00355000
is again called.  the code checks for current activity in progress,     00360000
and this being the case, branches to the completion section of the      00365000
driver.  here several status words are exaimed for errors or special    00370000
conditions which might have occurred during the execution of the        00375000
channel program, during the data transfer, or during the operation of   00380000
the line printer.  these conditions can cause error retries and/or      00385000
special notation back to the caller.  a list of the conditions and      00390000
the return codes is provided in this listing.                           00395000
$page                                                                   00400000
                device information table (dit)                          00405000
                ------------------------------                          00410000
                                                                        00415000
                                                                        00420000
there is one dit per physical device.  if a physical device represents  00425000
more than one logical device, the logical device number is obtained     00430000
from the ioq element (however, there is only one device per 2631        00435000
controller.)  the following diagram shows the dit used for the          00440000
2631 line printer driver.                                               00445000
                                                                        00450000
     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15   mnemonic          00455000
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+                    00460000
  0| 0| 0|ac|rq| 0| 0| 0|io|ia|no|st| 0|   state   |   dflag            00465000
   +--+--+--+--+--+--+--+--+--+--+--+--+-----------+                    00470000
  1| sysdb relative pointer to the dit for the next|   dlink            00475000
   | device requesting this resource or service    |                    00480000
   +-----------------------------------------------+                    00485000
  2| sysdb relative pointer to the first ioq in    |   dioqp            00490000
   | request list for this device                  |                    00495000
   +-----+-----------------+-----------------------+                    00500000
  3|          logical device number                |   dldev            00505000
   +-----+-----------------+-----------------------+                    00510000
  4| sysdb relative pointer to device linkage table|   ddltp            00515000
   +-----------------------------------------------+                    00520000
  5| sysdb relative pntr to interrupt linkage table|   diltp            00525000
   +-----------------------------------------------+                    00530000
  6|                                      |ps|fl|tp|   dsave            00535000
   +-----------------------------------------------+                    00540000
  7| hardware error status.  set when the driver   |   dserr            00545000
   | detects an error.  whenever <>0, the driver   |                    00550000
   | monitor logs an i/o error and clears this word|                    00555000
   +-----------------------------------------------+                    00560000
%10| bit 0 is set at completion of timer           |   dtime            00565000
   +-----------------------------------------------+                    00570000
%11| holds the time out request entry index while  |   drqst            00575000
   | a timer is active.                            |                    00580000
   +-----------------------------------------------+                    00585000
%12|iot  |/////////////| phyical unit number       |   dunit            00590000
   +-----------------------------------------------+                    00595000
%13|         hardware logged error status          |   dlogeror         00600000
   +-----------------------------------------------+                    00605000
                                                                        00610000
                                                                        00615000
dflag - flags and request state                                         00620000
  ac  active  - a monitor is currently servicing this device.           00625000
  rq  request - a service request is pending while the monitor is       00630000
                active.                                                 00635000
  io  ioprog  - an i/o channel program is running for this device.      00640000
  ia  iak     - an interrupt or response has occurred for this device.  00645000
  no  notrdy  - go to state %10 after idle channel program is started.  00650000
  st  stwait  - the device monitor is starting an idle channel program  00655000
                for this device.  there is no ioq associated with this  00660000
                type of request.                                        00665000
  state       - state of the device monitor.  specifies the next action 00670000
                to be taken in siodm in servicing the request:          00675000
                  0 - start new request                                 00680000
                  1 - not used                                          00685000
                  2 - call driver initiator procedure                   00690000
                  3 - call driver completor procedure                   00695000
                  4 - not used                                          00700000
                  5 - process request completed                         00705000
                  6 - initiate device recognition sequence              00710000
                  7 - start operator intervention wait                  00715000
                %10 - wait for interrupt (operator intervention)        00720000
                      restart at state 0                                00725000
                %11 - wait for data segment freeze, then state 2        00730000
                %12 - wait for driver initiator to be frozen, then      00735000
                      allocate controller (state 2)                     00740000
                %13 - wait for i/o completion interrupt, then state 3   00745000
                %14 - wait for controller, then call driver initiator   00750000
                %15 - not used                                          00755000
                %16 - wait for initiator make present, then state 2     00760000
                %17 - wait for completor make present, then state 3     00765000
                                                                        00770000
dldev - i/o system type, unit and logical device number                 00775000
  iot i/o type - type of i/o system                                     00780000
             0 - hp3000 series 2/3                                      00785000
             1 - hp3000 series 33 (hpib)                                00790000
             2 - unused                                                 00795000
             3 - unused                                                 00800000
                                                                        00805000
dsave - device processing flags                                         00810000
  ps   prespace  - last request used prespacing.                        00815000
  fl   full      - line printer buffer is full.                         00820000
  tp   top       - printer is at top of form                            00825000
                                                                        00830000
$page                                                                   00835000
                interrupt linkage table (ilt)                           00840000
                -----------------------------                           00845000
                                                                        00850000
                                                                        00855000
there is one ilt for each device controller configured on the system.   00860000
a controller may support more than one unit, however the 2631           00865000
controller only supports one unit.                                      00870000
                                                                        00875000
     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15   mnemonic          00880000
   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+                    00885000
  0|         channel                               |   icpva0           00890000
  1|              program                          |   icpva1           00895000
  2|                  variable                     |   icpva2           00900000
  3|                       area (icpva)            |   icpva3           00905000
   +-----------------------------------------------+                    00910000
  4|         dma abort                             |   icpva4           00915000
  5|              address                          |   icpva5           00920000
   +-----------------------------------------------+                    00925000
  6|                      0                        |   isrql            00930000
   +--+-----------------+-----+-----------+--------+                    00935000
  7|li|     chanque     |     |   chan    |  dev   |   icntrl           00940000
   +--+-----------------+-----+-----------+--------+                    00945000
%10| sysdb relative pointer to channel program area|   isiop            00950000
   +-----------------------------------------------+                    00955000
%11| sysdb relative pointer to status return area. |   istap            00960000
   | (the 2631 driver does not use the status      |                    00965000
   |  return area so this entry is 0.)             |                    00970000
   +-----------------------------------------------+                    00975000
%12| single instruction that is executed to extract|   iunit            00980000
   | the device unit number from the status pointed|                    00985000
   | to by istap.  (since there is only one unit   |                    00990000
   | on the controller, this entry is not used.)   |                    00995000
   +-----------------------------------------------+                    01000000
%13| sysdb relative dit pointer of the device      |   icdp             01005000
   | currently using the channel to perform a      |                    01010000
   | data operation.                               |                    01015000
   +-----------------------+-----------------------+                    01020000
%14|       siopsize        |        cquen          |   iqueue           01025000
   +--+--+--+--------------+-----------+-----------+                    01030000
%15|rw|wp|ig|                          |  hcunit   |   iflag            01035000
   +--+--+--+--------------------------+-----------+                    01040000
%16| sysdb relative dit pointer for unit 0         |   iditp0           01045000
   +-----------------------------------------------+                    01050000
%17|             line printer                      |                    01055000
   .               channel                         .                    01060000
   |                 program                       |                    01065000
   +-----------------------------------------------+                    01070000
                                                                        01075000
                                                                        01080000
icpva0 - channel program variable area                                  01085000
                                                                        01090000
  the first word is used by the channel program processor to store      01095000
  status information after i/o channel aborts.  the next word is used   01100000
  by the driver to indicate if status should be examined for special    01105000
  conditions or errors.  the other two words are not used.              01110000
                                                                        01115000
                                                                        01120000
icpva4 - dma abort address                                              01125000
                                                                        01130000
  if a dma abort occurs, the absolute address where the abort occurred  01135000
  is stored in this area.                                               01140000
                                                                        01145000
                                                                        01150000
icntrl - contains controller information                                01155000
                                                                        01160000
  lim     - if this bit is set, the controller is sharing a software    01165000
            channel resource in order to limit bandwidth.               01170000
  chanque - the software channel resource number.                       01175000
  chan    - channel number (four most significant bits of drtn).        01180000
  dev     - device number (three least significant bits of drtn).       01185000
                                                                        01190000
                                                                        01195000
iqueue -                                                                01200000
                                                                        01205000
  siopsize - (number of words + 1)/2 in the channel program area.       01210000
  cquen    - for a multi-unit controller this field contains the        01215000
             software controller resource number.                       01220000
                                                                        01225000
                                                                        01230000
iflag - controller and channel program state flags                      01235000
                                                                        01240000
  runwait  - an idle channel program should be started when there       01245000
             are no active requests to process.  this flag is always    01250000
             0 for the 2631.                                            01255000
  waitprog - an idle channel program has been started for this          01260000
             controller.  this bit is reset by an interrupt.            01265000
  ignorehi - an hiop instruction has been issued against this	          01270000
             controller but the channel program was not in a wait       01275000
             statement.  therefore ignore the interrupt generated by    01280000
             the channel code when this program halts.                  01285000
  hcunit   - highest configured unit number for this controller.        01290000
                                                                        01295000
                                                                        01300000
                                                                        01305000
            device reference table drt                                  01310000
            --------------------------                                  01315000
                                                                        01320000
there is one drt per device controller.  the the contents of this       01325000
table are used for processing interrupts.                               01330000
                                                                        01335000
     word 0  siop   - absolute address of the current i/o               01340000
                      instruction in execution.                         01345000
     word 1  dbi    - absolute address of the base of the ilt           01350000
                      for this controller.                              01355000
     word 2  plable - the external program label of the interrupt       01360000
                      service routine for this controller.              01365000
     word 3  chan   - contains channel program status information       01370000
                      which is used by the channel program interpreter. 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|pp|pe|pf|toutcntr|                 | waitcode  |   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.  vertical format specification.  |   qpar1            01545000
   | (see next section for detail.)                |                    01550000
   +-----------------------------------------------+                    01555000
%11| parameter 2.  space mode flags.  (see next    |   qpar2            01560000
   | section for details.)                         |                    01565000
   +-----------------------+--------------+--------+                    01570000
%12|         pcbn          |  qualifier   | status |   qstat            01575000
   +-----------------------+--------------+--------+                    01580000
                                                                        01585000
                                                                        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
                     (not used)                                         01625000
  bit 3  sysbuff   - target is an index relative to the sbuf table of   01630000
                     the data buffer.                                   01635000
  bit 4  iowake    - wake caller on completion of request.              01640000
  bit 5  blocked   - blocked i/o.  the caller is waited in attachio     01645000
                     until the request is completed.  implies iowake.   01650000
  bit 6  completed - the request has been completed and the caller      01655000
                     awakened if he had requested (with iowake).        01660000
  bit 7  datafrzn  - set by the memory management routines (mam) when a 01665000
                     makepresent request is successfully completed and  01670000
                     indicates the data segment is frozen in memory.    01675000
  bit 8  mamerrord - an error has occurred while mam was trying to      01680000
                     make the target data segment present and freeze    01685000
                     it in memory.                                      01690000
  bit 9  preq      - (not used)                                         01695000
  bit 10 sfail     - delayed failure of sio instruction.  if a call to  01700000
                     startio resulted in the request being added to     01705000
                     the channel queue, this bit indicates that the sio 01710000
                     instruction failed when the request was selected   01715000
                     for execution.                                     01720000
  bit 11 pfail     - the request was aborted because of a system power  01725000
                     failure.                                           01730000
                                                                        01735000
                                                                        01740000
qmisc - driver request dependent flags and counters.                    01745000
                                                                        01750000
  pre'to'post - pre to post spacing change flag.                        01755000
  peject      - last operation was a page eject.                        01760000
  toutcntr    - channel time-out retry counter.                         01765000
  powerfail   - power fail flag indicates power fail occurred.          01770000
  waitcode    - indicates type of wait:                                 01775000
                  0 - new request                                       01780000
                  1 - completion wait                                   01785000
                  2 - not ready wait                                    01790000
                                                                        01795000
                                                                        01800000
qstat - pcb number and request completion status.                       01805000
                                                                        01810000
  pcbn    - the process control block (pcb) number of the process       01815000
            which made this request.  if zero, the request is not       01820000
            associated with any process and the ioq element is to       01825000
            be returned by the system when the request has completed.   01830000
  status  - general status indicating the final state of the request.   01835000
            the following codes are used:                               01840000
              0 - not started or awaiting completion.                   01845000
              1 - successful completion.                                01850000
              2 - end-of-file detected.                                 01855000
              3 - unusual, but recoverable, condition detected.         01860000
              4 - irrecoverable error has occurred.                     01865000
  qualifier - a code which further defines or qualifies the general     01870000
              status.  (see the section driver return status codes.)    01875000
                                                                        01880000
$page                                                                   01885000
                                                                        01890000
     line printer request codes -                                       01895000
                                                                        01900000
  operation     function          parameters                            01905000
                                                                        01910000
    write          1      p1 - vertical format specification            01915000
                                  1 - use 1st data char as format spec  01920000
                                                                        01925000
                                %53 - "+", print and suppress spacing   01930000
                                %55 - "-", print and triple space       01935000
                                %60 - "0", print and double space       01940000
                                %61 - "1", print and top of form        01945000
                                                                        01950000
                                %200-%277, print and space n-%200 lines 01955000
                                %300-%307, print with channel n-%277    01960000
                                                                        01965000
                                %320- fill line printer buffer only     01970000
                                                                        01975000
                                all others, print and single space      01980000
                                                                        01985000
                           p2 - space mode flags                        01990000
                                (15:1) = prespace flag                  01995000
                                   if set, print then fill buffer       02000000
                                   if clear, fill buffer then print     02005000
                                (14:1) = no page stepover flag          02010000
                                   if set, single and double space      02015000
                                     without stepover (66 lines/page)   02020000
                                   if clear, single and double space    02025000
                                     with stepover (60 lines/page)      02030000
                                                                        02035000
                                                                        02040000
    file open      2      page eject if not at top of form              02045000
                                                                        02050000
    file close     3      page eject if not at top of form              02055000
                                                                        02060000
    device close   4      page eject if not at top of form              02065000
                                                                        02070000
    read status  %17      read i/o status                               02075000
                           count - 1 byte minimum required              02080000
                                                                        02085000
    vfc set     %100      loads vfc ram                                 02090000
                           p1 -  1 - 1 lpi (lines per inch)             02095000
                                 2 - 2 lpi                              02100000
                                 3 - 3 lpi                              02105000
                                 4 - 4 lpi                              02110000
                                 6 - 6 lpi                              02115000
                                 8 - 8 lpi                              02120000
                                12 - 12 lpi                             02125000
                                any other value defaults to 6 lpi       02130000
$page                                                                   02135000
                                                                        02140000
     status returns -                                                   02145000
                                                                        02150000
         1 - normal completion                                          02155000
                                                                        02160000
        33 - request aborted externally                                 02165000
        63 - request aborted due to power failure                       02170000
       213 - device powered up (restore environment)                    02175000
                                                                        02180000
         4 - invalid request (function or parameter)                    02185000
        24 - i/o timed out before completion                            02190000
        44 - sio failure                                                02195000
        54 - unit failure                                               02200000
       124 - no message link buffers available                          02205000
       144 - i/o channel failure                                        02210000
                                                                        02215000
   note:  when postspace mode follows a prespace operation which left   02220000
          data in the printer buffer, a single space with page stepover 02225000
          is executed to clear the buffer before the next operation is  02230000
          performed.                                                    02235000
                                                                        02240000
          page ejects are suppressed when the previous operation was    02245000
          a page eject.                                                 02250000
                                                                        02255000
          if the number of printable characters exceeds the carriage    02260000
          width, the line will be continued on the next line as the     02265000
          2631 does not perform line truncation.                        02270000
                                                                        02275000
                                                                        02280000
        2631 i/o status bits                                            02285000
                                                                        02290000
     0 - on line                                                        02295000
                                                                        02300000
     1 - ready                                                          02305000
     2 - (not used)                                                     02310000
     3 - (not used)                                                     02315000
                                                                        02320000
     4 - parity error                                                   02325000
     5 - (not used)                                                     02330000
     6 - paper out                                                      02335000
                                                                        02340000
     7 - power restored/unit reset                                      02345000
                                                                        02350000
>>                                                                      02355000
$page                                                                   02360000
   begin                                                                02365000
$include inclioq                                               <<06723>>02370000
$page                                                          <<06723>>02375000
     equate                                                             02380000
                                                                        02385000
            << channel program array pointers >>                        02390000
                                                                        02395000
       baddr       =   29,  << write data buffer address >>             02400000
       bcount      =   26,  << write data byte count >>                 02405000
       buffjmp     =   18,  << on/off switch for buff fill >>           02410000
       dsj'rb1     =    3,  << first dsj return byte >>        <<01367>>02415000
       esc'ctl     =   97,  << online esc code buffer >>       <<01482>>02420000
       idle        =   49,  << start of idle chan prog >>               02425000
       memx        =   28,  << write data bank address >>               02430000
       modecmd     =   96,  << restricted mode cmd buffer >>   <<01482>>02435000
       pbank       =   47,  << postspace ctl bank adr >>       <<01367>>02440000
       pcount      =   45,  << postspace byte count >>         <<01367>>02445000
       pollmask    =   95,  << poll mask buffer >>             <<01482>>02450000
       poncp       =   71,  << power on init routine >>        <<01482>>02455000
       post'ctl    =   93,  << post-space control buffer >>    <<01482>>02460000
       postjmp     =   43,  << on/off switch for post-spacing >>        02465000
       pre'ctl     =   92,  << prespace control buffer >>      <<01482>>02470000
       prejmp      =    9,  << on/off switch for prespacing >>          02475000
       scount      =   58,  << read status byte count >>       <<01201>>02480000
       sbank       =   60,  << read status bank addr >>        <<01201>>02485000
       statadr     =   61,  << read status buffer addr >>      <<01201>>02490000
       status      =   94,  << i/o status buffer >>            <<01482>>02495000
       wrtctl1     =   10,  << write control instruction >>             02500000
       wrtctl2     =   44,  << write control instruction >>             02505000
                                                                        02510000
                                                                        02515000
       aborted     =  %33,  << request aborted return status >>         02520000
       chanfail    = %144,  << i/o channel error >>                     02525000
       cmpltionwait=    1,  << waiting for i/o completion interrupt >>  02530000
       dclose      =    4,  << device close function >>                 02535000
       diltp       =    5,  << interrupt linkage table pointer >>       02540000
       dldev       =    3,  << logical device and unit numbers >>       02545000
       dlogerror   =   11,  << hardware logged error status>>  <<06723>>02550000
       drqst       =    9,  << driver request flags >>         <<01301>>02555000
       dsave       =    6,  << driver flags >>                 <<01301>>02560000
       dserr       =    7,  <<dit hardware count & index>>     <<01348>>02565000
       dtime       =    8,  << time-out request entry index >> <<01301>>02570000
       fopen       =    2,  << file open function >>                    02575000
       fclose      =    3,  << file close function >>                   02580000
       full'       =   14,  << line printer buffer full >>              02585000
       goodio      =    1,  << successful i/o status return >>          02590000
       initiowait  =    3,  << initialize unit wait in progress >>      02595000
       intrptwait  =  %13,  << wait for completion driver return >>     02600000
       invalidop   =    4,  << invalid operation requested >>           02605000
       iotimer     =  %20,  << wait for channel prog to finish >>       02610000
       isiop       =    8,  << channel program area pointer >>          02615000
       notrdymsg   =   11,  << not ready message # to mess processor >> 02620000
       notrdywait  =    2,  << not ready wait in progress >>            02625000
       notready    =    7,  << not ready driver return >>               02630000
       opconsole   =    0,  << output message to operator >>            02635000
       paperoutmsg =   14,  << paper out message # to mess processor >> 02640000
       parityerror =   -1,  << parity error logging value >>            02645000
       pfabort     =  %63,  << request aborted due to power fail >>     02650000
       powerup     = %213,  << unit reset due to power failure >>       02655000
       prespace'   =   13,  << last request used prespacing >>          02660000
       qfunc       =    6,  << function code >>                         02665000
       qlink       =    1,  << ioq pointer to next request >>           02670000
       qmisc       =    3,  << request state >>                         02675000
       qpar1       =    8,  << carriage control specification >>        02680000
       qpar2       =    9,  << prespace and stepover request flags >>   02685000
       qstat       =   10,  << request status and pcb number >>         02690000
       qwbct       =    7,  << word/byte count >>                       02695000
       requestdone =    5,  << request completed driver return >>       02700000
       siofail     =  %44,  << sio failure request status >>            02705000
       sysdb       =%1000,  << set start of sysdb area >>               02710000
       syserror    = %124,  << system error request status >>           02715000
     endeq         =    0;                                              02720000
                                                                        02725000
                                                                        02730000
                                                                        02735000
             << i/o status bit definitions >>                           02740000
                                                                        02745000
     define                                                             02750000
       rdybit     = ( 1:1)#, << unit ready for data/command bit >>      02755000
       paperout   = ( 6:1)#, << paper out indicator >>                  02760000
       parityerr  = ( 4:1)#, << parity error occurred bit >>            02765000
       pon        = ( 7:1)#, << unit powered up or was reset >>         02770000
                                                                        02775000
                                                                        02780000
               << qmisc bit definitions >>                              02785000
                                                                        02790000
       pre'to'post= ( 0:1)#, << pre to post spacing change flag >>      02795000
       peject     = ( 1:1)#, << last operation was a page eject >>      02800000
       toutcntr   = ( 3:3)#, << channel time-out retry counter >>       02805000
       pondone    = ( 2:1)#, << power fail occurred flag >>    <<01493>>02810000
       waitcode   = (12:4)#, << indicates type of wait >>               02815000
                             <<   0 - new request      >>               02820000
                             <<   1 - completion wait  >>               02825000
                             <<   2 - not ready wait   >>               02830000
                             <<   3 - initialize unit wait >>           02835000
                                                                        02840000
                                                                        02845000
            << dsave bit definitions >>                                 02850000
                                                                        02855000
       prespace   = (13:1)#, << last request used prespacing >>         02860000
       full       = (14:1)#, << line printer buffer is full >>          02865000
       top        = (15:1)#, << printer is at top-of-form (tof) >>      02870000
                                                                        02875000
                                                                        02880000
             << miscellaneous bit definitions >>                        02885000
                                                                        02890000
       cmd        = (12:4)#, << secondary command >>                    02895000
                                                               <<06723>>02900000
       errorcode  = ( 0:3)#, << cpvap, error code >>                    02905000
       func       = ( 8:8)#, << qfunc, function code >>                 02910000
       iostat     = ( 8:8)#, << qstat, request status returned >>       02915000
       lrbit      = ( 1:1)#, << write instruction left/right byte bit >>02920000
       pfail      = (11:1)#, << qflag, abort set due to power fail >>   02925000
       sfail      = (10:1)#, << qflag, failure on delayed start sio >>  02930000
       stepover   = (14:1)#, << if set then no page stepover >>         02935000
       timedout   = (13:1)#, << cpvap, transfer aborted due to to >>    02940000
       asmb       = assemble#,                                 <<01367>>02945000
       hiop       = con %20302; con 1#,                        <<01367>>02950000
       loadmemory = assemble(lsea)#,                                    02955000
     enddef       = 0#;                                                 02960000
                                                                        02965000
                                                                        02970000
                                                                        02975000
$page                                                                   02980000
<<      *********************************                               02985000
        *                               *                               02990000
        *   driver db area definition   *                               02995000
        *                               *                               03000000
        *********************************       >>                      03005000
                                                                        03010000
                                                                        03015000
array initial(0:113)= db:=                                     <<06723>>03020000
       [8/12,8/1],<<dit size,not core res/no idle cp/dvr type>><<06723>>03025000
                0,   << not used >>                                     03030000
                0,   << unit extract instruction - not used >>          03035000
       [8/49,8/1],   << cp size/2, status return size >>       <<06723>>03040000
                                                                        03045000
       << lp dit >>                                                     03050000
                0,   << dflag >>                                        03055000
                0,   << dlink >>                                        03060000
                0,   << dioqp >>                                        03065000
                0,   << dldev >>                               <<06723>>03070000
                0,   << ddltp >>                                        03075000
                0,   << diltp >>                                        03080000
                0,   << dsave >>                               <<01301>>03085000
                0,   << dserr >>                                        03090000
                0,   << dtime >>                               <<01301>>03095000
                0,   << drqst >>                               <<01301>>03100000
          %040000,   << hp-ib device - dunit >>                <<06723>>03105000
                0,   << dlogerror >>                           <<01348>>03110000
                                                                        03115000
                                                                        03120000
       << channel program >>                                            03125000
                                                                        03130000
<< 0>> << wait >>           %1000,  << make sure unit is responding >>  03135000
<< 1>>                          0,                                      03140000
                                                                        03145000
<< 2>> << dsj >>            %2403,  << check printer's condition >>     03150000
<< 3>>                          0,     << return byte >>                03155000
<< 4>>                          0,     << jmp *+0, ready for command >> 03160000
<< 5>>                         56,     << jmp *+56, error, read stat >> 03165000
<< 6>>                         56,     << jmp *+56, stat read required>>03170000
<< 7>>                         56,     << jmp *+56, parity error >>     03175000
                                                                        03180000
<< 8>> << jump >>               0,  << jump *+0 for prespace request >> 03185000
<< 9>>                          0,  << jump *+7 otherwise >>            03190000
                                                                        03195000
<<10>> << write control >>  %2010,  << prespace write control/set vfc >>03200000
<<11>>                          1,                                      03205000
<<12>>                          0,                                      03210000
<<13>>                     %42000,                                      03215000
<<14>>                          0,                                      03220000
                                                                        03225000
<<15>> << wait >>           %1000,  << wait for unit to parallel poll >>03230000
<<16>>                          0,                                      03235000
                                                                        03240000
<<17>> << jump >>               0,  << jump *+0 for buffer fill >>      03245000
<<18>>                          0,  << jump *+23 otherwise >>           03250000
                                                                        03255000
<<19>> << dsj >>            %2403,  << check printer's condition >>     03260000
<<20>>                          0,     << return byte >>                03265000
<<21>>                          0,     << jmp*+0, ready for next burst>>03270000
<<22>>                         39,     << jmp*+39, error, read status >>03275000
<<23>>                         39,     << jmp*+39, stat read required >>03280000
<<24>>                          0,     << jmp*+0, n/a in burst loop >>  03285000
                                                                        03290000
<<25>> << write data >>     %2000,  << write out data buffer >>         03295000
<<26>>                          0,                                      03300000
<<27>>                          7,     << burst of 7 bytes >>           03305000
<<28>>                    %100000,                                      03310000
<<29>>                          0,                                      03315000
                                                                        03320000
<<30>> << jump >>               0,  << jump *+2, end of transfer >>     03325000
<<31>>                          2,                                      03330000
                                                                        03335000
<<32>> << jump >>               0,  << jump *-19, end of burst >>       03340000
<<33>>                        -19,                                      03345000
                                                                        03350000
<<34>> << wait >>           %1000,  << wait for unit to parallel poll >>03355000
<<35>>                          0,                                      03360000
                                                                        03365000
<<36>> << dsj >>            %2403,  << check printer's state >>         03370000
<<37>>                          0,     << return byte >>                03375000
<<38>>                          0,     << jmp *+0, ready for command >> 03380000
<<39>>                         22,     << jmp *+22, error - read stat >>03385000
<<40>>                         22,     << jmp *+22, stat read required>>03390000
<<41>>                          0,     << jmp *+0, parity error >>      03395000
                                                                        03400000
<<42>> << jump >>               0,  << jump *+0 for postspace request >>03405000
<<43>>                          0,  << jump *+7 otherwise >>            03410000
                                                                        03415000
<<44>> << write control >>  %2010,  << postspace write control >>       03420000
<<45>>                          1,                                      03425000
<<46>>                          0,                                      03430000
<<47>>                     %44000,                             <<01367>>03435000
<<48>>                          0,                                      03440000
                                                                        03445000
<<49>> << wait >>           %1000,  << wait for unit to parallel poll >>03450000
<<50>>                          0,                                      03455000
                                                                        03460000
<<51>> << dsj >>            %2403,  << check printer's state >>         03465000
<<52>>                          0,     << return byte >>                03470000
<<53>>                          0,     << jmp *+0, ready for command >> 03475000
<<54>>                          7,     << jmp *+7, error - read stat >> 03480000
<<55>>                          7,     << jmp *+7, stat read required >>03485000
<<56>>                          0,     << jmp *+0, parity error >>      03490000
                                                                        03495000
<<57>> << read status >>    %1416,  << read status byte >>              03500000
<<58>>                          1,                                      03505000
<<59>>                          0,                                      03510000
<<60>>                      %2000,                                      03515000
<<61>>                          0,                                      03520000
                                                                        03525000
<<62>> << int/hlt >>         %601,  << interrupt/halt and put halt >>   03530000
<<63>>                          1,     <<code of 1 in cpva word 1 >>    03535000
                                                                        03540000
<<64>> << read status >>    %1416,  << read status byte >>              03545000
<<65>>                          1,                                      03550000
<<66>>                          0,                                      03555000
<<67>>                      %2000,                                      03560000
<<68>>                          0,                                      03565000
                                                                        03570000
<<69>> << int/hlt >>         %601,  << interrupt/halt and put halt >>   03575000
<<70>>                          2,     << code of 2 in cpva word 1 >>   03580000
                                                               <<01482>>03585000
       << power on initiation routine >>                       <<01482>>03590000
                                                               <<01482>>03595000
<<71>> << write command >>  %2000,  << set lp online >>        <<01482>>03600000
<<72>>                          2,                             <<01482>>03605000
<<73>>                          0,                             <<01482>>03610000
<<74>>                      %2000,                             <<01482>>03615000
<<75>>                          0,  << esc (online) adr >>     <<01482>>03620000
                                                               <<01482>>03625000
<<76>> << wait >>           %1000,                             <<01482>>03630000
<<77>>                          0,                             <<01482>>03635000
                                                               <<01482>>03640000
       << initialization routine >>                            <<01482>>03645000
                                                               <<01482>>03650000
<<78>> << clear >>          %4401,  << clr w/parity check >>   <<01482>>03655000
<<79>>                          0,                             <<01482>>03660000
                                                               <<01482>>03665000
<<80>> << write command >>  %2001,  << set poll mask cmd >>    <<01482>>03670000
<<81>>                          1,                             <<01482>>03675000
<<82>>                          0,                             <<01482>>03680000
<<83>>                     %42000,                             <<01482>>03685000
<<84>>                          0,                             <<01482>>03690000
                                                               <<01482>>03695000
<<85>> << write command >>  %2002,  << restricted mode cmd >>  <<01482>>03700000
<<86>>                          1,                             <<01482>>03705000
<<87>>                          0,                             <<01482>>03710000
<<88>>                     %42000,                             <<01482>>03715000
<<89>>                          0,                             <<01482>>03720000
                                                               <<01482>>03725000
<<90>> << int/hlt >>         %601,  << int/hlt & put halt >>   <<01482>>03730000
<<91>>                          0,  << code 0 in cpvap(1) >>   <<01482>>03735000
                                                               <<01482>>03740000
<<92>> << buffers >>            0,  << prespace control >>     <<01482>>03745000
<<93>>                          0,  << postspace control >>    <<01482>>03750000
<<94>>                          0,  << status buffer >>        <<01482>>03755000
<<95>>                       %330,  << poll mask >>            <<01482>>03760000
<<96>>                       %202,  << restricted mode code >> <<01482>>03765000
<<97>>                    %015556;  << online esc seq >>       <<01482>>03770000
$page                                                                   03775000
<<       ***************************************                        03780000
         *                                     *                        03785000
         *   external procedure declarations   *                        03790000
         *                                     *                        03795000
         ***************************************     >>                 03800000
                                                                        03805000
                                                                        03810000
   procedure aborttimereq(trlx);                                        03815000
     value trlx;   integer trlx;                                        03820000
     option external;                                                   03825000
                                                                        03830000
   procedure gip'hpib;                                         <<01301>>03835000
     option external;                                                   03840000
                                                                        03845000
   procedure help;                                                      03850000
     option external;                                                   03855000
                                                                        03860000
   logical procedure iomessage(setno,msgno,mask,p1,p2,p3,p4,p5,dest,    03865000
                               reply,offset,ditp,iotype);               03870000
     value  setno,msgno,mask,p1,p2,p3,p4,p5,dest,reply,offset,          03875000
            ditp,iotype;                                                03880000
     integer  setno,msgno,mask,p1,p2,p3,p4,p5,dest,reply,offset,iotype; 03885000
     integer pointer  ditp;                                             03890000
     option variable, external;                                         03895000
                                                                        03900000
   procedure siodm(ditp,flags);                                         03905000
     value ditp,flags;   logical flags;                                 03910000
     pointer ditp;   option external;                                   03915000
                                                                        03920000
   procedure masterclearhpib(ditp);                            <<01301>>03925000
     array ditp;   option external;                                     03930000
                                                                        03935000
   procedure start'hpib(ditp,siop,qflag);                      <<01301>>03940000
     value ditp,siop,qflag;   logical qflag;                            03945000
     pointer ditp,siop;   option external;                              03950000
                                                                        03955000
   integer procedure timereq(code,req,time);                            03960000
     value code,req,time;                                               03965000
     integer code,req;   double time;                                   03970000
     option external;                                                   03975000
$page                                                                   03980000
<<       ******************************************                     03985000
         *                                        *                     03990000
         *   lp driver initialization procedure   *                     03995000
         *                                        *                     04000000
         ******************************************     >>              04005000
                                                                        04010000
                                                                        04015000
   procedure lpinit(ditp);                                              04020000
     integer array ditp;                                                04025000
                                                                        04030000
<<                                                                      04035000
       this procedure initializes the prespacing, post-spacing, and     04040000
       status buffer addresses in the channel program.                  04045000
>>                                                                      04050000
     begin                                                              04055000
       integer pointer   iltp = q+1;                                    04060000
       integer pointer   siop = q+2;                                    04065000
       integer        siobase = q+3;                                    04070000
                                                                        04075000
                                                                        04080000
       tos := ditp(diltp);      << iltp    >>                           04085000
       tos := iltp(isiop);      << siop    >>                           04090000
       tos := @siop + sysdb;    << siobase >>                           04095000
                                                                        04100000
       siop(14) := siobase + pre'ctl;                                   04105000
       siop(48) := siobase + post'ctl;                                  04110000
       siop(75) := siobase + esc'ctl;                          <<01482>>04115000
       siop(68) := siobase + status;                                    04120000
       siop(84) := siobase + pollmask;                         <<01482>>04125000
       siop(89) := siobase + modecmd;                          <<01482>>04130000
                                                                        04135000
     end;                                                               04140000
$page                                                                   04145000
<<       ************************************************               04150000
         *                                              *               04155000
         *   line printer driver procedure  -  lpdrvr   *               04160000
         *                                              *               04165000
         ************************************************     >>        04170000
                                                                        04175000
                                                                        04180000
                                                                        04185000
   integer procedure lpdrvr(ioqp,ditp,bank,buffaddr,siop,drtn);<<01301>>04190000
<<                                                                      04195000
       this procedure initiates and completes i/o requests              04200000
       for the hp 2631 line printer connected to the hp-ib              04205000
       and controlled by the gic.                                       04210000
                                                                        04215000
       mode returns in lpdrvr -                                         04220000
           5 - request completed                                        04225000
           7 - not ready wait                                           04230000
         %13 - wait for completion                              >>      04235000
                                                                        04240000
   value  ditp,ioqp,bank,buffaddr,siop,drtn;                   <<01301>>04245000
   integer bank, buffaddr, drtn, ioqp;                         <<06723>>04250000
   integer pointer ditp, siop;                                 <<06723>>04255000
   option  privileged,uncallable;                                       04260000
                                                                        04265000
   begin                                                                04270000
     logical array                                                      04275000
       ditpl(*) = ditp, siopl(*) = siop;                       <<06723>>04280000
                                                                        04285000
     double                                                             04290000
       buffaddrd = q-7;    << bank and buffer address >>       <<01301>>04295000
                                                                        04300000
     integer pointer                                                    04305000
       cpvap    = q+1,    << holds channel i/o status >>                04310000
       idlesiop = q+2,    << points to start of idle chan prog >>       04315000
       initsiop = q+3,    << points to start of init cp >>     <<01367>>04320000
       statsiop = q+8,    << points to cp status read >>       <<01367>>04325000
       fillsiop = q+9,    << points to fill buffer >>          <<01367>>04330000
       postsiop = q+10;   << points to postspace prt >>        <<01367>>04335000
                                                                        04340000
     integer                                                            04345000
       count    = q+4,    << buffer byte count >>                       04350000
       param    = q+5,    << control parameter >>                       04355000
       printctl = q+6,    << print control byte >>                      04360000
       fcode    = q+7,    << function code >>                           04365000
       s0       = s-0;                                                  04370000
                                                                        04375000
     logical                                                   <<06723>>04380000
       ioq'entry'index = q+11;                                 <<06723>>04385000
$page                                                                   04390000
   << initialize local pointers and variables >>                        04395000
                                                                        04400000
     tos := ditp(diltp);     << cpvap >>                                04405000
     tos := @siop+idle;      << idlesiop >>                             04410000
     tos := @siop+poncp;     << ponsiop  >>                    <<01482>>04415000
     tos:= 0;                << stack dummy count >>           <<06723>>04420000
     tos := 0;               << param >>                                04425000
     tos := 0;               << printctl >>                             04430000
     tos:= 0;                << stack dummy fcode >>           <<06723>>04435000
     tos := @siop+57;        << statsiop >>                    <<01201>>04440000
     tos := @siop+15;        << fillsiop >>                    <<01367>>04445000
     tos := @siop+34;        << postsiop >>                    <<01367>>04450000
     tos:= ioqp;             << ioq'entry'index:= ioqp >>      <<06723>>04455000
     count:= ioq'count;                                        <<06723>>04460000
     fcode:= ioq'func;                                         <<06723>>04465000
                                                                        04470000
     if ioq'entry'index = 0 then goto exit; << nothing to do >><<06723>>04475000
                                                                        04480000
     if ioq'qmisc.waitcode = cmpltionwait then                 <<06723>>04485000
       aborttimereq(ditp(drqst));                              <<01301>>04490000
                                                                        04495000
     tos:= ioq'flags;                                          <<06723>>04500000
     if < then      << abort process >>                                 04505000
       begin                                                            04510000
         tos:= if ioq'pfail then pfabort else aborted;         <<06723>>04515000
         goto badio;                                                    04520000
         help;     << link >>                                           04525000
       end;                                                             04530000
     del;                                                      <<01367>>04535000
                                                                        04540000
     if ioq'qmisc.waitcode = notrdywait then                   <<06723>>04545000
       begin   << return from not ready cond >>                <<01493>>04550000
         ioq'qmisc.pondone:= 0;                                <<06723>>04555000
         if <> or siop(status).pon = 1 then  << pon occurred >><<01493>>04560000
           goto poninit;                                       <<01493>>04565000
         if siop(dsj'rb1) <> 7 then                            <<01493>>04570000
           begin                                               <<01493>>04575000
           tos := drtn;                                        <<01493>>04580000
           asmb( hiop );  << halt any incomplete chan prog >>  <<01493>>04585000
           go to restart;                                      <<01493>>04590000
           end;                                                <<01493>>04595000
       end;                                                    <<01493>>04600000
                                                               <<01493>>04605000
                                                                        04610000
     if ioq'qmisc.waitcode = cmpltionwait then                 <<06723>>04615000
       goto lpcont;                                                     04620000
                                                                        04625000
     if ioq'qmisc.waitcode = initiowait then                   <<06723>>04630000
       begin                                                            04635000
         tos := powerup;                                                04640000
         goto iodone;                                                   04645000
       end;                                                             04650000
                                                                        04655000
     siop(buffjmp) := 23;                                               04660000
     siop(prejmp) := siop(postjmp) := 7;  << init cp >>                 04665000
     siop(wrtctl1).cmd := %10;  << init write ctl to print command >>   04670000
     siop(wrtctl2).cmd := %10;  << init write ctl to print command >>   04675000
     siop(scount) := 1;  << read single status >>              <<01201>>04680000
     siop(sbank).(8:8) := 0;                                   <<01201>>04685000
     siop(statadr) := @siop+sysdb+status;  << cp stat adr >>   <<01482>>04690000
     siop(pcount) := 1;  << reset postsp ctrl cnt >>           <<01367>>04695000
     siop(pbank).lrbit := 1;  << reset rt byte bit >>          <<01367>>04700000
                                                                        04705000
                                                                        04710000
          << check for fopen, fclose, and dclose  (fcode = 2,3, or 4) >>04715000
                                                                        04720000
     if fcode = dclose then                                             04725000
       begin                                                            04730000
         if ditp(dsave).(full':2) <> 1 then  << eject a page >><<02695>>04735000
           begin                                                        04740000
             siop(prejmp) := 0;                                         04745000
             siop(pre'ctl) := %100;                                     04750000
           end;                                                         04755000
         ditp(dsave) := 1;   << set tof flag >>                         04760000
                                                               <<02694>>04765000
                                                               <<02694>>04770000
                                                               <<02694>>04775000
       ioq'qmisc.peject:= 1;                                   <<06723>>04780000
         goto startprint;                                               04785000
       end                                                              04790000
                                                                        04795000
                                                                        04800000
     else  if fcode=fopen or fcode=fclose then                          04805000
       begin                                                            04810000
         if ditp(dsave).(full':2) = 1 then                     <<02695>>04815000
           goto printdone;  << empty buffer & already at top >><<02695>>04820000
         ditp(dsave).full := 0;  << set buffer empty >>        <<02695>>04825000
       ioq'qmisc.peject:= 1;   <<set page eject flag >>        <<06723>>04830000
         siop(postjmp) := 0;                                   <<01367>>04835000
         siop(post'ctl) := %100;  << skip to top of page >>    <<01367>>04840000
         goto startprint;                                      <<01367>>04845000
       end                                                              04850000
                                                                        04855000
          << check for fwrite  (fcode = 1) >>                           04860000
   else if fcode = 1 then                                               04865000
     begin                                                              04870000
                                                                        04875000
                                                                        04880000
     if ditp(dsave).(prespace':2)= 3 and not ioq'parm2 then    <<06723>>04885000
       begin                                                            04890000
         siop(prejmp) := 0;                                             04895000
         if ioq'parm2.stepover then  << no auto eject >>       <<06723>>04900000
           siop(pre'ctl) := 1  << single space w/o stepover >> <<02695>>04905000
         else  << auto page eject >>                           <<02695>>04910000
         siop(pre'ctl) := %102;         << issue single space with >>   04915000
         ioq'qmisc.pre'to'post:= 1; << stepover to clr buff >> <<06723>>04920000
       end;                                                             04925000
                                                                        04930000
     tos:= ioq'count;                                          <<06723>>04935000
     if < then             << byte count >>                             04940000
       count := -tos         << make positive >>                        04945000
     else                  << word count >>                             04950000
       count := tos&asl(1);  << change to byte count >>                 04955000
                                                                        04960000
     if ioq'parm1= 1 then  << imbedded control >>              <<06723>>04965000
       begin                                                            04970000
         if count = 0 then    << invalid operation >>                   04975000
           begin                                                        04980000
             tos := invalidop;                                          04985000
             goto iodone;                                               04990000
           end;                                                         04995000
         tos := buffaddrd;    << load bank and buff address >>          05000000
         loadmemory;             << load first word >>                  05005000
         param := tos&lsr(8);    << isolate and save control param >>   05010000
         count := count - 1;     << decrement byte count >>             05015000
       end                                                              05020000
     else                      << control in param word >>              05025000
       param:= ioq'parm1;                                      <<06723>>05030000
                                                                        05035000
     ditp(dsave).prespace:= if ioq'parm2                       <<06723>>05040000
       then 1 else 0;                 << set prespace flag >>           05045000
                                                                        05050000
                                                                        05055000
        << initialize print control byte >>                             05060000
                                                                        05065000
     if ioq'parm2.stepover then << single space no stepover >> <<06723>>05070000
       printctl := 1                                                    05075000
     else                           << single space with stepover >>    05080000
       printctl := %102;                                                05085000
                                                                        05090000
                                                                        05095000
        << setup print control byte >>                                  05100000
                                                                        05105000
     if param = "+" then            << suppress spacing >>              05110000
       printctl := 0                                                    05115000
                                                                        05120000
     else if param = "0" then       << double space >>                  05125000
       printctl := printctl + 1                                         05130000
                                                                        05135000
     else if param = "-" then       << triple space >>                  05140000
       printctl := printctl + 2                                         05145000
                                                                        05150000
     else if param = "1" then       << top of form >>                   05155000
       begin                                                            05160000
         if count=0 and ditp(dsave).(full':2)=1 then                    05165000
           goto printdone;  << empty buffer and already at top >>       05170000
         printctl := %100;                                              05175000
         ioq'qmisc.peject:= 1;  << set page eject flag >>      <<06723>>05180000
       end                                                              05185000
                                                                        05190000
     else if %200 <= param <= %277 then  << slew n lines >>             05195000
       printctl := param - %200                                         05200000
                                                                        05205000
     else if %300 <= param <= %307 then  << select channel n >>         05210000
       printctl := param - %200                                         05215000
                                                                        05220000
     else if param = %320 then      << buffer fill only >>              05225000
       begin                                                            05230000
         printctl := -1;                                                05235000
         if ioq'qmisc.pre'to'post= 0 and count= 0 then         <<06723>>05240000
           goto printdone;                                              05245000
       end;                                                             05250000
                                                                        05255000
                                                                        05260000
<<  setup channel program for buffer fill and print control  >>         05265000
                                                                        05270000
  printsetup:                                                           05275000
     if printctl >= 0 then    << setup print control >>                 05280000
       begin                                                            05285000
         ditp(dsave).full := 0;                                         05290000
         if ditp(dsave).prespace=1 then    << prespace >>               05295000
           begin                                                        05300000
             siop(prejmp) := 0;                                         05305000
             siop(pre'ctl) := printctl;                                 05310000
           end                                                          05315000
         else                              << post-space >>             05320000
           begin                                                        05325000
             siop(postjmp) := 0;                                        05330000
             siop(post'ctl) := printctl;                                05335000
           end;                                                         05340000
       end;                                                             05345000
                                                                        05350000
                                                                        05355000
     if count <> 0 then        << setup buffer fill >>                  05360000
       begin                                                            05365000
         siop(buffjmp) := 0;                                            05370000
         siop(bcount) := count;                                         05375000
         siop(memx).(8:8) := bank;                                      05380000
         siop(memx).lrbit:= if ioq'parm1= 1 << imbed control >><<06723>>05385000
           then 1 else 0;               << start with right byte >>     05390000
         siop(baddr) := buffaddr;                                       05395000
         ditp(dsave).full := if ditpl(dsave).prespace                   05400000
           then 1 else 0;    << if prespacing indicate buff is full >>  05405000
       end;                                                             05410000
                                                                        05415000
                                                                        05420000
                                                                        05425000
<<  start channel program  >>                                           05430000
                                                                        05435000
  startprint:                                                           05440000
     cpvap := 0;                << clear channel status word >>         05445000
     siop(dsj'rb1) := 7;        << init 1st dsj return byte >> <<01367>>05450000
     siop(status) := 0;         << clear cp status word >>              05455000
                                                                        05460000
     start'hpib(ditp,siop,true);   << start channel program >> <<01301>>05465000
printcont:                                                     <<01201>>05470000
     if < then      << sio failure >>                                   05475000
       begin                                                            05480000
         tos := siofail;                                                05485000
         goto badio;                                                    05490000
       end;                                                             05495000
                                                                        05500000
     ioq'qmisc.waitcode:= cmpltionwait; << set request state >><<06723>>05505000
     ditp(dtime) := 0;                                         <<01301>>05510000
     ditp(drqst) := timereq(iotimer,@ditp,4000d);              <<01301>>05515000
     lpdrvr := intrptwait;                                              05520000
     return;                                                            05525000
                                                                        05530000
                                                                        05535000
     end      << of write logic (function code = 1) >>                  05540000
                                                                        05545000
                                                                        05550000
                                                                        05555000
   else if fcode = %17 then                                    <<01201>>05560000
     begin   << perform read status >>                         <<01201>>05565000
       if count = 0 then << single status minimum >>           <<01201>>05570000
         begin   << invalid request >>                         <<01201>>05575000
           tos := invalidop;                                   <<01201>>05580000
           go to badio;                                        <<01201>>05585000
         end;                                                  <<01201>>05590000
       tos:= ioq'count;                                        <<06723>>05595000
       if < then  << byte count >>                             <<01201>>05600000
         count := -tos  << make positive >>                    <<01201>>05605000
       else                                                    <<01201>>05610000
         count := tos&asl(1); << change to byte cnt >>         <<01201>>05615000
       if count > 1 then count := 1;  << max avail >>          <<01201>>05620000
                                                               <<01201>>05625000
       siop(scount) := count;  << status byte count >>         <<01201>>05630000
       siop(sbank).(8:8) := bank;                              <<01201>>05635000
       siop(statadr) := buffaddr;                              <<01201>>05640000
       start'hpib(ditp,statsiop,false);  << start cp >>        <<01367>>05645000
       go to printcont;                                        <<01201>>05650000
                                                               <<01201>>05655000
                                                               <<01201>>05660000
     end  << of read status (function code = %17) >>           <<01201>>05665000
                                                               <<01201>>05670000
                                                               <<01201>>05675000
                                                               <<01201>>05680000
   else  if fcode = %100 then                                           05685000
     begin   << set vfc processing >>                                   05690000
       tos:= ioq'parm1;                                        <<06723>>05695000
       if 0<s0 and s0<5 then tos := tos + %24                           05700000
       else if s0=8 then tos := tos + %22                               05705000
       else if tos=12 then tos := %24                                   05710000
       else tos := %31;                                                 05715000
                                                                        05720000
       siop(pre'ctl) := tos;    << set request into control buff >>     05725000
       siop(prejmp) := 0;                                               05730000
       siop(wrtctl1).cmd := 2;  << set write control to vfc command>>   05735000
       goto startprint;                                                 05740000
                                                                        05745000
                                                                        05750000
     end  << of set vfc logic (function code = %100) >>                 05755000
   else       << fall through  >>                                       05760000
                                                                        05765000
                                                                        05770000
$page                                                                   05775000
                                                                        05780000
  printdone:                                                            05785000
     tos := goodio;                                                     05790000
                                                                        05795000
  iodone:                                                               05800000
     ioq'stat:= tos;  << store return status >>                <<06723>>05805000
                                                               <<02695>>05810000
  exit:                                                        <<02695>>05815000
     lpdrvr := requestdone;                                             05820000
     return;                                                            05825000
                                                                        05830000
  chanerror:                                                            05835000
     tos := chanfail;                                                   05840000
     ditp(dserr):= [8/1,8/dlogerror];                          <<01348>>05845000
     ditp(dlogerror) := cpvap;    <<log error status>>         <<01348>>05850000
                                                                        05855000
  badio:                                                                05860000
     ditp(dsave) := 0;    << clear driver flags >>                      05865000
     masterclearhpib(ditp);                                    <<01301>>05870000
     goto iodone;                                                       05875000
                                                                        05880000
                                                                        05885000
                                                                        05890000
<<  line printer continuator section  >>                                05895000
                                                                        05900000
  lpcont:                                                               05905000
     if cpvap.errorcode = 6 then   << dma abort >>                      05910000
       goto chanerror;                                                  05915000
                                                                        05920000
     if cpvap.errorcode = 7 then   << channel abort >>                  05925000
       begin                                                            05930000
         if cpvap.timedout = 0 then   << bad channel >>                 05935000
           goto chanerror;                                              05940000
                                                                        05945000
         tos:= ioq'qmisc.toutcntr+1;  << timed-out counter >>  <<06723>>05950000
         if s0 > 3 then      << channel failure >>                      05955000
           goto chanerror                                               05960000
         else                                                           05965000
         ioq'qmisc.toutcntr:= tos;    << update counter >>     <<06723>>05970000
         goto startprint;                                               05975000
       end;                                                             05980000
                                                                        05985000
     if ioq'sfail then  << failure on delayed start i/o >>     <<06723>>05990000
       begin                                                            05995000
         tos := siofail;                                                06000000
         goto badio;                                                    06005000
       end;                                                             06010000
                                                                        06015000
     ditp(dtime).(0:1) := 0;                                   <<01301>>06020000
     if <> then   << timer popped >>                                    06025000
       begin                                                            06030000
                                                                        06035000
   lpnotready:                                                          06040000
         if iomessage(1,if siopl(status).paperout then paperoutmsg else 06045000
               notrdymsg,%10000,ditp(dldev),,,,,opconsole) then<<06723>>06050000
           begin                                                        06055000
             start'hpib(ditp,idlesiop,false);                  <<01301>>06060000
             if < then                                                  06065000
               begin                                                    06070000
                 tos := siofail;                                        06075000
                 goto badio;                                            06080000
               end;                                                     06085000
             ioq'qmisc.waitcode:= notrdywait;<< set req state>><<06723>>06090000
             lpdrvr := notready;                                        06095000
             return;                                                    06100000
           end;                                                         06105000
                                                                        06110000
         tos := syserror;   << indicate failure because there >>        06115000
         goto badio;        << are no message link buffers >>           06120000
       end;                                                             06125000
                                                                        06130000
     if fcode=%17 then  << if status read - done >>            <<01201>>06135000
       go to printdone;                                        <<01201>>06140000
                                                               <<01201>>06145000
     if cpvap(1).(14:2) = 2 then   << status diagnosis is required >>   06150000
       begin                                                            06155000
         if siop(status).rdybit = 0 then  << unit notready >>           06160000
           begin                                               <<01493>>06165000
             if siop(status).pon = 1 then                      <<01493>>06170000
             ioq'qmisc.pondone:= 1;  << pon occured >>         <<06723>>06175000
             goto lpnotready;                                  <<01493>>06180000
           end;                                                <<01493>>06185000
                                                                        06190000
         if siopl(status).paperout then  << unit out of paper >>        06195000
           begin                                               <<01493>>06200000
             if siop(status).pon = 1 then                      <<01493>>06205000
             ioq'qmisc.pondone:= 1;  << pon occured >>         <<06723>>06210000
             goto lpnotready;                                  <<01493>>06215000
           end;                                                <<01493>>06220000
                                                                        06225000
         if siop(status).pon = 1 then  << unit has just powered up >>   06230000
 poninit:                                                      <<01493>>06235000
           begin                                                        06240000
             start'hpib(ditp,initsiop,true);                   <<01301>>06245000
             if < then                                                  06250000
               begin                                                    06255000
                 tos := siofail;                                        06260000
                 goto badio;                                            06265000
               end;                                                     06270000
             ioq'qmisc.waitcode:= initiowait;                  <<06723>>06275000
             lpdrvr := intrptwait;                                      06280000
             return;                                                    06285000
           end;                                                         06290000
                                                                        06295000
         if siop(status).parityerr = 1 then                             06300000
           begin                                                        06305000
             ditp(dserr):= [8/1,8/dlogerror];                  <<01348>>06310000
             ditp(dlogerror) := parityerror;   <<log error>>   <<01348>>06315000
             goto startprint;                                           06320000
           end;                                                         06325000
                                                               <<01367>>06330000
  restart:                                                     <<01367>>06335000
         if fcode=1 then  << restart incomplete operation >>   <<01367>>06340000
           begin                                               <<01367>>06345000
           if siop(bcount)<>0 then  << burst cnt expired >>    <<01367>>06350000
             begin  << restart fill buf for pre & post space >><<01367>>06355000
             tos:= ioq'count;  << get total count >>           <<06723>>06360000
             if < then  << byte count >>                       <<01367>>06365000
               count := -tos  << make positive >>              <<01367>>06370000
             else  << word count >>                            <<01367>>06375000
               count := tos&asl(1);  << change to byte count >><<01367>>06380000
             siop(memx).(8:8) := bank;  << reset bank & adr >> <<01367>>06385000
             siop(baddr) := buffaddr+  << add offset to adr >> <<01367>>06390000
               (count-siop(bcount))/2;  << make wrd cnt >>     <<01367>>06395000
             start'hpib(ditp,fillsiop,false);                  <<01367>>06400000
             go to printcont;                                  <<01367>>06405000
             end;                                              <<01367>>06410000
                                                               <<01367>>06415000
           if siop(pcount)<>0 then  << postspace prt done? >>  <<01367>>06420000
             begin  << restart postspace operation >>          <<01367>>06425000
             start'hpib(ditp,postsiop,false);                  <<01367>>06430000
             go to printcont;                                  <<01367>>06435000
             end;                                              <<01367>>06440000
           end;                                                <<01367>>06445000
       end;                                                             06450000
                                                                        06455000
     ditp(dsave).top:= ioq'qmisc.peject;<<set top if pe done>> <<06723>>06460000
                                                                        06465000
                                                                        06470000
     go to printdone;    << got here - request completed >>    <<01367>>06475000
                                                                        06480000
   end;                                                                 06485000
$page                                                                   06490000
   assemble(                                                            06495000
     pcal siodm;     << monitor >>                                      06500000
     pcal lpdrvr;    << initiator >>                                    06505000
     pcal lpdrvr;    << completor >>                                    06510000
     con  0;         << no io process >>                                06515000
     pcal lpinit;    << initialization >>                               06520000
     con  1;         << one interrupt handler >>                        06525000
     pcal gip'hpib); << interrupt handler >>                   <<01301>>06530000
   end.                                                                 06535000
