fpc/rtl/go32v2/vesamode.pp
fpc 790a4fe2d3 * log and id tags removed
git-svn-id: trunk@42 -
2005-05-21 09:42:41 +00:00

244 lines
6.8 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 extension for VESA Modes for go32v2
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 vesamode;
interface
implementation
uses
dos,go32,dpmiexcp,video,mouse;
type
twordarray = array[0..0] of word;
pwordarray = ^twordarray;
TVESAInfoBlock = record
VESASignature : ARRAY[0..3] OF CHAR;
VESAVersion : WORD;
OEMStringPtr : PChar;
Capabilities : LONGINT;
VideoModePtr : pwordarray;
TotalMemory : WORD;
Reserved : ARRAY[1..242] OF BYTE;
end;
TVesaVideoMode = record
{Col,Row : word;
Color : boolean;}
V : TVideoMode;
Mode : word;
end;
Const
VesaVideoModeCount = 5;
VesaVMD : Array[264..268] of TVesaVideoMode = (
(V : (Col: 80; Row : 60; Color : True); Mode : 264),
(V : (Col: 132; Row : 25; Color : True); Mode : 265),
(V : (Col: 132; Row : 43; Color : True); Mode : 266),
(V : (Col: 132; Row : 50; Color : True); Mode : 267),
(V : (Col: 132; Row : 60; Color : True); Mode : 268)
);
var
infoblock : TVESAInfoBLock;
SupportedVesaVMD : Array[0..VesaVideoModeCount-1] of TVesaVideoMode;
i : longint;
m : word;
Var
SysGetVideoModeCount : function : word;
SysSetVideoMode : function (Const VideoMode : TVideoMode) : boolean;
SysGetVideoModeData : Function (Index : Word; Var Data : TVideoMode) : boolean;
const
VesaRegisteredModes : word = 0;
function ReturnSuperVGAInfo(var ib : TVESAInfoBLock) : Word;
var
regs : registers;
begin
regs.ah:=$4f;
regs.al:=0;
regs.es:=tb_segment;
regs.di:=tb_offset;
intr($10,regs);
dosmemget(tb_segment,tb_offset,ib,sizeof(ib));
ReturnSuperVGAInfo:=regs.ax;
end;
function SetSuperVGAMode(m : word) : word;
var
regs : registers;
begin
regs.ah:=$4f;
regs.al:=2;
regs.bx:=m;
intr($10,regs);
SetSuperVGAMode:=regs.ax;
end;
function SetVESAMode(const VideoMode: TVideoMode): Boolean;
var
w : word;
begin
SetVESAMode:=false;
for w:=VesaRegisteredModes-1 downto 0 do
begin
if (VideoMode.col=SupportedVesaVMD[w].v.col) and
(VideoMode.row=SupportedVesaVMD[w].v.row) and
(VideoMode.color=SupportedVesaVMD[w].v.color) then
begin
if SetSuperVGAMode(SupportedVesaVMD[w].mode) <> $4f then
SetVESAMode:=false
else
begin
SetVESAMode:=true;
ScreenWidth:=VideoMode.Col;
ScreenHeight:=VideoMode.Row;
ScreenColor:=VideoMode.Color;
// cheat to get a correct mouse
{
mem[$40:$84]:=ScreenHeight-1;
mem[$40:$4a]:=ScreenWidth;
memw[$40:$4c]:=ScreenHeight*((ScreenWidth shl 1)-1);
}
DoCustomMouse(true);
end;
end;
if SetVESAMode then
exit;
end;
SetVESAMode:=SysSetVideoMode(VideoMode);
end;
procedure InitializeVesaModes;
begin
ReturnSuperVGAInfo(infoblock);
if not((infoblock.VESASignature[0]<>'V') or
(infoblock.VESASignature[1]<>'E') or
(infoblock.VESASignature[2]<>'S') or
(infoblock.VESASignature[3]<>'A')) then
begin
{$R-}
i:=0;
while true do
begin
dosmemget(hi(dword(infoblock.VideoModePtr)),lo(dword(infoblock.VideoModePtr))+i*2,m,2);
case m of
264:
Begin
{RegisterVideoMode(80,60,true,@SetVESAMode,264);}
SupportedVesaVMD[VesaRegisteredModes]:=VesaVMD[m];
Inc(VesaRegisteredModes);
End;
265:
Begin
{RegisterVideoMode(132,25,true,@SetVESAMode,265);}
SupportedVesaVMD[VesaRegisteredModes]:=VesaVMD[m];
Inc(VesaRegisteredModes);
End;
266:
Begin
{RegisterVideoMode(132,43,true,@SetVESAMode,266);}
SupportedVesaVMD[VesaRegisteredModes]:=VesaVMD[m];
Inc(VesaRegisteredModes);
End;
267:
Begin
{RegisterVideoMode(132,50,true,@SetVESAMode,267);}
SupportedVesaVMD[VesaRegisteredModes]:=VesaVMD[m];
Inc(VesaRegisteredModes);
End;
268:
Begin
{RegisterVideoMode(132,60,true,@SetVESAMode,268);}
SupportedVesaVMD[VesaRegisteredModes]:=VesaVMD[m];
Inc(VesaRegisteredModes);
End;
$ffff:
break;
end;
inc(i);
end;
end;
end;
Function VesaGetVideoModeData (Index : Word; Var Data : TVideoMode) : boolean;
Var
PrevCount : word;
begin
PrevCount:=SysGetVideoModeCount();
VesaGetVideoModeData:=(Index<=PrevCount);
If VesaGetVideoModeData then
begin
SysGetVideoModeData(Index,Data);
exit;
end;
VesaGetVideoModeData:=(Index-PrevCount)<=VesaRegisteredModes;
If VesaGetVideoModeData then
Data:=SupportedVesaVMD[Index-PrevCount-1].V;
end;
Function VesaGetVideoModeCount : Word;
begin
VesaGetVideoModeCount:=SysGetVideoModeCount()+VesaRegisteredModes;
end;
Var
Driver : TVideoDriver;
(*
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
{ Get the videodriver to be used }
GetVideoDriver (Driver);
InitializeVesaModes;
{ Change needed functions }
SysGetVideoModeCount:=Driver.GetVideoModeCount;
Driver.GetVideoModeCount:=@VesaGetVideoModeCount;
SysGetVideoModeData:=Driver.GetVideoModeData;
Driver.GetVideoModeData:=@VesaGetVideoModeData;
SysSetVideoMode:=Driver.SetVideoMode;
Driver.SetVideoMode:=@SetVESAMode;
SetVideoDriver (Driver);
end.