vesa.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  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. Sel: word;
  280. begin
  281. FillChar(B,SizeOf(B),0);
  282. OK:=VESAGetInfo(VI);
  283. if OK then
  284. begin
  285. {$ifdef TP}
  286. {$ifdef DPMI}
  287. Sel:=AllocSelector(0);
  288. OK:=Sel<>0;
  289. if OK then
  290. begin
  291. SetSelectorBase(Sel,(longint(VI.VideoModeList) shr 16)*16+longint(VI.VideoModeList) and $ffff);
  292. SetSelectorLimit(Sel,SizeOf(B.Modes));
  293. Move(ptr(Sel,0)^,B.Modes,SizeOf(B.Modes));
  294. FreeSelector(Sel);
  295. end;
  296. {$endif}
  297. {$endif}
  298. {$ifdef FPC}
  299. with VI do
  300. dosmemget(PtrRec(VideoModeList).Seg,PtrRec(VideoModeList).Ofs,B.Modes,SizeOf(B.Modes));
  301. {$endif}
  302. if OK then
  303. while (B.Modes[B.Count+1]<>$ffff) and (B.Count<255) do
  304. Inc(B.Count);
  305. end;
  306. VESAGetModeList:=OK;
  307. end;
  308. function VESASearchMode(XRes,YRes,BPX: word; LFB: boolean; var Mode: word; var ModeInfo: TVESAModeInfoBlock): boolean;
  309. var B: TVESAModeList;
  310. OK: boolean;
  311. I: integer;
  312. MI: TVESAModeInfoBlock;
  313. begin
  314. OK:=VESAGetModeList(B);
  315. I:=1; Mode:=0;
  316. repeat
  317. OK:=VESAGetModeInfo(B.Modes[I],MI);
  318. if OK and (MI.XResolution=XRes) and (MI.YResolution=YRes) and
  319. (MI.BitsPerPixel=BPX) and
  320. ((LFB=false) or ((MI.Attributes and vesa_vma_LinearFrameBufferAvail)<>0)) then
  321. begin Mode:=B.Modes[I]; ModeInfo:=MI; end;
  322. Inc(I);
  323. until (OK=false) or (I>=B.Count) or (Mode<>0);
  324. OK:=Mode<>0;
  325. VESASearchMode:=OK;
  326. end;
  327. function VESAGetOemString: string;
  328. var OK: boolean;
  329. VI: TVESAInfoBlock;
  330. Sel: word;
  331. S: array[0..256] of char;
  332. begin
  333. FillChar(S,SizeOf(S),0);
  334. OK:=VESAGetInfo(VI);
  335. {$IFDEF DPMI}
  336. if OK then
  337. begin
  338. {$ifdef TP}
  339. Sel:=AllocSelector(0);
  340. OK:=Sel<>0;
  341. if OK then
  342. begin
  343. SetSelectorBase(Sel,longint(PtrRec16(VI.OemString).Seg)*16+PtrRec16(VI.OemString).Ofs);
  344. SetSelectorLimit(Sel,SizeOf(S));
  345. Move(ptr(Sel,0)^,S,SizeOf(S));
  346. FreeSelector(Sel);
  347. end;
  348. {$endif}
  349. {$ifdef FPC}
  350. dosmemget(PtrRec16(VI.OemString).Seg,PtrRec16(VI.OemString).Ofs,S,SizeOf(S));
  351. {$endif}
  352. end;
  353. {$ELSE}
  354. Move(VI.OemString^,S,SizeOf(S));
  355. {$ENDIF}
  356. VESAGetOemString:=StrPas(@S);
  357. end;
  358. function VESAGetModeInfo(Mode: word; var B: TVESAModeInfoBlock): boolean;
  359. {$IFNDEF DPMI}
  360. var r : registers;
  361. {$ELSE}
  362. var r : tregisters;
  363. {$ENDIF}
  364. OK: boolean;
  365. {$ifdef DPMI}
  366. pB: MemPtr;
  367. {$endif}
  368. begin
  369. r.ah:=$4f; r.al:=$01; r.cx:=Mode;
  370. {$IFDEF DPMI}
  371. GetMem(pB, SizeOf(B));
  372. {$ifdef TP}
  373. Move(B,MakePtr(pB)^,SizeOf(B));
  374. {$endif}
  375. {$ifdef FPC}
  376. dosmemput(pB.Segment,0,B,SizeOf(B));
  377. {$endif}
  378. r.es:=pB.Segment; r.di:=0; {r.ds:=r.es;}
  379. realintr($10,r);
  380. {$ELSE}
  381. r.es:=seg(B); r.di:=ofs(B);
  382. intr($10,r);
  383. {$ENDIF}
  384. {$IFDEF DPMI}
  385. {$ifdef TP}
  386. Move(MakePtr(pB)^,B,SizeOf(B));
  387. {$endif}
  388. {$ifdef FPC}
  389. dosmemget(pB.Segment,0,B,SizeOf(B));
  390. {$endif}
  391. FreeMem(pB, SizeOf(B));
  392. {$ENDIF}
  393. OK:=(r.ax=$004f);
  394. VESAGetModeInfo:=OK;
  395. end;
  396. function VESASetMode(Mode: word): boolean;
  397. var r: registers;
  398. OK: boolean;
  399. begin
  400. r.ah:=$4f; r.al:=$02; r.bx:=Mode;
  401. dos.intr($10,r);
  402. OK:=(r.ax=$004f);
  403. VESASetMode:=OK;
  404. end;
  405. function VESAGetMode(var Mode: word): boolean;
  406. var r : registers;
  407. OK: boolean;
  408. begin
  409. r.ah:=$4f; r.al:=$03;
  410. dos.intr($10,r);
  411. OK:=(r.ax=$004f);
  412. if OK then Mode:=r.bx;
  413. VESAGetMode:=OK;
  414. end;
  415. function VESASelectMemoryWindow(Window: byte; Position: word): boolean;
  416. var r : registers;
  417. OK : boolean;
  418. begin
  419. r.ah:=$4f; r.al:=$05; r.bh:=0; r.bl:=Window; r.dx:=Position;
  420. dos.intr($10,r);
  421. OK:=(r.ax=$004f);
  422. VESASelectMemoryWindow:=OK;
  423. end;
  424. function VESAReturnMemoryWindow(Window: byte; var Position: word): boolean;
  425. var r : registers;
  426. OK : boolean;
  427. begin
  428. r.ah:=$4f; r.al:=$05; r.bh:=1; r.bl:=Window;
  429. dos.intr($10,r);
  430. OK:=(r.ax=$004f);
  431. if OK then Position:=r.dx;
  432. VESAReturnMemoryWindow:=OK;
  433. end;
  434. function VESAInit: boolean;
  435. var OK: boolean;
  436. VI: TVESAInfoBlock;
  437. begin
  438. OK:=VESAGetInfo(VI);
  439. VESAInit:=OK;
  440. end;
  441. BEGIN
  442. END.
  443. {
  444. $Log$
  445. Revision 1.6 2000-01-03 11:38:35 michael
  446. Changes from Gabor
  447. Revision 1.4 1999/04/07 21:55:58 peter
  448. + object support for browser
  449. * html help fixes
  450. * more desktop saving things
  451. * NODEBUG directive to exclude debugger
  452. Revision 1.3 1999/04/01 10:04:18 pierre
  453. * uses typo errror fixed
  454. Revision 1.2 1999/03/26 19:09:44 peter
  455. * fixed for go32v2
  456. Revision 1.1 1999/03/23 15:11:39 peter
  457. * desktop saving things
  458. * vesa mode
  459. * preferences dialog
  460. }