<< LINES .001/.009 ARE RESERVED FOR SYSTEMS INTEGRATION>>               00005000
$control map,code,uslinit                                               00010000
<< measio - module 88 >>                                                00015000
<< hp32033c 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
$control  list, segment=mio'segment                                     00055000
                                                                        00060000
                                                                        00065000
<<**********************************************************************00070000
                                                                        00075000
             measurement i/o system                                     00080000
                                                                        00085000
                                                                        00090000
                                                                        00095000
declaration:                                                            00100000
                                                                        00105000
   integer procedure measio(ldev,fcode,bank,addr,count);                00110000
      value ldev, fcode, bank, addr, count;                             00115000
      integer ldev, fcode, bank, addr, count;                           00120000
      option privileged, uncallable, external;                          00125000
                                                                        00130000
                                                                        00135000
function:                                                               00140000
                                                                        00145000
   measio is a self contained, core resident i/o system used by         00150000
   various performance measurement subsystems (monitor, sampler,        00155000
   tracer, etc.) to write data to magnetic tape.  generally speak-      00160000
   ing, it is independent of, and unknown to mpe in order to min-       00165000
   imize the effects of the measurement subsystems on the system's      00170000
   operation.                                                           00175000
                                                                        00180000
                                                                        00185000
parameters:                                                             00190000
                                                                        00195000
   ldev     the logical device number of the tape drive.                00200000
                                                                        00205000
   fcode    the function to be performed:                               00210000
                                                                        00215000
            0 -- read status                                            00220000
            1 -- write data                                             00225000
            2 -- write file mark                                        00230000
            3 -- rewind                                                 00235000
            4 -- rewind/unload                                          00240000
                                                                        00245000
   bank     the bank number of the data to be written.                  00250000
                                                                        00255000
   addr     the absolute address of the data to be written.             00260000
                                                                        00265000
   count    the amount of data to be written:                           00270000
            >0 => word count     <0 => byte count                       00275000
            the maximum count allowed is 16383 words or 32766 bytes.    00280000
                                                                        00285000
                                                                        00290000
condition codes and returned values:                                    00295000
                                                                        00300000
   cce      condition code cce indicates that the previous request      00305000
            (if any) has been completed successfully and the cur-       00310000
            rent request has been started.  the returned value will     00315000
            be zero for all functions except read status which will     00320000
            return the following information obtained from the hard-    00325000
            ware status word:                                           00330000
                                                                        00335000
             bits     meaning                                           00340000
                                                                        00345000
            (0:12) -- not used                                          00350000
            (12:1) -- end of tape (eot)                                 00355000
            (13:1) -- write protect                                     00360000
            (14:1) -- ready (on line)                                   00365000
            (15:1) -- load point (bot)                                  00370000
                                                                        00375000
   ccg      condition code ccg is identical to cce except that it       00380000
            also indicates that the tape's eot reflective spot has      00385000
            been passed.                                                00390000
                                                                        00395000
   ccl      condition code ccl indicates that an error has occured.     00400000
            the returned value indicates the type of error:             00405000
                                                                        00410000
            1 -- ldev is invalid or not enabled.                        00415000
            2 -- fcode is invalid or count is too large.                00420000
            3 -- an irrecoverable error has occured.                    00425000
            4 -- fcode is something other than read status but the      00430000
                 tape drive is not ready.                               00435000
            5 -- fcode is write data or write file mark but there       00440000
                 is no write ring.                                      00445000
                                                                        00450000
            error codes 1 and 2 indicate an invalid parameter; the      00455000
            status of the previous request has not been checked         00460000
            and the current request is rejected.  error code 3          00465000
            indicates that an irrecoverable error has occured on a      00470000
            previous request; the current request was not started.      00475000
            once an irrecoverable error has occured, the only fun-      00480000
            tions that will be accepted are read status and rewind      00485000
            unload.  a successful rewind & reset request will clear     00490000
            the irrecoverable error.  a new tape should be mounted      00495000
            and the drive made ready.  error codes 4 and 5 indicate     00500000
            that the previous request has been completed successfully   00505000
            but the current request was not started.                    00510000
                                                                        00515000
                                                                        00520000
comments:                                                               00525000
                                                                        00530000
   measio must be called with db set to sysdb.                          00535000
                                                                        00540000
   for write data requests, it is the caller's responsibility to        00545000
   freeze the data.  the data must not be altered or unfrozen           00550000
   until a subsequent request indicates that the i/o has been           00555000
   completed successfully or an irrecoverable error has occured.        00560000
                                                                        00565000
   measio requires the exclusive use of the specified tape drive        00570000
   and its controller.  in order to avoid conflicts with mpe, it        00575000
   must be enabled with a console command that puts all drives on       00580000
   the controller (including measio's drive) in the down state and      00585000
   properly initializes the drt, dit, and sio program area.  an-        00590000
   other console command is used to disable measio and reset the        00595000
   tables for normal mpe operation.                                     00600000
                                                                        00605000
   since read status requests require running an sio program, they      00610000
   should not be issued capriciously.  in most applications, the        00615000
   status is only checked before the first i/o request and after        00620000
   a new tape is mounted.                                               00625000
                                                                        00630000
   for a variety of performance related reasons, it is preferable       00635000
   to call measio with the interrupt system enabled.  it may, how-      00640000
   ever, be called with the interrupt system enabled or disabled.       00645000
   measio will not enable the interrupt system if it was called         00650000
   while the system was disabled.                                       00655000
                                                                        00660000
note:  if measio is called from an interrupt processor, the inter-      00665000
   rupt system should be disabled.  otherwise, measio could loop,       00670000
   waiting for an interrupt, at a time when the interrupt priority      00675000
   poll prevents the tape controller from interrupting.                 00680000
                                                                        00685000
**********************************************************************>>00690000
$page "     MEASUREMENT I/O SYSTEM -- OPERATION ON THE SERIES 33"       00695000
<<**********************************************************************00700000
                                                                        00705000
             operation on the series 33                                 00710000
                                                                        00715000
                                                                        00720000
                                                                        00725000
   measio uses a portion of its tape drive's dit and sio program        00730000
   area for global data; the words used, their significance, and        00735000
   their initial values are:                                            00740000
                                                                        00745000
   mio'enable  dit(8)   a flag word containing "OK" (%47513) to         00750000
                        indicate that measio is enabled for some        00755000
                        unit on this controller.                        00760000
                                                                        00765000
   mio'state   dit(9)   current device state:                           00770000
                       -1 -- irrecoverable error                        00775000
                        0 -- no activity                                00780000
                        1 -- i/o in progress                            00785000
                        2 -- backspace record for retry                 00790000
                        3 -- tape gap for retry                         00795000
                        4 -- wait for rewind completion                 00800000
                        initialized to zero.                            00805000
                                                                        00810000
   mio'retry   dit(10)  number of retries for this request.             00815000
                        initialized to zero.                            00820000
                                                                        00825000
   mio'ldev    sio(75).(0:4)  downed unit flags.                        00830000
                      .(8:8)  the logical device number that            00835000
                              has been enabled for measio.              00840000
                                                                        00845000
   mio'unit    sio(95)  the unit number + 1 of the measio tape          00850000
                                                                        00855000
   mio'status  sio(99)  last known hardware status.                     00860000
                        initialized to zero.                            00865000
                                                                        00870000
   mio'fcode   sio(101) /                                               00875000
                        |                                               00880000
   mio'bank    sio(102) |  saved parameters for retry.                  00885000
                        |                                               00890000
   mio'addr    sio(103) |  uninitialized.                               00895000
                        |                                               00900000
   mio'count   sio(104) \                                               00905000
                                                                        00910000
                                                                        00915000
   in addition to measio, the measurement i/o system includes five      00920000
   supporting procedures:                                               00925000
                                                                        00930000
   mio'initiator -- this procedure builds and starts the necessary      00935000
                    sio programs and updates mio'state.                 00940000
                                                                        00945000
   mio'completor -- this procedure checks the i/o completion status     00950000
                    and updates mio'state.  if necessary, it calls      00955000
                    mio'initiator to start a retry.                     00960000
                                                                        00965000
   mio'intrpt'proc -- this is the interrupt processor.  when an in-     00970000
                      terrupt is received from the measio tape con-     00975000
                      troller, it saves the hardware status and         00980000
                      calls mio'completor.                              00985000
                                                                        00990000
   mio'init -- this procedure initializes the drt, dit, and sio         00995000
               program area as required by the 3000 series 33           01000000
               measurement i/o system.  this procedure also halts the   01005000
               mag tape's idle channel program.                         01010000
                                                                        01015000
   mio'reset -- this procedure resets the drt, dit, and sio program     01020000
                area for normal use by the series 33 i/o system and     01025000
                it starts an idle channel program for the mag tape      01030000
                driver.                                                 01035000
                                                                        01040000
                                                                        01045000
   each time measio is called, it verifies that the logical device      01050000
   is valid and enabled and that the function is valid.  it then        01055000
   checks the previous request and waits for completion.  if measio     01060000
   was called with the interrupt system enabled, the wait loop is       01065000
   simply a test of mio'state; otherwise, the wait loop checks the      01070000
   drt to test for sio ready, followed by a call to mio'completor.      01075000
                                                                        01080000
   after waiting for the completion of any previous request, measio     01085000
   disables the interrupt system in order to prevent any recursive      01090000
   calls while the current request is being processed.  if the cur-     01095000
   rent request is read status, the hardware status is read and re-     01100000
   turned to the caller.  otherwise, the previous request is check-     01105000
   ed for an irrecoverable error.  if there has been no error,          01110000
   measio verifies the unit ready and write enable status and calls     01115000
   mio'initiator to start the current request.                          01120000
                                                                        01125000
                                                                        01130000
7970e hp-ib mag tape controller status                                  01135000
                                                                        01140000
  bits       meaning                                                    01145000
                                                                        01150000
    0    end of file                                                    01155000
                                                                        01160000
    1    beginning of tape                                              01165000
    2    end of tape                                                    01170000
    3    single track error                                             01175000
                                                                        01180000
    4    command reject                                                 01185000
    5    file protect                                                   01190000
    6    multiple track error                                           01195000
                                                                        01200000
    7    unit online                                                    01205000
    8    (not used)                                                     01210000
    9    unit number (msb)                                              01215000
                                                                        01220000
   10    unit number (lsb)                                              01225000
   11    timing error                                                   01230000
   12    tape error                                                     01235000
                                                                        01240000
   13    rewinding                                                      01245000
   14    unit busy                                                      01250000
   15    interface busy                                                 01255000
                                                                        01260000
**********************************************************************>>01265000
$page "     MEASUREMENT I/O SYSTEM -- CHANNEL PROGRAM"                  01270000
<<*************************************************************<<04118>>01275000
*                                                             *<<04118>>01280000
*                                                             *<<04118>>01285000
***************************************************************<<04118>>01290000
<<                                                                      01295000
                 7970e hp-ib channel program                            01300000
                                                                        01305000
the following is a listing of the 3000 series 33 mag tape driver        01310000
channel program for the 7970e hp-ib magnetic tape.  if any changes      01315000
are made to the mag tape driver's channel program, appropriate          01320000
changes must be made to the measio procedures.  the comments shown      01325000
are for the measio usage of the channel program.                        01330000
                                                                        01335000
                                                                        01340000
( 0)  write command     %2001,   select unit command                    01345000
( 1)                        1,                                          01350000
( 2)                        0,                                          01355000
( 3)                   %42000,                                          01360000
( 4)                        0,                                          01365000
                                                                        01370000
( 5)  wait              %1000,   wait for command completion            01375000
( 6)                        0,                                          01380000
                                                                        01385000
( 7)  dsj               %2401,   check mag tape's condition             01390000
( 8)                        0,                                          01395000
( 9)  dsj'cmdjmp            0,   jmp*+0/50, min cmd/rd xfer cnt         01400000
(10)                       43,   jmp *+43, read status                  01405000
                                                                        01410000
(11)  write command     %2001,   issue motion command                   01415000
(12)                        1,                                          01420000
(13)                        0,                                          01425000
(14)                   %42000,                                          01430000
(15)                        0,                                          01435000
                                                                        01440000
(16)  wait              %1000,   wait for command completion            01445000
(17)                        0,                                          01450000
                                                                        01455000
(18)  dsj               %2401,   check mag tape's condition             01460000
(19)                        0,                                          01465000
(20)                        0,   jmp*+0/25, rd/wrt data bypass          01470000
(21)                       32,   jmp *+32, read status                  01475000
                                                                        01480000
(22)  read/write data     %20,   read/write record command              01485000
(23)  bytecnt               0,                                          01490000
(24)  tdbl              %2000,   termination disp. *+4                  01495000
(25)  memx            %000000,   record mode                            01500000
(26)  baddr                 0,                                          01505000
(27)  jump                  0,   eoi received - xfer completed          01510000
(28)  eoi'jmp               2,     jmp *+2/12, read/write completion    01515000
(29)  jmp                   0,   burst completion exit                  01520000
(30)                      -15,     jmp *-15 to wait instruction         01525000
(31)  write end         %2007,   issue stop polling for data            01530000
                                                                        01535000
(32)                        1,                                          01540000
(33)                        0,                                          01545000
                                                                        01550000
(34)                   %42000,                                          01555000
(35)                        0,                                          01560000
                                                                        01565000
(36)  read count        %1402,   read transfer count to                 01570000
(37)                        2,   provided delay needed                  01575000
(38)                        0,   for reads - kludge                     01580000
(39)                    %2000,                                          01585000
(40)                        0,                                          01590000
                                                                        01595000
(41)  wait              %1000,   wait for operation completion          01600000
(42)                        0,                                          01605000
(43)  dsj               %2401,   check mag tape's condition             01610000
(44)                        0,                                          01615000
(45)                        0,   jmp *+0, unit ok                       01620000
                                                                        01625000
(46)                        7,   jmp *+7, read status                   01630000
(47)  read status       %1401,   read status byte                       01635000
                                                                        01640000
(48)                        3,                                          01645000
(49)                        0,                                          01650000
(50)                    %2000,                                          01655000
(51)                        0,                                          01660000
                                                                        01665000
(52)  int/hlt            %601,   interupt/halt, halt code =0            01670000
(53)                        0,   status check not required              01675000
(54)  read status       %1401,   read status bytes                      01680000
(55)                        3,                                          01685000
(56)                        0,                                          01690000
                                                                        01695000
(57)                    %2000,                                          01700000
(58)                        0,                                          01705000
                                                                        01710000
(59)  int/hlt            %601,   interupt/halt, halt code =1            01715000
(60)                        1,   status check required                  01720000
(61)  read count        %1402,   read transfer count                    01725000
(62)                        2,                                          01730000
(63)                        0,                                          01735000
                                                                        01740000
(64)  memx'rc           %2000,                                          01745000
(65)                        0,                                          01750000
                                                                        01755000
(66)  jmp                   0,   jump back to dsj instruction           01760000
(67)                      -25,                                          01765000
(68)  write end         %2007,   issue end command                      01770000
(69)                        1,   idle channel program                   01775000
(70)                        0,                                          01780000
                                                                        01785000
(71)                   %42000,                                          01790000
(72)                        0,                                          01795000
                                                                        01800000
                                                                        01805000
                                                                        01810000
(73)  wait              %1000,   wait for mt to poll                    01815000
(74)                        0,                                          01820000
(75)  dsj               %2400,   clear any pending dsj's                01825000
(76)                        0,                                          01830000
(77)                        0,                                          01835000
                                                                        01840000
(78)  read status       %1401,   read status to ilt                     01845000
(79)                        3,                                          01850000
                                                                        01855000
(80)                        0,                                          01860000
(81)                    %2000,                                          01865000
(82)                        0,                                          01870000
                                                                        01875000
(83)  int/hlt            %601,   interupt/halt, halt code =0            01880000
(84)                        0,                                          01885000
(85)  write end         %2007,   issue end command                      01890000
(86)                        1,                                          01895000
(87)                        0,                                          01900000
                                                                        01905000
(88)                   %42000,                                          01910000
(89)                        0,                                          01915000
                                                                        01920000
                                                                        01925000
(90)  dsj               %2400,   clear any pending dsj's                01930000
(91)                        0,                                          01935000
(92)                        0,                                          01940000
(93)  int/hlt            %601,                                          01945000
(94)                        0,                                          01950000
(95)  storage(scltunit)     0,   select command unit number             01955000
(96)  cmdword               0,   motion command word                    01960000
(97)                      %23,   stop polling for data command          01965000
(98)                      %25,   end command                            01970000
(99)                        0,   status buffer area                     01975000
(100)                       0,                                          01980000
(101)                       0,   6 byte short read buffer               01985000
(102)                       0,                                          01990000
(103)                       0,                                          01995000
(104)                       0,   dummy buffer                           02000000
(105)                     %63;   abort end command                      02005000
                                                                        02010000
***************************************************************<<04118>>02015000
*************************************************************>><<04118>>02020000
$page "     MEASUREMENT I/O SYSTEM -- MEASIO"                           02025000
begin                                                                   02030000
    << measio global equates and defines >>                             02035000
                                                                        02040000
equate                                                                  02045000
  ccg         =     0,  << greater than condition code >>               02050000
  ccl         =     1,  << less than codition code >>                   02055000
  cce         =     2,  << equals condition code >>                     02060000
  cmdword     =    96,   << siop, motion command word >>       <<04118>>02065000
  diltp       =     5,  << dit, interrupt linkage table pointer >>      02070000
  dldev       =    10,   <<dit,contains controller unit number>><<mpev>>02075000
  drtsize     =     4,  << length of drt entry >>                       02080000
  dsj'cmdjmp  =     9,  << sio, command switch >>                       02085000
  dsj'rwjmp   =    20,  << sio, write data bypass switch >>             02090000
  icntrl      =     7,  << ilt, contains drt number in bits 8:8 >>      02095000
  iditp0      =    14,  << ilt, pointer to dit 0 >>                     02100000
  iflag       =    13,  << ilt, flag word >>                            02105000
  isiop       =     8,  << ilt, channel program area pointer >>         02110000
  lr          =    17,   << storage for interrupt interval >>  <<01185>>02115000
  sysdb       = %1000,  << location of sysdb >>                         02120000
endeq         =     0;                                                  02125000
                                                                        02130000
  equate   lpdt'ent'size = 4 ,                                  <<mpev>>02135000
           dit'offset    = 2 ;                                  <<mpev>>02140000
                                                                        02145000
define                                                                  02150000
  asmb        = assemble#,                                              02155000
  disable     = asmb(sed 1)#,                                           02160000
  idrtn       = ( 7:9)#,   << 9 bit drt number in ilt >>       <<04850>>02165000
  enable      = asmb(sed 0)#,                                           02170000
  siopg       = con %20302;con 0#,                                      02175000
  cc          = status.(6:2)#,                                 <<01185>>02180000
  ignorehi    = ( 2:1)#,   << ilt, ignore interrupt flag >>             02185000
  eot         = ( 2:1)#,   << end of tape status bit >>                 02190000
  fileprtct   = ( 5:1)#,   << file protect status bit >>                02195000
  ldpoint     = ( 1:1)#,   << load point status bit >>                  02200000
  online      = ( 7:1)#,   << online status bit >>                      02205000
  unit'field  = ( 8:8)#,   << unit field in dit >>              <<mpev>>02210000
  lmio'status = logical(siop(99))#,                            <<04118>>02215000
  mio'addr    = siop(103)#,<< storage of user buffer address >><<04118>>02220000
  mio'bank    = siop(102)#,<< storage of user bank address >>  <<04118>>02225000
  mio'count   = siop(104)#,<< storage of buffer length >>      <<04118>>02230000
  mio'enable  = ditp(8)#,  << measio flag word >>                       02235000
  mio'fcode   = siop(101)#,<< function request code >>         <<04118>>02240000
  mio'ldev    = siop(65)#, << logical device number >>         <<04118>>02245000
  mio'retry   = ditp(10)#, << retry counter >>                          02250000
  mio'state   = ditp(9)#,  << current process state >>                  02255000
  mio'status  = siop(99)#, << current mag tape status >>       <<04118>>02260000
  mio'unit    = siop(95)#, << mag tape unit number plus one >> <<04118>>02265000
  abs         = absolute#,                                     <<01185>>02270000
  trapoff     = push(status);                                  <<01185>>02275000
                tos.(2:1) := 0;                                <<01185>>02280000
                set(status)#,                                  <<01185>>02285000
  pdisable    = asmb(psdb)#,                                   <<01185>>02290000
  penable     = asmb(pseb)#,                                   <<01185>>02295000
  waitprog    = ( 1:1)#,   << wait pgm running flag in ilt >>  <<04850>>02300000
enddef        = 0#;                                                     02305000
                                                                        02310000
  integer status=q-1, s0=s-0, x=x;                             <<01185>>02315000
  integer pointer csti=1, dsti=2, lpdt=db+%10;                 <<01185>>02320000
$page                                                                   02325000
     << procedure declarations >>                                       02330000
                                                               <<04850>>02335000
procedure awakeio(ditp,flags);                                 <<04850>>02340000
  value flags;                                                 <<04850>>02345000
  array ditp;                                                  <<04850>>02350000
  logical flags;                                               <<04850>>02355000
  option external;                                             <<04850>>02360000
                                                                        02365000
                                                               <<04850>>02370000
integer procedure getdrt(drtn,offset);                         <<04850>>02375000
  value drtn,offset;                                           <<04850>>02380000
  integer drtn,offset;                                         <<04850>>02385000
  option external;                                             <<04850>>02390000
                                                                        02395000
procedure mio'initiator(drt,ditp,siop,fcode,bank,addr,count);           02400000
  value  drt, ditp, siop, fcode, bank, addr, count;                     02405000
  integer  drt, fcode, bank, addr, count;                               02410000
  integer pointer  ditp, siop;                                          02415000
  option  forward;                                                      02420000
                                                                        02425000
procedure mio'completor(drt,ditp,siop);                                 02430000
  value  drt, ditp, siop;                                               02435000
  integer  drt;                                                         02440000
  integer pointer  ditp, siop;                                          02445000
  option  forward;                                                      02450000
                                                                        02455000
procedure mio'intrpt'proc;                                              02460000
  option  forward;                                                      02465000
                                                                        02470000
procedure mio'init(ldev);                                               02475000
  value  ldev;                                                          02480000
  integer  ldev;                                                        02485000
  option  forward;                                                      02490000
                                                                        02495000
integer procedure mio'reset(ldev);                                      02500000
  value  ldev;                                                          02505000
  integer  ldev;                                                        02510000
  option  forward;                                                      02515000
                                                                        02520000
procedure gip'hpib;                                            <<01301>>02525000
  option  privileged, uncallable, external;                             02530000
                                                                        02535000
procedure iofailure(drt,ditp);                                          02540000
  value  drt, ditp;                                                     02545000
  integer  drt;                                                         02550000
  integer pointer  ditp;                                                02555000
  option  privileged, uncallable, external;                             02560000
                                                                        02565000
procedure putdrt(drtn,offset,dta);                             <<04850>>02570000
  value drtn,offset,dta;                                       <<04850>>02575000
  integer drtn,offset;                                         <<04850>>02580000
  logical dta;                                                 <<04850>>02585000
  option external;                                             <<04850>>02590000
                                                               <<04850>>02595000
procedure start'hpib(ditp,siop,qflag);                         <<01301>>02600000
  value  ditp, siop, qflag;                                             02605000
  logical  qflag;                                                       02610000
  integer pointer  ditp, siop;                                          02615000
  option  privileged, uncallable, external;                             02620000
                                                                        02625000
procedure halt'hpib(ditp);                                     <<01301>>02630000
  value  ditp;                                                          02635000
  integer pointer  ditp;                                                02640000
  option  privileged, uncallable, external;                             02645000
                                                               <<04850>>02650000
procedure wioc'hpib(cmd,channel,device);                       <<04850>>02655000
value cmd,channel,device;                                      <<04850>>02660000
integer cmd,channel,device;                                    <<04850>>02665000
option external;                                               <<04850>>02670000
$page                                                          <<04850>>02675000
<< this procedure gets drt into a known state >>               <<04850>>02680000
procedure quiesce'drt(drt);                                    <<04850>>02685000
value drt;                                                     <<04850>>02690000
integer drt;                                                   <<04850>>02695000
option internal,privileged;                                    <<04850>>02700000
begin                                                          <<04850>>02705000
                                                               <<04850>>02710000
disable;                                                       <<04850>>02715000
<< first, kill the channel program (if any) >>                 <<04850>>02720000
tos := drt;                                                    <<04850>>02725000
assemble(con %20302;con %1);  << hiop instruction >>           <<04850>>02730000
                                                               <<04850>>02735000
<< loop until it actually stops >>                             <<04850>>02740000
loop:                                                          <<04850>>02745000
                                                               <<04850>>02750000
if getdrt(drt,3) <> 0 then                                     <<04850>>02755000
  go to loop;                                                  <<04850>>02760000
                                                               <<04850>>02765000
<< clear any pending interrupts on device >>                   <<04850>>02770000
tos := %006000;   << write register "C" on gic >>              <<04850>>02775000
tos := drt;                                                    <<04850>>02780000
tos := logical(drt) land %7;  << device number >>              <<04850>>02785000
wioc'hpib(*,*,*);   << issue command >>                        <<04850>>02790000
                                                               <<04850>>02795000
end;                                                           <<04850>>02800000
$page                                                                   02805000
integer procedure measio(ldev,fcode,bank,addr,count);                   02810000
  value  ldev, fcode, bank, addr, count;                                02815000
  integer  ldev, fcode, bank, addr, count;                              02820000
  option  privileged, uncallable;                                       02825000
begin                                                                   02830000
                                                                        02835000
  integer  rtnstat=q-1;                                                 02840000
  integer cpu'number, drt, s0=s-0;                             <<04850>>02845000
  double counter,olddb;                                        <<04850>>02850000
  integer pointer  ditp, siop, iltp;                                    02855000
  define  intrpts'enabled = logical(tos.(1:1))#;                        02860000
  equate  maxcount = 32766;                                             02865000
                                                                        02870000
                                                                        02875000
                                                                        02880000
  subroutine wait'for'io;                                               02885000
    begin                                                               02890000
      while mio'state>0 do                                              02895000
        begin                                                           02900000
          push(status);                                                 02905000
          if intrpts'enabled then   << sit tight >>                     02910000
          else                                                          02915000
            begin                                                       02920000
                                                               <<04850>>02925000
              tos := getdrt(drt,3);  << get 4th word of drt >> <<04850>>02930000
                                                               <<04850>>02935000
              if tos.(0:2)=0 then   << i/o program completed >>         02940000
                mio'completor(drt,ditp,siop);  << call completor >>     02945000
            end;                                                        02950000
        end;                                                            02955000
    end;                                                                02960000
                                                                        02965000
                                                                        02970000
                                                                        02975000
     << procedure entry point >>                                        02980000
                                                               <<04850>>02985000
  << set db to sysdb >>                                        <<04850>>02990000
  pdisable;                                                    <<04850>>02995000
  tos := 0;                                                    <<04850>>03000000
  tos := sysdb;                                                <<04850>>03005000
  asmb(xchd);                                                  <<04850>>03010000
  olddb := tos;                                                <<04850>>03015000
                                                                        03020000
  if not (1 <= ldev <= lpdt(0)) then    << bad ldev >>          <<mpev>>03025000
bad'ldev:                                                               03030000
    begin                                                               03035000
      measio := 1;   << return invalid ldev indicator >>                03040000
bad'exit:                                                               03045000
      tos := olddb;                                            <<04850>>03050000
      asmb(xchd);                                              <<04850>>03055000
      penable;                                                 <<04850>>03060000
      cc := ccl;    << set return condition code to failure >> <<01185>>03065000
      return;                                                           03070000
    end;                                                                03075000
                                                                        03080000
  @ditp := lpdt (( ldev*lpdt'ent'size)+dit'offset);<<dit ptr>>  <<mpev>>03085000
  if < then goto bad'ldev;                                              03090000
                                                                        03095000
  @iltp := ditp(diltp);    << setup ilt pointer >>                      03100000
  @siop := iltp(isiop);    << setup sio pointer >>                      03105000
                                                                        03110000
  if mio'enable <> "OK" or    << check for measio enabled >>            03115000
    ldev <> mio'ldev.(8:8) then goto bad'ldev;                          03120000
                                                                        03125000
  if not (0 <= fcode <= 4) then   << bad function code >>               03130000
    begin                                                               03135000
      measio := 2;   << return bad function code indicator>>            03140000
      goto bad'exit;                                                    03145000
    end;                                                                03150000
                                                                        03155000
  drt := iltp(icntrl).idrtn;  << extract drt number from ilt >><<04850>>03160000
                                                                        03165000
  wait'for'io;       << complete previous i/o >>                        03170000
                                                                        03175000
  disable;                                                              03180000
                                                                        03185000
  if fcode=0 or mio'status=0 then  << get unit's status >>              03190000
    begin                                                               03195000
      iltp(iflag).ignorehi := 1;  << set ignore interrupt flag >>       03200000
      siop(dsj'cmdjmp) := 36;     << set up cmd jmp switch >>  <<04118>>03205000
      << get cpu number >>                                     <<04850>>03210000
      assemble(pcn);                                           <<04850>>03215000
      cpu'number := tos;   << save cpu number >>               <<04850>>03220000
                                                               <<04850>>03225000
      << figure delay according to cpu type >>                 <<04850>>03230000
      if cpu'number = 4 then                                   <<04850>>03235000
        tos := 256000d         << series/64 >>                 <<04850>>03240000
      else if cpu'number = 3 then                              <<04850>>03245000
        tos := 128000d         << series/44 >>                 <<04850>>03250000
      else tos := 32000d;      << series/33 >>                 <<04850>>03255000
                                                               <<04850>>03260000
      counter := tos;                                          <<04850>>03265000
                                                               <<04850>>03270000
      quiesce'drt(drt);                                        <<04850>>03275000
      tos := drt;                                                       03280000
      tos := @siop+sysdb;                                               03285000
      asmb(ddup;siopg;bl*-3;be*+2;br*-5;ddel);                          03290000
waitloop:                                                               03295000
                                                               <<04850>>03300000
      tos := getdrt(drt,3);  << get 4th word of drt >>         <<04850>>03305000
                                                               <<04850>>03310000
      if tos.(0:2) <> 0 then   << i/o program not done >>               03315000
        begin                                                           03320000
          if (counter:=counter+1d)= 0d then                    <<04850>>03325000
            mio'state := -1   << fatal error >>                <<04850>>03330000
          else                                                 <<04850>>03335000
            go to waitloop;                                    <<04850>>03340000
        end;                                                            03345000
    end;                                                                03350000
                                                                        03355000
                                                                        03360000
  if fcode = 0 and mio'state <> -1 then << ret. hdwe status >> <<04850>>03365000
    begin                                                               03370000
      tos := 0;                                                         03375000
      if lmio'status.eot then tos.(12:1) := 1;  << eot >>               03380000
      if lmio'status.fileprtct then tos.(13:1) := 1;  << file protect >>03385000
      if lmio'status.online then tos.(14:1) := 1;  << unit online >>    03390000
      if lmio'status.ldpoint then tos.(15:1) := 1;  << load point >>    03395000
      measio := tos;    << return encoded status >>                     03400000
      goto good'exit;                                                   03405000
    end;                                                                03410000
                                                                        03415000
  if mio'state=-1 and fcode<4 then  << irrecoverable error state >>     03420000
    begin                                                               03425000
      measio := 3;  << return irrecoverable error indicator >>          03430000
      goto bad'exit;                                                    03435000
    end;                                                                03440000
                                                                        03445000
  if not lmio'status.online then  << unit not ready >>                  03450000
    begin                                                               03455000
      measio := 4;   << return unit not ready indicator >>              03460000
      goto bad'exit;                                                    03465000
    end;                                                                03470000
                                                                        03475000
  if lmio'status.fileprtct and fcode<3 then  << file protect error >>   03480000
    begin                                                               03485000
      measio := 5;   << return file protect indicator >>                03490000
      goto bad'exit;                                                    03495000
    end;                                                                03500000
                                                                        03505000
  measio := 0;                                                          03510000
                                                                        03515000
  if fcode=1 then   << perform count checks >>                          03520000
    begin                                                               03525000
      if count<0 then count := -count    << setup count as >>           03530000
      else count := count&lsl(1);        << positive bytes >>  <<04850>>03535000
      if count=0 then goto good'exit;                                   03540000
      if count>maxcount then                                            03545000
        begin                                                           03550000
          measio := 2;   << return invalid count indicator >>           03555000
          goto bad'exit;                                                03560000
        end;                                                            03565000
    end;                                                                03570000
                                                                        03575000
  mio'fcode := fcode;    << save parameters for retry >>                03580000
  mio'bank := bank;                                                     03585000
  mio'addr := addr;                                                     03590000
  mio'count := count;                                                   03595000
  mio'retry := 0;                                                       03600000
                                                                        03605000
  mio'initiator(drt,ditp,siop,fcode,   << start current request >>      03610000
                bank,addr,count);                                       03615000
                                                                        03620000
good'exit:                                                              03625000
  tos := olddb;                                                <<04850>>03630000
  asmb(xchd);                                                  <<04850>>03635000
  penable;                                                     <<04850>>03640000
  cc := if lmio'status.eot  then  ccg  else  cce;              <<01185>>03645000
end;                                                                    03650000
$page "     MEASUREMENT I/O SYSTEM -- INITIATOR"                        03655000
procedure mio'initiator(drt,ditp,siop,fcode,bank,addr,count);           03660000
  value  drt, ditp, siop, fcode, bank, addr, count;                     03665000
  integer  drt, fcode, bank, addr, count;                               03670000
  integer pointer  ditp, siop;                                          03675000
  option  privileged, uncallable, internal;                             03680000
begin                                                                   03685000
                                                                        03690000
  equate                                                                03695000
    bsrecordcmd = %12,                                                  03700000
    rewindcmd   = %15,                                                  03705000
    rewunldcmd  = %16,                                                  03710000
    tapegapcmd  =   7,                                                  03715000
    writecmd    =   5,                                                  03720000
    wrtfmarkcmd =   6,                                                  03725000
                                                                        03730000
    baddr1      =  26,                                                  03735000
    bytecnt1    =  23,                                                  03740000
    bytecnt2    =  28,                                                  03745000
    cmdword     =  96,                                         <<04118>>03750000
    memx1       =  25,                                                  03755000
    memx2       =  30,                                                  03760000
    rwdata      =  22,                                                  03765000
    tdbl1       =  24,                                                  03770000
    tdbl2       =  29;                                                  03775000
                                                                        03780000
  switch sw := bsrecord,readstat,writerec,writefmark,rewind,rwdunload;  03785000
                                                                        03790000
  if not (-1 <= fcode <= 4) then return;   << invalid function code >>  03795000
                                                                        03800000
  disable;                                                              03805000
                                                               <<04850>>03810000
  << get into known state before modifying channel pgm >>      <<04850>>03815000
  quiesce'drt(drt);                                            <<04850>>03820000
                                                                        03825000
  goto sw(fcode+1);   << branch to label >>                             03830000
                                                                        03835000
writerec:                                                               03840000
  siop(rwdata) := %2000;          << write command >>                   03845000
  siop(bytecnt1) := count;        << byte count >>                      03850000
  if count = 0 then assemble ( halt);                                   03855000
  siop(tdbl1) := 0;               << term disp >>              <<04118>>03860000
  siop(memx1) := bank + %20000;   << burst mode/no eot/bank >> <<04118>>03865000
  siop(baddr1) := addr;           << buffer address >>                  03870000
  siop(bytecnt2) := 12;           << setup eoi exit jump >>    <<04118>>03875000
  siop(tdbl2) := 0;               << setup burst completion >>          03880000
  siop(memx2) := -15;             <<   return jump          >>          03885000
  siop(dsj'rwjmp) := 0;           << set switch to write branch >>      03890000
  tos := writecmd;       << write motion command >>                     03895000
                                                                        03900000
initio:                                                                 03905000
  siop(cmdword) := tos;   << setup motion command >>                    03910000
  siop(dsj'cmdjmp) := 0;  << set switch to motion command branch >>     03915000
                                                                        03920000
  tos := drt;             << start channel program >>                   03925000
  tos := @siop+sysdb;                                                   03930000
  asmb(ddup;siopg;bl*-3;be*+2;br*-5;ddel);                              03935000
  mio'state := if fcode>=0 then 1 else 2;   << set process state >>     03940000
                                                                        03945000
readstat:                                                               03950000
  return;                                                               03955000
                                                                        03960000
                                                                        03965000
writefmark:                                                             03970000
  tos := wrtfmarkcmd;   << write file mark command >>                   03975000
                                                                        03980000
controlcont:                                                            03985000
  siop(dsj'rwjmp) := 25;   << branch around write logic >>     <<04118>>03990000
  goto initio;                                                          03995000
                                                                        04000000
                                                                        04005000
bsrecord:                                                               04010000
  tos := bsrecordcmd;   << backspace record command >>                  04015000
  goto controlcont;                                                     04020000
                                                                        04025000
                                                                        04030000
rewind:                                                                 04035000
  if lmio'status.ldpoint then  << already at loadpoint >>               04040000
    begin                                                               04045000
      mio'state := 0;   << indicate completion >>                       04050000
      return;                                                           04055000
    end;                                                                04060000
  tos := rewindcmd;   << rewind command >>                              04065000
  goto controlcont;                                                     04070000
                                                                        04075000
rwdunload:                                                              04080000
  tos := rewunldcmd;   << rewind/unload command >>                      04085000
  goto controlcont;                                                     04090000
                                                                        04095000
end;                                                                    04100000
$page "     MEASUREMENT I/O SYSTEM -- COMPLETOR"                        04105000
procedure mio'completor(drt,ditp,siop);                                 04110000
  value  drt, ditp, siop;                                               04115000
  integer  drt;                                                         04120000
  integer pointer  ditp, siop;                                          04125000
  option  privileged, uncallable, internal;                             04130000
begin                                                                   04135000
                                                                        04140000
  integer pointer  iltp;                                                04145000
  define  errcode = (0:3)#;                                             04150000
  equate  errmask = %11020,                                             04155000
          fatal   = %4010,                                              04160000
          tapegapcmd = 7;                                               04165000
                                                                        04170000
                                                                        04175000
  @iltp := ditp(diltp);   << setup ilt pointer >>                       04180000
  if iltp.errcode > 5 then                     << chan err >>  <<04850>>04185000
    begin                                                               04190000
err'exit:                                                               04195000
      mio'state := -1;   << return failure indicator >>                 04200000
      return;                                                           04205000
    end;                                                                04210000
                                                               <<04850>>04215000
  quiesce'drt(drt);                                            <<04850>>04220000
                                                               <<04850>>04225000
  if (lmio'status land fatal) <> 0 then goto err'exit;                  04230000
                                                                        04235000
  if mio'state=1 then   << i/o in progress >>                           04240000
    begin                                                               04245000
      if (mio'fcode=1 or mio'fcode=2) and                               04250000
         ((lmio'status land errmask) <> 0) then   << retry >>           04255000
        begin                                                           04260000
        mio'status := 0;                                       <<04850>>04265000
          if (mio'retry := mio'retry+1) <= 2 then                       04270000
            begin                                                       04275000
              mio'initiator(drt,ditp,siop,-1,0,0,0);                    04280000
              return;                                                   04285000
            end                                                         04290000
          else                                                          04295000
            goto err'exit;                                              04300000
        end;                                                            04305000
                                                                        04310000
      if mio'fcode=3 then   << rewind operation started >>              04315000
        begin                                                           04320000
          siop(dsj'cmdjmp) := 57;                              <<04118>>04325000
          mio'state := 4;   << rewind completion wait >>                04330000
          goto iocont;                                                  04335000
        end;                                                            04340000
                                                                        04345000
      mio'state := 0;   << indicate successful completion >>            04350000
    end                                                                 04355000
                                                                        04360000
  else if mio'state=2 then   << backspace record completed >>           04365000
    begin                                                               04370000
      siop(cmdword) := tapegapcmd;   << tape gap command >>             04375000
      mio'state := 3;                                                   04380000
iocont:                                                                 04385000
      tos := drt;        << start channel program >>                    04390000
      tos := @siop+sysdb;                                               04395000
      asmb(ddup;siopg;bl*-3;be*+2;br*-5;ddel);                          04400000
    end                                                                 04405000
                                                                        04410000
  else if mio'state=3 then   << tape gap completed >>                   04415000
    begin                                                               04420000
      mio'initiator(drt,ditp,siop,mio'fcode,                            04425000
                    mio'bank,mio'addr,mio'count);                       04430000
    end                                                                 04435000
                                                                        04440000
  else if mio'state=4 then   << rewind completed >>                     04445000
    begin                                                               04450000
      mio'status.ldpoint :=1;                                           04455000
      mio'state := 0;                                                   04460000
    end;                                                                04465000
end;                                                                    04470000
$page "     MEASUREMENT I/O SYSTEM -- INTERRUPT PROCESSOR"              04475000
procedure mio'intrpt'proc;                                              04480000
  option  privileged, uncallable, interrupt;                            04485000
begin                                                                   04490000
                                                                        04495000
  integer                                                               04500000
    drt         = q+3,    << located at s-1 when procedure is entered >>04505000
    unit        = q+5;    << unit number of interrupting mag tape >>    04510000
                                                                        04515000
  integer pointer                                                       04520000
    siop        = q+4,    << channel program pointer >>                 04525000
    ditp        = q+6;    << dit pointer >>                             04530000
                                                                        04535000
  integer                                                               04540000
    ilt'siop    = db+isiop,  << ilt channel program pointer >>          04545000
    ilt'flag    = db+iflag;  << ilt flag word >>                        04550000
                                                                        04555000
  integer array                                                         04560000
    ilt'ditp(*) = db+iditp0;  << ilt pointer for dit 0 >>               04565000
                                                                        04570000
  logical  ls0=s-0;                                                     04575000
  integer  x=x;                                                         04580000
                                                                        04585000
                                                                        04590000
  tos := ilt'siop;        << siop >>                                    04595000
                                                                        04600000
  x := ls0 + sysdb + 94;                                                04605000
  tos := absolute(x).(9:2);  << unit >>                                 04610000
                                                                        04615000
  tos := ilt'ditp(unit);  << ditp >>                                    04620000
  if <= then return;        << unconfigured unit >>                     04625000
                                                                        04630000
                                                               <<04850>>04635000
                                                               <<04850>>04640000
                                                                        04645000
  tos := 0;                                                             04650000
  tos := sysdb;                                                         04655000
  asmb(xchd);       << set db to sysdb >>                               04660000
                                                                        04665000
                                                               <<04850>>04670000
  mio'completor(drt,ditp,siop);    << call completor >>                 04675000
end;                                                                    04680000
$page "     MEASUREMENT I/O SYSTEM -- DATA INITIALIZATION"              04685000
procedure mio'init(ldev);                                               04690000
  value  ldev;                                                          04695000
  integer  ldev;                                                        04700000
  option  privileged, uncallable;                                       04705000
begin                                                                   04710000
                                                                        04715000
<<  this procedure intializes the drt, dit, and sio program area  >>    04720000
<<  as required by the series 33 measurement i/o system.  it also >>    04725000
<<  halts the 7970e hp-ib mag tape driver's idle channel program. >>    04730000
                                                                        04735000
<<  the parameter, ldev, is an integer containing the measurement >>    04740000
<<  logical device number in bits (8:8) and a "unit downed" bit   >>    04745000
<<  map in bits(0:4).                                             >>    04750000
                                                                        04755000
  integer  drt;                                                         04760000
  integer pointer  ditp, iltp, siop;                                    04765000
                                                                        04770000
                                                                        04775000
  disable;                                                              04780000
  tos := 0;                                                             04785000
  tos := sysdb;                                                         04790000
  asmb(xchd);        << set db to sysdb >>                              04795000
                                                                        04800000
  @ditp := lpdt (( ldev.(8:8)*lpdt'ent'size)+dit'offset);       <<mpev>>04805000
  @iltp := ditp(diltp);                                                 04810000
  @siop := iltp(isiop);                                                 04815000
  drt := iltp(icntrl).idrtn;                                   <<04850>>04820000
                                                                        04825000
  quiesce'drt(drt);                                            <<04850>>04830000
                                                               <<04850>>04835000
                                                                        04840000
  mio'enable := "OK";     << initialize dit >>                          04845000
  mio'state  := 0;                                                      04850000
  mio'retry  := 0;                                                      04855000
                                                                        04860000
  mio'ldev   := ldev;     << initialize sio area >>                     04865000
  mio'unit   := ditp(dldev).unit'field+1; <<unit # from dit+1>><<01430>>04870000
  mio'status := 0;                                                      04875000
                                                                        04880000
  putdrt(drt,2,@mio'intrpt'proc); << initialize drt >>         <<04850>>04885000
                                                               <<04850>>04890000
                                                                        04895000
  asmb(xchd);      << reset db >>                                       04900000
end;                                                                    04905000
$page "     MEASUREMENT I/O SYSTEM -- RESET DATA"                       04910000
integer procedure mio'reset(ldev);                                      04915000
  value  ldev;                                                          04920000
  integer  ldev;                                                        04925000
  option  privileged, uncallable;                                       04930000
begin                                                                   04935000
                                                                        04940000
<<  this procedure resets the dit, drt, and sio program area for >>     04945000
<<  use by the series 33 mag tape driver.  it also starts an     >>     04950000
<<  idle channel program for the mag tape controller.            >>     04955000
                                                                        04960000
<<  this procedure returns an integer containing the measurement >>     04965000
<<  logical device number in bits (8:8) and the "unit downed"    >>     04970000
<<  bit map in bits (0:4).                                       >>     04975000
                                                                        04980000
  integer  drt;                                                         04985000
  integer pointer  ditp, iltp, siop, idlesio;                           04990000
  equate idle = 68;                                            <<04850>>04995000
                                                                        05000000
                                                                        05005000
  disable;                                                              05010000
  tos := 0;                                                             05015000
  tos := sysdb;                                                         05020000
  asmb(xchd);       << set db to sysdb >>                               05025000
                                                                        05030000
  @ditp := lpdt (( ldev.(8:8)*lpdt'ent'size)+dit'offset);       <<mpev>>05035000
  @iltp := ditp(diltp);                                                 05040000
  @siop := iltp(isiop);                                                 05045000
  @idlesio := @siop+idle;                                               05050000
  drt := iltp(icntrl).idrtn;                                   <<04850>>05055000
                                                                        05060000
  mio'reset := mio'ldev;    << save return value >>                     05065000
                                                                        05070000
  move ditp(8) := (3(0));   << reset dit >>                             05075000
  mio'status   := 0;        << reset sio status word >>                 05080000
                                                                        05085000
  putdrt(drt,2,@gip'hpib); << reset drt >>                     <<04850>>05090000
                                                                        05095000
  << turn off bit indicating that idle channel program is runni<<04850>>05100000
  iltp(iflag).waitprog := 0;                                   <<04850>>05105000
                                                               <<04850>>05110000
  awakeio(ditp,0); << start idle chanp, no impede >>           <<04850>>05115000
<< if < then iofailure(drt,ditp); >>                           <<04850>>05120000
                                                                        05125000
  asmb(xchd);     << reset db >>                                        05130000
end;                                                                    05135000
$control segment=seg'                                          <<01549>>05140000
end.                                                           <<01549>>05145000
