ibm.ppi 12 KB

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