vesa.pas 20 KB

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