program monitors;
 
(* this an example showing 5 processes: two of them are in fact monitors, one controls the screen=ekran *)

  unit ANSI: class;  
  (* CHECK whether config.sys contains a line device=ansi.sy the class ANSI enables operations on cursor, and bold, blink, underscore etc. *) 
                               
  unit Bold : procedure;
  begin
    write( chr(27), "[1m")
  end Bold;
    
  unit Blink : procedure;
  begin
    write( chr(27), "[5m")
  end Blink;
  
  unit Reverse : procedure;
  begin
    write( chr(27), "[7m")
  end Reverse;

  unit Normal : procedure;
  begin
    write( chr(27), "[0m")
  end Normal;
  
  unit Underscore : procedure;
  begin
    write( chr(27), "[4m")
  end Underscore;

  unit inchar : IIUWgraph function : integer;
    (*podaj nr znaku przeslanego z klawiatury *)
    var i : integer;
  begin
    do
      i := inkey;
      if i <> 0 then exit fi;
    od;
    result := i;
  end inchar;
  
  unit NewPage : procedure;
  begin
    write( chr(27), "[2J")
  end NewPage;
  
  unit  SetCursor : procedure(row, column : integer);
    var c,d,e,f  : char,
        i,j : integer;
  begin
    i := row div 10;
    j := row mod 10;
    c := chr(48+i);
    d := chr(48+j);
    i := column div 10;
    j := column mod 10;
    e := chr(48+i);
    f := chr(48+j);
    write( chr(27), "[", c, d, ";", e, f, "H")
  end SetCursor;        
end ANSI;

  
    unit monitor:  process(node:integer, size:integer,e: ekran);

       var buf: arrayof integer,
           nr,i,j,k1,k2,n1,n2: integer;

	
    unit lire: procedure(output k: integer);
    begin
      call e.druk(13,2+nr*30+k1,0,k2);
      call e.druk(13,2+nr*30+(i-1)*6,1,buf(i));
      k1:=(i-1)*6;
      k:=buf(i);
      k2:=k;
      i:= (i mod size)+1;
      if i=j
      then
        call e.printtext("i equal j")
      fi; 
    end lire;
    
    unit ecrire: procedure(n:integer);
    begin
      call e.druk(13,2+nr*30+n1,0,n2);
      call e.druk(13,2+nr*30+(j-1)*6,2,n);
      n1:=(j-1)*6;
      buf(j) := n;
      n2:=buf(j);
      j := (j mod size)+1;
      if i=j
      then
        call e.printtext("j equal i")
      fi; 
    end ecrire;
  begin
    array buf dim(1:size);
    nr := size - 4;
    for i := 1 to size
    do
      buf(i) :=  i+nr*4;
      call e.druk(13,2+nr*30+(i-1)*6,0,buf(i));
    od;
    i:=1;  
    j := size;
    k1:=0;
    k2:=buf(1);
    n1:=(size-1)*6;
    n2:=buf(size);
    (* end initialize buffer *)
    return;
    
    do
      accept lire, ecrire
    od
  end monitor;
  
  unit prcs:  process(node,nr:integer, mleft,mright:
							 monitor, e: ekran);
    var l,o: integer;

  begin
    call e.SetCursor(8+(nr-1)*10,29);
    if nr = 1
    then
      call e.printtext("<-- p1 <--");
    else
      call e.printtext("--> p2 -->");
    fi;    
    return;
    do
      call mleft.lire(l) ;
      call e.druk(11+(nr-1)*4,31-(nr-1)*8,1,l);
      l:= l+1;
      call mright.ecrire(l) ; 
      call e.druk(10+(nr-1)*6,23+(nr-1)*8,2,l);
      if l mod 15 = 0 
      then
        o:= e.inchar;
	      if o = -79 then call endrun fi;
      fi;	
    od;
  end prcs;
  
unit ekran : ANSI process(nrprocesora: integer);
    unit printtext: procedure(s:string);
    begin
      write(s);
      call Normal;
    end printtext;

    unit  druk: procedure(gdzieW,gdzieK,jak,co:integer);
    begin
      call SetCursor(gdzieW,gdzieK);
      write("   ");
      if jak=0 then call Normal else
        if jak=1 then call Reverse else
          if jak=2 then call Bold 
          fi
        fi
      fi;
      write(co:3);
      call Normal;
    end druk;

    unit print: procedure (i:integer);
    begin
      write(i:4)
    end print;
  begin
    return;
    
    do accept inchar, 
              Normal,NewPage, SetCursor, Bold, Underscore,
	      Reverse, Blink, print, printtext, druk
    od
  end ekran;
  
var m1,m2:monitor,
    e:ekran,
    p1,p2:prcs;
     
begin     (* ----- HERE IS THE MAIN PROGRAM ----- *)
  (* create a  configuration *)
  e:= new ekran(0);
  resume(e);
  call e.Normal;
  call e.NewPage;
  m1 := new monitor(0,4,e);
  m2 := new monitor(0,5,e);
  
  p1 := new prcs(0,1,m2,m1,e);
  p2 := new prcs(0,2,m1,m2,e);
    
  resume(m1);
  resume(m2);
  resume(p1);
  resume(p2);
end monitors;