vesa.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. {
  2. $Id$
  3. This file is part of the PinGUI - Platform Independent GUI Project
  4. Copyright (c) 1999 by Berczi Gabor
  5. VESA support routines
  6. See the file COPYING.GUI, 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 VESA;
  13. interface
  14. uses
  15. Dos,
  16. {$ifdef TP}
  17. {$ifdef DPMI}
  18. WinDos,WinAPI,
  19. {$endif}
  20. {$endif}
  21. {$ifdef FPC}
  22. {$ifdef GO32V2}
  23. Go32,
  24. {$endif}
  25. {$endif}
  26. Objects,Strings,WUtils;
  27. const
  28. { Video Mode Attributes mask constants }
  29. vesa_vma_CanBeSetInCurrentConfig = $0001;
  30. vesa_vma_OptionalBlockPresent = $0002;
  31. vesa_vma_BIOSSupport = $0004;
  32. vesa_vma_ColorMode = $0008; { else mono }
  33. vesa_vma_GraphicsMode = $0010; { else text }
  34. { -- VBE 2.0 --- }
  35. vesa_vma_VGACompatibleMode = $0020;
  36. vesa_vma_VGACompWindowedAvail = $0040;
  37. vesa_vma_LinearFrameBufferAvail = $0080;
  38. { Windows Attributes mask constants }
  39. vesa_wa_Present = $0001;
  40. vesa_wa_Readable = $0002;
  41. vesa_wa_Writeable = $0004;
  42. { Memory Model value constants }
  43. vesa_mm_Text = $0000;
  44. vesa_mm_CGAGraphics = $0001;
  45. vesa_mm_HerculesGraphics = $0002;
  46. vesa_mm_4planePlanar = $0003;
  47. vesa_mm_PackedPixel = $0004;
  48. vesa_mm_NonChain4_256color = $0005;
  49. vesa_mm_DirectColor = $0006;
  50. vesa_mm_YUV = $0007;
  51. { Memory Window value constants }
  52. vesa_mw_WindowA = $0000;
  53. vesa_mw_WindowB = $0001;
  54. type
  55. {$ifdef FPC}tregisters=registers;{$endif}
  56. {$ifdef TP}tregisters=registers;{$endif}
  57. PtrRec16 = record
  58. Ofs,Seg: word;
  59. end;
  60. TVESAInfoBlock = record
  61. Signature : longint; { 'VESA' }
  62. Version : word;
  63. OEMString : PString;
  64. Capabilities : longint;
  65. VideoModeList: PWordArray;
  66. TotalMemory : word; { in 64KB blocks }
  67. Fill : array[1..236] of byte;
  68. VBE2Fill : array[1..256] of byte;
  69. end;
  70. TVESAModeInfoBlock = record
  71. Attributes : word;
  72. WinAAttrs : byte;
  73. WinBAttrs : byte;
  74. Granularity : word;
  75. Size : word;
  76. ASegment : word;
  77. BSegment : word;
  78. FuncPtr : pointer;
  79. BytesPerLine : word;
  80. { optional }
  81. XResolution : word;
  82. YResolution : word;
  83. XCharSize : byte;
  84. YCharSize : byte;
  85. NumberOfPlanes : byte;
  86. BitsPerPixel : byte;
  87. NumberOfBanks : byte;
  88. MemoryModel : byte;
  89. BankSize : byte;
  90. NumberOfImagePages: byte;
  91. Reserved : byte;
  92. { direct color fields }
  93. RedMaskSize : byte;
  94. RedFieldPosition: byte;
  95. GreenMaskSize : byte;
  96. GreenFieldPosition: byte;
  97. BlueMaskSize : byte;
  98. BlueFieldPosition: byte;
  99. ReservedMaskSize: byte;
  100. ReservedPosition: byte;
  101. DirectColorModeInfo: byte;
  102. { --- VBE 2.0 optional --- }
  103. LinearFrameAddr : longint;
  104. OffScreenAddr : longint;
  105. OffScreenSize : word;
  106. Reserved2 : array[1..216-(4+4+2)] of byte;
  107. end;
  108. TVESAModeList = record
  109. Count : word;
  110. Modes : array[1..256] of word;
  111. end;
  112. function VESAInit: boolean;
  113. function VESAGetInfo(var B: TVESAInfoBlock): boolean;
  114. function VESAGetModeInfo(Mode: word; var B: TVESAModeInfoBlock): boolean;
  115. function VESAGetModeList(var B: TVESAModeList): boolean;
  116. function VESASearchMode(XRes,YRes,BPX: word; LFB: boolean; var Mode: word; var ModeInfo: TVESAModeInfoBlock): boolean;
  117. function VESAGetOemString: string;
  118. function VESASetMode(Mode: word): boolean;
  119. function VESAGetMode(var Mode: word): boolean;
  120. function VESASelectMemoryWindow(Window: byte; Position: word): boolean;
  121. function VESAReturnMemoryWindow(Window: byte; var Position: word): boolean;
  122. function MemToStr(var B; Count: byte): string;
  123. implementation
  124. {$IFDEF DPMI}
  125. const
  126. DPMI_INTR = $31;
  127. type
  128. TDPMIRegisters = record { DPMI call structure }
  129. EDI : LongInt;
  130. ESI : LongInt;
  131. EBP : LongInt;
  132. Reserved: LongInt;
  133. EBX : LongInt;
  134. EDX : LongInt;
  135. ECX : LongInt;
  136. EAX : LongInt;
  137. Flags : Word;
  138. ES : Word;
  139. DS : Word;
  140. FS : Word;
  141. GS : Word;
  142. IP : Word;
  143. CS : Word;
  144. SP : Word;
  145. SS : Word;
  146. end;
  147. MemPtr = record
  148. {$ifdef TP}
  149. Selector: Word; {Protected mode}
  150. Segment : Word; {Real mode}
  151. {$endif}
  152. {$ifdef FPC}
  153. Selector: Word; {Real mode}
  154. Segment : Word; {Protected mode}
  155. {$endif}
  156. end;
  157. Function GetMem(var Mem : MemPtr; Size : Word): Boolean;
  158. begin
  159. if (Size > 0) then
  160. begin
  161. {$ifdef TP}
  162. LongInt(Mem) := GlobalDOSAlloc(Size);
  163. {$endif}
  164. {$ifdef FPC}
  165. longint(Mem) := global_dos_alloc(Size);
  166. if int31error<>0 then longint(Mem):=0;
  167. {$endif}
  168. GetMem := (LongInt(Mem) <> 0);
  169. end
  170. else
  171. begin
  172. LongInt(Mem) := 0;
  173. GetMem := True;
  174. end;
  175. end;
  176. Procedure FreeMem(Mem : MemPtr; Size : Word);
  177. begin
  178. {$ifdef TP}
  179. if (Size > 0) then
  180. GlobalDOSFree(Mem.Selector);
  181. {$endif}
  182. {$ifdef FPC}
  183. if (Size > 0) then
  184. global_dos_free(Mem.Selector);
  185. {$endif}
  186. end;
  187. Function MakePtr(Mem : MemPtr): Pointer;
  188. begin
  189. MakePtr := Ptr(Mem.Selector, 0);
  190. end;
  191. {$ifdef TP}
  192. var
  193. DPMIRegs: TDPMIRegisters;
  194. procedure realintr(IntNo: byte; var r: tregisters);
  195. var Regs: TRegisters;
  196. begin
  197. FillChar(DPMIRegs, SizeOf(TDPMIRegisters), 0);
  198. DPMIRegs.EAX := r.ax;
  199. DPMIRegs.EBX := r.bx;
  200. DPMIRegs.ECX := r.cx;
  201. DPMIRegs.EDX := r.dx;
  202. DPMIRegs.EDI := r.di;
  203. DPMIRegs.ESI := r.si;
  204. DPMIRegs.EBP := r.bp;
  205. DPMIRegs.DS := r.ds;
  206. DPMIRegs.ES := r.es;
  207. DPMIRegs.Flags := r.flags;
  208. Regs.AX := $0300;
  209. Regs.BL := IntNo;
  210. Regs.BH := 0;
  211. Regs.CX := 0;
  212. Regs.ES := Seg(DPMIRegs);
  213. Regs.DI := Ofs(DPMIRegs);
  214. Dos.Intr(DPMI_INTR, Regs);
  215. r.ax := DPMIRegs.EAX;
  216. r.bx := DPMIRegs.EBX;
  217. r.cx := DPMIRegs.ECX;
  218. r.dx := DPMIRegs.EDX;
  219. r.di := DPMIRegs.EDI;
  220. r.si := DPMIRegs.ESI;
  221. r.bp := DPMIRegs.EBP;
  222. r.ds := DPMIRegs.DS;
  223. r.es := DPMIRegs.ES;
  224. r.Flags := DPMIRegs.Flags;
  225. end;
  226. {$endif}
  227. {$ENDIF}
  228. function MemToStr(var B; Count: byte): string;
  229. var S: string;
  230. begin
  231. S[0]:=chr(Count);
  232. if Count>0 then Move(B,S[1],Count);
  233. MemToStr:=S;
  234. end;
  235. procedure StrToMem(S: string; var B);
  236. begin
  237. if length(S)>0 then Move(S[1],B,length(S));
  238. end;
  239. function VESAGetInfo(var B: TVESAInfoBlock): boolean;
  240. {$IFNDEF DPMI}
  241. var r : registers;
  242. {$ELSE}
  243. var r : tregisters;
  244. pB : MemPtr;
  245. {$ENDIF}
  246. OK: boolean;
  247. begin
  248. StrToMem('VBE2',B.Signature);
  249. r.ah:=$4f; r.al:=0;
  250. {$IFNDEF DPMI}
  251. r.es:=seg(B); r.di:=ofs(B);
  252. intr($10,r);
  253. {$ELSE}
  254. GetMem(pB, SizeOf(B));
  255. {$ifdef TP}
  256. Move(B,MakePtr(pB)^,SizeOf(B));
  257. {$endif}
  258. {$ifdef FPC}
  259. dosmemput(pB.Segment,0,B,SizeOf(B));
  260. {$endif}
  261. r.es:=pB.Segment; r.di:=0; r.ds:=r.es;
  262. realintr($10,r);
  263. {$ENDIF}
  264. {$IFDEF DPMI}
  265. {$ifdef TP}
  266. Move(MakePtr(pB)^,B,SizeOf(B));
  267. {$endif}
  268. {$ifdef FPC}
  269. dosmemget(pB.Segment,0,B,SizeOf(B));
  270. {$endif}
  271. FreeMem(pB, SizeOf(B));
  272. {$ENDIF}
  273. OK:=(r.ax=$004f){ and (MemToStr(B.Signature,4)='VESA')};
  274. VESAGetInfo:=OK;
  275. end;
  276. function VESAGetModeList(var B: TVESAModeList): boolean;
  277. var OK: boolean;
  278. VI: TVESAInfoBlock;
  279. {$ifdef TP}
  280. {$ifdef DPMI}
  281. Sel: word;
  282. {$endif}
  283. {$endif}
  284. begin
  285. FillChar(B,SizeOf(B),0);
  286. OK:=VESAGetInfo(VI);
  287. if OK then
  288. begin
  289. {$ifdef TP}
  290. {$ifdef DPMI}
  291. Sel:=AllocSelector(0);
  292. OK:=Sel<>0;
  293. if OK then
  294. begin
  295. SetSelectorBase(Sel,(longint(VI.VideoModeList) shr 16)*16+longint(VI.VideoModeList) and $ffff);
  296. SetSelectorLimit(Sel,SizeOf(B.Modes));
  297. Move(ptr(Sel,0)^,B.Modes,SizeOf(B.Modes));
  298. FreeSelector(Sel);
  299. end;
  300. {$endif}
  301. {$endif}
  302. {$ifdef FPC}
  303. with VI do
  304. dosmemget(PtrRec(VideoModeList).Seg,PtrRec(VideoModeList).Ofs,B.Modes,SizeOf(B.Modes));
  305. {$endif}
  306. if OK then
  307. while (B.Modes[B.Count+1]<>$ffff) and (B.Count<255) do
  308. Inc(B.Count);
  309. end;
  310. VESAGetModeList:=OK;
  311. end;
  312. function VESASearchMode(XRes,YRes,BPX: word; LFB: boolean; var Mode: word; var ModeInfo: TVESAModeInfoBlock): boolean;
  313. var B: TVESAModeList;
  314. OK: boolean;
  315. I: integer;
  316. MI: TVESAModeInfoBlock;
  317. begin
  318. OK:=VESAGetModeList(B);
  319. I:=1; Mode:=0;
  320. repeat
  321. OK:=VESAGetModeInfo(B.Modes[I],MI);
  322. if OK and (MI.XResolution=XRes) and (MI.YResolution=YRes) and
  323. (MI.BitsPerPixel=BPX) and
  324. ((LFB=false) or ((MI.Attributes and vesa_vma_LinearFrameBufferAvail)<>0)) then
  325. begin Mode:=B.Modes[I]; ModeInfo:=MI; end;
  326. Inc(I);
  327. until (OK=false) or (I>=B.Count) or (Mode<>0);
  328. OK:=Mode<>0;
  329. VESASearchMode:=OK;
  330. end;
  331. function VESAGetOemString: string;
  332. var OK: boolean;
  333. VI: TVESAInfoBlock;
  334. {$ifdef TP}
  335. {$ifdef DPMI}
  336. Sel: word;
  337. {$endif}
  338. {$endif}
  339. S: array[0..256] of char;
  340. begin
  341. FillChar(S,SizeOf(S),0);
  342. OK:=VESAGetInfo(VI);
  343. {$IFDEF DPMI}
  344. if OK then
  345. begin
  346. {$ifdef TP}
  347. Sel:=AllocSelector(0);
  348. OK:=Sel<>0;
  349. if OK then
  350. begin
  351. SetSelectorBase(Sel,longint(PtrRec16(VI.OemString).Seg)*16+PtrRec16(VI.OemString).Ofs);
  352. SetSelectorLimit(Sel,SizeOf(S));
  353. Move(ptr(Sel,0)^,S,SizeOf(S));
  354. FreeSelector(Sel);
  355. end;
  356. {$endif}
  357. {$ifdef FPC}
  358. dosmemget(PtrRec16(VI.OemString).Seg,PtrRec16(VI.OemString).Ofs,S,SizeOf(S));
  359. {$endif}
  360. end;
  361. {$ELSE}
  362. Move(VI.OemString^,S,SizeOf(S));
  363. {$ENDIF}
  364. VESAGetOemString:=StrPas(@S);
  365. end;
  366. function VESAGetModeInfo(Mode: word; var B: TVESAModeInfoBlock): boolean;
  367. {$IFNDEF DPMI}
  368. var r : registers;
  369. {$ELSE}
  370. var r : tregisters;
  371. {$ENDIF}
  372. OK: boolean;
  373. {$ifdef DPMI}
  374. pB: MemPtr;
  375. {$endif}
  376. begin
  377. r.ah:=$4f; r.al:=$01; r.cx:=Mode;
  378. {$IFDEF DPMI}
  379. GetMem(pB, SizeOf(B));
  380. {$ifdef TP}
  381. Move(B,MakePtr(pB)^,SizeOf(B));
  382. {$endif}
  383. {$ifdef FPC}
  384. dosmemput(pB.Segment,0,B,SizeOf(B));
  385. {$endif}
  386. r.es:=pB.Segment; r.di:=0; {r.ds:=r.es;}
  387. realintr($10,r);
  388. {$ELSE}
  389. r.es:=seg(B); r.di:=ofs(B);
  390. intr($10,r);
  391. {$ENDIF}
  392. {$IFDEF DPMI}
  393. {$ifdef TP}
  394. Move(MakePtr(pB)^,B,SizeOf(B));
  395. {$endif}
  396. {$ifdef FPC}
  397. dosmemget(pB.Segment,0,B,SizeOf(B));
  398. {$endif}
  399. FreeMem(pB, SizeOf(B));
  400. {$ENDIF}
  401. OK:=(r.ax=$004f);
  402. VESAGetModeInfo:=OK;
  403. end;
  404. function VESASetMode(Mode: word): boolean;
  405. var r: registers;
  406. OK: boolean;
  407. begin
  408. r.ah:=$4f; r.al:=$02; r.bx:=Mode;
  409. dos.intr($10,r);
  410. OK:=(r.ax=$004f);
  411. VESASetMode:=OK;
  412. end;
  413. function VESAGetMode(var Mode: word): boolean;
  414. var r : registers;
  415. OK: boolean;
  416. begin
  417. r.ah:=$4f; r.al:=$03;
  418. dos.intr($10,r);
  419. OK:=(r.ax=$004f);
  420. if OK then Mode:=r.bx;
  421. VESAGetMode:=OK;
  422. end;
  423. function VESASelectMemoryWindow(Window: byte; Position: word): boolean;
  424. var r : registers;
  425. OK : boolean;
  426. begin
  427. r.ah:=$4f; r.al:=$05; r.bh:=0; r.bl:=Window; r.dx:=Position;
  428. dos.intr($10,r);
  429. OK:=(r.ax=$004f);
  430. VESASelectMemoryWindow:=OK;
  431. end;
  432. function VESAReturnMemoryWindow(Window: byte; var Position: word): boolean;
  433. var r : registers;
  434. OK : boolean;
  435. begin
  436. r.ah:=$4f; r.al:=$05; r.bh:=1; r.bl:=Window;
  437. dos.intr($10,r);
  438. OK:=(r.ax=$004f);
  439. if OK then Position:=r.dx;
  440. VESAReturnMemoryWindow:=OK;
  441. end;
  442. function VESAInit: boolean;
  443. var OK: boolean;
  444. VI: TVESAInfoBlock;
  445. begin
  446. OK:=VESAGetInfo(VI);
  447. VESAInit:=OK;
  448. end;
  449. BEGIN
  450. END.
  451. {
  452. $Log$
  453. Revision 1.7 2000-03-21 23:22:37 pierre
  454. Gabor fixes to avoid unused vars
  455. Revision 1.6 2000/01/03 11:38:35 michael
  456. Changes from Gabor
  457. Revision 1.4 1999/04/07 21:55:58 peter
  458. + object support for browser
  459. * html help fixes
  460. * more desktop saving things
  461. * NODEBUG directive to exclude debugger
  462. Revision 1.3 1999/04/01 10:04:18 pierre
  463. * uses typo errror fixed
  464. Revision 1.2 1999/03/26 19:09:44 peter
  465. * fixed for go32v2
  466. Revision 1.1 1999/03/23 15:11:39 peter
  467. * desktop saving things
  468. * vesa mode
  469. * preferences dialog
  470. }