$CONTROL MAP,CODE,USLINIT                                               00010000
<<iorem0 -- module 25>>                                                 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
                                                                        00060000
$control privileged,uncallable                                          00065000
$thirty                                                                 00070000
$title "IOREM0 - 'REMOTE' HP 2100 DRIVER FOR THE HP 3000"               00075000
begin  << iorem0 >>                                                     00080000
define                                                                  00085000
        disable    =    assemble(sed 0)#,                               00090000
        enable     =    assemble(sed 1)#,                               00095000
        duplicate  =    tos := s0#,                                     00100000
        iak        =    ( 1: 1)#,                                       00105000
        errbit     =    (12: 1)#,                                       00110000
        rstatus    =    ( 8: 8)#,      <<ioqp:  return status       >>  00115000
        status     =    ioqp(qstat).(8:8)#,                             00120000
        pfailb     =    (11:1)#,                                        00125000
        sbuf       =    ioqp(qflag).(3:1)#,                             00130000
        stopdefs   =    <<>>#;         <<stopper for defines        >>  00135000
equate                                                                  00140000
        mstrclear  =    %100000,       <<programmed master reset    >>  00145000
        clear      =    %040000,       <<reset ints,enable ints     >>  00150000
        null       =          0,       <<zero,nothing,empty, etc    >>  00155000
        qfunc      =          6,       <<ioq:  function code        >>  00160000
        qmisc      =         3,       <<ioq: driver state flags    >>   00165000
        qpar1      =          8,       <<ioq: parameter #1          >>  00170000
        qpar2      =          9,       <<ioq: parameter #2          >>  00175000
        qwbct      =          7,       <<ioq:  word/byte count      >>  00180000
        qstat      =          10,      <<ioq: status>>                  00185000
        qflag      =           0,      <<ioq: flags>>                   00190000
        siojmp     =    %000000,       <<sio jump command order     >>  00195000
        siores     =    %010000,       <<sio return residue command >>  00200000
        sioend     =    %030000,       <<sio end order              >>  00205000
        sioendint  =    %034000,       <<sio end and interrupt order>>  00210000
        siocntrl   =    %040000,       <<sio control command order  >>  00215000
        siowrite   =    %060000,       <<sio write command order    >>  00220000
        sioread    =    %070000,       <<sio read command order     >>  00225000
        siocmwrt   =    %170000-siowrite,                               00230000
        siocmrd    =    %170000-sioread,                                00235000
        setbank    =    %014000,        <<sio set bank instruction>>    00240000
        completion =     3,                                             00245000
        write      =     1,                                             00250000
        read       =     0,                                             00255000
        open       =     2,                                             00260000
        close      =     3,                                             00265000
        devclose   =     4,                                             00270000
        control    =     28,                                            00275000
        ditsize    =          11,       <<device info. table size    >> 00280000
        siosize    =         20,       <<sio program area size>>        00285000
        siosized2  =   siosize/2,<<sio pgm size/2 for initial>><<01300>>00290000
        count      =          8,       <<dit:  current word count   >>  00295000
        dstat      =          6,        <<dit: dev status>>             00300000
        eror       =          10,       <<dit:  error retry info     >> 00305000
        cond       =          9,       <<unusual condition flag     >>  00310000
        error      =       %400,       <<word count mismatch-send/rec>> 00315000
        aborted    =        %33,       <<i/o aborted return status  >>  00320000
        badcntrl   =        %03,       <<invallid control function  >>  00325000
        badlgth    =        %03,       <<bad reqst lgth>>  <<00.01>>    00330000
        pending    =        %10,       <<i/o innitiated status      >>  00335000
        pfabort    =        %63,                                        00340000
        badbuf     =        %104,                                       00345000
        siofail    =        %45,       <<bad rtn frm startio intr >>    00350000
        successful =          1,       <<i/o successfully completed >>  00355000
        xfererr    =        %15,       <<transfer error             >>  00360000
        endio      =          5,       <<end of i/o request         >>  00365000
        wcomp      =        %13,       <<call completor after int   >>  00370000
        tlog       =          7,       <<ioqp-transmission log      >>  00375000
        readcw     =    %000042,       <<read ready c.w.            >>  00380000
        writecw    =    %000102,       <<write ready c.w.           >>  00385000
        nrdycw     =    %001002,       <<ints. on only              >>  00390000
        residue    =         11,       <<sio area:  index to residue>>  00395000
        setdevstat =        %10,       <<set status to device status>>  00400000
        sysdb      =     %1000,                                         00405000
        stopeqts   =     000000;       <<stopper for equates        >>  00410000
                                                                        00415000
$page "IOREM0-DATA AREA-IOQH,DIT,SIO AREA"                              00420000
byte array config(0:7)=db:=                                             00425000
      ditsize,                                                          00430000
      1,                                                                00435000
      0,                                                                00440000
      0,                                                                00445000
      0,                                                                00450000
      0,                                                                00455000
      siosized2,0;                                             <<01300>>00460000
<<------------------------------- dit ------------------------------>>  00465000
array ditab(1:ditsize)=db:=                                             00470000
        0,0,0,0,0,0,0,0,0,0,0;                                          00475000
                                                                        00480000
<<----------------------------- sio program storage ---------------->>  00485000
                                                                        00490000
array  sioa(1:siosize)=db:=                                             00495000
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;                                        00500000
$page "IOREM0-EXTERNAL DECLARATIONS"                                    00505000
<<---------------------- external procedure declarations ----------->>  00510000
                                                                        00515000
                                                                        00520000
procedure gip;                                                          00525000
  option external;                                                      00530000
                                                                        00535000
procedure help;                                                         00540000
  option external;                                                      00545000
                                                                        00550000
logical procedure iomessage(dest,catn,p1,p2,p3,p4,ditp,buf,cont);       00555000
  value dest,catn,p1,p2,p3,p4,ditp,buf,cont;                            00560000
  pointer ditp;                                                         00565000
  integer dest,catn,p1,p2,p3,p4,buf,cont;                               00570000
  option variable,external;                                             00575000
                                                                        00580000
procedure siodm(ditp,flags);                                            00585000
  value ditp,flags;                                                     00590000
  logical flags;                                                        00595000
  pointer ditp;                                                         00600000
  option external;                                                      00605000
                                                                        00610000
                                                                        00615000
procedure masterclear(ditp);                                            00620000
  array ditp;                                                           00625000
  option external;                                                      00630000
                                                                        00635000
                                                                        00640000
                                                                        00645000
procedure checkindex(index,table);                                      00650000
  value index,table;                                                    00655000
  integer index;                                                        00660000
  integer pointer table;                                                00665000
  option external;                                                      00670000
                                                                        00675000
                                                                        00680000
                                                                        00685000
procedure startio(ditp,siop,qflag);                                     00690000
   value ditp,siop,qflag;                                               00695000
   pointer ditp,siop;                                                   00700000
   logical qflag;                                                       00705000
   option external;                                                     00710000
                                                                        00715000
                                                                        00720000
                                                                        00725000
procedure iofailure(drtn,ditp);                                         00730000
   value drtn;                                                          00735000
   integer drtn;                                                        00740000
   array ditp;                                                          00745000
   option external;                                                     00750000
                                                                        00755000
                                                                        00760000
procedure initz(iditp);                                                 00765000
   integer array iditp;                                                 00770000
   begin                                                                00775000
<<  dummy    >>                                                         00780000
   end;                                                                 00785000
$page "IOREM0-ENTRY:RESET INT,CHK FOR ABORT,DETERMINE ENTRY TYPE"       00790000
                                                                        00795000
<<-------------------------- driver code procedure ----------------->>  00800000
                                                                        00805000
integer procedure remdvr(ioqp,ditp,bank,bufadr,siop,drtn);              00810000
  value ioqp,ditp,bank,bufadr,siop,drtn;                                00815000
  integer bank,drtn,bufadr;                                             00820000
  integer pointer ioqp,ditp,siop;                                       00825000
                                                                        00830000
                                                                        00835000
  begin                                                                 00840000
                                                                        00845000
    logical siocw;                                                      00850000
    integer rdycw,mstate=remdvr,                                        00855000
       s0=s-0,                                                          00860000
       s1=s-1,                                                          00865000
       s2=s-2,                                                          00870000
       s3=s-3,                                                          00875000
       s4=s-4,                                                          00880000
       s5=s-5,                                                          00885000
       x=x,                                                             00890000
       func,                                                            00895000
       p1,                                                              00900000
       p2;                                                              00905000
    double pointer dsiop=siop;                                          00910000
    define siopbase=@siop+sysdb#;                                       00915000
                                                                        00920000
subroutine setflags;                                                    00925000
  begin                                                                 00930000
    func:=ioqp(qfunc);     <<get function code>>                        00935000
    p1:=ioqp(qpar1);       <<get parameter 1>>                          00940000
    p2:=ioqp(qpar2);       <<get parameter 2>>                          00945000
    <<  determine word count     >>                                     00950000
    tos:=ioqp(qwbct);                                                   00955000
    if < then                                                           00960000
    begin     <<bytes convert to  words>>                               00965000
      tos:=-tos&asr(1);  <<round down >>                                00970000
    end;                                                                00975000
    if s0 >4096 then go invalidlength;                                  00980000
    ditp(count):=tos;                                                   00985000
    if sbuf=1 then                                                      00990000
    begin     <<buffering not allowed>>                                 00995000
      tos:=badbuf;                                                      01000000
      go iodone;                                                        01005000
    end;                                                                01010000
  end;  <<setflags>>                                                    01015000
                                                                        01020000
                                                                        01025000
<<  i  n  i  t  i  a  t  o  r    >>                                     01030000
     disable;     <<disable interrupts>>                                01035000
     tos:=ioqp;                                                         01040000
     del;                                                               01045000
     if < then                                                          01050000
     begin     <<i/o has been aborted>>                                 01055000
       enable;                                                          01060000
       if mstate = completion then                                      01065000
       masterclear(ditp);                                               01070000
       if ioqp.pfailb =1 then tos:=pfabort else tos:=aborted;           01075000
       go to iodone;                                                    01080000
     end;                                                               01085000
     enable;                                                            01090000
     if mstate = completion then go comp;                               01095000
     tos:=drtn;     <<enable dev status,clear interrupts>>              01100000
     tos:=clear;                                                        01105000
     assemble (cio 1; del);                                             01110000
     if <> then                                                         01115000
     begin                                                              01120000
ufail:                                                                  01125000
       iofailure(drtn,ditp);   <<non responding device>>                01130000
      tos:=%54;                                                         01135000
      tos:=endio;                                                       01140000
fail:                                                                   01145000
      masterclear(ditp);                                                01150000
      go to out;                                                        01155000
    end;                                                                01160000
    setflags;                                                           01165000
    if p1.(0:1)=1 then help;                                            01170000
   if func=control then                                                 01175000
    begin                              << this is a control req.    >>  01180000
     go contrl;                                                         01185000
    end; del;                                                           01190000
   if func = write then                                                 01195000
    begin                              << write request             >>  01200000
     tos := siocmwrt;                                                   01205000
     tos := writecw;                                                    01210000
    end                                                                 01215000
   else                                                                 01220000
    begin                              << read request              >>  01225000
     tos := siocmrd;                                                    01230000
     tos := readcw;                                                     01235000
    end;                                                                01240000
   rdycw := tos;                                                        01245000
   siocw := tos;                                                        01250000
                                                                        01255000
   tos := ditp(count);                                                  01260000
   if = then go invalidlength;         << leave word count on tos   >>  01265000
<< set up sio program                                               >>  01270000
   tos := siocntrl;                    << turn on rdy bit           >>  01275000
   tos := rdycw;                                                        01280000
   tos:=tos lor logical(ditp(cond));   <<set unusual condition      >>  01285000
   assemble(ddup);                     <<duplicate control order>>      01290000
   dsiop(0):=tos;                                                       01295000
   if rdycw = readcw                   <<read operation>>               01300000
    then                               <<construct special read orders>>01305000
     begin                                                              01310000
      tos:=logical(-1)-logical(siocw); <<read order, 1 word>>           01315000
      tos:=siopbase+8;                 <<addr of 2nd read order>>       01320000
      dsiop(x:=x+1):=tos;                                               01325000
      tos:=sioendint;                  <<end with interrupt>>           01330000
      tos:=0;                          <<space for status>>             01335000
      dsiop(x:=x+1):=tos;                                               01340000
      dsiop(x:=x+1):=tos;              <<repeat control order>>         01345000
     end                                                                01350000
    else                               <<write operation>>              01355000
     begin                                                              01360000
      ddel;                            <<delete extra control order>>   01365000
      tos:=setbank;                                                     01370000
      tos:=bank;                                                        01375000
      dsiop(x:=x+1):=tos;                                               01380000
      tos:=siojmp;                     <<jump to write order  >>        01385000
      tos:=siopbase+8;                 <<jump address>>                 01390000
      dsiop(x:=x+1):=tos;                                               01395000
      x:=x+1;                                                           01400000
     end;                                                               01405000
   tos := -tos;  tos := logical(tos) - logical(siocw);                  01410000
   tos :=bufadr;                                                        01415000
   dsiop(x:=x+1):=tos;                                                  01420000
   tos := siores;                      << return residue            >>  01425000
   tos := 0;                                                            01430000
   dsiop(x:=x+1) := tos;                                                01435000
   tos := siocntrl;                    << turn off rdy bit          >>  01440000
   tos := nrdycw;                                                       01445000
   dsiop(x:=x+1) := tos;                                                01450000
   tos := sioend;                      <<sio end--no interrupt      >>  01455000
   tos := 0;                                                            01460000
   dsiop(x:=x+1) := tos;                                                01465000
<< start sio program                                                >>  01470000
doio:                                                                   01475000
   startio(ditp,siop,1);                                                01480000
   if <> then go badsio;                                                01485000
   tos := pending;                                                      01490000
   tos := wcomp;                                                        01495000
   go out;                                                              01500000
                                                                        01505000
$page "IOREM0-CONTROL REQUEST"                                          01510000
<< control request                                                  >>  01515000
contrl:                                                                 01520000
   if ioqp(qpar1) =1                   <<dynamic status reqst?>>        01525000
    then                                                                01530000
     begin                                                              01535000
      tos:=drtn;                                                        01540000
      tos:=setdevstat;                                                  01545000
      assemble(cio 1);                 <<enable device status>>         01550000
      assemble(tio 0);                 <<read device status>>           01555000
      ditp(dstat):=tos;  <<return status>>                              01560000
      del;                                                              01565000
      tos:=1;                          <<one word read>>                01570000
      go cntldone;                                                      01575000
     end;                                                               01580000
   if ioqp(qpar1) =%200 then                                            01585000
    ditp(cond):=ioqp(qpar1);                                            01590000
   tos:=0;                             <<no action on other requests >> 01595000
   go cntldone;                                                         01600000
$page "IOREM0-COMPLETION SECT: CHK STATUS & RETURN IOQP"                01605000
comp:                                                                   01610000
   tos:=drtn;                                                           01615000
   assemble(tio 0);                    <<read interrupt status>>        01620000
   assemble(delb);                                                      01625000
   if tos.(13:1) then                  <<initial read interrupt>>       01630000
    begin                                                               01635000
     tos:=siop(8);                     <<get 2100 word count>>          01640000
     duplicate;                                                         01645000
     if tos=0 then go ucount;          <<invalid count >>               01650000
     duplicate;                                                         01655000
     if tos = ditp(count)              <<send/receive counts match>>    01660000
      then go restrt                                                    01665000
      else                                                              01670000
       begin                                                            01675000
        duplicate;                                                      01680000
        if tos > ditp(x)                                                01685000
         then                                                           01690000
ucount:                                                                 01695000
          begin                                                         01700000
           del;                        <<ignore 2100 word cnt>>         01705000
           tos:=ditp(count);           <<use 3000 word count>>          01710000
           siop(13):=logical(siop(13)) lor error;  <<2100 error>>       01715000
          end;                                                          01720000
       end;                                                             01725000
restrt:                                                                 01730000
     tos:=setbank;                                                      01735000
     tos:=bank;                                                         01740000
     dsiop(0):=tos;                                                     01745000
     tos:=siojmp;                                                       01750000
     tos:=siopbase+6;                                                   01755000
     dsiop(1):=tos;                                                     01760000
     siop(8):=(-tos).(4:12) lor sioread; <<sio read - min count>>       01765000
     tos:=drtn;                                                         01770000
     tos:=clear;                       <<clear all interrupts>>         01775000
     assemble(cio 1);                                                   01780000
     del;                                                               01785000
     startio(ditp,siop,1);     <<start sio operation>>                  01790000
     if <> then go badsio;                                              01795000
     tos:=pending;                                                      01800000
     tos:=wcomp;                                                        01805000
     go out;                                                            01810000
    end;                                                                01815000
   tos := drtn;                                                         01820000
   tos := mstrclear;                                                    01825000
   assemble(cio 1);                                                     01830000
   tos := clear;                                                        01835000
   assemble(cio 1);                                                     01840000
   del;                                                                 01845000
<< determine number of words transferred                            >>  01850000
   tos := siop(residue);                                                01855000
   tos:=tos land %7777;                <<isolate residue count >>       01860000
   if <> then tos:=tos lor %170000;    <<residue now 0 or neg  >>       01865000
   tos := -(logical(siop(8).(4:12)) lor %170000);  << + sio cnt >>      01870000
   tos:=tos+tos;                       <<sio wd cnt - residue  >>       01875000
   if ioqp(qwbct) < 0 then                                              01880000
     begin                             <<convert to bytes           >>  01885000
      tos := -tos & asl(1);             <<00.01>>                       01890000
     end;                                                               01895000
   tos := drtn;                                                         01900000
   tos := setdevstat;                                                   01905000
   assemble(cio 1);                                                     01910000
   assemble(tio 0);                                                     01915000
   tos.errbit := 1;                                                     01920000
   assemble(ddel);                                                      01925000
   if <> then                                                           01930000
    begin                                                               01935000
     tos:=tos-1;                       <<residue 1 off on device end>>  01940000
     go transerr;                                                       01945000
    end                                                                 01950000
    else go welldone;                                                   01955000
invalidcntrl:                                                           01960000
   tos := badcntrl;                                                     01965000
   go iodone;                                                           01970000
invalidlength:                                                          01975000
   ioqp(tlog):=0;                                                       01980000
   tos:= badlgth;                                                       01985000
   go iodone;                                                           01990000
transerr:                                                               01995000
   ioqp(tlog):=tos;                                                     02000000
   tos := xfererr;                                                      02005000
   go iodone;                                                           02010000
badsio:                                                                 02015000
   tos := siofail;                                                      02020000
   go iodone;                                                           02025000
tryagain:                                                               02030000
   tos := drtn;                                                         02035000
   tos := mstrclear;                                                    02040000
   assemble(cio 1;del);                                                 02045000
   go doio;                                                             02050000
$page "IOREM0-EXITS:  GOOD,BAD, AND INDIFFERENT"                        02055000
welldone:                                                               02060000
   ditp(cond):=0;                      <<reset condition flag>>         02065000
cntldone:                                                               02070000
   ioqp(tlog) := tos;                                                   02075000
   tos := successful;                                                   02080000
iodone:                                                                 02085000
   tos := endio;                                                        02090000
   tos := drtn;                                                         02095000
   tos := mstrclear;                                                    02100000
   assemble(cio 1);                                                     02105000
   tos := clear;                                                        02110000
   assemble(cio 1);                                                     02115000
   tos := nrdycw;                                                       02120000
   assemble(cio 1);                                                     02125000
   del;                                                                 02130000
out:                                                                    02135000
   mstate:=tos;                                                         02140000
   status:=tos;                                                         02145000
end  <<remdvr >>  ;                                                     02150000
$page "IOREM0-'DUMMY' OUTER BLOCK GIVES CONFIGURATION DATA"             02155000
assemble(                                                               02160000
 pcal siodm;          <<monitor>>                                       02165000
 pcal remdvr;         <<initiator>>                                     02170000
 pcal remdvr;         <<completor>>                                     02175000
 con 0;               <<no io process>>                                 02180000
 pcal initz;          <<initialization>>                                02185000
con 1;                <<i interrupt handler>>                           02190000
pcal gip);            <<interrupt handler>>                             02195000
end  <<iorem0  >> ;.............................................        02200000
