home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / MINICRT.ZIP / MINICRT.PAS next >
Encoding:
Pascal/Delphi Source File  |  1987-12-20  |  6.5 KB  |  300 lines

  1.  
  2. (*
  3.  * MiniCrt - simplified version of Borland's CRT unit.
  4.  * Does not EVER do direct video.  The standard crt unit
  5.  * locks up multi-taskers with its direct video checking before
  6.  * the user program can turn it off.
  7.  *
  8.  * Samuel H. Smith, 20-dec-87
  9.  *
  10.  *)
  11.  
  12. unit MiniCrt;
  13.  
  14. {$S-,I-,R-}
  15.  
  16. interface
  17.  
  18.    uses
  19.       Dos;
  20.  
  21.    var
  22.       stdout:    text;
  23.  
  24.    function KeyPressed: Boolean;
  25.    function ReadKey: Char;
  26.  
  27.    procedure Window(X1,Y1,X2,Y2: Byte);  {only partial support}
  28.  
  29.    procedure GotoXY(X,Y: Byte);
  30.    function WhereX: Byte;
  31.    function WhereY: Byte;
  32.  
  33.    procedure ClrScr;
  34.    procedure ClrEol;
  35.  
  36.    procedure NormalVideo;
  37.    procedure ReverseVideo;
  38.    procedure BlinkVideo;
  39.  
  40.  
  41.    (* -------------------------------------------------------- *)
  42.    procedure ScrollUp;
  43.    {$F+} function ConFlush(var F: TextRec): integer; {$F-}
  44.    {$F+} function ConOutput(var F: TextRec): integer; {$F-}
  45.    {$F+} function ConOpen(var F: TextRec): Integer; {$F-}
  46.  
  47.  
  48. (* -------------------------------------------------------- *)
  49. implementation
  50.  
  51.    const
  52.       sign_flag  = $80;
  53.       zero_flag  = $40;
  54.       carry_flag = $01;
  55.  
  56.       window_y1 : byte = 1;
  57.       window_y2 : byte = 25;
  58.       attribute : byte = $0f;
  59.  
  60.       key_pending: char = #0;
  61.  
  62.  
  63.    (* -------------------------------------------------------- *)
  64.    function ReadKey: Char;
  65.    var
  66.       reg: registers;
  67.    begin
  68.       if key_pending <> #0 then
  69.       begin
  70.          ReadKey := key_pending;
  71.          key_pending := #0;
  72.          exit;
  73.       end;
  74.  
  75.       reg.ax := $0000;   {wait for character}
  76.       intr($16,reg);
  77.  
  78.       if reg.al = 0 then
  79.          key_pending := chr(reg.ah);
  80.  
  81.       ReadKey := chr(reg.al);
  82.    end;
  83.  
  84.  
  85.    (* -------------------------------------------------------- *)
  86.    function KeyPressed: Boolean;
  87.    var
  88.       reg: registers;
  89.    begin
  90.       reg.ax := $0100;   {check for character}
  91.       intr($16,reg);
  92.       KeyPressed := ((reg.flags and zero_flag) = 0) or (key_pending <> #0);
  93.    end;
  94.  
  95.  
  96.    (* -------------------------------------------------------- *)
  97.    procedure Window(X1,Y1,X2,Y2: Byte);
  98.    begin
  99.       window_y1 := y1;
  100.       window_y2 := y2;
  101.    end;
  102.  
  103.  
  104.    (* -------------------------------------------------------- *)
  105.    procedure GotoXY(X,Y: Byte);
  106.    var
  107.       reg: registers;
  108.    begin
  109.       if (x < 1) or (y < 1) or (x > 80) or (y > 25) then
  110.          exit;
  111.       reg.ah := 2;   {set cursor position}
  112.       reg.bh := 0;   {page}
  113.       reg.dh := y-1;
  114.       reg.dl := x-1;
  115.       intr($10,reg);
  116.    end;
  117.  
  118.  
  119.    (* -------------------------------------------------------- *)
  120.    function WhereX: Byte;
  121.    var
  122.       reg: registers;
  123.    begin
  124.       reg.ah := 3;
  125.       reg.bh := 0;
  126.       intr($10,reg);
  127.       WhereX := reg.dl+1;
  128.    end;
  129.  
  130.    function WhereY: Byte;
  131.    var
  132.       reg: registers;
  133.    begin
  134.       reg.ah := 3;
  135.       reg.bh := 0;
  136.       intr($10,reg);
  137.       WhereY := reg.dh+1;
  138.    end;
  139.  
  140.  
  141.    (* -------------------------------------------------------- *)
  142.    procedure ClrScr;
  143.    var
  144.       reg: registers;
  145.    begin
  146.       reg.ah := 6;  {scroll up}
  147.       reg.al := 0;  {blank window}
  148.       reg.cx := 0;  {upper left}
  149.       reg.dh := 25; {lower line}
  150.       reg.dl := 79; {lower column}
  151.       reg.bh := attribute;
  152.       intr($10,reg);
  153.       GotoXY(1,1);
  154.    end;
  155.  
  156.  
  157.    (* -------------------------------------------------------- *)
  158.    procedure ClrEol;
  159.    var
  160.       reg: registers;
  161.    begin
  162.       reg.ah := 6;  {scroll up}
  163.       reg.al := 0;  {blank window}
  164.       reg.ch := wherey-1;
  165.       reg.cl := wherex-1;
  166.       reg.dh := reg.ch;
  167.       reg.dl := 79; {lower column}
  168.       reg.bh := attribute;
  169.       intr($10,reg);
  170.    end;
  171.  
  172.  
  173.    (* -------------------------------------------------------- *)
  174.    procedure NormalVideo;
  175.    begin
  176.       attribute := $0f;
  177.    end;
  178.  
  179.    procedure ReverseVideo;
  180.    begin
  181.       attribute := $70;
  182.    end;
  183.  
  184.    procedure BlinkVideo;
  185.    begin
  186.       attribute := $F0;
  187.    end;
  188.  
  189.  
  190.    (* -------------------------------------------------------- *)
  191.    procedure ScrollUp;
  192.    var
  193.       reg: registers;
  194.    begin
  195.       reg.ah := 6;  {scroll up}
  196.       reg.al := 1;  {lines}
  197.       reg.cx := 0;  {upper left}
  198.       reg.dh := window_y2-1; {lower line}
  199.       reg.dl := 79;        {lower column}
  200.       reg.bh := attribute;
  201.       intr($10,reg);
  202.    end;
  203.  
  204.  
  205.    (* -------------------------------------------------------- *)
  206.    {$F+} function ConFlush(var F: TextRec): integer; {$F-}
  207.    var
  208.       P:   Word;
  209.       reg: registers;
  210.       x,y: byte;
  211.  
  212.    begin
  213.       {get present cursor position}
  214.       reg.ah := 3;
  215.       reg.bh := 0;
  216.       intr($10,reg);
  217.       y := reg.dh+1;
  218.       x := reg.dl+1;
  219.  
  220.       {process each character in the buffer}
  221.       P := 0;
  222.       while P < F.BufPos do
  223.       begin
  224.          reg.al := ord(F.BufPtr^[P]);
  225.  
  226.          case reg.al of
  227.             10:  if y >= window_y2 then   {scroll when needed}
  228.                     ScrollUp
  229.                  else
  230.                     inc(y);
  231.  
  232.             13:  x := 1;
  233.  
  234.             else 
  235.             begin
  236.                  reg.ah := 9;  {display character with attribute}
  237.                  reg.bx := 0;  {... does not move the cursor}
  238.                  reg.cx := 1;
  239.                  reg.bl := attribute;
  240.                  intr($10,reg);
  241.  
  242.                  if x = 80 then   {line wrap?}
  243.                  begin
  244.                     x := 1;
  245.                     if y >= window_y2 then   {scroll during wrap?}
  246.                        ScrollUp
  247.                     else
  248.                        inc(y);
  249.                  end
  250.                  else
  251.                     inc(x);
  252.             end;
  253.          end;
  254.  
  255.          {position physical cursor}
  256.          reg.ah := 2;   {set cursor position}
  257.          reg.bh := 0;   {page}
  258.          reg.dh := y-1;
  259.          reg.dl := x-1;
  260.          intr($10,reg);
  261.  
  262.          inc(P);
  263.       end;
  264.  
  265.       F.BufPos:=0;
  266.       ConFlush := 0;
  267.    end;
  268.  
  269.  
  270.    {$F+} function ConOutput(var F: TextRec): integer; {$F-}
  271.    begin
  272.       ConOutput := ConFlush(F);
  273.    end;
  274.  
  275.  
  276.    {$F+} function ConOpen(var F: TextRec): Integer; {$F-}
  277.    begin
  278.       F.InOutFunc := @ConOutput;
  279.       F.FlushFunc := @ConFlush;
  280.       F.CloseFunc := @ConFlush;
  281.       F.BufPos := 0;
  282.       ConOpen := 0;
  283.    end;
  284.  
  285.  
  286.    (* -------------------------------------------------------- *)
  287. begin
  288.    with TextRec(output) do
  289.    begin
  290.       InOutFunc := @ConOutput;
  291.       FlushFunc := @ConFlush;
  292.       OpenFunc  := @ConOpen;
  293.       BufPos := 0;
  294.    end;
  295.  
  296.    assign(stdout,'con');
  297.    rewrite(stdout);
  298. end.
  299.  
  300.