mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 14:59:37 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			358 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			358 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{****************************************************************************
 | 
						|
 | 
						|
 | 
						|
                            Standard CRT unit.
 | 
						|
                    Free Pascal runtime library for OS/2.
 | 
						|
                    Copyright (c) 1997 Daniel Mantione.
 | 
						|
 | 
						|
      This file may be reproduced and modified under the same conditions
 | 
						|
                      as all other Free Pascal source code.
 | 
						|
 | 
						|
****************************************************************************}
 | 
						|
 | 
						|
unit crt;
 | 
						|
 | 
						|
interface
 | 
						|
 | 
						|
{$INLINE ON}
 | 
						|
 | 
						|
{$i crth.inc}
 | 
						|
 | 
						|
procedure Window32 (X1, Y1, X2, Y2: dword);
 | 
						|
procedure GotoXY32 (X, Y: dword);
 | 
						|
function WhereX32: dword;
 | 
						|
function WhereY32: dword;
 | 
						|
 | 
						|
 | 
						|
var
 | 
						|
 ScreenHeight, ScreenWidth: dword;
 | 
						|
(* API *)
 | 
						|
 | 
						|
 | 
						|
implementation
 | 
						|
 | 
						|
{uses keyboard, video;}
 | 
						|
 | 
						|
 | 
						|
{$i textrec.inc}
 | 
						|
 | 
						|
const
 | 
						|
 VioHandle: word = 0;
 | 
						|
 | 
						|
 | 
						|
type
 | 
						|
 TKbdKeyInfo = record
 | 
						|
  CharCode, ScanCode: char;
 | 
						|
  fbStatus, bNlsShift: byte;
 | 
						|
  fsState: word;
 | 
						|
  Time: longint;
 | 
						|
 end;
 | 
						|
 | 
						|
 VioModeInfo = record
 | 
						|
  cb: word;                         { length of the entire data
 | 
						|
                                               structure }
 | 
						|
  fbType,                          { bit mask of mode being set}
 | 
						|
  Color: byte;                     { number of colors (power of 2) }
 | 
						|
  Col,                             { number of text columns }
 | 
						|
  Row,                             { number of text rows }
 | 
						|
  HRes,                            { horizontal resolution }
 | 
						|
  VRes: word;                      { vertical resolution }
 | 
						|
  fmt_ID,                          { attribute format }
 | 
						|
  Attrib: byte;                    { number of attributes }
 | 
						|
  Buf_Addr,                        { physical address of
 | 
						|
                                               videobuffer, e.g. $0b800}
 | 
						|
  Buf_Length,                      { length of a videopage (bytes)}
 | 
						|
  Full_Length,                     { total video-memory on video-
 | 
						|
                                               card (bytes)}
 | 
						|
  Partial_Length: longint;          { ????? info wanted !}
 | 
						|
  Ext_Data_Addr: pointer;           { ????? info wanted !}
 | 
						|
 end;
 | 
						|
 | 
						|
 TVioCursorInfo=record
 | 
						|
  case boolean of
 | 
						|
   false: (
 | 
						|
        yStart: word;    {Cursor start (top) scan line (0-based)}
 | 
						|
        cEnd: word;      {Cursor end (bottom) scan line}
 | 
						|
        cx: word;        {Cursor width (0=default width)}
 | 
						|
        Attr: word);     {Cursor colour attribute (-1=hidden)}
 | 
						|
   true:(
 | 
						|
        yStartInt: integer; {integer variants can be used to specify negative}
 | 
						|
        cEndInt: integer; {negative values (interpreted as percentage by OS/2)}
 | 
						|
        cxInt: integer;
 | 
						|
        AttrInt: integer);
 | 
						|
 end;
 | 
						|
 PVioCursorInfo = ^TVioCursorInfo;
 | 
						|
 | 
						|
 | 
						|
function KbdCharIn (var AKeyRec: TKbdKeyInfo; Wait, KbdHandle: longint):
 | 
						|
                                                                   word; cdecl;
 | 
						|
                   external 'EMXWRAP' index 204;
 | 
						|
function KbdPeek (var AKeyRec: TKbdKeyInfo; KbdHandle: longint): word; cdecl;
 | 
						|
                 external 'EMXWRAP' index 222;
 | 
						|
 | 
						|
function DosSleep (Time: cardinal): word; cdecl;
 | 
						|
                  external 'DOSCALLS' index 229;
 | 
						|
function VioScrollUp (Top, Left, Bottom, Right, Lines: longint;
 | 
						|
                      var ScrEl: word; VioHandle: word): word; cdecl;
 | 
						|
                      external 'EMXWRAP' index 107;
 | 
						|
{$WARNING ScrEl as word not DBCS safe!}
 | 
						|
function VioScrollDn (Top, Left, Bottom, Right, Lines: longint;
 | 
						|
                      var ScrEl: word; VioHandle: word): word; cdecl;
 | 
						|
                      external 'EMXWRAP' index 147;
 | 
						|
function VioScrollRight (Top, Left, Bottom, Right, Columns: word;
 | 
						|
                                var ScrEl: word; VioHandle: word): word; cdecl;
 | 
						|
external 'EMXWRAP' index 112;
 | 
						|
{external 'VIOCALLS' index 12;}
 | 
						|
function VioGetCurPos (var Row, Column: word; VioHandle: word): word; cdecl;
 | 
						|
                       external 'EMXWRAP' index 109;
 | 
						|
function VioSetCurPos (Row, Column, VioHandle: word): word; cdecl;
 | 
						|
                       external 'EMXWRAP' index 115;
 | 
						|
function VioWrtCharStrAtt (S: PChar; Len, Row, Col: longint; var Attr: byte;
 | 
						|
                           VioHandle: word): word; cdecl;
 | 
						|
                           external 'EMXWRAP' index 148;
 | 
						|
function VioGetMode (var AModeInfo: VioModeInfo; VioHandle: word): word; cdecl;
 | 
						|
                     external 'EMXWRAP' index 121;
 | 
						|
function VioSetMode (var AModeInfo: VioModeInfo; VioHandle: word): word; cdecl;
 | 
						|
                     external 'EMXWRAP' index 122;
 | 
						|
function VioSetCurType (var CurData: TVioCursorInfo; VioHandle: word): word;
 | 
						|
                                                                         cdecl;
 | 
						|
external 'EMXWRAP' index 132;
 | 
						|
{external 'VIOCALLS' index 32;}
 | 
						|
function VioGetCurType (var CurData: TVioCursorInfo; VioHandle: word): word;
 | 
						|
                                                                         cdecl;
 | 
						|
external 'EMXWRAP' index 127;
 | 
						|
{external 'VIOCALLS' index 27;}
 | 
						|
function VioCreatePS (var VPS: word; Depth, Width, Format, Attrs: integer;
 | 
						|
                                                  Reserved: word): word; cdecl;
 | 
						|
external 'EMXWRAP' index 156;
 | 
						|
{external 'VIOCALLS' index 56;}
 | 
						|
function DosBeep (Freq, MS: cardinal): cardinal; cdecl;
 | 
						|
external 'DOSCALLS' index 286;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
threadvar
 | 
						|
  ExtKeyCode: char;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
function KeyPressed: boolean;
 | 
						|
{Checks if a key is pressed.}
 | 
						|
var
 | 
						|
 AKeyRec: TKbdKeyinfo;
 | 
						|
begin
 | 
						|
 if ExtKeyCode <> #0 then
 | 
						|
  KeyPressed := true
 | 
						|
 else
 | 
						|
  KeyPressed := (KbdPeek (AKeyRec, 0) = 0)
 | 
						|
                                         and ((AKeyRec.fbStatus and $40) <> 0);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function ReadKey: char;
 | 
						|
{Reads the next character from the keyboard.}
 | 
						|
var
 | 
						|
 AKeyRec: TKbdKeyInfo;
 | 
						|
 C, S: char;
 | 
						|
begin
 | 
						|
 if ExtKeyCode <> #0 then
 | 
						|
  begin
 | 
						|
   ReadKey := ExtKeyCode;
 | 
						|
   ExtKeyCode := #0
 | 
						|
  end
 | 
						|
 else
 | 
						|
  begin
 | 
						|
   KbdCharIn (AKeyRec, 0, 0);
 | 
						|
   C := AKeyRec.CharCode;
 | 
						|
   S := AKeyRec.ScanCode;
 | 
						|
   if (C = #224) and (S <> #0) then
 | 
						|
    C := #0;
 | 
						|
   if C = #0 then
 | 
						|
    ExtKeyCode := S;
 | 
						|
   ReadKey := C;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure GetScreenCursor (var X, Y: dword);inline;
 | 
						|
(* Return current cursor postion - 0-based. *)
 | 
						|
var
 | 
						|
 X0, Y0: word;
 | 
						|
begin
 | 
						|
 X := 0;
 | 
						|
 Y := 0;
 | 
						|
 if VioGetCurPos (Y0, X0, VioHandle) = 0 then
 | 
						|
  begin
 | 
						|
   X := X0;
 | 
						|
   Y := Y0;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure SetScreenCursor (X, Y: dword); inline;
 | 
						|
(* Set current cursor postion - 0-based. *)
 | 
						|
begin
 | 
						|
 VioSetCurPos (Y, X, VioHandle);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure RemoveLines (Row: dword; Cnt: dword); inline;
 | 
						|
(* Remove Cnt lines from screen starting with (0-based) Row. *)
 | 
						|
var
 | 
						|
 ScrEl: word;
 | 
						|
begin
 | 
						|
 ScrEl := $20 or (TextAttr shl 8);
 | 
						|
 VioScrollUp (Row + WindMinY, WindMinX, WindMaxY, WindMaxX, Cnt, ScrEl,
 | 
						|
                                                                    VioHandle);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure ClearCells (X, Y, Cnt: dword); inline;
 | 
						|
(* Clear Cnt cells in line Y (0-based) starting with position X (0-based). *)
 | 
						|
var
 | 
						|
 ScrEl: word;
 | 
						|
begin
 | 
						|
 ScrEl := $20 or (TextAttr shl 8);
 | 
						|
 VioScrollRight (Y, X, Y, X + Pred (Cnt), Cnt, ScrEl, VioHandle);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure InsLine;
 | 
						|
(* Inserts a line at cursor position. *)
 | 
						|
var
 | 
						|
 ScrEl: word;
 | 
						|
begin
 | 
						|
 ScrEl := $20 or (TextAttr shl 8);
 | 
						|
 VioScrollDn (Pred (WhereY32) + WindMinY, WindMinX, WindMaxY, WindMaxX, 1,
 | 
						|
                                                             ScrEl, VioHandle);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure SetScreenMode (Mode: word);
 | 
						|
var
 | 
						|
 NewMode: VioModeInfo;
 | 
						|
begin
 | 
						|
 NewMode.cb := 8;
 | 
						|
 VioGetMode (NewMode, VioHandle);
 | 
						|
 NewMode.fbType := 1;  {Non graphics colour mode.}
 | 
						|
 NewMode.Color := 4;   {We want 16 colours, 2^4=16 - requests for BW ignored.}
 | 
						|
 case Mode and $FF of
 | 
						|
  BW40, CO40: NewMode.Col := 40;
 | 
						|
  BW80, CO80: NewMode.Col := 80;
 | 
						|
 else
 | 
						|
  begin
 | 
						|
(* Keep current amount of columns! *)
 | 
						|
  end;
 | 
						|
 end;
 | 
						|
 case Mode and $100 of
 | 
						|
  0: NewMode.Row := 25;
 | 
						|
  $100: NewMode.Row := 50
 | 
						|
 else
 | 
						|
  begin
 | 
						|
(* Keep current amount of rows! *)
 | 
						|
  end;
 | 
						|
 end;
 | 
						|
 VioSetMode (NewMode, VioHandle);
 | 
						|
 ScreenWidth := NewMode.Col;
 | 
						|
 ScreenHeight := NewMode.Row;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure Delay (Ms: word);
 | 
						|
{Waits ms milliseconds.}
 | 
						|
begin
 | 
						|
 DosSleep (Ms)
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure WriteNormal (C: char; X, Y: dword); inline;
 | 
						|
(* Write C to console at X, Y (0-based). *)
 | 
						|
begin
 | 
						|
 VioWrtCharStrAtt (@C, 1, Y, X, TextAttr, VioHandle);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure WriteBell; inline;
 | 
						|
(* Write character #7 - beep. *)
 | 
						|
begin
 | 
						|
 DosBeep (800, 250);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
{****************************************************************************
 | 
						|
                             Extra Crt Functions
 | 
						|
****************************************************************************}
 | 
						|
 | 
						|
 | 
						|
procedure CursorOn;
 | 
						|
var
 | 
						|
 I: TVioCursorInfo;
 | 
						|
begin
 | 
						|
 VioGetCurType (I, VioHandle);
 | 
						|
 with I do
 | 
						|
  begin
 | 
						|
   yStartInt := -90;
 | 
						|
   cEndInt := -100;
 | 
						|
   Attr := 15;
 | 
						|
  end;
 | 
						|
 VioSetCurType (I, VioHandle);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure CursorOff;
 | 
						|
var
 | 
						|
 I: TVioCursorInfo;
 | 
						|
begin
 | 
						|
 VioGetCurType (I, VioHandle);
 | 
						|
 I.AttrInt := -1;
 | 
						|
 VioSetCurType (I, VioHandle);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure CursorBig;
 | 
						|
var
 | 
						|
 I: TVioCursorInfo;
 | 
						|
begin
 | 
						|
 VioGetCurType (I, VioHandle);
 | 
						|
 with I do
 | 
						|
  begin
 | 
						|
   yStart := 0;
 | 
						|
   cEndInt := -100;
 | 
						|
   Attr := 15;
 | 
						|
  end;
 | 
						|
 VioSetCurType (I, VioHandle);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
(* Include common, platform independent part. *)
 | 
						|
{$I crt.inc}
 | 
						|
 | 
						|
 | 
						|
{Initialization.}
 | 
						|
 | 
						|
var
 | 
						|
 CurMode: VioModeInfo;
 | 
						|
begin
 | 
						|
 if not (IsConsole) then
 | 
						|
  VioCreatePS (VioHandle, 25, 80, 1, 1, 0);
 | 
						|
{  InitVideo;}
 | 
						|
 CurMode.cb := SizeOf (CurMode);
 | 
						|
 VioGetMode (CurMode, VioHandle);
 | 
						|
 ScreenWidth := CurMode.Col;
 | 
						|
 ScreenHeight := CurMode.Row;
 | 
						|
 LastMode := 0;
 | 
						|
 case ScreenWidth of
 | 
						|
  40: LastMode := CO40;
 | 
						|
  80: LastMode := CO80
 | 
						|
 else
 | 
						|
  LastMode := 255
 | 
						|
 end;
 | 
						|
 case ScreenHeight of
 | 
						|
  50: LastMode := LastMode + $100
 | 
						|
 else
 | 
						|
  LastMode := LastMode + $FF00;
 | 
						|
 end;
 | 
						|
 CrtInit;
 | 
						|
end.
 |