mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-16 10:59:33 +02:00
329 lines
6.6 KiB
ObjectPascal
329 lines
6.6 KiB
ObjectPascal
{
|
|
This file is part of the Free Pascal run time library.
|
|
Copyright (c) 1999-2000 by Florian Klaempfl
|
|
member of the Free Pascal development team
|
|
|
|
Video unit for DOS
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
**********************************************************************}
|
|
unit Video;
|
|
|
|
interface
|
|
|
|
{$i videoh.inc}
|
|
|
|
var
|
|
VideoSeg : word;
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
mouse,
|
|
go32;
|
|
|
|
{$i video.inc}
|
|
|
|
{$ASMMODE ATT}
|
|
|
|
{ used to know if LastCursorType is valid }
|
|
const
|
|
LastCursorType : word = crUnderline;
|
|
|
|
{ allways set blink state again }
|
|
|
|
procedure SetHighBitBlink;
|
|
var
|
|
regs : trealregs;
|
|
begin
|
|
regs.ax:=$1003;
|
|
regs.bx:=$0001;
|
|
realintr($10,regs);
|
|
end;
|
|
|
|
function BIOSGetScreenMode(var Cols,Rows: word; var Color: boolean): boolean;
|
|
var r: trealregs;
|
|
L: longint;
|
|
LSel,LSeg: word;
|
|
B: array[0..63] of byte;
|
|
type
|
|
TWord = word;
|
|
PWord = ^TWord;
|
|
var
|
|
OK: boolean;
|
|
begin
|
|
L:=global_dos_alloc(64);
|
|
LSeg:=(L shr 16);
|
|
LSel:=(L and $ffff);
|
|
|
|
r.ah:=$1b; r.bx:=0;
|
|
r.es:=LSeg; r.di:=0;
|
|
realintr($10,r);
|
|
OK:=(r.al=$1b);
|
|
if OK then
|
|
begin
|
|
dpmi_dosmemget(LSeg,0,B,64);
|
|
Cols:=PWord(@B[5])^; Rows:=B[$22];
|
|
Color:=PWord(@B[$27])^<>0;
|
|
end;
|
|
global_dos_free(LSel);
|
|
BIOSGetScreenMode:=OK;
|
|
end;
|
|
|
|
procedure SysInitVideo;
|
|
var
|
|
regs : trealregs;
|
|
begin
|
|
VideoSeg:=$b800;
|
|
if (ScreenWidth=$ffff) or (ScreenHeight=$ffff) or
|
|
(ScreenWidth=0) or (ScreenHeight=0) then
|
|
begin
|
|
ScreenColor:=true;
|
|
regs.ah:=$0f;
|
|
realintr($10,regs);
|
|
if (regs.al and 1)=0 then
|
|
ScreenColor:=false;
|
|
if regs.al=7 then
|
|
begin
|
|
ScreenColor:=false;
|
|
VideoSeg:=$b000;
|
|
end
|
|
else
|
|
VideoSeg:=$b800;
|
|
ScreenWidth:=regs.ah;
|
|
regs.ax:=$1130;
|
|
regs.bx:=0;
|
|
realintr($10,regs);
|
|
ScreenHeight:=regs.dl+1;
|
|
BIOSGetScreenMode(ScreenWidth,ScreenHeight,ScreenColor);
|
|
end;
|
|
regs.ah:=$03;
|
|
regs.bh:=0;
|
|
realintr($10,regs);
|
|
CursorLines:=regs.cl;
|
|
CursorX:=regs.dl;
|
|
CursorY:=regs.dh;
|
|
SetHighBitBlink;
|
|
SetCursorType(LastCursorType);
|
|
end;
|
|
|
|
|
|
procedure SysDoneVideo;
|
|
begin
|
|
LastCursorType:=GetCursorType;
|
|
ClearScreen;
|
|
SetCursorType(crUnderLine);
|
|
SetCursorPos(0,0);
|
|
end;
|
|
|
|
|
|
function SysGetCapabilities: Word;
|
|
begin
|
|
SysGetCapabilities := $3F;
|
|
end;
|
|
|
|
|
|
procedure SysSetCursorPos(NewCursorX, NewCursorY: Word);
|
|
var
|
|
regs : trealregs;
|
|
begin
|
|
regs.ah:=$02;
|
|
regs.bh:=0;
|
|
regs.dh:=NewCursorY;
|
|
regs.dl:=NewCursorX;
|
|
realintr($10,regs);
|
|
CursorY:=regs.dh;
|
|
CursorX:=regs.dl;
|
|
end;
|
|
|
|
{ I don't know the maximum value for the scan line
|
|
probably 7 or 15 depending on resolution !!
|
|
}
|
|
function SysGetCursorType: Word;
|
|
var
|
|
regs : trealregs;
|
|
begin
|
|
regs.ah:=$03;
|
|
regs.bh:=0;
|
|
realintr($10,regs);
|
|
SysGetCursorType:=crHidden;
|
|
if (regs.ch and $60)=0 then
|
|
begin
|
|
SysGetCursorType:=crBlock;
|
|
if (regs.ch and $1f)<>0 then
|
|
begin
|
|
SysGetCursorType:=crHalfBlock;
|
|
if regs.cl-1=(regs.ch and $1F) then
|
|
SysGetCursorType:=crUnderline;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure SysSetCursorType(NewType: Word);
|
|
var
|
|
regs : trealregs;
|
|
const
|
|
MaxCursorLines = 7;
|
|
begin
|
|
regs.ah:=$01;
|
|
regs.bx:=NewType;
|
|
case NewType of
|
|
crHidden : regs.cx:=$2000;
|
|
crHalfBlock : begin
|
|
regs.ch:=MaxCursorLines shr 1;
|
|
regs.cl:=MaxCursorLines;
|
|
end;
|
|
crBlock : begin
|
|
regs.ch:=0;
|
|
regs.cl:=MaxCursorLines;
|
|
end;
|
|
else begin
|
|
regs.ch:=MaxCursorLines-1;
|
|
regs.cl:=MaxCursorLines;
|
|
end;
|
|
end;
|
|
realintr($10,regs);
|
|
end;
|
|
|
|
procedure SysUpdateScreen(Force: Boolean);
|
|
var
|
|
Is_Mouse_Vis: boolean;
|
|
begin
|
|
Is_Mouse_Vis := MouseIsVisible; {MouseIsVisible is from Mouse unit}
|
|
if Is_Mouse_Vis then
|
|
HideMouse;
|
|
if not force then
|
|
begin
|
|
asm
|
|
pushl %esi
|
|
pushl %edi
|
|
movl VideoBuf,%esi
|
|
movl OldVideoBuf,%edi
|
|
movl VideoBufSize,%ecx
|
|
shrl $2,%ecx
|
|
repe
|
|
cmpsl
|
|
setne force
|
|
popl %edi
|
|
popl %esi
|
|
end;
|
|
end;
|
|
if Force then
|
|
begin
|
|
dosmemput(videoseg,0,videobuf^,VideoBufSize);
|
|
move(videobuf^,oldvideobuf^,VideoBufSize);
|
|
end;
|
|
if Is_Mouse_Vis then
|
|
ShowMouse;
|
|
end;
|
|
|
|
Procedure DoSetVideoMode(Params: Longint);
|
|
|
|
type
|
|
wordrec=packed record
|
|
lo,hi : word;
|
|
end;
|
|
var
|
|
regs : trealregs;
|
|
begin
|
|
regs.ax:=wordrec(Params).lo;
|
|
regs.bx:=wordrec(Params).hi;
|
|
realintr($10,regs);
|
|
end;
|
|
|
|
Procedure SetVideo8x8;
|
|
|
|
type
|
|
wordrec=packed record
|
|
lo,hi : word;
|
|
end;
|
|
var
|
|
regs : trealregs;
|
|
begin
|
|
regs.ax:=3;
|
|
regs.bx:=0;
|
|
realintr($10,regs);
|
|
regs.ax:=$1112;
|
|
regs.bx:=$0;
|
|
realintr($10,regs);
|
|
end;
|
|
|
|
Const
|
|
SysVideoModeCount = 5;
|
|
SysVMD : Array[0..SysVideoModeCount-1] of TVideoMode = (
|
|
(Col: 40; Row : 25; Color : False),
|
|
(Col: 40; Row : 25; Color : True),
|
|
(Col: 80; Row : 25; Color : False),
|
|
(Col: 80; Row : 25; Color : True),
|
|
(Col: 80; Row : 50; Color : True)
|
|
);
|
|
|
|
Function SysSetVideoMode (Const Mode : TVideoMode) : Boolean;
|
|
|
|
Var
|
|
I : Integer;
|
|
|
|
begin
|
|
I:=SysVideoModeCount-1;
|
|
SysSetVideoMode:=False;
|
|
While (I>=0) and Not SysSetVideoMode do
|
|
If (Mode.col=SysVMD[i].col) and
|
|
(Mode.Row=SysVMD[i].Row) and
|
|
(Mode.Color=SysVMD[i].Color) then
|
|
SysSetVideoMode:=True
|
|
else
|
|
Dec(I);
|
|
If SysSetVideoMode then
|
|
begin
|
|
If (I<SysVideoModeCount-1) then
|
|
DoSetVideoMode(I)
|
|
else
|
|
SetVideo8x8;
|
|
ScreenWidth:=SysVMD[I].Col;
|
|
ScreenHeight:=SysVMD[I].Row;
|
|
ScreenColor:=SysVMD[I].Color;
|
|
DoCustomMouse(false);
|
|
end;
|
|
end;
|
|
|
|
Function SysGetVideoModeData (Index : Word; Var Data : TVideoMode) : boolean;
|
|
|
|
begin
|
|
SysGetVideoModeData:=(Index<=SysVideoModeCount);
|
|
If SysGetVideoModeData then
|
|
Data:=SysVMD[Index];
|
|
end;
|
|
|
|
Function SysGetVideoModeCount : Word;
|
|
|
|
begin
|
|
SysGetVideoModeCount:=SysVideoModeCount;
|
|
end;
|
|
|
|
Const
|
|
SysVideoDriver : TVideoDriver = (
|
|
InitDriver : @SysInitVideo;
|
|
DoneDriver : @SysDoneVideo;
|
|
UpdateScreen : @SysUpdateScreen;
|
|
ClearScreen : Nil;
|
|
SetVideoMode : @SysSetVideoMode;
|
|
GetVideoModeCount : @SysGetVideoModeCount;
|
|
GetVideoModeData : @SysGetVideoModedata;
|
|
SetCursorPos : @SysSetCursorPos;
|
|
GetCursorType : @SysGetCursorType;
|
|
SetCursorType : @SysSetCursorType;
|
|
GetCapabilities : @SysGetCapabilities
|
|
);
|
|
|
|
initialization
|
|
SetVideoDriver(SysVideoDriver);
|
|
end.
|