DataMuseum.dk

Presents historical artifacts from the history of:

RC4000/8000/9000

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about RC4000/8000/9000

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦ef4b8a237⟧ Rc489k_TapeFile, TextFile

    Length: 9216 (0x2400)
    Types: Rc489k_TapeFile, TextFile

Derivation

└─⟦aa55fa693⟧ Bits:30007479 SW8110/1 TAS/SOS/PRIMO Rel 2.3
    └─⟦this⟧ 

TextFile

external integer procedure transfer(action, ipar, ileng, opar, oleng);
integer                             action,       ileng,       oleng;
integer array                               ipar,        opar;

begin
integer treply, tno, tname, tuser, tsend, treceiv, tktype, tkgroup,
        tkname, treser, tserr, trerr,
        tsubno, tsubst, tsubpos, tsubtime, tcause, terrst,
        tleng, level, nlevel, rectype, form, size, stackix,
       bytes,start, ecode, i;
integer field zix;
integer array descr(1:42), stack(1:10), ia(1:20);
zone z(50,1,stderror);

boolean test;


procedure putheader(type, level, form, size);
integer             type, level, form, size;

<* the four parameters is packed into one integer to give
 * a header. this is placed in primo parameter record pointed
 * out by zix. *>

begin zix := zix + 2;
      z.zix := type shift 12 +level shift 8
             + form shift 4 + size;
end;


procedure putfield(ix, size);
integer            ix, size;

<* moves the field pointed at by ix,size to primo parameter
 * record pointed out by zix. *>

begin integer i;
      
      for i:=0 step 1 until size-1 do
      begin zix := zix + 2;
            z.zix := ipar(ix+i);
     end;
end;


integer procedure gethdr(rectype, level, form, size);
integer                  rectype, level, form, size;

<* unpack a header pointed out in primo answer record and
 * delivers the components in the procedure parameters.
 * at entry zix points to the last delivered header in
 * primo record. *>

begin own integer oform,osize;
      integer field i;
    
      i := zix + 2;
      zix := if zix = 0 then 2 else zix + 2 + (case oform+1 of
             (osize, osize, 0, 0, z.i+1, z.i+1, 1, 0)) * 2;
      if zix > bytes then gethdr := 0 else
      begin
         gethdr := 1;
         rectype := z.zix shift (-12);
         level := z.zix shift (-8) extract 4;
         form  := oform := z.zix shift (-4) extract 4;
         size  := osize := z.zix extract 4;
      end;
end;


procedure getfield (ix, osize);
integer             ix, osize;

<* moves the field described in primo header pointed out by
 * zix,form,size to the user parameter area pointed out by
 * ix,osize. *>

begin integer field jf;
      integer i,n;

      if form = 2 then opar(ix) := size else
      begin
         jf := zix + 2;
         if form = 0 or form = 1 then n := max(size,osize) else
         if form = 4 or form = 5 then
         begin n := max(z.jf,osize);
               jf := zix + 2;
         end else  n := 1;
         for i := 0 step 1 until n-1 do
         begin  opar(ix + i) := z.jf;
               jf := jf + 2;
         end;
      end;
end;


integer procedure max(a, b);
integer               a, b;
begin
      max := if a > b then a else b;
end;


procedure testout(start, length);
integer           start, length;
begin integer array mov(1:length);
      integer i, j;

      system(5,start,mov);
      for i := 0 step 1 until 4 do
            write(out,<:<10>mess:>,<<d>,i,<<dddddddd>,ia(i+4));
      write(out,<:<10><10>record:<10>decimal     grouped:>);
      for i := 1 step 1 until length do
      begin write(out,<:<10>:>,<<dddddddd>,mov(i),<:   :>);
            for j := -20 step 4 until 0 do
                write(out,<<dddd>,mov(i) shift j extract 4);
      end;
end;



<* build record format for the user delivered parameter
 * area ipar and opar. *>

<* generel header, common to all records. *>

   treply := 1; tno := 2; tname := 3; tuser:= 9;

<* define transport.*>

   tsend := 21; treceiv := 26;
   tktype := 30; tkgroup := 31; tkname := 35;

<* answer define transport. *>

   treser := 7; tserr := 8; trerr := 10;

<* answer get transport state. *>

   tsubno := 20; tsubst := 21; tsubpos := 22;
   tsubtime := 24; tcause := 25; terrst := 26;

<* the data handled to primo is build in the
 * zone z. the fields are moved one by one, and
 * the field variable zix points to the last used
 * integer in the zone record. *>

   zix := 0;


<* the array descr gives the definition of which of 
 * the records in the primo output data is of interest.
 * it is represented as a tree structure, each node
 * occupies 2 words giving the value of an accepted
 * record type in the first word . in the second word
 * is either an action number or a pointer of the
 * description of the nodes on the next level. *>

   for i:= 1 step 1 until 42 do descr(i) := case i of
      (3, 11, 5, 23, 7, 23, 9, 41, -11, 41,
       1, -1, 3, -2, -4, 17,
       1, -3, 3, -4, -4, -5,
      4, 17, 1, -1, 3, -2, -1000, 31,
       -3, 33,
       4, -6, 5, -7, 6, -7, -7, -8,
       -4, 17);


<* make the zone ready for communication with primo. *>

  test := false;
 
   open(z, 0, <:primo:>, 0);
   outrec(z,50);

   if action = 2 then

<* define transport *>
   begin  ecode := 8;
      if ileng <30 or oleng < 11 then goto ereturn;
      putheader(2,0,0,0);      <*define transport*>
      putheader(1,1,0,4);         <*transport name*>
      putfield(tname,4);
      putheader(2,1,0,4);         <*user ident*>
      putfield(tuser,4);
      putheader(1000,1,0,0);      <*record subtransport*>
      putheader(1,2,0,0);            <*sender device*>
      putheader(2,3,0,4);              <*name*>
      putfield(tsend,4);
      putheader(2,2,0,0);           <*receiver device*>
      putheader(2,3,0,4);              <*name*>
      putfield(treceiv,4);

      tleng := ileng - 20;
      while ipar(tktype) <> -1 do
      begin ecode := 8;
         if tleng < 9 or zix > 200-26 then goto ereturn;
         ecode := 9;
         if ipar(tktype) <> 0 then goto ereturn;
         putheader(3,3,0,0);            <*queues*>
         putheader(1,4,0,4);               <*group id*>
         putfield(tkgroup,4);
         putheader(3,4,0,4);               <*name*>
         putfield(tkname,4);
         tktype := tktype + 9;
         tkgroup := tkgroup + 9;
         tkname := tkname + 9;
         tleng := tleng - 9;
     end;
   end else

   if action = 4 or action = 6 or action = 8 or action=10 then

<* get state of transport, wait and get state of transport,
 *  release transport and kill transport. *>

   begin
      tleng := if action = 8 or action = 10 then 7 else 9;
      ecode := 8; if ileng < tleng then goto ereturn;
      tleng := if action = 8 or action = 10  then 6 else 26;
      if oleng < tleng then goto ereturn;
      putheader(action,0,0,0);         <*record type*>
     putheader(3,1,0,1);                 <*transport no*>
      putfield(tno,1);
   end else

<* unknown action. *>

   begin ecode := 7; goto ereturn; end;

<* build primo message in share. *>

   repeat                  <* until status <> stopped *>
      getzone(z,ia); i:=ia(19);
      getshare(z, ia, 1);
      i := i + ia(2);
      ia(4):= 7 shift 12;         <*operation:=output-input*>
      ia(5) := i;             <*first output*>
      ia(6) := i + zix - 2;    <*last output *>
      ia(7) := i;             <*first input = first output*>
      ia(8) := i + 200-2;   <*last input = max*>
      setshare(z,ia,1);
      if test then testout(i, zix//2);
      ecode := 6;              <*send message*>
      if monitor(16, z, 1, ia) = 0 then goto ereturn;
      ecode := monitor(18, z, 1, ia);
      if ecode <> 1 then goto ereturn;
   until ia(1) = 0;
   bytes := ia(2);
   if test then testout(i,bytes//2);

<* clear user buffer*>

   for i:= 1 step 1 until oleng do opar(i) := -1;


<* translate primo dataformat to user output format.
 * array descr gives the structure for the fields
 * which has to be copied to the user area .*>

   ecode := level := zix := 0;
   stackix := 1;
   stack(stackix) := 1;

rep1:
<* look in primo data for a header with level <=
 * current level (nlevel).*>

   repeat
      if gethdr(rectype, nlevel, form, size) = 0 then goto ereturn;
   until nlevel <= level;

<* unstack description until level becomes nlevel in current
 * primo header. *>
   stackix := stackix - (level - nlevel);
   level := nlevel;
   start := stack(stackix);

<* search in description(level) for record typr.*>

   for i := start, i+2 while descr(i-2) > 0 do
   if rectype = abs(descr(i)) then goto found;
   goto rep1;

found:

<* check if the description tree is deeper, i.e.
 * there is one more level needed. *>;

   if descr(i+1) > 0 then
   begin stackix := stackix + 1;
      level := level + 1;
      stack(stackix):= descr(i+1);
      goto rep1;
   end else
  begin


<* a parameter field has to be moved acording to
 * action number. *>

      case -descr(i+1) of
     begin
      getfield(tname,4);
      getfield(tno,1);
      getfield(treply,1);
      getfield(tserr,2);
      getfield(trerr,2);
      begin opar(tsubno) := 1;
            getfield(tsubst,1);
      end;
      getfield(tcause,1);
      getfield(tsubpos,2);
     end;
  end;
   goto rep1;

ereturn:
   getzone(z, ia);
   ia(13):= 0;         <*zone state*>
   setzone(z, ia);
   close(z,true);
   transfer := ecode;
if test then
begin write(out,<:<10>transfer = :>, <<ddd>,ecode);
      for i := 1 step 1 until oleng do
      write(out,<:<10>:>, <<ddddddddd>, opar(i));
end;
end; end;
▶EOF◀