mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 02:19:22 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			715 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			715 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{
 | 
						|
    This file is part of the PinGUI - Platform Independent GUI Project
 | 
						|
    Copyright (c) 1999 by Berczi Gabor
 | 
						|
 | 
						|
    VESA support routines
 | 
						|
 | 
						|
    See the file COPYING.GUI, 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 VESA;
 | 
						|
 | 
						|
{$ifdef DEBUG}
 | 
						|
{$define TESTGRAPHIC}
 | 
						|
{$endif DEBUG}
 | 
						|
 | 
						|
interface
 | 
						|
 | 
						|
uses
 | 
						|
  Dos,
 | 
						|
  Objects,Strings,WUtils;
 | 
						|
 | 
						|
const
 | 
						|
     { Video Mode Attributes mask constants }
 | 
						|
     vesa_vma_CanBeSetInCurrentConfig = $0001;
 | 
						|
     vesa_vma_OptionalBlockPresent    = $0002;
 | 
						|
     vesa_vma_BIOSSupport             = $0004;
 | 
						|
     vesa_vma_ColorMode               = $0008; { else mono }
 | 
						|
     vesa_vma_GraphicsMode            = $0010; { else text }
 | 
						|
     { -- VBE 2.0 --- }
 | 
						|
     vesa_vma_VGACompatibleMode       = $0020;
 | 
						|
     vesa_vma_VGACompWindowedAvail    = $0040;
 | 
						|
     vesa_vma_LinearFrameBufferAvail  = $0080;
 | 
						|
 | 
						|
     { Windows Attributes mask constants }
 | 
						|
     vesa_wa_Present                  = $0001;
 | 
						|
     vesa_wa_Readable                 = $0002;
 | 
						|
     vesa_wa_Writeable                = $0004;
 | 
						|
 | 
						|
     { Memory Model value constants }
 | 
						|
     vesa_mm_Text                     = $0000;
 | 
						|
     vesa_mm_CGAGraphics              = $0001;
 | 
						|
     vesa_mm_HerculesGraphics         = $0002;
 | 
						|
     vesa_mm_4planePlanar             = $0003;
 | 
						|
     vesa_mm_PackedPixel              = $0004;
 | 
						|
     vesa_mm_NonChain4_256color       = $0005;
 | 
						|
     vesa_mm_DirectColor              = $0006;
 | 
						|
     vesa_mm_YUV                      = $0007;
 | 
						|
 | 
						|
     { Memory Window value constants }
 | 
						|
     vesa_mw_WindowA                  = $0000;
 | 
						|
     vesa_mw_WindowB                  = $0001;
 | 
						|
 | 
						|
type
 | 
						|
     {$ifdef FPC}tregisters=registers;{$endif}
 | 
						|
     {$ifdef TP}tregisters=registers;{$endif}
 | 
						|
 | 
						|
     PtrRec16 = record
 | 
						|
       Ofs,Seg: word;
 | 
						|
     end;
 | 
						|
 | 
						|
     TVESAInfoBlock = packed record
 | 
						|
       Signature    : longint; {  'VESA' }
 | 
						|
       Version      : word;
 | 
						|
       OEMString    : PString;
 | 
						|
       Capabilities : longint;
 | 
						|
       VideoModeList: PWordArray;
 | 
						|
       TotalMemory  : word; { in 64KB blocks }
 | 
						|
       Fill         : array[1..236] of byte;
 | 
						|
       VBE2Fill     : array[1..256] of byte;
 | 
						|
     end;
 | 
						|
 | 
						|
     TVESAModeInfoBlock = packed record
 | 
						|
       Attributes      : word;
 | 
						|
       WinAAttrs       : byte;
 | 
						|
       WinBAttrs       : byte;
 | 
						|
       Granularity     : word;
 | 
						|
       Size            : word;
 | 
						|
       ASegment        : word;
 | 
						|
       BSegment        : word;
 | 
						|
       FuncPtr         : pointer;
 | 
						|
       BytesPerLine    : word;
 | 
						|
     { optional }
 | 
						|
       XResolution     : word;
 | 
						|
       YResolution     : word;
 | 
						|
       XCharSize       : byte;
 | 
						|
       YCharSize       : byte;
 | 
						|
       NumberOfPlanes  : byte;
 | 
						|
       BitsPerPixel    : byte;
 | 
						|
       NumberOfBanks   : byte;
 | 
						|
       MemoryModel     : byte;
 | 
						|
       BankSize        : byte;
 | 
						|
       NumberOfImagePages: byte;
 | 
						|
       Reserved        : byte;
 | 
						|
     { direct color fields }
 | 
						|
       RedMaskSize     : byte;
 | 
						|
       RedFieldPosition: byte;
 | 
						|
       GreenMaskSize   : byte;
 | 
						|
       GreenFieldPosition: byte;
 | 
						|
       BlueMaskSize    : byte;
 | 
						|
       BlueFieldPosition: byte;
 | 
						|
       ReservedMaskSize: byte;
 | 
						|
       ReservedPosition: byte;
 | 
						|
       DirectColorModeInfo: byte;
 | 
						|
      { --- VBE 2.0 optional --- }
 | 
						|
       LinearFrameAddr : longint;
 | 
						|
       OffScreenAddr   : longint;
 | 
						|
       OffScreenSize   : word;
 | 
						|
       Reserved2       : array[1..216-(4+4+2)] of byte;
 | 
						|
     end;
 | 
						|
 | 
						|
     TVESAModeList = record
 | 
						|
       Count        : word;
 | 
						|
       Modes        : array[1..256] of word;
 | 
						|
     end;
 | 
						|
 | 
						|
function VESAInit: boolean;
 | 
						|
function VESAGetInfo(var B: TVESAInfoBlock): boolean;
 | 
						|
function VESAGetModeInfo(Mode: word; var B: TVESAModeInfoBlock): boolean;
 | 
						|
function VESAGetModeList(var B: TVESAModeList): boolean;
 | 
						|
function VESASearchMode(XRes,YRes,BPX: word; LFB: boolean; var Mode: word; var ModeInfo: TVESAModeInfoBlock): boolean;
 | 
						|
function VESAGetOemString: string;
 | 
						|
function VESASetMode(Mode: word): boolean;
 | 
						|
function VESAGetMode(var Mode: word): boolean;
 | 
						|
function VESASelectMemoryWindow(Window: byte; Position: word): boolean;
 | 
						|
function VESAReturnMemoryWindow(Window: byte; var Position: word): boolean;
 | 
						|
function RegisterVesaVideoMode(Mode : word) : boolean;
 | 
						|
Procedure FreeVesaModes;
 | 
						|
 | 
						|
implementation
 | 
						|
 | 
						|
uses
 | 
						|
{$ifdef FPC}
 | 
						|
  video, mouse,
 | 
						|
{$endif FPC}
 | 
						|
{$ifdef TESTGRAPHIC}
 | 
						|
  graph,
 | 
						|
{$endif TESTGRAPHIC}
 | 
						|
  pmode;
 | 
						|
 | 
						|
type
 | 
						|
 | 
						|
       PVesaVideoMode = ^TVesaVideoMode;
 | 
						|
       TVesaVideoMode = record
 | 
						|
         {Col,Row      : word;
 | 
						|
          Color        : boolean;}
 | 
						|
         V            : TVideoMode;
 | 
						|
         Mode         : word;
 | 
						|
         IsGraphic    : boolean;
 | 
						|
         { zero based vesa specific driver count }
 | 
						|
         VideoIndex   : word;
 | 
						|
         Next         : PVesaVideoMode;
 | 
						|
       end;
 | 
						|
       CursorBitMap = Record
 | 
						|
        width,height,size : longint;
 | 
						|
        colors : array[0..8*8-1] of word;
 | 
						|
       end;
 | 
						|
const
 | 
						|
  VesaVideoModeHead : PVesaVideoMode = nil;
 | 
						|
  VesaRegisteredModes : word = 0;
 | 
						|
{$ifdef TESTGRAPHIC}
 | 
						|
  IsGraphicMode : boolean = false;
 | 
						|
  GraphDriver   : integer = 0;
 | 
						|
  GraphMode     : Integer = 0;
 | 
						|
  FirstCallAfterSetVesaMode : boolean = false;
 | 
						|
  LastCursorX : word = $ffff;
 | 
						|
  LastCursorY : word = $ffff;
 | 
						|
  LastCursorType : word = crHidden;
 | 
						|
 | 
						|
var
 | 
						|
  UnderLineImage : CursorBitMap;
 | 
						|
  BlockImage : CursorBitMap;
 | 
						|
  HalfBlockImage : CursorBitMap;
 | 
						|
{$endif TESTGRAPHIC}
 | 
						|
 | 
						|
Var
 | 
						|
  SysGetVideoModeCount : function : word;
 | 
						|
  SysSetVideoMode      : function (Const VideoMode : TVideoMode) : boolean;
 | 
						|
  SysGetVideoModeData  : function (Index : Word; Var Data : TVideoMode) : boolean;
 | 
						|
  SysUpdateScreen      : procedure(Force : Boolean);
 | 
						|
  SysDoneVideo         : procedure;
 | 
						|
  SysInitVideo         : procedure;
 | 
						|
  SysSetCursorPos      : procedure(NewCursorX, NewCursorY: Word);
 | 
						|
  SysSetCursorType     : procedure(NewCurosrType : word);
 | 
						|
 | 
						|
 | 
						|
function VESAGetInfo(var B: TVESAInfoBlock): boolean;
 | 
						|
var r: registers;
 | 
						|
    OK: boolean;
 | 
						|
    M: MemPtr;
 | 
						|
begin
 | 
						|
  StrToMem('VBE2',B.Signature);
 | 
						|
  GetDosMem(M,SizeOf(B));
 | 
						|
  M.MoveDataTo(B,sizeof(B));
 | 
						|
  r.ah:=$4f; r.al:=0;
 | 
						|
  r.es:=M.DosSeg; r.di:=M.DosOfs;
 | 
						|
  realintr($10,r);
 | 
						|
  M.MoveDataFrom(sizeof(B),B);
 | 
						|
  FreeDosMem(M);
 | 
						|
  OK:=(r.ax=$004f){ and (MemToStr(B.Signature,4)='VESA')};
 | 
						|
  VESAGetInfo:=OK;
 | 
						|
end;
 | 
						|
 | 
						|
function VESAGetModeList(var B: TVESAModeList): boolean;
 | 
						|
var OK: boolean;
 | 
						|
    VI: TVESAInfoBlock;
 | 
						|
begin
 | 
						|
  FillChar(B,SizeOf(B),0);
 | 
						|
  OK:=VESAGetInfo(VI);
 | 
						|
  if OK then
 | 
						|
  begin
 | 
						|
    OK:=MoveDosToPM(VI.VideoModeList,@B.Modes,sizeof(B.Modes));
 | 
						|
    if OK then
 | 
						|
      while (B.Modes[B.Count+1]<>$ffff) and (B.Count<High(B.Modes)) do
 | 
						|
            Inc(B.Count);
 | 
						|
  end;
 | 
						|
  VESAGetModeList:=OK;
 | 
						|
end;
 | 
						|
 | 
						|
function VESASearchMode(XRes,YRes,BPX: word; LFB: boolean; var Mode: word; var ModeInfo: TVESAModeInfoBlock): boolean;
 | 
						|
var B: TVESAModeList;
 | 
						|
    OK: boolean;
 | 
						|
    I: integer;
 | 
						|
    MI: TVESAModeInfoBlock;
 | 
						|
begin
 | 
						|
  OK:=VESAGetModeList(B);
 | 
						|
  I:=1; Mode:=0;
 | 
						|
  repeat
 | 
						|
    OK:=VESAGetModeInfo(B.Modes[I],MI);
 | 
						|
    if OK and (MI.XResolution=XRes) and (MI.YResolution=YRes) and
 | 
						|
       (MI.BitsPerPixel=BPX) and
 | 
						|
       ((LFB=false) or ((MI.Attributes and vesa_vma_LinearFrameBufferAvail)<>0)) then
 | 
						|
      begin Mode:=B.Modes[I]; ModeInfo:=MI; end;
 | 
						|
    Inc(I);
 | 
						|
  until (OK=false) or (I>=B.Count) or (Mode<>0);
 | 
						|
  OK:=Mode<>0;
 | 
						|
  VESASearchMode:=OK;
 | 
						|
end;
 | 
						|
 | 
						|
function VESAGetOemString: string;
 | 
						|
var OK: boolean;
 | 
						|
    VI: TVESAInfoBlock;
 | 
						|
    S: array[0..256] of char;
 | 
						|
begin
 | 
						|
  FillChar(S,SizeOf(S),0);
 | 
						|
  OK:=VESAGetInfo(VI);
 | 
						|
  if OK then
 | 
						|
    OK:=MoveDosToPM(VI.OemString,@S,sizeof(S));
 | 
						|
  VESAGetOemString:=StrPas(@S);
 | 
						|
end;
 | 
						|
 | 
						|
function VESAGetModeInfo(Mode: word; var B: TVESAModeInfoBlock): boolean;
 | 
						|
var r : registers;
 | 
						|
    M : MemPtr;
 | 
						|
    OK: boolean;
 | 
						|
begin
 | 
						|
  r.ah:=$4f; r.al:=$01; r.cx:=Mode;
 | 
						|
  GetDosMem(M,sizeof(B));
 | 
						|
  r.es:=M.DosSeg; r.di:=M.DosOfs; {r.ds:=r.es;}
 | 
						|
  realintr($10,r);
 | 
						|
  M.MoveDataFrom(sizeof(B),B);
 | 
						|
  FreeDosMem(M);
 | 
						|
  OK:=(r.ax=$004f);
 | 
						|
  VESAGetModeInfo:=OK;
 | 
						|
end;
 | 
						|
 | 
						|
function RegisterVesaVideoMode(Mode : word) : boolean;
 | 
						|
var B: TVESAModeInfoBlock;
 | 
						|
    VH : PVesaVideoMode;
 | 
						|
    DoAdd : boolean;
 | 
						|
begin
 | 
						|
  if not VESAGetModeInfo(Mode,B) then
 | 
						|
    RegisterVesaVideoMode:=false
 | 
						|
  else
 | 
						|
    begin
 | 
						|
      VH:=VesaVideoModeHead;
 | 
						|
      DoAdd:=true;
 | 
						|
      RegisterVesaVideoMode:=false;
 | 
						|
      while assigned(VH) do
 | 
						|
        begin
 | 
						|
          if VH^.mode=mode then
 | 
						|
            DoAdd:=false;
 | 
						|
          VH:=VH^.next;
 | 
						|
        end;
 | 
						|
      if DoAdd then
 | 
						|
        begin
 | 
						|
          New(VH);
 | 
						|
          VH^.next:=VesaVideoModeHead;
 | 
						|
          VH^.mode:=mode;
 | 
						|
          VH^.IsGraphic:=(B.Attributes and vesa_vma_GraphicsMode)<>0;
 | 
						|
          VH^.v.color:=(B.Attributes and vesa_vma_ColorMode)<>0;
 | 
						|
          if VH^.IsGraphic then
 | 
						|
            begin
 | 
						|
              VH^.v.col:=B.XResolution div 8;
 | 
						|
              VH^.v.row:=B.YResolution div 8;
 | 
						|
            end
 | 
						|
          else
 | 
						|
            begin
 | 
						|
              VH^.v.col:=B.XResolution;
 | 
						|
              VH^.v.row:=B.YResolution;
 | 
						|
            end;
 | 
						|
          VH^.VideoIndex:=VesaRegisteredModes;
 | 
						|
          Inc(VesaRegisteredModes);
 | 
						|
          RegisterVesaVideoMode:=true;
 | 
						|
          VesaVideoModeHead:=VH;
 | 
						|
        end;
 | 
						|
    end;
 | 
						|
end;
 | 
						|
 | 
						|
function VESASetMode(Mode: word): boolean;
 | 
						|
var r: registers;
 | 
						|
    OK: boolean;
 | 
						|
begin
 | 
						|
  r.ah:=$4f; r.al:=$02; r.bx:=Mode;
 | 
						|
  dos.intr($10,r);
 | 
						|
  OK:=(r.ax=$004f);
 | 
						|
  VESASetMode:=OK;
 | 
						|
end;
 | 
						|
 | 
						|
function VESAGetMode(var Mode: word): boolean;
 | 
						|
var r : registers;
 | 
						|
    OK: boolean;
 | 
						|
begin
 | 
						|
  r.ah:=$4f; r.al:=$03;
 | 
						|
  dos.intr($10,r);
 | 
						|
  OK:=(r.ax=$004f);
 | 
						|
  if OK then Mode:=r.bx;
 | 
						|
  VESAGetMode:=OK;
 | 
						|
end;
 | 
						|
 | 
						|
function VESASelectMemoryWindow(Window: byte; Position: word): boolean;
 | 
						|
var r : registers;
 | 
						|
    OK : boolean;
 | 
						|
begin
 | 
						|
  r.ah:=$4f; r.al:=$05; r.bh:=0; r.bl:=Window; r.dx:=Position;
 | 
						|
  dos.intr($10,r);
 | 
						|
  OK:=(r.ax=$004f);
 | 
						|
  VESASelectMemoryWindow:=OK;
 | 
						|
end;
 | 
						|
 | 
						|
function VESAReturnMemoryWindow(Window: byte; var Position: word): boolean;
 | 
						|
var r  : registers;
 | 
						|
    OK : boolean;
 | 
						|
begin
 | 
						|
  r.ah:=$4f; r.al:=$05; r.bh:=1; r.bl:=Window;
 | 
						|
  dos.intr($10,r);
 | 
						|
  OK:=(r.ax=$004f);
 | 
						|
  if OK then Position:=r.dx;
 | 
						|
  VESAReturnMemoryWindow:=OK;
 | 
						|
end;
 | 
						|
 | 
						|
function VESAInit: boolean;
 | 
						|
var OK: boolean;
 | 
						|
    VI: TVESAInfoBlock;
 | 
						|
begin
 | 
						|
  OK:=VESAGetInfo(VI);
 | 
						|
  if OK then
 | 
						|
 | 
						|
  VESAInit:=OK;
 | 
						|
end;
 | 
						|
 | 
						|
{$ifdef FPC}
 | 
						|
Function VesaGetVideoModeData (Index : Word; Var Data : TVideoMode) : boolean;
 | 
						|
Var
 | 
						|
  PrevCount : word;
 | 
						|
  VH : PVesaVideoMode;
 | 
						|
 | 
						|
begin
 | 
						|
  PrevCount:=SysGetVideoModeCount();
 | 
						|
  VesaGetVideoModeData:=(Index<PrevCount);
 | 
						|
  If VesaGetVideoModeData then
 | 
						|
    begin
 | 
						|
      VesaGetVideoModeData:=SysGetVideoModeData(Index,Data);
 | 
						|
      exit;
 | 
						|
    end;
 | 
						|
  VesaGetVideoModeData:=(Index-PrevCount)<VesaRegisteredModes;
 | 
						|
  If VesaGetVideoModeData then
 | 
						|
    begin
 | 
						|
      VH:=VesaVideoModeHead;
 | 
						|
      while assigned(VH) and (VH^.VideoIndex<>Index-PrevCount) do
 | 
						|
        VH:=VH^.next;
 | 
						|
      if assigned(VH) then
 | 
						|
        Data:=VH^.v
 | 
						|
      else
 | 
						|
        VesaGetVideoModeData:=false;
 | 
						|
    end;
 | 
						|
end;
 | 
						|
 | 
						|
function SetVESAMode(const VideoMode: TVideoMode): Boolean;
 | 
						|
 | 
						|
  var
 | 
						|
     res : boolean;
 | 
						|
     VH : PVesaVideoMode;
 | 
						|
 | 
						|
  begin
 | 
						|
     res:=false;
 | 
						|
     VH:=VesaVideoModeHead;
 | 
						|
     while assigned(VH) do
 | 
						|
       begin
 | 
						|
         if (VideoMode.col=VH^.v.col) and
 | 
						|
            (VideoMode.row=VH^.v.row) and
 | 
						|
            (VideoMode.color=VH^.v.color) then
 | 
						|
           begin
 | 
						|
{$ifdef TESTGRAPHIC}
 | 
						|
             if VH^.IsGraphic then
 | 
						|
               begin
 | 
						|
                 if IsGraphicMode then
 | 
						|
                   CloseGraph;
 | 
						|
                 GraphDriver:=Graph.Vesa;
 | 
						|
                 if (VideoMode.col = 100) and (VideoMode.row = 75) then
 | 
						|
                   GraphMode:=m800x600x256
 | 
						|
                 else if (VideoMode.col = 80) and (VideoMode.row = 60) then
 | 
						|
                   GraphMode:=m640x480x256
 | 
						|
                 else if (VideoMode.col = 128) and (VideoMode.row = 96) then
 | 
						|
                   GraphMode:=m1024x768x256
 | 
						|
                 else
 | 
						|
                   GraphMode:=Graph.Detect;
 | 
						|
                 InitGraph(GraphDriver,GraphMode,'');
 | 
						|
                 res:=(GraphResult=grOK);
 | 
						|
                 if not res then
 | 
						|
                   begin
 | 
						|
                     SetVesaMode:=false;
 | 
						|
                     exit;
 | 
						|
                   end;
 | 
						|
               end
 | 
						|
             else
 | 
						|
{$endif TESTGRAPHIC}
 | 
						|
               res:=VESASetMode(VH^.mode);
 | 
						|
             if res then
 | 
						|
               begin
 | 
						|
                  ScreenWidth:=VideoMode.Col;
 | 
						|
                  ScreenHeight:=VideoMode.Row;
 | 
						|
                  ScreenColor:=VideoMode.Color;
 | 
						|
{$ifdef TESTGRAPHIC}
 | 
						|
                  IsGraphicMode:=VH^.IsGraphic;
 | 
						|
                  FirstCallAfterSetVesaMode:=true;
 | 
						|
                  LastCursorX:=$ffff;
 | 
						|
                  LastCursorY:=$ffff;
 | 
						|
                  LastCursorType:=crHidden;
 | 
						|
                  if IsGraphicMode then
 | 
						|
                    DoCustomMouse(false)
 | 
						|
                  else
 | 
						|
{$endif TESTGRAPHIC}
 | 
						|
                    DoCustomMouse(true);
 | 
						|
               end;
 | 
						|
           end;
 | 
						|
         if res then
 | 
						|
           begin
 | 
						|
             SetVesaMode:=true;
 | 
						|
             exit;
 | 
						|
           end;
 | 
						|
         VH:=VH^.next;
 | 
						|
       end;
 | 
						|
     SetVESAMode:=SysSetVideoMode(VideoMode);
 | 
						|
  end;
 | 
						|
 | 
						|
procedure VesaSetCursorPos(NewCursorX, NewCursorY: Word);
 | 
						|
begin
 | 
						|
{$ifdef TESTGRAPHIC}
 | 
						|
  if not IsGraphicMode then
 | 
						|
{$endif TESTGRAPHIC}
 | 
						|
    begin
 | 
						|
      SysSetCursorPos(NewCursorX,NewCursorY);
 | 
						|
      exit;
 | 
						|
    end;
 | 
						|
{$ifdef TESTGRAPHIC}
 | 
						|
  if (NewCursorX<>LastCursorX) or (NewCursorY<>LastCursorY) then
 | 
						|
    begin
 | 
						|
      Case GetCursorType of
 | 
						|
        crHidden  : ;
 | 
						|
        crUnderLine :
 | 
						|
          Begin
 | 
						|
            PutImage(LastCursorX*8,LastCursorY*8+7,UnderLineImage,XORPut);
 | 
						|
            PutImage(NewCursorX*8,NewCursorY*8+7,UnderLineImage,XORPut);
 | 
						|
          End;
 | 
						|
        crBlock     :
 | 
						|
          Begin
 | 
						|
            PutImage(LastCursorX*8,LastCursorY*8,BlockImage,XORPut);
 | 
						|
            PutImage(NewCursorX*8,NewCursorY*8,BlockImage,XORPut);
 | 
						|
          End;
 | 
						|
        crHalfBlock :
 | 
						|
          Begin
 | 
						|
            PutImage(LastCursorX*8,LastCursorY*8+4,HalfBlockImage,XORPut);
 | 
						|
            PutImage(NewCursorX*8,NewCursorY*8+4,HalfBlockImage,XORPut);
 | 
						|
          End;
 | 
						|
      end;
 | 
						|
      LastCursorX:=NewCursorX;
 | 
						|
      LastCursorY:=NewCursorY;
 | 
						|
    end;
 | 
						|
{$endif TESTGRAPHIC}
 | 
						|
end;
 | 
						|
 | 
						|
procedure VesaSetCursorType(NewType : Word);
 | 
						|
begin
 | 
						|
{$ifdef TESTGRAPHIC}
 | 
						|
  if not IsGraphicMode then
 | 
						|
{$endif TESTGRAPHIC}
 | 
						|
    begin
 | 
						|
      SysSetCursorType(NewType);
 | 
						|
      exit;
 | 
						|
    end;
 | 
						|
{$ifdef TESTGRAPHIC}
 | 
						|
  if (NewType<>LastCursorType) then
 | 
						|
    begin
 | 
						|
      Case LastCursorType of
 | 
						|
        crHidden  : ;
 | 
						|
        crUnderLine :
 | 
						|
          Begin
 | 
						|
            PutImage(LastCursorX*8,LastCursorY*8+7,UnderLineImage,XORPut);
 | 
						|
          End;
 | 
						|
        crBlock     :
 | 
						|
          Begin
 | 
						|
            PutImage(LastCursorX*8,LastCursorY*8,BlockImage,XORPut);
 | 
						|
          End;
 | 
						|
        crHalfBlock :
 | 
						|
          Begin
 | 
						|
            PutImage(LastCursorX*8,LastCursorY*8+4,HalfBlockImage,XORPut);
 | 
						|
          End;
 | 
						|
      end;
 | 
						|
      SysSetCursorType(NewType);
 | 
						|
      Case NewType of
 | 
						|
        crHidden  : ;
 | 
						|
        crUnderLine :
 | 
						|
          Begin
 | 
						|
            PutImage(LastCursorX*8,LastCursorY*8+7,UnderLineImage,XORPut);
 | 
						|
          End;
 | 
						|
        crBlock     :
 | 
						|
          Begin
 | 
						|
            PutImage(LastCursorX*8,LastCursorY*8,BlockImage,XORPut);
 | 
						|
          End;
 | 
						|
        crHalfBlock :
 | 
						|
          Begin
 | 
						|
            PutImage(LastCursorX*8,LastCursorY*8+4,HalfBlockImage,XORPut);
 | 
						|
          End;
 | 
						|
      end;
 | 
						|
      LastCursorType:=NewType;
 | 
						|
    end;
 | 
						|
{$endif TESTGRAPHIC}
 | 
						|
end;
 | 
						|
 | 
						|
procedure VesaUpdateScreen(Force: Boolean);
 | 
						|
{$ifdef TESTGRAPHIC}
 | 
						|
var
 | 
						|
  StoreDrawTextBackground,
 | 
						|
  MustUpdate : boolean;
 | 
						|
  x,y : longint;
 | 
						|
  w, prevcolor,
 | 
						|
  prevbkcolor, StoreCursorType : word;
 | 
						|
  Color,BkCol,Col : byte;
 | 
						|
  Ch : char;
 | 
						|
{$endif TESTGRAPHIC}
 | 
						|
begin
 | 
						|
{$ifdef TESTGRAPHIC}
 | 
						|
  if not IsGraphicMode then
 | 
						|
{$endif TESTGRAPHIC}
 | 
						|
    begin
 | 
						|
      SysUpdateScreen(Force);
 | 
						|
      exit;
 | 
						|
    end;
 | 
						|
{$ifdef TESTGRAPHIC}
 | 
						|
  if FirstCallAfterSetVesaMode then
 | 
						|
    begin
 | 
						|
      { Make sure to redraw all }
 | 
						|
      Fillchar(OldVideoBuf^,VideoBufSize,#0);
 | 
						|
      FirstCallAfterSetVesaMode:=false;
 | 
						|
    end;
 | 
						|
  if not force then
 | 
						|
   begin
 | 
						|
     MustUpdate:=false;
 | 
						|
     asm
 | 
						|
        movl    VideoBuf,%esi
 | 
						|
        movl    OldVideoBuf,%edi
 | 
						|
        movl    VideoBufSize,%ecx
 | 
						|
        shrl    $2,%ecx
 | 
						|
        repe
 | 
						|
        cmpsl
 | 
						|
        setne   MustUpdate
 | 
						|
     end;
 | 
						|
   end;
 | 
						|
  StoreDrawTextBackground:=DrawTextBackground;
 | 
						|
  DrawTextBackground:=true;
 | 
						|
  if Force or MustUpdate then
 | 
						|
   begin
 | 
						|
     PrevColor:=GetColor;
 | 
						|
     PrevBkColor:=GetBkColor;
 | 
						|
 | 
						|
     for y:=0 to ScreenHeight-1 do
 | 
						|
       for x:=0 to Screenwidth-1 do
 | 
						|
         begin
 | 
						|
           w:=VideoBuf^[x+y*ScreenWidth];
 | 
						|
           if Force or
 | 
						|
              (w<>OldVideoBuf^[x+y*ScreenWidth]) then
 | 
						|
             Begin
 | 
						|
               Color:=w shr 8;
 | 
						|
               Ch:=chr(w and $ff);
 | 
						|
               Col:=Color and $f;
 | 
						|
               if (Col = 0) and (GetMaxColor=255) then
 | 
						|
                 Col:=255;
 | 
						|
               SetColor(Col);
 | 
						|
               BkCol:=(Color shr 4) and 7;
 | 
						|
               if (BkCol = 0) and (GetMaxColor=255) then
 | 
						|
                 BkCol:=255;
 | 
						|
               SetBkColor(BkCol);
 | 
						|
               if (x=LastCursorX) and (Y=LastCursorY) then
 | 
						|
                 begin
 | 
						|
                   StoreCursorType:=LastCursorType;
 | 
						|
                   VesaSetCursorType(crHidden);
 | 
						|
                 end;
 | 
						|
               OutTextXY(x*8,y*8,Ch);
 | 
						|
               if (x=LastCursorX) and (Y=LastCursorY) then
 | 
						|
                 VesaSetCursorType(StoreCursorType);
 | 
						|
               if not force then
 | 
						|
                 OldVideoBuf^[x+y*ScreenWidth]:=w;
 | 
						|
             End;
 | 
						|
         end;
 | 
						|
     if Force then
 | 
						|
       move(videobuf^,oldvideobuf^,
 | 
						|
         VideoBufSize);
 | 
						|
     SetColor(PrevColor);
 | 
						|
     SetBkColor(GetBkColor);
 | 
						|
   end;
 | 
						|
  DrawTextBackground:=StoreDrawTextBackground;
 | 
						|
{$endif TESTGRAPHIC}
 | 
						|
end;
 | 
						|
 | 
						|
procedure VesaDoneVideo;
 | 
						|
begin
 | 
						|
{$ifdef TESTGRAPHIC}
 | 
						|
  if IsGraphicMode then
 | 
						|
    begin
 | 
						|
      CloseGraph;
 | 
						|
      IsGraphicMode:=false;
 | 
						|
    end;
 | 
						|
{$endif TESTGRAPHIC}
 | 
						|
  SysDoneVideo();
 | 
						|
end;
 | 
						|
 | 
						|
procedure VesaInitVideo;
 | 
						|
begin
 | 
						|
{$ifdef TESTGRAPHIC}
 | 
						|
  if IsGraphicMode then
 | 
						|
    begin
 | 
						|
      SysInitVideo();
 | 
						|
      InitGraph(GraphDriver,GraphMode,'');
 | 
						|
    end
 | 
						|
  else
 | 
						|
{$endif TESTGRAPHIC}
 | 
						|
    SysInitVideo();
 | 
						|
end;
 | 
						|
 | 
						|
Function VesaGetVideoModeCount : Word;
 | 
						|
 | 
						|
begin
 | 
						|
  VesaGetVideoModeCount:=SysGetVideoModeCount()+VesaRegisteredModes;
 | 
						|
end;
 | 
						|
 | 
						|
Procedure FreeVesaModes;
 | 
						|
var
 | 
						|
  VH : PVesaVideoMode;
 | 
						|
begin
 | 
						|
  VH:=VesaVideoModeHead;
 | 
						|
  While assigned(VH) do
 | 
						|
    begin
 | 
						|
      VesaVideoModeHead:=VH^.Next;
 | 
						|
      FreeMem(VH,Sizeof(TVesaVideoMode));
 | 
						|
      VH:=VesaVideoModeHead;
 | 
						|
    end;
 | 
						|
end;
 | 
						|
 | 
						|
Var
 | 
						|
  Driver : TVideoDriver;
 | 
						|
{$ifdef TESTGRAPHIC}
 | 
						|
  i : longint;
 | 
						|
{$endif TESTGRAPHIC}
 | 
						|
 | 
						|
BEGIN
 | 
						|
{ Get the videodriver to be used }
 | 
						|
  GetVideoDriver (Driver);
 | 
						|
{ Change needed functions }
 | 
						|
  SysGetVideoModeCount:=Driver.GetVideoModeCount;
 | 
						|
  Driver.GetVideoModeCount:=@VesaGetVideoModeCount;
 | 
						|
  SysGetVideoModeData:=Driver.GetVideoModeData;
 | 
						|
  Driver.GetVideoModeData:=@VesaGetVideoModeData;
 | 
						|
  SysSetVideoMode:=Driver.SetVideoMode;
 | 
						|
  Driver.SetVideoMode:=@SetVESAMode;
 | 
						|
  SysSetCursorPos:=Driver.SetCursorPos;
 | 
						|
  Driver.SetCursorPos:=@VESASetCursorPos;
 | 
						|
  SysSetCursorType:=Driver.SetCursorType;
 | 
						|
  Driver.SetCursorType:=@VESASetCursorType;
 | 
						|
  SysUpdateScreen:=Driver.UpdateScreen;
 | 
						|
  Driver.UpdateScreen:=@VesaUpdateScreen;
 | 
						|
  SysDoneVideo:=Driver.DoneDriver;
 | 
						|
  Driver.DoneDriver:=@VesaDoneVideo;
 | 
						|
  SysInitVideo:=Driver.InitDriver;
 | 
						|
  Driver.InitDriver:=@VesaInitVideo;
 | 
						|
 | 
						|
{$ifdef TESTGRAPHIC}
 | 
						|
  BlockImage.width:=7;
 | 
						|
  BlockImage.height:=7;
 | 
						|
  For i:=0 to 8*8-1 do
 | 
						|
    BlockImage.colors[i]:=White;
 | 
						|
  HalfBlockImage:=BlockImage;
 | 
						|
  HalfBlockImage.height:=3;
 | 
						|
  UnderLineImage:=BlockImage;
 | 
						|
  UnderLineImage.height:=0;
 | 
						|
{$endif TESTGRAPHIC}
 | 
						|
 | 
						|
  SetVideoDriver (Driver);
 | 
						|
{$endif FPC}
 | 
						|
END.
 |