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.

3474 lines
126 KiB

  1. /************************************************************************/
  2. /* */
  3. /* QUERY_M.C */
  4. /* */
  5. /* Copyright (c) 1992, ATI Technologies Incorporated. */
  6. /************************************************************************/
  7. /********************** PolyTron RCS Utilities
  8. $Revision: 1.24 $
  9. $Date: 01 May 1996 14:11:40 $
  10. $Author: RWolff $
  11. $Log: S:/source/wnt/ms11/miniport/archive/query_m.c_v $
  12. *
  13. * Rev 1.24 01 May 1996 14:11:40 RWolff
  14. * Locked out 24BPP on Alpha.
  15. *
  16. * Rev 1.23 23 Apr 1996 17:27:24 RWolff
  17. * Expanded lockout of 800x600 16BPP 72Hz to all Mach 32 cards, since
  18. * some VRAM cards are also affected.
  19. *
  20. * Rev 1.22 12 Apr 1996 16:16:36 RWolff
  21. * Now rejects 24BPP modes if linear aperture is not present, since new
  22. * source stream display driver can't do 24BPP in a paged aperture. This
  23. * rejection should be done in the display driver (the card still supports
  24. * the mode, but the display driver doesn't want to handle it), but at
  25. * the point where the display driver must decide to either accept or reject
  26. * modes, it doesn't have access to the aperture information.
  27. *
  28. * Rev 1.21 10 Apr 1996 17:02:04 RWolff
  29. * Locked out 800x600 16BPP 72Hz on DRAM cards, fix for checking
  30. * resolution-dependent special cases against a value which is
  31. * only set if the mode is installed.
  32. *
  33. *
  34. * Rev 1.20 23 Jan 1996 11:48:12 RWolff
  35. * Eliminated level 3 warnings, protected against false values of
  36. * TARGET_BUILD, added debug print statements, now assumes DEC Alpha
  37. * has a 2M card since the memory size check routine generates a
  38. * false value (4M) on this platform.
  39. *
  40. * Rev 1.19 11 Jan 1996 19:37:10 RWolff
  41. * Added maximum pixel clock rate to all calls to SetFixedModes().
  42. * This is required as part of a Mach 64 fix.
  43. *
  44. * Rev 1.18 20 Jul 1995 17:58:56 mgrubac
  45. * Added support for VDIF files.
  46. *
  47. * Rev 1.17 31 Mar 1995 11:52:36 RWOLFF
  48. * Changed from all-or-nothing debug print statements to thresholds
  49. * depending on importance of the message.
  50. *
  51. * Rev 1.16 14 Mar 1995 15:59:58 ASHANMUG
  52. * Check wait for idle status before continuing block write test.
  53. * This fixes an Intel AX problem where the engine was hanging.
  54. *
  55. * Rev 1.15 23 Dec 1994 10:47:42 ASHANMUG
  56. * ALPHA/Chrontel-DAC
  57. *
  58. * Rev 1.14 18 Nov 1994 11:44:22 RWOLFF
  59. * Now detects STG1702/1703 DACs in native mode, added support for
  60. * split rasters.
  61. *
  62. * Rev 1.13 19 Aug 1994 17:13:16 RWOLFF
  63. * Added support for SC15026 DAC, Graphics Wonder, non-standard pixel
  64. * clock generators, and 1280x1024 70Hz and 74Hz.
  65. *
  66. * Rev 1.12 22 Jul 1994 17:48:24 RWOLFF
  67. * Merged with Richard's non-x86 code stream.
  68. *
  69. * Rev 1.11 30 Jun 1994 18:21:06 RWOLFF
  70. * Removed routine IsApertureConflict_m() (moved to SETUP_M.C), no longer
  71. * enables aperture while querying the card (aperture is now enabled in
  72. * IsApertureConflict_m() after we find that there is no conflict).
  73. *
  74. * Rev 1.10 15 Jun 1994 11:08:34 RWOLFF
  75. * Now lists block write as unavailable on DRAM cards, gives correct
  76. * vertical resolution if CRT parameters are stored in skip-1-2 format
  77. * (as is the case on some Graphics Ultra cards which were upgraded from
  78. * 512k to 1M) instead of the normal skip-2 format.
  79. *
  80. * Rev 1.9 20 May 1994 19:19:38 RWOLFF
  81. * No longer inserts phantom 16BPP mode table for resolutions where
  82. * 16BPP can be supported but which are not configured.
  83. *
  84. * Rev 1.8 20 May 1994 16:08:44 RWOLFF
  85. * Fix for 800x600 screen tearing on Intel BATMAN PCI motherboards.
  86. *
  87. * Rev 1.7 20 May 1994 14:02:58 RWOLFF
  88. * Ajith's change: no longer falsely detects NCR dual Pentium MCA card
  89. * as being susceptible to MIO bug.
  90. *
  91. * Rev 1.6 12 May 1994 11:17:44 RWOLFF
  92. * For Mach 32, now lists predefined refresh rates as available instead of
  93. * only the refresh rate stored in EEPROM, no longer makes 1024x768 87Hz
  94. * interlaced available if no 1024x768 mode configured, since the predefined
  95. * rates will allow all resolutions even on uninstalled cards.
  96. * For all cards, writes refresh rate to mode tables.
  97. *
  98. * Rev 1.5 27 Apr 1994 13:56:30 RWOLFF
  99. * Added routine IsMioBug_m() which checks to see if card has multiple
  100. * input/output bug.
  101. *
  102. * Rev 1.4 26 Apr 1994 12:43:44 RWOLFF
  103. * Put back use of 1024x768 interlaced when no 1024 resolution installed,
  104. * no longer uses 32BPP.
  105. *
  106. * Rev 1.3 31 Mar 1994 15:07:16 RWOLFF
  107. * Added debugging code.
  108. *
  109. * Rev 1.2 08 Feb 1994 19:01:32 RWOLFF
  110. * Removed unused routine get_num_modes_m(), no longer makes 1024x768 87Hz
  111. * interlaced available if Mach 32 card is configured with 1024x768
  112. * set to "Not installed".
  113. *
  114. * Rev 1.1 07 Feb 1994 14:03:26 RWOLFF
  115. * Added alloc_text() pragmas to allow miniport to be swapped out when
  116. * not needed, removed routine GetMemoryNeeded_m() which was only called
  117. * by LookForSubstitute(), a routine removed from ATIMP.C.
  118. *
  119. * Rev 1.0 31 Jan 1994 11:12:34 RWOLFF
  120. * Initial revision.
  121. *
  122. * Rev 1.7 24 Jan 1994 18:08:16 RWOLFF
  123. * Now fills in 16 and 24 BPP mode tables for BT48x and AT&T 49[123] DACs
  124. * using dedicated (and undocumented) mode tables in the EEPROM rather
  125. * than expecting the mode set routine to multiply the pixel clock from
  126. * the 8BPP mode tables.
  127. *
  128. * Rev 1.6 14 Jan 1994 15:25:32 RWOLFF
  129. * Uses defined values for bus types, added routine to see if block write
  130. * mode is available.
  131. *
  132. * Rev 1.5 15 Dec 1993 15:28:14 RWOLFF
  133. * Added support for SC15021 DAC, hardcoded aperture location for
  134. * DEC ALPHA (BIOS can't initialize the registers).
  135. *
  136. * Rev 1.4 30 Nov 1993 18:28:44 RWOLFF
  137. * Added support for AT&T 498 DAC, removed dead code.
  138. *
  139. * Rev 1.3 10 Nov 1993 19:26:00 RWOLFF
  140. * GetTrueMemSize_m() now handles 1M cards correctly, doesn't depend on the
  141. * VGA aperture being available.
  142. *
  143. * Rev 1.2 05 Nov 1993 13:26:34 RWOLFF
  144. * Added support for PCI bus and STG1700 DAC.
  145. *
  146. * Rev 1.1 08 Oct 1993 11:13:40 RWOLFF
  147. * Added routine to get true amount of memory needed for a particular mode
  148. * on 8514/A-compatible ATI accelerators, and fix for BIOS bug that reports
  149. * less than the true amount of memory in MEM_SIZE_ALIAS field of MISC_OPTIONS.
  150. *
  151. * Rev 1.0 24 Sep 1993 11:52:28 RWOLFF
  152. * Initial revision.
  153. *
  154. * Rev 1.0 03 Sep 1993 14:24:08 RWOLFF
  155. * Initial revision.
  156. Rev 1.0 16 Aug 1993 13:28:54 Robert_Wolff
  157. Initial revision.
  158. Rev 1.31 06 Jul 1993 15:52:08 RWOLFF
  159. No longer sets mach32_split_fixup (support for non-production hardware).
  160. Rev 1.30 24 Jun 1993 16:18:18 RWOLFF
  161. Now inverts COMPOSITE_SYNC bit of m_clock_select field on Mach 8 cards,
  162. since the EEPROM holds the value to use when using the shadow sets and
  163. we use the primrary CRT register set. Now takes the proper byte of
  164. EEPROM word 0x13 when calculating the clock select for 1280x1024
  165. on an 8514/ULTRA.
  166. Rev 1.29 18 Jun 1993 16:09:40 RWOLFF
  167. Fix for 68800 Rev. 3 hardware problem (screen pitch must be a multiple of
  168. 128 pixels, but no symptoms exhibited except at high colour depths with
  169. fast pixel clock).
  170. Rev 1.28 10 Jun 1993 15:55:18 RWOLFF
  171. Now uses static buffer rather than dynamic allocation for CRT
  172. parameter read by BIOS function call.
  173. Change originated by Andre Vachon at Microsoft.
  174. Rev 1.27 07 Jun 1993 11:44:00 BRADES
  175. Rev 6 split transfer fixup.
  176. Rev 1.25 12 May 1993 16:33:42 RWOLFF
  177. Changed test order for aperture calculations to avoid trouble due to
  178. undefined bits being 1 instead of 0.
  179. Rev 1.24 10 May 1993 16:39:28 RWOLFF
  180. Now recognizes maximum pixel depth of each possible DAC at all supported
  181. resolutions rather than assuming that TI34075 can handle 32 BPP at all
  182. resolutions while all other DACs can do 16 BPP at all resolutions but
  183. can't do 24 BPP.
  184. Rev 1.23 30 Apr 1993 16:42:24 RWOLFF
  185. Buffer for CRT parameter read via BIOS call is now dynamically allocated.
  186. Rev 1.22 24 Apr 1993 16:32:24 RWOLFF
  187. Now recognizes that 800x600 8BPP is not available on Mach 8 cards with
  188. 512k of accelerator memory, Mach 32 ASIC revision number is now recorded
  189. as the value read from the "revision code" register rather than the chip
  190. revision (i.e. Rev. 3 chip is recorded as Rev. 0), no longer falls back to
  191. 56Hz in 800x600 16BPP on 1M Mach 32 cards.
  192. Rev 1.21 21 Apr 1993 17:33:38 RWOLFF
  193. Now uses AMACH.H instead of 68800.H/68801.H.
  194. Added include file for error definitions.
  195. Added function to fill in the CRT tables on a Mach 32 using the BIOS
  196. function call <video segment>:006C if extended BIOS functions are available.
  197. Rev 1.20 15 Apr 1993 13:35:58 BRADES
  198. will not report a mode if Mach32 and 1 Meg and 1280 res.
  199. add ASIC revision from register.
  200. Rev 1.19 25 Mar 1993 11:21:50 RWOLFF
  201. Brought a function header comment up to date, assumes that 1024x768
  202. 87Hz interlaced is available if no 1024x768 mode is configured,
  203. query functions return failure if no EEPROM is present. It is assumed
  204. that an absent EEPROM will produce a read value of 0xFFFF, and the
  205. check is made at the start of mode table filling so the remainder
  206. of the query structure will contain valid data in the fields our
  207. driver uses.
  208. Rev 1.18 21 Mar 1993 15:58:28 BRADES
  209. use 1024 pitch for Mach32 if using VGA aperture.
  210. Rev 1.17 16 Mar 1993 17:00:54 BRADES
  211. Set Pitch to 1024 on the Mach32 for 640 and 800 resolutions.
  212. Allows VGA bank mgr to function.
  213. Rev 1.16 15 Mar 1993 22:21:04 BRADES
  214. use m_screen_pitch for the # pixels per display line
  215. Rev 1.15 08 Mar 1993 19:30:10 BRADES
  216. clean up, submit to MS NT
  217. Rev 1.13 19 Jan 1993 09:35:38 Robert_Wolff
  218. Removed commented-out code.
  219. Rev 1.12 13 Jan 1993 13:46:16 Robert_Wolff
  220. Added support for the Corsair and other machines where the aperture
  221. location is not kept in the EEPROM.
  222. Rev 1.11 06 Jan 1993 11:06:04 Robert_Wolff
  223. Eliminated dead code and compile warnings.
  224. Rev 1.10 24 Dec 1992 14:38:02 Chris_Brady
  225. fix up warnings
  226. Rev 1.9 09 Dec 1992 10:28:48 Robert_Wolff
  227. Mach 8 information gathering routines now accept a parameter to
  228. indicate whether 1280x1024 mode table should be ignored. This is
  229. because on cards with an old BIOS which can't do 1280x1024, the
  230. same mode table is used for 132 column text mode, so if we don't
  231. ignore the mode table we'd generate a garbage entry in the query
  232. structure.
  233. Rev 1.8 02 Dec 1992 18:26:08 Robert_Wolff
  234. On a Mach32 card with 1M of memory and 800x600 installed for
  235. a noninterlaced mode with a vertical frequency other than 56Hz,
  236. force the mode table for 800x600 16 bits per pixel to use the
  237. parameters for the 56Hz (lowest vertical frequency available for
  238. 800x600) mode in the Programmer's Guide to the Mach 32 Registers.
  239. This is done because this hardware is unable to deliver video data
  240. fast enough to do 800x600 16 BPP in noninterlaced modes with a
  241. higher vertical frequency than 56Hz.
  242. Rev 1.7 27 Nov 1992 18:39:16 Chris_Brady
  243. update ASIC rev to 3.
  244. Rev 1.6 25 Nov 1992 09:37:58 Robert_Wolff
  245. Routine s_query() now accepts an extra parameter which tells it to
  246. check for modes available when VGA boundary is set to shared, rather
  247. than left at its current value. This is for use with programs that force
  248. the boundary to shared, so that they will have access to all modes.
  249. Rev 1.5 20 Nov 1992 16:01:52 Robert_Wolff
  250. Functions Query8514Ultra() and QueryGUltra() are now
  251. available to Windows NT driver.
  252. Rev 1.4 17 Nov 1992 17:16:18 Robert_Wolff
  253. Fixed gathering of CRT parameters for 68800 card with minimal
  254. install (EEPROM blank, then predefined monitor type selected).
  255. Rev 1.3 13 Nov 1992 17:10:20 Robert_Wolff
  256. Now includes 68801.H, which consists of the now-obsolete MACH8.H
  257. and elements moved from VIDFIND.H.
  258. Rev 1.2 12 Nov 1992 17:10:32 Robert_Wolff
  259. Same source file can now be used for both Windows NT driver and
  260. VIDEO.EXE test program. Code specific to one or the other is
  261. under conditional compilation.
  262. Rev 1.1 06 Nov 1992 19:04:28 Robert_Wolff
  263. Moved prototypes for routines to initialize DAC to specified pixel
  264. depths to VIDFIND.H.
  265. Rev 1.0 05 Nov 1992 14:03:40 Robert_Wolff
  266. Initial revision.
  267. Rev 1.4 15 Oct 1992 16:26:36 Robert_Wolff
  268. Now builds one mode table for each resolution/colour depth
  269. combination, rather than one for each resolution. Mode tables
  270. no longer trash memory beyond the query structure.
  271. Rev 1.3 01 Oct 1992 17:31:08 Robert_Wolff
  272. Routines get_num_modes() and s_query() now count only those modes
  273. which are available with the monitor selected in "Power on configuration"
  274. when the install program is run.
  275. Rev 1.2 01 Oct 1992 15:23:54 Robert_Wolff
  276. Now handles the case where EEPROM values are stored in VGA format
  277. rather than 8514 format, Mach 32 card with shared memory now reports
  278. VGA boundary as 0 rather than -256.
  279. Rev 1.1 09 Sep 1992 17:42:40 Chris_Brady
  280. CRTC table for Graphics Ultra NOT enabled if == 0xFFFF
  281. Rev 1.0 02 Sep 1992 12:12:26 Chris_Brady
  282. Initial revision.
  283. End of PolyTron RCS section *****************/
  284. #ifdef DOC
  285. QUERY_M.C - Functions to find out the configuration of 8514/A-compatible
  286. ATI accelerators.
  287. #endif
  288. #include <stdio.h>
  289. #include <stdlib.h>
  290. #include <string.h>
  291. #include "dderror.h"
  292. #include "miniport.h"
  293. #include "ntddvdeo.h"
  294. #include "video.h"
  295. #include "stdtyp.h"
  296. #include "amach.h"
  297. #include "amach1.h"
  298. #include "atimp.h"
  299. #include "atint.h"
  300. #include "cvtvga.h"
  301. #include "eeprom.h"
  302. #define INCLUDE_QUERY_M
  303. #include "modes_m.h"
  304. #include "query_m.h"
  305. #include "services.h"
  306. #include "setup_m.h"
  307. /*
  308. * String written to the aperture to see if we can read it back, and
  309. * its length (including the null terminator).
  310. */
  311. #define APERTURE_TEST "ATI"
  312. #define APERTURE_TEST_LEN 4
  313. //
  314. // HACK to remove call to exallocate pool
  315. //
  316. UCHAR gBiosRaw[QUERYSIZE];
  317. //----------------------------------------------------------------------
  318. // Local Prototyping statements
  319. static void short_query_m (struct query_structure *query, struct st_eeprom_data *ee);
  320. short fill_mode_table_m (WORD, struct st_mode_table *, struct st_eeprom_data *);
  321. BOOL BiosFillTable_m(short, PUCHAR, struct st_mode_table *, struct query_structure *);
  322. static UCHAR BrooktreeOrATT_m(void);
  323. static void ClrDacCmd_m(BOOL ReadIndex);
  324. static BOOL ChkATTDac_m(BYTE MaskVal);
  325. static UCHAR ThompsonOrATT_m(void);
  326. static UCHAR SierraOrThompson_m(void);
  327. short GetTrueMemSize_m(void);
  328. void SetupRestoreEngine_m(int DesiredStatus);
  329. USHORT ReadPixel_m(short XPos, short YPos);
  330. void WritePixel_m(short XPos, short YPos, short Colour);
  331. void SetupRestoreVGAPaging_m(int DesiredStatus);
  332. /*
  333. * Allow miniport to be swapped out when not needed.
  334. */
  335. #if defined (ALLOC_PRAGMA)
  336. #pragma alloc_text(PAGE_M, Query8514Ultra)
  337. #pragma alloc_text(PAGE_M, QueryGUltra)
  338. #pragma alloc_text(PAGE_M, short_query_m)
  339. #pragma alloc_text(PAGE_M, QueryMach32)
  340. #pragma alloc_text(PAGE_M, fill_mode_table_m)
  341. #pragma alloc_text(PAGE_M, BiosFillTable_m)
  342. #pragma alloc_text(PAGE_M, BrooktreeOrATT_m)
  343. #pragma alloc_text(PAGE_M, ChkATTDac_m)
  344. #pragma alloc_text(PAGE_M, ClrDacCmd_m)
  345. #pragma alloc_text(PAGE_M, ThompsonOrATT_m)
  346. #pragma alloc_text(PAGE_M, SierraOrThompson_m)
  347. #pragma alloc_text(PAGE_M, GetTrueMemSize_m)
  348. #pragma alloc_text(PAGE_M, SetupRestoreEngine_m)
  349. #pragma alloc_text(PAGE_M, ReadPixel_m)
  350. #pragma alloc_text(PAGE_M, WritePixel_m)
  351. #pragma alloc_text(PAGE_M, BlockWriteAvail_m)
  352. #pragma alloc_text(PAGE_M, IsMioBug_m)
  353. #endif
  354. //----------------------------------------------------------------------
  355. // Query8514Ultra
  356. //
  357. // Fill in the query structure with the eeprom and register info
  358. // for the 8514/Ultra adapters.
  359. //
  360. // Returns:
  361. // NO_ERROR if successful
  362. // ERROR_DEV_NOT_EXIST if unable to read EEPROM
  363. //
  364. VP_STATUS Query8514Ultra (struct query_structure *query)
  365. {
  366. // 8514/Ultra initially only supported 1024x768 and 640x480.
  367. // Later 800x600 and then 1280x1024 support was added.
  368. struct st_eeprom_data *ee = phwDeviceExtension->ee;
  369. BOOL is800, is1280;
  370. WORD jj, kk;
  371. struct st_mode_table *pmode; /* CRT table parameters */
  372. long MemAvail; /* Bytes of memory available for the accelerator */
  373. struct st_mode_table ThisRes; /* Mode table for the given resolution */
  374. query->q_structure_rev = 0;
  375. query->q_mode_offset = sizeof(struct query_structure);
  376. query->q_sizeof_mode = sizeof(struct st_mode_table);
  377. query->q_status_flags = 0; // will indicate resolutions
  378. query->q_mouse_cfg = 0; // no MOUSE
  379. query->q_DAC_type = DAC_ATI_68830; // one DAC type similar to 68830
  380. query->q_aperture_addr = 0; // no aperture address
  381. query->q_aperture_cfg = 0; // no aperture configuration
  382. query->q_asic_rev = CI_38800_1; // only one ASIC revision
  383. query->q_VGA_type = 0; // 8514_ONLY == no VGA ever installed
  384. query->q_VGA_boundary = 0; /* No VGA, so accelerator gets all the memory */
  385. kk = INPW (CONFIG_STATUS_1);
  386. query->q_memory_size = (kk & MEM_INSTALLED) ? VRAM_1mb : VRAM_512k;
  387. query->q_memory_type = (kk & DRAM_ENA) ? VMEM_DRAM_256Kx4 : VMEM_VRAM_256Kx4_SER512;
  388. if (kk & MC_BUS) // is microchannel bus
  389. query->q_bus_type = BUS_MC_16; // 16 bit bus
  390. else
  391. query->q_bus_type = kk & BUS_16 ? BUS_ISA_16 : BUS_ISA_8;
  392. /*
  393. * We don't use the q_monitor_alias field, so plug in a typical
  394. * value rather than reading it from the EEPROM, in case we are
  395. * dealing with a card that doesn't have an EEPROM.
  396. */
  397. query->q_monitor_alias = 0x0F;
  398. query->q_shadow_1 = 0; // do not know what to put here
  399. query->q_shadow_2 = 0;
  400. /*
  401. * Record the number of bytes available for the coprocessor, so we
  402. * can determine what pixel depths are available at which resolutions.
  403. */
  404. MemAvail = (query->q_memory_size == VRAM_1mb) ? ONE_MEG : HALF_MEG;
  405. /*
  406. * If the EEPROM is not present, we can't fill in the mode
  407. * tables. Return and let the user know that the mode tables
  408. * have not been filled in.
  409. */
  410. if (query->q_eeprom == FALSE)
  411. return ERROR_DEV_NOT_EXIST;
  412. /*
  413. * Fill in the mode tables. The mode tables are sorted in increasing
  414. * order of resolution, and in increasing order of pixel depth.
  415. * Ensure pmode is initialized to the END of query structure
  416. */
  417. pmode = (struct st_mode_table *) query;
  418. ((struct query_structure *) pmode)++;
  419. /*
  420. * Initially assume 640x480 4BPP.
  421. */
  422. query->q_number_modes = 1;
  423. query->q_status_flags |= VRES_640x480;
  424. ThisRes.control = 0x140; // no equal to 68800 CRT 0 entry
  425. ThisRes.m_reserved = 3; /* Put EEPROM base address here, shadow sets are combined */
  426. jj = (ee->EEread) (3); /* Composite and Vfifo */
  427. kk = (ee->EEread) (4); /* Clock select and divisor */
  428. ThisRes.m_clock_select = ((jj & 0x1F) << 8) | ((kk & 0x003F) << 2);
  429. ThisRes.ClockFreq = GetFrequency((BYTE)((ThisRes.m_clock_select & 0x007C) >> 2));
  430. /*
  431. * The COMPOSITE_SYNC bit of the m_clock_select field is set up
  432. * to handle composite sync with shadow sets. We use the primrary
  433. * CRT register set, so we must invert it.
  434. */
  435. ThisRes.m_clock_select ^= 0x1000;
  436. kk = (ee->EEread) (17); // H_total
  437. ThisRes.m_h_total = kk & 0xFF;
  438. kk = (ee->EEread) (16); // H_display
  439. ThisRes.m_h_disp = kk & 0xFF;
  440. ThisRes.m_x_size = (ThisRes.m_h_disp+1) * 8;
  441. ThisRes.m_screen_pitch = ThisRes.m_x_size;
  442. kk = (ee->EEread) (15); // H_sync_strt
  443. ThisRes.m_h_sync_strt = kk & 0xFF;
  444. kk = (ee->EEread) (14); // H_sync_width
  445. ThisRes.m_h_sync_wid = kk & 0xFF;
  446. kk = (ee->EEread) (7); // V_sync_width
  447. ThisRes.m_v_sync_wid = kk & 0xFF;
  448. kk = (ee->EEread) (6); // Display_cntl
  449. ThisRes.m_disp_cntl = kk & 0xFF;
  450. ThisRes.m_v_total = (ee->EEread) (13);
  451. ThisRes.m_v_disp = (ee->EEread) (11);
  452. ThisRes.m_y_size = (((ThisRes.m_v_disp >> 1) & 0xFFFC) | (ThisRes.m_v_disp & 0x03)) +1;
  453. ThisRes.m_v_sync_strt = (ee->EEread) (9);
  454. ThisRes.enabled = 0x80; // use stored values from eeprom
  455. ThisRes.m_status_flags = 0;
  456. ThisRes.m_h_overscan = 0; // not supported
  457. ThisRes.m_v_overscan = 0;
  458. ThisRes.m_overscan_8b = 0;
  459. ThisRes.m_overscan_gr = 0;
  460. ThisRes.m_vfifo_24 = 0;
  461. ThisRes.m_vfifo_16 = 0;
  462. ThisRes.Refresh = DEFAULT_REFRESH;
  463. /*
  464. * Copy the mode table we have just built into the 4 BPP
  465. * mode table, and fill in the pixel depth field.
  466. */
  467. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  468. pmode->m_pixel_depth = 4;
  469. pmode++;
  470. /*
  471. * We don't support 640x480 256 colour minimum mode, so 8BPP
  472. * is only available on 1M cards.
  473. */
  474. if (query->q_memory_size == VRAM_1mb)
  475. {
  476. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  477. pmode->m_pixel_depth = 8;
  478. pmode++;
  479. query->q_number_modes++;
  480. }
  481. /*
  482. * Look for more mode tables defined. Original 8514 did not define these
  483. * -- undefined if = 0xFFFF
  484. *
  485. * Some cards with a BIOS too early to support 1280x1024 use the
  486. * same mode table for 132 column text mode. On these cards,
  487. * query->q_ignore1280 will be TRUE when this function is called.
  488. */
  489. kk = (ee->EEread) (20); // are 800 and 1280 defined ??
  490. jj = kk & 0xFF00; // 1280 by 1024
  491. kk &= 0xFF; // 800 by 600
  492. if ((kk == 0) || (kk == 0xFF))
  493. is800 = FALSE;
  494. else
  495. is800 = TRUE;
  496. if ((jj == 0) || (jj == 0xFF00) || (query->q_ignore1280 == TRUE))
  497. is1280 = FALSE;
  498. else
  499. is1280 = TRUE;
  500. /*
  501. * If we support 800x600, fill in its mode tables. Both 4 and 8 BPP
  502. * can be handled by a 512k card.
  503. */
  504. if (is800)
  505. {
  506. query->q_status_flags |= VRES_800x600;
  507. ThisRes.control = 0x140; // no equal to 68800 CRT 0 entry
  508. ThisRes.m_reserved = 19; // shadow sets are combined
  509. jj = (ee->EEread) (19); // Composite and Vfifo
  510. kk = (ee->EEread) (20); // clock select and divisor
  511. ThisRes.m_clock_select = ((jj & 0x1F) << 8) | ((kk & 0x003F) << 2);
  512. ThisRes.m_clock_select ^= 0x1000;
  513. ThisRes.ClockFreq = GetFrequency((BYTE)((ThisRes.m_clock_select & 0x007C) >> 2));
  514. kk = (ee->EEread) (30); // H_total
  515. ThisRes.m_h_total = kk & 0xFF;
  516. kk = (ee->EEread) (29); // H_display
  517. ThisRes.m_h_disp = kk & 0xFF;
  518. ThisRes.m_x_size = (ThisRes.m_h_disp+1) * 8;
  519. // Mach8 must be a multiple of 128
  520. ThisRes.m_screen_pitch = 896;
  521. kk = (ee->EEread) (28); // H_sync_strt
  522. ThisRes.m_h_sync_strt = kk & 0xFF;
  523. kk = (ee->EEread) (27); // H_sync_width
  524. ThisRes.m_h_sync_wid = kk & 0xFF;
  525. kk = (ee->EEread) (23); // V_sync_width
  526. ThisRes.m_v_sync_wid = kk & 0xFF;
  527. kk = (ee->EEread) (22); // Display_cntl
  528. ThisRes.m_disp_cntl = kk & 0xFF;
  529. ThisRes.m_v_total = (ee->EEread) (26);
  530. ThisRes.m_v_disp = (ee->EEread) (25);
  531. ThisRes.m_y_size = (((ThisRes.m_v_disp >> 1) & 0xFFFC) | (ThisRes.m_v_disp & 0x03)) +1;
  532. ThisRes.m_v_sync_strt = (ee->EEread) (24);
  533. ThisRes.enabled = 0x80; // use stored values from eeprom
  534. ThisRes.m_status_flags = 0;
  535. ThisRes.m_h_overscan = 0; // not supported
  536. ThisRes.m_v_overscan = 0;
  537. ThisRes.m_overscan_8b = 0;
  538. ThisRes.m_overscan_gr = 0;
  539. ThisRes.m_vfifo_24 = 0;
  540. ThisRes.m_vfifo_16 = 0;
  541. ThisRes.Refresh = DEFAULT_REFRESH;
  542. /*
  543. * Copy the mode table we have just built into the 4 and 8 BPP
  544. * mode tables, and fill in the pixel depth field of each.
  545. */
  546. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  547. pmode->m_pixel_depth = 4;
  548. pmode++;
  549. query->q_number_modes++;
  550. /*
  551. * 800x600 8BPP needs 1M because it is actually 896x600
  552. * (screen pitch must be a multiple of 128).
  553. */
  554. if (MemAvail == ONE_MEG)
  555. {
  556. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  557. pmode->m_pixel_depth = 8;
  558. pmode++;
  559. query->q_number_modes++;
  560. }
  561. }
  562. /*
  563. * Take care of 1024x768, which is always supported (even though
  564. * a 512k card can only do 4 BPP).
  565. */
  566. query->q_status_flags |= VRES_1024x768;
  567. ThisRes.control = 0x140; // no equal to 68800 CRT 0 entry
  568. ThisRes.m_reserved = 3; /* Put EEPROM base address here, shadow sets are combined */
  569. ThisRes.enabled = 0x80; /* Use stored values from EEPROM */
  570. kk = (ee->EEread) (16); // H_display
  571. ThisRes.m_h_disp = (kk >> 8) & 0xFF;
  572. /*
  573. * An 8514/ULTRA configured for a monitor which does not support
  574. * 1024x768 will have the 640x480 parameters in the high-res
  575. * shadow set. Force the use of 1024x768 87Hz interlaced instead.
  576. */
  577. if (ThisRes.m_h_disp != 0x7F)
  578. {
  579. BookVgaTable(B1024F87, &ThisRes);
  580. ThisRes.m_screen_pitch = ThisRes.m_x_size;
  581. }
  582. else{
  583. /*
  584. * Configured for a monitor which supports 1024x768,
  585. * so use actual parameters.
  586. */
  587. jj = (ee->EEread) (3); /* Composite and Vfifo */
  588. kk = (ee->EEread) (4); /* Clock select and divisor */
  589. ThisRes.m_clock_select = (jj & 0x1F00) | ((kk & 0x3F00) >> 6);
  590. ThisRes.m_clock_select ^= 0x1000;
  591. ThisRes.ClockFreq = GetFrequency((BYTE)((ThisRes.m_clock_select & 0x007C) >> 2));
  592. kk = (ee->EEread) (17); // H_total
  593. ThisRes.m_h_total = (kk >> 8) & 0xFF;
  594. ThisRes.m_x_size = (ThisRes.m_h_disp+1) * 8;
  595. ThisRes.m_screen_pitch = ThisRes.m_x_size;
  596. kk = (ee->EEread) (15); // H_sync_strt
  597. ThisRes.m_h_sync_strt = (kk >> 8) & 0xFF;
  598. kk = (ee->EEread) (14); // H_sync_width
  599. ThisRes.m_h_sync_wid = (kk >> 8) & 0xFF;
  600. kk = (ee->EEread) (7); // V_sync_width
  601. ThisRes.m_v_sync_wid = (kk >> 8) & 0xFF;
  602. kk = (ee->EEread) (6); // Display_cntl
  603. ThisRes.m_disp_cntl = (kk >> 8) & 0xFF;
  604. ThisRes.m_v_total = (ee->EEread) (12);
  605. ThisRes.m_v_disp = (ee->EEread) (10);
  606. ThisRes.m_y_size = (((ThisRes.m_v_disp >> 1) & 0xFFFC) | (ThisRes.m_v_disp & 0x03)) +1;
  607. ThisRes.m_v_sync_strt = (ee->EEread) (8);
  608. ThisRes.m_status_flags = 0;
  609. ThisRes.m_h_overscan = 0; // not supported
  610. ThisRes.m_v_overscan = 0;
  611. ThisRes.m_overscan_8b = 0;
  612. ThisRes.m_overscan_gr = 0;
  613. ThisRes.m_vfifo_24 = 0;
  614. ThisRes.m_vfifo_16 = 0;
  615. }
  616. ThisRes.Refresh = DEFAULT_REFRESH;
  617. /*
  618. * Copy the mode table we have just built into the 4 and 8 BPP
  619. * mode tables.
  620. */
  621. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  622. pmode->m_pixel_depth = 4;
  623. pmode++;
  624. query->q_number_modes++;
  625. if (MemAvail == ONE_MEG) // 1024 needs this memory amount
  626. {
  627. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  628. pmode->m_pixel_depth = 8;
  629. pmode++;
  630. query->q_number_modes++;
  631. }
  632. // Finally do 1280x1024. 4 bpp is the only color depth supported
  633. if (is1280 && (MemAvail == ONE_MEG))
  634. {
  635. query->q_number_modes++;
  636. query->q_status_flags |= VRES_1280x1024;
  637. pmode->control = 0x140; // no equal to 68800 CRT 0 entry
  638. pmode->m_pixel_depth = 4; // 4 bits per pixel
  639. pmode->m_reserved = 19; // shadow sets are combined
  640. jj = (ee->EEread) (19); // Composite and Vfifo
  641. kk = (ee->EEread) (20); // clock select and divisor
  642. pmode->m_clock_select = (jj & 0x1F00) | ((kk & 0x3F00) >> 6);
  643. pmode->m_clock_select ^= 0x1000;
  644. ThisRes.ClockFreq = GetFrequency((BYTE)((ThisRes.m_clock_select & 0x007C) >> 2));
  645. kk = (ee->EEread) (30); // H_total
  646. pmode->m_h_total = (kk >> 8) & 0xFF;
  647. kk = (ee->EEread) (29); // H_display
  648. pmode->m_h_disp = (kk >> 8) & 0xFF;
  649. pmode->m_x_size = (pmode->m_h_disp+1) * 8;
  650. pmode->m_screen_pitch = pmode->m_x_size;
  651. kk = (ee->EEread) (28); // H_sync_strt
  652. pmode->m_h_sync_strt = (kk >> 8) & 0xFF;
  653. kk = (ee->EEread) (27); // H_sync_width
  654. pmode->m_h_sync_wid = (kk >> 8) & 0xFF;
  655. kk = (ee->EEread) (23); // V_sync_width
  656. pmode->m_v_sync_wid = (kk >> 8) & 0xFF;
  657. kk = (ee->EEread) (22); // Display_cntl
  658. pmode->m_disp_cntl = (kk >> 8) & 0xFF;
  659. pmode->m_v_total = (ee->EEread) (51);
  660. pmode->m_v_disp = (ee->EEread) (50);
  661. pmode->m_y_size = (((pmode->m_v_disp >> 1) & 0xFFFC) | (pmode->m_v_disp & 0x03)) +1;
  662. pmode->m_v_sync_strt = (ee->EEread) (49);
  663. pmode->enabled = 0x80; // use stored values from eeprom
  664. pmode->m_status_flags = 0;
  665. pmode->m_h_overscan = 0; // not supported
  666. pmode->m_v_overscan = 0;
  667. pmode->m_overscan_8b = 0;
  668. pmode->m_overscan_gr = 0;
  669. pmode->m_vfifo_24 = 0;
  670. pmode->m_vfifo_16 = 0;
  671. pmode->Refresh = DEFAULT_REFRESH;
  672. }
  673. query->q_sizeof_struct = query->q_number_modes * sizeof(struct st_mode_table) + sizeof(struct query_structure);
  674. return NO_ERROR;
  675. } /* Query8514Ultra */
  676. //----------------------------------------------------------------------
  677. // QueryGUltra
  678. //
  679. // Fill in the query structure with the eeprom and register info
  680. // for the Graphics Ultra adapters. (Similar to Mach32 layout)
  681. // There are a maximum of 7 mode tables, two each for 640x480,
  682. // 800x600, and 1024x768, and one for 1280x1024.
  683. //
  684. // Returns:
  685. // NO_ERROR if successful
  686. // ERROR_DEV_NOT_EXIST if EEPROM read fails
  687. //
  688. VP_STATUS QueryGUltra (struct query_structure *query)
  689. {
  690. struct st_eeprom_data *ee = phwDeviceExtension->ee;
  691. short crttable[4] = {13, 24, 35, 46}; // start of eeprom crt table
  692. WORD ee_value, table_offset, jj, kk, ee_word;
  693. BYTE bhigh, blow;
  694. struct st_mode_table *pmode; // CRT table parameters
  695. short VgaTblEntry; /* VGA parameter table entry to use if translation needed */
  696. short BookTblEntry; /* Appendix D parameter table entry to use if parameters not in EEPROM */
  697. long NumPixels; /* Number of pixels at the selected resolution */
  698. long MemAvail; /* Bytes of memory available for the accelerator */
  699. struct st_mode_table ThisRes; /* Mode table for the given resolution */
  700. BYTE VgaMem; /* Code for amount of VGA memory on board */
  701. query->q_structure_rev = 0;
  702. query->q_mode_offset = sizeof(struct query_structure);
  703. query->q_sizeof_mode = sizeof(struct st_mode_table);
  704. query->q_status_flags = 0; // will indicate resolutions
  705. /*
  706. * We don't use the q_mouse_cfg field, so fill in a typical value
  707. * (mouse disabled) rather than reading from the EEPROM in case we
  708. * are dealing with a card without an EEPROM.
  709. */
  710. kk = 0x0000;
  711. bhigh = (kk >> 8) & 0xFF;
  712. blow = kk & 0xFF;
  713. query->q_mouse_cfg = (bhigh >> 3) | ((blow & 0x18) >> 1); // mouse configuration
  714. query->q_DAC_type = DAC_ATI_68830; // one DAC type similar to 68830
  715. query->q_aperture_addr = 0; // no aperture address
  716. query->q_aperture_cfg = 0; // no aperture configuration
  717. query->q_asic_rev = CI_38800_1; // only one ASIC revision
  718. query->q_VGA_type = 1; // VGA always Enabled
  719. OUTP (ati_reg, 0xB0); // find out how much VGA memory
  720. VgaMem = INP(ati_reg+1);
  721. switch (VgaMem & 0x18)
  722. {
  723. case 0x00:
  724. jj = 256;
  725. query->q_VGA_boundary = VRAM_256k;
  726. break;
  727. case 0x10:
  728. jj = 512;
  729. query->q_VGA_boundary = VRAM_512k;
  730. break;
  731. case 0x08:
  732. jj = 1024;
  733. query->q_VGA_boundary = VRAM_1mb;
  734. break;
  735. default: // assume most likely VGA amount
  736. jj = 512;
  737. query->q_VGA_boundary = VRAM_512k;
  738. break;
  739. }
  740. kk = INPW (CONFIG_STATUS_1);
  741. query->q_memory_type = kk & DRAM_ENA ? VMEM_DRAM_256Kx4 : VMEM_VRAM_256Kx4_SER512;
  742. jj += (kk & MEM_INSTALLED) ? 1024 : 512; // 8514 memory
  743. switch (jj)
  744. {
  745. case 0x300:
  746. jj = VRAM_768k;
  747. MemAvail = HALF_MEG; // Accelerator amount
  748. break;
  749. case 0x400:
  750. jj = VRAM_1mb;
  751. MemAvail = HALF_MEG; // Accelerator amount
  752. break;
  753. case 0x500:
  754. jj = VRAM_1_25mb;
  755. MemAvail = ONE_MEG;
  756. break;
  757. case 0x600:
  758. jj = VRAM_1_50mb;
  759. if (query->q_VGA_boundary == VRAM_1mb)
  760. MemAvail = HALF_MEG; // Accelerator amount
  761. else MemAvail = ONE_MEG;
  762. break;
  763. case 0x800:
  764. jj = VRAM_2mb;
  765. MemAvail = ONE_MEG;
  766. break;
  767. }
  768. query->q_memory_size = (UCHAR)jj;
  769. if (kk & MC_BUS) // is microchannel bus
  770. query->q_bus_type = BUS_MC_16; // 16 bit bus
  771. else
  772. query->q_bus_type = kk & BUS_16 ? BUS_ISA_16 : BUS_ISA_8;
  773. /*
  774. * We don't use the q_monitor_alias field, so fill in a typical
  775. * value rather than reading from the EEPROM in case we are
  776. * dealing with a card without an EEPROM.
  777. */
  778. query->q_monitor_alias = 0x0F;
  779. query->q_shadow_1 = 0; // do not know what to put here
  780. query->q_shadow_2 = 0;
  781. /*
  782. * If the EEPROM is not present, we can't fill in the mode
  783. * tables. Return and let the user know that the mode tables
  784. * have not been filled in.
  785. */
  786. if (query->q_eeprom == FALSE)
  787. return ERROR_DEV_NOT_EXIST;
  788. /*
  789. * Fill in the mode tables. The mode tables are sorted in increasing
  790. * order of resolution, and in increasing order of pixel depth.
  791. * Ensure pmode is initialized to the END of query structure
  792. */
  793. pmode = (struct st_mode_table *) query;
  794. ((struct query_structure *) pmode)++; // first mode table at end of query
  795. query->q_number_modes = 0;
  796. ee_word = 7; // starting ee word to read, 7,8,9 and 10 are
  797. // the resolutions supported.
  798. for (jj=0; jj < 4; jj++, ee_word++)
  799. {
  800. ee_value = (ee->EEread) (ee_word);
  801. /*
  802. * If no 1024x768 mode is configured, assume that
  803. * 87Hz interlaced is avialable (Windows 3.1 compatibility).
  804. */
  805. if ((ee_word == 9) && !(ee_value & 0x001F))
  806. ee_value |= M1024F87;
  807. table_offset = crttable[jj]; // offset to resolution table
  808. /*
  809. * If we have found a resolution which is supported with
  810. * the currently installed card and monitor, set the flag
  811. * to show that this resolution is available, record which
  812. * VGA parameter table to use if translation is needed,
  813. * get the #define for the 4BPP mode at that resolution,
  814. * and get the pixel count for the resolution.
  815. *
  816. * In 640x480, ee_value will be zero if IBM Default
  817. * was selected for vertical scan frequency,
  818. * For all other resolutions, the resolution is unsupported if
  819. * ee_value is zero.
  820. *
  821. * Some Graphics Ultra cards (due to an early BIOS)
  822. * have a 132 column text mode where the 1280x1024
  823. * graphics mode should be. If we have one of these
  824. * cards, we must treat it as if the mode table
  825. * were empty, otherwise we'd generate a 1280x1024
  826. * mode table full of garbage values.
  827. */
  828. if ((ee_value | (jj == 0))
  829. && !((ee_word == 10) && (query->q_ignore1280 == TRUE)))
  830. {
  831. switch (ee_word)
  832. {
  833. case 7:
  834. query->q_status_flags |= VRES_640x480;
  835. ThisRes.m_screen_pitch = 640;
  836. if (ee_value & M640F72)
  837. {
  838. VgaTblEntry = T640F72;
  839. BookTblEntry = B640F72;
  840. }
  841. else{
  842. VgaTblEntry = T640F60;
  843. BookTblEntry = B640F60;
  844. }
  845. NumPixels = (long) 640*480;
  846. break;
  847. case 8:
  848. query->q_status_flags |= VRES_800x600;
  849. // mach8 must be multiple of 128
  850. ThisRes.m_screen_pitch = 896;
  851. if (ee_value & M800F72)
  852. {
  853. VgaTblEntry = T800F72;
  854. BookTblEntry = B800F72;
  855. }
  856. else if (ee_value & M800F70)
  857. {
  858. VgaTblEntry = T800F70;
  859. BookTblEntry = B800F70;
  860. }
  861. else if (ee_value & M800F60)
  862. {
  863. VgaTblEntry = T800F60;
  864. BookTblEntry = B800F60;
  865. }
  866. else if (ee_value & M800F56)
  867. {
  868. VgaTblEntry = T800F56;
  869. BookTblEntry = B800F56;
  870. }
  871. else if (ee_value & M800F89)
  872. {
  873. VgaTblEntry = T800F89;
  874. BookTblEntry = B800F89;
  875. }
  876. else if (ee_value & M800F95)
  877. {
  878. VgaTblEntry = T800F95;
  879. BookTblEntry = B800F95;
  880. }
  881. else
  882. {
  883. VgaTblEntry = NO_TBL_ENTRY;
  884. BookTblEntry = NO_TBL_ENTRY;
  885. }
  886. NumPixels = (long) ThisRes.m_screen_pitch*600;
  887. break;
  888. case 9:
  889. query->q_status_flags |= VRES_1024x768;
  890. ThisRes.m_screen_pitch = 1024;
  891. if (ee_value & M1024F66)
  892. {
  893. VgaTblEntry = T1024F66;
  894. BookTblEntry = B1024F66;
  895. }
  896. else if (ee_value & M1024F72)
  897. {
  898. VgaTblEntry = T1024F72;
  899. BookTblEntry = B1024F72;
  900. }
  901. else if (ee_value & M1024F70)
  902. {
  903. VgaTblEntry = T1024F70;
  904. BookTblEntry = B1024F70;
  905. }
  906. else if (ee_value & M1024F60)
  907. {
  908. VgaTblEntry = T1024F60;
  909. BookTblEntry = B1024F60;
  910. }
  911. else if (ee_value & M1024F87)
  912. {
  913. VgaTblEntry = T1024F87;
  914. BookTblEntry = B1024F87;
  915. }
  916. else
  917. {
  918. VgaTblEntry = NO_TBL_ENTRY;
  919. BookTblEntry = NO_TBL_ENTRY;
  920. }
  921. NumPixels = (long) 1024*768;
  922. break;
  923. case 10:
  924. query->q_status_flags |= VRES_1280x1024;
  925. ThisRes.m_screen_pitch = 1280;
  926. if (ee_value & M1280F95)
  927. {
  928. VgaTblEntry = T1280F95;
  929. BookTblEntry = B1280F95;
  930. }
  931. else if (ee_value & M1280F87)
  932. {
  933. VgaTblEntry = T1280F87;
  934. BookTblEntry = B1280F87;
  935. }
  936. else
  937. {
  938. VgaTblEntry = NO_TBL_ENTRY;
  939. BookTblEntry = NO_TBL_ENTRY;
  940. }
  941. NumPixels = (long) 1280*1024;
  942. break;
  943. }
  944. /*
  945. * For a given resolution, there will be one mode table
  946. * per colour depth. Replicate it for ALL pixel depths
  947. */
  948. ThisRes.enabled = ee_value; /* Which vertical scan frequency */
  949. ThisRes.m_reserved = table_offset; /* Put EEPROM base address here */
  950. /*
  951. * Assume that the EEPROM parameters are in 8514 format
  952. * and try to fill the pmode table. If they are in
  953. * VGA format, translate them and fill as much of the
  954. * table as we can.
  955. * The case where the CRT parameters aren't stored in
  956. * the EEPROM is handled inside XlateVgaTable().
  957. * If the parameters aren't stored in the EEPROM,
  958. * both the FMT_8514 bit and the CRTC_USAGE bit
  959. * will be clear.
  960. */
  961. if (!fill_mode_table_m (table_offset, &ThisRes, ee))
  962. {
  963. XlateVgaTable(phwDeviceExtension, table_offset, &ThisRes, VgaTblEntry, BookTblEntry, ee, FALSE);
  964. }
  965. else{
  966. ThisRes.m_h_overscan = 0;
  967. ThisRes.m_v_overscan = 0;
  968. ThisRes.m_overscan_8b = 0;
  969. ThisRes.m_overscan_gr = 0;
  970. }
  971. ThisRes.Refresh = DEFAULT_REFRESH;
  972. /*
  973. * The COMPOSITE_SYNC bit of the m_clock_select field is
  974. * set up to handle composite sync with shadow sets. We use
  975. * the primrary CRT register set, so we must invert it.
  976. */
  977. ThisRes.m_clock_select ^= 0x1000;
  978. ThisRes.m_status_flags = 0;
  979. ThisRes.m_vfifo_24 = 0;
  980. ThisRes.m_vfifo_16 = 0;
  981. /*
  982. * For each supported pixel depth at the given resolution,
  983. * copy the mode table, fill in the colour depth field, set
  984. * a flag to show that this resolution/depth pair is supported,
  985. * and increment the counter for the number of supported modes.
  986. * Test 4BPP before 8BPP so the mode tables will appear in
  987. * increasing order of pixel depth.
  988. *
  989. * We don't support 640x480 256 colour minimum mode, so there
  990. * are no 8BPP modes available on a 512k card.
  991. */
  992. if (NumPixels <= MemAvail*2)
  993. {
  994. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  995. pmode->m_pixel_depth = 4;
  996. query->q_number_modes++;
  997. pmode++;
  998. }
  999. if ((NumPixels <= MemAvail) && (MemAvail == ONE_MEG))
  1000. {
  1001. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  1002. pmode->m_pixel_depth = 8;
  1003. query->q_number_modes++;
  1004. pmode++;
  1005. }
  1006. }
  1007. }
  1008. query->q_sizeof_struct = query->q_number_modes * sizeof(struct st_mode_table) + sizeof(struct query_structure);
  1009. return NO_ERROR;
  1010. } /* QueryGUltra */
  1011. //----------------------------------------------------------------------
  1012. //; QueryMach32 Mach32 -- 68800 query function
  1013. //;
  1014. //; INPUT: QUERY_GET_SIZE, return query structure size (varying modes)
  1015. //; QUERY_LONG , return query structure filled in
  1016. //; QUERY_SHORT , return short query
  1017. //;
  1018. //; OUTPUT: ax = size of query structure
  1019. //; or query structure is filled in
  1020. //----------------------------------------------------------------------
  1021. static void short_query_m (struct query_structure *query, struct st_eeprom_data *ee)
  1022. {
  1023. WORD kk;
  1024. BYTE bhigh, blow;
  1025. WORD ApertureLocation; /* Aperture location, in megabytes */
  1026. /*
  1027. * We don't use the q_mouse_cfg field, so fill in a typical value
  1028. * (mouse disabled) rather than reading from the EEPROM in case we
  1029. * are dealing with a card without an EEPROM.
  1030. */
  1031. kk = 0x0000;
  1032. bhigh = (kk >> 8) & 0xFF;
  1033. blow = kk & 0xFF;
  1034. query->q_mouse_cfg = (bhigh >> 3) | ((blow & 0x18) >> 1); // mouse configuration
  1035. kk = INPW (CONFIG_STATUS_1); // get DAC type
  1036. query->q_DAC_type = ((kk >> 8) & 0x0E) >> 1;
  1037. /*
  1038. * The BT48x and AT&T 491/2/3 families of DAC are incompatible, but
  1039. * CONFIG_STATUS_1 reports the same value for both. If this value
  1040. * was reported, determine which DAC type we have.
  1041. */
  1042. if (query->q_DAC_type == DAC_BT48x)
  1043. query->q_DAC_type = BrooktreeOrATT_m();
  1044. /*
  1045. * The STG1700 and AT&T498 are another pair of incompatible DACs that
  1046. * share a reporting code.
  1047. */
  1048. else if (query->q_DAC_type == DAC_STG1700)
  1049. query->q_DAC_type = ThompsonOrATT_m();
  1050. /*
  1051. * The SC15021 and STG1702/1703 are yet another pair of DACs that
  1052. * share a reporting code.
  1053. */
  1054. else if (query->q_DAC_type == DAC_SC15021)
  1055. query->q_DAC_type = SierraOrThompson_m();
  1056. /*
  1057. * Chip subfamily is stored in bits 0-9 of ASIC_ID. Each subfamily
  1058. * starts the revision counter over from 0.
  1059. */
  1060. switch (INPW(ASIC_ID) & 0x03FF)
  1061. {
  1062. /*
  1063. * 68800-3 does not implement this register, a read returns
  1064. * all 0 bits.
  1065. */
  1066. case 0:
  1067. query->q_asic_rev = CI_68800_3;
  1068. break;
  1069. /*
  1070. * Subsequent revisions of 68800 store the revision count.
  1071. * 68800-6 stores a "2" in the top 4 bits.
  1072. */
  1073. case 0x2F7:
  1074. VideoDebugPrint(( DEBUG_DETAIL, "ASIC_ID = 0x%X\n", INPW(ASIC_ID) ));
  1075. if ((INPW(ASIC_ID) & 0x0F000) == 0x2000)
  1076. {
  1077. query->q_asic_rev = CI_68800_6;
  1078. }
  1079. else
  1080. {
  1081. query->q_asic_rev = CI_68800_UNKNOWN;
  1082. VideoDebugPrint(( DEBUG_ERROR, "*/n*/n* ASIC_ID has invalid value/n*/n*/n"));
  1083. }
  1084. break;
  1085. /*
  1086. * 68800AX
  1087. */
  1088. case 0x17:
  1089. query->q_asic_rev = CI_68800_AX;
  1090. break;
  1091. /*
  1092. * Chips we don't know about yet.
  1093. */
  1094. default:
  1095. query->q_asic_rev = CI_68800_UNKNOWN;
  1096. VideoDebugPrint((DEBUG_ERROR, "*/n*/n* Unknown Mach 32 ASIC type/n*/n*/n"));
  1097. break;
  1098. }
  1099. /*
  1100. * If the query->q_m32_aper_calc field is set, then we read bits
  1101. * 0-6 of the aperture address from bits 8-14 of MEM_CFG
  1102. * and bits 7-11 from bits 0-4 of the high word of SCRATCH_PAD_0.
  1103. */
  1104. if (query->q_m32_aper_calc)
  1105. {
  1106. ApertureLocation = (INPW(MEM_CFG) & 0x7F00) >> 8;
  1107. ApertureLocation |= ((INPW(SCRATCH_PAD_0) & 0x1F00) >> 1);
  1108. }
  1109. /*
  1110. * If the query->q_m32_aper_calc field is clear, and we have an ASIC
  1111. * other than 68800-3 set up to allow the aperture anywhere in the
  1112. * CPU's address space, bits 0-11 of the aperture address are read
  1113. * from bits 4-15 of MEM_CFG. PCI bus always uses this setup, even
  1114. * if CONFIG_STATUS_2 says to use 128M aperture range.
  1115. */
  1116. else if (((query->q_asic_rev != CI_68800_3) && (INPW(CONFIG_STATUS_2) & 0x2000))
  1117. || ((INPW(CONFIG_STATUS_1) & 0x0E) == 0x0E))
  1118. {
  1119. ApertureLocation = (INPW(MEM_CFG) & 0xFFF0) >> 4;
  1120. }
  1121. /*
  1122. * If the query->q_m32_aper_calc field is clear, and we have either
  1123. * a revision 0 ASIC or a newer ASIC set up for a limited range of
  1124. * aperture locations, bits 0-7 of the aperture address are read
  1125. * from bits 8-15 of MEM_CFG.
  1126. */
  1127. else
  1128. {
  1129. ApertureLocation = (INPW(MEM_CFG) & 0xFF00) >> 8;
  1130. }
  1131. #if !defined (i386) && !defined (_i386_)
  1132. //RKE: MEM_CFG expect aperture location in <4:15> for PCI and <8:15>
  1133. // for VLB.
  1134. kk = (query->q_system_bus_type == PCIBus)? 4:8;
  1135. #if defined (ALPHA)
  1136. kk = 4; // Problem with alpha
  1137. #endif
  1138. /*
  1139. * Force aperture location to a fixed address.
  1140. * Since there is no BIOS on Alpha, can't depend on MEM_CFG being preset.
  1141. */
  1142. ApertureLocation = 0x78; // 120 Mb
  1143. OUTPW(MEM_CFG, (USHORT)((ApertureLocation << kk) | 0x02));
  1144. VideoDebugPrint(( DEBUG_DETAIL, "ATI.SYS: MEM_CFG = %x (%x)\n",
  1145. (INPW(MEM_CFG)), ((ApertureLocation << kk) | 0x02) ));
  1146. #endif /* defined Alpha */
  1147. query->q_aperture_addr = ApertureLocation;
  1148. /*
  1149. * If the aperture address is zero, then the aperture has not
  1150. * been set up. We can't use the aperture size field of
  1151. * MEM_CFG, since it is cleared on system boot, disabling the
  1152. * aperture until an application explicitly enables it.
  1153. */
  1154. if (ApertureLocation == 0)
  1155. {
  1156. query->q_aperture_cfg = 0;
  1157. }
  1158. /*
  1159. * If the aperture has been set up and the card has no more
  1160. * than 1M of memory, indicate that a 1M aperture could be
  1161. * used, otherwise indicate that a 4M aperture is needed.
  1162. *
  1163. * In either case, set memory use to shared VGA/coprocessor.
  1164. * When the aperture is enabled later in the execution of the
  1165. * miniport, we will always use a 4M aperture. No address space
  1166. * will be wasted, because we will only ask NT to use a block the
  1167. * size of the installed video memory.
  1168. *
  1169. * The format of data in bits 2-15 of MEM_CFG differs
  1170. * between various Mach 32 cards. To avoid having to identify
  1171. * which Mach 32 we are dealing with, read the current value
  1172. * and only change the aperture size bits.
  1173. */
  1174. else{
  1175. if ((INP(MISC_OPTIONS) & MEM_SIZE_ALIAS) <= MEM_SIZE_1M)
  1176. query->q_aperture_cfg = 1;
  1177. else
  1178. query->q_aperture_cfg = 2;
  1179. OUTP(MEM_BNDRY,0);
  1180. }
  1181. return;
  1182. } /* short_query_m */
  1183. //---------------------------------------------------------------------
  1184. VP_STATUS QueryMach32 (struct query_structure *query, BOOL ForceShared)
  1185. {
  1186. struct st_eeprom_data *ee = phwDeviceExtension->ee;
  1187. struct st_mode_table *pmode;
  1188. short jj, kk, ee_word;
  1189. WORD pitch, ee_value, table_offset, config_status_1, current_mode;
  1190. short VgaTblEntry; /* VGA parameter table entry to use if translation needed */
  1191. short BookTblEntry; /* Appendix D parameter table entry to use if parameters not in EEPROM */
  1192. long NumPixels; /* Number of pixels at the selected resolution */
  1193. long MemAvail; /* Bytes of memory available for the accelerator */
  1194. struct st_mode_table ThisRes; /* Mode table for the given resolution */
  1195. PUCHAR BiosRaw; /* Storage for information retrieved by BIOS call */
  1196. short CurrentRes; /* Array index based on current resolution. */
  1197. UCHAR Scratch; /* Scratch variable */
  1198. short StartIndex; /* First mode for SetFixedModes() to set up */
  1199. short EndIndex; /* Last mode for SetFixedModes() to set up */
  1200. BOOL ModeInstalled; /* Is this resolution configured? */
  1201. WORD Multiplier; /* Pixel clock multiplier */
  1202. short MaxModes; /* Maximum number of modes possible */
  1203. short FreeTables; /* Number of remaining free mode tables */
  1204. /*
  1205. * Checking the number of modes available would involve
  1206. * duplicating most of the code to fill in the mode tables.
  1207. * Since this is to determine how much memory is needed
  1208. * to hold the query structure, we can assume the worst
  1209. * case (all possible modes are present). This would be:
  1210. *
  1211. * Resolution Pixel Depths (BPP) Refresh rates (Hz) Number of modes
  1212. * 640x480 4,8,16,24 HWD,60,72 12
  1213. * 800x600 4,8,16,24 HWD,56,60,70,72,89,95 28
  1214. * 1024x768 4,8,16 HWD,60,66,70,72,87 18
  1215. * 1280x1024 4,8 HWD,60,70,74,87,95 12
  1216. *
  1217. * HWD = hardware default refresh rate (rate set by INSTALL)
  1218. *
  1219. * Total: 70 modes
  1220. */
  1221. if (QUERYSIZE < (70 * sizeof(struct st_mode_table) + sizeof(struct query_structure)))
  1222. return ERROR_INSUFFICIENT_BUFFER;
  1223. MaxModes = (QUERYSIZE - sizeof(struct query_structure)) /
  1224. sizeof(struct st_mode_table);
  1225. query->q_structure_rev = 0;
  1226. query->q_mode_offset = sizeof(struct query_structure);
  1227. query->q_sizeof_mode = sizeof(struct st_mode_table);
  1228. query->q_number_modes = 0; /* Initially assume no modes available */
  1229. query->q_status_flags = 0; // will indicate resolutions
  1230. short_query_m (query, ee);
  1231. config_status_1 = INPW (CONFIG_STATUS_1);
  1232. query->q_VGA_type = config_status_1 & 0x01 ? 0 : 1;
  1233. /*
  1234. * If the program using this routine is going to force the
  1235. * use of shared memory, assume a VGA boundary of 0 when
  1236. * calculating the amount of available memory.
  1237. */
  1238. kk = INP (MEM_BNDRY);
  1239. if ((kk & 0x10) && !ForceShared)
  1240. query->q_VGA_boundary = kk & 0x0F;
  1241. else query->q_VGA_boundary = 0x00; // shared by both
  1242. switch (INPW(MISC_OPTIONS) & MEM_SIZE_ALIAS)
  1243. {
  1244. case MEM_SIZE_512K:
  1245. jj = VRAM_512k;
  1246. MemAvail = HALF_MEG;
  1247. VideoDebugPrint((DEBUG_NORMAL, "MISC_OPTIONS register reports 512k of video memory\n"));
  1248. break;
  1249. case MEM_SIZE_1M:
  1250. jj = VRAM_1mb;
  1251. MemAvail = ONE_MEG;
  1252. VideoDebugPrint((DEBUG_NORMAL, "MISC_OPTIONS register reports 1M of video memory\n"));
  1253. break;
  1254. case MEM_SIZE_2M:
  1255. jj = VRAM_2mb;
  1256. MemAvail = 2*ONE_MEG;
  1257. VideoDebugPrint((DEBUG_NORMAL, "MISC_OPTIONS register reports 2M of video memory\n"));
  1258. break;
  1259. case MEM_SIZE_4M:
  1260. jj = VRAM_4mb;
  1261. MemAvail = 4*ONE_MEG;
  1262. VideoDebugPrint((DEBUG_NORMAL, "MISC_OPTIONS register reports 4M of video memory\n"));
  1263. break;
  1264. }
  1265. query->q_memory_type = (config_status_1 >> 4) & 0x07; // CONFIG_STATUS_1.MEM_TYPE
  1266. /*
  1267. * Some 68800-6 and later cards have a bug where one VGA mode (not used
  1268. * by Windows NT VGA miniport, so we don't need to worry about it in
  1269. * full-screen sessions) doesn't work properly if the card has more than
  1270. * 1M of memory. The "fix" for this bug involves telling the memory size
  1271. * field of MISC_OPTIONS to report a memory size smaller than the true
  1272. * amount of memory (most cards with this "fix" report 1M, but some
  1273. * only report 512k).
  1274. *
  1275. * On these cards (DRAM only), get the true memory size.
  1276. *
  1277. * On non-x86 platforms, GetTrueMemSize_m() may either hang
  1278. * (MIPS) or report a false value (Alpha) (on the Power PC,
  1279. * we only support Mach 64). Since we can't rely on the value
  1280. * in MISC_OPTIONS being correct either (the video BIOS may
  1281. * not be executed properly on startup, or we may have a card
  1282. * that reports 1M instead of the true size), assume that
  1283. * non-x86 machines have 2M of video memory available.
  1284. */
  1285. #if defined (i386) || defined (_i386_)
  1286. if (((query->q_asic_rev == CI_68800_6) || (query->q_asic_rev == CI_68800_AX)) &&
  1287. (query->q_VGA_type == 1) &&
  1288. ((query->q_memory_type == VMEM_DRAM_256Kx4) ||
  1289. (query->q_memory_type == VMEM_DRAM_256Kx16) ||
  1290. (query->q_memory_type == VMEM_DRAM_256Kx4_GRAP)))
  1291. {
  1292. jj = GetTrueMemSize_m();
  1293. MemAvail = jj * QUARTER_MEG;
  1294. }
  1295. #else /* non-x86 system */
  1296. jj = VRAM_2mb;
  1297. MemAvail = 2*ONE_MEG;
  1298. #endif
  1299. query->q_memory_size = (UCHAR)jj;
  1300. /*
  1301. * Subtract the "reserved for VGA" memory size from the total
  1302. * memory to get the amount available to the accelerator.
  1303. */
  1304. MemAvail -= (query->q_VGA_boundary) * QUARTER_MEG;
  1305. jj = (config_status_1 >> 1) & 0x07; // CONFIG_STATUS_1.BUS_TYPE
  1306. if (jj == BUS_ISA_16) // is ISA bus
  1307. {
  1308. if (query->q_VGA_type) // is VGA enabled and ISA BUS
  1309. jj = BUS_ISA_8;
  1310. }
  1311. query->q_bus_type = (UCHAR)jj;
  1312. /*
  1313. * We don't use the q_monitor_alias field, so fill in a typical
  1314. * value rather than reading from the EEPROM in case we are
  1315. * dealing with a card without an EEPROM.
  1316. */
  1317. query->q_monitor_alias = 0x0F;
  1318. kk = INPW (SCRATCH_PAD_1);
  1319. pitch = (kk & 0x20) | ((kk & 0x01) << 4);
  1320. kk = INP (SCRATCH_PAD_0+1) & 0x07;
  1321. switch (kk)
  1322. {
  1323. case 0: // 800x600?
  1324. pitch |= 0x01;
  1325. break;
  1326. case 1: // 1280x1024?
  1327. pitch |= 0x03;
  1328. break;
  1329. case 4: // alternate mode?
  1330. pitch |= 0x04;
  1331. break;
  1332. case 2: // 640x480?
  1333. pitch |= 0x0;
  1334. break;
  1335. default: // 1024x768
  1336. pitch |= 0x02;
  1337. break;
  1338. }
  1339. query->q_shadow_1 = pitch + 1;
  1340. kk = INP(SCRATCH_PAD_1+1);
  1341. pitch = (kk & 0x20) | ((kk & 0x01) << 4);
  1342. kk = INP(SCRATCH_PAD_0+1) & 0x30;
  1343. switch (kk)
  1344. {
  1345. case 0: // 800x600?
  1346. pitch |= 0x01;
  1347. break;
  1348. case 0x10: // 1280x1024?
  1349. pitch |= 0x03;
  1350. break;
  1351. case 0x40: // alternate mode?
  1352. pitch |= 0x04;
  1353. break;
  1354. case 0x20: // 640x480?
  1355. pitch |= 0x0;
  1356. break;
  1357. default: // 1024x768
  1358. pitch |= 0x02;
  1359. break;
  1360. }
  1361. query->q_shadow_2 = pitch + 1;
  1362. /*
  1363. * If extended BIOS functions are available, set up a buffer
  1364. * for the call to the BIOS query function, then make the call.
  1365. */
  1366. if (query->q_ext_bios_fcn)
  1367. {
  1368. BiosRaw = gBiosRaw;
  1369. /* Make the BIOS call (not yet supported by Windows NT) */
  1370. }
  1371. /*
  1372. * If neither the extended BIOS functions nor the EEPROM
  1373. * is present, we can't fill in the mode tables. Return
  1374. * and let the user know that the mode tables have not
  1375. * been filled in.
  1376. */
  1377. else if (query->q_eeprom == FALSE)
  1378. return ERROR_DEV_NOT_EXIST;
  1379. /*
  1380. * Fill in the mode tables. The mode tables are sorted in increasing
  1381. * order of resolution, and in increasing order of pixel depth.
  1382. * Ensure pmode is initialized to the END of query structure
  1383. */
  1384. pmode = (struct st_mode_table *)query; // first mode table at end of query
  1385. ((struct query_structure *)pmode)++;
  1386. ee_word = 7; // starting ee word to read, 7,8,9,10 and 11 are
  1387. // the resolutions supported.
  1388. for (jj=0; jj < 4; jj++, ee_word++)
  1389. {
  1390. /*
  1391. * Get the pixel depth-independent portion of the
  1392. * mode tables at the current resolution. Use the
  1393. * extended BIOS functions if available, otherwise
  1394. * read from the EEPROM.
  1395. */
  1396. if (query->q_ext_bios_fcn)
  1397. {
  1398. if (BiosFillTable_m(ee_word, BiosRaw, &ThisRes, query) == FALSE)
  1399. ModeInstalled = FALSE;
  1400. else
  1401. ModeInstalled = TRUE;
  1402. switch (ee_word)
  1403. {
  1404. case 7:
  1405. CurrentRes = RES_640;
  1406. StartIndex = B640F60;
  1407. EndIndex = B640F72;
  1408. break;
  1409. case 8:
  1410. CurrentRes = RES_800;
  1411. StartIndex = B800F89;
  1412. EndIndex = B800F72;
  1413. break;
  1414. case 9:
  1415. CurrentRes = RES_1024;
  1416. StartIndex = B1024F87;
  1417. EndIndex = B1024F72;
  1418. break;
  1419. case 10:
  1420. CurrentRes = RES_1280;
  1421. StartIndex = B1280F87;
  1422. /*
  1423. * 1280x1024 modes above 60Hz noninterlaced
  1424. * are only available on VRAM cards.
  1425. */
  1426. if ((query->q_memory_type == VMEM_DRAM_256Kx4) ||
  1427. (query->q_memory_type == VMEM_DRAM_256Kx16) ||
  1428. (query->q_memory_type == VMEM_DRAM_256Kx4_GRAP))
  1429. EndIndex = B1280F60;
  1430. else
  1431. EndIndex = B1280F74;
  1432. break;
  1433. }
  1434. }
  1435. else{
  1436. ee_value = (ee->EEread) (ee_word);
  1437. current_mode = ee_value & 0x00FF;
  1438. table_offset = (ee_value >> 8) & 0xFF; // offset to resolution table
  1439. /*
  1440. * Record whether or not this resolution is enabled.
  1441. * We will report "canned" mode tables for all resolutions,
  1442. * but calculations dependent on the configured refresh
  1443. * rate can only be made if this resolution was enabled
  1444. * by the install program.
  1445. *
  1446. * For all modes except 640x480, there will be a bit set
  1447. * to show which vertical scan rate is used. If no bit is
  1448. * set, then that resolution is not configured.
  1449. *
  1450. * In 640x480, no bit is set if "IBM Default" was selected
  1451. * during monitor configuration, so we assume that 640x480
  1452. * is configured.
  1453. */
  1454. if ((!jj) | ((current_mode) && (current_mode != 0xFF)))
  1455. ModeInstalled = TRUE;
  1456. else
  1457. ModeInstalled = FALSE;
  1458. switch (ee_word) // are defined for resolutions
  1459. {
  1460. case 7:
  1461. query->q_status_flags |= VRES_640x480;
  1462. CurrentRes = RES_640;
  1463. StartIndex = B640F60;
  1464. EndIndex = B640F72;
  1465. // 1024 pitch ONLY if NO aperture on a Mach32
  1466. #if !defined (SPLIT_RASTERS)
  1467. if (query->q_aperture_cfg == 0)
  1468. ThisRes.m_screen_pitch = 1024;
  1469. else
  1470. #endif
  1471. ThisRes.m_screen_pitch = 640;
  1472. NumPixels = (long) ThisRes.m_screen_pitch * 480;
  1473. if (ModeInstalled)
  1474. {
  1475. if (ee_value & M640F72)
  1476. {
  1477. VgaTblEntry = T640F72;
  1478. BookTblEntry = B640F72;
  1479. }
  1480. else
  1481. {
  1482. VgaTblEntry = T640F60;
  1483. BookTblEntry = B640F60;
  1484. }
  1485. }
  1486. break;
  1487. case 8:
  1488. query->q_status_flags |= VRES_800x600;
  1489. CurrentRes = RES_800;
  1490. StartIndex = B800F89;
  1491. EndIndex = B800F72;
  1492. #if defined (SPLIT_RASTERS)
  1493. if ((query->q_asic_rev == CI_68800_3) ||
  1494. #else
  1495. // 1024 pitch ONLY if NO aperture on a Mach32
  1496. if (query->q_aperture_cfg == 0)
  1497. ThisRes.m_screen_pitch = 1024;
  1498. // Original production revision has trouble
  1499. // with deep colour if screen pitch not
  1500. // divisible by 128.
  1501. else if ((query->q_asic_rev == CI_68800_3) ||
  1502. #endif
  1503. (query->q_bus_type == BUS_PCI))
  1504. ThisRes.m_screen_pitch = 896;
  1505. else
  1506. ThisRes.m_screen_pitch = 800;
  1507. NumPixels = (long) ThisRes.m_screen_pitch * 600;
  1508. if (ModeInstalled)
  1509. {
  1510. if (ee_value & M800F72)
  1511. {
  1512. VgaTblEntry = T800F72;
  1513. BookTblEntry = B800F72;
  1514. }
  1515. else if (ee_value & M800F70)
  1516. {
  1517. VgaTblEntry = T800F70;
  1518. BookTblEntry = B800F70;
  1519. }
  1520. else if (ee_value & M800F60)
  1521. {
  1522. VgaTblEntry = T800F60;
  1523. BookTblEntry = B800F60;
  1524. }
  1525. else if (ee_value & M800F56)
  1526. {
  1527. VgaTblEntry = T800F56;
  1528. BookTblEntry = B800F56;
  1529. }
  1530. else if (ee_value & M800F89)
  1531. {
  1532. VgaTblEntry = T800F89;
  1533. BookTblEntry = B800F89;
  1534. }
  1535. else if (ee_value & M800F95)
  1536. {
  1537. VgaTblEntry = T800F95;
  1538. BookTblEntry = B800F95;
  1539. }
  1540. else
  1541. {
  1542. VgaTblEntry = NO_TBL_ENTRY;
  1543. BookTblEntry = NO_TBL_ENTRY;
  1544. }
  1545. }
  1546. break;
  1547. case 9:
  1548. query->q_status_flags |= VRES_1024x768;
  1549. CurrentRes = RES_1024;
  1550. StartIndex = B1024F87;
  1551. EndIndex = B1024F72;
  1552. ThisRes.m_screen_pitch = 1024;
  1553. NumPixels = (long) ThisRes.m_screen_pitch * 768;
  1554. if (ModeInstalled)
  1555. {
  1556. if (ee_value & M1024F66)
  1557. {
  1558. VgaTblEntry = T1024F66;
  1559. BookTblEntry = B1024F66;
  1560. }
  1561. else if (ee_value & M1024F72)
  1562. {
  1563. VgaTblEntry = T1024F72;
  1564. BookTblEntry = B1024F72;
  1565. }
  1566. else if (ee_value & M1024F70)
  1567. {
  1568. VgaTblEntry = T1024F70;
  1569. BookTblEntry = B1024F70;
  1570. }
  1571. else if (ee_value & M1024F60)
  1572. {
  1573. VgaTblEntry = T1024F60;
  1574. BookTblEntry = B1024F60;
  1575. }
  1576. else if (ee_value & M1024F87)
  1577. {
  1578. VgaTblEntry = T1024F87;
  1579. BookTblEntry = B1024F87;
  1580. }
  1581. else
  1582. {
  1583. VgaTblEntry = NO_TBL_ENTRY;
  1584. BookTblEntry = NO_TBL_ENTRY;
  1585. }
  1586. }
  1587. break;
  1588. case 10:
  1589. query->q_status_flags |= VRES_1280x1024;
  1590. CurrentRes = RES_1280;
  1591. ThisRes.m_screen_pitch = 1280;
  1592. StartIndex = B1280F87;
  1593. /*
  1594. * 1280x1024 modes above 60Hz noninterlaced
  1595. * are only available on VRAM cards.
  1596. */
  1597. if ((query->q_memory_type == VMEM_DRAM_256Kx4) ||
  1598. (query->q_memory_type == VMEM_DRAM_256Kx16) ||
  1599. (query->q_memory_type == VMEM_DRAM_256Kx4_GRAP))
  1600. EndIndex = B1280F60;
  1601. else
  1602. EndIndex = B1280F74;
  1603. NumPixels = (long) ThisRes.m_screen_pitch * 1024;
  1604. // 68800-3 cannot support 4 bpp with 1 meg ram.
  1605. if ((query->q_asic_rev == CI_68800_3) && (MemAvail == ONE_MEG))
  1606. NumPixels *= 2; //ensures mode failure
  1607. if (ModeInstalled)
  1608. {
  1609. if (ee_value & M1280F95)
  1610. {
  1611. VgaTblEntry = T1280F95;
  1612. BookTblEntry = B1280F95;
  1613. }
  1614. else if (ee_value & M1280F87)
  1615. {
  1616. VgaTblEntry = T1280F87;
  1617. BookTblEntry = B1280F87;
  1618. }
  1619. else
  1620. {
  1621. VgaTblEntry = NO_TBL_ENTRY;
  1622. BookTblEntry = NO_TBL_ENTRY;
  1623. }
  1624. }
  1625. break;
  1626. } /* end switch(ee_word) */
  1627. /*
  1628. * For a given resolution, there will be one mode table
  1629. * per colour depth. Since the mode tables will differ
  1630. * only in the bits per pixel field, make up one mode
  1631. * table and copy its contents as many times as needed,
  1632. * changing only the colour depth field.
  1633. */
  1634. ThisRes.enabled = ee_value; /* Which vertical scan frequency */
  1635. /*
  1636. * Assume that the EEPROM parameters are in 8514
  1637. * format and try to fill the pmode table. If they
  1638. * are in VGA format, translate them and fill as much
  1639. * of the table as we can.
  1640. * The case where the CRT parameters aren't stored in
  1641. * the EEPROM is handled inside XlateVgaTable().
  1642. * If the parameters aren't stored in the EEPROM,
  1643. * both the FMT_8514 bit and the CRTC_USAGE bit
  1644. * will be clear.
  1645. */
  1646. if (!fill_mode_table_m (table_offset, &ThisRes, ee))
  1647. XlateVgaTable(phwDeviceExtension, table_offset, &ThisRes, VgaTblEntry, BookTblEntry, ee, TRUE);
  1648. } /* endif reading CRT parameters from EEPROM */
  1649. ThisRes.Refresh = DEFAULT_REFRESH;
  1650. /*
  1651. * For each supported pixel depth at the given resolution,
  1652. * copy the mode table, fill in the colour depth field, set
  1653. * a flag to show that this resolution/depth pair is supported,
  1654. * and increment the counter for the number of supported modes.
  1655. * Test 4BPP before 8BPP so the mode tables will appear in
  1656. * increasing order of pixel depth.
  1657. *
  1658. * All the DACs we support can handle 4 and 8 BPP if there
  1659. * is enough memory on the card.
  1660. */
  1661. if (NumPixels <= MemAvail*2)
  1662. {
  1663. if (ModeInstalled)
  1664. {
  1665. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  1666. pmode->m_pixel_depth = 4;
  1667. pmode++; /* ptr to next mode table */
  1668. query->q_number_modes++;
  1669. }
  1670. /*
  1671. * Some DAC and card types don't support 1280x1024 noninterlaced.
  1672. */
  1673. if ((CurrentRes == RES_1280) &&
  1674. ((query->q_DAC_type == DAC_BT48x) ||
  1675. (query->q_DAC_type == DAC_ATT491) ||
  1676. (query->q_DAC_type == DAC_SC15026) ||
  1677. (query->q_DAC_type == DAC_ATI_68830) ||
  1678. (query->q_GraphicsWonder == TRUE)))
  1679. EndIndex = B1280F95;
  1680. /*
  1681. * Add "canned" mode tables
  1682. */
  1683. if ((FreeTables = MaxModes - query->q_number_modes) <= 0)
  1684. {
  1685. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1686. return ERROR_INSUFFICIENT_BUFFER;
  1687. }
  1688. query->q_number_modes += SetFixedModes(StartIndex,
  1689. EndIndex,
  1690. CLOCK_SINGLE,
  1691. 4,
  1692. ThisRes.m_screen_pitch,
  1693. FreeTables,
  1694. BookValues[EndIndex].ClockFreq,
  1695. &pmode);
  1696. }
  1697. if (NumPixels <= MemAvail)
  1698. {
  1699. if (ModeInstalled)
  1700. {
  1701. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  1702. pmode->m_pixel_depth = 8;
  1703. pmode++; /* ptr to next mode table */
  1704. query->q_number_modes++;
  1705. }
  1706. /*
  1707. * Some DAC and card types don't support 1280x1024 noninterlaced.
  1708. */
  1709. if ((CurrentRes == RES_1280) &&
  1710. ((query->q_DAC_type == DAC_BT48x) ||
  1711. (query->q_DAC_type == DAC_ATT491) ||
  1712. (query->q_DAC_type == DAC_SC15026) ||
  1713. (query->q_DAC_type == DAC_ATI_68830) ||
  1714. (query->q_GraphicsWonder == TRUE)))
  1715. EndIndex = B1280F95;
  1716. /*
  1717. * Add "canned" mode tables
  1718. */
  1719. if ((FreeTables = MaxModes - query->q_number_modes) <= 0)
  1720. {
  1721. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1722. return ERROR_INSUFFICIENT_BUFFER;
  1723. }
  1724. query->q_number_modes += SetFixedModes(StartIndex,
  1725. EndIndex,
  1726. CLOCK_SINGLE,
  1727. 8,
  1728. ThisRes.m_screen_pitch,
  1729. FreeTables,
  1730. BookValues[EndIndex].ClockFreq,
  1731. &pmode);
  1732. }
  1733. /*
  1734. * 16, 24, and 32 BPP require a DAC which can support
  1735. * the selected pixel depth at the current resolution
  1736. * as well as enough memory.
  1737. *
  1738. * The BT48x and AT&T 49[123] DACs have separate mode
  1739. * tables for 4/8, 16, and 24 BPP (32 BPP not supported).
  1740. * Since the refresh rate for 16 and 24 BPP may differ from
  1741. * that for the paletted modes, we can't be sure that the
  1742. * same tables can be used for translation from VGA to
  1743. * 8514 format. Fortunately, the 16 and 24 BPP tables
  1744. * are always supposed to be written in 8514 format.
  1745. * If the high colour depth is not supported, the
  1746. * table will be empty.
  1747. */
  1748. if ((NumPixels*2 <= MemAvail) &&
  1749. (MaxDepth[query->q_DAC_type][CurrentRes] >= 16))
  1750. {
  1751. if ((query->q_DAC_type == DAC_BT48x) ||
  1752. (query->q_DAC_type == DAC_SC15026) ||
  1753. (query->q_DAC_type == DAC_ATT491))
  1754. {
  1755. Multiplier = CLOCK_DOUBLE;
  1756. if (CurrentRes == RES_640)
  1757. {
  1758. Scratch = (UCHAR)fill_mode_table_m(0x49, pmode, ee);
  1759. }
  1760. else if (CurrentRes == RES_800)
  1761. {
  1762. Scratch = (UCHAR)fill_mode_table_m(0x67, pmode, ee);
  1763. EndIndex = B800F60; /* 70 Hz and up not supported at 16BPP */
  1764. }
  1765. else /* Should never hit this case */
  1766. {
  1767. Scratch = 0;
  1768. }
  1769. /*
  1770. * If the mode table is present and in 8514 format,
  1771. * move to the next mode table and increment the
  1772. * table counter. If it is not usable, the table
  1773. * will be overwritten by the table for the next
  1774. * resolution.
  1775. */
  1776. if (ModeInstalled && (Scratch != 0))
  1777. {
  1778. pmode->m_screen_pitch = ThisRes.m_screen_pitch;
  1779. pmode->m_pixel_depth = 16;
  1780. pmode->Refresh = DEFAULT_REFRESH;
  1781. pmode++; /* ptr to next mode table */
  1782. query->q_number_modes++;
  1783. }
  1784. }
  1785. else
  1786. {
  1787. Multiplier = CLOCK_SINGLE;
  1788. if (ModeInstalled)
  1789. {
  1790. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  1791. pmode->m_pixel_depth = 16;
  1792. pmode++; /* ptr to next mode table */
  1793. query->q_number_modes++;
  1794. }
  1795. /*
  1796. * If this is a Graphics Wonder with a TI34075 DAC
  1797. * (only other DAC is BT48x, which is handled in
  1798. * "if" section above), 70 Hz and up are not
  1799. * supported in 800x600 16BPP.
  1800. *
  1801. * On some but not all non-Graphics Wonder cards, 800x600
  1802. * 16BPP 72Hz will overdrive the DAC (cards with fast
  1803. * RAM are less likely to be affected than cards with
  1804. * slow RAM, VRAM or DRAM does not seem to make a
  1805. * difference). Since we have no way to tell whether
  1806. * or not any given card is affected, we must lock out
  1807. * this mode for all non-Graphics Wonder cards (this
  1808. * mode and a number of others are already locked out
  1809. * on the Graphics Wonder).
  1810. */
  1811. if ((query->q_GraphicsWonder) && (CurrentRes == RES_800))
  1812. {
  1813. EndIndex = B800F60;
  1814. }
  1815. else if (CurrentRes == RES_800)
  1816. {
  1817. EndIndex = B800F70;
  1818. }
  1819. }
  1820. /*
  1821. * Add "canned" mode tables
  1822. */
  1823. if ((FreeTables = MaxModes - query->q_number_modes) <= 0)
  1824. {
  1825. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1826. return ERROR_INSUFFICIENT_BUFFER;
  1827. }
  1828. query->q_number_modes += SetFixedModes(StartIndex,
  1829. EndIndex,
  1830. Multiplier,
  1831. 16,
  1832. ThisRes.m_screen_pitch,
  1833. FreeTables,
  1834. BookValues[EndIndex].ClockFreq,
  1835. &pmode);
  1836. }
  1837. /*
  1838. * Our new source stream display driver needs a linear aperture
  1839. * in order to handle 24BPP. Since the display driver doesn't
  1840. * have access to the aperture information when it is deciding
  1841. * which modes to pass on to the display applet, it can't make
  1842. * the decision to reject 24BPP modes for cards with only a
  1843. * VGA aperture. This decision must therefore be made in the
  1844. * miniport, so in a paged aperture configuration there are no
  1845. * 24BPP modes for the display driver to accept or reject.
  1846. *
  1847. * On the Alpha, we can't use dense space on the Mach 32 LFB,
  1848. * so we treat it as a no-aperture case.
  1849. */
  1850. if (query->q_aperture_cfg == 0)
  1851. {
  1852. VideoDebugPrint((DEBUG_DETAIL, "24BPP not available because we don't have a linear aperture\n"));
  1853. continue;
  1854. }
  1855. #if defined(ALPHA)
  1856. VideoDebugPrint((DEBUG_DETAIL, "24BPP not available in sparse space on Alpha\n"));
  1857. continue;
  1858. #endif
  1859. /*
  1860. * 800x600 24BPP exhibits screen tearing unless the pitch
  1861. * is a multiple of 128 (only applies to Rev. 6, since Rev. 3
  1862. * and PCI implementations already have a pitch of 896).
  1863. * Other pixel depths are not affected, and other resolutions
  1864. * are already a multiple of 128 pixels wide.
  1865. *
  1866. * Expand the 800x600 pitch to 896 here, rather than for
  1867. * all pixel depths, because making the change for all
  1868. * pixel depths would disable 16BPP (which doesn't have
  1869. * the problem) on 1M cards. The screen pitch will only
  1870. * be 800 on cards which will exhibit this problem - don't
  1871. * check for a resolution of 800x600 because we don't want
  1872. * to cut the pitch from 1024 down to 896 if SPLIT_RASTERS
  1873. * is not defined.
  1874. */
  1875. if (ThisRes.m_screen_pitch == 800)
  1876. {
  1877. ThisRes.m_screen_pitch = 896;
  1878. NumPixels = (long) ThisRes.m_screen_pitch * 600;
  1879. }
  1880. if ((NumPixels*3 <= MemAvail) &&
  1881. (MaxDepth[query->q_DAC_type][CurrentRes] >= 24))
  1882. {
  1883. if ((query->q_DAC_type == DAC_BT48x) ||
  1884. (query->q_DAC_type == DAC_SC15026) ||
  1885. (query->q_DAC_type == DAC_ATT491))
  1886. {
  1887. Multiplier = CLOCK_TRIPLE;
  1888. if (CurrentRes == RES_640)
  1889. {
  1890. EndIndex = B640F60; /* Only refresh rate supported at 24BPP */
  1891. Scratch = (UCHAR)fill_mode_table_m(0x58, pmode, ee);
  1892. }
  1893. else /* Should never hit this case */
  1894. {
  1895. Scratch = 0;
  1896. }
  1897. /*
  1898. * If the mode table is present and in 8514 format,
  1899. * move to the next mode table and increment the
  1900. * table counter. If it is not usable, the table
  1901. * will be overwritten by the table for the next
  1902. * resolution.
  1903. */
  1904. if (ModeInstalled && (Scratch != 0))
  1905. {
  1906. pmode->m_screen_pitch = ThisRes.m_screen_pitch;
  1907. pmode->m_pixel_depth = 24;
  1908. pmode->Refresh = DEFAULT_REFRESH;
  1909. pmode++; /* ptr to next mode table */
  1910. query->q_number_modes++;
  1911. }
  1912. }
  1913. else
  1914. {
  1915. VideoPortMoveMemory(pmode, &ThisRes, sizeof(struct st_mode_table));
  1916. pmode->m_pixel_depth = 24;
  1917. /*
  1918. * Handle DACs that require higher pixel clocks for 24BPP.
  1919. */
  1920. Scratch = 0;
  1921. if ((query->q_DAC_type == DAC_STG1700) ||
  1922. (query->q_DAC_type == DAC_ATT498))
  1923. {
  1924. Multiplier = CLOCK_DOUBLE;
  1925. Scratch = (UCHAR)(pmode->m_clock_select & 0x007C) >> 2;
  1926. Scratch = DoubleClock(Scratch);
  1927. pmode->m_clock_select &= 0x0FF83;
  1928. pmode->m_clock_select |= (Scratch << 2);
  1929. pmode->ClockFreq <<= 1;
  1930. }
  1931. else if ((query->q_DAC_type == DAC_SC15021) ||
  1932. (query->q_DAC_type == DAC_STG1702) ||
  1933. (query->q_DAC_type == DAC_STG1703))
  1934. {
  1935. Multiplier = CLOCK_THREE_HALVES;
  1936. Scratch = (UCHAR)(pmode->m_clock_select & 0x007C) >> 2;
  1937. Scratch = ThreeHalvesClock(Scratch);
  1938. pmode->m_clock_select &= 0x0FF83;
  1939. pmode->m_clock_select |= (Scratch << 2);
  1940. pmode->ClockFreq *= 3;
  1941. pmode->ClockFreq >>= 1;
  1942. }
  1943. else
  1944. {
  1945. Multiplier = CLOCK_SINGLE;
  1946. if ((query->q_DAC_type == DAC_TI34075) && (CurrentRes == RES_800))
  1947. EndIndex = B800F70;
  1948. }
  1949. /*
  1950. * If we needed to alter the clock frequency, and couldn't
  1951. * generate an appropriate selector/divisor pair,
  1952. * then ignore this mode.
  1953. */
  1954. if (ModeInstalled && (Scratch != 0x0FF))
  1955. {
  1956. pmode++; /* ptr to next mode table */
  1957. query->q_number_modes++;
  1958. }
  1959. /*
  1960. * If this is a Graphics Wonder with a TI34075 DAC
  1961. * (only other DAC is BT48x, which is handled in
  1962. * "if" section above), 72 Hz is not supported in
  1963. * 640x480 24BPP.
  1964. */
  1965. if ((query->q_GraphicsWonder) && (CurrentRes == RES_640))
  1966. {
  1967. EndIndex = B640F60;
  1968. }
  1969. }
  1970. /*
  1971. * Add "canned" mode tables
  1972. */
  1973. if ((FreeTables = MaxModes - query->q_number_modes) <= 0)
  1974. {
  1975. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1976. return ERROR_INSUFFICIENT_BUFFER;
  1977. }
  1978. query->q_number_modes += SetFixedModes(StartIndex,
  1979. EndIndex,
  1980. Multiplier,
  1981. 24,
  1982. ThisRes.m_screen_pitch,
  1983. FreeTables,
  1984. BookValues[EndIndex].ClockFreq,
  1985. &pmode);
  1986. }
  1987. } /* end for (list of resolutions) */
  1988. query->q_sizeof_struct = query->q_number_modes * sizeof(struct st_mode_table) + sizeof(struct query_structure);
  1989. return NO_ERROR;
  1990. } /* QueryMach32 */
  1991. /****************************************************************
  1992. * fill_mode_table_m
  1993. * INPUT: table_offset = EEPROM address to start of table
  1994. * pmode = ptr to mode table to fill in
  1995. *
  1996. * RETURN: Nonzero if EEPROM data was in 8514 format.
  1997. * Zero if EEPROM data was in VGA format. Only those
  1998. * table entries which are the same in both formats
  1999. * will be filled in.
  2000. *
  2001. ****************************************************************/
  2002. short fill_mode_table_m(WORD table_offset, struct st_mode_table *pmode,
  2003. struct st_eeprom_data *ee)
  2004. {
  2005. WORD kk;
  2006. /*
  2007. * Fill in the values which are the same in 8514 and VGA formats.
  2008. */
  2009. pmode->control = (ee->EEread) ((WORD)(table_offset+0));
  2010. pmode->m_pixel_depth = (pmode->control >> 8) & 0x07;
  2011. pmode->m_reserved = table_offset; /* EEPROM word with start of mode table */
  2012. /*
  2013. * Check the VGA/8514 mode bit of the control word.
  2014. * If the parameters are in VGA format, fail so can be translated
  2015. */
  2016. if (!(pmode->control & FMT_8514))
  2017. return 0;
  2018. /*
  2019. * The parameters in the EEPROM are in 8514 format, so we can
  2020. * fill in the structure.
  2021. */
  2022. kk = (ee->EEread) ((WORD)(table_offset+3));
  2023. pmode->m_h_total = (kk >> 8) & 0xFF;
  2024. pmode->m_h_disp = kk & 0xFF;
  2025. pmode->m_x_size = (pmode->m_h_disp+1) * 8;
  2026. kk = (ee->EEread) ((WORD)(table_offset+4));
  2027. pmode->m_h_sync_strt = (kk >> 8) & 0xFF;
  2028. pmode->m_h_sync_wid = kk & 0xFF;
  2029. kk = (ee->EEread) ((WORD)(table_offset+8));
  2030. pmode->m_v_sync_wid = (kk >> 8) & 0xFF;
  2031. pmode->m_disp_cntl = kk & 0xFF;
  2032. pmode->m_v_total = (ee->EEread) ((WORD)(table_offset+5));
  2033. pmode->m_v_disp = (ee->EEread) ((WORD)(table_offset+6));
  2034. // y_size is derived by removing bit 2
  2035. pmode->m_y_size = (((pmode->m_v_disp >> 1) & 0xFFFC) | (pmode->m_v_disp & 0x03)) +1;
  2036. pmode->m_v_sync_strt = (ee->EEread) ((WORD)(table_offset+7));
  2037. /*
  2038. * On some cards, the vertical information may be stored in skip-1-2
  2039. * format instead of the normal skip-2 format. If this happens, m_y_size
  2040. * will exceed m_x_size (we don't support any resolutions that are
  2041. * taller than they are wide). Re-calculate m_y_size for skip-1-2 format.
  2042. */
  2043. if (pmode->m_y_size > pmode->m_x_size)
  2044. {
  2045. pmode->m_y_size = (((pmode->m_v_disp >> 2) & 0xFFFE) | (pmode->m_v_disp & 0x01)) +1;
  2046. }
  2047. pmode->m_h_overscan = (ee->EEread) ((WORD)(table_offset+11));
  2048. pmode->m_v_overscan = (ee->EEread) ((WORD)(table_offset+12));
  2049. pmode->m_overscan_8b = (ee->EEread) ((WORD)(table_offset+13));
  2050. pmode->m_overscan_gr = (ee->EEread) ((WORD)(table_offset+14));
  2051. pmode->m_status_flags = ((ee->EEread) ((WORD)(table_offset+10)) >> 8) & 0xC0;
  2052. pmode->m_clock_select = (ee->EEread) ((WORD)(table_offset+9));
  2053. pmode->ClockFreq = GetFrequency((BYTE)((pmode->m_clock_select & 0x007C) >> 2));
  2054. kk = (ee->EEread) ((WORD)(table_offset+2));
  2055. pmode->m_vfifo_24 = (kk >> 8) & 0xFF;
  2056. pmode->m_vfifo_16 = kk & 0xFF;
  2057. return 1; // table filled in successfully
  2058. } /* fill_mode_table_m() */
  2059. /*
  2060. * BOOL BiosFillTable_m(ResWanted, BiosRaw, OutputTable, QueryPtr);
  2061. *
  2062. * short ResWanted; Indicates which resolution is wanted
  2063. * PUCHAR BiosRaw; Raw data read in from BIOS query function
  2064. * struct st_mode_table *OutputTable; Mode table to fill in
  2065. * struct query_structure *QueryPtr; Query structure for video card
  2066. *
  2067. * Fill in pixel depth-independent fields of OutputTable using
  2068. * CRT parameters retrieved from a BIOS query.
  2069. *
  2070. * Returns:
  2071. * TRUE if table filled in
  2072. * FALSE if table not filled in (resolution not supported?)
  2073. */
  2074. BOOL BiosFillTable_m(short ResWanted, PUCHAR BiosRaw,
  2075. struct st_mode_table *OutputTable,
  2076. struct query_structure *QueryPtr)
  2077. {
  2078. WORD ResFlag; /* Flag to show which mode is supported */
  2079. short PixelsWide; /* Horizontal resolution of desired mode */
  2080. long NumPixels; /* Number of pixels on-screen at desired resolution */
  2081. short Count; /* Loop counter */
  2082. struct query_structure *BiosQuery; /* QueryStructure read in by BIOS query */
  2083. struct st_mode_table *BiosMode; /* Pointer to first mode table returned by BIOS query */
  2084. /*
  2085. * Set up pointers to the query information and first mode table
  2086. * stored in BiosRaw.
  2087. */
  2088. BiosQuery = (struct query_structure *)BiosRaw;
  2089. BiosMode = (struct st_mode_table *)BiosRaw;
  2090. ((PUCHAR)BiosMode) += BiosQuery->q_mode_offset;
  2091. /*
  2092. * Determine which resolution we are looking for.
  2093. */
  2094. switch (ResWanted)
  2095. {
  2096. case 7:
  2097. ResFlag = VRES_640x480;
  2098. PixelsWide = 640;
  2099. /*
  2100. * 1024 pitch ONLY if NO aperture on a Mach32
  2101. */
  2102. #if !defined (SPLIT_RASTERS)
  2103. if (QueryPtr->q_aperture_cfg == 0)
  2104. OutputTable->m_screen_pitch = 1024;
  2105. else
  2106. #endif
  2107. OutputTable->m_screen_pitch = 640;
  2108. NumPixels = (long) OutputTable->m_screen_pitch * 480;
  2109. break;
  2110. case 8:
  2111. ResFlag = VRES_800x600;
  2112. PixelsWide = 800;
  2113. /*
  2114. * 1024 pitch ONLY if NO aperture on a Mach32
  2115. */
  2116. #if defined (SPLIT_RASTERS)
  2117. if (QueryPtr->q_asic_rev != CI_68800_3)
  2118. #else
  2119. if (QueryPtr->q_aperture_cfg == 0)
  2120. OutputTable->m_screen_pitch = 1024;
  2121. /*
  2122. * Original production revision has trouble with deep colour
  2123. * if screen pitch not divisible by 128.
  2124. */
  2125. else if (QueryPtr->q_asic_rev != CI_68800_3)
  2126. #endif
  2127. OutputTable->m_screen_pitch = 896;
  2128. else
  2129. OutputTable->m_screen_pitch = 800;
  2130. NumPixels = (long) OutputTable->m_screen_pitch * 600;
  2131. break;
  2132. case 9:
  2133. ResFlag = VRES_1024x768;
  2134. PixelsWide = 1024;
  2135. OutputTable->m_screen_pitch = 1024;
  2136. NumPixels = (long) OutputTable->m_screen_pitch * 768;
  2137. break;
  2138. case 10:
  2139. ResFlag = VRES_1280x1024;
  2140. PixelsWide = 1280;
  2141. OutputTable->m_screen_pitch = 1280;
  2142. NumPixels = (long) OutputTable->m_screen_pitch * 1024;
  2143. /*
  2144. * 68800-3 cannot support 4 bpp with 1 meg ram.
  2145. */
  2146. if ((QueryPtr->q_asic_rev == CI_68800_3) && (QueryPtr->q_memory_size == VRAM_1mb))
  2147. NumPixels *= 2; /* Ensures mode failure */
  2148. break;
  2149. case 11:
  2150. ResFlag = VRES_ALT_1;
  2151. PixelsWide = 1120;
  2152. OutputTable->m_screen_pitch = 1120;
  2153. NumPixels = (long) OutputTable->m_screen_pitch * 750;
  2154. break;
  2155. }
  2156. /*
  2157. * Check if the card is configured for the desired mode.
  2158. */
  2159. for (Count = 0; Count < BiosQuery->q_number_modes; Count++)
  2160. {
  2161. /*
  2162. * If the current mode is the one we want, go to the
  2163. * next step. Otherwise, look at the next mode table.
  2164. */
  2165. if (BiosMode->m_x_size == PixelsWide)
  2166. break;
  2167. else
  2168. ((PUCHAR)BiosMode) += BiosQuery->q_sizeof_mode;
  2169. }
  2170. /*
  2171. * Special case: If 1024x768 is not configured, assume that
  2172. * it is available at 87Hz interlaced (Windows 3.1 compatibility).
  2173. */
  2174. if ((Count == BiosQuery->q_number_modes) && (PixelsWide == 1024))
  2175. {
  2176. BookVgaTable(B1024F87, OutputTable);
  2177. QueryPtr->q_status_flags |= ResFlag;
  2178. return TRUE;
  2179. }
  2180. /*
  2181. * All other cases where mode is not configured: report
  2182. * that the mode is not available.
  2183. */
  2184. else if (Count == BiosQuery->q_number_modes)
  2185. return FALSE;
  2186. /*
  2187. * We have found the mode table for the current resolution.
  2188. * Transfer it to OutputTable.
  2189. */
  2190. QueryPtr->q_status_flags |= ResFlag;
  2191. OutputTable->m_h_total = BiosMode->m_h_total;
  2192. OutputTable->m_h_disp = BiosMode->m_h_disp;
  2193. OutputTable->m_x_size = BiosMode->m_x_size;
  2194. OutputTable->m_h_sync_strt = BiosMode->m_h_sync_strt;
  2195. OutputTable->m_h_sync_wid = BiosMode->m_h_sync_wid;
  2196. OutputTable->m_v_total = BiosMode->m_v_total;
  2197. OutputTable->m_v_disp = BiosMode->m_v_disp;
  2198. OutputTable->m_y_size = BiosMode->m_y_size;
  2199. OutputTable->m_v_sync_strt = BiosMode->m_v_sync_strt;
  2200. OutputTable->m_v_sync_wid = BiosMode->m_v_sync_wid;
  2201. OutputTable->m_disp_cntl = BiosMode->m_disp_cntl;
  2202. OutputTable->m_clock_select = BiosMode->m_clock_select;
  2203. OutputTable->ClockFreq = GetFrequency((BYTE)((OutputTable->m_clock_select & 0x007C) >> 2));
  2204. OutputTable->m_h_overscan = BiosMode->m_h_overscan;
  2205. OutputTable->m_v_overscan = BiosMode->m_v_overscan;
  2206. OutputTable->m_overscan_8b = BiosMode->m_overscan_8b;
  2207. OutputTable->m_overscan_gr = BiosMode->m_overscan_gr;
  2208. OutputTable->m_status_flags = BiosMode->m_status_flags;
  2209. /*
  2210. * Assume 8 FIFO entries for 16 and 24 bit colour.
  2211. */
  2212. OutputTable->m_vfifo_24 = 8;
  2213. OutputTable->m_vfifo_16 = 8;
  2214. return TRUE;
  2215. } /* BiosFillTable_m() */
  2216. /*
  2217. * static UCHAR BrooktreeOrATT_m(void);
  2218. *
  2219. * Function to determine whether the DAC is a BT48x, a SC15026,
  2220. * or an AT&T 49x. These three DAC families are incompatible,
  2221. * but CONFIG_STATUS_1 contains the same value for all.
  2222. *
  2223. * Returns:
  2224. * DAC_BT48x if Brooktree DAC found
  2225. * DAC_ATT491 if AT&T 49[123] DAC found
  2226. * DAC_SC15026 if Sierra SC15026 DAC found
  2227. *
  2228. * NOTE: Results are undefined if called after CONFIG_STATUS_1
  2229. * reports a DAC that does not belong to either of these
  2230. * two families.
  2231. */
  2232. static UCHAR BrooktreeOrATT_m(void)
  2233. {
  2234. BYTE OriginalMask; /* Original value from VGA DAC_MASK register */
  2235. WORD ValueRead; /* Value read during AT&T 490 check */
  2236. BYTE Scratch; /* Temporary variable */
  2237. short RetVal; /* Value to be returned */
  2238. /*
  2239. * Get the DAC to a known state and get the original value
  2240. * from the VGA DAC_MASK register.
  2241. */
  2242. ClrDacCmd_m(TRUE);
  2243. OriginalMask = LioInp(regVGA_END_BREAK_PORT, 6); /* VGA DAC_MASK */
  2244. /*
  2245. * Re-clear the DAC state, and set the extended register
  2246. * programming flag in the DAC command register.
  2247. */
  2248. ClrDacCmd_m(TRUE);
  2249. Scratch = (BYTE)((OriginalMask & 0x00FF) | 0x10);
  2250. LioOutp(regVGA_END_BREAK_PORT, Scratch, 6); /* VGA DAC_MASK */
  2251. /*
  2252. * Select ID register byte #1, and read its contents.
  2253. */
  2254. LioOutp(regVGA_END_BREAK_PORT, 0x09, 7); /* Look-up table read index */
  2255. Scratch = LioInp(regVGA_END_BREAK_PORT, 8); /* Look-up table write index */
  2256. /*
  2257. * Put the DAC back in a known state and restore
  2258. * the original pixel mask value.
  2259. */
  2260. ClrDacCmd_m(TRUE);
  2261. LioOutp(regVGA_END_BREAK_PORT, OriginalMask, 6); /* VGA DAC_MASK */
  2262. /*
  2263. * Sierra SC15026 DACs will have 0x53 in ID register byte 1.
  2264. */
  2265. if (Scratch == 0x53)
  2266. {
  2267. VideoDebugPrint((DEBUG_DETAIL, "BrooktreeOrATT_m() - SC15026 found\n"));
  2268. return DAC_SC15026;
  2269. }
  2270. /*
  2271. * Get the DAC to a known state and get the original value
  2272. * from the VGA DAC_MASK register. Assume AT&T DAC.
  2273. */
  2274. ClrDacCmd_m(FALSE);
  2275. OriginalMask = LioInp(regVGA_END_BREAK_PORT, 6); /* VGA DAC_MASK */
  2276. RetVal = DAC_ATT491;
  2277. /*
  2278. * Check the two opposite alternating bit patterns. If both succeed,
  2279. * this is an AT&T 491 DAC. If either or both fails, it is either
  2280. * another AT&T DAC or a Brooktree DAC. In either case, restore
  2281. * the value from the VGA DAC_MASK register, since the test will
  2282. * have corrupted it.
  2283. */
  2284. if (!ChkATTDac_m(0x0AA))
  2285. {
  2286. RetVal = DAC_BT48x;
  2287. }
  2288. if (!ChkATTDac_m(0x055))
  2289. {
  2290. RetVal = DAC_BT48x;
  2291. }
  2292. ClrDacCmd_m(FALSE);
  2293. LioOutp(regVGA_END_BREAK_PORT, OriginalMask, 6); /* VGA DAC_MASK */
  2294. LioOutp(regVGA_END_BREAK_PORT, 0x0FF, 6); /* VGA DAC_MASK */
  2295. /*
  2296. * If we know that the DAC is an AT&T 491, we don't need
  2297. * to do further testing.
  2298. */
  2299. if (RetVal == DAC_ATT491)
  2300. {
  2301. VideoDebugPrint((DEBUG_DETAIL, "BrooktreeOrATT_m() - AT&T 491 found\n"));
  2302. return (UCHAR)RetVal;
  2303. }
  2304. /*
  2305. * The DAC is either an AT&T 490 or a Brooktree 48x. Determine
  2306. * which one.
  2307. */
  2308. ClrDacCmd_m(TRUE); /* Get the DAC to a known state */
  2309. LioOutp(regVGA_END_BREAK_PORT, 0x0FF, 6); /* VGA DAC_MASK */
  2310. ClrDacCmd_m(TRUE);
  2311. Scratch = LioInp(regVGA_END_BREAK_PORT, 6); /* VGA DAC_MASK */
  2312. ValueRead = Scratch << 8;
  2313. ClrDacCmd_m(TRUE);
  2314. LioOutp(regVGA_END_BREAK_PORT, 0x07F, 6); /* VGA DAC_MASK */
  2315. ClrDacCmd_m(TRUE);
  2316. Scratch = LioInp(regVGA_END_BREAK_PORT, 6); /* VGA DAC_MASK */
  2317. ValueRead |= Scratch;
  2318. ValueRead &= 0x0E0E0;
  2319. ClrDacCmd_m(TRUE);
  2320. LioOutp(regVGA_END_BREAK_PORT, 0, 6); /* VGA_DAC_MASK */
  2321. if (ValueRead == 0x0E000)
  2322. {
  2323. VideoDebugPrint((DEBUG_DETAIL, "BrooktreeOrATT_m() - AT&T 490 found\n"));
  2324. return DAC_ATT491;
  2325. }
  2326. else
  2327. {
  2328. VideoDebugPrint((DEBUG_DETAIL, "BrooktreeOrATT_m() - BT48x found\n"));
  2329. /*
  2330. * The test to find an AT&T 491 scrambles the DAC_MASK register
  2331. * on a BT48x. Simply resetting this register doesn't work -
  2332. * the DAC needs to be re-initialized. This is done when the
  2333. * video mode is set, but for now the "blue screen" winds up
  2334. * as magenta on blue instead of white on blue.
  2335. *
  2336. * This "blue screen" change is harmless, but may result in
  2337. * user complaints. To get around it, change palette entry 5
  2338. * from magenta to white.
  2339. */
  2340. LioOutp(regVGA_END_BREAK_PORT, 5, 8); /* VGA DAC_W_INDEX */
  2341. LioOutp(regVGA_END_BREAK_PORT, 0x2A, 9); /* VGA DAC_DATA */
  2342. LioOutp(regVGA_END_BREAK_PORT, 0x2A, 9); /* VGA DAC_DATA */
  2343. LioOutp(regVGA_END_BREAK_PORT, 0x2A, 9); /* VGA DAC_DATA */
  2344. return DAC_BT48x;
  2345. }
  2346. } /* BrooktreeOrATT_m() */
  2347. /*
  2348. * static BOOL ChkATTDac_m(MaskVal);
  2349. *
  2350. * BYTE MaskVal; Value to write to VGA DAC_MASK register
  2351. *
  2352. * Low-level test routine called by BrooktreeOrATT_m() to determine
  2353. * whether an AT&T 491 DAC is present.
  2354. *
  2355. * Returns:
  2356. * TRUE if AT&T 491 DAC found
  2357. * FALSE if AT&T 491 DAC not found (may still be other AT&T DAC)
  2358. */
  2359. static BOOL ChkATTDac_m(BYTE MaskVal)
  2360. {
  2361. BYTE ValueRead; /* Value read back from VGA DAC_MASK register */
  2362. ClrDacCmd_m(FALSE); /* Get things to a known state */
  2363. LioOutp(regVGA_END_BREAK_PORT, MaskVal, 6); /* VGA DAC_MASK */
  2364. short_delay();
  2365. LioOutp(regVGA_END_BREAK_PORT, (BYTE)(~MaskVal), 6); /* VGA DAC_MASK */
  2366. ClrDacCmd_m(FALSE); /* See if inverted value was cleared */
  2367. ValueRead = LioInp(regVGA_END_BREAK_PORT, 6); /* VGA DAC_MASK */
  2368. return (ValueRead == MaskVal);
  2369. } /* ChkATTDac_m() */
  2370. /*
  2371. * static void ClrDacCmd_m(ReadIndex);
  2372. *
  2373. * BOOL ReadIndex; TRUE if VGA DAC_W_INDEX must be read
  2374. *
  2375. * Read various VGA registers from the DAC. This is done as part
  2376. * of the BT48x/ATT491 identification.
  2377. */
  2378. static void ClrDacCmd_m(BOOL ReadIndex)
  2379. {
  2380. short Count; /* Loop counter */
  2381. BYTE Dummy; /* Used to collect the values we read */
  2382. if (ReadIndex)
  2383. {
  2384. Dummy = LioInp(regVGA_END_BREAK_PORT, 8); /* VGA DAC_W_INDEX */
  2385. }
  2386. for (Count = 4; Count > 0; Count--)
  2387. {
  2388. short_delay();
  2389. Dummy = LioInp(regVGA_END_BREAK_PORT, 6); /* VGA DAC_MASK */
  2390. }
  2391. return;
  2392. } /* ClrDacCmd_m() */
  2393. /***************************************************************************
  2394. *
  2395. * static UCHAR ThompsonOrATT_m(void);
  2396. *
  2397. * DESCRIPTION:
  2398. * Checks the AT&T 498 device identification number register to
  2399. * determine whether we are dealing with an AT&T 498 or a
  2400. * STG 1700 DAC (both types report the same value in CONFIG_STATUS_1).
  2401. * This is a non-destructive test, since no register writes
  2402. * are involved.
  2403. *
  2404. * RETURN VALUE:
  2405. * DAC_STG1700 if S.G. Thompson 1700 DAC found
  2406. * DAC_ATT498 if AT&T 498 DAC found
  2407. *
  2408. * NOTE:
  2409. * Results are undefined if called after CONFIG_STATUS_1 reports
  2410. * a DAC that does not belong to either of these two families.
  2411. *
  2412. * GLOBALS CHANGED:
  2413. * none
  2414. *
  2415. * CALLED BY:
  2416. * short_query_m()
  2417. *
  2418. * AUTHOR:
  2419. * Robert Wolff
  2420. *
  2421. * CHANGE HISTORY:
  2422. *
  2423. * TEST HISTORY:
  2424. *
  2425. ***************************************************************************/
  2426. static UCHAR ThompsonOrATT_m(void)
  2427. {
  2428. BYTE Scratch; /* Temporary variable */
  2429. UCHAR DacType; /* Type of DAC we are dealing with */
  2430. VideoDebugPrint((DEBUG_NORMAL, "ThompsonOrATT_m() entry\n"));
  2431. /*
  2432. * The extended registers hidden behind DAC_MASK on the AT&T 498
  2433. * and STG1700 are accessed by making a specified number of reads
  2434. * from the DAC_MASK register. Read from another register to reset
  2435. * the read counter to 0.
  2436. */
  2437. Scratch = INP(DAC_W_INDEX);
  2438. /*
  2439. * The AT&T 498 Manufacturer Identification Register is accessed on
  2440. * the sixth read from DAC_MASK, and the Device Identification
  2441. * Register is accessed on the seventh. If these registers contain
  2442. * 0x84 and 0x98 respectively, then this is an AT&T 498. Initially
  2443. * assume that an AT&T 498 is present.
  2444. */
  2445. DacType = DAC_ATT498;
  2446. Scratch = INP(DAC_MASK);
  2447. Scratch = INP(DAC_MASK);
  2448. Scratch = INP(DAC_MASK);
  2449. Scratch = INP(DAC_MASK);
  2450. Scratch = INP(DAC_MASK);
  2451. Scratch = INP(DAC_MASK);
  2452. if (Scratch != 0x84)
  2453. {
  2454. VideoDebugPrint((DEBUG_DETAIL, "STG1700 found\n"));
  2455. DacType = DAC_STG1700;
  2456. }
  2457. Scratch = INP(DAC_MASK);
  2458. if (Scratch != 0x98)
  2459. {
  2460. VideoDebugPrint((DEBUG_DETAIL, "STG1700 found\n"));
  2461. DacType = DAC_STG1700;
  2462. }
  2463. VideoDebugPrint((DEBUG_DETAIL, "If no STG1700 message, AT&T498 found\n"));
  2464. /*
  2465. * Reset the read counter so subsequent accesses to DAC_MASK don't
  2466. * accidentally write a hidden register.
  2467. */
  2468. Scratch = INP(DAC_W_INDEX);
  2469. return DacType;
  2470. } /* ThompsonOrATT_m() */
  2471. /***************************************************************************
  2472. *
  2473. * static UCHAR SierraOrThompson_m(void);
  2474. *
  2475. * DESCRIPTION:
  2476. * Checks the first 2 bytes of the Sierra SC15021 device
  2477. * identification register to determine whether we are dealing
  2478. * with an SC15021 or a STG1702/1703 in native mode (STG170x
  2479. * can also be strapped to emulate the STG1700, but this DAC
  2480. * has different capabilities, and so strapped STG170x DACs won't
  2481. * be reported as SC15021).
  2482. *
  2483. * RETURN VALUE:
  2484. * DAC_STG1702 if S.G. Thompson 1702/1703 DAC found
  2485. * DAC_SC15021 if Sierra SC15021 DAC found
  2486. *
  2487. * NOTE:
  2488. * Results are undefined if called after CONFIG_STATUS_1 reports
  2489. * a DAC that does not belong to either of these two families.
  2490. *
  2491. * GLOBALS CHANGED:
  2492. * none
  2493. *
  2494. * CALLED BY:
  2495. * short_query_m()
  2496. *
  2497. * AUTHOR:
  2498. * Robert Wolff
  2499. *
  2500. * CHANGE HISTORY:
  2501. *
  2502. * TEST HISTORY:
  2503. *
  2504. ***************************************************************************/
  2505. static UCHAR SierraOrThompson_m(void)
  2506. {
  2507. BYTE Scratch; /* Temporary variable */
  2508. UCHAR DacType; /* Type of DAC we are dealing with */
  2509. VideoDebugPrint((DEBUG_NORMAL, "SierraOrThompson_m() entry\n"));
  2510. /*
  2511. * The extended registers hidden behind DAC_MASK on the SC15021
  2512. * and STG1702/1703 are accessed by making a specified number of
  2513. * reads from the DAC_MASK register. Read from another register
  2514. * to reset the read counter to 0.
  2515. */
  2516. Scratch = INP(DAC_W_INDEX);
  2517. /*
  2518. * Set the extended register programming flag in the DAC command
  2519. * register so we don't need to hit the "magic" reads for each
  2520. * register access. Initially assume that a SC15021 is present.
  2521. */
  2522. DacType = DAC_SC15021;
  2523. Scratch = INP(DAC_MASK);
  2524. Scratch = INP(DAC_MASK);
  2525. Scratch = INP(DAC_MASK);
  2526. Scratch = INP(DAC_MASK);
  2527. OUTP(DAC_MASK, 0x10);
  2528. /*
  2529. * Check the ID registers. If either of them doesn't match the
  2530. * values for the SC15021, we are dealing with a STG1702/1703.
  2531. */
  2532. OUTP(DAC_R_INDEX, 0x09);
  2533. Scratch = INP(DAC_W_INDEX);
  2534. if (Scratch != 0x53)
  2535. {
  2536. VideoDebugPrint((DEBUG_DETAIL, "STG1702/1703 found\n"));
  2537. DacType = DAC_STG1702;
  2538. }
  2539. OUTP(DAC_R_INDEX, 0x0A);
  2540. Scratch = INP(DAC_W_INDEX);
  2541. if (Scratch != 0x3A)
  2542. {
  2543. VideoDebugPrint((DEBUG_DETAIL, "STG1702/1703 found\n"));
  2544. DacType = DAC_STG1702;
  2545. }
  2546. VideoDebugPrint((DEBUG_DETAIL, "If no STG1702/1703 message, SC15021 found\n"));
  2547. /*
  2548. * Clear the ERPF and reset the read counter so subsequent accesses
  2549. * to DAC_MASK don't accidentally write a hidden register.
  2550. */
  2551. OUTP(DAC_MASK, 0);
  2552. Scratch = INP(DAC_W_INDEX);
  2553. return DacType;
  2554. } /* SierraOrThompson_m() */
  2555. /***************************************************************************
  2556. *
  2557. * short GetTrueMemSize_m(void);
  2558. *
  2559. * DESCRIPTION:
  2560. * Determine the amount of video memory installed on the graphics card.
  2561. * This is done because the 68800-6 contains a bug which causes MISC_OPTIONS
  2562. * to report 1M rather than the true amount of memory.
  2563. *
  2564. * RETURN VALUE:
  2565. * Enumerated value for amount of memory (VRAM_512k, VRAM_1mb, VRAM_2mb,
  2566. * or VRAM_4mb)
  2567. *
  2568. * GLOBALS CHANGED:
  2569. * none
  2570. *
  2571. * CALLED BY:
  2572. * QueryMach32()
  2573. *
  2574. * AUTHOR:
  2575. * Robert Wolff
  2576. *
  2577. * CHANGE HISTORY:
  2578. *
  2579. * TEST HISTORY:
  2580. *
  2581. ***************************************************************************/
  2582. short GetTrueMemSize_m(void)
  2583. {
  2584. USHORT SavedPixel; /* Saved value from pixel being tested */
  2585. /*
  2586. * Switch into accelerator mode, and initialize the engine to
  2587. * a pitch of 1024 pixels in 16BPP.
  2588. */
  2589. SetupRestoreEngine_m(SETUP_ENGINE);
  2590. /*
  2591. * Given the current engine settings, only a 4M card will have
  2592. * enough memory to back up the 1025th line of the display.
  2593. * Since the pixel coordinates are zero-based, line 1024 will
  2594. * be the first one which is only backed on 4M cards.
  2595. *
  2596. * Save the first pixel of line 1024, paint it in our test colour,
  2597. * then read it back. If it is the same as the colour we painted
  2598. * it, then this is a 4M card.
  2599. */
  2600. SavedPixel = ReadPixel_m(0, 1024);
  2601. WritePixel_m(0, 1024, TEST_COLOUR);
  2602. if (ReadPixel_m(0, 1024) == TEST_COLOUR)
  2603. {
  2604. /*
  2605. * This is a 4M card. Restore the pixel and the graphics engine.
  2606. */
  2607. VideoDebugPrint((DEBUG_NORMAL, "GetTrueMemSize_m() found 4M card\n"));
  2608. WritePixel_m(0, 1024, SavedPixel);
  2609. SetupRestoreEngine_m(RESTORE_ENGINE);
  2610. return VRAM_4mb;
  2611. }
  2612. /*
  2613. * We know this card has 2M or less. On a 1M card, the first 2M
  2614. * of the card's memory will have even doublewords backed by
  2615. * physical memory and odd doublewords unbacked.
  2616. *
  2617. * Pixels 0 and 1 of a row will be in the zeroth doubleword, while
  2618. * pixels 2 and 3 will be in the first. Check both pixels 2 and 3
  2619. * in case this is a pseudo-1M card (one chip pulled to turn a 2M
  2620. * card into a 1M card).
  2621. */
  2622. SavedPixel = ReadPixel_m(2, 0);
  2623. WritePixel_m(2, 0, TEST_COLOUR);
  2624. if (ReadPixel_m(2, 0) == TEST_COLOUR)
  2625. {
  2626. /*
  2627. * This is a either a 2M card or a pseudo-1M card. Restore
  2628. * the pixel, then test the other half of the doubleword.
  2629. */
  2630. WritePixel_m(2, 0, SavedPixel);
  2631. SavedPixel = ReadPixel_m(3, 0);
  2632. WritePixel_m(3, 0, TEST_COLOUR);
  2633. if (ReadPixel_m(3, 0) == TEST_COLOUR)
  2634. {
  2635. /*
  2636. * This is a 2M card. Restore the pixel and the graphics engine.
  2637. */
  2638. VideoDebugPrint((DEBUG_NORMAL, "GetTrueMemSize_m() found 2M card\n"));
  2639. WritePixel_m(3, 0, SavedPixel);
  2640. SetupRestoreEngine_m(RESTORE_ENGINE);
  2641. return VRAM_2mb;
  2642. }
  2643. }
  2644. /*
  2645. * This is a either a 1M card or a 512k card. Test pixel 1, since
  2646. * it is an odd word in an even doubleword.
  2647. *
  2648. * NOTE: We have not received 512k cards for testing - this is an
  2649. * extrapolation of the 1M/2M determination code.
  2650. */
  2651. SavedPixel = ReadPixel_m(1, 0);
  2652. WritePixel_m(1, 0, TEST_COLOUR);
  2653. if (ReadPixel_m(1, 0) == TEST_COLOUR)
  2654. {
  2655. /*
  2656. * This is a 1M card. Restore the pixel and the graphics engine.
  2657. */
  2658. VideoDebugPrint((DEBUG_NORMAL, "GetTrueMemSize_m() found 1M card\n"));
  2659. WritePixel_m(1, 0, SavedPixel);
  2660. SetupRestoreEngine_m(RESTORE_ENGINE);
  2661. return VRAM_1mb;
  2662. }
  2663. /*
  2664. * This is a 512k card.
  2665. */
  2666. VideoDebugPrint((DEBUG_NORMAL, "GetTrueMemSize_m() found 512k card\n"));
  2667. SetupRestoreEngine_m(RESTORE_ENGINE);
  2668. return VRAM_512k;
  2669. } /* GetTrueMemSize_m() */
  2670. /***************************************************************************
  2671. *
  2672. * void SetupRestoreEngine_m(DesiredStatus);
  2673. *
  2674. * int DesiredStatus; Whether the user wants to set up or restore
  2675. *
  2676. * DESCRIPTION:
  2677. * Set engine to 1024 pitch 16BPP with 512k of VGA memory,
  2678. * or restore the engine and boundary status, as selected by the user.
  2679. *
  2680. * GLOBALS CHANGED:
  2681. * none
  2682. *
  2683. * CALLED BY:
  2684. * GetTrueMemSize_m()
  2685. *
  2686. * AUTHOR:
  2687. * Robert Wolff
  2688. *
  2689. * CHANGE HISTORY:
  2690. *
  2691. * TEST HISTORY:
  2692. *
  2693. ***************************************************************************/
  2694. void SetupRestoreEngine_m(int DesiredStatus)
  2695. {
  2696. static WORD MiscOptions; /* Contents of MISC_OPTIONS register */
  2697. static WORD ExtGeConfig; /* Contents of EXT_GE_CONFIG register */
  2698. static WORD MemBndry; /* Contents of MEM_BNDRY register */
  2699. if (DesiredStatus == SETUP_ENGINE)
  2700. {
  2701. Passth8514_m(SHOW_ACCEL);
  2702. /*
  2703. * Set up a 512k VGA boundary so "blue screen" writes that happen
  2704. * when we are in accelerator mode won't show up in the wrong place.
  2705. */
  2706. MemBndry = INPW(MEM_BNDRY); /* Set up shared memory */
  2707. OUTPW(MEM_BNDRY, 0);
  2708. /*
  2709. * Save the contents of the MISC_OPTIONS register, then
  2710. * tell it that we have 4M of video memory. Otherwise,
  2711. * video memory will wrap when it hits the boundary
  2712. * in the MEM_SIZE_ALIAS field.
  2713. */
  2714. MiscOptions = INPW(MISC_OPTIONS);
  2715. OUTPW(MISC_OPTIONS, (WORD) (MiscOptions | MEM_SIZE_4M));
  2716. /*
  2717. * Set 16BPP with pitch of 1024. Only set up the drawing
  2718. * engine, and not the CRT, since the results of this test
  2719. * are not intended to be seen.
  2720. */
  2721. ExtGeConfig = INPW(R_EXT_GE_CONFIG);
  2722. OUTPW(EXT_GE_CONFIG, (WORD)(PIX_WIDTH_16BPP | ORDER_16BPP_565 | 0x000A));
  2723. OUTPW(GE_PITCH, (1024 >> 3));
  2724. OUTPW(GE_OFFSET_HI, 0);
  2725. OUTPW(GE_OFFSET_LO, 0);
  2726. }
  2727. else /* DesiredStatus == RESTORE_ENGINE */
  2728. {
  2729. /*
  2730. * Restore the memory boundary, MISC_OPTIONS register,
  2731. * and EXT_GE_CONFIG. It is not necessary to reset the
  2732. * drawing engine pitch and offset, because they don't
  2733. * affect what is displayed and they will be set to
  2734. * whatever values are needed when the desired video
  2735. * mode is set.
  2736. */
  2737. OUTPW(EXT_GE_CONFIG, ExtGeConfig);
  2738. OUTPW(MISC_OPTIONS, MiscOptions);
  2739. OUTPW(MEM_BNDRY, MemBndry);
  2740. /*
  2741. * Give the VGA control of the screen.
  2742. */
  2743. Passth8514_m(SHOW_VGA);
  2744. }
  2745. return;
  2746. } /* SetupRestoreEngine_m() */
  2747. /***************************************************************************
  2748. *
  2749. * USHORT ReadPixel_m(XPos, YPos);
  2750. *
  2751. * short XPos; X coordinate of pixel to read
  2752. * short YPos; Y coordinate of pixel to read
  2753. *
  2754. * DESCRIPTION:
  2755. * Read a single pixel from the screen.
  2756. *
  2757. * RETURN VALUE:
  2758. * Colour of pixel at the desired location.
  2759. *
  2760. * GLOBALS CHANGED:
  2761. * none
  2762. *
  2763. * CALLED BY:
  2764. * GetTrueMemSize_m()
  2765. *
  2766. * AUTHOR:
  2767. * Robert Wolff
  2768. *
  2769. * CHANGE HISTORY:
  2770. *
  2771. * TEST HISTORY:
  2772. *
  2773. ***************************************************************************/
  2774. USHORT ReadPixel_m(short XPos, short YPos)
  2775. {
  2776. USHORT RetVal;
  2777. /*
  2778. * Don't read if the engine is busy.
  2779. */
  2780. WaitForIdle_m();
  2781. /*
  2782. * Set up the engine to read colour data from the screen.
  2783. */
  2784. CheckFIFOSpace_m(SEVEN_WORDS);
  2785. OUTPW(RD_MASK, 0x0FFFF);
  2786. OUTPW(DP_CONFIG, (WORD)(FG_COLOR_SRC_BLIT | DATA_WIDTH | DRAW | DATA_ORDER));
  2787. OUTPW(CUR_X, XPos);
  2788. OUTPW(CUR_Y, YPos);
  2789. OUTPW(DEST_X_START, XPos);
  2790. OUTPW(DEST_X_END, (WORD)(XPos+1));
  2791. OUTPW(DEST_Y_END, (WORD)(YPos+1));
  2792. /*
  2793. * Wait for the engine to process the orders we just gave it and
  2794. * start asking for data.
  2795. */
  2796. CheckFIFOSpace_m(SIXTEEN_WORDS);
  2797. while (!(INPW(GE_STAT) & DATA_READY));
  2798. RetVal = INPW(PIX_TRANS);
  2799. WaitForIdle_m();
  2800. return RetVal;
  2801. } /* ReadPixel_m() */
  2802. /***************************************************************************
  2803. *
  2804. * void WritePixel_m(XPos, YPos, Colour);
  2805. *
  2806. * short XPos; X coordinate of pixel to read
  2807. * short YPos; Y coordinate of pixel to read
  2808. * short Colour; Colour to paint the pixel
  2809. *
  2810. * DESCRIPTION:
  2811. * Write a single pixel to the screen.
  2812. *
  2813. * GLOBALS CHANGED:
  2814. * none
  2815. *
  2816. * CALLED BY:
  2817. * GetTrueMemSize_m()
  2818. *
  2819. * AUTHOR:
  2820. * Robert Wolff
  2821. *
  2822. * CHANGE HISTORY:
  2823. *
  2824. * TEST HISTORY:
  2825. *
  2826. ***************************************************************************/
  2827. void WritePixel_m(short XPos, short YPos, short Colour)
  2828. {
  2829. /*
  2830. * Set up the engine to paint to the screen.
  2831. */
  2832. CheckFIFOSpace_m(EIGHT_WORDS);
  2833. OUTPW(DP_CONFIG, (WORD)(FG_COLOR_SRC_FG | DRAW | READ_WRITE));
  2834. OUTPW(ALU_FG_FN, MIX_FN_PAINT);
  2835. OUTPW(FRGD_COLOR, Colour);
  2836. OUTPW(CUR_X, XPos);
  2837. OUTPW(CUR_Y, YPos);
  2838. OUTPW(DEST_X_START, XPos);
  2839. OUTPW(DEST_X_END, (WORD)(XPos+1));
  2840. OUTPW(DEST_Y_END, (WORD)(YPos+1));
  2841. return;
  2842. } /* WritePixel_m() */
  2843. /***************************************************************************
  2844. *
  2845. * BOOL BlockWriteAvail_m(Query);
  2846. *
  2847. * struct query_structure *Query; Query information for the card
  2848. *
  2849. * DESCRIPTION:
  2850. * Test to see whether block write mode is available. This function
  2851. * assumes that the card has been set to an accelerated mode.
  2852. *
  2853. * RETURN VALUE:
  2854. * TRUE if this mode is available
  2855. * FALSE if it is not available
  2856. *
  2857. * GLOBALS CHANGED:
  2858. * None
  2859. *
  2860. * CALLED BY:
  2861. * IOCTL_VIDEO_SET_CURRENT_MODE packet of ATIMPStartIO()
  2862. *
  2863. * AUTHOR:
  2864. * Robert Wolff
  2865. *
  2866. * CHANGE HISTORY:
  2867. *
  2868. * TEST HISTORY:
  2869. *
  2870. ***************************************************************************/
  2871. BOOL BlockWriteAvail_m(struct query_structure *Query)
  2872. {
  2873. BOOL RetVal = TRUE;
  2874. ULONG ColourMask; /* Masks off unneeded bits of Colour */
  2875. ULONG Colour; /* Colour to use in testing */
  2876. USHORT LimitColumn; /* Used to determine when we have finished reading */
  2877. USHORT Column; /* Column being checked */
  2878. /*
  2879. * Block write mode is only possible on 68800-6 and later cards.
  2880. * If we don't have an appropriate card, then report that this
  2881. * mode is not available.
  2882. */
  2883. if ((Query->q_asic_rev != CI_68800_6) && (Query->q_asic_rev != CI_68800_AX))
  2884. return FALSE;
  2885. /*
  2886. * Block write is only available on VRAM cards.
  2887. */
  2888. if ((Query->q_memory_type == VMEM_DRAM_256Kx4) ||
  2889. (Query->q_memory_type == VMEM_DRAM_256Kx16) ||
  2890. (Query->q_memory_type == VMEM_DRAM_256Kx4_GRAP))
  2891. return FALSE;
  2892. /*
  2893. * Acceleration is not available for pixel depths above 16BPP.
  2894. * Since block write is only used when we are in an accelerated
  2895. * mode, it is not available for high pixel depths.
  2896. */
  2897. if (Query->q_pix_depth > 16)
  2898. return FALSE;
  2899. /*
  2900. * Set up according to the current pixel depth. At 16BPP, we must make
  2901. * one read per pixel, but at 8BPP we only make one read per two pixels,
  2902. * since we will be reading 16 bits at a time. Our display driver
  2903. * does not support 4BPP.
  2904. */
  2905. if (Query->q_pix_depth == 16)
  2906. {
  2907. ColourMask = 0x0000FFFF;
  2908. LimitColumn = 512;
  2909. }
  2910. else
  2911. {
  2912. ColourMask = 0x000000FF;
  2913. LimitColumn = 256;
  2914. }
  2915. /*
  2916. * Clear the block we will be testing.
  2917. */
  2918. CheckFIFOSpace_m(TEN_WORDS);
  2919. OUTPW(WRT_MASK, 0x0FFFF);
  2920. OUTPW(DEST_CMP_FN, 0);
  2921. OUTPW(DP_CONFIG, (WORD)(FG_COLOR_SRC_FG | DRAW | READ_WRITE));
  2922. OUTPW(ALU_FG_FN, MIX_FN_PAINT);
  2923. OUTPW(FRGD_COLOR, 0);
  2924. OUTPW(CUR_X, 0);
  2925. OUTPW(CUR_Y, 0);
  2926. OUTPW(DEST_X_START, 0);
  2927. OUTPW(DEST_X_END, 512);
  2928. OUTPW(DEST_Y_END, 1);
  2929. WaitForIdle_m();
  2930. /*
  2931. * To test block write mode, try painting each of the alternating bit
  2932. * patterns, then read the block back one pixel at a time. If there
  2933. * is at least one mismatch, then block write is not supported.
  2934. */
  2935. for (Colour = 0x5555; Colour < 0x10000; Colour *= 2)
  2936. {
  2937. /*
  2938. * Paint the block.
  2939. */
  2940. CheckFIFOSpace_m(ELEVEN_WORDS);
  2941. OUTPW(MISC_OPTIONS, (WORD)(INPW(MISC_OPTIONS) | BLK_WR_ENA));
  2942. OUTPW(WRT_MASK, 0x0FFFF);
  2943. OUTPW(DEST_CMP_FN, 0);
  2944. OUTPW(DP_CONFIG, (WORD)(FG_COLOR_SRC_FG | DRAW | READ_WRITE));
  2945. OUTPW(ALU_FG_FN, MIX_FN_PAINT);
  2946. OUTPW(FRGD_COLOR, (WORD)(Colour & ColourMask));
  2947. OUTPW(CUR_X, 0);
  2948. OUTPW(CUR_Y, 0);
  2949. OUTPW(DEST_X_START, 0);
  2950. OUTPW(DEST_X_END, 512);
  2951. OUTPW(DEST_Y_END, 1);
  2952. if(!WaitForIdle_m())
  2953. {
  2954. RetVal = FALSE;
  2955. break;
  2956. }
  2957. /*
  2958. * Set up the engine to read colour data from the screen.
  2959. */
  2960. CheckFIFOSpace_m(SEVEN_WORDS);
  2961. OUTPW(RD_MASK, 0x0FFFF);
  2962. OUTPW(DP_CONFIG, (WORD)(FG_COLOR_SRC_BLIT | DATA_WIDTH | DRAW | DATA_ORDER));
  2963. OUTPW(CUR_X, 0);
  2964. OUTPW(CUR_Y, 0);
  2965. OUTPW(DEST_X_START, 0);
  2966. OUTPW(DEST_X_END, 512);
  2967. OUTPW(DEST_Y_END, 1);
  2968. /*
  2969. * Wait for the engine to process the orders we just gave it and
  2970. * start asking for data.
  2971. */
  2972. CheckFIFOSpace_m(SIXTEEN_WORDS);
  2973. for (Column = 0; Column < LimitColumn; Column++)
  2974. {
  2975. /*
  2976. * Ensure that the next word is available to be read
  2977. */
  2978. while (!(INPW(GE_STAT) & DATA_READY));
  2979. /*
  2980. * If even one pixel is not the colour we tried to paint it,
  2981. * then block write is not available.
  2982. */
  2983. if (INPW(PIX_TRANS) != (WORD)Colour)
  2984. {
  2985. RetVal = FALSE;
  2986. }
  2987. }
  2988. }
  2989. /*
  2990. * If block write is unavailable, turn off the block write bit.
  2991. */
  2992. if (RetVal == FALSE)
  2993. OUTPW(MISC_OPTIONS, (WORD)(INPW(MISC_OPTIONS) & ~BLK_WR_ENA));
  2994. return RetVal;
  2995. } /* BlockWriteAvail_m() */
  2996. /***************************************************************************
  2997. *
  2998. * BOOL IsMioBug_m(Query);
  2999. *
  3000. * struct query_structure *Query; Query information for the card
  3001. *
  3002. * DESCRIPTION:
  3003. * Test to see whether the card has the multiple input/output
  3004. * hardware bug, which results in corrupted draw operations
  3005. * on fast machines.
  3006. *
  3007. * RETURN VALUE:
  3008. * TRUE if this bug is present
  3009. * FALSE if it is not present
  3010. *
  3011. * GLOBALS CHANGED:
  3012. * None
  3013. *
  3014. * CALLED BY:
  3015. * IOCTL_VIDEO_ATI_GET_MODE_INFORMATION packet of ATIMPStartIO()
  3016. *
  3017. * AUTHOR:
  3018. * Robert Wolff
  3019. *
  3020. * CHANGE HISTORY:
  3021. *
  3022. * TEST HISTORY:
  3023. *
  3024. ***************************************************************************/
  3025. BOOL IsMioBug_m(struct query_structure *Query)
  3026. {
  3027. /*
  3028. * This hardware problem is only present on 68800-3 VLB cards.
  3029. * Assume that all these cards are affected.
  3030. */
  3031. if ((Query->q_asic_rev == CI_68800_3) &&
  3032. (Query->q_system_bus_type != MicroChannel) &&
  3033. ((Query->q_bus_type == BUS_LB_386SX) ||
  3034. (Query->q_bus_type == BUS_LB_386DX) ||
  3035. (Query->q_bus_type == BUS_LB_486)))
  3036. {
  3037. VideoDebugPrint((DEBUG_DETAIL, "MIO bug found\n"));
  3038. return TRUE;
  3039. }
  3040. else
  3041. {
  3042. VideoDebugPrint((DEBUG_DETAIL, "MIO bug not found\n"));
  3043. return FALSE;
  3044. }
  3045. } /* IsMioBug_m() */
  3046. //******************** end of QUERY_M.C ***************************