vesamode.pp 7.0 KB

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