(****************************************************************************)
(*   Bibliotheks-Modul GRAFIK.BIB                                           *)
(*                                                                          *)
(* ( p Page(p:byte) : Waelt die Schreib- und Lese-Seite p an )              *)
(* t tzeich : Variable dieses Typs enthaelt ein Zeichen fuer CharOut        *)
(* t tstr : String mit 80 Zeichen ( eine Zeile )                            *)
(* p Move(x,y:integer) : Geht auf Position (x,y)                            *)
(* p Draw(x,y:integer) : Zeichnet von der aktuellen Position nach (x,y)     *)
(* p Line(x1,y1,x2,y2:integer) : zieht eine Linie von (x1,y1) nach (x2,y2)  *)
(* p Plot(x,y:integer) : setzt einen Punkt bei (x,y)                        *)
(* p Cmd(Reg,Bef:byte) : gibt and das GDP-Register Reg den Wert Bef aus     *)
(* p gPrint(x,y:integer; c:char) : gibt einen Text aus                      *)
(* p CharOut(x,y:integer; c:tzeich) : gibt Zeichen in einer 8x12 Matrix aus *)
(* p Maus(var x,y:integer; taste:byte) : liefert die aktuelle Maus-         *)
(*                                       koordinate und gedrueckte Tasten   *)
(* p Kreuz(x,y:integer) : setzt das Fadenkreuz auf die Position (x,y)       *)
(*                                                                          *)
(*   Es wird immer auf beide Bildschirmseiten gezeichnet, damit die Grafik  *)
(*   nicht blinkt.                                                          *)
(****************************************************************************)

type tzeich = array[0..15] of integer;
     tstr = string[80];

const pixx = 15; (* Pixelzahl fuer CharOut *)
      pixy = 15;

procedure page(pw,pr:byte);
  begin
    inline($3a/pw/$4f/$cd/$4c/$f0/$3a/pr/$4f/$cd/$4f/$f0);
  end;

procedure move(x,y:integer);
  begin
    inline( $2a/x/$ed/$5b/y/$cd/$46/$f0 );
  end;

procedure draw(x,y:integer);
  begin
    inline( $2a/x/$ed/$5b/y/$cd/$49/$f0 );
  end;

procedure line(x1,y1,x2,y2:integer);
  begin
    page(0,0); move(x1,y1); draw(x2,y2);
    page(1,1); move(x1,y1); draw(x2,y2);
  end;

procedure cmd(reg,bef:byte);
  begin
    reg:=reg+$70;
    inline( $cd/$55/$f0/$3a/reg/$4f/$3a/bef/$ed/$79 );
  end;

procedure plot(x,y:integer);
  begin
    move(x,y);
    page(0,1); cmd(0,$80);
    page(1,1); cmd(0,$80);
  end;

procedure gprint(x,y:integer; txt:tstr);
  var i:integer;

  procedure print(x,y:integer; c:char);
    begin
      move(x,y); page(0,0); cmd(0,ord(c));
      move(x,y); page(1,1); cmd(0,ord(c));
    end;

  begin
    for i:=1 to length(txt) do begin
      print(x,y,txt[i]); x:=x+6 end;
  end;

procedure maus(var x,y:integer; var taste:byte);
  var dx,dy : integer;
  begin
    port[$8d]:=0; port[$8e]:=0;
    dx:=port[$8e]-port[$8f];
    dy:=port[$8c]-port[$8d];
    x:=x+dx; y:=y+dy;
    taste:=255-port[$8b];
  end;

procedure kreuz(x,y:integer);
  begin
    x:=x+191;
    y:=256-y;
    port[$88]:=255-hi(x);
    port[$89]:=255-lo(x);
    port[$8a]:=255-hi(y);
    port[$8b]:=255-lo(y);
  end;

procedure charout(x,y:integer; zeichen:tzeich);

  procedure out(x,y:integer; zeichen:tzeich);
    var i,j : integer;
        pix : byte;
    begin
      for i:=0 to pixy do
        begin
          move(x,y+i);
          for j:=0 to pixx do
            begin
              if j<8 then pix:=hi(zeichen[i]) else pix:=lo(zeichen[i]);
              if pix and ($80 shr (j mod 8)) = 0 then cmd(0,1) else cmd(0,0);
              cmd(0,$a8);
            end;
        end;
    end;
  begin
    page(0,0);
    out(x,y,zeichen);
    page(1,1);
    out(x,y,zeichen);
  end;
