vesamode.pp 6.8 KB

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