program Matrix;

{ program nasobi matice A (MxN) a B (NxP) na C (MxP) }
{ pouziti asynchronnich schranek }

uses Kernel, Crt;

const
     MaxM = 10;
     MaxN = 10;
     MaxP = 10;

     RealMNP = 7;

     ColA = 1;
     RowA = 22;
     ColB = 39;
     RowB = 1;

     RowD = 2;
     ColD = 4;

     Max = 10;

type
    Elem = Integer;
    Index = Integer;

const
     ElemSize = SizeOf(Elem);

var
   A: array [1..MaxM,1..MaxN] of Elem;
   B: array [1..MaxN,1..MaxP] of Elem;
   C: array [1..MaxM,1..MaxP] of Elem;

   Ver,Hor: array [1..MaxM,1..MaxP] of MailBox;

   M,N,P: Index;

   StrCol, StrRow : String;

procedure Generate;
var Col,Row: Integer;
    E: Elem;
begin
     for Row := 1 to M do
     begin
         for Col := 1 to N do
         begin
              GotoXY(ColA+ColD*(Col-1), RowA+Rowd*Row);
              E := Integer(Random(Max)) - Max div 2;
              Write(E:ColD-1);
              A[Row, Col] := E;
         end;
         Write('  |');
     end;
     for Row := 1 to N do
         for Col := 1 to P do
         begin
              GotoXY(ColB+ColD*(Col-1), RowB+RowD*Row);
              E := Integer(Random(Max)) - Max div 2;
              Write(E:ColD-1);
              B[Row, Col] := E;
         end;
     GotoXY(ColB,RowA);
     for Col := 1 to N*ColD do Write('-');
     for Row := 1 to M do
         for Col := 1 to P do
         begin
              GotoXY(ColB+ColD*(Col-1), RowA+RowD*Row);
              Write(0:ColD-1);
              C[Row, Col] := 0;
         end;
end {Generate};

procedure Inc(I,Row,Col: Index; Val: Elem);
begin
     System.Inc(C[Row,Col], Val);
     Lock;
     TextColor(I);
     GotoXY(ColB+ColD*(Col-1), RowA+RowD*Row);
     Write(C[Row,Col]:ColD-1);
     Unlock;
end {Inc};

{$F+}
procedure Vertical(Pri: Integer; Col: Index);
var Row,I: Index;
begin
     Start('Vertical', 1000, 100, Pri); Exit;
     for Row := N downto 1 do
     begin
          Send(Ver[1,Col], B[Row,Col], ElemSize);
          Lock;
          GotoXY(ColB+ColD*(Col-1), RowB+RowD*(N-Row+1));
           Write(' ':ColD-1);
          Unlock;
          for I := 1 to Row-1 do
          begin
               Lock;
               GotoXY(ColB+ColD*(Col-1), RowB+RowD*(I+N-Row+1));
               TextAttr := 2;
               Write(B[I, Col]:ColD-1);
               Unlock;
          end;
          Delay(50);
     end;
end {Vertical};

procedure Horizontal(Pri: Integer; Row: Index);
var Col,I: Index;
begin
     Start('Horizontal', 1000, 100, Pri); Exit;
     for Col := N downto 1 do
     begin
          Send(Hor[Row,1], A[Row,Col], ElemSize);
          Lock;
          GotoXY(ColA+ColD*(N-Col), RowA+RowD*Row);
          Write(' ':ColD-1);
          Unlock;
          for I := 1 to Col-1 do
          begin
               Lock;
               GotoXY(ColA+ColD*(I+N-Col), RowA+RowD*Row);
               TextAttr := 2;
               Write(A[Row, I]:ColD-1);
               Unlock;
          end;
          Delay(50);
     end;
end {Horizontal};


procedure Cell(Row, Col: Index);
var X,Y: Elem;
    I: Index;
    SRow,SCol: String[1];
begin
     Str(Row,SRow);
     Str(Col,SCol);
     Start('Cell'+SRow+SCol, 1000, 100, 200); Exit;
     for I := 1 to N do
       begin
         if Arrived(Hor[Row,Col], X, ElemSize) then
            begin
             if Arrived(Ver[Row,Col], Y, ElemSize) then
             else Accept;
            end
         else if Arrived(Ver[Row,Col], Y, ElemSize) then
            begin
             if Arrived(Hor[Row,Col], X, ElemSize) then
             else Accept;
            end
         else Accept;
         Inc(I, Row, Col, X*Y);
         Delay(50);
         if Col<RealMNP then
          Send(Hor[Row,Col+1], X, ElemSize);
         if Row<RealMNP then
          Send(Ver[Row+1,Col], Y, ElemSize);
       end;
end {Cell};

var Row,Col: Index;
PM : _MailBoxPtr;

begin
     StartMain(1000, 0);
     InitInterruptStack(1, 128);
     StartTimeSlicing(8);
     TextMode(259);
     TextAttr := 2;
     ClrScr;
     M := RealMNP;
     N := RealMNP;
     P := RealMNP;
     for Row := 1 to M do
      for Col := 1 to P do
       begin
        Str(Row, StrRow); Str(Col, StrCol);
        InitDynMailBox(Ver[Row,Col], 'Ver,'+StrRow+','+StrCol, ElemSize, Normal);
        InitDynMailBox(Hor[Row,Col], 'Hor,'+StrRow+','+StrCol, ElemSize, Normal);
       end;
     RandSeed := 1;
     Generate;
     for Row := 1 to M do Horizontal(14*(N-Row+1), Row);
     for Col := 1 to P do Vertical(14*(N-Col+1), Col);
     GotoXY(1, 10);
     TextAttr:=Yellow;
     Writeln('   Ukazka paralelniho');
     Writeln;
     Writeln('   systolickeho nasobeni matic');
     for Row := 1 to M do
         for Col := 1 to P do
              Cell(Row, Col);
     TerminateMain;
     repeat
     until KeyPressed;
     TextMode(3);
end.