$CONTROL MAP,CODE,USLINIT                                               00010000
<<ioplot0 - module 15>>                                                 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
                                                                        00065000
                                                                        00070000
                                                                        00075000
                                                                        00080000
$control privileged,uncallable                                          00085000
$thirty                                                                 00090000
$title "30226A PLOTTER INTERFACE DRIVER"                                00095000
                                                                        00100000
                                                                        00105000
                                                                        00110000
driver request codes:                                                   00115000
                                                                        00120000
    1 - write                                                           00125000
    2 - open file                                                       00130000
    3 - close file                                                      00135000
    4 - close device                                                    00140000
    5 - return device subtype                                           00145000
                                                                        00150000
                                                                        00155000
                                                                        00160000
                                                                        00165000
begin                                                                   00170000
    equate                                                              00175000
         qdstn        = 4,       <<index into ioq-dst#>>                00180000
         qfunc        = 6,       <<index into ioq-funct code>>          00185000
         qpar1        = 8,       <<index into ioq-param #1>>            00190000
         qpar2        = 9,       <<index into ioq-param #2>>            00195000
         qmisc        = 3,       <<index into ioq-internal flags>>      00200000
         qwbcnt       = 7,       <<index into ioq-word/byte cnt>>       00205000
         qflag        = 0,       <<index into ioq-flags>>               00210000
         qldev        = 2,       <<index into ioq-log dev#>>            00215000
         qstat        =10,       <<index into ioq-status>>              00220000
         dflag        = 0,       <<index into dit-flags>>               00225000
         dldev        = 3,       <<index into dit-log dev#>>            00230000
         dstat        = 6,       <<index into dit-status>>              00235000
         daccess      = 8,       <<index into dit-access type>>         00240000
         write        = 1,       <<function-write>>                     00245000
         open         = 2,       <<function-file open>>                 00250000
         close        = 3,       <<function-file close>>                00255000
         devclose     = 4,       <<function-device close>>              00260000
         cntrl        = %40000,  <<sio cntrl order>>                    00265000
         jump         = 0,       <<sio uncond jump>>                    00270000
         setbank      = %14000,  <<sio set bank>>                       00275000
         sioend       = %34000,  <<sio end order>>                      00280000
         completion   = 3,       <<monitor state-completion>>           00285000
         endio        = 5,       <<monitor state-end of request>>       00290000
         reinit       = %7,      <<monitor state-reinit on intrp>>      00295000
         unitfail     = %54,     <<status ret-unit fail>>               00300000
         invalid      = 4,       <<status ret-inv func>>                00305000
         xferr        = %14,     <<status ret=transferr err>>           00310000
         timeout      = %34,     <<status ret=timeout>>                 00315000
         limitsw      = %143,    <<status ret=limit sw reached>>        00320000
         ntrdy        = %100,    <<status ret=not rdy>>                 00325000
         success      = 1,       <<status ret=successful  >>   <<02654>>00330000
         macc         = %123,    <<status return-multiple access>>      00335000
         aborted      = %33,     <<status return-i/0 aborted>>          00340000
         pfabort      = %63,     <<status return-pwr fail abort>>       00345000
         clear        = %040000, <<clear all interrupts>>               00350000
         mstrclear    = %100000, <<master clear>>                       00355000
         sysdb        = %1000,   <<system db>>                          00360000
         syssbuf      = 6,       <<sys buf table index>>                00365000
         wnew         = %7,      <<reinitiate on interrupt>>            00370000
         callcmplt    = %13,     <<call cmpltr on intrpt>>              00375000
         badcntrl     = %3,      <<invalid control function>>           00380000
         badfunc      = %5,      <<invalid function code>>              00385000
         xfererr      = %14,     <<transferr error-status>>             00390000
         syslpdt      = %10,     <<lpdt pointer index>>                 00395000
         ditsize      = 10,      <<dit size>>                           00400000
         siosize      =30,       <<sio pgm size>>                       00405000
         siosized2    =siosize/2,<<sio pgm size/2 for initial>><<01300>>00410000
         siowr1       = %67777,  <<siowr 1 word>>                       00415000
         siowr2       = %60000,  <<siowr 0 cnt>>                        00420000
          termi       = 0;        <<terminator>>                        00425000
                                                                        00430000
  define                                                                00435000
       abs            = absolute#,                                      00440000
       disable        = assemble(sed 0)#,                               00445000
       enable         = assemble(sed 1)#,                               00450000
       pfailb         = (11:1)#,                                        00455000
       iak            = (8:1)#,                                         00460000
       eof            = (8:2)#,   <<eof field in lpdt>>                 00465000
       deof           =ditp(daccess).(12:1)#,                           00470000
       status         =ioqp(qstat).(8:8)#,                              00475000
       daccp          =ditp(daccess)#,                                  00480000
       msgdone        =ioqp(qflag)#,   <<message done flg>>             00485000
       sbuf           =ioqp(qflag).(3:1)#,  <<sys buffer flag>>         00490000
       qmiscp         =ioqp(qmisc)#,                                    00495000
       termd          = 0#;                                             00500000
                                                                        00505000
                                                                        00510000
                                                                        00515000
                                                                        00520000
<< dit definition and driver linkage area >>                            00525000
                                                                        00530000
byte array config(0:7)=db:=                                             00535000
ditsize,1,0,0,0,0,siosized2,0;                                 <<01300>>00540000
                                                                        00545000
array ditab(1:ditsize)=db:=                                             00550000
0,0,0,0,0,0,0,0,0,0;                                                    00555000
                                                                        00560000
array sioa(1:siosize)=db:=                                              00565000
0,0,0,0,0,0,0,0,0,0,                                                    00570000
0,0,0,0,0,0,0,0,0,0,                                                    00575000
0,0,0,0,0,0,0,0,0,0                                                     00580000
                                                                        00585000
;     <<terminator >>                                                   00590000
procedure eofcheck(ioqp,bufr,cnt,hardchk);                              00595000
  value ioqp,bufr,cnt,hardchk;                                          00600000
  double bufr;                                                          00605000
  pointer ioqp;                                                         00610000
  integer cnt,hardchk;                                                  00615000
  option external;                                                      00620000
                                                                        00625000
procedure gip;                                                          00630000
  option external;                                                      00635000
                                                                        00640000
procedure help;                                                         00645000
  option external;                                                      00650000
                                                                        00655000
procedure ldevnotrdy(ditp);                                    <<0u.eb>>00660000
   value ditp; pointer ditp; option external;                  <<0u.eb>>00665000
                                                                        00670000
procedure siodm(ditp,flags);                                            00675000
  value ditp,flags;                                                     00680000
  logical flags;                                                        00685000
  pointer ditp;                                                         00690000
  option external;                                                      00695000
                                                                        00700000
                                                                        00705000
procedure masterclear(ditp);                                            00710000
  array ditp;                                                           00715000
  option external;                                                      00720000
                                                                        00725000
                                                                        00730000
                                                                        00735000
procedure checkindex(index,table);                                      00740000
  value index,table;                                                    00745000
  integer index;                                                        00750000
  integer pointer table;                                                00755000
  option external;                                                      00760000
                                                                        00765000
                                                                        00770000
                                                                        00775000
procedure startio(ditp,siop,qflag);                                     00780000
   value ditp,siop,qflag;                                               00785000
   pointer ditp,siop;                                                   00790000
   logical qflag;                                                       00795000
   option external;                                                     00800000
                                                                        00805000
                                                                        00810000
                                                                        00815000
procedure iofailure(drtn,ditp);                                         00820000
   value drtn;                                                          00825000
   integer drtn;                                                        00830000
   array ditp;                                                          00835000
   option external;                                                     00840000
                                                                        00845000
                                                                        00850000
procedure initz(iditp);                                                 00855000
   integer array iditp;                                                 00860000
   begin                                                                00865000
<<  dummy    >>                                                         00870000
   end;                                                                 00875000
integer procedure plotdrvr(ioqp,ditp,bank,bufadr,siop,drtn);            00880000
  value ioqp,ditp,bank,bufadr,siop,drtn;                                00885000
  integer bank,drtn,bufadr;                                             00890000
  integer pointer ioqp,ditp,siop;                                       00895000
                                                                        00900000
                                                                        00905000
  begin                                                                 00910000
                                                                        00915000
    double ubuf=bank;                                                   00920000
    integer mstate=plotdrvr,                                            00925000
            s0=s-0,                                                     00930000
            s1=s-1,                                                     00935000
            s2=s-2,                                                     00940000
            s3=s-3,                                                     00945000
            s4=s-4,                                                     00950000
            s5=s-5,                                                     00955000
            x=x,                                                        00960000
            func,                                                       00965000
            p1,                                                         00970000
            p2,                                                         00975000
            mode,                                                       00980000
            i,k,j,l,m,n,cnt,ix,                                         00985000
            maxbufsize,                                                 00990000
            bnkno,                                                      00995000
            temp,                                                       01000000
            fword,                                                      01005000
            wbcnt;                                                      01010000
    define ldev   = ioqp(qldev).(8:8)#,                                 01015000
           stat1    = ditp(dstat)#,                                     01020000
           siopbase = @siop+sysdb#;                                     01025000
                                                                        01030000
                                                                        01035000
                                                                        01040000
        integer pointer sbufr=db+syssbuf,badr;                          01045000
        double pointer lpdtd = db+syslpdt;                              01050000
        double pointer dsiop = siop;                                    01055000
        logical oddbyte,oddone;                                         01060000
                                                                        01065000
                                                                        01070000
                                                                        01075000
subroutine dosio;                                                       01080000
  begin  <<do start io>>                                                01085000
    startio(ditp,siop,1);                                               01090000
    if <> then                                                          01095000
    begin                                                               01100000
      iofailure(drtn,ditp);   <<non responding device>>                 01105000
    end;                                                                01110000
    tos:=%10;                                                           01115000
    tos:=callcmplt;                                                     01120000
    go to bend;                                                         01125000
  end;  <<start i/o>>                                                   01130000
                                                                        01135000
                                                                        01140000
                                                                        01145000
                                                                        01150000
                                                                        01155000
subroutine setflags;                                                    01160000
  begin                                                                 01165000
    func:=ioqp(qfunc);     <<get function code>>                        01170000
    p1:=ioqp(qpar1);       <<get parameter 1>>                          01175000
    p2:=ioqp(qpar2);       <<get parameter 2>>                          01180000
    oddbyte:=false;                                                     01185000
    tos:=ioqp(qwbcnt);  <<get word byte count>>                         01190000
    assemble(dup,dup);                                                  01195000
    if tos.(0:1)=1 then                                                 01200000
    begin   <<negative count is in bytes>>                              01205000
      if tos.(15:1)=1 then oddbyte:=true                                01210000
      else oddbyte:=false;                                              01215000
      wbcnt:=(-tos)/2;                                                  01220000
      if oddbyte then                                                   01225000
      begin                                                             01230000
        if wbcnt=0 then                                                 01235000
        begin                                                           01240000
          wbcnt:=1;                                                     01245000
          oddone:=true;                                                 01250000
        end;                                                            01255000
      end;                                                              01260000
    end                                                                 01265000
    else                                                                01270000
    begin                                                               01275000
    wbcnt:=tos;<<count is in words>>                                    01280000
    del;                                                                01285000
    end;                                                                01290000
  end;  <<setflags>>                                                    01295000
                                                                        01300000
                                                                        01305000
subroutine setsysbuf;                                                   01310000
  begin                                                                 01315000
    checkindex(@sbufr+sysdb-bufadr,sbufr);                              01320000
    if wbcnt > 1024 then go bf;                                         01325000
    cnt:=wbcnt;                                                         01330000
    while cnt>0 do                                                      01335000
    begin                                                               01340000
      if cnt >128 then                                                  01345000
      begin                                                             01350000
        tos:=%160000;   <<wr chained>>                                  01355000
        tos.(4:12):=-128;  <<set full count>>                           01360000
        tos:=bufadr;                                                    01365000
        dsiop(i):=tos;     <<store in siopgm>>                          01370000
        i:=i+1;                                                         01375000
        cnt:=cnt-128;                                                   01380000
      end                                                               01385000
      else                                                              01390000
      begin  <<cnt is 128 or less>>                                     01395000
        tos:=%60000;  <<wr unchained>>                                  01400000
        tos.(4:12):=-cnt;  <<set wr count>>                             01405000
        tos:=bufadr;                                                    01410000
        dsiop(i):=tos;                                                  01415000
        i:=i+1;                                                         01420000
        cnt:=0;                                                         01425000
      end;                                                              01430000
       <<get next address>>                                             01435000
      if cnt > 0 then                                                   01440000
      begin                                                             01445000
      checkindex(abs(bufadr-1),sbufr);                                  01450000
      bufadr:=abs(x)+@sbufr+sysdb;                                      01455000
      end;                                                              01460000
    end;                                                                01465000
  end;  <<setsysbuf>>                                                   01470000
                                                                        01475000
                                                                        01480000
                                                                        01485000
                                                                        01490000
$page                                                                   01495000
<<  i  n  i  t  i  a  t  o  r    >>                                     01500000
     disable;     <<disable interrupts>>                                01505000
     tos:=ioqp;                                                         01510000
     del;                                                               01515000
     if < then                                                          01520000
     begin     <<i/o has been aborted>>                                 01525000
       enable;                                                          01530000
       if mstate = completion then                                      01535000
       masterclear(ditp);                                               01540000
       if ioqp.pfailb =1 then tos:=pfabort else tos:=aborted;           01545000
       tos:=endio;                                                      01550000
       go to bend;                                                      01555000
     end;                                                               01560000
     enable;                                                            01565000
     if mstate = completion then go completor;                          01570000
     tos:=drtn;     <<enable dev status,clear interrupts>>              01575000
     tos:=clear;                                                        01580000
     assemble (cio 1; del);                                             01585000
     if <> then                                                         01590000
     begin                                                              01595000
ufail:                                                                  01600000
       iofailure(drtn,ditp);   <<non responding device>>                01605000
      tos:=unitfail;                                                    01610000
      tos:=endio;                                                       01615000
fail:                                                                   01620000
      masterclear(ditp);                                                01625000
      go to bend;                                                       01630000
    end;                                                                01635000
    setflags;                                                           01640000
    if p1.(0:1)=1 then help;                                            01645000
if func=write then                                                      01650000
$page                                                                   01655000
<<  i n i t i a t o r    w r i t e               >>                     01660000
    begin                                                               01665000
                                                                        01670000
formsiop:                                                               01675000
      i:=0;                                                             01680000
      tos:=setbank;                                                     01685000
      tos:=bank;                                                        01690000
      dsiop(i):=tos;                                                    01695000
      i:=i+1;                                                           01700000
      if sbuf =1 then setsysbuf                                         01705000
      else                                                              01710000
      begin     <<set up write cmds>>                                   01715000
        tos:=wbcnt;     <<get count>>                                   01720000
        if < then go bf;     <<invalid>>                                01725000
        if = then go docio;                                             01730000
        k:=bufadr;     <<buffer address>>                               01735000
again:                                                                  01740000
        if s0 > %7777 then                                              01745000
        j:=%7777                                                        01750000
        else                                                            01755000
        j:=s0;     <<j=word count for this write>>                      01760000
        tos:=tos-j;  <<# words remaining>>                              01765000
        tos:=%67777 land logical(-j);                                   01770000
        tos:=k;                                                         01775000
        dsiop(i):=tos;                                                  01780000
        i:=i+1;                                                         01785000
        if s0 > 0 then                                                  01790000
        begin     <<more words in buffer>>                              01795000
          k:=k+j;  <<buffer address>>                                   01800000
          go again;                                                     01805000
        end;                                                            01810000
      end;                                                              01815000
      tos:=sioend;                                                      01820000
      tos:=-1;                                                          01825000
      dsiop(i):=tos;                                                    01830000
      i:=i+1;                                                           01835000
docio:                                                                  01840000
      masterclear(ditp);                                                01845000
      tos:=drtn;                                                        01850000
      assemble(tio 0);                                                  01855000
      if <> then go ufail;                                              01860000
      x:=i;                                                             01865000
      if <= then                                                        01870000
      begin     <<no sio pgm or stat req>>                              01875000
        if < then                                                       01880000
        stat1:=tos;                                                     01885000
        go welldone;                                                    01890000
      end;                                                              01895000
      assemble (del; tio 0);                                            01900000
      if <> then go ufail;                                              01905000
      if (tos&lsr(6)) then                                              01910000
      begin     <<plotter not ready>>                                   01915000
        ldevnotrdy(ditp);                                      <<0u.eb>>01920000
        tos:=%30;                                                       01925000
        tos:=wnew;                                                      01930000
        go bend;                                                        01935000
      end;                                                              01940000
    dosio;                                                              01945000
    end;     <<write>>                                                  01950000
    if func = open then                                                 01955000
$page                                                                   01960000
<<  i n i t i a t o r    o p e n                  >>                    01965000
    begin     <<file open>>                                             01970000
      masterclear(ditp);                                                01975000
      go welldone;                                                      01980000
    end;                                                                01985000
    if func = close then                                                01990000
$page                                                                   01995000
<<  i n i t i a t o r    c l o s e                 >>                   02000000
    begin     <<file close>>                                            02005000
    go welldone;                                                        02010000
    end;     <<file close>>                                             02015000
    if func = devclose then                                             02020000
$page                                                                   02025000
<<  i n i t i a t o r    d e v i c e   c l o s e   >>                   02030000
    begin     <<device close>>                                          02035000
      go to welldone;                                                   02040000
    end;    <<device close>>                                            02045000
    if func > 4 then                                                    02050000
$page                                                                   02055000
<<  i n i t i a t o r    i n v a l i d                >>                02060000
    begin                                                               02065000
      tos:=invalid;                                                     02070000
bf:                                                                     02075000
      tos:=endio;                                                       02080000
      go bend;                                                          02085000
welldone:                                                               02090000
      tos:=1;     <<ending stat ok>>                                    02095000
      tos:=endio;                                                       02100000
bend:                                                                   02105000
      mstate:=tos;     <<set monitor state>>                            02110000
      status:=tos;     <<set status>>                                   02115000
                                                                        02120000
      return;                                                           02125000
    end;     <<initiator>>                                              02130000
                                                                        02135000
                                                                        02140000
                                                                        02145000
$page                                                                   02150000
<<        c  o  m  p  l  e  t  o  r        >>                           02155000
                                                                        02160000
                                                                        02165000
completor:                                                              02170000
   <<test for limit sw ignored>>                                        02175000
   if stat1.(14:1) =1 then                                              02180000
   begin                                                                02185000
     tos:=logical(stat1) land %100100;                                  02190000
     if = then                                                          02195000
     begin  <<only limit sw>>                                           02200000
       tos:=%10;                                                        02205000
       tos:=callcmplt;                                                  02210000
       go to bend;                                                      02215000
     end;                                                               02220000
   end;                                                                 02225000
   tos:=drtn;                                                           02230000
   assemble(tio 0);                                                     02235000
   if < then go ufail;                                                  02240000
   tos:=clear ;  <<clear interrupts>>                                   02245000
   assemble(cio 2);                                                     02250000
   if <> then go ufail;                                                 02255000
   stat1:=tos;                                                          02260000
   if stat1.(11:1) =1 then                                              02265000
   begin     <<transfer error interrupt>>                               02270000
     tos:=xfererr;                                                      02275000
     tos:=endio;                                                        02280000
     go fail;                                                           02285000
   end;                                                                 02290000
   if stat1.(12:1) =1 then                                              02295000
   begin     <<timeout>>                                                02300000
     tos:=timeout;                                                      02305000
     tos:=endio;                                                        02310000
     go fail;                                                           02315000
   end;                                                                 02320000
   tos:=logical (stat1) land %100100;                                   02325000
   if < then go welldone else                                           02330000
   begin     <<not ready>>                                              02335000
notrdy:                                                                 02340000
     ldevnotrdy(ditp);                                         <<0u.eb>>02345000
     masterclear(ditp);                                                 02350000
     tos:=%30;                                                          02355000
     tos:=reinit;                                                       02360000
     go bend;                                                           02365000
   end;                                                                 02370000
   go welldone;                                                         02375000
                                                                        02380000
if func < 5 then go welldone;                                           02385000
$page                                                                   02390000
<<  c o m p l e t o r  i n v a l i d  >>                                02395000
                                                                        02400000
<< if you get here function is invalid.should not happen>>              02405000
invfunc:                                                                02410000
   tos:=invalid;                                                        02415000
   tos:=endio;                                                          02420000
   go bend;                                                             02425000
                                                                        02430000
end;     <<plotdrvr>>                                                   02435000
<< d r i v e r  l i n k a g e  a r e a >>                               02440000
                                                                        02445000
assemble(                                                               02450000
         pcal siodm;          <<monitor>>                               02455000
         pcal plotdrvr;       <<initiator>>                             02460000
         pcal plotdrvr;       <<completor>>                             02465000
         con 0;               <<no i/o process>>                        02470000
         pcal initz;          <<initialization>>                        02475000
         con 1;               <<1 interrupt handler>>                   02480000
         pcal gip);           <<interrupt handler>>                     02485000
end.                                                           <<02654>>02490000
