vesa.pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  1. {
  2. This file is part of the PinGUI - Platform Independent GUI Project
  3. Copyright (c) 1999 by Berczi Gabor
  4. VESA support routines
  5. See the file COPYING.GUI, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit VESA;
  12. {$ifdef DEBUG}
  13. {$define TESTGRAPHIC}
  14. {$endif DEBUG}
  15. {$H-}
  16. interface
  17. uses
  18. Dos,
  19. Objects,Strings,WUtils;
  20. const
  21. { Video Mode Attributes mask constants }
  22. vesa_vma_CanBeSetInCurrentConfig = $0001;
  23. vesa_vma_OptionalBlockPresent = $0002;
  24. vesa_vma_BIOSSupport = $0004;
  25. vesa_vma_ColorMode = $0008; { else mono }
  26. vesa_vma_GraphicsMode = $0010; { else text }
  27. { -- VBE 2.0 --- }
  28. vesa_vma_VGACompatibleMode = $0020;
  29. vesa_vma_VGACompWindowedAvail = $0040;
  30. vesa_vma_LinearFrameBufferAvail = $0080;
  31. { Windows Attributes mask constants }
  32. vesa_wa_Present = $0001;
  33. vesa_wa_Readable = $0002;
  34. vesa_wa_Writeable = $0004;
  35. { Memory Model value constants }
  36. vesa_mm_Text = $0000;
  37. vesa_mm_CGAGraphics = $0001;
  38. vesa_mm_HerculesGraphics = $0002;
  39. vesa_mm_4planePlanar = $0003;
  40. vesa_mm_PackedPixel = $0004;
  41. vesa_mm_NonChain4_256color = $0005;
  42. vesa_mm_DirectColor = $0006;
  43. vesa_mm_YUV = $0007;
  44. { Memory Window value constants }
  45. vesa_mw_WindowA = $0000;
  46. vesa_mw_WindowB = $0001;
  47. type
  48. tregisters=registers;
  49. PtrRec16 = record
  50. Ofs,Seg: word;
  51. end;
  52. TVESAInfoBlock = packed record
  53. Signature : longint; { 'VESA' }
  54. Version : word;
  55. OEMString : PString;
  56. Capabilities : longint;
  57. VideoModeList: PWordArray;
  58. TotalMemory : word; { in 64KB blocks }
  59. Fill : array[1..236] of byte;
  60. VBE2Fill : array[1..256] of byte;
  61. end;
  62. TVESAModeInfoBlock = packed record
  63. Attributes : word;
  64. WinAAttrs : byte;
  65. WinBAttrs : byte;
  66. Granularity : word;
  67. Size : word;
  68. ASegment : word;
  69. BSegment : word;
  70. FuncPtr : pointer;
  71. BytesPerLine : word;
  72. { optional }
  73. XResolution : word;
  74. YResolution : word;
  75. XCharSize : byte;
  76. YCharSize : byte;
  77. NumberOfPlanes : byte;
  78. BitsPerPixel : byte;
  79. NumberOfBanks : byte;
  80. MemoryModel : byte;
  81. BankSize : byte;
  82. NumberOfImagePages: byte;
  83. Reserved : byte;
  84. { direct color fields }
  85. RedMaskSize : byte;
  86. RedFieldPosition: byte;
  87. GreenMaskSize : byte;
  88. GreenFieldPosition: byte;
  89. BlueMaskSize : byte;
  90. BlueFieldPosition: byte;
  91. ReservedMaskSize: byte;
  92. ReservedPosition: byte;
  93. DirectColorModeInfo: byte;
  94. { --- VBE 2.0 optional --- }
  95. LinearFrameAddr : longint;
  96. OffScreenAddr : longint;
  97. OffScreenSize : word;
  98. Reserved2 : array[1..216-(4+4+2)] of byte;
  99. end;
  100. TVESAModeList = record
  101. Count : word;
  102. Modes : array[1..256] of word;
  103. end;
  104. function VESAInit: boolean;
  105. function VESAGetInfo(var B: TVESAInfoBlock): boolean;
  106. function VESAGetModeInfo(Mode: word; var B: TVESAModeInfoBlock): boolean;
  107. function VESAGetModeList(var B: TVESAModeList): boolean;
  108. function VESASearchMode(XRes,YRes,BPX: word; LFB: boolean; var Mode: word; var ModeInfo: TVESAModeInfoBlock): boolean;
  109. function VESAGetOemString: string;
  110. function VESASetMode(Mode: word): boolean;
  111. function VESAGetMode(var Mode: word): boolean;
  112. function VESASelectMemoryWindow(Window: byte; Position: word): boolean;
  113. function VESAReturnMemoryWindow(Window: byte; var Position: word): boolean;
  114. function RegisterVesaVideoMode(Mode : word) : boolean;
  115. Procedure FreeVesaModes;
  116. const
  117. DisableVESA : boolean = false;
  118. implementation
  119. uses
  120. video, mouse,
  121. {$ifdef TESTGRAPHIC}
  122. graph,
  123. {$endif TESTGRAPHIC}
  124. pmode;
  125. type
  126. PVesaVideoMode = ^TVesaVideoMode;
  127. TVesaVideoMode = record
  128. {Col,Row : word;
  129. Color : boolean;}
  130. V : TVideoMode;
  131. Mode : word;
  132. IsGraphic : boolean;
  133. { zero based vesa specific driver count }
  134. VideoIndex : word;
  135. Next : PVesaVideoMode;
  136. end;
  137. CursorBitMap = Record
  138. width,height,size : longint;
  139. colors : array[0..8*8-1] of word;
  140. end;
  141. const
  142. VesaVideoModeHead : PVesaVideoMode = nil;
  143. VesaRegisteredModes : word = 0;
  144. {$ifdef TESTGRAPHIC}
  145. IsGraphicMode : boolean = false;
  146. GraphDriver : integer = 0;
  147. GraphMode : Integer = 0;
  148. FirstCallAfterSetVesaMode : boolean = false;
  149. LastCursorX : word = $ffff;
  150. LastCursorY : word = $ffff;
  151. LastCursorType : word = crHidden;
  152. var
  153. UnderLineImage : CursorBitMap;
  154. BlockImage : CursorBitMap;
  155. HalfBlockImage : CursorBitMap;
  156. {$endif TESTGRAPHIC}
  157. Var
  158. SysGetVideoModeCount : function : word;
  159. SysSetVideoMode : function (Const VideoMode : TVideoMode) : boolean;
  160. SysGetVideoModeData : function (Index : Word; Var Data : TVideoMode) : boolean;
  161. SysUpdateScreen : procedure(Force : Boolean);
  162. SysDoneVideo : procedure;
  163. SysInitVideo : procedure;
  164. SysSetCursorPos : procedure(NewCursorX, NewCursorY: Word);
  165. SysSetCursorType : procedure(NewCurosrType : word);
  166. function VESAGetInfo(var B: TVESAInfoBlock): boolean;
  167. var r: registers;
  168. OK: boolean;
  169. M: MemPtr;
  170. begin
  171. if disableVESA then
  172. exit(false);
  173. StrToMem('VBE2',B.Signature);
  174. GetDosMem(M,SizeOf(B));
  175. M.MoveDataTo(B,sizeof(B));
  176. r.ah:=$4f; r.al:=0;
  177. r.es:=M.DosSeg; r.di:=M.DosOfs;
  178. realintr($10,r);
  179. M.MoveDataFrom(sizeof(B),B);
  180. FreeDosMem(M);
  181. OK:=(r.ax=$004f){ and (MemToStr(B.Signature,4)='VESA')};
  182. VESAGetInfo:=OK;
  183. end;
  184. function VESAGetModeList(var B: TVESAModeList): boolean;
  185. var OK: boolean;
  186. VI: TVESAInfoBlock;
  187. begin
  188. FillChar(B,SizeOf(B),0);
  189. if disableVESA then
  190. exit(false);
  191. OK:=VESAGetInfo(VI);
  192. if OK then
  193. begin
  194. OK:=MoveDosToPM(VI.VideoModeList,@B.Modes,sizeof(B.Modes));
  195. if OK then
  196. while (B.Modes[B.Count+1]<>$ffff) and (B.Count<High(B.Modes)) do
  197. Inc(B.Count);
  198. end;
  199. VESAGetModeList:=OK;
  200. end;
  201. function VESASearchMode(XRes,YRes,BPX: word; LFB: boolean; var Mode: word; var ModeInfo: TVESAModeInfoBlock): boolean;
  202. var B: TVESAModeList;
  203. OK: boolean;
  204. I: integer;
  205. MI: TVESAModeInfoBlock;
  206. begin
  207. OK:=VESAGetModeList(B);
  208. I:=1; Mode:=0;
  209. repeat
  210. OK:=VESAGetModeInfo(B.Modes[I],MI);
  211. if OK and (MI.XResolution=XRes) and (MI.YResolution=YRes) and
  212. (MI.BitsPerPixel=BPX) and
  213. ((LFB=false) or ((MI.Attributes and vesa_vma_LinearFrameBufferAvail)<>0)) then
  214. begin Mode:=B.Modes[I]; ModeInfo:=MI; end;
  215. Inc(I);
  216. until (OK=false) or (I>=B.Count) or (Mode<>0);
  217. OK:=Mode<>0;
  218. VESASearchMode:=OK;
  219. end;
  220. function VESAGetOemString: string;
  221. var OK: boolean;
  222. VI: TVESAInfoBlock;
  223. S: array[0..256] of AnsiChar;
  224. begin
  225. if disableVESA then
  226. begin
  227. VESAGetOemString:='VESA disabled';
  228. exit;
  229. end;
  230. FillChar(S,SizeOf(S),0);
  231. OK:=VESAGetInfo(VI);
  232. if OK then
  233. OK:=MoveDosToPM(VI.OemString,@S,sizeof(S));
  234. VESAGetOemString:=StrPas(@S);
  235. end;
  236. function VESAGetModeInfo(Mode: word; var B: TVESAModeInfoBlock): boolean;
  237. var r : registers;
  238. M : MemPtr;
  239. OK: boolean;
  240. begin
  241. if disableVESA then
  242. exit(false);
  243. r.ah:=$4f; r.al:=$01; r.cx:=Mode;
  244. GetDosMem(M,sizeof(B));
  245. r.es:=M.DosSeg; r.di:=M.DosOfs; {r.ds:=r.es;}
  246. realintr($10,r);
  247. M.MoveDataFrom(sizeof(B),B);
  248. FreeDosMem(M);
  249. OK:=(r.ax=$004f);
  250. VESAGetModeInfo:=OK;
  251. end;
  252. function RegisterVesaVideoMode(Mode : word) : boolean;
  253. var B: TVESAModeInfoBlock;
  254. VH : PVesaVideoMode;
  255. DoAdd : boolean;
  256. begin
  257. if not VESAGetModeInfo(Mode,B) then
  258. RegisterVesaVideoMode:=false
  259. else
  260. begin
  261. VH:=VesaVideoModeHead;
  262. DoAdd:=true;
  263. RegisterVesaVideoMode:=false;
  264. while assigned(VH) do
  265. begin
  266. if VH^.mode=mode then
  267. DoAdd:=false;
  268. VH:=VH^.next;
  269. end;
  270. if DoAdd then
  271. begin
  272. New(VH);
  273. VH^.next:=VesaVideoModeHead;
  274. VH^.mode:=mode;
  275. VH^.IsGraphic:=(B.Attributes and vesa_vma_GraphicsMode)<>0;
  276. VH^.v.color:=(B.Attributes and vesa_vma_ColorMode)<>0;
  277. if VH^.IsGraphic then
  278. begin
  279. VH^.v.col:=B.XResolution div 8;
  280. VH^.v.row:=B.YResolution div 8;
  281. end
  282. else
  283. begin
  284. VH^.v.col:=B.XResolution;
  285. VH^.v.row:=B.YResolution;
  286. end;
  287. VH^.VideoIndex:=VesaRegisteredModes;
  288. Inc(VesaRegisteredModes);
  289. RegisterVesaVideoMode:=true;
  290. VesaVideoModeHead:=VH;
  291. end;
  292. end;
  293. end;
  294. function VESASetMode(Mode: word): boolean;
  295. var r: registers;
  296. OK: boolean;
  297. begin
  298. if disableVESA then
  299. exit(false);
  300. r.ah:=$4f; r.al:=$02; r.bx:=Mode;
  301. dos.intr($10,r);
  302. OK:=(r.ax=$004f);
  303. VESASetMode:=OK;
  304. end;
  305. function VESAGetMode(var Mode: word): boolean;
  306. var r : registers;
  307. OK: boolean;
  308. begin
  309. if disableVESA then
  310. exit(false);
  311. if disableVESA then
  312. exit(false);
  313. r.ah:=$4f; r.al:=$03;
  314. dos.intr($10,r);
  315. OK:=(r.ax=$004f);
  316. if OK then Mode:=r.bx;
  317. VESAGetMode:=OK;
  318. end;
  319. function VESASelectMemoryWindow(Window: byte; Position: word): boolean;
  320. var r : registers;
  321. OK : boolean;
  322. begin
  323. if disableVESA then
  324. exit(false);
  325. r.ah:=$4f; r.al:=$05; r.bh:=0; r.bl:=Window; r.dx:=Position;
  326. dos.intr($10,r);
  327. OK:=(r.ax=$004f);
  328. VESASelectMemoryWindow:=OK;
  329. end;
  330. function VESAReturnMemoryWindow(Window: byte; var Position: word): boolean;
  331. var r : registers;
  332. OK : boolean;
  333. begin
  334. if disableVESA then
  335. exit(false);
  336. r.ah:=$4f; r.al:=$05; r.bh:=1; r.bl:=Window;
  337. dos.intr($10,r);
  338. OK:=(r.ax=$004f);
  339. if OK then Position:=r.dx;
  340. VESAReturnMemoryWindow:=OK;
  341. end;
  342. function VESAInit: boolean;
  343. var OK: boolean;
  344. VI: TVESAInfoBlock;
  345. begin
  346. if disableVESA then
  347. OK:=false
  348. else
  349. OK:=VESAGetInfo(VI);
  350. VESAInit:=OK;
  351. end;
  352. Function VesaGetVideoModeData (Index : Word; Var Data : TVideoMode) : boolean;
  353. Var
  354. PrevCount : word;
  355. VH : PVesaVideoMode;
  356. begin
  357. PrevCount:=SysGetVideoModeCount();
  358. VesaGetVideoModeData:=(Index<PrevCount);
  359. If VesaGetVideoModeData then
  360. begin
  361. VesaGetVideoModeData:=SysGetVideoModeData(Index,Data);
  362. exit;
  363. end;
  364. VesaGetVideoModeData:=(Index-PrevCount)<VesaRegisteredModes;
  365. If VesaGetVideoModeData then
  366. begin
  367. VH:=VesaVideoModeHead;
  368. while assigned(VH) and (VH^.VideoIndex<>Index-PrevCount) do
  369. VH:=VH^.next;
  370. if assigned(VH) then
  371. Data:=VH^.v
  372. else
  373. VesaGetVideoModeData:=false;
  374. end;
  375. end;
  376. function SetVESAMode(const VideoMode: TVideoMode): Boolean;
  377. var
  378. res : boolean;
  379. VH : PVesaVideoMode;
  380. begin
  381. res:=false;
  382. if disableVESA then
  383. exit(res);
  384. VH:=VesaVideoModeHead;
  385. while assigned(VH) do
  386. begin
  387. if (VideoMode.col=VH^.v.col) and
  388. (VideoMode.row=VH^.v.row) and
  389. (VideoMode.color=VH^.v.color) then
  390. begin
  391. {$ifdef TESTGRAPHIC}
  392. if VH^.IsGraphic then
  393. begin
  394. if IsGraphicMode then
  395. CloseGraph;
  396. GraphDriver:=Graph.Vesa;
  397. if (VideoMode.col = 100) and (VideoMode.row = 75) then
  398. GraphMode:=m800x600x256
  399. else if (VideoMode.col = 80) and (VideoMode.row = 60) then
  400. GraphMode:=m640x480x256
  401. else if (VideoMode.col = 128) and (VideoMode.row = 96) then
  402. GraphMode:=m1024x768x256
  403. else
  404. GraphMode:=Graph.Detect;
  405. InitGraph(GraphDriver,GraphMode,'');
  406. res:=(GraphResult=grOK);
  407. if not res then
  408. begin
  409. SetVesaMode:=false;
  410. exit;
  411. end;
  412. end
  413. else
  414. {$endif TESTGRAPHIC}
  415. res:=VESASetMode(VH^.mode);
  416. if res then
  417. begin
  418. ScreenWidth:=VideoMode.Col;
  419. ScreenHeight:=VideoMode.Row;
  420. ScreenColor:=VideoMode.Color;
  421. {$ifdef TESTGRAPHIC}
  422. IsGraphicMode:=VH^.IsGraphic;
  423. FirstCallAfterSetVesaMode:=true;
  424. LastCursorX:=$ffff;
  425. LastCursorY:=$ffff;
  426. LastCursorType:=crHidden;
  427. if IsGraphicMode then
  428. DoCustomMouse(false)
  429. else
  430. {$endif TESTGRAPHIC}
  431. DoCustomMouse(true);
  432. end;
  433. end;
  434. if res then
  435. begin
  436. SetVesaMode:=true;
  437. exit;
  438. end;
  439. VH:=VH^.next;
  440. end;
  441. SetVESAMode:=SysSetVideoMode(VideoMode);
  442. end;
  443. procedure VesaSetCursorPos(NewCursorX, NewCursorY: Word);
  444. begin
  445. {$ifdef TESTGRAPHIC}
  446. if not IsGraphicMode then
  447. {$endif TESTGRAPHIC}
  448. begin
  449. SysSetCursorPos(NewCursorX,NewCursorY);
  450. exit;
  451. end;
  452. {$ifdef TESTGRAPHIC}
  453. if (NewCursorX<>LastCursorX) or (NewCursorY<>LastCursorY) then
  454. begin
  455. Case GetCursorType of
  456. crHidden : ;
  457. crUnderLine :
  458. Begin
  459. PutImage(LastCursorX*8,LastCursorY*8+7,UnderLineImage,XORPut);
  460. PutImage(NewCursorX*8,NewCursorY*8+7,UnderLineImage,XORPut);
  461. End;
  462. crBlock :
  463. Begin
  464. PutImage(LastCursorX*8,LastCursorY*8,BlockImage,XORPut);
  465. PutImage(NewCursorX*8,NewCursorY*8,BlockImage,XORPut);
  466. End;
  467. crHalfBlock :
  468. Begin
  469. PutImage(LastCursorX*8,LastCursorY*8+4,HalfBlockImage,XORPut);
  470. PutImage(NewCursorX*8,NewCursorY*8+4,HalfBlockImage,XORPut);
  471. End;
  472. end;
  473. LastCursorX:=NewCursorX;
  474. LastCursorY:=NewCursorY;
  475. end;
  476. {$endif TESTGRAPHIC}
  477. end;
  478. procedure VesaSetCursorType(NewType : Word);
  479. begin
  480. {$ifdef TESTGRAPHIC}
  481. if not IsGraphicMode then
  482. {$endif TESTGRAPHIC}
  483. begin
  484. SysSetCursorType(NewType);
  485. exit;
  486. end;
  487. {$ifdef TESTGRAPHIC}
  488. if (NewType<>LastCursorType) then
  489. begin
  490. Case LastCursorType of
  491. crHidden : ;
  492. crUnderLine :
  493. Begin
  494. PutImage(LastCursorX*8,LastCursorY*8+7,UnderLineImage,XORPut);
  495. End;
  496. crBlock :
  497. Begin
  498. PutImage(LastCursorX*8,LastCursorY*8,BlockImage,XORPut);
  499. End;
  500. crHalfBlock :
  501. Begin
  502. PutImage(LastCursorX*8,LastCursorY*8+4,HalfBlockImage,XORPut);
  503. End;
  504. end;
  505. SysSetCursorType(NewType);
  506. Case NewType of
  507. crHidden : ;
  508. crUnderLine :
  509. Begin
  510. PutImage(LastCursorX*8,LastCursorY*8+7,UnderLineImage,XORPut);
  511. End;
  512. crBlock :
  513. Begin
  514. PutImage(LastCursorX*8,LastCursorY*8,BlockImage,XORPut);
  515. End;
  516. crHalfBlock :
  517. Begin
  518. PutImage(LastCursorX*8,LastCursorY*8+4,HalfBlockImage,XORPut);
  519. End;
  520. end;
  521. LastCursorType:=NewType;
  522. end;
  523. {$endif TESTGRAPHIC}
  524. end;
  525. procedure VesaUpdateScreen(Force: Boolean);
  526. {$ifdef TESTGRAPHIC}
  527. var
  528. StoreDrawTextBackground,
  529. MustUpdate : boolean;
  530. x,y : longint;
  531. w, prevcolor,
  532. prevbkcolor, StoreCursorType : word;
  533. Color,BkCol,Col : byte;
  534. Ch : AnsiChar;
  535. {$endif TESTGRAPHIC}
  536. begin
  537. {$ifdef TESTGRAPHIC}
  538. if not IsGraphicMode then
  539. {$endif TESTGRAPHIC}
  540. begin
  541. SysUpdateScreen(Force);
  542. exit;
  543. end;
  544. {$ifdef TESTGRAPHIC}
  545. if FirstCallAfterSetVesaMode then
  546. begin
  547. { Make sure to redraw all }
  548. Fillchar(OldVideoBuf^,VideoBufSize,#0);
  549. FirstCallAfterSetVesaMode:=false;
  550. end;
  551. if not force then
  552. begin
  553. MustUpdate:=false;
  554. asm
  555. movl VideoBuf,%esi
  556. movl OldVideoBuf,%edi
  557. movl VideoBufSize,%ecx
  558. shrl $2,%ecx
  559. repe
  560. cmpsl
  561. setne MustUpdate
  562. end;
  563. end;
  564. StoreDrawTextBackground:=DrawTextBackground;
  565. DrawTextBackground:=true;
  566. if Force or MustUpdate then
  567. begin
  568. PrevColor:=GetColor;
  569. PrevBkColor:=GetBkColor{$ifdef FPC}(){$endif};
  570. for y:=0 to ScreenHeight-1 do
  571. for x:=0 to Screenwidth-1 do
  572. begin
  573. w:=VideoBuf^[x+y*ScreenWidth];
  574. if Force or
  575. (w<>OldVideoBuf^[x+y*ScreenWidth]) then
  576. Begin
  577. Color:=w shr 8;
  578. Ch:=chr(w and $ff);
  579. Col:=Color and $f;
  580. if (Col = 0) and (GetMaxColor=255) then
  581. Col:=255;
  582. SetColor(Col);
  583. BkCol:=(Color shr 4) and 7;
  584. if (BkCol = 0) and (GetMaxColor=255) then
  585. BkCol:=255;
  586. SetBkColor(BkCol);
  587. if (x=LastCursorX) and (Y=LastCursorY) then
  588. begin
  589. StoreCursorType:=LastCursorType;
  590. VesaSetCursorType(crHidden);
  591. end;
  592. OutTextXY(x*8,y*8,Ch);
  593. if (x=LastCursorX) and (Y=LastCursorY) then
  594. VesaSetCursorType(StoreCursorType);
  595. if not force then
  596. OldVideoBuf^[x+y*ScreenWidth]:=w;
  597. End;
  598. end;
  599. if Force then
  600. move(videobuf^,oldvideobuf^,
  601. VideoBufSize);
  602. SetColor(PrevColor);
  603. SetBkColor(GetBkColor{$ifdef FPC}(){$endif});
  604. end;
  605. DrawTextBackground:=StoreDrawTextBackground;
  606. {$endif TESTGRAPHIC}
  607. end;
  608. procedure VesaDoneVideo;
  609. begin
  610. {$ifdef TESTGRAPHIC}
  611. if IsGraphicMode then
  612. begin
  613. CloseGraph;
  614. IsGraphicMode:=false;
  615. end;
  616. {$endif TESTGRAPHIC}
  617. SysDoneVideo();
  618. end;
  619. function SetVESAVideoDriver : boolean; forward;
  620. procedure VesaInitVideo;
  621. begin
  622. if not SetVESAVideoDriver then
  623. exit;
  624. {$ifdef TESTGRAPHIC}
  625. if IsGraphicMode then
  626. begin
  627. SysInitVideo();
  628. InitGraph(GraphDriver,GraphMode,'');
  629. end
  630. else
  631. {$endif TESTGRAPHIC}
  632. SysInitVideo();
  633. end;
  634. Function VesaGetVideoModeCount : Word;
  635. begin
  636. VesaGetVideoModeCount:=SysGetVideoModeCount()+VesaRegisteredModes;
  637. end;
  638. Procedure FreeVesaModes;
  639. var
  640. VH : PVesaVideoMode;
  641. begin
  642. VH:=VesaVideoModeHead;
  643. While assigned(VH) do
  644. begin
  645. VesaVideoModeHead:=VH^.Next;
  646. FreeMem(VH,Sizeof(TVesaVideoMode));
  647. VH:=VesaVideoModeHead;
  648. end;
  649. end;
  650. Var
  651. Driver : TVideoDriver;
  652. {$ifdef TESTGRAPHIC}
  653. i : longint;
  654. {$endif TESTGRAPHIC}
  655. function SetVESAVideoDriver : boolean;
  656. BEGIN
  657. if disableVESA then
  658. exit(false);
  659. { Get the videodriver to be used }
  660. GetVideoDriver (Driver);
  661. { Change needed functions }
  662. SysGetVideoModeCount:=Driver.GetVideoModeCount;
  663. Driver.GetVideoModeCount:=@VesaGetVideoModeCount;
  664. SysGetVideoModeData:=Driver.GetVideoModeData;
  665. Driver.GetVideoModeData:=@VesaGetVideoModeData;
  666. SysSetVideoMode:=Driver.SetVideoMode;
  667. Driver.SetVideoMode:=@SetVESAMode;
  668. SysSetCursorPos:=Driver.SetCursorPos;
  669. Driver.SetCursorPos:=@VESASetCursorPos;
  670. SysSetCursorType:=Driver.SetCursorType;
  671. Driver.SetCursorType:=@VESASetCursorType;
  672. SysUpdateScreen:=Driver.UpdateScreen;
  673. Driver.UpdateScreen:=@VesaUpdateScreen;
  674. SysDoneVideo:=Driver.DoneDriver;
  675. Driver.DoneDriver:=@VesaDoneVideo;
  676. SysInitVideo:=Driver.InitDriver;
  677. Driver.InitDriver:=@VesaInitVideo;
  678. {$ifdef TESTGRAPHIC}
  679. BlockImage.width:=7;
  680. BlockImage.height:=7;
  681. For i:=0 to 8*8-1 do
  682. BlockImage.colors[i]:=White;
  683. HalfBlockImage:=BlockImage;
  684. HalfBlockImage.height:=3;
  685. UnderLineImage:=BlockImage;
  686. UnderLineImage.height:=0;
  687. {$endif TESTGRAPHIC}
  688. SetVideoDriver (Driver);
  689. SetVESAVideoDriver:=true;
  690. END;
  691. function ChkWinNT: boolean;
  692. var
  693. R: Registers;
  694. begin
  695. ChkWinNT := false;
  696. R.AX := $3306;
  697. RealIntr ($21, R);
  698. if (R.AL = 255) or (R.BX <> 50 * 256 + 5) then
  699. Exit;
  700. R.AX := $3000;
  701. RealIntr ($21, R);
  702. if (R.AX = 5) and (R.BH = 255) then
  703. ChkWinNT := true;
  704. end;
  705. begin
  706. (* Let's disable VESA functions by default if running under MS Windows NT+ *)
  707. if ChkWinNT then
  708. DisableVESA := true;
  709. END.