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.

2036 lines
71 KiB

  1. /************************************************************************/
  2. /* */
  3. /* ATIOEM.C */
  4. /* */
  5. /* Copyright (c) 1993, ATI Technologies Incorporated. */
  6. /************************************************************************/
  7. /********************** PolyTron RCS Utilities
  8. $Revision: 1.20 $
  9. $Date: 01 May 1996 14:08:38 $
  10. $Author: RWolff $
  11. $Log: S:/source/wnt/ms11/miniport/archive/atioem.c_v $
  12. *
  13. * Rev 1.20 01 May 1996 14:08:38 RWolff
  14. * Locked out 24BPP on Alpha and on machines without LFB.
  15. *
  16. * Rev 1.19 23 Jan 1996 11:43:24 RWolff
  17. * Eliminated level 3 warnings, protected against false values of TARGET_BUILD.
  18. *
  19. * Rev 1.18 11 Jan 1996 19:35:58 RWolff
  20. * Added maximum pixel clock rate to all calls to SetFixedModes().
  21. * This is required as part of a Mach 64 fix.
  22. *
  23. * Rev 1.17 22 Dec 1995 14:52:52 RWolff
  24. * Switched to TARGET_BUILD to identify the NT version for which
  25. * the driver is being built.
  26. *
  27. * Rev 1.16 20 Jul 1995 17:26:54 mgrubac
  28. * Added support for VDIF files
  29. *
  30. * Rev 1.15 31 Mar 1995 11:51:36 RWOLFF
  31. * Changed from all-or-nothing debug print statements to thresholds
  32. * depending on importance of the message.
  33. *
  34. * Rev 1.14 23 Dec 1994 10:47:28 ASHANMUG
  35. * ALPHA/Chrontel-DAC
  36. *
  37. * Rev 1.13 18 Nov 1994 11:37:56 RWOLFF
  38. * Added support for Dell Sylvester, STG1703 DAC, and display driver
  39. * that can handle split rasters.
  40. *
  41. * Rev 1.12 14 Sep 1994 15:29:52 RWOLFF
  42. * Now reads in frequency table and monitor description from disk.
  43. * If disk-based frequency table is missing or invalid, loads default
  44. * OEM-specific frequency table if it is different from the retail
  45. * frequency table. If disk-based monitor description is missing or
  46. * invalid, reads installed modes in OEM-specific manner if the OEM
  47. * type is known. For unknown OEM types with no disk-based monitor
  48. * description, only predefined mode tables are listed.
  49. *
  50. * Rev 1.11 31 Aug 1994 16:20:06 RWOLFF
  51. * Changed includes to correspond to Daytona RC1, now skips over
  52. * 1152x864 (Mach 64-only mode, this module is for Mach 32), assumes
  53. * system is not a Premmia SE under NT retail because the definition
  54. * we use to look for this machine is not available under NT retail.
  55. *
  56. * Rev 1.10 19 Aug 1994 17:08:28 RWOLFF
  57. * Fixed aperture location bug on AST Premmia SE, added support for
  58. * SC15026 DAC and 1280x1024 70Hz and 74Hz, and pixel clock
  59. * generator independence.
  60. *
  61. * Rev 1.9 20 Jul 1994 13:01:56 RWOLFF
  62. * Added diagnostic print statements for DELL, now defaults to "worst"
  63. * (interlaced if available, else lowest frequency) refresh rate instead
  64. * of skipping the resolution if we get an invalid result when trying
  65. * to find which refresh rate is desired on a DELL Omniplex.
  66. *
  67. * Rev 1.8 12 Jul 1994 17:42:24 RWOLFF
  68. * Andre Vachon's changes: different way of allowing DELL users
  69. * to run without an ATIOEM field.
  70. *
  71. * Rev 1.7 11 Jul 1994 11:57:34 RWOLFF
  72. * No longer aborts if ATIOEM field is missing from registry. Some OEMs
  73. * auto-detect, and generic OEMs can use the "canned" mode tables,
  74. * so this field is no longer mandatory and someone removed it from
  75. * the registry sometime after Beta 2 for Daytona.
  76. *
  77. * Rev 1.6 15 Jun 1994 11:05:16 RWOLFF
  78. * No longer lists "canned" mode tables for Dell Omniplex, since these tables
  79. * assume the use of the same clock generator as on our retail cards, and
  80. * Dell uses a different clock generator.
  81. *
  82. * Rev 1.5 20 May 1994 16:07:12 RWOLFF
  83. * Fix for 800x600 screen tearing on Intel BATMAN PCI motherboards.
  84. *
  85. * Rev 1.4 18 May 1994 17:02:14 RWOLFF
  86. * Interlaced mode tables now report frame rate rather than vertical
  87. * scan frequency in the refresh rate field.
  88. *
  89. * Rev 1.3 12 May 1994 11:06:20 RWOLFF
  90. * Added refresh rate to OEM mode tables, sets up "canned" mode tables
  91. * for all OEMs except AST Premmia, no longer aborts if no OEM string
  92. * found either in ATIOEM registry entry or through auto-detection since
  93. * the "canned" mode tables will be available, no longer supports 32BPP,
  94. * since this module is for the Mach 8 and Mach 32.
  95. *
  96. * Rev 1.2 31 Mar 1994 15:06:20 RWOLFF
  97. * Added debugging code.
  98. *
  99. * Rev 1.1 07 Feb 1994 14:05:14 RWOLFF
  100. * Added alloc_text() pragmas to allow miniport to be swapped out when
  101. * not needed.
  102. *
  103. * Rev 1.0 31 Jan 1994 10:57:34 RWOLFF
  104. * Initial revision.
  105. Rev 1.7 24 Jan 1994 18:02:54 RWOLFF
  106. Pixel clock multiplication on BT48x and AT&T 49[123] DACs at 16 and 24 BPP
  107. is now done when mode tables are created rather than when mode is set.
  108. Rev 1.6 15 Dec 1993 15:25:26 RWOLFF
  109. Added support for SC15021 DAC, removed debug print statements.
  110. Rev 1.5 30 Nov 1993 18:12:28 RWOLFF
  111. Added support for AT&T 498 DAC, now doubles pixel clock at 32BPP for
  112. DACs that need it. Removed extra increment of mode table counter
  113. (previously, counter would show 1 more mode table than actually
  114. existed for each 24BPP mode table present that required clock doubling).
  115. Rev 1.4 05 Nov 1993 13:31:44 RWOLFF
  116. Added STG1700 DAC and Dell support
  117. Rev 1.2 08 Oct 1993 11:03:16 RWOLFF
  118. Removed debug breakpoint.
  119. Rev 1.1 03 Sep 1993 14:21:26 RWOLFF
  120. Partway through CX isolation.
  121. Rev 1.0 16 Aug 1993 13:27:00 Robert_Wolff
  122. Initial revision.
  123. Rev 1.8 10 Jun 1993 15:59:34 RWOLFF
  124. Translation of VDP-format monitor description file is now done inside
  125. the registry callback function to eliminate the need for an excessively
  126. large static buffer (Andre Vachon at Microsoft doesn't want the
  127. callback function to dynamically allocate a buffer).
  128. Rev 1.7 10 May 1993 16:37:56 RWOLFF
  129. GetOEMParms() now recognizes maximum pixel depth of each possible DAC at
  130. each supported resolution, eliminated unnecessary passing of
  131. hardware device extension as a parameter.
  132. Rev 1.6 04 May 1993 16:44:00 RWOLFF
  133. Removed INT 3s (debugging code), added workaround for optimizer bug that
  134. turned a FOR loop into an infinite loop.
  135. Rev 1.5 30 Apr 1993 16:37:02 RWOLFF
  136. Changed to work with dynamically allocated registry read buffer.
  137. Parameters are now read in from disk in VDP file format rather than
  138. as binary data (need floating point bug in NT fixed before this can be used).
  139. Rev 1.4 24 Apr 1993 17:14:48 RWOLFF
  140. No longer falls back to 56Hz at 800x600 16BPP on 1M Mach 32.
  141. Rev 1.3 21 Apr 1993 17:24:12 RWOLFF
  142. Now uses AMACH.H instead of 68800.H/68801.H.
  143. Sets q_status_flags to show which resolutions are supported.
  144. Can now read either CRT table to use or raw CRT parameters from
  145. disk file.
  146. Rev 1.2 14 Apr 1993 18:39:30 RWOLFF
  147. On AST machines, now reads from the computer what monitor type
  148. is configured and sets CRT parameters appropriately.
  149. Rev 1.1 08 Apr 1993 16:52:58 RWOLFF
  150. Revision level as checked in at Microsoft.
  151. Rev 1.0 30 Mar 1993 17:12:38 RWOLFF
  152. Initial revision.
  153. End of PolyTron RCS section *****************/
  154. #ifdef DOC
  155. ATIOEM.C - Functions to obtain CRT parameters from OEM versions
  156. of Mach 32/Mach 8 accelerators which lack an EEPROM.
  157. #endif
  158. #include <stdlib.h>
  159. #include <string.h>
  160. #include "dderror.h"
  161. #include "miniport.h"
  162. #include "ntddvdeo.h"
  163. #include "video.h" /* for VP_STATUS definition */
  164. #include "vidlog.h"
  165. #include "stdtyp.h"
  166. #include "amach.h"
  167. #include "amach1.h"
  168. #include "atimp.h"
  169. #include "atint.h"
  170. #include "cvtvga.h"
  171. #include "atioem.h"
  172. #include "services.h"
  173. #include "vdptocrt.h"
  174. /*
  175. * Definition needed to build under revision 404 of Windows NT.
  176. * Under later revisions, it is defined in a header which we
  177. * include.
  178. */
  179. #ifndef ERROR_DEV_NOT_EXIST
  180. #define ERROR_DEV_NOT_EXIST 55L
  181. #endif
  182. /*
  183. * OEM types supported by this module
  184. */
  185. enum {
  186. OEM_AST_PREMMIA, /* Also includes Bravo machines */
  187. OEM_DELL_OMNIPLEX,
  188. OEM_DELL_SYLVESTER, /* Different programming of clock generator from Omniplex */
  189. OEM_UNKNOWN /* Generic OEM - "canned" modes only, no HW defaults */
  190. };
  191. /*
  192. * AST machines have "AST " starting at offset 0x50 into the BIOS.
  193. * AST_REC_VALUE is the character sequence "AST " stored as an
  194. * Intel-format DWORD.
  195. */
  196. #define AST_REC_OFFSET 0x50
  197. #define AST_REC_VALUE 0x20545341
  198. /*
  199. * Definitions used to distinguish Premmia SE from other
  200. * AST machines. The Premmia SE has its aperture in the
  201. * 4G range, with the location split between MEM_CFG and
  202. * SCRATCH_PAD_0, but it does not have bit 0 of byte 0x62
  203. * in the BIOS set to indicate this.
  204. */
  205. #define EISA_ID_OFFSET 8 /* Offset to feed VideoPortGetBusData() */
  206. #define PREMMIA_SE_SLOT 0 /* Motherboard is slot 0 */
  207. #define PREMMIA_SE_ID 0x01057406 /* EISA ID of Premmia SE */
  208. /*
  209. * Indices into 1CE register where AST monitor configuration is kept.
  210. */
  211. #define AST_640_STORE 0xBA
  212. #define AST_800_STORE 0x81
  213. #define AST_1024_STORE 0x80
  214. /*
  215. * Values found in AST monitor configuration registers for the
  216. * different monitor setups.
  217. */
  218. #define M640F60AST 0x02
  219. #define M640F72AST 0x03
  220. #define M800F56AST 0x84
  221. #define M800F60AST 0x88
  222. #define M800F72AST 0xA0
  223. #define M1024F60AST 0x02
  224. #define M1024F70AST 0x04
  225. #define M1024F72AST 0x08
  226. #define M1024F87AST 0x01
  227. /*
  228. * Definitions used in stepping through pixel depths for AST Premmia.
  229. * Since the supported depths can't be stepped through a FOR loop
  230. * by a simple mathematical function, use an array index instead.
  231. */
  232. enum {
  233. DEPTH_4BPP = 0,
  234. DEPTH_8BPP,
  235. DEPTH_16BPP,
  236. DEPTH_24BPP
  237. };
  238. /*
  239. * Pixel depth
  240. */
  241. USHORT ASTDepth[DEPTH_24BPP - DEPTH_4BPP + 1] =
  242. {
  243. 4,
  244. 8,
  245. 16,
  246. 24
  247. };
  248. /*
  249. * Pixel clock frequency multiplier
  250. */
  251. USHORT ASTClockMult[DEPTH_24BPP - DEPTH_4BPP + 1] =
  252. {
  253. CLOCK_SINGLE,
  254. CLOCK_SINGLE,
  255. CLOCK_DOUBLE,
  256. CLOCK_TRIPLE
  257. };
  258. /*
  259. * Pixel size as a multiple of 4BPP (lowest depth)
  260. */
  261. USHORT ASTNybblesPerPixel[DEPTH_24BPP - DEPTH_4BPP + 1] =
  262. {
  263. 1,
  264. 2,
  265. 4,
  266. 6
  267. };
  268. /*
  269. * Dell machines have "DELL" starting at an offset into the BIOS which
  270. * is a multiple of 0x100. Currently, it is always at offset 0x100, but
  271. * this may change. DELL_REC_VALUE is the character sequence "DELL"
  272. * stored as an Intel-format DWORD.
  273. *
  274. * Some Dell machines store the pixel clock frequency table in the BIOS
  275. * rather than using the default Dell frequency table. On these machines,
  276. * the identifier DELL_TABLE_PRESENT will be found at offset DELL_TP_OFFSET
  277. * from the start of DELL_REC_VALUE, and the offset of the frequency table
  278. * into the video BIOS will be found at offset DELL_TABLE_OFFSET from the
  279. * start of DELL_TABLE_PRESENT.
  280. *
  281. * The table consists of 18 words. The first word is DELL_TABLE_SIG,
  282. * the second is the table type, and the remaining 16 are the clock
  283. * table entries.
  284. */
  285. #define DELL_REC_SPACING 0x100
  286. #define DELL_REC_VALUE 0x4C4C4544
  287. #define DELL_TABLE_PRESENT 0x7674 /* "tv" as WORD */
  288. #define DELL_TP_OFFSET 0x08
  289. #define DELL_TABLE_OFFSET 0x0C
  290. #define DELL_TABLE_SIG 0x7463 /* "ct" as WORD */
  291. /*
  292. * Indices into 1CE register where Dell monitor configuration is kept.
  293. */
  294. #define DELL_640_STORE 0xBA
  295. #define DELL_800_STORE 0x81
  296. #define DELL_1024_STORE 0x80
  297. #define DELL_1280_STORE 0x84
  298. /*
  299. * Values found in Dell monitor configuration registers for the
  300. * different monitor setups.
  301. */
  302. #define MASK_640_DELL 0x01
  303. #define M640F60DELL 0x00
  304. #define M640F72DELL 0x01
  305. #define MASK_800_DELL 0x3F
  306. #define M800F56DELL 0x04
  307. #define M800F60DELL 0x08
  308. #define M800F72DELL 0x20
  309. #define MASK_1024_DELL 0x1F
  310. #define M1024F87DELL 0x01
  311. #define M1024F60DELL 0x02
  312. #define M1024F70DELL 0x04
  313. #define M1024F72DELL 0x08
  314. #define MASK_1280_DELL 0xFC
  315. #define M1280F87DELL 0x04
  316. #define M1280F60DELL 0x10
  317. #define M1280F70DELL 0x20
  318. #define M1280F74DELL 0x40
  319. /*
  320. * Local functions to get CRT data for specific OEM cards.
  321. */
  322. VP_STATUS ReadAST(struct query_structure *query);
  323. VP_STATUS ReadZenith(struct st_mode_table *Modes);
  324. VP_STATUS ReadOlivetti(struct st_mode_table *Modes);
  325. VP_STATUS ReadDell(struct st_mode_table *Modes);
  326. ULONG DetectDell(struct query_structure *Query);
  327. BOOL DetectSylvester(struct query_structure *Query, ULONG HeaderOffset);
  328. VP_STATUS ReadOEM1(struct st_mode_table *Modes);
  329. VP_STATUS ReadOEM2(struct st_mode_table *Modes);
  330. VP_STATUS ReadOEM3(struct st_mode_table *Modes);
  331. VP_STATUS ReadOEM4(struct st_mode_table *Modes);
  332. VP_STATUS ReadOEM5(struct st_mode_table *Modes);
  333. /*
  334. * Allow miniport to be swapped out when not needed.
  335. */
  336. #if defined (ALLOC_PRAGMA)
  337. #pragma alloc_text(PAGE_COM, OEMGetParms)
  338. #pragma alloc_text(PAGE_COM, CompareASCIIToUnicode)
  339. #pragma alloc_text(PAGE_COM, ReadAST)
  340. #pragma alloc_text(PAGE_COM, ReadZenith)
  341. #pragma alloc_text(PAGE_COM, ReadOlivetti)
  342. #pragma alloc_text(PAGE_COM, ReadDell)
  343. #pragma alloc_text(PAGE_COM, DetectDell)
  344. #pragma alloc_text(PAGE_COM, DetectSylvester)
  345. #pragma alloc_text(PAGE_COM, ReadOEM1)
  346. #pragma alloc_text(PAGE_COM, ReadOEM2)
  347. #pragma alloc_text(PAGE_COM, ReadOEM3)
  348. #pragma alloc_text(PAGE_COM, ReadOEM4)
  349. #pragma alloc_text(PAGE_COM, ReadOEM5)
  350. #endif
  351. /*
  352. * VP_STATUS OEMGetParms(query);
  353. *
  354. * struct query_structure *query; Description of video card setup
  355. *
  356. * Routine to fill in the mode tables for an OEM version of one
  357. * of our video cards which lacks an EEPROM to store this data.
  358. *
  359. * Returns:
  360. * NO_ERROR if successful
  361. * ERROR_DEV_NOT_EXIST if an unknown OEM card is specified
  362. * ERROR_INVALID_PARAMETER if an error occurs
  363. */
  364. VP_STATUS OEMGetParms(struct query_structure *query)
  365. {
  366. struct st_mode_table *pmode; /* Mode table we are currently working on */
  367. struct st_mode_table ListOfModes[RES_1280 - RES_640 + 1];
  368. VP_STATUS RetVal; /* Value returned by called functions */
  369. short CurrentResolution; /* Resolution we are setting up */
  370. long NumPixels; /* Number of pixels at current resolution */
  371. long MemAvail; /* Bytes of video memory available to accelerator */
  372. UCHAR Scratch; /* Temporary variable */
  373. short StartIndex; /* First mode for SetFixedModes() to set up */
  374. short EndIndex; /* Last mode for SetFixedModes() to set up */
  375. BOOL ModeInstalled; /* Is this resolution configured? */
  376. WORD Multiplier; /* Pixel clock multiplier */
  377. USHORT OEMType; /* Which OEM accelerator we are dealing with */
  378. ULONG OEMInfoOffset; /* Offset of OEM information block into the BIOS */
  379. short MaxModes; /* Maximum number of modes possible */
  380. short FreeTables; /* Number of remaining free mode tables */
  381. /*
  382. * Clear out our mode tables, then check to see which OEM card
  383. * we are dealing with and read its CRT parameters.
  384. */
  385. VideoPortZeroMemory(ListOfModes, (RES_1280-RES_640+1)*sizeof(struct st_mode_table));
  386. /*
  387. * Try to auto-detect the type of OEM accelerator using recognition
  388. * strings in the BIOS. If we can't identify the OEM in this manner,
  389. * or there is no BIOS, treat it as a generic OEM card.
  390. */
  391. if (query->q_bios != FALSE)
  392. {
  393. if ((OEMInfoOffset = DetectDell(query)) != 0)
  394. OEMType = OEM_DELL_OMNIPLEX;
  395. else if (*(PULONG)(query->q_bios + AST_REC_OFFSET) == AST_REC_VALUE)
  396. OEMType = OEM_AST_PREMMIA;
  397. else
  398. OEMType = OEM_UNKNOWN;
  399. }
  400. else
  401. {
  402. OEMType = OEM_UNKNOWN;
  403. }
  404. /*
  405. * The ATIOEM registry field can override the auto-detected OEM type.
  406. * If this field is not present, or we don't recognize the value
  407. * it contains, continue with the OEM type we detected in the
  408. * previous step.
  409. */
  410. RegistryBufferLength = 0;
  411. if (VideoPortGetRegistryParameters(phwDeviceExtension,
  412. L"ATIOEM",
  413. FALSE,
  414. RegistryParameterCallback,
  415. NULL) == NO_ERROR)
  416. {
  417. VideoDebugPrint((DEBUG_DETAIL, "ATIOEM field found\n"));
  418. if (RegistryBufferLength == 0)
  419. {
  420. VideoDebugPrint((DEBUG_DETAIL, "Registry call gave Zero Length\n"));
  421. }
  422. else if (!CompareASCIIToUnicode("AST", RegistryBuffer, CASE_INSENSITIVE))
  423. {
  424. OEMType = OEM_AST_PREMMIA;
  425. }
  426. else if (!CompareASCIIToUnicode("DELL", RegistryBuffer, CASE_INSENSITIVE))
  427. {
  428. OEMType = OEM_DELL_OMNIPLEX;
  429. /*
  430. * If the auto-detection failed, assume the Dell header
  431. * starts at the default location (for Sylvester/Omniplex
  432. * determination). If the auto-detection succeeded, but
  433. * the ATIOEM registry field still exists, leave this
  434. * value alone.
  435. */
  436. if (OEMInfoOffset == 0)
  437. OEMInfoOffset = DELL_REC_SPACING;
  438. }
  439. else
  440. {
  441. VideoPortLogError(phwDeviceExtension, NULL, VID_ATIOEM_UNUSED, 20);
  442. }
  443. }
  444. /*
  445. * Load the frequency table corresponding to
  446. * the selected OEM type, unless it uses the
  447. * same frequency table as our retail clock chip.
  448. *
  449. */
  450. /*
  451. * Load the table for the desired OEM type.
  452. */
  453. if (OEMType == OEM_DELL_OMNIPLEX)
  454. {
  455. /*
  456. * On a Sylvester (more recent model than the Omniplex),
  457. * we must read the clock frequency table from the BIOS
  458. * rather than using the Omniplex table. Otherwise, the
  459. * two machines can be handled in the same manner.
  460. *
  461. * DetectSylvester() will load the clock frequency table
  462. * if it finds a Sylvester, and return without loading
  463. * the table if it finds a non-Sylvester machine.
  464. */
  465. if (DetectSylvester(query,OEMInfoOffset) == FALSE)
  466. {
  467. ClockGenerator[0] = 25175000L;
  468. ClockGenerator[1] = 28322000L;
  469. ClockGenerator[2] = 31500000L;
  470. ClockGenerator[3] = 36000000L;
  471. ClockGenerator[4] = 40000000L;
  472. ClockGenerator[5] = 44900000L;
  473. ClockGenerator[6] = 50000000L;
  474. ClockGenerator[7] = 65000000L;
  475. ClockGenerator[8] = 75000000L;
  476. ClockGenerator[9] = 77500000L;
  477. ClockGenerator[10] = 80000000L;
  478. ClockGenerator[11] = 90000000L;
  479. ClockGenerator[12] = 100000000L;
  480. ClockGenerator[13] = 110000000L;
  481. ClockGenerator[14] = 126000000L;
  482. ClockGenerator[15] = 135000000L;
  483. }
  484. }
  485. else if (OEMType == OEM_AST_PREMMIA)
  486. {
  487. ClockGenerator[0] = 50000000L;
  488. ClockGenerator[1] = 63000000L;
  489. ClockGenerator[2] = 92400000L;
  490. ClockGenerator[3] = 36000000L;
  491. ClockGenerator[4] = 50350000L;
  492. ClockGenerator[5] = 56640000L;
  493. ClockGenerator[6] = 0L;
  494. ClockGenerator[7] = 44900000L;
  495. ClockGenerator[8] = 67500000L;
  496. ClockGenerator[9] = 31500000L;
  497. ClockGenerator[10] = 55000000L;
  498. ClockGenerator[11] = 80000000L;
  499. ClockGenerator[12] = 39910000L;
  500. ClockGenerator[13] = 72000000L;
  501. ClockGenerator[14] = 75000000L;
  502. ClockGenerator[15] = 65000000L;
  503. }
  504. /*
  505. * else (this OEM type uses the retail frequency table)
  506. */
  507. /*
  508. * Checking the number of modes available would involve
  509. * duplicating most of the code to fill in the mode tables.
  510. * Since this is to determine how much memory is needed
  511. * to hold the query structure, we can assume the worst
  512. * case (all possible modes are present). This would be:
  513. *
  514. * Resolution Pixel Depths (BPP) Refresh rates (Hz) Number of modes
  515. * 640x480 4,8,16,24 HWD,60,72 12
  516. * 800x600 4,8,16,24 HWD,56,60,70,72,89,95 28
  517. * 1024x768 4,8,16 HWD,60,66,70,72,87 18
  518. * 1280x1024 4,8 HWD,60,70,74,87,95 12
  519. *
  520. * HWD = hardware default refresh rate (rate set by INSTALL)
  521. *
  522. * Total: 70 modes
  523. */
  524. if (QUERYSIZE < (70 * sizeof(struct st_mode_table) + sizeof(struct query_structure)))
  525. return ERROR_INSUFFICIENT_BUFFER;
  526. MaxModes = (QUERYSIZE - sizeof(struct query_structure)) /
  527. sizeof(struct st_mode_table);
  528. /*
  529. * Load the configured mode tables corresponding
  530. * to the selected OEM type. If there is no custom monitor description,
  531. * and we do not recognize the OEM type, use only the predefined
  532. * mode tables.
  533. *
  534. */
  535. /*
  536. * Load the configured mode tables according to the OEM type
  537. * detected.
  538. * AST machines load the entire list of mode tables (all
  539. * pixel depths, including "canned" modes). Generic OEM
  540. * machines only load the "canned" modes (done later).
  541. */
  542. if (OEMType == OEM_DELL_OMNIPLEX)
  543. {
  544. RetVal = ReadDell(ListOfModes);
  545. }
  546. else if (OEMType == OEM_AST_PREMMIA)
  547. {
  548. RetVal = ReadAST(query);
  549. return RetVal;
  550. }
  551. /*
  552. * Get a pointer into the mode table section of the query structure.
  553. */
  554. pmode = (struct st_mode_table *)query; // first mode table at end of query
  555. ((struct query_structure *)pmode)++;
  556. /*
  557. * Get the amount of available video memory.
  558. */
  559. MemAvail = query->q_memory_size * QUARTER_MEG; // Total memory installed
  560. /*
  561. * Subtract the amount of memory reserved for the VGA. This only
  562. * applies to the Graphics Ultra, since the 8514/ULTRA has no
  563. * VGA, and we will set all memory as shared on the Mach 32.
  564. if (phwDeviceExtension->ModelNumber == GRAPHICS_ULTRA)
  565. MemAvail -= (query->q_VGA_boundary * QUARTER_MEG);
  566. /*
  567. * Initially assume no video modes are available.
  568. */
  569. query->q_number_modes = 0;
  570. query->q_status_flags = 0;
  571. /*
  572. * Fill in the mode tables section of the query structure.
  573. */
  574. for (CurrentResolution = RES_640; CurrentResolution <= RES_1280; CurrentResolution++)
  575. {
  576. /*
  577. * Skip over 1152x864 (new resolution for Mach 64, which
  578. * would require extensive re-work for Mach 32, the family
  579. * for which this module was written).
  580. */
  581. if (CurrentResolution == RES_1152)
  582. continue;
  583. /*
  584. * If this resolution is configured, indicate that there is a
  585. * hardware default mode. If not, only list the "canned" refresh
  586. * rates for this resolution.
  587. */
  588. if (!ListOfModes[CurrentResolution].m_h_total)
  589. ModeInstalled = FALSE;
  590. else
  591. ModeInstalled = TRUE;
  592. /*
  593. * Find the number of pixels for the current resolution.
  594. */
  595. switch (CurrentResolution)
  596. {
  597. case RES_640:
  598. /*
  599. * On a Mach 32 with no aperture, we use a screen pitch
  600. * of 1024. Other cases and Mach 32 with an aperture
  601. * use a screen pitch of the number of pixels.
  602. */
  603. #if !defined (SPLIT_RASTERS)
  604. if((phwDeviceExtension->ModelNumber == MACH32_ULTRA)
  605. && (query->q_aperture_cfg == 0))
  606. ListOfModes[CurrentResolution].m_screen_pitch = 1024;
  607. else
  608. #endif
  609. ListOfModes[CurrentResolution].m_screen_pitch = 640;
  610. NumPixels = ListOfModes[CurrentResolution].m_screen_pitch * 480;
  611. query->q_status_flags |= VRES_640x480;
  612. ListOfModes[CurrentResolution].Refresh = DEFAULT_REFRESH;
  613. StartIndex = B640F60;
  614. EndIndex = B640F72;
  615. break;
  616. case RES_800:
  617. /*
  618. * On a Mach 32 with no aperture, we use a screen pitch
  619. * of 1024. Mach 32 rev. 3 and Mach 8 cards need a screen
  620. * pitch which is a multiple of 128. Other cases and
  621. * Mach 32 rev. 6 and higher with an aperture use a screen
  622. * pitch of the number of pixels.
  623. */
  624. #if defined (SPLIT_RASTERS)
  625. if ((query->q_asic_rev == CI_68800_3)
  626. #else
  627. if((phwDeviceExtension->ModelNumber == MACH32_ULTRA)
  628. && (query->q_aperture_cfg == 0))
  629. ListOfModes[CurrentResolution].m_screen_pitch = 1024;
  630. else if ((query->q_asic_rev == CI_68800_3)
  631. #endif
  632. || (query->q_asic_rev == CI_38800_1)
  633. || (query->q_bus_type == BUS_PCI))
  634. ListOfModes[CurrentResolution].m_screen_pitch = 896;
  635. else
  636. ListOfModes[CurrentResolution].m_screen_pitch = 800;
  637. NumPixels = ListOfModes[CurrentResolution].m_screen_pitch * 600;
  638. query->q_status_flags |= VRES_800x600;
  639. ListOfModes[CurrentResolution].Refresh = DEFAULT_REFRESH;
  640. StartIndex = B800F89;
  641. EndIndex = B800F72;
  642. break;
  643. case RES_1024:
  644. ListOfModes[CurrentResolution].m_screen_pitch = 1024;
  645. NumPixels = ListOfModes[CurrentResolution].m_screen_pitch * 768;
  646. query->q_status_flags |= VRES_1024x768;
  647. ListOfModes[CurrentResolution].Refresh = DEFAULT_REFRESH;
  648. StartIndex = B1024F87;
  649. EndIndex = B1024F72;
  650. break;
  651. case RES_1280:
  652. ListOfModes[CurrentResolution].m_screen_pitch = 1280;
  653. NumPixels = ListOfModes[CurrentResolution].m_screen_pitch * 1024;
  654. query->q_status_flags |= VRES_1024x768;
  655. ListOfModes[CurrentResolution].Refresh = DEFAULT_REFRESH;
  656. StartIndex = B1280F87;
  657. /*
  658. * 1280x1024 noninterlaced has the following restrictions:
  659. *
  660. * Dell machines:
  661. * VRAM supports up to 70Hz
  662. * DRAM supports up to 74Hz
  663. *
  664. * Other machines:
  665. * VRAM supports up to 74Hz
  666. * DRAM supports up to 60Hz
  667. *
  668. * This is because Dell uses faster (and more expensive)
  669. * DRAM than on our retail cards (non-x86 implementations
  670. * will hit this code block on retail cards), but has
  671. * problems at 74Hz on their VRAM implementations. Other
  672. * OEMs have not requested that their cards be treated
  673. * differently from our retail cards in this respect.
  674. */
  675. if ((query->q_memory_type == VMEM_DRAM_256Kx4) ||
  676. (query->q_memory_type == VMEM_DRAM_256Kx16) ||
  677. (query->q_memory_type == VMEM_DRAM_256Kx4_GRAP))
  678. {
  679. if (OEMType == OEM_DELL_OMNIPLEX)
  680. EndIndex = B1280F74;
  681. else
  682. EndIndex = B1280F60;
  683. }
  684. else
  685. {
  686. if (OEMType == OEM_DELL_OMNIPLEX)
  687. EndIndex = B1280F70;
  688. else
  689. EndIndex = B1280F74;
  690. }
  691. break;
  692. }
  693. /*
  694. * For each supported pixel depth at the given resolution,
  695. * copy the mode table, fill in the colour depth field,
  696. * and increment the counter for the number of supported modes.
  697. * Test 4BPP before 8BPP so the mode tables will appear in
  698. * increasing order of pixel depth.
  699. */
  700. if (NumPixels <= MemAvail*2)
  701. {
  702. if (ModeInstalled)
  703. {
  704. VideoPortMoveMemory(pmode, &ListOfModes[CurrentResolution],
  705. sizeof(struct st_mode_table));
  706. pmode->m_pixel_depth = 4;
  707. pmode++; /* ptr to next mode table */
  708. query->q_number_modes++;
  709. }
  710. /*
  711. * Add "canned" mode tables
  712. */
  713. if ((FreeTables = MaxModes - query->q_number_modes) <= 0)
  714. {
  715. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  716. return ERROR_INSUFFICIENT_BUFFER;
  717. }
  718. query->q_number_modes += SetFixedModes(StartIndex,
  719. EndIndex,
  720. CLOCK_SINGLE,
  721. 4,
  722. ListOfModes[CurrentResolution].m_screen_pitch,
  723. FreeTables,
  724. BookValues[EndIndex].ClockFreq,
  725. &pmode);
  726. }
  727. if (NumPixels <= MemAvail)
  728. {
  729. if (ModeInstalled)
  730. {
  731. VideoPortMoveMemory(pmode, &ListOfModes[CurrentResolution],
  732. sizeof(struct st_mode_table));
  733. pmode->m_pixel_depth = 8;
  734. pmode++; /* ptr to next mode table */
  735. query->q_number_modes++;
  736. }
  737. /*
  738. * Add "canned" mode tables
  739. */
  740. if ((FreeTables = MaxModes - query->q_number_modes) <= 0)
  741. {
  742. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  743. return ERROR_INSUFFICIENT_BUFFER;
  744. }
  745. query->q_number_modes += SetFixedModes(StartIndex,
  746. EndIndex,
  747. CLOCK_SINGLE,
  748. 8,
  749. ListOfModes[CurrentResolution].m_screen_pitch,
  750. FreeTables,
  751. BookValues[EndIndex].ClockFreq,
  752. &pmode);
  753. }
  754. /*
  755. * Resolutions above 8BPP are only available for the Mach 32.
  756. */
  757. if (phwDeviceExtension->ModelNumber != MACH32_ULTRA)
  758. continue;
  759. /*
  760. * 16, 24, and 32 BPP require a DAC which can support
  761. * the selected pixel depth at the current resolution
  762. * as well as enough memory.
  763. */
  764. if ((NumPixels*2 <= MemAvail) &&
  765. (MaxDepth[query->q_DAC_type][CurrentResolution] >= 16))
  766. {
  767. VideoPortMoveMemory(pmode, &ListOfModes[CurrentResolution],
  768. sizeof(struct st_mode_table));
  769. /*
  770. * Handle DACs that require higher pixel clocks for 16BPP.
  771. */
  772. if ((query->q_DAC_type == DAC_BT48x) ||
  773. (query->q_DAC_type == DAC_SC15026) ||
  774. (query->q_DAC_type == DAC_ATT491))
  775. {
  776. pmode->ClockFreq *= 2;
  777. Multiplier = CLOCK_DOUBLE;
  778. if (CurrentResolution == RES_800)
  779. EndIndex = B800F60; /* 70 Hz and up not supported at 16BPP */
  780. }
  781. else
  782. {
  783. Scratch = 0;
  784. Multiplier = CLOCK_SINGLE;
  785. }
  786. pmode->m_pixel_depth = 16;
  787. /*
  788. * If this resolution is not configured, or if we need to
  789. * double the clock frequency but can't, ignore the mode
  790. * table we just created.
  791. */
  792. if (ModeInstalled && (Scratch != 0xFF))
  793. {
  794. pmode++; /* ptr to next mode table */
  795. query->q_number_modes++;
  796. }
  797. /*
  798. * Add "canned" mode tables
  799. */
  800. if ((FreeTables = MaxModes - query->q_number_modes) <= 0)
  801. {
  802. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  803. return ERROR_INSUFFICIENT_BUFFER;
  804. }
  805. query->q_number_modes += SetFixedModes(StartIndex,
  806. EndIndex,
  807. Multiplier,
  808. 16,
  809. ListOfModes[CurrentResolution].m_screen_pitch,
  810. FreeTables,
  811. BookValues[EndIndex].ClockFreq,
  812. &pmode);
  813. }
  814. /*
  815. * Our new source stream display driver needs a linear aperture
  816. * in order to handle 24BPP. Since the display driver doesn't
  817. * have access to the aperture information when it is deciding
  818. * which modes to pass on to the display applet, it can't make
  819. * the decision to reject 24BPP modes for cards with only a
  820. * VGA aperture. This decision must therefore be made in the
  821. * miniport, so in a paged aperture configuration there are no
  822. * 24BPP modes for the display driver to accept or reject.
  823. *
  824. * On the Alpha, we can't use dense space on the Mach 32 LFB,
  825. * so we treat it as a no-aperture case.
  826. */
  827. if (query->q_aperture_cfg == 0)
  828. {
  829. VideoDebugPrint((DEBUG_DETAIL, "24BPP not available because we don't have a linear aperture\n"));
  830. continue;
  831. }
  832. #if defined(ALPHA)
  833. VideoDebugPrint((DEBUG_DETAIL, "24BPP not available in sparse space on Alpha\n"));
  834. continue;
  835. #endif
  836. /*
  837. * 800x600 24BPP exhibits screen tearing unless the pitch
  838. * is a multiple of 128 (only applies to Rev. 6, since Rev. 3
  839. * and PCI implementations already have a pitch of 896).
  840. * Other pixel depths are not affected, and other resolutions
  841. * are already a multiple of 128 pixels wide.
  842. *
  843. * Expand the 800x600 pitch to 896 here, rather than for
  844. * all pixel depths, because making the change for all
  845. * pixel depths would disable 16BPP (which doesn't have
  846. * the problem) on 1M cards. The screen pitch will only
  847. * be 800 on cards which will exhibit this problem - don't
  848. * check for a resolution of 800x600 because we don't want
  849. * to cut the pitch from 1024 down to 896 if SPLIT_RASTERS
  850. * is not defined.
  851. */
  852. if (ListOfModes[CurrentResolution].m_screen_pitch == 800)
  853. {
  854. ListOfModes[CurrentResolution].m_screen_pitch = 896;
  855. NumPixels = (long) ListOfModes[CurrentResolution].m_screen_pitch * 600;
  856. }
  857. if ((NumPixels*3 <= MemAvail) &&
  858. (MaxDepth[query->q_DAC_type][CurrentResolution] >= 24))
  859. {
  860. VideoPortMoveMemory(pmode, &ListOfModes[CurrentResolution],
  861. sizeof(struct st_mode_table));
  862. pmode->m_pixel_depth = 24;
  863. /*
  864. * Handle DACs that require higher pixel clocks for 24BPP.
  865. */
  866. Scratch = 0;
  867. if ((query->q_DAC_type == DAC_STG1700) ||
  868. (query->q_DAC_type == DAC_ATT498))
  869. {
  870. pmode->ClockFreq *= 2;
  871. Multiplier = CLOCK_DOUBLE;
  872. }
  873. else if ((query->q_DAC_type == DAC_SC15021) ||
  874. (query->q_DAC_type == DAC_STG1702) ||
  875. (query->q_DAC_type == DAC_STG1703))
  876. {
  877. pmode->ClockFreq *= 3;
  878. pmode->ClockFreq >>= 1;
  879. Multiplier = CLOCK_THREE_HALVES;
  880. }
  881. else if ((query->q_DAC_type == DAC_BT48x) ||
  882. (query->q_DAC_type == DAC_SC15026) ||
  883. (query->q_DAC_type == DAC_ATT491))
  884. {
  885. pmode->ClockFreq *= 3;
  886. Multiplier = CLOCK_TRIPLE;
  887. EndIndex = B640F60; /* Only supports 24BPP in 640x480 60Hz */
  888. }
  889. else
  890. {
  891. Multiplier = CLOCK_SINGLE;
  892. if ((query->q_DAC_type == DAC_TI34075) && (CurrentResolution == RES_800))
  893. EndIndex = B800F70;
  894. }
  895. /*
  896. * If we needed to alter the clock frequency, and couldn't
  897. * generate an appropriate selector/divisor pair,
  898. * then ignore this mode.
  899. */
  900. if (ModeInstalled && (Scratch != 0x0FF))
  901. {
  902. pmode++; /* ptr to next mode table */
  903. query->q_number_modes++;
  904. }
  905. /*
  906. * Add "canned" mode tables
  907. */
  908. if ((FreeTables = MaxModes - query->q_number_modes) <= 0)
  909. {
  910. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  911. return ERROR_INSUFFICIENT_BUFFER;
  912. }
  913. query->q_number_modes += SetFixedModes(StartIndex,
  914. EndIndex,
  915. Multiplier,
  916. 24,
  917. ListOfModes[CurrentResolution].m_screen_pitch,
  918. FreeTables,
  919. BookValues[EndIndex].ClockFreq,
  920. &pmode);
  921. }
  922. }
  923. return NO_ERROR;
  924. } /* OEMGetParms() */
  925. /*
  926. * LONG CompareASCIIToUnicode(Ascii, Unicode, IgnoreCase);
  927. *
  928. * PUCHAR Ascii; ASCII string to be compared
  929. * PUCHAR Unicode; Unicode string to be compared
  930. * BOOL IgnoreCase; Flag to determine case sensitive/insensitive comparison
  931. *
  932. * Compare 2 strings, one ASCII and the other UNICODE, to see whether
  933. * they are equal, and if not, which one is first in alphabetical order.
  934. *
  935. * Returns:
  936. * 0 if strings are equal
  937. * positive if ASCII string comes first
  938. * negative if UNICODE string comes first
  939. */
  940. LONG CompareASCIIToUnicode(PUCHAR Ascii, PUCHAR Unicode, BOOL IgnoreCase)
  941. {
  942. UCHAR CharA;
  943. UCHAR CharU;
  944. /*
  945. * Keep going until both strings have a simultaneous null terminator.
  946. */
  947. while (*Ascii || *Unicode)
  948. {
  949. /*
  950. * Get the next character from each string. If we are doing a
  951. * case-insensitive comparison, translate to upper case.
  952. */
  953. if (IgnoreCase)
  954. {
  955. if ((*Ascii >= 'a') && (*Ascii <= 'z'))
  956. CharA = *Ascii - ('a'-'A');
  957. else
  958. CharA = *Ascii;
  959. if ((*Unicode >= 'a') && (*Unicode <= 'z'))
  960. CharU = *Unicode - ('a' - 'A');
  961. else
  962. CharU = *Unicode;
  963. }
  964. else{
  965. CharA = *Ascii;
  966. CharU = *Unicode;
  967. }
  968. /*
  969. * Check if one of the characters precedes the other. This will
  970. * catch the case of unequal length strings, since the null
  971. * terminator on the shorter string will precede any character
  972. * in the longer string.
  973. */
  974. if (CharA < CharU)
  975. return 1;
  976. else if (CharA > CharU)
  977. return -1;
  978. /*
  979. * Advance to the next character in each string. Unicode strings
  980. * occupy 2 bytes per character, so we must check only every
  981. * second character.
  982. */
  983. Ascii++;
  984. Unicode++;
  985. Unicode++;
  986. }
  987. /*
  988. * The strings are identical and of equal length.
  989. */
  990. return 0;
  991. } /* CompareASCIIToUnicode() */
  992. /*
  993. * VP_STATUS ReadAST(Modes);
  994. *
  995. * struct query_structure *query; Mode tables to be filled in
  996. *
  997. * Routine to get CRT parameters for AST versions of
  998. * our cards. All AST cards choose from a limited selection
  999. * of vertical refresh rates with no "custom monitor" option,
  1000. * so we can use hardcoded tables for each refresh rate. We
  1001. * can't use the BookVgaTable() function, since AST cards have
  1002. * a different clock chip from retail cards, resulting in different
  1003. * values in the ClockSel field for AST and retail versions. Also,
  1004. * AST cards all use the Brooktree DAC.
  1005. *
  1006. * Returns:
  1007. * NO_ERROR
  1008. */
  1009. VP_STATUS ReadAST(struct query_structure *query)
  1010. {
  1011. struct st_mode_table *pmode; /* Mode table we are currently working on */
  1012. struct st_mode_table *OldPmode; /* Mode table pointer before SetFixedModes() call */
  1013. unsigned char Frequency; /* Vertical refresh rate for monitor */
  1014. long NumPixels; /* Number of pixels at current resolution */
  1015. USHORT Pitch; /* Screen pitch */
  1016. long MemAvail; /* Bytes of video memory available to accelerator */
  1017. USHORT LastNumModes; /* Number of modes not including current resolution */
  1018. short StartIndex; /* First mode for SetFixedModes() to set up */
  1019. short EndIndex; /* Last mode for SetFixedModes() to set up */
  1020. short HWIndex; /* Mode selected as hardware default */
  1021. USHORT PixelDepth; /* Pixel depth we are working on */
  1022. #if (TARGET_BUILD >= 350)
  1023. ULONG EisaId; /* EISA ID of the motherboard */
  1024. #endif
  1025. short MaxModes; /* Maximum number of modes possible */
  1026. short FreeTables; /* Number of remaining free mode tables */
  1027. #if (TARGET_BUILD >= 350)
  1028. /*
  1029. * The Premmia SE splits its aperture location between MEM_CFG and
  1030. * SCRATCH_PAD_0, but does not set the flag bit (bit 0 of BIOS byte
  1031. * 0x62). According to AST, the only way to distinguish this from
  1032. * other Premmia machines is to check its EISA ID.
  1033. *
  1034. * The VideoPortGetBusData() routine is not available in NT 3.1,
  1035. * so Premmia users running NT 3.1 are out of luck.
  1036. */
  1037. VideoPortGetBusData(phwDeviceExtension,
  1038. EisaConfiguration,
  1039. PREMMIA_SE_SLOT,
  1040. &EisaId,
  1041. EISA_ID_OFFSET,
  1042. sizeof(ULONG));
  1043. if (EisaId == PREMMIA_SE_ID)
  1044. {
  1045. query->q_aperture_addr = (INPW(MEM_CFG) & 0x7F00) >> 8;
  1046. query->q_aperture_addr |= ((INPW(SCRATCH_PAD_0) & 0x1F00) >> 1);
  1047. }
  1048. #endif
  1049. /*
  1050. * Get the memory size in nybbles (half a byte). A 4BPP pixel
  1051. * uses 1 nybble. For other depths, compare this number to the
  1052. * product of the number of pixels needed and the number of
  1053. * nybbles per pixel.
  1054. *
  1055. * The q_memory_size field contains the number of quarter-megabyte
  1056. * blocks of memory available, so multiplying it by HALF_MEG yields
  1057. * the number of nybbles of video memory.
  1058. */
  1059. MemAvail = query->q_memory_size * HALF_MEG;
  1060. /*
  1061. * Initially assume no video modes.
  1062. */
  1063. query->q_number_modes = 0;
  1064. LastNumModes = 0;
  1065. query->q_status_flags = 0;
  1066. /*
  1067. * Get a pointer into the mode table section of the query structure.
  1068. */
  1069. pmode = (struct st_mode_table *)query; // first mode table at end of query
  1070. ((struct query_structure *)pmode)++;
  1071. MaxModes = (QUERYSIZE - sizeof(struct query_structure)) /
  1072. sizeof(struct st_mode_table);
  1073. /*
  1074. * Find out which refresh rate is used at 640x480, and fill in the
  1075. * mode tables for the various pixel depths at this resoulution.
  1076. */
  1077. OUTP(reg1CE, AST_640_STORE);
  1078. Frequency = INP(reg1CF);
  1079. switch(Frequency)
  1080. {
  1081. case M640F72AST:
  1082. HWIndex = B640F72;
  1083. break;
  1084. case M640F60AST:
  1085. default:
  1086. HWIndex = B640F60;
  1087. break;
  1088. }
  1089. /*
  1090. * Select the "canned" mode tables for 640x480, and get
  1091. * information regarding the screen size. The Premmia always
  1092. * has the linear aperture enabled, so we don't need to
  1093. * stretch the pitch to 1024. Also, it always uses a
  1094. * Mach 32 ASIC and a BT48x or equivalent DAC, so we
  1095. * don't need to check the ASIC family or DAC type
  1096. * to determine if a particular resolution/pixel depth/
  1097. * refresh rate combination is supported.
  1098. */
  1099. StartIndex = B640F60;
  1100. EndIndex = B640F72;
  1101. Pitch = 640;
  1102. NumPixels = Pitch * 480;
  1103. /*
  1104. * Fill in the mode tables for 640x480 at all pixel depths.
  1105. */
  1106. for (PixelDepth = DEPTH_4BPP; PixelDepth <= DEPTH_24BPP; PixelDepth++)
  1107. {
  1108. /*
  1109. * Only include modes if there is enough memory.
  1110. */
  1111. if ((NumPixels * ASTNybblesPerPixel[PixelDepth]) <= MemAvail)
  1112. {
  1113. /*
  1114. * 640x480 24BPP is only available at 60Hz.
  1115. */
  1116. if (ASTDepth[PixelDepth] == 24)
  1117. {
  1118. HWIndex = B640F60;
  1119. EndIndex = B640F60;
  1120. }
  1121. /*
  1122. * Set up the hardware default refresh rate.
  1123. */
  1124. OldPmode = pmode;
  1125. if ((FreeTables = MaxModes - query->q_number_modes) <= 0)
  1126. {
  1127. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1128. return ERROR_INSUFFICIENT_BUFFER;
  1129. }
  1130. query->q_number_modes += SetFixedModes(HWIndex,
  1131. HWIndex,
  1132. ASTClockMult[PixelDepth],
  1133. ASTDepth[PixelDepth],
  1134. Pitch,
  1135. FreeTables,
  1136. BookValues[EndIndex].ClockFreq,
  1137. &pmode);
  1138. OldPmode->Refresh = DEFAULT_REFRESH;
  1139. /*
  1140. * Set up the canned mode tables.
  1141. */
  1142. if ((FreeTables = MaxModes - query->q_number_modes) <= 0)
  1143. {
  1144. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1145. return ERROR_INSUFFICIENT_BUFFER;
  1146. }
  1147. query->q_number_modes += SetFixedModes(StartIndex,
  1148. EndIndex,
  1149. ASTClockMult[PixelDepth],
  1150. ASTDepth[PixelDepth],
  1151. Pitch,
  1152. FreeTables,
  1153. BookValues[EndIndex].ClockFreq,
  1154. &pmode);
  1155. } /* end if (enough memory for 640x480) */
  1156. } /* end for (loop on 640x480 pixel depth) */
  1157. /*
  1158. * If we installed any 640x480 mode tables, report that
  1159. * 640x480 is supported.
  1160. */
  1161. if (query->q_number_modes > LastNumModes)
  1162. {
  1163. query->q_status_flags |= VRES_640x480;
  1164. LastNumModes = query->q_number_modes;
  1165. }
  1166. /*
  1167. * Find out which refresh rate is used at 800x600, and fill in the
  1168. * mode tables for the various pixel depths at this resoulution.
  1169. */
  1170. OUTP(reg1CE, AST_800_STORE);
  1171. Frequency = INP(reg1CF);
  1172. switch(Frequency)
  1173. {
  1174. case M800F72AST:
  1175. HWIndex = B800F72;
  1176. break;
  1177. case M800F60AST:
  1178. HWIndex = B800F60;
  1179. break;
  1180. case M800F56AST:
  1181. default:
  1182. HWIndex = B800F56;
  1183. break;
  1184. }
  1185. /*
  1186. * Select the "canned" mode tables for 800x600, and get
  1187. * information regarding the screen size. 68800-3 cards
  1188. * need a screen pitch that is a multiple of 128.
  1189. */
  1190. StartIndex = B800F89;
  1191. EndIndex = B800F72;
  1192. if (query->q_asic_rev == CI_68800_3)
  1193. Pitch = 896;
  1194. else
  1195. Pitch = 800;
  1196. NumPixels = Pitch * 600;
  1197. /*
  1198. * Fill in the mode tables for 800x600 at all pixel depths.
  1199. */
  1200. for (PixelDepth = DEPTH_4BPP; PixelDepth <= DEPTH_16BPP; PixelDepth++)
  1201. {
  1202. /*
  1203. * Only include modes if there is enough memory.
  1204. */
  1205. if ((NumPixels * ASTNybblesPerPixel[PixelDepth]) <= MemAvail)
  1206. {
  1207. /*
  1208. * 800x600 16BPP is only supported for 56Hz, 60Hz,
  1209. * and interlaced. Machines with a hardware default
  1210. * of 72Hz fall back to 56Hz.
  1211. */
  1212. if (ASTDepth[PixelDepth] == 16)
  1213. {
  1214. HWIndex = B800F56;
  1215. EndIndex = B800F60;
  1216. }
  1217. /*
  1218. * Set up the hardware default refresh rate.
  1219. */
  1220. OldPmode = pmode;
  1221. if ((FreeTables = MaxModes - query->q_number_modes) <= 0)
  1222. {
  1223. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1224. return ERROR_INSUFFICIENT_BUFFER;
  1225. }
  1226. query->q_number_modes += SetFixedModes(HWIndex,
  1227. HWIndex,
  1228. ASTClockMult[PixelDepth],
  1229. ASTDepth[PixelDepth],
  1230. Pitch,
  1231. FreeTables,
  1232. BookValues[EndIndex].ClockFreq,
  1233. &pmode);
  1234. OldPmode->Refresh = DEFAULT_REFRESH;
  1235. /*
  1236. * Set up the canned mode tables.
  1237. */
  1238. if ((FreeTables = MaxModes - query->q_number_modes) <= 0)
  1239. {
  1240. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1241. return ERROR_INSUFFICIENT_BUFFER;
  1242. }
  1243. query->q_number_modes += SetFixedModes(StartIndex,
  1244. EndIndex,
  1245. ASTClockMult[PixelDepth],
  1246. ASTDepth[PixelDepth],
  1247. Pitch,
  1248. FreeTables,
  1249. BookValues[EndIndex].ClockFreq,
  1250. &pmode);
  1251. } /* end if (enough memory for 800x600) */
  1252. } /* end for (loop on 800x600 pixel depth) */
  1253. /*
  1254. * If we installed any 800x600 mode tables, report that
  1255. * 800x600 is supported.
  1256. */
  1257. if (query->q_number_modes > LastNumModes)
  1258. {
  1259. query->q_status_flags |= VRES_800x600;
  1260. LastNumModes = query->q_number_modes;
  1261. }
  1262. /*
  1263. * Find out which refresh rate is used at 1024x768, and fill in the
  1264. * mode tables for the various pixel depths at this resoulution.
  1265. */
  1266. OUTP(reg1CE, AST_1024_STORE);
  1267. Frequency = INP(reg1CF);
  1268. switch(Frequency)
  1269. {
  1270. case M1024F72AST:
  1271. HWIndex = B1024F72;
  1272. break;
  1273. case M1024F70AST:
  1274. HWIndex = B1024F70;
  1275. break;
  1276. case M1024F60AST:
  1277. HWIndex = B1024F60;
  1278. break;
  1279. case M1024F87AST:
  1280. default:
  1281. HWIndex = B1024F87;
  1282. break;
  1283. }
  1284. /*
  1285. * Select the "canned" mode tables for 1024x768.
  1286. */
  1287. StartIndex = B1024F87;
  1288. EndIndex = B1024F72;
  1289. Pitch = 1024;
  1290. NumPixels = Pitch * 768;
  1291. /*
  1292. * Fill in the mode tables for 1024x768 at all pixel depths.
  1293. */
  1294. for (PixelDepth = DEPTH_4BPP; PixelDepth <= DEPTH_8BPP; PixelDepth++)
  1295. {
  1296. /*
  1297. * Only include modes if there is enough memory.
  1298. */
  1299. if ((NumPixels * ASTNybblesPerPixel[PixelDepth]) <= MemAvail)
  1300. {
  1301. /*
  1302. * Set up the hardware default refresh rate.
  1303. */
  1304. OldPmode = pmode;
  1305. if ((FreeTables = MaxModes - query->q_number_modes) <= 0)
  1306. {
  1307. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1308. return ERROR_INSUFFICIENT_BUFFER;
  1309. }
  1310. query->q_number_modes += SetFixedModes(HWIndex,
  1311. HWIndex,
  1312. ASTClockMult[PixelDepth],
  1313. ASTDepth[PixelDepth],
  1314. Pitch,
  1315. FreeTables,
  1316. BookValues[EndIndex].ClockFreq,
  1317. &pmode);
  1318. OldPmode->Refresh = DEFAULT_REFRESH;
  1319. /*
  1320. * Set up the canned mode tables.
  1321. */
  1322. if ((FreeTables = MaxModes - query->q_number_modes) <= 0)
  1323. {
  1324. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1325. return ERROR_INSUFFICIENT_BUFFER;
  1326. }
  1327. query->q_number_modes += SetFixedModes(StartIndex,
  1328. EndIndex,
  1329. ASTClockMult[PixelDepth],
  1330. ASTDepth[PixelDepth],
  1331. Pitch,
  1332. FreeTables,
  1333. BookValues[EndIndex].ClockFreq,
  1334. &pmode);
  1335. } /* end if (enough memory for 1024x768) */
  1336. } /* end for (loop on 1024x768 pixel depth) */
  1337. /*
  1338. * If we installed any 1024x768 mode tables, report that
  1339. * 1024x768 is supported.
  1340. */
  1341. if (query->q_number_modes > LastNumModes)
  1342. {
  1343. query->q_status_flags |= VRES_1024x768;
  1344. LastNumModes = query->q_number_modes;
  1345. }
  1346. /*
  1347. * Select the "canned" mode tables for 1280x1024.
  1348. *
  1349. * The DACs used on AST Premmia machines only support
  1350. * interlaced modes at this resolution, and there
  1351. * is no configured hardware default refresh rate.
  1352. */
  1353. StartIndex = B1280F87;
  1354. EndIndex = B1280F95;
  1355. Pitch = 1280;
  1356. NumPixels = Pitch * 1024;
  1357. /*
  1358. * Fill in the mode tables for 1280x1024 at all pixel depths.
  1359. */
  1360. for (PixelDepth = DEPTH_4BPP; PixelDepth <= DEPTH_8BPP; PixelDepth++)
  1361. {
  1362. /*
  1363. * Only include modes if there is enough memory.
  1364. */
  1365. if ((NumPixels * ASTNybblesPerPixel[PixelDepth]) <= MemAvail)
  1366. {
  1367. /*
  1368. * Set up the canned mode tables.
  1369. */
  1370. if ((FreeTables = MaxModes - query->q_number_modes) <= 0)
  1371. {
  1372. VideoDebugPrint((DEBUG_ERROR, "Exceeded maximum allowable number of modes - aborting query\n"));
  1373. return ERROR_INSUFFICIENT_BUFFER;
  1374. }
  1375. query->q_number_modes += SetFixedModes(StartIndex,
  1376. EndIndex,
  1377. ASTClockMult[PixelDepth],
  1378. ASTDepth[PixelDepth],
  1379. Pitch,
  1380. FreeTables,
  1381. BookValues[EndIndex].ClockFreq,
  1382. &pmode);
  1383. } /* end if (enough memory for 1280x1024) */
  1384. } /* end for (loop on 1280x1024 pixel depth) */
  1385. /*
  1386. * If we installed any 1280x1024 mode tables, report that
  1387. * 1280x1024 is supported.
  1388. */
  1389. if (query->q_number_modes > LastNumModes)
  1390. query->q_status_flags |= VRES_1280x1024;
  1391. return NO_ERROR;
  1392. } /* ReadAST() */
  1393. /*
  1394. * VP_STATUS ReadZenith(, Modes);
  1395. *
  1396. * struct st_mode_table *Modes; Mode tables to be filled in
  1397. *
  1398. * Routine to get CRT parameters for Zenith versions of
  1399. * our cards. Mapped to NEC 3D or compatible until we get
  1400. * info on how to read the actual parameters.
  1401. *
  1402. * Returns:
  1403. * NO_ERROR
  1404. */
  1405. VP_STATUS ReadZenith(struct st_mode_table *Modes)
  1406. {
  1407. ReadOEM3(Modes);
  1408. return NO_ERROR;
  1409. }
  1410. /*
  1411. * VP_STATUS ReadOlivetti(Modes);
  1412. *
  1413. * struct st_mode_table *Modes; Mode tables to be filled in
  1414. *
  1415. * Routine to get CRT parameters for Olivetti versions of
  1416. * our cards. Mapped to NEC 3D or compatible until we get
  1417. * info on how to read the actual parameters.
  1418. *
  1419. * Returns:
  1420. * NO_ERROR
  1421. */
  1422. VP_STATUS ReadOlivetti(struct st_mode_table *Modes)
  1423. {
  1424. ReadOEM3(Modes);
  1425. return NO_ERROR;
  1426. }
  1427. /***************************************************************************
  1428. *
  1429. * VP_STATUS ReadDell(Modes);
  1430. *
  1431. * struct st_mode_table *Modes; Mode table to be filled in
  1432. *
  1433. * DESCRIPTION:
  1434. * Routine to get CRT parameters for Dell versions of our cards.
  1435. *
  1436. * RETURN VALUE:
  1437. * NO_ERROR
  1438. *
  1439. * GLOBALS CHANGED:
  1440. * ClockGenerator[] array
  1441. *
  1442. * CALLED BY:
  1443. * OEMGetParms()
  1444. *
  1445. * AUTHOR:
  1446. * Robert Wolff
  1447. *
  1448. * CHANGE HISTORY:
  1449. *
  1450. * TEST HISTORY:
  1451. *
  1452. ***************************************************************************/
  1453. VP_STATUS ReadDell(struct st_mode_table *Modes)
  1454. {
  1455. struct st_mode_table *pmode; /* Mode table we are currently working on */
  1456. UCHAR Fubar; // Temporary variable
  1457. pmode = Modes;
  1458. /*
  1459. * Get the 640x480 mode table.
  1460. *
  1461. * NOTE: Modes points to an array of 4 mode tables, one for each
  1462. * resolution. If a resolution is not configured, its
  1463. * mode table is left empty.
  1464. */
  1465. OUTP(reg1CE, DELL_640_STORE);
  1466. Fubar = INP(reg1CF);
  1467. VideoDebugPrint((DEBUG_DETAIL, "Dell 640x480: 0x1CF reports 0x%X\n", Fubar));
  1468. switch(Fubar & MASK_640_DELL)
  1469. {
  1470. case M640F72DELL:
  1471. VideoDebugPrint((DEBUG_DETAIL, "Dell 640x480: 72Hz\n"));
  1472. BookVgaTable(B640F72, pmode);
  1473. break;
  1474. case M640F60DELL:
  1475. VideoDebugPrint((DEBUG_DETAIL, "Dell 640x480: 60Hz explicit\n"));
  1476. default: /* All VGA monitors support 640x480 60Hz */
  1477. VideoDebugPrint((DEBUG_DETAIL, "Dell 640x480: 60Hz\n"));
  1478. BookVgaTable(B640F60, pmode);
  1479. break;
  1480. }
  1481. pmode++;
  1482. /*
  1483. * Get the 800x600 mode table.
  1484. */
  1485. OUTP(reg1CE, DELL_800_STORE);
  1486. Fubar = INP(reg1CF);
  1487. VideoDebugPrint((DEBUG_DETAIL, "Dell 800x600: 0x1CF reports 0x%X\n", Fubar));
  1488. switch(Fubar & MASK_800_DELL)
  1489. {
  1490. case M800F72DELL:
  1491. VideoDebugPrint((DEBUG_DETAIL, "Dell 800x600: 72Hz\n"));
  1492. BookVgaTable(B800F72, pmode);
  1493. break;
  1494. case M800F60DELL:
  1495. VideoDebugPrint((DEBUG_DETAIL, "Dell 800x600: 60Hz\n"));
  1496. BookVgaTable(B800F60, pmode);
  1497. break;
  1498. case M800F56DELL:
  1499. VideoDebugPrint((DEBUG_DETAIL, "Dell 800x600: 56Hz explicit\n"));
  1500. default:
  1501. VideoDebugPrint((DEBUG_DETAIL, "Dell 800x600: 56Hz\n"));
  1502. BookVgaTable(B800F56, pmode);
  1503. break;
  1504. }
  1505. pmode++;
  1506. /*
  1507. * Get the 1024x768 mode table.
  1508. */
  1509. OUTP(reg1CE, DELL_1024_STORE);
  1510. Fubar = INP(reg1CF);
  1511. VideoDebugPrint((DEBUG_DETAIL, "Dell 1024x768: 0x1CF reports 0x%X\n", Fubar));
  1512. switch(Fubar & MASK_1024_DELL)
  1513. {
  1514. case M1024F72DELL:
  1515. VideoDebugPrint((DEBUG_DETAIL, "Dell 1024x768: 72Hz\n"));
  1516. BookVgaTable(B1024F72, pmode);
  1517. break;
  1518. case M1024F70DELL:
  1519. VideoDebugPrint((DEBUG_DETAIL, "Dell 1024x768: 70Hz\n"));
  1520. BookVgaTable(B1024F70, pmode);
  1521. break;
  1522. case M1024F60DELL:
  1523. VideoDebugPrint((DEBUG_DETAIL, "Dell 1024x768: 60Hz\n"));
  1524. BookVgaTable(B1024F60, pmode);
  1525. break;
  1526. case M1024F87DELL:
  1527. VideoDebugPrint((DEBUG_DETAIL, "Dell 1024x768: 87Hz interlaced explicit\n"));
  1528. default:
  1529. VideoDebugPrint((DEBUG_DETAIL, "Dell 1024x768: 87Hz interlaced\n"));
  1530. BookVgaTable(B1024F87, pmode);
  1531. break;
  1532. }
  1533. pmode++;
  1534. /*
  1535. * Skip 1152x864. This mode is not used on Mach 32 cards, and
  1536. * this routine is only called for Mach 32 cards.
  1537. */
  1538. pmode++;
  1539. /*
  1540. * Get the 1280x1024 mode table.
  1541. */
  1542. OUTP(reg1CE, DELL_1280_STORE);
  1543. Fubar = INP(reg1CF);
  1544. VideoDebugPrint((DEBUG_DETAIL, "Dell 1280x1024: 0x1CF reports 0x%X\n", Fubar));
  1545. switch(Fubar & MASK_1280_DELL)
  1546. {
  1547. case M1280F74DELL:
  1548. VideoDebugPrint((DEBUG_DETAIL, "Dell 1280x1024: 74Hz\n"));
  1549. BookVgaTable(B1280F74, pmode);
  1550. break;
  1551. case M1280F70DELL:
  1552. VideoDebugPrint((DEBUG_DETAIL, "Dell 1280x1024: 70Hz\n"));
  1553. BookVgaTable(B1280F70, pmode);
  1554. break;
  1555. case M1280F60DELL:
  1556. VideoDebugPrint((DEBUG_DETAIL, "Dell 1280x1024: 60Hz\n"));
  1557. BookVgaTable(B1280F60, pmode);
  1558. break;
  1559. case M1280F87DELL:
  1560. VideoDebugPrint((DEBUG_DETAIL, "Dell 1280x1024: 87Hz interlaced explicit\n"));
  1561. default:
  1562. VideoDebugPrint((DEBUG_DETAIL, "Dell 1280x1024: 87Hz interlaced\n"));
  1563. BookVgaTable(B1280F87, pmode);
  1564. break;
  1565. }
  1566. return NO_ERROR;
  1567. } /* ReadDell() */
  1568. /***************************************************************************
  1569. *
  1570. * ULONG DetectDell(Query);
  1571. *
  1572. * struct query_structure *Query; Description of video card setup
  1573. *
  1574. * DESCRIPTION:
  1575. * Routine to check whether or not we are dealing with a Dell machine.
  1576. *
  1577. * RETURN VALUE:
  1578. * Offset of beginning of the Dell information block into the BIOS
  1579. * 0 if this is not a Dell OEM implementation.
  1580. *
  1581. * GLOBALS CHANGED:
  1582. * None
  1583. *
  1584. * CALLED BY:
  1585. * OEMGetParms()
  1586. *
  1587. * AUTHOR:
  1588. * Robert Wolff
  1589. *
  1590. * CHANGE HISTORY:
  1591. *
  1592. * TEST HISTORY:
  1593. *
  1594. ***************************************************************************/
  1595. ULONG DetectDell(struct query_structure *Query)
  1596. {
  1597. ULONG CurrentOffset; /* Current offset to check for Dell signature */
  1598. ULONG BiosLength; /* Length of the video BIOS */
  1599. /*
  1600. * Dell OEM implementations will have an information block
  1601. * starting at an offset that is a multiple of DELL_REC_SPACING
  1602. * into the video BIOS. The first 4 bytes of this block will
  1603. * contain the signature value DELL_REC_VALUE. Find out how
  1604. * large the video BIOS is, and step through it checking for
  1605. * the signature string. If we reach the end of the video
  1606. * BIOS without finding the signature string, this is not
  1607. * a Dell OEM implementation.
  1608. */
  1609. BiosLength = (ULONG)(VideoPortReadRegisterUchar(Query->q_bios + 2)) * 512;
  1610. for(CurrentOffset = DELL_REC_SPACING; CurrentOffset < BiosLength; CurrentOffset += DELL_REC_SPACING)
  1611. {
  1612. if (VideoPortReadRegisterUlong((PULONG)(Query->q_bios + CurrentOffset)) == DELL_REC_VALUE)
  1613. return CurrentOffset;
  1614. }
  1615. /*
  1616. * Signature string not found, so this is not a Dell OEM implementation.
  1617. */
  1618. return 0;
  1619. } /* DetectDell() */
  1620. /***************************************************************************
  1621. *
  1622. * BOOL DetectSylvester(Query, HeaderOffset);
  1623. *
  1624. * struct query_structure *Query; Description of video card setup
  1625. * ULONG HeaderOffset; Offset of Dell header into video BIOS
  1626. *
  1627. * DESCRIPTION:
  1628. * Routine to check whether or not the Dell machine we are dealing
  1629. * with is a Sylvester (table of pixel clock frequencies is stored
  1630. * in BIOS image, rather than using a fixed table). If it is a
  1631. * Sylvester, load the table of clock frequencies.
  1632. *
  1633. * RETURN VALUE:
  1634. * TRUE if this is a Sylvester
  1635. * FALSE if this is not a Sylvester
  1636. *
  1637. * GLOBALS CHANGED:
  1638. * ClockGenerator[]
  1639. *
  1640. * CALLED BY:
  1641. * OEMGetParms()
  1642. *
  1643. * NOTE:
  1644. * Assumes that this is a Dell OEM implementation. Results are undefined
  1645. * when run on other systems.
  1646. *
  1647. * AUTHOR:
  1648. * Robert Wolff
  1649. *
  1650. * CHANGE HISTORY:
  1651. *
  1652. * TEST HISTORY:
  1653. *
  1654. ***************************************************************************/
  1655. BOOL DetectSylvester(struct query_structure *Query, ULONG HeaderOffset)
  1656. {
  1657. PUSHORT TablePointer; /* Pointer to the clock table in the BIOS */
  1658. USHORT Scratch; /* Temporary variable */
  1659. /*
  1660. * Dell machines which store the clock table in the BIOS have
  1661. * the signature DELL_TABLE_PRESENT at offset DELL_TP_OFFSET
  1662. * into the video information table (which starts at offset
  1663. * HeaderOffset into the BIOS). Older implementations (i.e.
  1664. * the Omniplex) use a fixed frequency table, and do not have
  1665. * this signature string.
  1666. */
  1667. if (VideoPortReadRegisterUshort((PUSHORT)(Query->q_bios + HeaderOffset + DELL_TP_OFFSET)) != DELL_TABLE_PRESENT)
  1668. return FALSE;
  1669. /*
  1670. * This is a Sylvester. The offset of the frequency table into the
  1671. * BIOS is stored at offset DELL_TABLE_OFFSET into the video
  1672. * information table.
  1673. */
  1674. TablePointer = (PUSHORT)(Query->q_bios + VideoPortReadRegisterUshort((PUSHORT)(Query->q_bios + HeaderOffset + DELL_TABLE_OFFSET)));
  1675. /*
  1676. * The frequency table has a 4-byte header. The first 2 bytes are
  1677. * the signature string DELL_TABLE_SIG - if this signature is not
  1678. * present, assume that the DELL_TABLE_PRESENT string was actually
  1679. * other data that happened to match, and treat this as an older
  1680. * implementation.
  1681. *
  1682. * The last 2 bytes are the table type. Currently, only table type
  1683. * 1 (16 entries, each is a word specifying the pixel clock frequency
  1684. * in units of 10 kHz) is supported. Treat other table types as an
  1685. * older implementation.
  1686. */
  1687. if (VideoPortReadRegisterUshort(TablePointer++) != DELL_TABLE_SIG)
  1688. return FALSE;
  1689. if (VideoPortReadRegisterUshort(TablePointer++) != 1)
  1690. return FALSE;
  1691. /*
  1692. * We have found a valid frequency table. Load its contents into
  1693. * our frequency table. The multiplication is because the table
  1694. * in the BIOS is in units of 10 kHz, and our table is in Hz.
  1695. */
  1696. for (Scratch = 0; Scratch < 16; Scratch++)
  1697. {
  1698. ClockGenerator[Scratch] = VideoPortReadRegisterUshort(TablePointer++) * 10000L;
  1699. }
  1700. return TRUE;
  1701. } /* DetectSylvester() */
  1702. /*
  1703. * VP_STATUS ReadOEM1(Modes);
  1704. *
  1705. * struct st_mode_table *Modes; Mode tables to be filled in
  1706. *
  1707. * Generic OEM monitor for future use.
  1708. *
  1709. * Resolutions supported:
  1710. * 640x480 60Hz noninterlaced
  1711. *
  1712. * (straight VGA monitor)
  1713. *
  1714. * Returns:
  1715. * NO_ERROR
  1716. */
  1717. VP_STATUS ReadOEM1(struct st_mode_table *Modes)
  1718. {
  1719. BookVgaTable(B640F60, &(Modes[RES_640]));
  1720. return NO_ERROR;
  1721. }
  1722. /*
  1723. * VP_STATUS ReadOEM2(Modes);
  1724. *
  1725. * struct st_mode_table *Modes; Mode tables to be filled in
  1726. *
  1727. * Generic OEM monitor for future use.
  1728. *
  1729. * Resolutions supported:
  1730. * 640x480 60Hz noninterlaced
  1731. * 1024x768 87Hz interlaced
  1732. *
  1733. * (8514-compatible monitor)
  1734. *
  1735. * Returns:
  1736. * NO_ERROR
  1737. */
  1738. VP_STATUS ReadOEM2(struct st_mode_table *Modes)
  1739. {
  1740. BookVgaTable(B640F60, &(Modes[RES_640]));
  1741. BookVgaTable(B1024F87, &(Modes[RES_1024]));
  1742. return NO_ERROR;
  1743. }
  1744. /*
  1745. * VP_STATUS ReadOEM3(Modes);
  1746. *
  1747. * struct st_mode_table *Modes; Mode tables to be filled in
  1748. *
  1749. * Generic OEM monitor for future use.
  1750. *
  1751. * Resolutions supported:
  1752. * 640x480 60Hz noninterlaced
  1753. * 800x600 56Hz noninterlaced
  1754. * 1024x768 87Hz interlaced
  1755. *
  1756. * (NEC 3D or compatible)
  1757. *
  1758. * Returns:
  1759. * NO_ERROR
  1760. */
  1761. VP_STATUS ReadOEM3(struct st_mode_table *Modes)
  1762. {
  1763. BookVgaTable(B640F60, &(Modes[RES_640]));
  1764. BookVgaTable(B800F56, &(Modes[RES_800]));
  1765. BookVgaTable(B1024F87, &(Modes[RES_1024]));
  1766. return NO_ERROR;
  1767. }
  1768. /*
  1769. * VP_STATUS ReadOEM4(Modes);
  1770. *
  1771. * struct st_mode_table *Modes; Mode tables to be filled in
  1772. *
  1773. * Generic OEM monitor for future use.
  1774. *
  1775. * Resolutions supported:
  1776. * 640x480 60Hz noninterlaced
  1777. * 800x600 72Hz noninterlaced
  1778. * 1024x768 60Hz noninterlaced
  1779. * 1280x1024 87Hz interlaced
  1780. *
  1781. * (TVM MediaScan 4A+ or compatible)
  1782. *
  1783. * Returns:
  1784. * NO_ERROR
  1785. */
  1786. VP_STATUS ReadOEM4(struct st_mode_table *Modes)
  1787. {
  1788. BookVgaTable(B640F60, &(Modes[RES_640]));
  1789. BookVgaTable(B800F72, &(Modes[RES_800]));
  1790. BookVgaTable(B1024F60, &(Modes[RES_1024]));
  1791. BookVgaTable(B1280F87, &(Modes[RES_1280]));
  1792. return NO_ERROR;
  1793. }
  1794. /*
  1795. * VP_STATUS ReadOEM5(Modes);
  1796. *
  1797. * struct st_mode_table *Modes; Mode tables to be filled in
  1798. *
  1799. * Generic OEM monitor for future use.
  1800. *
  1801. * Resolutions supported:
  1802. * 640x480 60Hz noninterlaced
  1803. * 800x600 72Hz noninterlaced
  1804. * 1024x768 72Hz noninterlaced
  1805. * 1280x1024 60Hz noninterlaced
  1806. *
  1807. * (NEC 5FG or compatible)
  1808. *
  1809. * Returns:
  1810. * NO_ERROR
  1811. */
  1812. VP_STATUS ReadOEM5(struct st_mode_table *Modes)
  1813. {
  1814. BookVgaTable(B640F60, &(Modes[RES_640]));
  1815. BookVgaTable(B800F72, &(Modes[RES_800]));
  1816. BookVgaTable(B1024F72, &(Modes[RES_1024]));
  1817. BookVgaTable(B1280F60, &(Modes[RES_1280]));
  1818. return NO_ERROR;
  1819. }