vesa.pas 20 KB

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