program GRAPHICS; (* by Doug Cox for an Osborne *)
label A, B;
(* const ScreenTop: Integer= $F000;
type
  Row= 1..24; Col= 1..128;
  PointerType= ^ScreenPointer;
  ScreenPointer= Array[Row, Col] of Byte; *)
var
(* p     : PointerType ABSOLUTE ScreenTop; *)
  square : Array[1..80,1..23] of Char;
  ch     : Char;
  x,y,z  : Integer;
  fv     : Text;
  ok     :  Boolean;

procedure GetGraphics;
begin
  Assign (fv, 'GRAPHICS.DTA');
  {$I-} Reset (fv); {$I+}
  ok:= (IOresult= 0);
  if ok then
  begin
    write (#27#103);
    while not Eof (fv) do
    begin
      readln (fv, x, y, ch);
      GotoXY(x,y); write (ch); (* or p^[y,x]:= Ord(ch)-96; *)
      square[x,y]:= ch;
    end;
    write (#27#71);
    Close (fv);
  end;
end;

begin
ClrScr;
write (#27#103); (* start graphics *)
write ('u h j y v q a z x w e d c g t f r b n m ` k i | { p  ',^_,' o ~ l');
writeln (#27#71); (* end graphics *)
write ('u h j y v q a z x w e d c g t f r b n m ` k i | { p ^_ o ~ l');
GotoXY(1,24); write (' /S to SAVE  /Q to QUIT ');
FillChar (square, SizeOf(square), ' ');
GetGraphics;
x:= 26; y:= 12; ch:= ' ';
repeat
A:
  GotoXY(28,24); ClrEol; write (' Char= ',ord(ch),' ');
  GotoXY(41,24); ClrEol; write (' X= ',x,' ','Y= ',y,' ');
  GotoXY(57,24); ClrEol; write (' ESC to Clear Line ');
  GotoXY(x,y); read (Kbd, ch);
  case ch of
    ^D : begin
           if x < 80 then x:= x+1 else x:=80;
           GotoXY(x,y);
         end;
    ^X : begin
           if y < 23 then y:= y+1 else y:= 23;
           GotoXY(x,y);
         end;
    ^S : begin
           if x > 1 then x:= x-1 else x:= 1;
           GotoXY(x,y);
         end;
    ^E : begin
           if y > 1 then y:= y-1 else y:= 1;
           GotoXY(x,y);
         end;
    ^F : begin if x < 70 then x:= x+10 else x:= 80; GotoXY(x,y); end;
    ^A : begin if x > 10 then x:= x-10 else x:= 1; GotoXY(x,y); end;
    ^R : begin if y > 5 then y:= y-5 else y:= 1; GotoXY(x,y); end;
    ^C : begin if y < 18 then y:= y+5 else y:= 23; GotoXY(x,y); end;
    ^M : begin
           if (x > 1) and (x < 80) then x:= x-1;
           if y < 23 then y:= y+1;
           GotoXY(x,y);
         end;
    ^[ : begin
           GotoXY(1,y); ClrEol; GotoXY(x,y);
           for z:= 1 to 80 do square[z,y]:= ' ';
         end;
  else if ch <> '/' then
  begin
    if ch= ^H then
    begin
      if x > 1 then x:= x-1 else x:= 1;
      GotoXY(x,y); write (' ');
      square[x,y]:= ' ';
    end
    else
    begin
      write (#27#103);
      write (ch);
      write (#27#71);
      square[x,y]:= ch;
      if x < 80 then x:= x+1;
    end;
  end;
  end; (* of Case *)
until ch= '/';
GotoXY(28,24); ClrEol; write (ch); read (Kbd, ch); ch:= UpCase(ch);
if ch= 'S' then
begin
B:write ('Saving "Graphics.Dta"...');
  Assign (fv, 'GRAPHICS.DTA'); Rewrite (fv);
  for x:= 1 to 80 do
    for y:= 1 to 23 do
      if square[x,y] <> ' ' then writeln (fv, x,' ',y,' ',square[x,y]);
  Close (fv);
end
else if ch= 'Q' then
begin
  write ('Quit without saving (Y/N)? ');
  repeat
    read (Kbd, ch); ch:= UpCase(ch);
  until (ch= 'N') or (ch='Y');
  if UpCase(ch)= 'N' then Goto B;
end
else Goto A;
ClrScr;
end.
