{ 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 MS-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 vesamode; interface implementation uses dos,video,mouse; type PFarChar = ^Char; far; twordarray = array[0..0] of word; pwordarray = ^twordarray; far; TVESAInfoBlock = packed record VESASignature : ARRAY[0..3] OF CHAR; VESAVersion : WORD; OEMStringPtr : PFarChar; 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 SupportedVesaVMD : Array[0..VesaVideoModeCount-1] of TVesaVideoMode; SysGetVideoModeCount : function : word; SysSetVideoMode : function (Const VideoMode : TVideoMode) : boolean; SysGetVideoModeData : Function (Index : Word; Var Data : TVideoMode) : boolean; VesaRegisteredModes : word = 0; function ReturnSuperVGAInfo(var ib : TVESAInfoBLock) : Word; var regs : registers; begin FillChar(ib,SizeOf(ib),0); regs.ax:=$4f00; regs.es:=Seg(ib); regs.di:=Ofs(ib); intr($10,regs); ReturnSuperVGAInfo:=regs.ax; end; function SetSuperVGAMode(m : word) : word; var regs : registers; begin regs.ax:=$4f02; 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; var infoblock : TVESAInfoBLock; i : word; m : word; 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 m := MemW[Seg(infoblock.VideoModePtr^):Ofs(infoblock.VideoModePtr^)+i*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.