ibm.ppi 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 by the Free Pascal development team
  5. See the file COPYING.FPC, 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. function DetectVESA:Boolean;
  12. var Result_:longint;
  13. begin
  14. Result_:=Global_dos_alloc($0200);
  15. Sel:=word(Result_);
  16. Seg:=word(Result_ shr 16);
  17. dregs.RealSP:=0; dregs.RealSS:=0;
  18. dregs.RealES:=Seg; dregs.RealEDI:=0;
  19. dregs.RealEAX:=$4F00; RealIntr($10,dregs);
  20. if isDPMI
  21. then MoveLong(sel,@VGAInfo,256)
  22. else Move(pointer((seg shl 4)+core)^,VGAInfo,256);
  23. global_dos_free(sel);
  24. DetectVesa:=(dregs.RealEAX and $FF=$4F);
  25. isVESA2:=VGAInfo.VESAHiVersion=2;
  26. end;
  27. function GetVESAInfo( Mode : WORD ):Boolean;
  28. var Result_:longint;
  29. St : string;
  30. {$ifdef Test_linear}
  31. Temp : longint;
  32. {$endif Test_linear}
  33. begin
  34. Result_:=Global_dos_alloc($0200);
  35. Sel:=word(Result_);
  36. Seg:=word(Result_ shr 16);
  37. dregs.RealECX:=mode;
  38. dregs.RealSP:=0; dregs.RealSS:=0;
  39. dregs.RealES:=Seg; dregs.RealEDI:=0;
  40. dregs.RealEAX:=$4F01; RealIntr($10,dregs);
  41. if isDPMI
  42. then MoveLong(sel,@VESAInfo,256)
  43. else Move(Pointer((seg shl 4)+core)^,VESAINFO,256);
  44. global_dos_free(sel);
  45. { this is wrong because AH is set to one if mode not detected !!!
  46. if (dregs.RealEAX and $ff) =$4F then must be replaced by }
  47. if (dregs.RealEAX and $1ff) =$4F then
  48. begin
  49. GetVESAInfo:=true;
  50. { mode is supported only if bit 0 in modeAttributes is set }
  51. if (VESAInfo.ModeAttributes and 1)=0 then
  52. GetVESAInfo:=false;
  53. BytesPerLine:=VESAInfo.BPL;
  54. case VESAInfo.BitsPerPixel of
  55. 8 : begin
  56. BytesPerPixel:=1;
  57. ColorMask:=$ff;
  58. end;
  59. 15,16 : begin
  60. BytesPerPixel:=2;
  61. ColorMask:=$ffff;
  62. end;
  63. {$ifdef TEST_24BPP}
  64. 24 : begin
  65. BytesPerPixel:=3;
  66. ColorMask:=$ffffff;
  67. end;
  68. 32 : begin
  69. BytesPerPixel:=4;
  70. ColorMask:=$ffffff;
  71. end;
  72. {$endif TEST_24BPP}
  73. else begin
  74. str(VESAInfo.BitsPerPixel,St);
  75. GraphFault(St+'-Bit Mode not implemented !');
  76. exit;
  77. end;
  78. end;
  79. _maxx:=VESAInfo.XResolution;
  80. _maxy:=VESAInfo.YResolution;
  81. {$ifdef TEST_24BPP}
  82. { problem with pseudo 32 bit modes !! }
  83. if BytesPerPixel*VESAInfo.XResolution<>BytesPerLine then
  84. begin
  85. GraphFault('Unconsistant VESA data');
  86. { GetVesaInfo:=False; }
  87. BytesPerPixel:=BytesPerLine div VESAInfo.XResolution;
  88. end;
  89. {$endif TEST_24BPP}
  90. WinSize:=VESAInfo.Winsize*1024;
  91. WinLoMask:=WinSize-1;
  92. case VESAInfo.WinSize of
  93. 64 : WinShift:=16; { x div 65536 = x shr 16 }
  94. 32 : WinShift:=15; { x div 32768 = x shr 15 }
  95. 16 : WinShift:=14; { ... }
  96. 8 : WinShift:=13;
  97. 4 : WinShift:=12;
  98. 2 : WinShift:=11;
  99. 1 : WinShift:=10;
  100. end;
  101. Granularity:=VESAInfo.WinGranularity;
  102. Granular:=VESAInfo.WinSize div Granularity;
  103. case Granular of
  104. 256 : GranShift:=8;
  105. 128 : GranShift:=7;
  106. 64 : GranShift:=6;
  107. 32 : GranShift:=5;
  108. 16 : GranShift:=4;
  109. 8 : GranShift:=3;
  110. 4 : GranShift:=2;
  111. 2 : GranShift:=1;
  112. 1 : GranShift:=0;
  113. end;
  114. (* { on my ATI rage pro card these field are zeroed !! (PM) }
  115. if VesaInfo.rf_pos=VesaInfo.bf_pos then
  116. begin
  117. VesaInfo.rm_size:=VESAInfo.BitsPerPixel div 3;
  118. VesaInfo.bm_size:=VESAInfo.BitsPerPixel div 3;
  119. VesaInfo.gm_size:=VESAInfo.BitsPerPixel -2*VesaInfo.bm_size;
  120. VesaInfo.bf_pos:=0;
  121. VesaInfo.gf_pos:=VesaInfo.bm_size;
  122. VesaInfo.rf_pos:=VesaInfo.bm_size+VesaInfo.gm_size;
  123. end; *)
  124. if isDPMI then begin
  125. set_segment_base_address(seg_write,$A000 shl 4);
  126. set_segment_limit(seg_write,$FFFF);
  127. set_segment_base_address(seg_read,$A000 shl 4);
  128. set_segment_limit(seg_read,$FFFF);
  129. end;
  130. { read and write window can be different !!! PM }
  131. if ((VESAInfo.WinAAttributes and 5)=5) then
  132. AW_Window:=AWindow
  133. else if ((VESAInfo.WinBAttributes and 5)=5) then
  134. AW_Window:=BWindow
  135. else GraphFault('No write window !! ');
  136. if ((VESAInfo.WinAAttributes and 3)=3) then
  137. AR_Window:=AWindow
  138. else if ((VESAInfo.WinBAttributes and 3)=3) then
  139. AR_Window:=BWindow
  140. else GraphFault('No read window !! ');
  141. if AW_Window=AR_Window then
  142. same_window:=true
  143. else
  144. same_window:=false;
  145. if (VESAInfo.ModeAttributes and $80)=$80 then
  146. LinearFrameBufferSupported:=true
  147. else
  148. LinearFrameBufferSupported:=false;
  149. {$ifdef Test_linear}
  150. (* bug was due to alignment problem in VesaInfoBlock !! PM
  151. { try to swap the FrameBuffer Physical Address }
  152. if switch_physical_address then
  153. begin
  154. w:=VESAInfo.PhysAddress and $FFFF;
  155. VESAInfo.PhysAddress:=(w shl 16) or (VESAInfo.PhysAddress shr 16);
  156. end; *)
  157. If LinearFrameBufferSupported then
  158. begin
  159. FrameBufferLinearAddress:=Get_linear_addr(VESAInfo.PhysAddress and $FFFF0000,VGAInfo.TotalMem shl 16);
  160. if int31error<>0 then
  161. writeln(stderr,'Error in get linear address for ',hexstr(VESAInfo.PhysAddress,8));
  162. end
  163. else
  164. {$endif Test_linear}
  165. FrameBufferLinearAddress:=$A0000;
  166. {$ifdef Test_linear}
  167. If isDPMI and LinearFrameBufferSupported and UseLinear then
  168. UseLinearFrameBuffer:=true
  169. else
  170. UseLinearFrameBuffer:=false;
  171. if UseLinearFrameBuffer then
  172. begin
  173. set_segment_base_address(seg_write,FrameBufferLinearAddress);
  174. set_segment_limit(seg_write,(VGAInfo.TotalMem shl 16)-1);
  175. set_segment_base_address(seg_read,FrameBufferLinearAddress);
  176. set_segment_limit(seg_read,(VGAInfo.TotalMem shl 16)-1);
  177. WinSize:=(VGAInfo.TotalMem shl 16);
  178. WinLoMask:=(VGAInfo.TotalMem shl 16)-1;
  179. WinShift:=15;
  180. Temp:=VGAInfo.TotalMem;
  181. while Temp>0 do
  182. begin
  183. inc(WinShift);
  184. Temp:=Temp shr 1;
  185. end;
  186. end;
  187. {$endif Test_linear}
  188. SwitchCS:=hi(VESAInfo.RealWinFuncPtr);
  189. SwitchIP:=lo(VESAInfo.RealWinFuncPtr);
  190. { usefull for boundary problems }
  191. if BytesPerPixel=3 then
  192. WinLoMaskMinusPixelSize:=WinLoMask-4
  193. else
  194. WinLoMaskMinusPixelSize:=WinLoMask-BytesPerPixel;
  195. end else GetVESAInfo:=false;
  196. end;
  197. function SetVESAMode(Mode:WORD):Boolean;
  198. begin
  199. dregs.RealEBX:=Mode;
  200. dregs.RealSP:=0; dregs.RealSS:=0;
  201. dregs.RealEAX:=$4F02; RealIntr($10,dregs);
  202. { idem as above !!! }
  203. if (dregs.RealEAX and $1FF) <> $4F then begin
  204. writeln('Couldn''t initialize VESAMode ',HexStr(mode,4));
  205. SetVESAMode:=false;
  206. end
  207. else SetVESAMode:=true;
  208. end;
  209. procedure SetDisplayPage(PageNum : word);
  210. begin
  211. dregs.RealSP:=0; dregs.RealSS:=0;
  212. dregs.RealEAX:=$0500+(PageNum and $FF);
  213. RealIntr($10,dregs);
  214. end;
  215. function SetVESADisplayStart(PageNum : word;x,y : integer):Boolean;
  216. begin
  217. if PageNum>VesaInfo.NumberOfPages then
  218. PageNum:=0;
  219. {$ifdef DEBUG}
  220. if PageNum>0 then
  221. writeln(stderr,'Setting Display Page ',PageNum);
  222. {$endif DEBUG}
  223. dregs.RealEBX:=0{ $80 for Wait for retrace };
  224. dregs.RealECX:=x;
  225. dregs.RealEDX:=y+PageNum*_maxy;
  226. dregs.RealSP:=0; dregs.RealSS:=0;
  227. dregs.RealEAX:=$4F07; RealIntr($10,dregs);
  228. { idem as above !!! }
  229. if (dregs.RealEAX and $1FF) <> $4F then
  230. begin
  231. writeln(stderr,'Set Display start error');
  232. SetVESADisplayStart:=false;
  233. end
  234. else
  235. SetVESADisplayStart:=true;
  236. end;
  237. function GetVESAMode:Integer;
  238. begin
  239. dregs.RealSP:=0; dregs.RealSS:=0;
  240. dregs.RealEAX:=$4F03; RealIntr($10,dregs);
  241. GetVESAMode:=lo(dregs.RealEBX);
  242. end;
  243. procedure InitVESA;
  244. var RM:Word;
  245. begin
  246. isDPMI:=false;
  247. rm:=get_run_mode;
  248. {$ifdef Debug}
  249. case rm of
  250. 0 : writeln('unknown mode');
  251. 1 : writeln('RAW mode');
  252. 2 : writeln('XMS detected');
  253. 3 : writeln('VCPI detected');
  254. 4 : writeln('DPMI detected');
  255. end; { case }
  256. {$endif Debug}
  257. if rm=4 then
  258. isDPMI:=true;
  259. if isDPMI then begin
  260. seg_write:=allocate_ldt_descriptors(1);
  261. seg_read:=allocate_ldt_descriptors(1);
  262. end else begin
  263. seg_write:=get_DS;
  264. seg_read:=get_DS;
  265. end;
  266. end;
  267. procedure DoneVESA;
  268. begin
  269. if isDPMI then begin
  270. free_ldt_descriptor(seg_read);
  271. free_ldt_descriptor(seg_write);
  272. end;
  273. end;
  274. procedure Switchbank(bank:longint);
  275. begin
  276. with dregs do
  277. begin
  278. a_bank:=bank;
  279. realedx:=bank shl granshift;
  280. realcs:=switchcs;
  281. realip:=switchip;
  282. realebx:=aw_window;
  283. realss:=0;
  284. realsp:=0;
  285. end;
  286. asm
  287. leal _DREGS,%edi
  288. xorl %ecx,%ecx
  289. movl %ecx,%ebx
  290. movw $0x0301,%ax
  291. int $0x31
  292. end;
  293. if not same_window then
  294. with dregs do
  295. begin
  296. realedx:=bank shl granshift;
  297. realcs:=switchcs;
  298. realip:=switchip;
  299. realebx:=ar_window;
  300. realss:=0;
  301. realsp:=0;
  302. asm
  303. leal _DREGS,%edi
  304. xorl %ecx,%ecx
  305. movl %ecx,%ebx
  306. movw $0x0301,%ax
  307. int $0x31
  308. end;
  309. end;
  310. end;
  311. {
  312. $Log$
  313. Revision 1.3 1999-05-04 17:17:32 florian
  314. * some explicit language removed
  315. Revision 1.2 1998/12/21 14:06:03 pierre
  316. * var declaration was missing ??
  317. Revision 1.1 1998/12/21 13:07:03 peter
  318. * use -FE
  319. Revision 1.7 1998/11/25 13:04:46 pierre
  320. + added multi page support
  321. Revision 1.6 1998/11/20 18:42:08 pierre
  322. * many bugs related to floodfill and ellipse fixed
  323. Revision 1.5 1998/11/20 10:16:02 pierre
  324. * Found out the LinerFrameBuffer problem
  325. Was an alignment problem in VesaInfoBlock (see graph.pp file)
  326. Compile with -dDEBUG and answer 'y' to 'Use Linear ?' to test
  327. Revision 1.4 1998/11/18 12:12:54 pierre
  328. * WinShift was wrong for LinearBuffer
  329. Revision 1.3 1998/11/18 09:31:35 pierre
  330. * changed color scheme
  331. all colors are in RGB format if more than 256 colors
  332. + added 24 and 32 bits per pixel mode
  333. (compile with -dDEBUG)
  334. 24 bit mode with banked still as problems on pixels across
  335. the bank boundary, but works in LinearFrameBufferMode
  336. Look at install/demo/nmandel.pp
  337. Revision 1.2 1998/10/09 10:26:36 peter
  338. * rename result -> result_
  339. Revision 1.1.1.1 1998/03/25 11:18:42 root
  340. * Restored version
  341. Revision 1.6 1998/01/26 11:58:09 michael
  342. + Added log at the end
  343. Working file: rtl/dos/ppi/ibm.ppi
  344. description:
  345. ----------------------------
  346. revision 1.5
  347. date: 1997/12/11 11:26:54; author: pierre; state: Exp; lines: +165 -165
  348. * forgot dtou !!
  349. ----------------------------
  350. revision 1.4
  351. date: 1997/12/11 11:24:19; author: pierre; state: Exp; lines: +165 -165
  352. * bug in string at line 103 corrected
  353. ----------------------------
  354. revision 1.3
  355. date: 1997/12/04 08:52:35; author: florian; state: Exp; lines: +4 -4
  356. + vesa mode 1280x1024x256 added
  357. ----------------------------
  358. revision 1.2
  359. date: 1997/12/01 12:21:30; author: michael; state: Exp; lines: +13 -1
  360. + added copyright reference in header.
  361. ----------------------------
  362. revision 1.1
  363. date: 1997/11/27 08:33:51; author: michael; state: Exp;
  364. Initial revision
  365. ----------------------------
  366. revision 1.1.1.1
  367. date: 1997/11/27 08:33:51; author: michael; state: Exp; lines: +0 -0
  368. FPC RTL CVS start
  369. =============================================================================
  370. }