1{ 2 This file is part of the Free Pascal run time library. 3 Copyright (c) 1999-2000 by Florian Klaempfl 4 member of the Free Pascal development team 5 6 Video unit extension for VESA Modes for MS-DOS 7 8 See the file COPYING.FPC, included in this distribution, 9 for details about the copyright. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 15 **********************************************************************} 16unit vesamode; 17 18 interface 19 20 implementation 21 22 uses 23 dos,video,mouse; 24 25 type 26 PFarChar = ^Char; far; 27 twordarray = array[0..0] of word; 28 29 pwordarray = ^twordarray; far; 30 TVESAInfoBlock = packed record 31 VESASignature : ARRAY[0..3] OF CHAR; 32 VESAVersion : WORD; 33 OEMStringPtr : PFarChar; 34 Capabilities : LONGINT; 35 VideoModePtr : pwordarray; 36 TotalMemory : WORD; 37 Reserved : ARRAY[1..242] OF BYTE; 38 end; 39 40 TVesaVideoMode = record 41 {Col,Row : word; 42 Color : boolean;} 43 V : TVideoMode; 44 Mode : word; 45 end; 46 47Const 48 VesaVideoModeCount = 5; 49 VesaVMD : Array[264..268] of TVesaVideoMode = ( 50 (V : (Col: 80; Row : 60; Color : True); Mode : 264), 51 (V : (Col: 132; Row : 25; Color : True); Mode : 265), 52 (V : (Col: 132; Row : 43; Color : True); Mode : 266), 53 (V : (Col: 132; Row : 50; Color : True); Mode : 267), 54 (V : (Col: 132; Row : 60; Color : True); Mode : 268) 55 ); 56 57var 58 SupportedVesaVMD : Array[0..VesaVideoModeCount-1] of TVesaVideoMode; 59 SysGetVideoModeCount : function : word; 60 SysSetVideoMode : function (Const VideoMode : TVideoMode) : boolean; 61 SysGetVideoModeData : Function (Index : Word; Var Data : TVideoMode) : boolean; 62 VesaRegisteredModes : word = 0; 63 64 function ReturnSuperVGAInfo(var ib : TVESAInfoBLock) : Word; 65 66 var 67 regs : registers; 68 69 begin 70 FillChar(ib,SizeOf(ib),0); 71 regs.ax:=$4f00; 72 regs.es:=Seg(ib); 73 regs.di:=Ofs(ib); 74 intr($10,regs); 75 ReturnSuperVGAInfo:=regs.ax; 76 end; 77 78 function SetSuperVGAMode(m : word) : word; 79 80 var 81 regs : registers; 82 83 begin 84 regs.ax:=$4f02; 85 regs.bx:=m; 86 intr($10,regs); 87 SetSuperVGAMode:=regs.ax; 88 end; 89 90 function SetVESAMode(const VideoMode: TVideoMode): Boolean; 91 92 var 93 w : word; 94 95 begin 96 SetVESAMode:=false; 97 for w:=VesaRegisteredModes-1 downto 0 do 98 begin 99 if (VideoMode.col=SupportedVesaVMD[w].v.col) and 100 (VideoMode.row=SupportedVesaVMD[w].v.row) and 101 (VideoMode.color=SupportedVesaVMD[w].v.color) then 102 begin 103 if SetSuperVGAMode(SupportedVesaVMD[w].mode) <> $4f then 104 SetVESAMode:=false 105 else 106 begin 107 SetVESAMode:=true; 108 ScreenWidth:=VideoMode.Col; 109 ScreenHeight:=VideoMode.Row; 110 ScreenColor:=VideoMode.Color; 111 // cheat to get a correct mouse 112 { 113 mem[$40:$84]:=ScreenHeight-1; 114 mem[$40:$4a]:=ScreenWidth; 115 memw[$40:$4c]:=ScreenHeight*((ScreenWidth shl 1)-1); 116 } 117 DoCustomMouse(true); 118 end; 119 end; 120 if SetVESAMode then 121 exit; 122 end; 123 SetVESAMode:=SysSetVideoMode(VideoMode); 124 end; 125 126procedure InitializeVesaModes; 127var 128 infoblock : TVESAInfoBLock; 129 i : word; 130 m : word; 131begin 132 ReturnSuperVGAInfo(infoblock); 133 if not((infoblock.VESASignature[0]<>'V') or 134 (infoblock.VESASignature[1]<>'E') or 135 (infoblock.VESASignature[2]<>'S') or 136 (infoblock.VESASignature[3]<>'A')) then 137 begin 138{$R-} 139 i:=0; 140 while true do 141 begin 142 m := MemW[Seg(infoblock.VideoModePtr^):Ofs(infoblock.VideoModePtr^)+i*2]; 143 case m of 144 264: 145 Begin 146 {RegisterVideoMode(80,60,true,@SetVESAMode,264);} 147 SupportedVesaVMD[VesaRegisteredModes]:=VesaVMD[m]; 148 Inc(VesaRegisteredModes); 149 End; 150 265: 151 Begin 152 {RegisterVideoMode(132,25,true,@SetVESAMode,265);} 153 SupportedVesaVMD[VesaRegisteredModes]:=VesaVMD[m]; 154 Inc(VesaRegisteredModes); 155 End; 156 266: 157 Begin 158 {RegisterVideoMode(132,43,true,@SetVESAMode,266);} 159 SupportedVesaVMD[VesaRegisteredModes]:=VesaVMD[m]; 160 Inc(VesaRegisteredModes); 161 End; 162 267: 163 Begin 164 {RegisterVideoMode(132,50,true,@SetVESAMode,267);} 165 SupportedVesaVMD[VesaRegisteredModes]:=VesaVMD[m]; 166 Inc(VesaRegisteredModes); 167 End; 168 268: 169 Begin 170 {RegisterVideoMode(132,60,true,@SetVESAMode,268);} 171 SupportedVesaVMD[VesaRegisteredModes]:=VesaVMD[m]; 172 Inc(VesaRegisteredModes); 173 End; 174 $ffff: 175 break; 176 end; 177 inc(i); 178 end; 179 end; 180end; 181 182 183Function VesaGetVideoModeData (Index : Word; Var Data : TVideoMode) : boolean; 184Var 185 PrevCount : word; 186 187begin 188 PrevCount:=SysGetVideoModeCount(); 189 VesaGetVideoModeData:=(Index<=PrevCount); 190 If VesaGetVideoModeData then 191 begin 192 SysGetVideoModeData(Index,Data); 193 exit; 194 end; 195 VesaGetVideoModeData:=(Index-PrevCount)<=VesaRegisteredModes; 196 If VesaGetVideoModeData then 197 Data:=SupportedVesaVMD[Index-PrevCount-1].V; 198end; 199 200Function VesaGetVideoModeCount : Word; 201 202begin 203 VesaGetVideoModeCount:=SysGetVideoModeCount()+VesaRegisteredModes; 204end; 205 206 207Var 208 Driver : TVideoDriver; 209(* 210Const 211 SysVideoDriver : TVideoDriver = ( 212 InitDriver : @SysInitVideo; 213 DoneDriver : @SysDoneVideo; 214 UpdateScreen : @SysUpdateScreen; 215 ClearScreen : Nil; 216 SetVideoMode : @SysSetVideoMode; 217 GetVideoModeCount : @SysGetVideoModeCount; 218 GetVideoModeData : @SysGetVideoModedata; 219 SetCursorPos : @SysSetCursorPos; 220 GetCursorType : @SysGetCursorType; 221 SetCursorType : @SysSetCursorType; 222 GetCapabilities : @SysGetCapabilities 223 ); 224*) 225initialization 226 227{ Get the videodriver to be used } 228 GetVideoDriver (Driver); 229 InitializeVesaModes; 230{ Change needed functions } 231 SysGetVideoModeCount:=Driver.GetVideoModeCount; 232 Driver.GetVideoModeCount:=@VesaGetVideoModeCount; 233 SysGetVideoModeData:=Driver.GetVideoModeData; 234 Driver.GetVideoModeData:=@VesaGetVideoModeData; 235 SysSetVideoMode:=Driver.SetVideoMode; 236 Driver.SetVideoMode:=@SetVESAMode; 237 238 SetVideoDriver (Driver); 239end. 240