Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2563 lines
104 KiB

  1. /************************************************************************/
  2. /* */
  3. /* QUERY_CX.C */
  4. /* */
  5. /* Copyright (c) 1993, ATI Technologies Incorporated. */
  6. /************************************************************************/
  7. /********************** PolyTron RCS Utilities
  8. $Revision: 1.61 $
  9. $Date: 01 May 1996 14:10:14 $
  10. $Author: RWolff $
  11. $Log: S:/source/wnt/ms11/miniport/archive/query_cx.c_v $
  12. *
  13. * Rev 1.61 01 May 1996 14:10:14 RWolff
  14. * Calls new routine DenseOnAlpha() to determine dense space support rather
  15. * than assuming all PCI cards support dense space, routine treats only
  16. * PCI cards with ?T ASICs as supporting dense space.
  17. *
  18. * Rev 1.60 23 Apr 1996 17:21:18 RWolff
  19. * Split mapping of memory types reported by BIOS into our enumeration
  20. * of memory types according to ASIC type, since ?T and ?X use the same
  21. * memory type code to refer to different memory types.
  22. *
  23. * Rev 1.59 15 Apr 1996 16:57:56 RWolff
  24. * Added routine to identify which flavour of the Mach 64 is in use.
  25. *
  26. * Rev 1.58 12 Apr 1996 16:14:48 RWolff
  27. * Now rejects 24BPP modes if linear aperture is not present, since new
  28. * source stream display driver can't do 24BPP in a paged aperture. This
  29. * rejection should be done in the display driver (the card still supports
  30. * the mode, but the display driver doesn't want to handle it), but at
  31. * the point where the display driver must decide to either accept or reject
  32. * modes, it doesn't have access to the aperture information.
  33. *
  34. * Rev 1.57 20 Mar 1996 13:45:02 RWolff
  35. * Fixed truncation of screen buffer save size.
  36. *
  37. * Rev 1.56 01 Mar 1996 12:14:20 RWolff
  38. * Can now use the existing VGA graphics screen used as the startup
  39. * "blue screen" on the DEC Alpha to store the results of the BIOS
  40. * query call rather than forcing a mode switch and destroying the
  41. * contents of the "blue screen".
  42. *
  43. * Rev 1.55 06 Feb 1996 16:01:00 RWolff
  44. * Updated start and end indices for 1600x1200 to take into account addition
  45. * of 66Hz and 76Hz, and deletion of 52Hz.
  46. *
  47. * Rev 1.54 02 Feb 1996 17:17:38 RWolff
  48. * DDC/VDIF merge source information is now stored in hardware device
  49. * extension rather than static variables, switches back to a VGA text
  50. * screen after we have finished with the query information if we needed
  51. * to switch into a graphics screen in order to obtain a buffer below
  52. * 1M physical (more information needed from DEC in order to make this
  53. * work on the Alpha), moved redundant cleanup code to its own routine.
  54. *
  55. * Rev 1.53 29 Jan 1996 17:00:48 RWolff
  56. * Now uses VideoPortInt10() rather than no-BIOS code on PPC, restricted
  57. * 4BPP to 1M cards, and only for resolutions where 8BPP won't fit.
  58. *
  59. * Rev 1.52 23 Jan 1996 11:47:26 RWolff
  60. * Protected against false values of TARGET_BUILD.
  61. *
  62. * Rev 1.51 11 Jan 1996 19:42:16 RWolff
  63. * Now restricts refresh rates for each resolution/pixel depth combination
  64. * using data from AX=A?07 BIOS call rather than special cases.
  65. *
  66. * Rev 1.50 22 Dec 1995 14:54:02 RWolff
  67. * Added support for Mach 64 GT internal DAC.
  68. *
  69. * Rev 1.49 21 Dec 1995 14:04:02 RWolff
  70. * Locked out modes that ran into trouble at high refresh rates.
  71. *
  72. * Rev 1.48 19 Dec 1995 13:57:02 RWolff
  73. * Added support for refresh rates up to 100Hz at 640x480, 800x600, and
  74. * 1024x768, and 76Hz at 1280x1024.
  75. *
  76. * Rev 1.47 29 Nov 1995 14:36:16 RWolff
  77. * Fix for EPR#08840. The mode that was causing problems (1152x864 32BPP
  78. * 80Hz on IBM DAC) was one that (according to the INSTALL program)
  79. * shouldn't be available on the card.
  80. *
  81. * Rev 1.46 28 Nov 1995 18:14:58 RWolff
  82. * Added debug print statements.
  83. *
  84. * Rev 1.45 21 Nov 1995 11:02:02 RWolff
  85. * Restricted maximum size of BIOS query structure to allow space below
  86. * 1M for reading DDC data.
  87. *
  88. * Rev 1.44 27 Oct 1995 14:23:54 RWolff
  89. * No longer checks for block write on non-LFB configurations, moved
  90. * mapping and unmapping of LFB into the block write check routine
  91. * rather than using the (no longer exists) mapped LFB in the hardware
  92. * device extension.
  93. *
  94. * Rev 1.43 08 Sep 1995 16:35:32 RWolff
  95. * Added support for AT&T 408 DAC (STG1703 equivalent).
  96. *
  97. * Rev 1.42 24 Aug 1995 15:37:20 RWolff
  98. * Changed detection of block I/O cards to match Microsoft's
  99. * standard for plug-and-play.
  100. *
  101. * Rev 1.41 28 Jul 1995 14:40:36 RWolff
  102. * Added support for the Mach 64 VT (CT equivalent with video overlay).
  103. *
  104. * Rev 1.40 26 Jul 1995 12:44:54 mgrubac
  105. * Locked out modes that didn't work on 4M CX cards with STG1703
  106. * and similar DACs.
  107. *
  108. * Rev 1.39 20 Jul 1995 17:57:54 mgrubac
  109. * Added support for VDIF files.
  110. *
  111. * Rev 1.38 13 Jun 1995 15:13:14 RWOLFF
  112. * Now uses VideoPortReadRegisterUlong() instead of direct memory
  113. * reads in BlockWriteAvailable_cx(), since direct reads don't
  114. * work on the DEC Alpha. Breaks out of block write test on
  115. * finding first mismatch, rather than testing the whole block,
  116. * to save time. One mismatch is enough to indicate that block
  117. * write mode is not supported, so after we find one we don't
  118. * need to check the rest of the block.
  119. *
  120. * Rev 1.37 02 Jun 1995 14:31:44 RWOLFF
  121. * Added debug print statements, locked out modes that don't work properly
  122. * on some DACs.
  123. *
  124. * Rev 1.36 10 Apr 1995 15:58:20 RWOLFF
  125. * Now replaces BookValues[] entries where the Mach 64 needs different CRT
  126. * parameters from the Mach 8/Mach 32 (fixes Chrontel DAC 1M 640x480 72Hz
  127. * 24BPP noise problem), locked out 800x600 16BPP 72Hz on 1M cards with
  128. * STG170x and equivalent DACs (another noise problem, this mode is not
  129. * supposed to be supported on 1M cards).
  130. *
  131. * Rev 1.35 31 Mar 1995 11:56:16 RWOLFF
  132. * Changed from all-or-nothing debug print statements to thresholds
  133. * depending on importance of the message.
  134. *
  135. * Rev 1.34 27 Mar 1995 16:12:14 RWOLFF
  136. * Locked out modes that didn't work on 1M cards with STG1702 and
  137. * similar DACs.
  138. *
  139. * Rev 1.33 16 Mar 1995 14:41:08 ASHANMUG
  140. * Limit 1024x768 24 bpp on a STG17xx DAC to 87Hz interlaced
  141. *
  142. * Rev 1.32 03 Mar 1995 10:51:22 ASHANMUG
  143. * Lock-out high refresh rates on CT and '75 DACs
  144. *
  145. * Rev 1.31 24 Feb 1995 12:29:54 RWOLFF
  146. * Added routine to check if the card is susceptible to 24BPP text banding
  147. *
  148. * Rev 1.30 20 Feb 1995 18:02:28 RWOLFF
  149. * Locked out block write on GX rev. E with IBM RAM.
  150. *
  151. * Rev 1.29 14 Feb 1995 15:54:22 RWOLFF
  152. * Now checks CFG_CHIP_TYPE field of CONFIG_CHIP_ID against values found
  153. * in this field for all Mach 64 ASICs, and reports "no Mach 64" if
  154. * no match is found. This fixes a problem on an Apricot FT\\2E with
  155. * a Mach 32 MCA card, where the Mach 32 supplied the BIOS signature
  156. * string, and the machine cached our writes to SCRATCH_PAD0 so it
  157. * looked like the register was present, falsely identifying a Mach 64
  158. * as being present.
  159. *
  160. * Rev 1.28 09 Feb 1995 14:58:14 RWOLFF
  161. * Fix for GX-E IBM DAC screen tearing in 800x600 8BPP.
  162. *
  163. * Rev 1.27 07 Feb 1995 18:21:14 RWOLFF
  164. * Locked out some more resolution/pixel depth/refresh rate combinations
  165. * that are not supported.
  166. *
  167. * Rev 1.26 30 Jan 1995 17:44:20 RWOLFF
  168. * Mach 64 detection now does a low word test before the doubleword test
  169. * to avoid hanging a VLB Mach 32 by writing garbage to the MEM_BNDRY register.
  170. *
  171. * Rev 1.25 30 Jan 1995 11:56:12 RWOLFF
  172. * Now detects CT internal DAC.
  173. *
  174. * Rev 1.24 19 Jan 1995 15:38:18 RWOLFF
  175. * Removed 24BPP no-BIOS lockout and comment explaining why it was
  176. * locked out. 24BPP now works on no-BIOS implementations.
  177. *
  178. * Rev 1.23 18 Jan 1995 15:41:08 RWOLFF
  179. * Added support for Chrontel DAC, now clips maximum colour depth from BIOS
  180. * mode tables to the maximum identified in the query header, locks out
  181. * high refresh rate 1152x864 16BPP modes (8BPP can still be handled through
  182. * double-pixel mode), re-enabled 24BPP on no-BIOS implementations (work
  183. * in progress).
  184. *
  185. * Rev 1.22 11 Jan 1995 14:00:28 RWOLFF
  186. * 1280x1024 no longer restricted to 60Hz maximum on DRAM cards. This
  187. * restriction was a carryover from the Mach 32, since at the time I wrote
  188. * this code, I did not have any information to show that the Mach 64 didn't
  189. * need it.
  190. *
  191. * Rev 1.21 04 Jan 1995 13:20:10 RWOLFF
  192. * Now uses VGA graphics memory if neither text screen is backed by
  193. * physical memory (needed on some DEC Alpha machines), temporarily
  194. * locked out 24BPP on no-BIOS implementations.
  195. *
  196. * Rev 1.20 23 Dec 1994 10:48:10 ASHANMUG
  197. * ALPHA/Chrontel-DAC
  198. *
  199. * Rev 1.19 18 Nov 1994 11:41:54 RWOLFF
  200. * Added support for Mach 64 without BIOS, separated handling of STG1703 from
  201. * other STG170x DACs, no longer creates mode tables for resolutions that the
  202. * DAC doesn't support, added handling for split rasters, rejects 4BPP on
  203. * TVP3026 DAC, recognizes that the Power PC doesn't support block write mode.
  204. *
  205. * Rev 1.18 14 Sep 1994 15:21:30 RWOLFF
  206. * Now stores most desirable supported colour ordering for 24 and 32 BPP
  207. * in the query structure.
  208. *
  209. * Rev 1.17 06 Sep 1994 10:47:32 ASHANMUG
  210. * Force 4bpp on mach64 to have one meg ram
  211. *
  212. * Rev 1.16 31 Aug 1994 16:26:10 RWOLFF
  213. * Now uses VideoPort[Read|Write]Register[Uchar|Ushort|Ulong]() instead
  214. * of direct assignments when accessing structures stored in VGA text
  215. * screen off-screen memory, added support for TVP3026 DAC and new
  216. * list of DAC subtypes, updates maximum supported pixel depth to
  217. * correspond to the card being used rather than taking the normal
  218. * maximum values for the DAC type, added 1152x864 and 1600x1200 support.
  219. *
  220. * Rev 1.15 19 Aug 1994 17:11:56 RWOLFF
  221. * Added support for SC15026 and AT&T 49[123] DACs, fixed reporting
  222. * of "canned" mode tables for resolutions that do not have a
  223. * hardware default refresh rate, added support for 1280x1024 70Hz and 74Hz.
  224. *
  225. * Rev 1.14 30 Jun 1994 18:14:28 RWOLFF
  226. * Moved IsApertureConflict_cx() to SETUP_CX.C because the new method
  227. * of checking for conflict requires access to definitions and data
  228. * structures which are only available in this module.
  229. *
  230. * Rev 1.13 15 Jun 1994 11:08:02 RWOLFF
  231. * Now lists block write as unavailable on DRAM cards.
  232. *
  233. * Rev 1.12 17 May 1994 15:59:48 RWOLFF
  234. * No longer sets a higher pixel clock for "canned" mode tables on some
  235. * DACs. The BIOS will increase the pixel clock frequency for DACs that
  236. * require it.
  237. *
  238. * Rev 1.11 12 May 1994 11:15:26 RWOLFF
  239. * No longer does 1600x1200, now lists predefined refresh rates as available
  240. * instead of only the refresh rate stored in EEPROM.
  241. *
  242. * Rev 1.10 05 May 1994 13:41:00 RWOLFF
  243. * Now reports block write unavailable on Rev. C and earlier ASICs.
  244. *
  245. * Rev 1.9 27 Apr 1994 14:02:26 RWOLFF
  246. * Fixed detection of "LFB disabled" case, no longer creates 4BPP mode tables
  247. * for 68860 DAC (this DAC doesn't do 4BPP), fixed query of DAC type (DAC
  248. * list in BIOS guide is wrong).
  249. *
  250. * Rev 1.8 26 Apr 1994 12:49:16 RWOLFF
  251. * Fixed handling of 640x480 and 800x600 if LFB configured but not available.
  252. *
  253. * Rev 1.7 31 Mar 1994 15:03:40 RWOLFF
  254. * Added 4BPP support, debugging code to see why some systems were failing.
  255. *
  256. * Rev 1.6 15 Mar 1994 16:27:00 RWOLFF
  257. * Rounds 8M aperture down to 8M boundary, not 16M boundary.
  258. *
  259. * Rev 1.5 14 Mar 1994 16:34:40 RWOLFF
  260. * Fixed handling of 8M linear aperture installed so it doesn't start on
  261. * an 8M boundary (retail version of install program shouldn't allow this
  262. * condition to exist), fix for tearing on 2M boundary.
  263. *
  264. * Rev 1.4 09 Feb 1994 15:32:22 RWOLFF
  265. * Corrected name of variable for best colour depth found, closed
  266. * comment that had been left open in previous revision.
  267. *
  268. * Rev 1.3 08 Feb 1994 19:02:34 RWOLFF
  269. * No longer makes 1024x768 87Hz interlaced available if Mach 64 card is
  270. * configured with 1024x768 set to "Not installed".
  271. *
  272. * Rev 1.2 07 Feb 1994 14:12:00 RWOLFF
  273. * Added alloc_text() pragmas to allow miniport to be swapped out when
  274. * not needed, removed GetMemoryNeeded_cx() which was only called by
  275. * LookForSubstitute(), a routine removed from ATIMP.C.
  276. *
  277. * Rev 1.1 03 Feb 1994 16:43:20 RWOLFF
  278. * Fixed "ceiling check" on right scissor registers (documentation
  279. * had maximum value wrong).
  280. *
  281. * Rev 1.0 31 Jan 1994 11:12:08 RWOLFF
  282. * Initial revision.
  283. *
  284. * Rev 1.2 14 Jan 1994 15:23:34 RWOLFF
  285. * Gives unambiguous value for ASIC revision, uses deepest mode table for
  286. * a given resolution rather than the first one it finds, added routine
  287. * to check if block write mode is available, support for 1600x1200.
  288. *
  289. * Rev 1.1 30 Nov 1993 18:26:30 RWOLFF
  290. * Fixed hang bug in DetectMach64(), moved query buffer off visible screen,
  291. * changed QueryMach64() to correspond to latest BIOS specifications,
  292. * added routines to check for aperture conflict and to find the
  293. * amount of video memory needed by a given mode.
  294. *
  295. * Rev 1.0 05 Nov 1993 13:36:28 RWOLFF
  296. * Initial revision.
  297. End of PolyTron RCS section *****************/
  298. #ifdef DOC
  299. QUERY_CX.C - Functions to detect the presence of and find out the
  300. configuration of 68800CX-compatible ATI accelerators.
  301. #endif
  302. #include "dderror.h"
  303. #include <stdio.h>
  304. #include <stdlib.h>
  305. #include <string.h>
  306. #include "miniport.h"
  307. #include "ntddvdeo.h"
  308. #include "video.h"
  309. #include "stdtyp.h"
  310. #include "amachcx.h"
  311. #include "amach1.h"
  312. #include "atimp.h"
  313. #include "atint.h"
  314. #include "cvtvga.h"
  315. #define INCLUDE_QUERY_CX
  316. #define STRUCTS_QUERY_CX
  317. #include "query_cx.h"
  318. #include "services.h"
  319. #include "setup_cx.h"
  320. #include "cvtddc.h"
  321. /*
  322. * Prototypes for static functions.
  323. */
  324. static void CleanupQuery(PUCHAR CapBuffer, PUCHAR SupBuffer, PUCHAR MappedBuffer, long BufferSeg, PUCHAR SavedScreen);
  325. /*
  326. * Allow miniport to be swapped out when not needed.
  327. */
  328. #if defined (ALLOC_PRAGMA)
  329. #pragma alloc_text(PAGE_CX, DetectMach64)
  330. #pragma alloc_text(PAGE_CX, QueryMach64)
  331. #pragma alloc_text(PAGE_CX, BlockWriteAvail_cx)
  332. #pragma alloc_text(PAGE_CX, TextBanding_cx)
  333. #pragma alloc_text(PAGE_CX, CleanupQuery)
  334. #endif
  335. /***************************************************************************
  336. *
  337. * int DetectMach64(void);
  338. *
  339. * DESCRIPTION:
  340. * Detect whether or not a Mach 64 accelerator is present.
  341. *
  342. * RETURN VALUE:
  343. * MACH64_ULTRA if Mach 64 accelerator found
  344. * NO_ATI_ACCEL if no Mach 64 accelerator found
  345. *
  346. * GLOBALS CHANGED:
  347. * none
  348. *
  349. * CALLED BY:
  350. * ATIMPFindAdapter()
  351. *
  352. * AUTHOR:
  353. * Robert Wolff
  354. *
  355. * CHANGE HISTORY:
  356. *
  357. * TEST HISTORY:
  358. *
  359. ***************************************************************************/
  360. int DetectMach64(void)
  361. {
  362. int CardType = MACH64_ULTRA; /* Initially assume Mach 64 is present */
  363. DWORD ScratchReg0; /* Saved contents of SCRATCH_REG0 */
  364. WORD CfgChipType; /* CFG_CHIP_TYPE field of CONFIG_CHIP_ID */
  365. /*
  366. * Some other brands of video card will pass the write/read back
  367. * test for the Mach 64. To avoid falsely identifying them as
  368. * Mach 64 cards, check for the ATI signature string in the BIOS.
  369. *
  370. * Failure cases use DEBUG_DETAIL rather than DEBUG_ERROR because
  371. * failed detection of the Mach 64 is a normal case for Mach 8 and
  372. * Mach 32 cards, and for non-ATI cards in "run all the miniports
  373. * and see which ones find their cards" video determination.
  374. */
  375. if (Get_BIOS_Seg() == FALSE)
  376. {
  377. VideoDebugPrint((DEBUG_DETAIL, "DetectMach64() no ATI BIOS signature found\n"));
  378. }
  379. /*
  380. * On a machine with a Mach 32 to provide an ATI video BIOS
  381. * segment, a card with a 32 bit read/write register matching
  382. * SCRATCH_REG0 would be falsely detected as a Mach 64. To
  383. * avoid this, check the CFG_CHIP_TYPE field of CONFIG_CHIP_ID
  384. * against values found in this field for known Mach 64 ASICs
  385. * as an additional test. Since this test is non-destructive,
  386. * do it first.
  387. */
  388. CfgChipType = INPW(CONFIG_CHIP_ID);
  389. if ((CfgChipType != CONFIG_CHIP_ID_TypeGX) && /* GX */
  390. (CfgChipType != CONFIG_CHIP_ID_TypeCX) && /* CX */
  391. (CfgChipType != 0x4354) && /* CT */
  392. (CfgChipType != 0x4554) && /* ET */
  393. (CfgChipType != 0x4754) && /* GT */
  394. (CfgChipType != 0x4C54) && /* LT */
  395. (CfgChipType != 0x4D54) && /* MT */
  396. (CfgChipType != 0x5254) && /* RT */
  397. (CfgChipType != 0x5654) && /* VT */
  398. (CfgChipType != 0x3354)) /* 3T */
  399. {
  400. VideoDebugPrint((DEBUG_DETAIL, "DetectMach64() - CFG_CHIP_TYPE = 0x%X doesn't match known Mach 64 ASIC\n", CfgChipType));
  401. return NO_ATI_ACCEL;
  402. }
  403. /*
  404. * Save the contents of SCRATCH_REG0, since they are destroyed in
  405. * the test for Mach 64 accelerators.
  406. */
  407. ScratchReg0 = INPD(SCRATCH_REG0);
  408. /*
  409. * On a Mach 64 card, any 32 bit pattern written to SCRATCH_REG0
  410. * will be read back as the same value. Since unimplemented registers
  411. * normally drift to either all set or all clear, test this register
  412. * with two patterns (second is the complement of the first) containing
  413. * alternating set and clear bits. If either of them is not read back
  414. * unchanged, then assume that no Mach 64 card is present.
  415. *
  416. * After writing, we must wait long enough for the contents of
  417. * SCRATCH_REG0 to settle down. We can't use a WaitForIdle_cx() call
  418. * because this function uses a register which only exists in
  419. * memory-mapped form, and we don't initialize the memory-mapped
  420. * registers until we know that we are dealing with a Mach 64 card.
  421. * Instead, assume that it will settle down in 1 millisecond.
  422. *
  423. * Test the low word of SCRATCH_REG0 before testing the whole
  424. * doubleword. This is because the high word of this register
  425. * corresponds to the MEM_BNDRY register on the Mach 32 (low
  426. * word not used). If we do a doubleword write on a Mach 32
  427. * card (Mach 64 detection is before Mach 32 detection), we
  428. * will plug garbage data into MEM_BNDRY, which will hang the machine.
  429. */
  430. OUTPW(SCRATCH_REG0,0x05555);
  431. delay(1);
  432. if (INPW(SCRATCH_REG0) != 0x05555)
  433. CardType = NO_ATI_ACCEL;
  434. OUTPW(SCRATCH_REG0, 0x0AAAA);
  435. delay(1);
  436. if (INPW(SCRATCH_REG0) != 0x0AAAA)
  437. CardType = NO_ATI_ACCEL;
  438. /*
  439. * Failure - restore the register and return.
  440. */
  441. if (CardType == NO_ATI_ACCEL)
  442. {
  443. OUTPW(SCRATCH_REG0, (WORD)(ScratchReg0 & 0x0000FFFF));
  444. VideoDebugPrint((DEBUG_DETAIL, "DetectMach64() - SCRATCH_REG0 word readback doesn't match value written\n"));
  445. return CardType;
  446. }
  447. /*
  448. * Success - test the register as a doubleword.
  449. */
  450. OUTPD(SCRATCH_REG0, 0x055555555);
  451. delay(1);
  452. if (INPD(SCRATCH_REG0) != 0x055555555)
  453. CardType = NO_ATI_ACCEL;
  454. OUTPD(SCRATCH_REG0, 0x0AAAAAAAA);
  455. delay(1);
  456. if (INPD(SCRATCH_REG0) != 0x0AAAAAAAA)
  457. CardType = NO_ATI_ACCEL;
  458. /*
  459. * Restore the contents of SCRATCH_REG0 and let the caller know
  460. * whether or not we found a Mach 64.
  461. */
  462. OUTPD(SCRATCH_REG0, ScratchReg0);
  463. return CardType;
  464. } /* DetectMach64() */
  465. /***************************************************************************
  466. *
  467. * VP_STATUS QueryMach64(Query);
  468. *
  469. * struct query_structure *Query; Query structure to fill in
  470. *
  471. * DESCRIPTION:
  472. * Fill in the query structure and mode tables for the
  473. * Mach 64 accelerator.
  474. *
  475. * RETURN VALUE:
  476. * NO_ERROR if successful
  477. * ERROR_INSUFFICIENT_BUFFER if not enough space to collect data
  478. * any error code returned by operating system calls.
  479. *
  480. * GLOBALS CHANGED:
  481. * none
  482. *
  483. * CALLED BY:
  484. * ATIMPFindAdapter()
  485. *
  486. * AUTHOR:
  487. * Robert Wolff
  488. *
  489. * CHANGE HISTORY:
  490. *
  491. * TEST HISTORY:
  492. *
  493. ***************************************************************************/
  494. VP_STATUS QueryMach64(struct query_structure *Query)
  495. {
  496. VIDEO_X86_BIOS_ARGUMENTS Registers; /* Used in VideoPortInt10() calls */
  497. VP_STATUS RetVal; /* Status returned by VideoPortInt10() */
  498. short MaxModes; /* Maximum number of modes possible in query structure */
  499. short AbsMaxDepth; /* Maximum pixel depth supported by the DAC */
  500. struct cx_query *CxQuery; /* Query header from BIOS call */
  501. struct cx_mode_table *CxModeTable; /* Mode tables from BIOS call */
  502. struct st_mode_table ThisRes; /* All-depth mode table for current resolution */
  503. short CurrentRes; /* Current resolution we are working on */
  504. long BufferSeg; /* Segment of buffer used for BIOS query */
  505. long BufferSize; /* Size of buffer needed for BIOS query */
  506. PUCHAR MappedBuffer; /* Pointer to buffer used for BIOS query */
  507. short Count; /* Loop counter */
  508. DWORD Scratch; /* Temporary variable */
  509. long MemAvail; /* Memory available, in bytes */
  510. long NumPixels; /* Number of pixels for the current mode */
  511. struct st_mode_table *pmode; /* Mode table to be filled in */
  512. short StartIndex; /* First mode for SetFixedModes() to set up */
  513. short EndIndex; /* Last mode for SetFixedModes() to set up */
  514. BOOL ModeInstalled; /* Is this resolution configured? */
  515. short FreeTables; /* Number of remaining free mode tables */
  516. short FormatType; /* Which table format is in use */
  517. UCHAR DacTypeMask; /* Bitmask for DAC type on the card */
  518. UCHAR OrigDacType; /* DAC type before processing into AMACH1.H ordering */
  519. UCHAR OrigRamType; /* RAM type before processing into AMACH1.H ordering */
  520. UCHAR OrigRamSize; /* Amount of RAM before processing into number of 256k banks */
  521. PUCHAR HwCapBuffer; /* Pointer to buffer of hardware capabilities */
  522. PUCHAR HwSupBuffer; /* Pointer to supplemental buffer */
  523. PUCHAR HwCapWalker; /* Pointer to walk through above buffer */
  524. struct cx_hw_cap *HwCapEntry; /* Pointer to single entry in table of hardware capabilities */
  525. UCHAR HwCapBytesPerRow; /* Number of bytes in each hardware capability entry */
  526. UCHAR MaxDotClock[HOW_MANY_DEPTHS]; /* Maximum dot clock at each pixel depth for the current resolution */
  527. UCHAR CurrentDepth; /* Pixel depth for current hardware capability entry */
  528. /*
  529. * Place to save the contents of the VGA screen before making a BIOS
  530. * query using the VGA memory as a buffer. Needed only when using
  531. * the existing graphics screen as a buffer, since we use an offscreen
  532. * portion of the text screen, and if we have to switch into a VGA
  533. * graphics mode there will be nothing to save.
  534. */
  535. UCHAR SavedVgaBuffer[VGA_TOTAL_SIZE];
  536. /*
  537. * If we do not yet know the BIOS prefix for this card (i.e.
  538. * it is a block relocatable card where we must match the
  539. * BIOS prefix to the I/O base in case we have multiple
  540. * cards.
  541. */
  542. if (phwDeviceExtension->BiosPrefix == BIOS_PREFIX_UNASSIGNED)
  543. {
  544. /*
  545. * We don't support block relocatable cards in the
  546. * no-BIOS configuration.
  547. */
  548. phwDeviceExtension->BiosPrefix = BIOS_PREFIX_VGA_ENAB;
  549. /*
  550. * We shouldn't need to check for equality, but this allows
  551. * us to catch the "too many cards - this one doesn't have
  552. * a BIOS prefix" case by checking for an out-of-range
  553. * prefix after the loop exits.
  554. */
  555. while (phwDeviceExtension->BiosPrefix <= BIOS_PREFIX_MAX_DISAB)
  556. {
  557. VideoDebugPrint((DEBUG_DETAIL, "Testing BIOS prefix 0x%X\n", phwDeviceExtension->BiosPrefix));
  558. VideoPortZeroMemory(&Registers, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  559. Registers.Eax = BIOS_QUERY_IOBASE;
  560. if ((RetVal = VideoPortInt10(phwDeviceExtension, &Registers)) != NO_ERROR)
  561. {
  562. VideoDebugPrint((DEBUG_ERROR, "QueryMach64() - failed BIOS_QUERY_IOBASE\n"));
  563. return RetVal;
  564. }
  565. /*
  566. * If the card with the current BIOS prefix uses our I/O base
  567. * address, we have found the correct prefix. Otherwise,
  568. * try the next prefix.
  569. */
  570. if (Registers.Edx == phwDeviceExtension->BaseIOAddress)
  571. {
  572. VideoDebugPrint((DEBUG_DETAIL, "Card with I/O base address 0x%X uses BIOS prefix 0x%X\n", Registers.Edx, phwDeviceExtension->BiosPrefix));
  573. break;
  574. }
  575. else
  576. {
  577. VideoDebugPrint((DEBUG_DETAIL, "Reported I/O base of 0x%X - no match\n", Registers.Edx));
  578. }
  579. phwDeviceExtension->BiosPrefix += BIOS_PREFIX_INCREMENT;
  580. } /* end while (searching for the correct prefix) */
  581. /*
  582. * The equality test on the loop will result in an illegal
  583. * prefix on exit if there are too many cards for us to
  584. * handle, and this is one of the "orphans".
  585. */
  586. if (phwDeviceExtension->BiosPrefix > BIOS_PREFIX_MAX_DISAB)
  587. {
  588. VideoDebugPrint((DEBUG_ERROR, "QueryMach64() - can't find BIOS prefix for card with I/O base 0x%X\n", phwDeviceExtension->BaseIOAddress));
  589. return ERROR_DEV_NOT_EXIST;
  590. }
  591. } /* endif (unassigned BIOS prefix) */
  592. /*
  593. * Find out how large a buffer we need when making a BIOS query call.
  594. */
  595. VideoPortZeroMemory(&Registers, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  596. Registers.Eax = BIOS_GET_QUERY_SIZE;
  597. Registers.Ecx = BIOS_QUERY_FULL;
  598. if ((RetVal = VideoPortInt10(phwDeviceExtension, &Registers)) != NO_ERROR)
  599. {
  600. VideoDebugPrint((DEBUG_ERROR, "QueryMach64() - failed BIOS_GET_QUERY_SIZE\n"));
  601. return RetVal;
  602. }
  603. BufferSize = Registers.Ecx & 0x0000FFFF;
  604. /*
  605. * Allocate a buffer to store the query information. Due to the BIOS
  606. * being real mode, this buffer must be below 1M. When this function
  607. * is called, we are on the "blue screen", so there is a 32k window
  608. * below 1M that we can use without risk of corrupting executable code.
  609. *
  610. * To avoid the need to save and restore our buffer, use only the
  611. * offscreen portion of this window (video memory contents will be
  612. * initialized before they are used, so the leftover query structure
  613. * won't harm anything). Assume a 50 line text screen.
  614. *
  615. * Check to see if the query structure is small enough to fit into
  616. * this region, and fail if it's too big. If it fits, try to allocate
  617. * the memory in the colour text window and see if there's enough
  618. * physical memory to meet our needs. If this fails, try again for
  619. * the monochrome text window (since VGA can run as either colour
  620. * or monochrome).
  621. *
  622. * If both fail (will happen on some DEC ALPHA machines), try using
  623. * the existing VGA graphics screen. Since we will be using an
  624. * on-screen portion of this buffer, we must save and restore the
  625. * contents of this buffer.
  626. *
  627. * If this fails (haven't run into any machines where this is the
  628. * case), switch into SVGA 640x480 8BPP and use the VGA graphics
  629. * screen. This is a last resort, since unlike using an existing
  630. * screen, this will destroy the "blue screen", and is therefore not
  631. * transparent to the user. If we can't even get this to work, report
  632. * that there isn't enough buffer space. This would only happen when
  633. * the onboard VGA is disabled and a low-end (MDA - even CGA has 16k
  634. * of memory available) card is used to provide the text screen.
  635. */
  636. /*
  637. * Leave some room for the EDID structure, which must also be
  638. * read into a buffer below 1M physical.
  639. */
  640. if (BufferSize > 0x5000)
  641. {
  642. VideoDebugPrint((DEBUG_ERROR, "QueryMach64() - query needs more buffer than we have\n"));
  643. return ERROR_INSUFFICIENT_BUFFER;
  644. }
  645. BufferSeg = 0x0BA00; /* Colour text */
  646. MappedBuffer = MapFramebuffer((BufferSeg << 4), BufferSize);
  647. if (MappedBuffer != 0)
  648. {
  649. if (IsBufferBacked(MappedBuffer, BufferSize) == FALSE)
  650. {
  651. VideoDebugPrint((DEBUG_NORMAL, "Colour text screen not backed by physical memory\n"));
  652. VideoPortFreeDeviceBase(phwDeviceExtension, MappedBuffer);
  653. MappedBuffer = 0;
  654. }
  655. }
  656. else
  657. {
  658. VideoDebugPrint((DEBUG_NORMAL, "Can't map colour text screen\n"));
  659. }
  660. /*
  661. * If we were unable to allocate a large enough buffer in the
  662. * colour text screen, try the monochrome text screen.
  663. */
  664. if (MappedBuffer == 0)
  665. {
  666. VideoDebugPrint((DEBUG_NORMAL, "Can't use colour text screen, trying monochrome text screen\n"));
  667. BufferSeg = 0x0B200;
  668. if ((MappedBuffer = MapFramebuffer((BufferSeg << 4), BufferSize)) != 0)
  669. {
  670. if (IsBufferBacked(MappedBuffer, BufferSize) == FALSE)
  671. {
  672. VideoDebugPrint((DEBUG_NORMAL, "Monochrome text screen not backed by physical memory\n"));
  673. VideoPortFreeDeviceBase(phwDeviceExtension, MappedBuffer);
  674. MappedBuffer = 0;
  675. }
  676. }
  677. else
  678. {
  679. VideoDebugPrint((DEBUG_NORMAL, "Can't map monochrome text screen\n"));
  680. }
  681. }
  682. if (MappedBuffer == 0)
  683. {
  684. /*
  685. * We were unable to use the offscreen portion of video memory
  686. * in either of the text screens. Try to use an existing graphics
  687. * screen.
  688. *
  689. * Currently, only the DEC Alpha will fail to find the offscreen
  690. * portion of either text screen.
  691. */
  692. VideoDebugPrint((DEBUG_NORMAL, "Can't use monochrome text screen, trying existing graphics screen\n"));
  693. BufferSeg = 0x0A000;
  694. if ((MappedBuffer = MapFramebuffer((BufferSeg << 4), BufferSize)) != 0)
  695. {
  696. /*
  697. * Preserve the contents of VGA registers which affect the
  698. * manner in which graphics memory is accessed, then set
  699. * the values we need.
  700. */
  701. OUTP(VGA_SEQ_IND, 2);
  702. SavedVgaBuffer[VGA_SAVE_SEQ02] = INP(VGA_SEQ_DATA);
  703. OUTP(VGA_SEQ_IND, 2);
  704. OUTP(VGA_SEQ_DATA, 0x01);
  705. OUTP(VGA_GRAX_IND, 8);
  706. SavedVgaBuffer[VGA_SAVE_GRA08] = INP(VGA_GRAX_DATA);
  707. OUTP(VGA_GRAX_IND, 8);
  708. OUTP(VGA_GRAX_DATA, 0xFF);
  709. OUTP(VGA_GRAX_IND, 1);
  710. SavedVgaBuffer[VGA_SAVE_GRA01] = INP(VGA_GRAX_DATA);
  711. OUTP(VGA_GRAX_IND, 1);
  712. OUTP(VGA_GRAX_DATA, 0x00);
  713. /*
  714. * Save the contents of the screen to our private
  715. * buffer, so we can restore the screen later.
  716. */
  717. if (BufferSize > VGA_SAVE_SIZE)
  718. {
  719. VideoDebugPrint((DEBUG_ERROR, "Buffer too big to fully save/restore\n"));
  720. Scratch = VGA_SAVE_SIZE;
  721. }
  722. else
  723. {
  724. Scratch = BufferSize;
  725. }
  726. SavedVgaBuffer[VGA_SAVE_SIZE] = (UCHAR)(Scratch & 0x00FF);
  727. SavedVgaBuffer[VGA_SAVE_SIZE_H] = (UCHAR)((ULONG)((Scratch & 0xFF00) >> 8));
  728. for (Count = 0; (short)Count < (short)Scratch; Count++)
  729. {
  730. SavedVgaBuffer[Count] = VideoPortReadRegisterUchar(&(MappedBuffer[Count]));
  731. }
  732. if (IsBufferBacked(MappedBuffer, BufferSize) == FALSE)
  733. {
  734. VideoDebugPrint((DEBUG_NORMAL, "Existing graphics screen not backed by physical memory\n"));
  735. VideoPortFreeDeviceBase(phwDeviceExtension, MappedBuffer);
  736. MappedBuffer = 0;
  737. OUTP(VGA_SEQ_IND, 2);
  738. OUTP(VGA_SEQ_DATA, SavedVgaBuffer[VGA_SAVE_SEQ02]);
  739. OUTP(VGA_GRAX_IND, 8);
  740. OUTP(VGA_GRAX_DATA, SavedVgaBuffer[VGA_SAVE_GRA08]);
  741. OUTP(VGA_GRAX_IND, 1);
  742. OUTP(VGA_GRAX_DATA, SavedVgaBuffer[VGA_SAVE_GRA01]);
  743. }
  744. }
  745. else
  746. {
  747. VideoDebugPrint((DEBUG_NORMAL, "Can't map existing graphics screen\n"));
  748. }
  749. } /* end if (previous buffer allocation failed) */
  750. /*
  751. * If we were unable to allocate a large enough buffer in an existing
  752. * screen, try the VGA graphics screen. This will wipe out
  753. * the Windows NT "blue screen", but it gives us one last chance
  754. * to get a block of memory below 1M.
  755. * Don't start at the beginning of the VGA graphics window, since
  756. * we will need to distinguish this case from the nondestructive
  757. * access to the VGA graphics screen at cleanup time, and the
  758. * different buffer segment for the two cases will allow us to
  759. * do this.
  760. */
  761. if (MappedBuffer == 0)
  762. {
  763. VideoDebugPrint((DEBUG_NORMAL, "Nondestructive VGA memory access failed, trying graphics screen\n"));
  764. Registers.Eax = 0x62; /* 640x480 8BPP */
  765. VideoPortInt10(phwDeviceExtension, &Registers);
  766. BufferSeg = 0x0A100;
  767. if ((MappedBuffer = MapFramebuffer((BufferSeg << 4), BufferSize)) == 0)
  768. {
  769. VideoDebugPrint((DEBUG_ERROR, "Can't map graphics screen - aborting query\n"));
  770. return ERROR_INSUFFICIENT_BUFFER;
  771. }
  772. if (IsBufferBacked(MappedBuffer, BufferSize) == FALSE)
  773. {
  774. VideoDebugPrint((DEBUG_ERROR, "Graphics screen not backed by memory - aborting query\n"));
  775. VideoPortFreeDeviceBase(phwDeviceExtension, MappedBuffer);
  776. return ERROR_INSUFFICIENT_BUFFER;
  777. }
  778. }
  779. /*
  780. * We now have a buffer big enough to hold the query structure,
  781. * so make the BIOS call to fill it in.
  782. */
  783. Registers.Ebx = 0;
  784. Registers.Edx = BufferSeg;
  785. Registers.Eax = BIOS_QUERY;
  786. Registers.Ecx = BIOS_QUERY_FULL;
  787. if ((RetVal = VideoPortInt10(phwDeviceExtension, &Registers)) != NO_ERROR)
  788. {
  789. VideoDebugPrint((DEBUG_ERROR, "QueryMach64() - failed BIOS_QUERY_FULL call\n"));
  790. return RetVal;
  791. }
  792. CxQuery = (struct cx_query *)MappedBuffer;
  793. /*
  794. * The Mach 64 query structure and mode tables may be a different size
  795. * from their equivalents (query_structure and st_mode_table). To avoid
  796. * overflowing our buffer, find out how many mode tables we have space
  797. * to hold.
  798. *
  799. * Later, when we are filling the mode tables, we will check to see
  800. * whether the current mode table would exceed this limit. If it would,
  801. * we will return ERROR_INSUFFICIENT_BUFFER rather than overflowing
  802. * the table.
  803. */
  804. MaxModes = (QUERYSIZE - sizeof(struct query_structure)) / sizeof(struct st_mode_table);
  805. /*
  806. * Fill in the header of the query stucture.
  807. */
  808. Query->q_structure_rev = VideoPortReadRegisterUchar(&(CxQuery->cx_structure_rev));
  809. VideoDebugPrint((DEBUG_DETAIL, "Structure revision = 0x%X\n", VideoPortReadRegisterUchar(&(CxQuery->cx_structure_rev))));
  810. Query->q_mode_offset = VideoPortReadRegisterUshort(&(CxQuery->cx_mode_offset));
  811. VideoDebugPrint((DEBUG_DETAIL, "Mode offset = 0x%X\n", VideoPortReadRegisterUshort(&(CxQuery->cx_mode_offset))));
  812. Query->q_sizeof_mode = VideoPortReadRegisterUchar(&(CxQuery->cx_mode_size));
  813. VideoDebugPrint((DEBUG_DETAIL, "Mode size = 0x%X\n", VideoPortReadRegisterUchar(&(CxQuery->cx_mode_size))));
  814. /*
  815. * Currently only one revision of Mach 64. Will need to
  816. * set multiple values once new (production) revisions come out.
  817. */
  818. Query->q_asic_rev = CI_88800_GX;
  819. Query->q_number_modes = 0; /* Initially assume no modes supported */
  820. Query->q_status_flags = 0;
  821. /*
  822. * If the on-board VGA is enabled, set shared VGA/accelerator memory.
  823. * Whether or not it is enabled, the accelerator will be able to
  824. * access all the video memory.
  825. */
  826. if ((Query->q_VGA_type = VideoPortReadRegisterUchar(&(CxQuery->cx_vga_type)) != 0))
  827. {
  828. Scratch = INPD(MEM_CNTL) & 0x0FFFBFFFF; /* Clear MEM_BNDRY_EN bit */
  829. OUTPD(MEM_CNTL, Scratch);
  830. VideoDebugPrint((DEBUG_DETAIL, "VGA enabled on this card\n"));
  831. }
  832. else
  833. {
  834. VideoDebugPrint((DEBUG_DETAIL, "VGA disabled on this card\n"));
  835. }
  836. Query->q_VGA_boundary = 0;
  837. OrigRamSize = VideoPortReadRegisterUchar(&(CxQuery->cx_memory_size));
  838. VideoDebugPrint((DEBUG_DETAIL, "Raw memory size = 0x%X\n", OrigRamSize));
  839. Query->q_memory_size = CXMapMemSize[OrigRamSize];
  840. MemAvail = Query->q_memory_size * QUARTER_MEG;
  841. /*
  842. * DAC types are not contiguous, so a lookup table would be
  843. * larger than necessary and restrict future expansion.
  844. */
  845. OrigDacType = VideoPortReadRegisterUchar(&(CxQuery->cx_dac_type));
  846. VideoDebugPrint((DEBUG_DETAIL, "cx_dac_type = 0x%X\n", OrigDacType));
  847. switch(OrigDacType)
  848. {
  849. case 0x00:
  850. VideoDebugPrint((DEBUG_DETAIL, "Internal DAC\n"));
  851. Scratch = VideoPortReadRegisterUshort(&(CxQuery->cx_asic_rev));
  852. if ((Scratch & 0xFF00) == 0x4300)
  853. {
  854. VideoDebugPrint((DEBUG_DETAIL, "Mach 64 CT internal DAC\n"));
  855. Query->q_DAC_type = DAC_INTERNAL_CT;
  856. }
  857. else if ((Scratch & 0xFF00) == 0x5600)
  858. {
  859. VideoDebugPrint((DEBUG_DETAIL, "Mach 64 VT internal DAC\n"));
  860. Query->q_DAC_type = DAC_INTERNAL_VT;
  861. }
  862. else if ((Scratch & 0xFF00) == 0x4700)
  863. {
  864. VideoDebugPrint((DEBUG_DETAIL, "Mach 64 GT internal DAC\n"));
  865. Query->q_DAC_type = DAC_INTERNAL_GT;
  866. }
  867. else
  868. {
  869. VideoDebugPrint((DEBUG_ERROR, "Unknown internal DAC (ASIC ID = 0x%X), treating as BT47x\n", Scratch));
  870. Query->q_DAC_type = DAC_BT47x;
  871. }
  872. DacTypeMask = 0x01;
  873. break;
  874. case 0x01:
  875. VideoDebugPrint((DEBUG_DETAIL, "IBM 514 DAC\n"));
  876. Query->q_DAC_type = DAC_IBM514;
  877. DacTypeMask = 0x02;
  878. break;
  879. case 0x02:
  880. VideoDebugPrint((DEBUG_DETAIL, "TI34075 DAC\n"));
  881. Query->q_DAC_type = DAC_TI34075;
  882. DacTypeMask = 0x04;
  883. break;
  884. case 0x72:
  885. VideoDebugPrint((DEBUG_DETAIL, "TVP 3026 DAC\n"));
  886. Query->q_DAC_type = DAC_TVP3026;
  887. DacTypeMask = 0x04;
  888. break;
  889. case 0x04:
  890. VideoDebugPrint((DEBUG_DETAIL, "BT48x DAC\n"));
  891. Query->q_DAC_type = DAC_BT48x;
  892. DacTypeMask = 0x10;
  893. break;
  894. case 0x14:
  895. VideoDebugPrint((DEBUG_DETAIL, "AT&T 49[123] DAC\n"));
  896. Query->q_DAC_type = DAC_ATT491;
  897. DacTypeMask = 0x10;
  898. break;
  899. case 0x05:
  900. case 0x15:
  901. VideoDebugPrint((DEBUG_DETAIL, "ATI68860 DAC\n"));
  902. Query->q_DAC_type = DAC_ATI_68860;
  903. DacTypeMask = 0x20;
  904. break;
  905. case 0x06:
  906. VideoDebugPrint((DEBUG_DETAIL, "STG1700 DAC\n"));
  907. Query->q_DAC_type = DAC_STG1700;
  908. DacTypeMask = 0x40;
  909. break;
  910. case 0x07:
  911. case 0x67:
  912. case 0x77:
  913. case 0x87:
  914. case 0x97:
  915. case 0xA7:
  916. case 0xB7:
  917. case 0xC7:
  918. case 0xD7:
  919. case 0xE7:
  920. case 0xF7:
  921. VideoDebugPrint((DEBUG_DETAIL, "STG1702 DAC\n"));
  922. Query->q_DAC_type = DAC_STG1702;
  923. DacTypeMask = 0x80;
  924. break;
  925. case 0x37:
  926. VideoDebugPrint((DEBUG_DETAIL, "STG1703 DAC\n"));
  927. Query->q_DAC_type = DAC_STG1703;
  928. DacTypeMask = 0x80;
  929. break;
  930. case 0x47:
  931. VideoDebugPrint((DEBUG_DETAIL, "CH8398 DAC\n"));
  932. Query->q_DAC_type = DAC_CH8398;
  933. DacTypeMask = 0x80;
  934. break;
  935. case 0x57:
  936. VideoDebugPrint((DEBUG_DETAIL, "AT&T 408 DAC\n"));
  937. Query->q_DAC_type = DAC_ATT408;
  938. DacTypeMask = 0x80;
  939. break;
  940. case 0x16:
  941. case 0x27:
  942. VideoDebugPrint((DEBUG_DETAIL, "AT&T 498 DAC\n"));
  943. Query->q_DAC_type = DAC_ATT498;
  944. DacTypeMask = 0x80;
  945. break;
  946. case 0x17:
  947. VideoDebugPrint((DEBUG_DETAIL, "SC15021 DAC\n"));
  948. Query->q_DAC_type = DAC_SC15021;
  949. DacTypeMask = 0x80;
  950. break;
  951. case 0x75:
  952. VideoDebugPrint((DEBUG_DETAIL, "TVP 3026 DAC\n"));
  953. Query->q_DAC_type = DAC_TVP3026;
  954. DacTypeMask = 0x20;
  955. break;
  956. case 0x03:
  957. VideoDebugPrint((DEBUG_DETAIL, "BT 47x DAC\n"));
  958. Query->q_DAC_type = DAC_BT47x;
  959. DacTypeMask = 0x04;
  960. break;
  961. default:
  962. VideoDebugPrint((DEBUG_ERROR, "Unknown DAC, treating as BT 47x\n"));
  963. Query->q_DAC_type = DAC_BT47x;
  964. DacTypeMask = 0x04;
  965. break;
  966. }
  967. VideoDebugPrint((DEBUG_DETAIL, "Raw memory type = 0x%X\n", VideoPortReadRegisterUchar(&(CxQuery->cx_memory_type))));
  968. /*
  969. * Bit 7 of the memory type is used to indicate lack of block write
  970. * capability on recent BIOSes, but not on older ones. Strip it
  971. * before mapping the RAM type in order to avoid the need for an
  972. * additional 128 entries, most of which are unused, in the
  973. * mapping table.
  974. *
  975. * Even though the absence of this flag is not a reliable indicator
  976. * of block write capability, its presence is a reliable indicator
  977. * of a lack of block write capability.
  978. *
  979. * We can strip this flag after setting the block write status since
  980. * this is the only place it is used, and subsequent references to
  981. * the memory type require only the lower 7 bits.
  982. */
  983. OrigRamType = VideoPortReadRegisterUchar(&(CxQuery->cx_memory_type));
  984. if (OrigRamType & 0x80)
  985. Query->q_BlockWrite = BLOCK_WRITE_NO;
  986. OrigRamType &= 0x7F;
  987. /*
  988. * A given memory type value will have different meanings for
  989. * different ASIC types. While the GX and CX use different
  990. * RAM types, none of them require special-case handling,
  991. * so we can treat these ASIC types as equivalent.
  992. */
  993. Scratch = INPD(CONFIG_CHIP_ID) & CONFIG_CHIP_ID_TypeMask;
  994. if ((Scratch == CONFIG_CHIP_ID_TypeGX) ||
  995. (Scratch == CONFIG_CHIP_ID_TypeCX))
  996. {
  997. VideoDebugPrint((DEBUG_DETAIL, "Setting q_memory_type for CX or GX\n"));
  998. Query->q_memory_type = CXMapRamType[OrigRamType];
  999. }
  1000. else
  1001. {
  1002. VideoDebugPrint((DEBUG_DETAIL, "Setting q_memory_type for CT/VT/GT\n"));
  1003. Query->q_memory_type = CTMapRamType[OrigRamType];
  1004. }
  1005. VideoDebugPrint((DEBUG_DETAIL, "Raw bus type = 0x%X\n", VideoPortReadRegisterUchar(&(CxQuery->cx_bus_type))));
  1006. Query->q_bus_type = CXMapBus[VideoPortReadRegisterUchar(&(CxQuery->cx_bus_type))];
  1007. /*
  1008. * Get the linear aperture configuration. If the linear aperture and
  1009. * VGA aperture are both disabled, return ERROR_DEV_NOT_EXIST, since
  1010. * some Mach 64 registers exist only in memory mapped form and are
  1011. * therefore not available without an aperture.
  1012. */
  1013. Query->q_aperture_cfg = VideoPortReadRegisterUchar(&(CxQuery->cx_aperture_cfg)) & BIOS_AP_SIZEMASK;
  1014. VideoDebugPrint((DEBUG_DETAIL, "Aperture configuration = 0x%X\n", VideoPortReadRegisterUchar(&(CxQuery->cx_aperture_cfg))));
  1015. if (Query->q_aperture_cfg == 0)
  1016. {
  1017. if (Query->q_VGA_type == 0)
  1018. {
  1019. VideoDebugPrint((DEBUG_ERROR, "Neither linear nor VGA aperture exists - aborting query\n"));
  1020. return ERROR_DEV_NOT_EXIST;
  1021. }
  1022. Query->q_aperture_addr = 0;
  1023. }
  1024. else
  1025. {
  1026. Query->q_aperture_addr = VideoPortReadRegisterUshort(&(CxQuery->cx_aperture_addr));
  1027. VideoDebugPrint((DEBUG_DETAIL, "Aperture at %d megabytes\n", Query->q_aperture_addr));
  1028. /*
  1029. * If the 8M aperture is configured on a 4M boundary that is
  1030. * not also an 8M boundary, it will actually start on the 8M
  1031. * boundary obtained by truncating the reported value to a
  1032. * multiple of 8M.
  1033. */
  1034. if ((Query->q_aperture_cfg & BIOS_AP_SIZEMASK) == BIOS_AP_8M)
  1035. {
  1036. VideoDebugPrint((DEBUG_DETAIL, "8 megabyte aperture\n"));
  1037. Query->q_aperture_addr &= 0xFFF8;
  1038. }
  1039. }
  1040. /*
  1041. * The Mach 64 does not support shadow sets, so re-use the shadow
  1042. * set 1 definition to hold deep colour support and RAMDAC special
  1043. * features information.
  1044. */
  1045. Query->q_shadow_1 = VideoPortReadRegisterUchar(&(CxQuery->cx_deep_colour)) | (VideoPortReadRegisterUchar(&(CxQuery->cx_ramdac_info)) << 8);
  1046. VideoDebugPrint((DEBUG_DETAIL, "Deep colour support = 0x%X\n", VideoPortReadRegisterUchar(&(CxQuery->cx_deep_colour))));
  1047. /*
  1048. * If this card supports non-palette modes, choose which of the supported
  1049. * colour orderings to use at each pixel depth. Record the maximum
  1050. * pixel depth the card supports, since some of the mode tables
  1051. * may list a maximum pixel depth beyond the DAC's capabilities.
  1052. *
  1053. * Assume that no DAC will support nBPP (n > 8) without also supporting
  1054. * all colour depths between 8 and n.
  1055. */
  1056. AbsMaxDepth = 8; /* Cards without high colour support */
  1057. if (Query->q_shadow_1 & S1_16BPP_565)
  1058. {
  1059. Query->q_HiColourSupport = RGB16_565;
  1060. AbsMaxDepth = 16;
  1061. }
  1062. if (Query->q_shadow_1 & S1_24BPP)
  1063. {
  1064. if (Query->q_shadow_1 & S1_24BPP_RGB)
  1065. {
  1066. VideoDebugPrint((DEBUG_DETAIL, "24BPP order RGB\n"));
  1067. Query->q_HiColourSupport |= RGB24_RGB;
  1068. }
  1069. else
  1070. {
  1071. VideoDebugPrint((DEBUG_DETAIL, "24BPP order BGR\n"));
  1072. Query->q_HiColourSupport |= RGB24_BGR;
  1073. }
  1074. AbsMaxDepth = 24;
  1075. }
  1076. if (Query->q_shadow_1 & S1_32BPP)
  1077. {
  1078. if (Query->q_shadow_1 & S1_32BPP_RGBx)
  1079. {
  1080. VideoDebugPrint((DEBUG_DETAIL, "32BPP order RGBx\n"));
  1081. Query->q_HiColourSupport |= RGB32_RGBx;
  1082. }
  1083. else if (Query->q_shadow_1 & S1_32BPP_xRGB)
  1084. {
  1085. VideoDebugPrint((DEBUG_DETAIL, "32BPP order xRGB\n"));
  1086. Query->q_HiColourSupport |= RGB32_xRGB;
  1087. }
  1088. else if (Query->q_shadow_1 & S1_32BPP_BGRx)
  1089. {
  1090. VideoDebugPrint((DEBUG_DETAIL, "32BPP order BGRx\n"));
  1091. Query->q_HiColourSupport |= RGB32_BGRx;
  1092. }
  1093. else
  1094. {
  1095. VideoDebugPrint((DEBUG_DETAIL, "32BPP order xBGR\n"));
  1096. Query->q_HiColourSupport |= RGB32_xBGR;
  1097. }
  1098. AbsMaxDepth = 32;
  1099. }
  1100. /*
  1101. * Get the hardware capability list.
  1102. */
  1103. Registers.Eax = BIOS_CAP_LIST;
  1104. Registers.Ecx = 0xFFFF;
  1105. if ((RetVal = VideoPortInt10(phwDeviceExtension, &Registers)) != NO_ERROR)
  1106. {
  1107. VideoDebugPrint((DEBUG_ERROR, "QueryMach64() - failed BIOS_CAP_LIST\n"));
  1108. return RetVal;
  1109. }
  1110. FormatType = (short)(Registers.Eax & 0x000000FF);
  1111. /*
  1112. * Map in the table of hardware capabilities whose pointer was returned
  1113. * by the BIOS call. The call does not return the size of the table,
  1114. * but according to Steve Stefanidis 1k is plenty of space.
  1115. *
  1116. * We must include the 2 bytes immediately preceeding the table when
  1117. * we map it, since they contain information about the way the table
  1118. * is arranged.
  1119. */
  1120. if ((HwCapBuffer = MapFramebuffer(((Registers.Edx << 4) | (Registers.Ebx - 2)), 1024)) == 0)
  1121. {
  1122. VideoDebugPrint((DEBUG_ERROR, "Can't map hardware capability table at 0x%X:0x%X\n", Registers.Edx, Registers.Ebx));
  1123. return ERROR_INSUFFICIENT_BUFFER;
  1124. }
  1125. /*
  1126. * If the value in the CX register was changed, there is a second
  1127. * table with supplemental values. According to Arthur Lai, this
  1128. * second table will only extend the original table, and never
  1129. * detract from it. If this table exists, but we can't map it,
  1130. * we can still work with the primrary table rather than treating
  1131. * the failure as a fatal error.
  1132. *
  1133. * While the BIOS will leave the CX register alone if the second
  1134. * table doesn't exist, there is no guarantee that Windows NT will
  1135. * leave the upper 16 bits of ECX alone.
  1136. */
  1137. if ((Registers.Ecx & 0x0000FFFF) == 0xFFFF)
  1138. {
  1139. HwSupBuffer = 0;
  1140. }
  1141. else
  1142. {
  1143. HwSupBuffer = MapFramebuffer(((Registers.Edx << 4) | Registers.Ecx), 1024);
  1144. }
  1145. HwCapBytesPerRow = VideoPortReadRegisterUchar(HwCapBuffer + 1);
  1146. VideoDebugPrint((DEBUG_DETAIL, "Table has %d bytes per row\n", HwCapBytesPerRow));
  1147. pmode = (struct st_mode_table *)Query;
  1148. ((struct query_structure *)pmode)++;
  1149. /*
  1150. * Initially, we do not know whether to merge our "canned" mode
  1151. * tables with tables from an EDID structure returned via DDC,
  1152. * or with tables from a VDIF file. If we are dealing with an
  1153. * EDID structure, we have not yet read any data, so the initial
  1154. * checksum is zero.
  1155. */
  1156. phwDeviceExtension->MergeSource = MERGE_UNKNOWN;
  1157. phwDeviceExtension->EdidChecksum = 0;
  1158. /*
  1159. * Search through the returned mode tables, and fill in the query
  1160. * structure's mode tables using the information we find there.
  1161. *
  1162. * DOES NOT ASSUME: Order of mode tables, or number of mode
  1163. * tables per resolution.
  1164. */
  1165. for (CurrentRes = RES_640; CurrentRes <= RES_1600; CurrentRes++)
  1166. {
  1167. CxModeTable = (struct cx_mode_table *)(MappedBuffer + VideoPortReadRegisterUshort(&(CxQuery->cx_mode_offset)));
  1168. /*
  1169. * The list of maximum pixel clock frequencies contains either
  1170. * garbage (640x480), or the results for the previous resolution.
  1171. * Clear it.
  1172. */
  1173. for (Count = DEPTH_NOTHING; Count <= DEPTH_32BPP; Count++)
  1174. MaxDotClock[Count] = 0;
  1175. /*
  1176. * Search through the list of hardware capabilities. If we find
  1177. * an entry for the current resolution, the DAC/RAM type is
  1178. * correct, and we have enough memory, update the list of
  1179. * maximum pixel clock frequencies.
  1180. *
  1181. * If we have switched to the supplemental table on a previous
  1182. * resolution, switch back to the primrary table.
  1183. */
  1184. HwCapWalker = HwCapBuffer + 2;
  1185. HwCapEntry = (struct cx_hw_cap *)HwCapWalker;
  1186. if (FormatType >= FORMAT_DACTYPE)
  1187. FormatType -= FORMAT_DACTYPE;
  1188. while (VideoPortReadRegisterUchar(&(HwCapEntry->cx_HorRes)) != 0)
  1189. {
  1190. /*
  1191. * Assigning HwCapEntry is redundant on the first pass
  1192. * through the loop, but by assigning it and then incrementing
  1193. * HwCapWalker at the beginning of the loop it reduces the
  1194. * complexity of each "skip this entry because it doesn't
  1195. * apply to us" decision point.
  1196. *
  1197. * A side effect of this is that we will check each entry
  1198. * to see if its horizontal resolution is zero (end-of-table
  1199. * flag) only after we have examined it in an attempt to
  1200. * add its pixel clock data to our list. This is harmless,
  1201. * since a horizontal resolution of zero will not match any
  1202. * of the resolutions we are looking for, so the check to
  1203. * see if the current entry is for the correct resolution
  1204. * will always interpret the end-of-table flag as being
  1205. * an entry for the wrong resolution, and skip to the next
  1206. * entry. This will take us to the top of the loop, where
  1207. * we will see that we have hit the end of the table.
  1208. */
  1209. HwCapEntry = (struct cx_hw_cap *)HwCapWalker;
  1210. HwCapWalker += HwCapBytesPerRow;
  1211. /*
  1212. * If we have run into the end of the first table and
  1213. * the second (supplemental) table exists, switch to
  1214. * it. If we have hit the end of the supplemental
  1215. * table, the check to see if we're looking at an
  1216. * entry corresponding to the desired resolution will
  1217. * catch it and get us out of the loop.
  1218. *
  1219. * The format type returned by the BIOS is the same
  1220. * regardless of whether we are working with the
  1221. * primrary or supplemental table. Since the primrary
  1222. * table uses masks based on the type, while the
  1223. * supplemental table requires an exact match, we
  1224. * must distinguish between the tables when looking
  1225. * at the format type. By making a duplicate set of
  1226. * format types for "exact match", with each defined
  1227. * value in this set being greater than its "mask"
  1228. * counterpart by the number of format types the BIOS
  1229. * can return, we can also use the format type to
  1230. * determine which table we are working with. The
  1231. * DAC-formatted table is the lowest (zero for "mask",
  1232. * number of format types for "exact match").
  1233. */
  1234. if ((VideoPortReadRegisterUchar(&(HwCapEntry->cx_HorRes)) == 0) &&
  1235. (FormatType < FORMAT_DACTYPE))
  1236. {
  1237. VideoDebugPrint((DEBUG_DETAIL, "Switching to supplemental table\n"));
  1238. HwCapWalker = HwSupBuffer;
  1239. HwCapEntry = (struct cx_hw_cap *)HwCapWalker;
  1240. HwCapWalker += HwCapBytesPerRow;
  1241. FormatType += FORMAT_DACTYPE;
  1242. }
  1243. /*
  1244. * Reject entries dealing with resolutions other than the
  1245. * one we are interested in. The cx_HorRes field is in units
  1246. * of 8 pixels.
  1247. */
  1248. Scratch = VideoPortReadRegisterUchar(&(HwCapEntry->cx_HorRes));
  1249. if (((CurrentRes == RES_640) && (Scratch != 80)) ||
  1250. ((CurrentRes == RES_800) && (Scratch != 100)) ||
  1251. ((CurrentRes == RES_1024) && (Scratch != 128)) ||
  1252. ((CurrentRes == RES_1152) && (Scratch != 144)) ||
  1253. ((CurrentRes == RES_1280) && (Scratch != 160)) ||
  1254. ((CurrentRes == RES_1600) && (Scratch != 200)))
  1255. {
  1256. VideoDebugPrint((DEBUG_DETAIL, "Incorrect resolution - %d pixels wide\n", (Scratch*8)));
  1257. continue;
  1258. }
  1259. VideoDebugPrint((DEBUG_DETAIL, "Correct resolution"));
  1260. /*
  1261. * Reject entries which require a DAC or RAM type other
  1262. * than that installed on the card.
  1263. *
  1264. * Reminder - Unlike loops, switch statements are affected
  1265. * by "break" but not by "continue".
  1266. */
  1267. switch(FormatType)
  1268. {
  1269. case FORMAT_DACMASK:
  1270. if ((VideoPortReadRegisterUchar(&(HwCapEntry->cx_RamOrDacType)) & DacTypeMask) == 0)
  1271. {
  1272. VideoDebugPrint((DEBUG_DETAIL, " but wrong DAC type (mask)\n"));
  1273. continue;
  1274. }
  1275. break;
  1276. case FORMAT_RAMMASK:
  1277. /*
  1278. * Although the BIOS query structure definition allows bits
  1279. * 0 through 3 of the memory type field to be used as a
  1280. * memory type identifier, we must use only bits 0 through
  1281. * 2 to avoid shifting past the end of the 8-bit mask. Since
  1282. * even the ASIC which supports the most memory types (GX)
  1283. * only supports 7 types according to my BIOS guide, this
  1284. * should not be a problem.
  1285. */
  1286. if ((VideoPortReadRegisterUchar(&(HwCapEntry->cx_RamOrDacType)) & (1 << (OrigRamType & 0x07))) == 0)
  1287. {
  1288. VideoDebugPrint((DEBUG_DETAIL, " but wrong RAM type (mask)\n"));
  1289. continue;
  1290. }
  1291. break;
  1292. case FORMAT_DACTYPE:
  1293. if (VideoPortReadRegisterUchar(&(HwCapEntry->cx_RamOrDacType)) != OrigDacType)
  1294. {
  1295. VideoDebugPrint((DEBUG_DETAIL, " but wrong DAC type (exact match)\n"));
  1296. continue;
  1297. }
  1298. break;
  1299. case FORMAT_RAMTYPE:
  1300. if (VideoPortReadRegisterUchar(&(HwCapEntry->cx_RamOrDacType)) != OrigRamType)
  1301. {
  1302. VideoDebugPrint((DEBUG_DETAIL, " but wrong RAM type (exact match)\n"));
  1303. continue;
  1304. }
  1305. break;
  1306. default:
  1307. VideoDebugPrint((DEBUG_ERROR, "\nInvalid format type %d\n", FormatType));
  1308. continue;
  1309. break;
  1310. }
  1311. VideoDebugPrint((DEBUG_DETAIL, ", correct DAC/RAM type"));
  1312. /*
  1313. * Reject entries which require more RAM than is
  1314. * installed on the card. The amount of RAM required
  1315. * for a given mode may vary between VRAM and DRAM
  1316. * cards.
  1317. *
  1318. * The same RAM type code may represent different
  1319. * types of RAM for different Mach 64 ASICs. Since
  1320. * only the GX supports VRAM (as of the time of printing
  1321. * of my BIOS guide), it is safe to assume that any
  1322. * non-GX ASIC is using DRAM.
  1323. */
  1324. Scratch = OrigRamType;
  1325. if ((INPW(CONFIG_CHIP_ID) == CONFIG_CHIP_ID_TypeGX) &&
  1326. ((Scratch == 1) ||
  1327. (Scratch == 2) ||
  1328. (Scratch == 5) ||
  1329. (Scratch == 6)))
  1330. {
  1331. Scratch = VideoPortReadRegisterUchar(&(HwCapEntry->cx_MemReq)) & 0x0F;
  1332. }
  1333. else /* if (card uses DRAM) */
  1334. {
  1335. Scratch = VideoPortReadRegisterUchar(&(HwCapEntry->cx_MemReq)) & 0xF0;
  1336. Scratch >>= 4;
  1337. }
  1338. if (Scratch > OrigRamSize)
  1339. {
  1340. VideoDebugPrint((DEBUG_DETAIL, " but insufficient RAM\n"));
  1341. continue;
  1342. }
  1343. VideoDebugPrint((DEBUG_DETAIL, ", and enough RAM to support the mode\n"));
  1344. /*
  1345. * We have found an entry corresponding to this card's
  1346. * capabilities. For each pixel depth up to and including
  1347. * the maximum applicable for this entry, set the maximum
  1348. * pixel clock rate to the higher of its current value
  1349. * and the value for this entry.
  1350. *
  1351. * We must mask off the high bit of the maximum pixel depth
  1352. * because it is a flag which is irrelevant for our purposes.
  1353. */
  1354. Scratch = VideoPortReadRegisterUchar(&(HwCapEntry->cx_MaxPixDepth)) & 0x7F;
  1355. for (CurrentDepth = DEPTH_NOTHING; CurrentDepth <= Scratch; CurrentDepth++)
  1356. {
  1357. if (VideoPortReadRegisterUchar(&(HwCapEntry->cx_MaxDotClock)) > MaxDotClock[CurrentDepth])
  1358. {
  1359. MaxDotClock[CurrentDepth] = VideoPortReadRegisterUchar(&(HwCapEntry->cx_MaxDotClock));
  1360. VideoDebugPrint((DEBUG_DETAIL, "Increased MaxDotClock[%d] to %d MHz\n", CurrentDepth, MaxDotClock[CurrentDepth]));
  1361. }
  1362. }
  1363. } /* end while (more entries in hardware capability table) */
  1364. /*
  1365. * On some cards, the BIOS will report in AX=0xA?07 maximum pixel
  1366. * clock rates for pixel depths which AX=0xA?09 byte 0x13 reports
  1367. * as unsupported. Since switching into these modes will produce
  1368. * bizarre displays, we must mark these pixel depths as unavailable.
  1369. */
  1370. switch (AbsMaxDepth)
  1371. {
  1372. case 8:
  1373. VideoDebugPrint((DEBUG_DETAIL, "Forcing cutback to 8BPP maximum\n"));
  1374. MaxDotClock[DEPTH_16BPP] = 0;
  1375. MaxDotClock[DEPTH_24BPP] = 0;
  1376. MaxDotClock[DEPTH_32BPP] = 0;
  1377. break;
  1378. case 16:
  1379. VideoDebugPrint((DEBUG_DETAIL, "Forcing cutback to 16BPP maximum\n"));
  1380. MaxDotClock[DEPTH_24BPP] = 0;
  1381. MaxDotClock[DEPTH_32BPP] = 0;
  1382. break;
  1383. case 24:
  1384. VideoDebugPrint((DEBUG_DETAIL, "Forcing cutback to 24BPP maximum\n"));
  1385. MaxDotClock[DEPTH_32BPP] = 0;
  1386. break;
  1387. case 32:
  1388. default:
  1389. VideoDebugPrint((DEBUG_DETAIL, "No forced cutback needed\n"));
  1390. break;
  1391. }
  1392. /*
  1393. * Our new source stream display driver needs a linear aperture
  1394. * in order to handle 24BPP. Since the display driver doesn't
  1395. * have access to the aperture information when it is deciding
  1396. * which modes to pass on to the display applet, it can't make
  1397. * the decision to reject 24BPP modes for cards with only a
  1398. * VGA aperture. This decision must therefore be made in the
  1399. * miniport, so in a paged aperture configuration there are no
  1400. * 24BPP modes for the display driver to accept or reject.
  1401. *
  1402. * On the DEC Alpha, we treat machines using sparse space as
  1403. * a synthetic no-aperture case even if the LFB is enabled,
  1404. * so we must lock out 24BPP on these machines as well.
  1405. */
  1406. if (Query->q_aperture_cfg == 0)
  1407. {
  1408. VideoDebugPrint((DEBUG_DETAIL, "24BPP not available because we don't have a linear aperture\n"));
  1409. MaxDotClock[DEPTH_24BPP] = 0;
  1410. }
  1411. #if defined(ALPHA)
  1412. if (DenseOnAlpha(Query) == FALSE)
  1413. {
  1414. VideoDebugPrint((DEBUG_DETAIL, "24BPP not available in sparse space on Alpha\n"));
  1415. MaxDotClock[DEPTH_24BPP] = 0;
  1416. }
  1417. #endif
  1418. VideoDebugPrint((DEBUG_NORMAL, "Horizontal resolution = %d\n", CXHorRes[CurrentRes]));
  1419. VideoDebugPrint((DEBUG_NORMAL, "Maximum dot clock for 4BPP = %d MHz\n", MaxDotClock[DEPTH_4BPP]));
  1420. VideoDebugPrint((DEBUG_NORMAL, "Maximum dot clock for 8BPP = %d MHz\n", MaxDotClock[DEPTH_8BPP]));
  1421. VideoDebugPrint((DEBUG_NORMAL, "Maximum dot clock for 16BPP = %d MHz\n", MaxDotClock[DEPTH_16BPP]));
  1422. VideoDebugPrint((DEBUG_NORMAL, "Maximum dot clock for 24BPP = %d MHz\n", MaxDotClock[DEPTH_24BPP]));
  1423. VideoDebugPrint((DEBUG_NORMAL, "Maximum dot clock for 32BPP = %d MHz\n", MaxDotClock[DEPTH_32BPP]));
  1424. /*
  1425. * Search through the list of installed mode tables to see if there
  1426. * are any for the current resolution. We need this information
  1427. * in order to decide whether or not to make the hardware default
  1428. * refresh rate available for this resolution (BIOS behaviour is
  1429. * undefined when trying to load CRT parameters for the hardware
  1430. * default refresh rate at a given resolution if that resolution
  1431. * is not among the installed modes).
  1432. */
  1433. ModeInstalled = FALSE;
  1434. for (Count = 1; Count <= VideoPortReadRegisterUchar(&(CxQuery->cx_number_modes)); Count++)
  1435. {
  1436. /*
  1437. * If the current mode table matches the resolution we are
  1438. * looking for, then we know that there is a hardware
  1439. * default refresh rate available for this resolution.
  1440. * Since we only need to find one such mode table, there
  1441. * is no need to search the remainder of the mode tables.
  1442. */
  1443. if (VideoPortReadRegisterUshort(&(CxModeTable->cx_x_size)) == CXHorRes[CurrentRes])
  1444. {
  1445. ModeInstalled = TRUE;
  1446. VideoDebugPrint((DEBUG_DETAIL, "%d table found\n", CXHorRes[CurrentRes]));
  1447. break;
  1448. }
  1449. ((PUCHAR)CxModeTable) += VideoPortReadRegisterUchar(&(CxQuery->cx_mode_size));
  1450. }
  1451. /*
  1452. * The MaxDotClock[] entry for any pixel depth will
  1453. * contain either the maximum pixel clock for that
  1454. * pixel depth at the current resolution, or zero
  1455. * if that pixel depth is not supported at the
  1456. * current resolution. For any resolution, the
  1457. * maximum supported pixel clock rate will either
  1458. * remain the same or decrease as the pixel depth
  1459. * increases, but it will never increase.
  1460. *
  1461. * The pixel clock rate for 4BPP (lowest pixel depth
  1462. * we support) will only be zero if the card does not
  1463. * support the current resolution. If this is the case,
  1464. * skip to the next resolution.
  1465. */
  1466. if (MaxDotClock[DEPTH_4BPP] == 0)
  1467. {
  1468. VideoDebugPrint((DEBUG_NORMAL, "Current resolution not supported on this card - skipping to next.\n"));
  1469. continue;
  1470. }
  1471. Query->q_status_flags |= CXStatusFlags[CurrentRes];
  1472. VideoPortZeroMemory(&ThisRes, sizeof(struct st_mode_table));
  1473. /*
  1474. * Replace the "canned" mode tables with the Mach 64 versions
  1475. * in cases where the Mach 64 needs CRT parameters the
  1476. * Mach 8 and Mach 32 can't handle.
  1477. */
  1478. SetMach64Tables();
  1479. /*
  1480. * Set up the ranges of "canned" mode tables to use for each
  1481. * resolution. Initially assume that all tables at the desired
  1482. * resolution are available, later we will cut out those that
  1483. * are unavailable because the DAC and/or memory type doesn't
  1484. * support them at specific resolutions.
  1485. */
  1486. switch (CurrentRes)
  1487. {
  1488. case RES_640:
  1489. StartIndex = B640F60;
  1490. EndIndex = B640F100;
  1491. ThisRes.m_x_size = 640;
  1492. ThisRes.m_y_size = 480;
  1493. break;
  1494. case RES_800:
  1495. StartIndex = B800F89;
  1496. EndIndex = B800F100;
  1497. ThisRes.m_x_size = 800;
  1498. ThisRes.m_y_size = 600;
  1499. break;
  1500. case RES_1024:
  1501. StartIndex = B1024F87;
  1502. EndIndex = B1024F100;
  1503. ThisRes.m_x_size = 1024;
  1504. ThisRes.m_y_size = 768;
  1505. break;
  1506. case RES_1152:
  1507. StartIndex = B1152F87;
  1508. EndIndex = B1152F80;
  1509. ThisRes.m_x_size = 1152;
  1510. ThisRes.m_y_size = 864;
  1511. break;
  1512. case RES_1280:
  1513. StartIndex = B1280F87;
  1514. EndIndex = B1280F75;
  1515. ThisRes.m_x_size = 1280;
  1516. ThisRes.m_y_size = 1024;
  1517. break;
  1518. case RES_1600:
  1519. StartIndex = B1600F60;
  1520. EndIndex = B1600F76;
  1521. ThisRes.m_x_size = 1600;
  1522. ThisRes.m_y_size = 1200;
  1523. break;
  1524. }
  1525. /*
  1526. * Use a screen pitch equal to the horizontal resolution for
  1527. * linear aperture, and of 1024 or the horizontal resolution
  1528. * (whichever is higher) for VGA aperture.
  1529. */
  1530. ThisRes.m_screen_pitch = ThisRes.m_x_size;
  1531. #if !defined (SPLIT_RASTERS)
  1532. if (((Query->q_aperture_cfg & BIOS_AP_SIZEMASK) == 0) &&
  1533. (ThisRes.m_x_size < 1024))
  1534. ThisRes.m_screen_pitch = 1024;
  1535. /*
  1536. * Temporary until split rasters implemented.
  1537. */
  1538. if (((Query->q_aperture_cfg & BIOS_AP_SIZEMASK) == 0) &&
  1539. (ThisRes.m_x_size > 1024))
  1540. ThisRes.m_screen_pitch = 2048;
  1541. #endif
  1542. /*
  1543. * Get the parameters we need out of the table returned
  1544. * by the BIOS call.
  1545. */
  1546. ThisRes.m_h_total = VideoPortReadRegisterUchar(&(CxModeTable->cx_crtc_h_total));
  1547. ThisRes.m_h_disp = VideoPortReadRegisterUchar(&(CxModeTable->cx_crtc_h_disp));
  1548. ThisRes.m_h_sync_strt = VideoPortReadRegisterUchar(&(CxModeTable->cx_crtc_h_sync_strt));
  1549. ThisRes.m_h_sync_wid = VideoPortReadRegisterUchar(&(CxModeTable->cx_crtc_h_sync_wid));
  1550. ThisRes.m_v_total = VideoPortReadRegisterUshort(&(CxModeTable->cx_crtc_v_total));
  1551. ThisRes.m_v_disp = VideoPortReadRegisterUshort(&(CxModeTable->cx_crtc_v_disp));
  1552. ThisRes.m_v_sync_strt = VideoPortReadRegisterUshort(&(CxModeTable->cx_crtc_v_sync_strt));
  1553. ThisRes.m_v_sync_wid = VideoPortReadRegisterUchar(&(CxModeTable->cx_crtc_v_sync_wid));
  1554. ThisRes.m_h_overscan = VideoPortReadRegisterUshort(&(CxModeTable->cx_h_overscan));
  1555. ThisRes.m_v_overscan = VideoPortReadRegisterUshort(&(CxModeTable->cx_v_overscan));
  1556. ThisRes.m_overscan_8b = VideoPortReadRegisterUshort(&(CxModeTable->cx_overscan_8b));
  1557. ThisRes.m_overscan_gr = VideoPortReadRegisterUshort(&(CxModeTable->cx_overscan_gr));
  1558. ThisRes.m_clock_select = VideoPortReadRegisterUchar(&(CxModeTable->cx_clock_cntl));
  1559. ThisRes.control = VideoPortReadRegisterUshort(&(CxModeTable->cx_crtc_gen_cntl));
  1560. ThisRes.Refresh = DEFAULT_REFRESH;
  1561. /*
  1562. * For each supported pixel depth at the given resolution,
  1563. * copy the mode table, fill in the colour depth field,
  1564. * and increment the counter for the number of supported modes.
  1565. * Test 4BPP before 8BPP so the mode tables will appear in
  1566. * increasing order of pixel depth.
  1567. *
  1568. * If filling in the mode table would overflow the space available
  1569. * for mode tables, return the appropriate error code instead
  1570. * of continuing.
  1571. *
  1572. * All the DACs we support can handle 8 BPP at all the
  1573. * resolutions they support if there is enough memory on
  1574. * the card, and all but the 68860, IBM514, and TVP3026
  1575. * can support 4BPP under the same circumstances. If a
  1576. * DAC doesn't support a given resolution (e.g. 1600x1200),
  1577. * the MaxDotClock[] array will be zero for the resolution,
  1578. * and the INSTALL program won't set up any mode tables for
  1579. * that resolution. This will result in a kick-out at an
  1580. * earlier point in the code (when we found that 4BPP has a
  1581. * maximum pixel clock rate of zero), so we will never reach
  1582. * this point on resolutions the DAC doesn't support.
  1583. *
  1584. * 4BPP is only needed for resolutions where we don't have
  1585. * enough video memory to support 8BPP. At Microsoft's request,
  1586. * we must lock out 4BPP for resolutions where we can support
  1587. * 8BPP. We only support 4BPP on 1M cards since a BIOS quirk
  1588. * on some cards requires that we set the memory size to 1M
  1589. * when we switch into 4BPP. The DACs where we lock out 4BPP
  1590. * unconditionally are only found on VRAM cards, where the
  1591. * minimum configuration is 2M.
  1592. */
  1593. NumPixels = ThisRes.m_screen_pitch * ThisRes.m_y_size;
  1594. if((NumPixels < ONE_MEG*2) &&
  1595. ((MemAvail == ONE_MEG) && (NumPixels >= ONE_MEG)) &&
  1596. (MaxDotClock[DEPTH_4BPP] > 0) &&
  1597. (Query->q_DAC_type != DAC_ATI_68860) &&
  1598. (Query->q_DAC_type != DAC_TVP3026) &&
  1599. (Query->q_DAC_type != DAC_IBM514))
  1600. {
  1601. if (ModeInstalled)
  1602. {
  1603. if (Query->q_number_modes >= MaxModes)
  1604. {
  1605. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1606. CleanupQuery(HwCapBuffer, HwSupBuffer, MappedBuffer, BufferSeg, SavedVgaBuffer);
  1607. return ERROR_INSUFFICIENT_BUFFER;
  1608. }
  1609. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  1610. pmode->m_pixel_depth = 4;
  1611. pmode++; /* ptr to next mode table */
  1612. Query->q_number_modes++;
  1613. }
  1614. /*
  1615. * Add "canned" mode tables after verifying that the
  1616. * worst case (all possible "canned" modes can actually
  1617. * be loaded) won't exceed the maximum possible number
  1618. * of mode tables.
  1619. */
  1620. if ((FreeTables = MaxModes - Query->q_number_modes) <= 0)
  1621. {
  1622. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1623. CleanupQuery(HwCapBuffer, HwSupBuffer, MappedBuffer, BufferSeg, SavedVgaBuffer);
  1624. return ERROR_INSUFFICIENT_BUFFER;
  1625. }
  1626. Query->q_number_modes += SetFixedModes(StartIndex,
  1627. EndIndex,
  1628. CLOCK_SINGLE,
  1629. 4,
  1630. ThisRes.m_screen_pitch,
  1631. FreeTables,
  1632. (ULONG)(MaxDotClock[DEPTH_4BPP] * 1000000L),
  1633. &pmode);
  1634. }
  1635. if ((NumPixels < MemAvail) &&
  1636. (MaxDotClock[DEPTH_8BPP] > 0))
  1637. {
  1638. /*
  1639. * On some Mach 64 cards (depends on ASIC revision, RAM type,
  1640. * and DAC type), screen tearing will occur in 8BPP if the
  1641. * pitch is not a multiple of 64 pixels (800x600 is the only
  1642. * resolution where this is possible).
  1643. *
  1644. * If the pitch has already been boosted to 1024 (VGA aperture
  1645. * with no split rasters), it is already a multiple of 64, so
  1646. * no change is needed.
  1647. */
  1648. if (ThisRes.m_screen_pitch == 800)
  1649. ThisRes.m_screen_pitch = 832;
  1650. if (ModeInstalled)
  1651. {
  1652. if (Query->q_number_modes >= MaxModes)
  1653. {
  1654. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1655. CleanupQuery(HwCapBuffer, HwSupBuffer, MappedBuffer, BufferSeg, SavedVgaBuffer);
  1656. return ERROR_INSUFFICIENT_BUFFER;
  1657. }
  1658. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  1659. pmode->m_pixel_depth = 8;
  1660. pmode++; /* ptr to next mode table */
  1661. Query->q_number_modes++;
  1662. }
  1663. /*
  1664. * Add "canned" mode tables after verifying that the
  1665. * worst case (all possible "canned" modes can actually
  1666. * be loaded) won't exceed the maximum possible number
  1667. * of mode tables.
  1668. */
  1669. if ((FreeTables = MaxModes - Query->q_number_modes) <= 0)
  1670. {
  1671. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1672. CleanupQuery(HwCapBuffer, HwSupBuffer, MappedBuffer, BufferSeg, SavedVgaBuffer);
  1673. return ERROR_INSUFFICIENT_BUFFER;
  1674. }
  1675. Query->q_number_modes += SetFixedModes(StartIndex,
  1676. EndIndex,
  1677. CLOCK_SINGLE,
  1678. 8,
  1679. ThisRes.m_screen_pitch,
  1680. FreeTables,
  1681. (ULONG)(MaxDotClock[DEPTH_8BPP] * 1000000L),
  1682. &pmode);
  1683. /*
  1684. * If we have boosted the screen pitch to avoid tearing,
  1685. * cut it back to normal, since the boost is only needed
  1686. * in 8BPP. We will only have a pitch of 832 in 800x600
  1687. * with the pitch boost in place.
  1688. */
  1689. if (ThisRes.m_screen_pitch == 832)
  1690. ThisRes.m_screen_pitch = 800;
  1691. }
  1692. if ((NumPixels*2 < MemAvail) &&
  1693. (MaxDotClock[DEPTH_16BPP] > 0))
  1694. {
  1695. if (ModeInstalled)
  1696. {
  1697. if (Query->q_number_modes >= MaxModes)
  1698. {
  1699. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1700. CleanupQuery(HwCapBuffer, HwSupBuffer, MappedBuffer, BufferSeg, SavedVgaBuffer);
  1701. return ERROR_INSUFFICIENT_BUFFER;
  1702. }
  1703. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  1704. pmode->m_pixel_depth = 16;
  1705. pmode++; /* ptr to next mode table */
  1706. Query->q_number_modes++;
  1707. }
  1708. /*
  1709. * Add "canned" mode tables after verifying that the
  1710. * worst case (all possible "canned" modes can actually
  1711. * be loaded) won't exceed the maximum possible number
  1712. * of mode tables.
  1713. */
  1714. if ((FreeTables = MaxModes - Query->q_number_modes) <= 0)
  1715. {
  1716. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1717. CleanupQuery(HwCapBuffer, HwSupBuffer, MappedBuffer, BufferSeg, SavedVgaBuffer);
  1718. return ERROR_INSUFFICIENT_BUFFER;
  1719. }
  1720. Query->q_number_modes += SetFixedModes(StartIndex,
  1721. EndIndex,
  1722. CLOCK_SINGLE,
  1723. 16,
  1724. ThisRes.m_screen_pitch,
  1725. FreeTables,
  1726. (ULONG)(MaxDotClock[DEPTH_16BPP] * 1000000L),
  1727. &pmode);
  1728. }
  1729. if ((NumPixels*3 < MemAvail) &&
  1730. (MaxDotClock[DEPTH_24BPP] > 0))
  1731. {
  1732. if (ModeInstalled)
  1733. {
  1734. if (Query->q_number_modes >= MaxModes)
  1735. {
  1736. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1737. CleanupQuery(HwCapBuffer, HwSupBuffer, MappedBuffer, BufferSeg, SavedVgaBuffer);
  1738. return ERROR_INSUFFICIENT_BUFFER;
  1739. }
  1740. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  1741. pmode->m_pixel_depth = 24;
  1742. pmode++; /* ptr to next mode table */
  1743. Query->q_number_modes++;
  1744. }
  1745. /*
  1746. * Add "canned" mode tables after verifying that the
  1747. * worst case (all possible "canned" modes can actually
  1748. * be loaded) won't exceed the maximum possible number
  1749. * of mode tables.
  1750. */
  1751. if ((FreeTables = MaxModes - Query->q_number_modes) <= 0)
  1752. {
  1753. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1754. CleanupQuery(HwCapBuffer, HwSupBuffer, MappedBuffer, BufferSeg, SavedVgaBuffer);
  1755. return ERROR_INSUFFICIENT_BUFFER;
  1756. }
  1757. Query->q_number_modes += SetFixedModes(StartIndex,
  1758. EndIndex,
  1759. CLOCK_SINGLE,
  1760. 24,
  1761. ThisRes.m_screen_pitch,
  1762. FreeTables,
  1763. (ULONG)(MaxDotClock[DEPTH_24BPP] * 1000000L),
  1764. &pmode);
  1765. }
  1766. if ((NumPixels*4 < MemAvail) &&
  1767. (MaxDotClock[DEPTH_32BPP] > 0))
  1768. {
  1769. if (ModeInstalled)
  1770. {
  1771. if (Query->q_number_modes > MaxModes)
  1772. {
  1773. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1774. CleanupQuery(HwCapBuffer, HwSupBuffer, MappedBuffer, BufferSeg, SavedVgaBuffer);
  1775. return ERROR_INSUFFICIENT_BUFFER;
  1776. }
  1777. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  1778. pmode->m_pixel_depth = 32;
  1779. pmode++; /* ptr to next mode table */
  1780. Query->q_number_modes++;
  1781. }
  1782. /*
  1783. * Add "canned" mode tables after verifying that the
  1784. * worst case (all possible "canned" modes can actually
  1785. * be loaded) won't exceed the maximum possible number
  1786. * of mode tables.
  1787. */
  1788. if ((FreeTables = MaxModes - Query->q_number_modes) <= 0)
  1789. {
  1790. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1791. CleanupQuery(HwCapBuffer, HwSupBuffer, MappedBuffer, BufferSeg, SavedVgaBuffer);
  1792. return ERROR_INSUFFICIENT_BUFFER;
  1793. }
  1794. Query->q_number_modes += SetFixedModes(StartIndex,
  1795. EndIndex,
  1796. CLOCK_SINGLE,
  1797. 32,
  1798. ThisRes.m_screen_pitch,
  1799. FreeTables,
  1800. (ULONG)(MaxDotClock[DEPTH_32BPP] * 1000000L),
  1801. &pmode);
  1802. }
  1803. } /* end for */
  1804. Query->q_sizeof_struct = Query->q_number_modes * sizeof(struct st_mode_table) + sizeof(struct query_structure);
  1805. CleanupQuery(HwCapBuffer, HwSupBuffer, MappedBuffer, BufferSeg, SavedVgaBuffer);
  1806. return NO_ERROR;
  1807. } /* QueryMach64() */
  1808. /***************************************************************************
  1809. *
  1810. * BOOL BlockWriteAvail_cx(Query);
  1811. *
  1812. * struct query_structure *Query; Query information for the card
  1813. *
  1814. * DESCRIPTION:
  1815. * Test to see whether block write mode is available. This function
  1816. * assumes that the card has been set to an accelerated mode.
  1817. *
  1818. * RETURN VALUE:
  1819. * TRUE if this mode is available
  1820. * FALSE if it is not available
  1821. *
  1822. * GLOBALS CHANGED:
  1823. * None
  1824. *
  1825. * CALLED BY:
  1826. * IOCTL_VIDEO_SET_CURRENT_MODE packet of ATIMPStartIO()
  1827. *
  1828. * AUTHOR:
  1829. * Robert Wolff
  1830. *
  1831. * CHANGE HISTORY:
  1832. *
  1833. * TEST HISTORY:
  1834. *
  1835. ***************************************************************************/
  1836. #define BLOCK_WRITE_LENGTH 120
  1837. BOOL BlockWriteAvail_cx(struct query_structure *Query)
  1838. {
  1839. BOOL RetVal = TRUE;
  1840. ULONG ColourMask; /* Mask off unneeded bits of Colour */
  1841. ULONG Colour; /* Colour to use in testing */
  1842. USHORT Width, excess = 8; /* Width of test block */
  1843. USHORT Column; /* Column being checked */
  1844. ULONG ScreenPitch; /* Pitch in units of 8 pixels */
  1845. ULONG PixelDepth; /* Colour depth of screen */
  1846. ULONG HorScissors; /* Horizontal scissor values */
  1847. PULONG FrameAddress; /* Pointer to base of LFB */
  1848. PULONG ReadPointer; /* Used in reading test block */
  1849. ULONG DstOffPitch; /* Saved contents of DST_OFF_PITCH register */
  1850. #if defined (PPC)
  1851. /*
  1852. * Block write does not work properly on the power PC. Under some
  1853. * circumstances, we will detect that the card is capable of using
  1854. * block write mode, but it will hang the machine when used for
  1855. * a large block (our test is for a small block).
  1856. */
  1857. VideoDebugPrint((DEBUG_DETAIL, "Can't do block write on a PPC\n"));
  1858. return FALSE;
  1859. #else
  1860. /*
  1861. * Our block write test involves an engine draw followed by
  1862. * a read back through the linear framebuffer. If the linear
  1863. * framebuffer is unavailable, assume that we can't do block
  1864. * write, since all our cards are able to function without
  1865. * block write.
  1866. */
  1867. if (!(Query->q_aperture_cfg))
  1868. {
  1869. VideoDebugPrint((DEBUG_DETAIL, "LFB unavailable, can't do block write check\n"));
  1870. return FALSE;
  1871. }
  1872. /*
  1873. * Mach 64 ASICs prior to revision D have a hardware bug that does
  1874. * not allow transparent block writes (special handling is required
  1875. * that in some cases can cut performance).
  1876. */
  1877. if ((INPD(CONFIG_CHIP_ID) & CONFIG_CHIP_ID_RevMask) < CONFIG_CHIP_ID_RevD)
  1878. {
  1879. VideoDebugPrint((DEBUG_DETAIL, "ASIC/memory combination doesn't allow block write\n"));
  1880. return FALSE;
  1881. }
  1882. /*
  1883. * Block write is only available on "special VRAM" cards.
  1884. */
  1885. if (Query->q_memory_type != VMEM_VRAM_256Kx4_SPLIT512
  1886. && Query->q_memory_type != VMEM_VRAM_256Kx16_SPLIT256)
  1887. {
  1888. VideoDebugPrint((DEBUG_DETAIL, "*** No block write - wrong RAM type\n" ));
  1889. return FALSE;
  1890. }
  1891. /*
  1892. * Special case: block write doesn't work properly on the
  1893. * GX rev. E with IBM RAM.
  1894. */
  1895. if ((INPD(CONFIG_CHIP_ID) == (CONFIG_CHIP_ID_GXRevE)) &&
  1896. (Query->q_memory_type == VMEM_VRAM_256Kx16_SPLIT256))
  1897. {
  1898. VideoDebugPrint((DEBUG_DETAIL, "*** No block write - GX/E with IBM RAM\n"));
  1899. return FALSE;
  1900. }
  1901. /*
  1902. * Use a 480 byte test block. This size will fit on a single line
  1903. * even at the lowest resolution (640x480) and pixel depth supported
  1904. * by the display driver (8BPP), and is divisible by all the supported
  1905. * pixel depths. Get the depth-specific values for the pixel depth we
  1906. * are using.
  1907. *
  1908. * True 24BPP acceleration is not available, so 24BPP is actually
  1909. * handled as an 8BPP engine mode with a width 3 times the display
  1910. * width.
  1911. */
  1912. switch(Query->q_pix_depth)
  1913. {
  1914. case 4:
  1915. ColourMask = 0x0000000F;
  1916. Width = BLOCK_WRITE_LENGTH*8;
  1917. ScreenPitch = Query->q_screen_pitch / 8;
  1918. PixelDepth = BIOS_DEPTH_4BPP;
  1919. HorScissors = (Query->q_desire_x) << 16;
  1920. break;
  1921. case 8:
  1922. ColourMask = 0x000000FF;
  1923. Width = BLOCK_WRITE_LENGTH*4;
  1924. ScreenPitch = Query->q_screen_pitch / 8;
  1925. PixelDepth = BIOS_DEPTH_8BPP;
  1926. HorScissors = (Query->q_desire_x) << 16;
  1927. break;
  1928. case 16:
  1929. ColourMask = 0x0000FFFF;
  1930. Width = BLOCK_WRITE_LENGTH*2;
  1931. ScreenPitch = Query->q_screen_pitch / 8;
  1932. PixelDepth = BIOS_DEPTH_16BPP_565;
  1933. HorScissors = (Query->q_desire_x) << 16;
  1934. break;
  1935. case 24:
  1936. ColourMask = 0x000000FF;
  1937. Width = BLOCK_WRITE_LENGTH*4;
  1938. ScreenPitch = (Query->q_screen_pitch * 3) / 8;
  1939. PixelDepth = BIOS_DEPTH_8BPP;
  1940. /*
  1941. * Horizontal scissors are only valid in the range
  1942. * -4096 to +4095. If the horizontal resolution
  1943. * is high enough to put the scissor outside this
  1944. * range, clamp the scissors to the maximum
  1945. * permitted value.
  1946. */
  1947. HorScissors = Query->q_desire_x * 3;
  1948. if (HorScissors > 4095)
  1949. HorScissors = 4095;
  1950. HorScissors <<= 16;
  1951. break;
  1952. case 32:
  1953. ColourMask = 0xFFFFFFFF;
  1954. Width = BLOCK_WRITE_LENGTH;
  1955. ScreenPitch = Query->q_screen_pitch / 8;
  1956. PixelDepth = BIOS_DEPTH_32BPP;
  1957. HorScissors = (Query->q_desire_x) << 16;
  1958. break;
  1959. default:
  1960. return FALSE; /* Unsupported pixel depths */
  1961. }
  1962. /*
  1963. * Get a pointer to the beginning of the framebuffer. If we
  1964. * can't do this, assume block write is unavailable.
  1965. */
  1966. if ((FrameAddress = MapFramebuffer(phwDeviceExtension->PhysicalFrameAddress.LowPart,
  1967. phwDeviceExtension->FrameLength)) == (PVOID) 0)
  1968. {
  1969. VideoDebugPrint((DEBUG_ERROR, "Couldn't map LFB - assuming no block write\n"));
  1970. return FALSE;
  1971. }
  1972. /*
  1973. * To use block write mode, the pixel widths for destination,
  1974. * source, and host must be the same.
  1975. */
  1976. PixelDepth |= ((PixelDepth << 8) | (PixelDepth << 16));
  1977. /*
  1978. * Save the contents of the DST_OFF_PITCH register.
  1979. */
  1980. DstOffPitch = INPD(DST_OFF_PITCH);
  1981. /*
  1982. * Clear the block we will be testing.
  1983. */
  1984. CheckFIFOSpace_cx(ELEVEN_WORDS);
  1985. OUTPD(DP_WRITE_MASK, 0xFFFFFFFF);
  1986. OUTPD(DST_OFF_PITCH, ScreenPitch << 22);
  1987. OUTPD(DST_CNTL, (DST_CNTL_XDir | DST_CNTL_YDir));
  1988. OUTPD(DP_PIX_WIDTH, PixelDepth);
  1989. OUTPD(DP_SRC, (DP_FRGD_SRC_FG | DP_BKGD_SRC_BG | DP_MONO_SRC_ONE));
  1990. OUTPD(DP_MIX, ((MIX_FN_PAINT << 16) | MIX_FN_PAINT));
  1991. OUTPD(DP_FRGD_CLR, 0);
  1992. OUTPD(SC_LEFT_RIGHT, HorScissors);
  1993. OUTPD(SC_TOP_BOTTOM, (Query->q_desire_y) << 16);
  1994. OUTPD(DST_Y_X, 0);
  1995. OUTPD(DST_HEIGHT_WIDTH, ((Width+excess) << 16) | 1);
  1996. WaitForIdle_cx();
  1997. /*
  1998. * To test block write mode, try painting each of the alternating bit
  1999. * patterns, then read the block back. If there is at least one
  2000. * mismatch, then block write is not supported.
  2001. */
  2002. for (Colour = 0x55555555; Colour <= 0xAAAAAAAA; Colour += 0x55555555)
  2003. {
  2004. /*
  2005. * Paint the block.
  2006. */
  2007. CheckFIFOSpace_cx(FIVE_WORDS);
  2008. OUTPD(GEN_TEST_CNTL, (INPD(GEN_TEST_CNTL) | GEN_TEST_CNTL_BlkWrtEna));
  2009. OUTPD(DP_MIX, ((MIX_FN_PAINT << 16) | MIX_FN_LEAVE_ALONE));
  2010. OUTPD(DP_FRGD_CLR, (Colour & ColourMask));
  2011. OUTPD(DST_Y_X, 0);
  2012. OUTPD(DST_HEIGHT_WIDTH, (Width << 16) | 1);
  2013. WaitForIdle_cx();
  2014. /*
  2015. * Check to see if the block was written properly. Mach 64 cards
  2016. * can't do a screen to host blit, but we can read the test block
  2017. * back through the aperture.
  2018. */
  2019. ReadPointer = FrameAddress;
  2020. for (Column = 0; Column < BLOCK_WRITE_LENGTH; Column++)
  2021. {
  2022. if (VideoPortReadRegisterUlong(ReadPointer + Column) != Colour)
  2023. {
  2024. VideoDebugPrint((DEBUG_NORMAL, "*** No block write - bad pattern\n" ));
  2025. RetVal = FALSE;
  2026. break;
  2027. }
  2028. }
  2029. /*
  2030. * Check the next dword beyond the block.
  2031. */
  2032. if (VideoPortReadRegisterUlong(ReadPointer + BLOCK_WRITE_LENGTH) != 0)
  2033. {
  2034. VideoDebugPrint((DEBUG_NORMAL, "*** No block write - corruption\n" ));
  2035. RetVal = FALSE;
  2036. }
  2037. }
  2038. /*
  2039. * If block write is unavailable, turn off the block write bit.
  2040. */
  2041. if (RetVal == FALSE)
  2042. OUTPD(GEN_TEST_CNTL, (INPD(GEN_TEST_CNTL) & ~GEN_TEST_CNTL_BlkWrtEna));
  2043. /*
  2044. * Restore the contents of the DST_OFF_PITCH register.
  2045. */
  2046. OUTPD(DST_OFF_PITCH, DstOffPitch);
  2047. /*
  2048. * Free the pointer to the start of the framebuffer.
  2049. */
  2050. VideoPortFreeDeviceBase(phwDeviceExtension, FrameAddress);
  2051. return RetVal;
  2052. #endif /* Not Power PC */
  2053. } /* BlockWriteAvail_cx() */
  2054. /***************************************************************************
  2055. *
  2056. * BOOL TextBanding_cx(Query);
  2057. *
  2058. * struct query_structure *Query; Query information for the card
  2059. *
  2060. * DESCRIPTION:
  2061. * Test to see whether the current mode is susceptible to text
  2062. * banding. This function assumes that the card has been set to
  2063. * an accelerated mode.
  2064. *
  2065. * RETURN VALUE:
  2066. * TRUE if this mode is susceptible to text banding
  2067. * FALSE if it is immune to text banding
  2068. *
  2069. * GLOBALS CHANGED:
  2070. * None
  2071. *
  2072. * CALLED BY:
  2073. * IOCTL_VIDEO_ATI_GET_MODE_INFORMATION packet of ATIMPStartIO()
  2074. *
  2075. * AUTHOR:
  2076. * Robert Wolff
  2077. *
  2078. * CHANGE HISTORY:
  2079. *
  2080. * TEST HISTORY:
  2081. *
  2082. ***************************************************************************/
  2083. BOOL TextBanding_cx(struct query_structure *Query)
  2084. {
  2085. DWORD ConfigChipId;
  2086. ConfigChipId = INPD(CONFIG_CHIP_ID);
  2087. /*
  2088. * Text banding only occurs in 24BPP with the Mach 64
  2089. * GX rev. E & rev. F ASICs.
  2090. */
  2091. if ((Query->q_pix_depth == 24) &&
  2092. ((ConfigChipId == (CONFIG_CHIP_ID_GXRevE)) || (ConfigChipId == (CONFIG_CHIP_ID_GXRevF))))
  2093. {
  2094. return TRUE;
  2095. }
  2096. else
  2097. {
  2098. return FALSE;
  2099. }
  2100. } /* TextBanding_cx() */
  2101. /***************************************************************************
  2102. *
  2103. * PWSTR IdentifyMach64Asic(Query, AsicStringLength);
  2104. *
  2105. * struct query_structure *Query; Query information for the card
  2106. * PULONG AsicStringLength; Length of ASIC identification string
  2107. *
  2108. * DESCRIPTION:
  2109. * Generate a string describing which Mach 64 ASIC is in use on
  2110. * this particular card.
  2111. *
  2112. * RETURN VALUE:
  2113. * Pointer to a string identifying which Mach 64 ASIC is present. The
  2114. * length of this string is returned in *AsicStringLength.
  2115. *
  2116. * GLOBALS CHANGED:
  2117. * None
  2118. *
  2119. * CALLED BY:
  2120. * FillInRegistry()
  2121. *
  2122. * AUTHOR:
  2123. * Robert Wolff
  2124. *
  2125. * CHANGE HISTORY:
  2126. *
  2127. * TEST HISTORY:
  2128. *
  2129. ***************************************************************************/
  2130. PWSTR IdentifyMach64Asic(struct query_structure *Query, PULONG AsicStringLength)
  2131. {
  2132. PWSTR ChipString; /* Identification string for the ASIC in use */
  2133. DWORD ConfigChipId; /* Contents of chip identification register */
  2134. ConfigChipId = INPD(CONFIG_CHIP_ID);
  2135. if (Query->q_DAC_type == DAC_INTERNAL_CT)
  2136. {
  2137. ChipString = L"Mach 64 CT";
  2138. *AsicStringLength = sizeof(L"Mach 64 CT");
  2139. }
  2140. else if (Query->q_DAC_type == DAC_INTERNAL_GT)
  2141. {
  2142. ChipString = L"ATI 3D RAGE (GT-A)";
  2143. *AsicStringLength = sizeof(L"ATI 3D RAGE (GT-A)");
  2144. }
  2145. else if (Query->q_DAC_type == DAC_INTERNAL_VT)
  2146. { switch (ConfigChipId & CONFIG_CHIP_ID_RevMask)
  2147. {
  2148. case ASIC_ID_SGS_VT_A4:
  2149. ChipString = L"ATI mach64 (SGS VT-A4)";
  2150. *AsicStringLength = sizeof(L"ATI mach64 (SGS VT-A4)");
  2151. break;
  2152. case ASIC_ID_NEC_VT_A4:
  2153. ChipString = L"ATI mach64 (NEC VT-A4)";
  2154. *AsicStringLength = sizeof(L"ATI mach64 (NEC VT-A4)");
  2155. break;
  2156. case ASIC_ID_NEC_VT_A3:
  2157. ChipString = L"ATI mach64 (NEC VT-A3)";
  2158. *AsicStringLength = sizeof(L"ATI mach64 (NEC VT-A3)");
  2159. break;
  2160. default:
  2161. ChipString = L"ATI 3D RAGE (VT-A) Internal DAC";
  2162. *AsicStringLength = sizeof(L"ATI 3D RAGE (VT-A) Internal DAC");
  2163. //ChipString = L"ATI mach64 (VT-A)";
  2164. //*AsicStringLength = sizeof(L"ATI mach64 (VT-A)");
  2165. break;
  2166. }
  2167. }
  2168. else if ((ConfigChipId & CONFIG_CHIP_ID_TypeMask) == CONFIG_CHIP_ID_TypeCX)
  2169. {
  2170. ChipString = L"Mach 64 CX";
  2171. *AsicStringLength = sizeof(L"Mach 64 CX");
  2172. }
  2173. else if ((ConfigChipId & CONFIG_CHIP_ID_TypeMask) == CONFIG_CHIP_ID_TypeGX)
  2174. {
  2175. switch(ConfigChipId & CONFIG_CHIP_ID_RevMask)
  2176. {
  2177. case CONFIG_CHIP_ID_RevC:
  2178. ChipString = L"Mach 64 GX Rev. C";
  2179. *AsicStringLength = sizeof(L"Mach 64 GX Rev. C");
  2180. break;
  2181. case CONFIG_CHIP_ID_RevD:
  2182. ChipString = L"Mach 64 GX Rev. D";
  2183. *AsicStringLength = sizeof(L"Mach 64 GX Rev. D");
  2184. break;
  2185. case CONFIG_CHIP_ID_RevE:
  2186. ChipString = L"Mach 64 GX Rev. E";
  2187. *AsicStringLength = sizeof(L"Mach 64 GX Rev. E");
  2188. break;
  2189. case CONFIG_CHIP_ID_RevF:
  2190. ChipString = L"Mach 64 GX Rev. F";
  2191. *AsicStringLength = sizeof(L"Mach 64 GX Rev. F");
  2192. break;
  2193. default:
  2194. ChipString = L"Mach 64 GX";
  2195. *AsicStringLength = sizeof(L"Mach 64 GX");
  2196. break;
  2197. }
  2198. }
  2199. else
  2200. {
  2201. ChipString = L"Miscellaneous Mach 64";
  2202. *AsicStringLength = sizeof(L"Miscelaneous Mach 64");
  2203. }
  2204. return ChipString;
  2205. } /* IdentifyMach64Asic() */
  2206. /***************************************************************************
  2207. *
  2208. * void CleanupQuery(CapBuffer, SupBuffer, MappedBuffer, BufferSeg, SavedScreen);
  2209. *
  2210. * PUCHAR CapBuffer; Pointer to the main capabilities table
  2211. * for the card
  2212. * PUCHAR SupBuffer; Pointer to the supplementary capabilities
  2213. * table for the card
  2214. * PUCHAR MappedBuffer; Pointer to the buffer used to query the
  2215. * card's capabilities
  2216. * long BufferSeg; Physical segment associated with MappedBuffer
  2217. * PUCHAR SavedScreen; Buffer containing data to be restored to the
  2218. * memory region used to store the query data.
  2219. * Depending on the buffer used, this data may
  2220. * or may not need to be restored.
  2221. *
  2222. * DESCRIPTION:
  2223. * Clean up after we have finished querying the card by restoring
  2224. * the VGA screen if needed, then freeing the buffers we used to query
  2225. * the card. We only need to restore the VGA screen if we used the
  2226. * graphics screen (either write back the information we saved if we
  2227. * used the existing screen, or switch into text mode if we had to
  2228. * switch into graphics mode) since we use the offscreen portion of
  2229. * video memory in cases where we use the text screen.
  2230. *
  2231. *
  2232. * GLOBALS CHANGED:
  2233. * None
  2234. *
  2235. * CALLED BY:
  2236. * QueryMach64()
  2237. *
  2238. * AUTHOR:
  2239. * Robert Wolff
  2240. *
  2241. * CHANGE HISTORY:
  2242. *
  2243. * TEST HISTORY:
  2244. *
  2245. ***************************************************************************/
  2246. static void CleanupQuery(PUCHAR CapBuffer, PUCHAR SupBuffer, PUCHAR MappedBuffer, long BufferSeg, PUCHAR SavedScreen)
  2247. {
  2248. VIDEO_X86_BIOS_ARGUMENTS Registers; /* Used in VideoPortInt10() calls */
  2249. ULONG CurrentByte; /* Buffer byte being restored */
  2250. ULONG BytesToRestore; /* Number of bytes of graphics screen to restore */
  2251. /*
  2252. * BufferSeg will be 0xBA00 if we stored our query information on
  2253. * the VGA colour text screen, 0xB200 if we used the VGA mono text
  2254. * screen, 0xA000 if we switched into accelerator mode withoug
  2255. * disturbing the VGA controller, and 0xA100 if we forced a VGA
  2256. * graphics mode in order to use the VGA graphics screen.
  2257. *
  2258. * Since we use the offscreen portion of the text screens, which
  2259. * leaves the information displayed on boot undisturbed, it is not
  2260. * only unnecessary but also undesirable (since this would destroy pre-
  2261. * query information printed to the blue screen) to change modes.
  2262. * If we used the existing graphics screen, we merely need to restore
  2263. * the screen contents and the registers we changed. If we changed
  2264. * into a graphics mode, the pre-query information has already been
  2265. * lost when changed modes, but switching back to text mode should
  2266. * allow the user to see information that is printed after our query
  2267. * is complete (not guarranteed, since we will only need to do this
  2268. * on extremely ill-behaved systems, which may have been using something
  2269. * other than a standard VGA text screen as the blue screen).
  2270. */
  2271. if (BufferSeg == 0xA000)
  2272. {
  2273. BytesToRestore = SavedScreen[VGA_SAVE_SIZE_H];
  2274. BytesToRestore <<= 8;
  2275. BytesToRestore += SavedScreen[VGA_SAVE_SIZE];
  2276. VideoDebugPrint((DEBUG_NORMAL, "Restoring %d bytes of the VGA graphics screen\n", BytesToRestore));
  2277. for (CurrentByte = 0; CurrentByte < BytesToRestore; CurrentByte++)
  2278. {
  2279. VideoPortWriteRegisterUchar(&(MappedBuffer[CurrentByte]), SavedScreen[CurrentByte]);
  2280. }
  2281. OUTP(VGA_SEQ_IND, 2);
  2282. OUTP(VGA_SEQ_DATA, SavedScreen[VGA_SAVE_SEQ02]);
  2283. OUTP(VGA_GRAX_IND, 8);
  2284. OUTP(VGA_GRAX_DATA, SavedScreen[VGA_SAVE_GRA08]);
  2285. OUTP(VGA_GRAX_IND, 1);
  2286. OUTP(VGA_GRAX_DATA, SavedScreen[VGA_SAVE_GRA01]);
  2287. }
  2288. else if (BufferSeg == 0xA100)
  2289. {
  2290. VideoDebugPrint((DEBUG_NORMAL, "Switching back to VGA text mode\n"));
  2291. VideoPortZeroMemory(&Registers, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  2292. Registers.Eax = 3;
  2293. VideoPortInt10(phwDeviceExtension, &Registers);
  2294. }
  2295. /*
  2296. * For each of the three buffers, free it if it exists.
  2297. */
  2298. if (CapBuffer != 0)
  2299. VideoPortFreeDeviceBase(phwDeviceExtension, CapBuffer);
  2300. if (SupBuffer != 0)
  2301. VideoPortFreeDeviceBase(phwDeviceExtension, SupBuffer);
  2302. if (MappedBuffer != 0)
  2303. VideoPortFreeDeviceBase(phwDeviceExtension, MappedBuffer);
  2304. return;
  2305. } /* CleanupQuery() */
  2306. #if defined(ALPHA)
  2307. /***************************************************************************
  2308. *
  2309. * BOOL DenseOnAlpha(Query);
  2310. *
  2311. * struct query_structure *Query; Query information for the card
  2312. *
  2313. * DESCRIPTION:
  2314. * Reports whether or not we can use dense space on this card
  2315. * in a DEC Alpha.
  2316. *
  2317. * RETURN VALUE:
  2318. * TRUE if this card can use dense space
  2319. * FALSE if it can't
  2320. *
  2321. * GLOBALS CHANGED:
  2322. * None
  2323. *
  2324. * CALLED BY:
  2325. * Any routine after the query structure is filled in.
  2326. *
  2327. * AUTHOR:
  2328. * Robert Wolff
  2329. *
  2330. * CHANGE HISTORY:
  2331. *
  2332. * TEST HISTORY:
  2333. *
  2334. ***************************************************************************/
  2335. BOOL DenseOnAlpha(struct query_structure *Query)
  2336. {
  2337. /*
  2338. * Some older Alpha machines are unable to support dense space,
  2339. * so these must be mapped as sparse. The easiest way to distinguish
  2340. * dense-capable from older machines is that all PCI Alpha systems
  2341. * are dense-capable, so if we are dealing with a PCI card the
  2342. * machine must be capable of handling dense space.
  2343. *
  2344. * Our older cards will generate drawing bugs if GDI handles
  2345. * the screen in dense mode (we made different assumptions from
  2346. * DEC about the PCI interface), so only use dense space for
  2347. * cards which will not have this problem.
  2348. */
  2349. if ((Query->q_bus_type == BUS_PCI) &&
  2350. ((Query->q_DAC_type == DAC_INTERNAL_CT) ||
  2351. (Query->q_DAC_type == DAC_INTERNAL_GT) ||
  2352. (Query->q_DAC_type == DAC_INTERNAL_VT)))
  2353. return TRUE;
  2354. else
  2355. return FALSE;
  2356. } /* DenseOnAlpha() */
  2357. #endif