mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 09:39:32 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			254 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			254 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{
 | 
						|
    $Id$
 | 
						|
    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.
 | 
						|
{
 | 
						|
  $Log$
 | 
						|
  Revision 1.4  2004-09-14 20:11:31  hajny
 | 
						|
    * fix incorrect reuse of for loop counter
 | 
						|
 | 
						|
  Revision 1.3  2002/09/07 16:01:19  peter
 | 
						|
    * old logs removed and tabs fixed
 | 
						|
 | 
						|
}
 |