Source code of Windows XP (NT5)
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.

3840 lines
144 KiB

  1. /**************************************************************************\
  2. $Header: o:\src/RCS/MGA.C 1.10 94/03/02 04:46:47 jyharbec Exp $
  3. $Log: MGA.C $
  4. * Revision 1.10 94/03/02 04:46:47 jyharbec
  5. * Modification for PCI to default to board 0.
  6. *
  7. * Revision 1.9 94/02/28 04:04:36 jyharbec
  8. * Code for 5-6-5 driver;
  9. * Setting cursor colors for ViewPoint.
  10. *
  11. * Revision 1.8 94/01/05 12:03:32 jyharbec
  12. * New service IOCTL_VIDEO_MTX_QUERY_HW_DATA.
  13. *
  14. * Revision 1.7 93/12/20 11:42:36 jyharbec
  15. * Modified S3 to MGA in debug message text.
  16. *
  17. * Revision 1.6 93/11/04 04:50:04 dlee
  18. * Modified for Alpha.
  19. *
  20. * Revision 1.5 93/10/15 11:30:00 jyharbec
  21. * Added service IOCTL_VIDEO_MTX_QUERY_BOARD_ID.
  22. *
  23. * Revision 1.4 93/10/06 05:39:59 jyharbec
  24. * Modifications required to update MGA.INF file to current version.
  25. *
  26. * Revision 1.3 93/09/23 11:42:49 jyharbec
  27. * Modification to IOCTL_VIDEO_MTX_QUERY_RAMDAC_INFO to include Overscan.
  28. *
  29. * Revision 1.2 93/09/01 13:29:07 jyharbec
  30. * Take into account DISPTYPE_UNUSABLE from HwModeData structures.
  31. *
  32. * Revision 1.1 93/08/27 12:37:09 jyharbec
  33. * Initial revision
  34. *
  35. \**************************************************************************/
  36. /****************************************************************************\
  37. * MODULE: MGA.C
  38. *
  39. * DESCRIPTION: This module contains the code that implements the MGA miniport
  40. * driver. [Based on S3.C (Mar 1,1993) from Windows-NT DDK]
  41. *
  42. * Copyright (c) 1990-1992 Microsoft Corporation
  43. * Copyright (c) 1993 Matrox Electronic Systems Ltd.
  44. *
  45. * History:
  46. * 23AUG93 - Added check for micro-channel adapter in FindAdapter
  47. *
  48. \****************************************************************************/
  49. #include "switches.h"
  50. #include <string.h>
  51. #include "bind.h"
  52. #include "sxci.h"
  53. #include "mga.h"
  54. #include "defbind.h"
  55. #include "mga_nt.h"
  56. //
  57. // New entry points added for NT 5.0.
  58. //
  59. #if (_WIN32_WINNT >= 500)
  60. //
  61. // Routine to set a desired DPMS power management state.
  62. //
  63. VP_STATUS
  64. MgaSetPower50(
  65. PMGA_DEVICE_EXTENSION phwDeviceExtension,
  66. ULONG HwDeviceId,
  67. PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
  68. );
  69. //
  70. // Routine to retrieve possible DPMS power management states.
  71. //
  72. VP_STATUS
  73. MgaGetPower50(
  74. PMGA_DEVICE_EXTENSION phwDeviceExtension,
  75. ULONG HwDeviceId,
  76. PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
  77. );
  78. //
  79. // Routine to retrieve the Enhanced Display ID structure via DDC
  80. //
  81. ULONG
  82. MgaGetVideoChildDescriptor(
  83. PVOID HwDeviceExtension,
  84. PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
  85. PVIDEO_CHILD_TYPE pChildType,
  86. PVOID pvChildDescriptor,
  87. PULONG pHwId,
  88. PULONG pUnused
  89. );
  90. #endif // _WIN32_WINNT >= 500
  91. // From MTXINIT.C; it should be in some header file.
  92. #define BOARD_MGA_RESERVED 0x07
  93. VIDEO_MODE_INFORMATION CommonVideoModeInformation =
  94. {
  95. sizeof(VIDEO_MODE_INFORMATION), // Size of the mode informtion structure
  96. 0, // *Mode index used in setting the mode
  97. 1280, // *X Resolution, in pixels
  98. 1024, // *Y Resolution, in pixels
  99. 1024, // *Screen stride
  100. 1, // Number of video memory planes
  101. 8, // *Number of bits per plane
  102. 1, // Screen Frequency, in Hertz
  103. 330, // Horizontal size of screen in millimeters
  104. 240, // Vertical size of screen in millimeters
  105. 8, // Number Red pixels in DAC
  106. 8, // Number Green pixels in DAC
  107. 8, // Number Blue pixels in DAC
  108. 0x00000000, // *Mask for Red Pixels in non-palette modes
  109. 0x00000000, // *Mask for Green Pixels in non-palette modes
  110. 0x00000000, // *Mask for Blue Pixels in non-palette modes
  111. 0, // *Mode description flags.
  112. 1280, // *Video Memory Bitmap Width
  113. 1024 // *Video Memory Bitmap Height
  114. };
  115. #if NB_BOARD_MAX > 7
  116. #error Error! Modify MultiModes array!
  117. #endif
  118. UCHAR MgaBusType[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  119. // Nb of modes supported by 1, 2, 3, 4, 5, 6, 7 boards.
  120. USHORT MultiModes[] = { 0, 1, 2, 2, 3, 2, 4, 2 };
  121. USHORT SingleWidths[] = { 640, 768, 800, 1024, 1152, 1280, 1600, 0xffff};
  122. USHORT SingleHeights[]= { 480, 576, 600, 768, 882, 1024, 1200, 0xffff};
  123. // MGA communication access ranges.
  124. VIDEO_ACCESS_RANGE MgaDriverCommonAccessRange[] =
  125. {
  126. // {0x00000400, 0x00000000, 0x000000AB, 0, 0, 1}, // BIOS Communication Area
  127. {0x000003B4, 0x00000000, 0x00000002, 1, 0, 1}, // 0 Titan VGA & CRTC
  128. {0x000003BA, 0x00000000, 0x00000001, 1, 0, 1}, // 1
  129. {0x000003C0, 0x00000000, 0x00000010, 1, 0, 1}, // 2
  130. {0x000003D4, 0x00000000, 0x00000008, 1, 0, 1}, // 3
  131. {0x000003DE, 0x00000000, 0x00000002, 1, 0, 1}, // 4
  132. #if USE_SETUP_VGA
  133. {0x000046E8, 0x00000000, 0x00000002, 1, 0, 1}, // 5
  134. {0x00000410, 0x00000000, 0x00000001, 0, 0, 1}, // 6
  135. {0x00000449, 0x00000000, 0x0000001e, 0, 0, 1}, // 7
  136. {0x00000484, 0x00000000, 0x00000007, 0, 0, 1}, // 8
  137. {0x000004A8, 0x00000000, 0x00000004, 0, 0, 1}, // 9
  138. {0x000A0000, 0x00000000, 0x00010000, 0, 0, 1} // 10
  139. //{0x000B8000, 0x00000000, 0x00008000, 0, 0, 1} // 11
  140. #else
  141. {0x000046E8, 0x00000000, 0x00000002, 1, 0, 1} // 5
  142. #endif
  143. };
  144. // MGA windows access ranges.
  145. VIDEO_ACCESS_RANGE MgaDriverAccessRange[] =
  146. {
  147. {0x000C8000, 0x00000000, 0x00004000, 0, 0, 0}, // Command window 0
  148. {0x0000C000, 0x00000000, 0x00000100, 1, 0, 0}, // Config space 0
  149. {0x00000000, 0x00000000, 0x00004000, 0, 0, 0}, // Command window 1
  150. {0x0000C000, 0x00000000, 0x00000100, 1, 0, 0}, // Config space 1
  151. {0x00000000, 0x00000000, 0x00004000, 0, 0, 0}, // Command window 2
  152. {0x0000C000, 0x00000000, 0x00000100, 1, 0, 0}, // Config space 2
  153. {0x00000000, 0x00000000, 0x00004000, 0, 0, 0}, // Command window 3
  154. {0x0000C000, 0x00000000, 0x00000100, 1, 0, 0}, // Config space 3
  155. {0x00000000, 0x00000000, 0x00004000, 0, 0, 0}, // Command window 4
  156. {0x0000C000, 0x00000000, 0x00000100, 1, 0, 0}, // Config space 4
  157. {0x00000000, 0x00000000, 0x00004000, 0, 0, 0}, // Command window 5
  158. {0x0000C000, 0x00000000, 0x00000100, 1, 0, 0}, // Config space 5
  159. {0x00000000, 0x00000000, 0x00004000, 0, 0, 0}, // Command window 6
  160. {0x0000C000, 0x00000000, 0x00000100, 1, 0, 0} // Config space 6
  161. };
  162. #if (!USE_VP_GET_ACCESS_RANGES)
  163. VIDEO_ACCESS_RANGE MgaDriverSupplAccessRange[] =
  164. {
  165. {0x00000CF8, 0x00000000, 0x00000008, 1, 0, 1}
  166. //{0x000E0000, 0x00000000, 0x00020000, 1, 0, 1}
  167. };
  168. #endif
  169. #define NUM_MGA_COMMON_ACCESS_RANGES \
  170. (sizeof(MgaDriverCommonAccessRange) / sizeof(VIDEO_ACCESS_RANGE))
  171. #define NUM_MGA_ACCESS_RANGES \
  172. (sizeof(MgaDriverAccessRange) / sizeof(VIDEO_ACCESS_RANGE))
  173. #if (!USE_VP_GET_ACCESS_RANGES)
  174. #define NUM_MGA_SUPPL_ACCESS_RANGES \
  175. (sizeof(MgaDriverSupplAccessRange) / sizeof(VIDEO_ACCESS_RANGE))
  176. #else
  177. #define NUM_MGA_SUPPL_ACCESS_RANGES 0
  178. #endif
  179. #define NUM_ALL_ACCESS_RANGES \
  180. (NUM_MGA_COMMON_ACCESS_RANGES + NUM_MGA_ACCESS_RANGES + NUM_MGA_SUPPL_ACCESS_RANGES)
  181. INTERFACE_TYPE NtInterfaceType;
  182. HwData *pMgaBoardData;
  183. ULONG ulNewInfoSize;
  184. PUCHAR pucNewInfo;
  185. PUCHAR pMgaBiosVl;
  186. extern PVOID pMgaDeviceExtension;
  187. extern word mtxVideoMode;
  188. extern byte NbBoard;
  189. extern dword MgaSel;
  190. extern PVOID pMgaBaseAddr;
  191. extern HwData Hw[NB_BOARD_MAX+1];
  192. extern byte iBoard;
  193. extern char *mgainf;
  194. extern char DefaultVidset[];
  195. extern dword ProductMGA[NB_BOARD_MAX];
  196. // Board number conversion macro.
  197. // In the user-mode drivers, boards are numbered sequentially starting from 0
  198. // at the upper left corner and going from left to right and then top to
  199. // bottom. In the miniport driver, we might want to start from the lower
  200. // left corner.
  201. #if 1
  202. // Same numbering convention as the user-mode driver.
  203. #define CONVERT_BOARD_NUMBER(n) n = n
  204. #else
  205. // Starting from lower left instead of upper left corner.
  206. #define CONVERT_BOARD_NUMBER(n) n = ((pCurMulti->MulArrayHeight - 1) * \
  207. pCurMulti->MulArrayWidth) - n + \
  208. 2*(n % pCurMulti->MulArrayWidth)
  209. #endif
  210. // Function Prototypes
  211. //
  212. // Functions that start with 'Mga' are entry points for the OS port driver.
  213. #ifdef MGA_WINNT35
  214. BOOLEAN
  215. MgaResetHw(
  216. PVOID HwDeviceExtension,
  217. ULONG Columns,
  218. ULONG Rows
  219. );
  220. #endif
  221. VP_STATUS
  222. MgaFindAdapter(
  223. PVOID HwDeviceExtension,
  224. PVOID HwContext,
  225. PWSTR ArgumentString,
  226. PVIDEO_PORT_CONFIG_INFO ConfigInfo,
  227. PUCHAR Again
  228. );
  229. BOOLEAN
  230. MgaInitialize(
  231. PVOID HwDeviceExtension
  232. );
  233. BOOLEAN
  234. MgaStartIO(
  235. PVOID HwDeviceExtension,
  236. PVIDEO_REQUEST_PACKET RequestPacket
  237. );
  238. VP_STATUS
  239. MgaInitModeList(
  240. PMGA_DEVICE_EXTENSION MgaDeviceExtension);
  241. VP_STATUS
  242. MgaSetColorLookup(
  243. PMGA_DEVICE_EXTENSION MgaDeviceExtension,
  244. PVIDEO_CLUT ClutBuffer,
  245. ULONG ClutBufferSize
  246. );
  247. VOID MgaSetCursorColour(
  248. PMGA_DEVICE_EXTENSION MgaDeviceExtension,
  249. ULONG ulFgColour,
  250. ULONG ulBgColour);
  251. // For WinNT 3.5
  252. // Code NOT to be made pageable:
  253. // SetVgaEn();
  254. // setVgaMode();
  255. // restoreVga();
  256. // checkCursorEn();
  257. // mtxCheckVgaEn();
  258. // mtxMapVLBSpace();
  259. // mtxUnMapVLBSpace();
  260. // mtxIsVLB();
  261. // isPciBus();
  262. // wideToIsa();
  263. // blankEcran();
  264. // delay_us();
  265. // _inp(); (macro)
  266. // _outp(); (macro)
  267. // rdDubicDReg();
  268. // rdDubicIReg();
  269. // rdDacReg();
  270. // rdTitanReg();
  271. // mgaReadDWORD(); (macro)
  272. // mgaReadBYTE(); (macro)
  273. // wrDubicDReg();
  274. // wrDubicIReg();
  275. // wrDacReg();
  276. // wrTitanReg();
  277. // mgaWriteBYTE(); (macro)
  278. // mgaWriteDWORD(); (macro)
  279. // Data NOT to be made pageable:
  280. // Hw (in mtxinit.c)
  281. // pMgaBaseAddr (in mtxinit.c)
  282. // iBoard (in mtxinit.c)
  283. // mtxVideoMode (in mtxinit.c)
  284. // pMgaDeviceExtension (in mtxinit.c)
  285. // isVLBFlag (in mtxvideo.c)
  286. // cursorStat (in mtxvideo.c)
  287. // saveBitOperation (in mtxvideo.c)
  288. #if defined(ALLOC_PRAGMA)
  289. #pragma alloc_text(PAGE,DriverEntry)
  290. #pragma alloc_text(PAGE,MgaFindAdapter)
  291. #pragma alloc_text(PAGE,MgaInitialize)
  292. #pragma alloc_text(PAGE,MgaStartIO)
  293. #pragma alloc_text(PAGE,MgaInitModeList)
  294. //#pragma alloc_text(PAGE,MgaSetColorLookup)
  295. #pragma alloc_text(PAGE,MgaSetCursorColour)
  296. #if (_WIN32_WINNT >= 500)
  297. #pragma alloc_text(PAGE_COM, MgaSetPower50)
  298. #pragma alloc_text(PAGE_COM, MgaGetPower50)
  299. #pragma alloc_text(PAGE_COM, MgaGetVideoChildDescriptor)
  300. #endif // _WIN32_WINNT >= 500
  301. #endif
  302. //#if defined(ALLOC_PRAGMA)
  303. // #pragma data_seg("PAGE")
  304. //#endif
  305. // External function prototypes
  306. extern volatile byte _Far *setmgasel(dword MgaSel, dword phyadr, dword limit);
  307. bool MapBoard(void);
  308. char *adjustDefaultVidset();
  309. PVOID AllocateSystemMemory(ULONG NumberOfBytes);
  310. char *mtxConvertMgaInf( char * );
  311. void SetVgaEn();
  312. char *selectMgaInfoBoard();
  313. #if USE_SETUP_VGA
  314. void setupVga(void);
  315. void restoreVga();
  316. #endif
  317. /****************************************************************************\
  318. * ULONG
  319. * DriverEntry (
  320. * PVOID Context1,
  321. * PVOID Context2)
  322. *
  323. * DESCRIPTION:
  324. * Installable driver initialization entry point.
  325. * This entry point is called directly by the I/O system.
  326. *
  327. * ARGUMENTS:
  328. * Context1 - First context value passed by the operating system. This is
  329. * the value with which the miniport driver calls VideoPortInitialize().
  330. *
  331. * Context2 - Second context value passed by the operating system. This is
  332. * the value with which the miniport driver calls VideoPortInitialize().
  333. *
  334. * RETURNS:
  335. * Status from VideoPortInitialize()
  336. *
  337. \****************************************************************************/
  338. ULONG
  339. DriverEntry (
  340. PVOID Context1,
  341. PVOID Context2
  342. )
  343. {
  344. VIDEO_HW_INITIALIZATION_DATA hwInitData;
  345. ULONG isaStatus, eisaStatus, microChannelStatus, pciStatus, minStatus;
  346. ULONG i, j;
  347. HwData TempHw;
  348. VideoDebugPrint((1, "MGA.SYS!DriverEntry\n"));
  349. //DbgBreakPoint();
  350. // Zero out structure.
  351. VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA)) ;
  352. // Specify sizes of structure and extension.
  353. hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
  354. // Set entry points.
  355. hwInitData.HwFindAdapter = MgaFindAdapter;
  356. hwInitData.HwInitialize = MgaInitialize;
  357. //hwInitData.HwInterrupt = NULL;
  358. hwInitData.HwStartIO = MgaStartIO;
  359. #ifdef MGA_WINNT35
  360. hwInitData.HwResetHw = MgaResetHw;
  361. //hwInitData.HwTimer = NULL;
  362. #endif
  363. #if (_WIN32_WINNT >= 500)
  364. //
  365. // Set new entry points added for NT 5.0.
  366. //
  367. hwInitData.HwSetPowerState = MgaSetPower50;
  368. hwInitData.HwGetPowerState = MgaGetPower50;
  369. hwInitData.HwGetVideoChildDescriptor = MgaGetVideoChildDescriptor;
  370. #endif // _WIN32_WINNT >= 500
  371. //
  372. // Determine the size we require for the device extension.
  373. //
  374. hwInitData.HwDeviceExtensionSize = sizeof(MGA_DEVICE_EXTENSION);
  375. // Always start with parameters for device0 in this case.
  376. //hwInitData.StartingDeviceNumber = 0;
  377. // This device only supports the internal bus type. So return the status
  378. // value directly to the operating system.
  379. // I think that each VPInitialize call will itself call MgaFindAdapter,
  380. // provided that the specified AdapterInterfaceType makes sense for the
  381. // hardware. MgaFindAdapter will call MapBoard. We can't be sure that
  382. // the last call to MapBoard will find all the boards, so we'll have to
  383. // accumulate the boards found, making sure that we don't record the
  384. // same board twice.
  385. //#if (defined(MGA_WINNT35) && defined(MGA_ALPHA))
  386. NbBoard = 0;
  387. //#endif
  388. hwInitData.AdapterInterfaceType = PCIBus;
  389. pciStatus = VideoPortInitialize(Context1,
  390. Context2,
  391. &hwInitData,
  392. NULL);
  393. hwInitData.AdapterInterfaceType = Isa;
  394. isaStatus = VideoPortInitialize(Context1,
  395. Context2,
  396. &hwInitData,
  397. NULL);
  398. hwInitData.AdapterInterfaceType = Eisa;
  399. eisaStatus = VideoPortInitialize(Context1,
  400. Context2,
  401. &hwInitData,
  402. NULL);
  403. hwInitData.AdapterInterfaceType = MicroChannel;
  404. microChannelStatus = VideoPortInitialize(Context1,
  405. Context2,
  406. &hwInitData,
  407. NULL);
  408. // We should have found all our boards at this point. We want to
  409. // reorder the Hw array so that the PCI boards are the first ones.
  410. // The MgaBusType array was initialized to MGA_BUS_INVALID.
  411. for (i = 0; i < NbBoard; i++)
  412. {
  413. // The only possibilities are MGA_BUS_PCI and MGA_BUS_ISA.
  414. if (MgaBusType[i] == MGA_BUS_ISA)
  415. {
  416. // We found an ISA board. Look for a PCI board.
  417. for (j = i+1; j < NbBoard; j++)
  418. {
  419. if (MgaBusType[j] == MGA_BUS_PCI)
  420. {
  421. // We found a PCI board, exchange them.
  422. TempHw = Hw[j];
  423. Hw[j] = Hw[i];
  424. Hw[i] = TempHw;
  425. MgaBusType[i] = MGA_BUS_PCI;
  426. MgaBusType[j] = MGA_BUS_ISA;
  427. MgaDriverAccessRange[i*2].RangeStart.LowPart = Hw[i].MapAddress;
  428. MgaDriverAccessRange[i*2+1].RangeStart.LowPart = Hw[i].ConfigSpace;
  429. MgaDriverAccessRange[j*2].RangeStart.LowPart = Hw[j].MapAddress;
  430. MgaDriverAccessRange[j*2+1].RangeStart.LowPart = Hw[j].ConfigSpace;
  431. break;
  432. }
  433. }
  434. }
  435. }
  436. // Return the smallest of isaStatus, eisaStatus, pciStatus, and
  437. // microChannelStatus.
  438. minStatus = (isaStatus < eisaStatus) ? isaStatus : eisaStatus;
  439. if (microChannelStatus < minStatus)
  440. minStatus = microChannelStatus;
  441. if (pciStatus < minStatus)
  442. minStatus = pciStatus;
  443. return(minStatus);
  444. } // end DriverEntry()
  445. #ifdef MGA_WINNT35
  446. /****************************************************************************\
  447. * VOID
  448. * MgaResetHw(VOID)
  449. *
  450. * DESCRIPTION:
  451. *
  452. * This function is called when the machine needs to bugchecks (go back
  453. * to the blue screen).
  454. *
  455. * This function should reset the video adapter to a character mode,
  456. * or at least to a state from which an int 10 can reset the card to
  457. * a character mode.
  458. *
  459. * This routine CAN NOT call int10.
  460. * It can only call Read\Write Port\Register functions from the port driver.
  461. *
  462. * The function must also be completely in non-paged pool since the IO\MM
  463. * subsystems may have crashed.
  464. *
  465. * ARGUMENTS:
  466. *
  467. * HwDeviceExtension - Supplies the miniport driver's adapter storage.
  468. *
  469. * Columns - Number of columns in the requested mode.
  470. *
  471. * Rows - Number of rows in the requested mode.
  472. *
  473. * RETURN VALUE:
  474. *
  475. * The return value determines if the mode was completely programmed (TRUE)
  476. * or if an int10 should be done by the HAL to complete the modeset (FALSE).
  477. *
  478. \****************************************************************************/
  479. BOOLEAN MgaResetHw(
  480. PVOID HwDeviceExtension,
  481. ULONG Columns,
  482. ULONG Rows
  483. )
  484. {
  485. PMGA_DEVICE_EXTENSION MgaDeviceExtension;
  486. VideoDebugPrint((1, "MGA.SYS!MgaResetHw\n"));
  487. // There is nothing to be done to reset the board if the one that
  488. // went into hi-res was not VGA-enabled to start with. However it
  489. // will look nicer if we clear the screen. If the board was VGA-
  490. // enabled, we put it back into text mode, or as near as we can get.
  491. pMgaDeviceExtension =
  492. MgaDeviceExtension = (PMGA_DEVICE_EXTENSION)HwDeviceExtension;
  493. pMgaBaseAddr = MgaDeviceExtension->KernelModeMappedBaseAddress[0];
  494. // Make the cursor disappear.
  495. mtxCursorEnable(0);
  496. if (Hw[0].VGAEnable)
  497. {
  498. SetVgaEn();
  499. #if USE_SETUP_VGA
  500. setupVga();
  501. restoreVga();
  502. #endif
  503. mtxVideoMode = mtxPASSTHRU;
  504. }
  505. // Let the caller execute the Int10.
  506. return(FALSE);
  507. }
  508. #endif
  509. /****************************************************************************\
  510. * FIND_ADAPTER_STATUS
  511. * MgaFindAdapter(
  512. * PVOID HwDeviceExtension,
  513. * PVOID HwContext,
  514. * PWSTR ArgumentString,
  515. * PVIDEO_PORT_CONFIG_INFO ConfigInfo,
  516. * PUCHAR Again
  517. * )
  518. *
  519. * DESCRIPTION:
  520. *
  521. * This routine is called to determine if the adapter for this driver
  522. * is present in the system.
  523. * If it is present, the function fills out some information describing
  524. * the adapter.
  525. *
  526. * ARGUMENTS:
  527. *
  528. * HwDeviceExtension - Supplies the miniport driver's adapter storage. This
  529. * storage is initialized to zero before this call.
  530. *
  531. * HwContext - Supplies the context value which was passed to
  532. * VideoPortInitialize(). Must be NULL for PnP drivers.
  533. *
  534. * ArgumentString - Suuplies a NULL terminated ASCII string. This string
  535. * originates from the user.
  536. *
  537. * ConfigInfo - Returns the configuration information structure which is
  538. * filled by the miniport driver. This structure is initialized with
  539. * any knwon configuration information (such as SystemIoBusNumber) by
  540. * the port driver. Where possible, drivers should have one set of
  541. * defaults which do not require any supplied configuration information.
  542. *
  543. * Again - Indicates if the miniport driver wants the port driver to call
  544. * its VIDEO_HW_FIND_ADAPTER function again with a new device extension
  545. * and the same config info. This is used by the miniport drivers which
  546. * can search for several adapters on a bus.
  547. *
  548. * RETURN VALUE:
  549. *
  550. * This routine must return:
  551. *
  552. * VP_RETURN_FOUND - Indicates a host adapter was found and the
  553. * configuration information was successfully determined.
  554. *
  555. * VP_RETURN_ERROR - Indicates a host adapter was found but there was an
  556. * error obtaining the configuration information. If possible an error
  557. * should be logged.
  558. *
  559. * VP_RETURN_BAD_CONFIG - Indicates the supplied configuration was invalid.
  560. *
  561. * VP_RETURN_NOT_FOUND - Indicates no host adapter was found for the
  562. * supplied configuration information.
  563. *
  564. \****************************************************************************/
  565. VP_STATUS
  566. MgaFindAdapter(
  567. PVOID HwDeviceExtension,
  568. PVOID HwContext,
  569. PWSTR ArgumentString,
  570. PVIDEO_PORT_CONFIG_INFO ConfigInfo,
  571. PUCHAR Again
  572. )
  573. {
  574. PMGA_DEVICE_EXTENSION MgaDeviceExtension;
  575. VIDEO_ACCESS_RANGE AllAccessRanges[NUM_ALL_ACCESS_RANGES+1];
  576. VP_STATUS status;
  577. ULONG i, j, SetBiosVl;
  578. //ULONG PreNbBoards;
  579. VideoDebugPrint((1, "MGA.SYS!MgaFindAdapter\n"));
  580. // Make sure the size of the structure is at least as large as what we
  581. // are expecting (check version of the config info structure).
  582. if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO))
  583. {
  584. return ERROR_INVALID_PARAMETER;
  585. }
  586. pMgaDeviceExtension =
  587. MgaDeviceExtension = HwDeviceExtension;
  588. // Set some global variable saying which bus we'll be exploring.
  589. NtInterfaceType = ConfigInfo->AdapterInterfaceType;
  590. // Get access ranges for our I/O.
  591. // Check to see if there is a hardware resource conflict.
  592. // Register all we'll need for now, unless we already did it.
  593. for (i = 0; i < NUM_MGA_COMMON_ACCESS_RANGES; i++)
  594. {
  595. AllAccessRanges[i] = MgaDriverCommonAccessRange[i];
  596. }
  597. #if (!USE_VP_GET_ACCESS_RANGES)
  598. for (i = 0; i < NUM_MGA_SUPPL_ACCESS_RANGES; i++)
  599. {
  600. AllAccessRanges[i + NUM_MGA_COMMON_ACCESS_RANGES] =
  601. MgaDriverSupplAccessRange[i];
  602. }
  603. #endif
  604. status = VideoPortVerifyAccessRanges(MgaDeviceExtension,
  605. (ULONG)(NUM_MGA_COMMON_ACCESS_RANGES +
  606. NUM_MGA_SUPPL_ACCESS_RANGES),
  607. AllAccessRanges);
  608. if (status != NO_ERROR)
  609. {
  610. VideoDebugPrint((1, "MGA.SYS!MgaFindAdapter: Access Range conflict\n"));
  611. return status;
  612. }
  613. for (i=0; i < NUM_MGA_COMMON_ACCESS_RANGES; i++)
  614. {
  615. if ((MgaDeviceExtension->MappedAddress[i] =
  616. VideoPortGetDeviceBase(
  617. MgaDeviceExtension,
  618. MgaDriverCommonAccessRange[i].RangeStart,
  619. MgaDriverCommonAccessRange[i].RangeLength,
  620. MgaDriverCommonAccessRange[i].RangeInIoSpace)) == NULL)
  621. {
  622. VideoDebugPrint((1, "MGA.SYS!MgaFindAdapter failed to map port addresses\n"));
  623. return(ERROR_INVALID_PARAMETER);
  624. }
  625. }
  626. // Search for MGA boards installed in the system.
  627. // On x86, the first call to MapBoard should have found all the boards.
  628. if (NbBoard != 0)
  629. {
  630. return(ERROR_DEV_NOT_EXIST);
  631. }
  632. if (!MapBoard())
  633. {
  634. VideoDebugPrint((1, "MGA.SYS!MgaFindAdapter failed MapBoard\n"));
  635. return(ERROR_DEV_NOT_EXIST);
  636. }
  637. //PreNbBoards = (ULONG)NbBoard;
  638. ////if (!MapBoard())
  639. //if (!MapBoard() || (PreNbBoards == (ULONG)NbBoard))
  640. //{
  641. // VideoDebugPrint((1, "MGA.SYS!MgaFindAdapter failed MapBoard\n"));
  642. // return(ERROR_DEV_NOT_EXIST);
  643. //}
  644. SetBiosVl = 0;
  645. // Fill out RangeStart portion of VIDEO_ACCESS_RANGE structure
  646. // with the mapping of the MGA boards found.
  647. for (i = 0; i < (ULONG)NbBoard; i++)
  648. {
  649. MgaDriverAccessRange[i*2].RangeStart.LowPart = Hw[i].MapAddress;
  650. if (Hw[i].MapAddress == 0xAC000)
  651. {
  652. // Make sure that this is shareable.
  653. MgaDriverAccessRange[i*2].RangeShareable = 1;
  654. // We'll also need access to 4 pages for BIOS_VL.
  655. SetBiosVl = 1;
  656. }
  657. MgaDriverAccessRange[i*2+1].RangeStart.LowPart = Hw[i].ConfigSpace;
  658. if (Hw[i].ConfigSpace == 0)
  659. {
  660. // This board doesn't require access to config space.
  661. MgaDriverAccessRange[i*2+1].RangeLength = 0;
  662. MgaDriverAccessRange[i*2+1].RangeInIoSpace = 0;
  663. }
  664. // Also make sure that the pHwMode field is set to 0.
  665. Hw[i].pHwMode = NULL;
  666. }
  667. // Register all we'll need.
  668. j = NUM_MGA_SUPPL_ACCESS_RANGES + NUM_MGA_COMMON_ACCESS_RANGES;
  669. for (i = 0; i < (ULONG)NbBoard*2; i++)
  670. {
  671. if (MgaDriverAccessRange[i].RangeStart.LowPart != 0)
  672. {
  673. AllAccessRanges[j] = MgaDriverAccessRange[i];
  674. j++;
  675. }
  676. }
  677. if (SetBiosVl == 1)
  678. {
  679. // Add one more range.
  680. AllAccessRanges[j] = MgaDriverAccessRange[0];
  681. AllAccessRanges[j].RangeStart.LowPart = 0xc0000;
  682. AllAccessRanges[j].RangeShareable = 1;
  683. j++;
  684. pMgaBiosVl = (PUCHAR)setmgasel(MgaSel, 0xc0000, 4);
  685. }
  686. //status = VideoPortVerifyAccessRanges(MgaDeviceExtension,
  687. // (ULONG) (NbBoard +
  688. // NUM_MGA_SUPPL_ACCESS_RANGES +
  689. // NUM_MGA_COMMON_ACCESS_RANGES),
  690. // AllAccessRanges);
  691. //if (status != NO_ERROR)
  692. //{
  693. // VideoDebugPrint((1, "MGA.SYS!MgaFindAdapter: Access Range conflict\n"));
  694. // return status;
  695. //}
  696. VideoPortVerifyAccessRanges(MgaDeviceExtension,
  697. j,
  698. AllAccessRanges);
  699. // Special limitation:
  700. // The user-mode driver used by Microsoft doesn't allow for multiple
  701. // boards, so we'll make certain that only one board is considered here:
  702. NbBoard = 1;
  703. // Intel and Alpha both support VideoPortInt10.
  704. MgaDeviceExtension->bUsingInt10 = TRUE;
  705. // Clear out the Emulator entries and the state size since this driver
  706. // is not VGA compatible and does not support them.
  707. ConfigInfo->NumEmulatorAccessEntries = 0;
  708. ConfigInfo->EmulatorAccessEntries = NULL;
  709. ConfigInfo->EmulatorAccessEntriesContext = 0;
  710. // BUGBUG: Andrea, why do I have to do this. Faking out a VGA.
  711. if (!(MgaDeviceExtension->bUsingInt10))
  712. {
  713. ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0x00000000;
  714. ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000;
  715. ConfigInfo->VdmPhysicalVideoMemoryLength = 0x00000000;
  716. }
  717. else
  718. {
  719. // !!! This should be removed or looked into some more.
  720. // These values are set to the same values as a VGA to try and
  721. // work around some memory mapping issues in the port driver.
  722. ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0x000A0000;
  723. ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000;
  724. ConfigInfo->VdmPhysicalVideoMemoryLength = 0x00020000;
  725. }
  726. ConfigInfo->HardwareStateSize = 0;
  727. // Let's try to build a list of modes right here. We'll use the
  728. // default vidset for now, but we may change our mind later and
  729. // build a different list.
  730. iBoard = 0;
  731. mgainf = adjustDefaultVidset();
  732. // Call the service.
  733. MgaInitModeList(MgaDeviceExtension);
  734. // If an error occurred, pMgaDeviceExtension->NumberOfSuperModes will
  735. // be zero; otherwise, it will be the appropriate number of modes.
  736. // Indicate we do not wish to be called over
  737. *Again = 0;
  738. // Indicate a successful completion status.
  739. return NO_ERROR;
  740. } // end MgaFindAdapter()
  741. /****************************************************************************\
  742. * BOOLEAN
  743. * MgaInitialize(
  744. * PVOID HwDeviceExtension
  745. * )
  746. *
  747. *
  748. * DESCRIPTION:
  749. *
  750. * This routine does one time initialization of the device.
  751. *
  752. * ARGUMENTS:
  753. *
  754. * HwDeviceExtension - Supplies a pointer to the miniport's device extension.
  755. *
  756. * RETURN VALUE:
  757. *
  758. * Always returns TRUE since this routine can never fail.
  759. *
  760. \****************************************************************************/
  761. BOOLEAN
  762. MgaInitialize(
  763. PVOID HwDeviceExtension
  764. )
  765. {
  766. UNREFERENCED_PARAMETER(HwDeviceExtension);
  767. VideoDebugPrint((1, "MGA.SYS!MgaInitialize\n"));
  768. // We would like to do some work here, but we have to wait until we get
  769. // the contents of the MGA.INF file. Since MGA.INF has to be opened by
  770. // the user-mode driver, this work will be done by a special
  771. // INITIALIZE_MGA service of MgaStartIO.
  772. // Some day, we might want to write an application that will update the
  773. // registry instead of a file. We would then be able to do our work here.
  774. return (TRUE);
  775. } // end MgaInitialize()
  776. /****************************************************************************\
  777. * BOOLEAN
  778. * MgaStartIO(
  779. * PVOID HwDeviceExtension,
  780. * PVIDEO_REQUEST_PACKET RequestPacket
  781. * )
  782. *
  783. * Routine Description:
  784. *
  785. * This routine is the main execution routine for the miniport driver. It
  786. * acceptss a Video Request Packet, performs the request, and then returns
  787. * with the appropriate status.
  788. *
  789. * Arguments:
  790. *
  791. * HwDeviceExtension - Supplies a pointer to the miniport's device
  792. * extension.
  793. *
  794. * RequestPacket - Pointer to the video request packet. This structure
  795. * contains all the parameters passed to the VideoIoControl function.
  796. *
  797. * Return Value:
  798. *
  799. \****************************************************************************/
  800. BOOLEAN
  801. MgaStartIO(
  802. PVOID HwDeviceExtension,
  803. PVIDEO_REQUEST_PACKET RequestPacket
  804. )
  805. {
  806. PMGA_DEVICE_EXTENSION MgaDeviceExtension = HwDeviceExtension;
  807. PVIDEO_MODE_INFORMATION modeInformation;
  808. PVIDEO_MEMORY_INFORMATION memoryInformation;
  809. PVIDEO_CLUT pclutBuffer;
  810. PVIDEO_PUBLIC_ACCESS_RANGES publicAccessRanges;
  811. PRAMDAC_INFO pVideoPointerAttributes;
  812. HwModeData *pMgaDispMode;
  813. OffScrData *pMgaOffScreenData;
  814. MULTI_MODE *pCurMulti;
  815. PWSTR pwszChip, pwszDAC, pwszAdapterString;
  816. PUCHAR pucInBuffer, pucOutBuffer;
  817. PVOID pCurBaseAddr;
  818. VIDEO_CLUT clutBufferOne;
  819. VP_STATUS status;
  820. ULONG ZoomFactor;
  821. ULONG i, n;
  822. ULONG ulWindowLength, ulSizeOfBuffer;
  823. ULONG CurrentResNbBoards, ModeInit;
  824. ULONG cbChip, cbDAC, cbAdapterString, AdapterMemorySize;
  825. USHORT j;
  826. USHORT MaxWidth, MaxHeight, usTemp;
  827. UCHAR iCurBoard;
  828. UCHAR ucTemp;
  829. //DbgBreakPoint();
  830. VideoDebugPrint((1, "MGA.SYS!MgaStartIO\n"));
  831. pMgaDeviceExtension = MgaDeviceExtension;
  832. // Switch on the IoContolCode in the RequestPacket. It indicates which
  833. // function must be performed by the driver.
  834. switch (RequestPacket->IoControlCode)
  835. {
  836. /*------------------------------------------------------------------*\
  837. | Special service: IOCTL_VIDEO_MTX_INITIALIZE_MGA
  838. |
  839. | This will normally be the first call made to MgaStartIO. We do
  840. | here what we should have done in MgaInitialize, but couldn't.
  841. | We first determine if we'll be using the default vidset or the
  842. | contents of some MGA.INF file. If the file is an older version,
  843. | we will send back a non-zero FileInfoSize, so that the user-mode
  844. | driver can call us with MTX_GET_UPDATED_INF to get an updated
  845. | version.
  846. |
  847. \*------------------------------------------------------------------*/
  848. case IOCTL_VIDEO_MTX_INITIALIZE_MGA:
  849. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - MTX_INITIALIZE_MGA\n"));
  850. //DbgBreakPoint();
  851. #if 1
  852. status = NO_ERROR;
  853. pucInBuffer = (PUCHAR)(RequestPacket->InputBuffer);
  854. ulSizeOfBuffer = RequestPacket->InputBufferLength;
  855. ulNewInfoSize = 0;
  856. iBoard = 0;
  857. mgainf = adjustDefaultVidset();
  858. pucNewInfo = mgainf;
  859. *(PULONG)(RequestPacket->OutputBuffer) = ulNewInfoSize;
  860. RequestPacket->StatusBlock->Information = sizeof(ULONG);
  861. break;
  862. #else
  863. status = NO_ERROR;
  864. pucInBuffer = (PUCHAR)(RequestPacket->InputBuffer);
  865. ulSizeOfBuffer = RequestPacket->InputBufferLength;
  866. // We may have to update the current MGA.INF file later.
  867. // For now, assume that we won't. If the call to mtxConvertMgaInf
  868. // is required and successful, this will be changed.
  869. ulNewInfoSize = 0;
  870. iBoard = 0;
  871. // Check to see if we are to use the default vidset.
  872. if ((pucInBuffer == NULL) ||
  873. (ulSizeOfBuffer == 0))
  874. {
  875. // The user-mode driver tells us to use the default.
  876. mgainf = adjustDefaultVidset();
  877. }
  878. else
  879. {
  880. // The user-mode driver sends us the actual file contents.
  881. if ( ((header *)pucInBuffer)->Revision != (short)VERSION_NUMBER)
  882. {
  883. // The file is an older version, convert it to current format.
  884. // The returned value can be DefaultVidset, NULL, or a pointer
  885. // to a character buffer allocated by the conversion routine.
  886. if ( !(mgainf = mtxConvertMgaInf(pucInBuffer)) ||
  887. (mgainf == DefaultVidset) )
  888. {
  889. // The returned value was NULL or DefaultVidset.
  890. mgainf = adjustDefaultVidset();
  891. }
  892. }
  893. else
  894. {
  895. // The file is in the current format.
  896. // Allocate memory for the input buffer.
  897. mgainf = (PUCHAR)AllocateSystemMemory(ulSizeOfBuffer);
  898. if (mgainf == NULL)
  899. {
  900. // The memory allocation failed, use the default set.
  901. mgainf = adjustDefaultVidset();
  902. }
  903. else
  904. {
  905. // The memory allocation was successful, copy the buffer.
  906. VideoPortMoveMemory(mgainf, pucInBuffer, ulSizeOfBuffer);
  907. }
  908. }
  909. // At this point, mgainf points to DefaultVidset or to the
  910. // MGA.INF information, in the current version format.
  911. if (mgainf != DefaultVidset)
  912. {
  913. // We are not looking at the default vidset.
  914. if ((selectMgaInfoBoard() == NULL) ||
  915. (strncmp(mgainf, "Matrox MGA Setup file", 21) != 0))
  916. {
  917. // The MGA.INF file is incomplete or corrupted.
  918. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - Incomplete MGA.INF file, using default\n"));
  919. // Either memory was allocated for the input buffer, or
  920. // memory was allocated by mtxConvertMgaInf. Free it.
  921. VideoPortReleaseBuffer(pMgaDeviceExtension, mgainf);
  922. // Make sure that we won't try to update MGA.INF.
  923. ulNewInfoSize = 0;
  924. // And use the default set.
  925. mgainf = adjustDefaultVidset();
  926. }
  927. }
  928. }
  929. // At this point, mgainf points to DefaultVidset or to the
  930. // validated MGA.INF information, in the current version format.
  931. // Record the mgainf value, in case we need it later.
  932. pucNewInfo = mgainf;
  933. // Set the length of the file to be updated.
  934. *(PULONG)(RequestPacket->OutputBuffer) = ulNewInfoSize;
  935. // And don't forget to set this to the appropriate length!
  936. RequestPacket->StatusBlock->Information = sizeof(ULONG);
  937. break; // end MTX_INITIALIZE_MGA
  938. #endif // #if 0
  939. /*------------------------------------------------------------------*\
  940. | Special service: IOCTL_VIDEO_MTX_INIT_MODE_LIST
  941. |
  942. | This will normally be the second or third call made to MgaStartIO.
  943. | We call mtxCheckHwAll() and we fill in our MgaDeviceExtension
  944. | structure with mode information for each board we found. From
  945. | this, we build a series of MULTI_MODE structures describing each
  946. | 'super-mode', starting at MgaDeviceExtension->pSuperModes, and
  947. | we set the total number of supported modes in
  948. | MgaDeviceExtension->NumberOfSuperModes.
  949. |
  950. | The miniport driver builds a default list of modes (using the
  951. | default vidset) at HwFindAdapter time. The default list will
  952. | be discarded when the user-mode driver calls INIT_MODE_LIST
  953. | explicitly. When the BASEVIDEO driver calls QUERY_NUM_AVAIL_MODES
  954. | without first calling INIT_MODE_LIST, the default list will be
  955. | used.
  956. \*------------------------------------------------------------------*/
  957. case IOCTL_VIDEO_MTX_INIT_MODE_LIST:
  958. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - MTX_INIT_MODE_LIST\n"));
  959. //DbgBreakPoint();
  960. status = MgaInitModeList(MgaDeviceExtension);
  961. break; // end MTX_INIT_MODE_LIST
  962. /*------------------------------------------------------------------*\
  963. | Special service: MTX_GET_UPDATED_INF
  964. |
  965. | This service will be called if a non-zero file size was returned
  966. | by MTX_INITIALIZE_MGA. It will return the updated MGA.INF
  967. | contents to the user-mode driver.
  968. |
  969. \*------------------------------------------------------------------*/
  970. case IOCTL_VIDEO_MTX_GET_UPDATED_INF:
  971. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - MTX_GET_UPDATED_INF\n"));
  972. //DbgBreakPoint();
  973. if (ulNewInfoSize == 0)
  974. {
  975. status = NO_ERROR;
  976. break;
  977. }
  978. pucOutBuffer = (PUCHAR)(RequestPacket->OutputBuffer);
  979. ulSizeOfBuffer = RequestPacket->OutputBufferLength;
  980. if (ulSizeOfBuffer < ulNewInfoSize)
  981. {
  982. // Not enough room reserved for the file contents.
  983. status = ERROR_INSUFFICIENT_BUFFER;
  984. }
  985. else
  986. {
  987. // We should be able to copy our data.
  988. VideoPortMoveMemory(pucOutBuffer, pucNewInfo, ulNewInfoSize);
  989. // And don't forget to set this to the appropriate length!
  990. RequestPacket->StatusBlock->Information = ulNewInfoSize;
  991. status = NO_ERROR;
  992. }
  993. break; // end MTX_GET_UPDATED_INF
  994. /*------------------------------------------------------------------*\
  995. | Required service: IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
  996. |
  997. | The MGA user-mode drivers will call this very early in their
  998. | initialization sequence, probably right after MTX_INITIALIZE_MGA.
  999. | This will return the number of video modes supported by the
  1000. | adapter by filling out a VIDEO_NUM_MODES structure.
  1001. |
  1002. \*------------------------------------------------------------------*/
  1003. case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
  1004. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - QUERY_NUM_AVAIL_MODES\n"));
  1005. //DbgBreakPoint();
  1006. // Find out the size of the data to be put in the the buffer and
  1007. // return that in the status information (whether or not the
  1008. // information is there).
  1009. // If the buffer passed in is not large enough return an appropriate
  1010. // error code.
  1011. if (RequestPacket->OutputBufferLength <
  1012. (RequestPacket->StatusBlock->Information =
  1013. sizeof(VIDEO_NUM_MODES)))
  1014. {
  1015. status = ERROR_INSUFFICIENT_BUFFER;
  1016. }
  1017. else
  1018. {
  1019. if (MgaDeviceExtension->NumberOfSuperModes == 0)
  1020. {
  1021. // No modes are listed so far, try to make up the list.
  1022. iBoard = 0;
  1023. if (mgainf == NULL)
  1024. {
  1025. // No vidset yet, use the default one.
  1026. mgainf = adjustDefaultVidset();
  1027. }
  1028. // Call the service.
  1029. MgaInitModeList(MgaDeviceExtension);
  1030. // If an error occurred, NumberOfSuperModes will be zero;
  1031. // otherwise, it will be the appropriate number of modes.
  1032. }
  1033. ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->NumModes =
  1034. MgaDeviceExtension->NumberOfSuperModes;
  1035. ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->
  1036. ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
  1037. status = NO_ERROR;
  1038. }
  1039. break; // end QUERY_NUM_AVAIL_MODES
  1040. /*------------------------------------------------------------------*\
  1041. | Required service: IOCTL_VIDEO_QUERY_AVAIL_MODES
  1042. |
  1043. | The MGA user-mode drivers will call this very early in their
  1044. | initialization sequence, just after QUERY_NUM_AVAIL_MODES.
  1045. | This will return return information about each video mode
  1046. | supported by the adapter (including modes that require more than
  1047. | one board if more than one are present) by filling out an array
  1048. | of VIDEO_MODE_INFORMATION structures.
  1049. |
  1050. \*------------------------------------------------------------------*/
  1051. case IOCTL_VIDEO_QUERY_AVAIL_MODES:
  1052. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - QUERY_AVAIL_MODES\n"));
  1053. //DbgBreakPoint();
  1054. if (RequestPacket->OutputBufferLength <
  1055. (RequestPacket->StatusBlock->Information =
  1056. MgaDeviceExtension->NumberOfSuperModes *
  1057. sizeof(VIDEO_MODE_INFORMATION)) )
  1058. {
  1059. status = ERROR_INSUFFICIENT_BUFFER;
  1060. }
  1061. else
  1062. {
  1063. modeInformation = RequestPacket->OutputBuffer;
  1064. // Fill in a VIDEO_MODE_INFORMATION struc for each available mode.
  1065. pCurMulti = MgaDeviceExtension->pSuperModes;
  1066. if (pCurMulti == NULL)
  1067. {
  1068. status = ERROR_DEV_NOT_EXIST;
  1069. break;
  1070. }
  1071. for (i = 0; i < MgaDeviceExtension->NumberOfSuperModes; i++)
  1072. {
  1073. // Fill in common values that apply to all modes
  1074. modeInformation[i] = CommonVideoModeInformation;
  1075. // Fill in mode specific informations
  1076. modeInformation[i].ModeIndex = pCurMulti->MulModeNumber;
  1077. modeInformation[i].VisScreenWidth = pCurMulti->MulWidth;
  1078. modeInformation[i].VisScreenHeight= pCurMulti->MulHeight;
  1079. modeInformation[i].ScreenStride =
  1080. pCurMulti->MulWidth * pCurMulti->MulPixWidth / 8;
  1081. modeInformation[i].BitsPerPlane = pCurMulti->MulPixWidth;
  1082. modeInformation[i].Frequency = pCurMulti->MulRefreshRate;
  1083. // XMillimeter and YMillimeter will be modified by the user-
  1084. // mode driver.
  1085. // If we're in TrueColor mode, then set RGB masks
  1086. if ((modeInformation[i].BitsPerPlane == 32) ||
  1087. (modeInformation[i].BitsPerPlane == 24))
  1088. {
  1089. // This makes 32 bpp look like 24 to the display driver
  1090. modeInformation[i].BitsPerPlane = 24;
  1091. modeInformation[i].RedMask = 0x00FF0000;
  1092. modeInformation[i].GreenMask = 0x0000FF00;
  1093. modeInformation[i].BlueMask = 0x000000FF;
  1094. modeInformation[i].AttributeFlags =
  1095. VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS;
  1096. }
  1097. else if (modeInformation[i].BitsPerPlane == 16)
  1098. {
  1099. modeInformation[i].AttributeFlags =
  1100. VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS;
  1101. if (pCurMulti->MulHwModes[0]->DispType & DISPTYPE_M565)
  1102. {
  1103. modeInformation[i].RedMask = 0x0000F800;
  1104. modeInformation[i].GreenMask = 0x000007E0;
  1105. modeInformation[i].BlueMask = 0x0000001F;
  1106. }
  1107. else
  1108. {
  1109. modeInformation[i].RedMask = 0x00007C00;
  1110. modeInformation[i].GreenMask = 0x000003E0;
  1111. modeInformation[i].BlueMask = 0x0000001F;
  1112. modeInformation[i].AttributeFlags |= VIDEO_MODE_555;
  1113. modeInformation[i].BitsPerPlane = 15;
  1114. }
  1115. }
  1116. else
  1117. {
  1118. modeInformation[i].AttributeFlags =
  1119. VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS |
  1120. VIDEO_MODE_PALETTE_DRIVEN |
  1121. VIDEO_MODE_MANAGED_PALETTE;
  1122. }
  1123. if (pCurMulti->MulHwModes[0]->ZBuffer)
  1124. {
  1125. // This is a 3D mode.
  1126. modeInformation[i].AttributeFlags |= VIDEO_MODE_3D;
  1127. }
  1128. // Number of boards involved in the current super-mode.
  1129. CurrentResNbBoards = pCurMulti->MulArrayWidth *
  1130. pCurMulti->MulArrayHeight;
  1131. // For each of them...
  1132. for (n = 0; n < CurrentResNbBoards; n++)
  1133. {
  1134. // Point to the mode information structure.
  1135. pMgaDispMode = pCurMulti->MulHwModes[n];
  1136. // For now, don't disclose whether we're interlaced.
  1137. //if (pMgaDispMode->DispType & TYPE_INTERLACED)
  1138. //{
  1139. // modeInformation[i].AttributeFlags |=
  1140. // VIDEO_MODE_INTERLACED;
  1141. //}
  1142. // Figure out the width and height of the video memory bitmap
  1143. MaxWidth = pMgaDispMode->DispWidth;
  1144. MaxHeight = pMgaDispMode->DispHeight;
  1145. pMgaOffScreenData = pMgaDispMode->pOffScr;
  1146. for (j = 0; j < pMgaDispMode->NumOffScr; j++)
  1147. {
  1148. if ((usTemp=(pMgaOffScreenData[j].XStart +
  1149. pMgaOffScreenData[j].Width)) > MaxWidth)
  1150. MaxWidth=usTemp;
  1151. if ((usTemp=(pMgaOffScreenData[j].YStart +
  1152. pMgaOffScreenData[j].Height)) > MaxHeight)
  1153. MaxHeight=usTemp;
  1154. }
  1155. modeInformation[i].VideoMemoryBitmapWidth = MaxWidth;
  1156. modeInformation[i].VideoMemoryBitmapHeight= MaxHeight;
  1157. }
  1158. pCurMulti++;
  1159. }
  1160. status = NO_ERROR;
  1161. }
  1162. break; // end QUERY_AVAIL_MODES
  1163. /*------------------------------------------------------------------*\
  1164. | Required service: IOCTL_VIDEO_SET_CURRENT_MODE
  1165. |
  1166. | The MGA user-mode drivers will probably call this service right
  1167. | after QUERY_AVAIL_MODES. This will set the adapter to the mode
  1168. | specified by VIDEO_MODE. If more than one board are involved
  1169. | in the mode, each one will be set to the appropriate mode. We
  1170. | want to take care not to re-program the mode already current.
  1171. |
  1172. \*------------------------------------------------------------------*/
  1173. case IOCTL_VIDEO_SET_CURRENT_MODE:
  1174. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - SET_CURRENT_MODE\n"));
  1175. //DbgBreakPoint();
  1176. ModeInit = *(ULONG *)(RequestPacket->InputBuffer);
  1177. if (MgaDeviceExtension->SuperModeNumber == ModeInit)
  1178. {
  1179. // The requested mode is already the current mode
  1180. status = NO_ERROR;
  1181. break;
  1182. }
  1183. // Save the current board, because this service will modify it.
  1184. iCurBoard = iBoard;
  1185. pCurBaseAddr = pMgaBaseAddr;
  1186. // Check to see if we have a valid ModeNumber.
  1187. if (ModeInit >= MgaDeviceExtension->NumberOfSuperModes)
  1188. {
  1189. // If the mode number is invalid, choose the first one.
  1190. ModeInit = 0;
  1191. }
  1192. MgaDeviceExtension->SuperModeNumber = ModeInit;
  1193. // Point to the appropriate MULTI_MODE structure.
  1194. pCurMulti = &MgaDeviceExtension->pSuperModes[ModeInit];
  1195. if (pCurMulti == NULL)
  1196. {
  1197. status = ERROR_DEV_NOT_EXIST;
  1198. break;
  1199. }
  1200. #if DBG
  1201. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - Requested mode: %u\n", ModeInit));
  1202. VideoDebugPrint((1, "ModeNumber Width Height PW X Y n mo pHwMode\n"));
  1203. VideoDebugPrint((1, "0x%08x % 6d % 6d % 3d % 3d % 3d\n",
  1204. pCurMulti->MulModeNumber,
  1205. pCurMulti->MulWidth,
  1206. pCurMulti->MulHeight,
  1207. pCurMulti->MulPixWidth,
  1208. pCurMulti->MulArrayWidth,
  1209. pCurMulti->MulArrayHeight));
  1210. j = pCurMulti->MulArrayWidth * pCurMulti->MulArrayHeight;
  1211. for (n = 0; n < j; n++)
  1212. {
  1213. VideoDebugPrint((1, " %d %02x 0x%08x\n",
  1214. pCurMulti->MulBoardNb[n],
  1215. pCurMulti->MulBoardMode[n],
  1216. pCurMulti->MulHwModes[n]));
  1217. }
  1218. //DbgBreakPoint();
  1219. #endif
  1220. // Use info for the first board to set a few Registry values.
  1221. iBoard = pCurMulti->MulBoardNb[0];
  1222. switch((Hw[iBoard].ProductRev >> 4) & 0x0000000f)
  1223. {
  1224. case TITAN_CHIP: pwszChip = L"MGA (A2681700)";
  1225. cbChip = sizeof(L"MGA (A2681700)");
  1226. break;
  1227. case ATLAS_CHIP: pwszChip = L"MGA (A2681701)";
  1228. cbChip = sizeof(L"MGA (A2681701)");
  1229. break;
  1230. case ATHENA_CHIP: pwszChip = L"MGA (A2681702)";
  1231. cbChip = sizeof(L"MGA (A2681702)");
  1232. break;
  1233. default: pwszChip = L"MGA (Unspecified)";
  1234. cbChip = sizeof(L"MGA (Unspecified)");
  1235. break;
  1236. }
  1237. switch(Hw[iBoard].DacType)
  1238. {
  1239. case BT482: pwszDAC = L"Brooktree Bt482";
  1240. cbDAC = sizeof(L"Brooktree Bt482");
  1241. break;
  1242. case BT485: pwszDAC = L"Brooktree Bt485";
  1243. cbDAC = sizeof(L"Brooktree Bt485");
  1244. break;
  1245. case PX2085: pwszDAC = L"Cirrus Logic PX2085";
  1246. cbDAC = sizeof(L"Cirrus Logic PX2085");
  1247. break;
  1248. case VIEWPOINT: pwszDAC = L"TI TVP3020";
  1249. cbDAC = sizeof(L"TI TVP3020");
  1250. break;
  1251. case TVP3026: pwszDAC = L"TI TVP3026";
  1252. cbDAC = sizeof(L"TI TVP3026");
  1253. break;
  1254. default: pwszDAC = L"Unknown";
  1255. cbDAC = sizeof(L"Unknown");
  1256. break;
  1257. }
  1258. AdapterMemorySize = Hw[iBoard].VramAvail + Hw[iBoard].DramAvail;
  1259. if ((Hw[iBoard].ProductType & 0x0f) == BOARD_MGA_RESERVED)
  1260. {
  1261. MgaDeviceExtension->BoardId = TYPE_QVISION_PCI;
  1262. // This is a Compaq board.
  1263. if (Hw[iBoard].DacType == PX2085)
  1264. {
  1265. pwszAdapterString = L"QVision 2000";
  1266. cbAdapterString = sizeof(L"QVision 2000");
  1267. }
  1268. else if (Hw[iBoard].DacType == TVP3026)
  1269. {
  1270. pwszAdapterString = L"QVision 2000+";
  1271. cbAdapterString = sizeof(L"QVision 2000+");
  1272. }
  1273. else
  1274. {
  1275. MgaDeviceExtension->BoardId = TYPE_QVISION_ISA;
  1276. pwszAdapterString = L"Compaq Unknown";
  1277. cbAdapterString = sizeof(L"Compaq Unknown");
  1278. }
  1279. }
  1280. else
  1281. {
  1282. MgaDeviceExtension->BoardId = TYPE_MATROX;
  1283. switch(Hw[iBoard].ProductType >> 16)
  1284. {
  1285. case MGA_ULTIMA: pwszAdapterString = L"Ultima";
  1286. cbAdapterString = sizeof(L"Ultima");
  1287. break;
  1288. case MGA_ULTIMA_VAFC:
  1289. pwszAdapterString = L"Ultima VAFC";
  1290. cbAdapterString = sizeof(L"Ultima VAFC");
  1291. break;
  1292. case MGA_ULTIMA_PLUS:
  1293. pwszAdapterString = L"Ultima Plus";
  1294. cbAdapterString = sizeof(L"Ultima Plus");
  1295. break;
  1296. case MGA_ULTIMA_PLUS_200:
  1297. pwszAdapterString = L"Ultima Plus 200";
  1298. cbAdapterString = sizeof(L"Ultima Plus 200");
  1299. break;
  1300. case MGA_IMPRESSION_PLUS:
  1301. pwszAdapterString = L"Impression Plus";
  1302. cbAdapterString = sizeof(L"Impression Plus");
  1303. break;
  1304. case MGA_IMPRESSION_PLUS_200:
  1305. pwszAdapterString = L"Impression Plus 200";
  1306. cbAdapterString = sizeof(L"Impression Plus 200");
  1307. break;
  1308. case MGA_IMPRESSION:
  1309. pwszAdapterString = L"Impression";
  1310. cbAdapterString = sizeof(L"Impression");
  1311. break;
  1312. case MGA_IMPRESSION_PRO:
  1313. pwszAdapterString = L"Impression PRO";
  1314. cbAdapterString = sizeof(L"Impression PRO");
  1315. break;
  1316. case MGA_IMPRESSION_LTE:
  1317. pwszAdapterString = L"Impression Lite";
  1318. cbAdapterString = sizeof(L"Impression Lite");
  1319. break;
  1320. default: pwszAdapterString = L"Unknown";
  1321. cbAdapterString = sizeof(L"Unknown");
  1322. break;
  1323. }
  1324. }
  1325. VideoPortSetRegistryParameters(MgaDeviceExtension,
  1326. L"HardwareInformation.ChipType",
  1327. pwszChip,
  1328. cbChip);
  1329. VideoPortSetRegistryParameters(MgaDeviceExtension,
  1330. L"HardwareInformation.DacType",
  1331. pwszDAC,
  1332. cbDAC);
  1333. VideoPortSetRegistryParameters(MgaDeviceExtension,
  1334. L"HardwareInformation.MemorySize",
  1335. &AdapterMemorySize,
  1336. sizeof(ULONG));
  1337. VideoPortSetRegistryParameters(MgaDeviceExtension,
  1338. L"HardwareInformation.AdapterString",
  1339. pwszAdapterString,
  1340. cbAdapterString);
  1341. // Number of boards involved in the current super-mode.
  1342. CurrentResNbBoards = pCurMulti->MulArrayWidth *
  1343. pCurMulti->MulArrayHeight;
  1344. // For each of them...
  1345. for (n = 0; n < CurrentResNbBoards; n++)
  1346. {
  1347. // Point to the mode information structure.
  1348. pMgaDispMode = pCurMulti->MulHwModes[n];
  1349. // Make the board current.
  1350. iBoard = pCurMulti->MulBoardNb[n];
  1351. pMgaBaseAddr = MgaDeviceExtension->KernelModeMappedBaseAddress[iBoard];
  1352. // If the board is mapped at 0x000AC000, we must set the
  1353. // MAP SEL 1 bit of the VGA MISC register to have the TITAN
  1354. // mapped.
  1355. if (Hw[iBoard].MapAddress == 0x000AC000)
  1356. {
  1357. // Select VGA MISC register (Index 6)
  1358. VideoPortWritePortUchar(TITAN_GCTL_ADDR_PORT, (UCHAR) 6);
  1359. ucTemp = VideoPortReadPortUchar(TITAN_GCTL_DATA_PORT) | 0x08;
  1360. VideoPortWritePortUchar(TITAN_GCTL_DATA_PORT, ucTemp);
  1361. }
  1362. // Reset all Titan host registers
  1363. VideoPortWriteRegisterUlong((PULONG)((PUCHAR)pMgaBaseAddr +
  1364. TITAN_OFFSET + TITAN_RST), 1);
  1365. VideoPortStallExecution(2000);
  1366. VideoPortWriteRegisterUlong((PULONG)((PUCHAR)pMgaBaseAddr +
  1367. TITAN_OFFSET + TITAN_RST), 0);
  1368. // Set the graphics mode from the available hardware modes.
  1369. mtxSelectHwMode(pMgaDispMode);
  1370. // Select the display mode.
  1371. // Pass the frequency in the last byte of the ZOOM factor
  1372. ZoomFactor = (pCurMulti->MulRefreshRate << 24) | ZOOM_X1;
  1373. mtxSetDisplayMode(pMgaDispMode, ZoomFactor);
  1374. // Set the cursor colors to white and black.
  1375. MgaSetCursorColour(MgaDeviceExtension, 0xFFFFFF, 0x000000);
  1376. // Set the MCtlWtSt register.
  1377. VideoPortWriteRegisterUlong((PULONG)((PUCHAR)pMgaBaseAddr +
  1378. TITAN_OFFSET + TITAN_MCTLWTST), (ULONG)MCTLWTST_STD);
  1379. }
  1380. // Restore the current board to what it used to be.
  1381. iBoard = iCurBoard;
  1382. pMgaBaseAddr = pCurBaseAddr;
  1383. // At this point, the RAMDAC should be okay, but it looks
  1384. // like it's not quite ready to accept data, particularly
  1385. // on VL boards. Adding a delay seems to fix things.
  1386. VideoPortStallExecution(100); // Microseconds
  1387. status = NO_ERROR;
  1388. break; // end SET_CURRENT_MODE
  1389. /*------------------------------------------------------------------*\
  1390. | Special service: IOCTL_VIDEO_MTX_QUERY_BOARD_ARRAY
  1391. |
  1392. | The MGA user-mode drivers will probably call this service after
  1393. | the mode has been set by SET_CURRENT_MODE. The user-mode drivers
  1394. | have to know how the boards are arrayed to make up the display
  1395. | surface, so that they know which board to address when writing
  1396. | to a specific (x, y) position. The miniport driver knows this,
  1397. | since it has just set the mode.
  1398. |
  1399. \*------------------------------------------------------------------*/
  1400. case IOCTL_VIDEO_MTX_QUERY_BOARD_ARRAY:
  1401. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - MTX_QUERY_BOARD_ARRAY\n"));
  1402. //DbgBreakPoint();
  1403. // If the buffer passed in is not large enough return an appropriate
  1404. // error code.
  1405. if (RequestPacket->OutputBufferLength <
  1406. (RequestPacket->StatusBlock->Information = sizeof(SIZEL)))
  1407. {
  1408. status = ERROR_INSUFFICIENT_BUFFER;
  1409. }
  1410. else
  1411. {
  1412. if(MgaDeviceExtension->SuperModeNumber == 0xFFFFFFFF)
  1413. {
  1414. // No mode has been selected yet, so we don't know...
  1415. status = ERROR_DEV_NOT_EXIST;
  1416. }
  1417. else
  1418. {
  1419. ModeInit = MgaDeviceExtension->SuperModeNumber;
  1420. // Point to the appropriate MULTI_MODE structure.
  1421. pCurMulti = &MgaDeviceExtension->pSuperModes[ModeInit];
  1422. if (pCurMulti == NULL)
  1423. {
  1424. status = ERROR_DEV_NOT_EXIST;
  1425. break;
  1426. }
  1427. ((SIZEL*)RequestPacket->OutputBuffer)->cx =
  1428. pCurMulti->MulArrayWidth;
  1429. ((SIZEL*)RequestPacket->OutputBuffer)->cy =
  1430. pCurMulti->MulArrayHeight;
  1431. status = NO_ERROR;
  1432. }
  1433. }
  1434. break; // end MTX_QUERY_BOARD_ARRAY
  1435. /*------------------------------------------------------------------*\
  1436. | Special service: IOCTL_VIDEO_MTX_MAKE_BOARD_CURRENT
  1437. |
  1438. | The MGA user-mode drivers will call this service whenever a
  1439. | miniport operation need be executed on a particular board, as
  1440. | opposed to every single board involved in the current mode.
  1441. |
  1442. \*------------------------------------------------------------------*/
  1443. case IOCTL_VIDEO_MTX_MAKE_BOARD_CURRENT:
  1444. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - MTX_MAKE_BOARD_CURRENT\n"));
  1445. //DbgBreakPoint();
  1446. n = *(ULONG *)(RequestPacket->InputBuffer);
  1447. // Check to see if we have a valid board number.
  1448. i = MgaDeviceExtension->SuperModeNumber;
  1449. if (i == 0xFFFFFFFF)
  1450. {
  1451. status = ERROR_DEV_NOT_EXIST;
  1452. break;
  1453. }
  1454. pCurMulti = &MgaDeviceExtension->pSuperModes[i];
  1455. if (pCurMulti == NULL)
  1456. {
  1457. status = ERROR_DEV_NOT_EXIST;
  1458. break;
  1459. }
  1460. if (n >= (ULONG)(pCurMulti->MulArrayWidth * pCurMulti->MulArrayHeight))
  1461. {
  1462. status = ERROR_DEV_NOT_EXIST;
  1463. }
  1464. else
  1465. {
  1466. // Make the board current.
  1467. CONVERT_BOARD_NUMBER(n);
  1468. iBoard = pCurMulti->MulBoardNb[n];
  1469. pMgaBaseAddr = MgaDeviceExtension->KernelModeMappedBaseAddress[iBoard];
  1470. status = NO_ERROR;
  1471. }
  1472. break; // end MTX_MAKE_BOARD_CURRENT
  1473. /*------------------------------------------------------------------*\
  1474. | Special service: IOCTL_VIDEO_MTX_QUERY_BOARD_ID
  1475. |
  1476. | This service returns the board type information to the user-mode
  1477. | driver. A call to MTX_MAKE_BOARD_CURRENT must have been made
  1478. | previously to set which board is to be queried.
  1479. |
  1480. \*------------------------------------------------------------------*/
  1481. case IOCTL_VIDEO_MTX_QUERY_BOARD_ID:
  1482. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - MTX_QUERY_BOARD_ID\n"));
  1483. //DbgBreakPoint();
  1484. if (RequestPacket->OutputBufferLength < sizeof(ULONG))
  1485. {
  1486. // Not enough room reserved for the board ID.
  1487. status = ERROR_INSUFFICIENT_BUFFER;
  1488. }
  1489. else
  1490. {
  1491. *((PULONG)(RequestPacket->OutputBuffer)) = ProductMGA[iBoard];
  1492. // And don't forget to set this to the appropriate length!
  1493. RequestPacket->StatusBlock->Information = sizeof(ULONG);
  1494. status = NO_ERROR;
  1495. }
  1496. break; // end MTX_QUERY_BOARD_ID
  1497. /*------------------------------------------------------------------*\
  1498. | Special service: IOCTL_VIDEO_MTX_QUERY_HW_DATA
  1499. |
  1500. | This service returns hardware information about the current
  1501. | board by filling out a HW_DATA structure. A call to
  1502. | MTX_MAKE_BOARD_CURRENT must have been made previously to set
  1503. | which board is to be queried.
  1504. |
  1505. \*------------------------------------------------------------------*/
  1506. case IOCTL_VIDEO_MTX_QUERY_HW_DATA:
  1507. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - MTX_QUERY_HW_DATA\n"));
  1508. //DbgBreakPoint();
  1509. // Check if we have a sufficient output buffer
  1510. if (RequestPacket->OutputBufferLength <
  1511. (RequestPacket->StatusBlock->Information = sizeof(HW_DATA)))
  1512. {
  1513. status = ERROR_INSUFFICIENT_BUFFER;
  1514. }
  1515. else
  1516. {
  1517. register PHW_DATA pUserModeHwData;
  1518. register HwData *pMiniportHwData;
  1519. pUserModeHwData = RequestPacket->OutputBuffer;
  1520. pMiniportHwData = &Hw[iBoard];
  1521. pUserModeHwData->MapAddress = pMiniportHwData->MapAddress;
  1522. pUserModeHwData->ProductType = pMiniportHwData->ProductType;
  1523. pUserModeHwData->ProductRev = pMiniportHwData->ProductRev;
  1524. pUserModeHwData->ShellRev = pMiniportHwData->ShellRev;
  1525. pUserModeHwData->BindingRev = pMiniportHwData->BindingRev;
  1526. pUserModeHwData->VGAEnable = pMiniportHwData->VGAEnable;
  1527. pUserModeHwData->Sync = pMiniportHwData->Sync;
  1528. pUserModeHwData->Device8_16 = pMiniportHwData->Device8_16;
  1529. pUserModeHwData->PortCfg = pMiniportHwData->PortCfg;
  1530. pUserModeHwData->PortIRQ = pMiniportHwData->PortIRQ;
  1531. pUserModeHwData->MouseMap = pMiniportHwData->MouseMap;
  1532. pUserModeHwData->MouseIRate = pMiniportHwData->MouseIRate;
  1533. pUserModeHwData->DacType = pMiniportHwData->DacType;
  1534. pUserModeHwData->cursorInfo.MaxWidth =
  1535. pMiniportHwData->cursorInfo.MaxWidth;
  1536. pUserModeHwData->cursorInfo.MaxHeight =
  1537. pMiniportHwData->cursorInfo.MaxHeight;
  1538. pUserModeHwData->cursorInfo.MaxDepth =
  1539. pMiniportHwData->cursorInfo.MaxDepth;
  1540. pUserModeHwData->cursorInfo.MaxColors =
  1541. pMiniportHwData->cursorInfo.MaxColors;
  1542. pUserModeHwData->cursorInfo.CurWidth =
  1543. pMiniportHwData->cursorInfo.CurWidth;
  1544. pUserModeHwData->cursorInfo.CurHeight =
  1545. pMiniportHwData->cursorInfo.CurHeight;
  1546. pUserModeHwData->cursorInfo.cHotSX =
  1547. pMiniportHwData->cursorInfo.cHotSX;
  1548. pUserModeHwData->cursorInfo.cHotSY =
  1549. pMiniportHwData->cursorInfo.cHotSY;
  1550. pUserModeHwData->cursorInfo.HotSX =
  1551. pMiniportHwData->cursorInfo.HotSX;
  1552. pUserModeHwData->cursorInfo.HotSY =
  1553. pMiniportHwData->cursorInfo.HotSY;
  1554. pUserModeHwData->VramAvail = pMiniportHwData->VramAvail;
  1555. pUserModeHwData->DramAvail = pMiniportHwData->DramAvail;
  1556. pUserModeHwData->CurrentOverScanX = pMiniportHwData->CurrentOverScanX;
  1557. pUserModeHwData->CurrentOverScanY = pMiniportHwData->CurrentOverScanY;
  1558. pUserModeHwData->YDstOrg = pMiniportHwData->YDstOrg;
  1559. status = NO_ERROR;
  1560. }
  1561. break; // end MTX_QUERY_HW_DATA
  1562. /*------------------------------------------------------------------*\
  1563. | Special service: IOCTL_VIDEO_MTX_QUERY_NUM_OFFSCREEN_BLOCKS
  1564. |
  1565. | This service returns the number of offscreen memory areas
  1566. | available for the requested super-mode. A call to
  1567. | MTX_MAKE_BOARD_CURRENT must have been made previously to set
  1568. | which board is to be queried.
  1569. |
  1570. | Input: A pointer to a VIDEO_MODE_INFORMATION structure, as
  1571. | returned by a QUERY_AVAIL_MODES request.
  1572. |
  1573. | Output: A pointer to a VIDEO_NUM_OFFSCREEN_BLOCKS structure, as
  1574. | defined below.
  1575. |
  1576. | The calling routine will have allocated the memory for the
  1577. | VIDEO_NUM_OFFSCREEN_BLOCKS structure.
  1578. |
  1579. \*------------------------------------------------------------------*/
  1580. case IOCTL_VIDEO_MTX_QUERY_NUM_OFFSCREEN_BLOCKS:
  1581. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - MTX_QUERY_NUM_OFFSCREEN_BLOCKS\n"));
  1582. //DbgBreakPoint();
  1583. // Verify that input & output buffers are the correct sizes
  1584. if ( (RequestPacket->OutputBufferLength <
  1585. (RequestPacket->StatusBlock->Information =
  1586. sizeof(VIDEO_NUM_OFFSCREEN_BLOCKS))) ||
  1587. (RequestPacket->InputBufferLength <
  1588. sizeof(VIDEO_MODE_INFORMATION)) )
  1589. {
  1590. status = ERROR_INSUFFICIENT_BUFFER;
  1591. }
  1592. else
  1593. {
  1594. PVIDEO_NUM_OFFSCREEN_BLOCKS pVideoNumOffscreenBlocks =
  1595. RequestPacket->OutputBuffer;
  1596. // Get the super-mode number the user-mode driver is asking about.
  1597. modeInformation = RequestPacket->InputBuffer;
  1598. ModeInit = modeInformation->ModeIndex;
  1599. // Point to the appropriate MULTI_MODE structure.
  1600. pCurMulti = &MgaDeviceExtension->pSuperModes[ModeInit];
  1601. if (pCurMulti == NULL)
  1602. {
  1603. status = ERROR_DEV_NOT_EXIST;
  1604. break;
  1605. }
  1606. // Look for the current board.
  1607. i = 0;
  1608. while ((i < NB_BOARD_MAX) && (pCurMulti->MulBoardNb[i] != iBoard))
  1609. i++;
  1610. // Point to the appropriate hw mode.
  1611. pMgaDispMode = pCurMulti->MulHwModes[i];
  1612. // Fill out NumBlocks.
  1613. pVideoNumOffscreenBlocks->NumBlocks = pMgaDispMode->NumOffScr;
  1614. // Fill out OffScreenBlockLength.
  1615. pVideoNumOffscreenBlocks->OffscreenBlockLength =
  1616. sizeof(OFFSCREEN_BLOCK);
  1617. status = NO_ERROR;
  1618. }
  1619. break; // end MTX_QUERY_NUM_OFFSCREEN_BLOCKS
  1620. /*------------------------------------------------------------------*\
  1621. | Special service: IOCTL_VIDEO_MTX_QUERY_OFFSCREEN_BLOCKS
  1622. |
  1623. | This service returns a description of each offscreen memory area
  1624. | available for the requested super-mode. A call to
  1625. | MTX_MAKE_BOARD_CURRENT must have been made previously to set
  1626. | which board is to be queried.
  1627. |
  1628. | Input: A pointer to a VIDEO_MODE_INFORMATION structure, as
  1629. | returned by a QUERY_AVAIL_MODES request.
  1630. |
  1631. | Output: A pointer to the first of a series of OFFSCREEN_BLOCK
  1632. | structures, as defined below.
  1633. |
  1634. | The calling routine will have allocated the memory for the
  1635. | OFFSCREEN_BLOCK structures.
  1636. |
  1637. \*------------------------------------------------------------------*/
  1638. case IOCTL_VIDEO_MTX_QUERY_OFFSCREEN_BLOCKS:
  1639. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - MTX_QUERY_OFFSCREEN_BLOCKS\n"));
  1640. //DbgBreakPoint();
  1641. // Verify that the input buffer is the correct size.
  1642. if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE_INFORMATION))
  1643. {
  1644. status = ERROR_INSUFFICIENT_BUFFER;
  1645. }
  1646. else
  1647. {
  1648. UCHAR NumOffScrBlocks;
  1649. OffScrData *pOffScrDataArray;
  1650. POFFSCREEN_BLOCK pOffscreenBlockArray =
  1651. RequestPacket->OutputBuffer;
  1652. // Get the super-mode number the user-mode driver is asking about.
  1653. modeInformation = RequestPacket->InputBuffer;
  1654. ModeInit = modeInformation->ModeIndex;
  1655. // Point to the appropriate MULTI_MODE structure.
  1656. pCurMulti = &MgaDeviceExtension->pSuperModes[ModeInit];
  1657. if (pCurMulti == NULL)
  1658. {
  1659. status = ERROR_DEV_NOT_EXIST;
  1660. break;
  1661. }
  1662. // Look for the current board.
  1663. i = 0;
  1664. while ((i < NB_BOARD_MAX) && (pCurMulti->MulBoardNb[i] != iBoard))
  1665. i++;
  1666. // Point to the appropriate hw mode.
  1667. pMgaDispMode = pCurMulti->MulHwModes[i];
  1668. NumOffScrBlocks = pMgaDispMode->NumOffScr;
  1669. // Verify that the output buffer is the correct size.
  1670. if (RequestPacket->OutputBufferLength <
  1671. (RequestPacket->StatusBlock->Information =
  1672. NumOffScrBlocks * sizeof(OFFSCREEN_BLOCK)))
  1673. {
  1674. status = ERROR_INSUFFICIENT_BUFFER;
  1675. }
  1676. else
  1677. {
  1678. // Fill the OFFSCREEN_BLOCK structures
  1679. pOffScrDataArray = pMgaDispMode->pOffScr;
  1680. for (i = 0; i < NumOffScrBlocks; i++)
  1681. {
  1682. pOffscreenBlockArray[i].Type =pOffScrDataArray[i].Type;
  1683. pOffscreenBlockArray[i].XStart=pOffScrDataArray[i].XStart;
  1684. pOffscreenBlockArray[i].YStart=pOffScrDataArray[i].YStart;
  1685. pOffscreenBlockArray[i].Width =pOffScrDataArray[i].Width;
  1686. pOffscreenBlockArray[i].Height=pOffScrDataArray[i].Height;
  1687. pOffscreenBlockArray[i].SafePlanes =
  1688. pOffScrDataArray[i].SafePlanes;
  1689. pOffscreenBlockArray[i].ZOffset =
  1690. pOffScrDataArray[i].ZXStart;
  1691. }
  1692. status = NO_ERROR;
  1693. }
  1694. }
  1695. break; // end MTX_QUERY_OFFSCREEN_BLOCKS
  1696. /*------------------------------------------------------------------*\
  1697. | Special service: IOCTL_VIDEO_MTX_QUERY_RAMDAC_INFO
  1698. |
  1699. | This service returns information about the type and capabilities
  1700. | of the installed ramdac by filling out a RAMDAC_INFO structure.
  1701. | A call to MTX_MAKE_BOARD_CURRENT must have been made previously
  1702. | to set which board is to be queried.
  1703. |
  1704. \*------------------------------------------------------------------*/
  1705. case IOCTL_VIDEO_MTX_QUERY_RAMDAC_INFO:
  1706. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - MTX_QUERY_RAMDAC_INFO\n"));
  1707. //DbgBreakPoint();
  1708. // Check if we have a sufficient output buffer
  1709. if (RequestPacket->OutputBufferLength <
  1710. (RequestPacket->StatusBlock->Information =
  1711. sizeof(RAMDAC_INFO)))
  1712. {
  1713. status = ERROR_INSUFFICIENT_BUFFER;
  1714. }
  1715. else
  1716. {
  1717. pVideoPointerAttributes=RequestPacket->OutputBuffer;
  1718. pVideoPointerAttributes->Flags = RAMDAC_NONE;
  1719. pVideoPointerAttributes->OverScanX =
  1720. Hw[iBoard].CurrentOverScanX;
  1721. pVideoPointerAttributes->OverScanY =
  1722. Hw[iBoard].CurrentOverScanY;
  1723. if (Hw[iBoard].DacType == DacTypeBT482)
  1724. {
  1725. pVideoPointerAttributes->Flags = VIDEO_MODE_MONO_POINTER | RAMDAC_BT482;
  1726. pVideoPointerAttributes->Width = 32;
  1727. pVideoPointerAttributes->Height = 32;
  1728. }
  1729. if (Hw[iBoard].DacType == DacTypeBT485)
  1730. {
  1731. pVideoPointerAttributes->Flags = VIDEO_MODE_MONO_POINTER | RAMDAC_BT485;
  1732. pVideoPointerAttributes->Width = 64;
  1733. pVideoPointerAttributes->Height = 64;
  1734. }
  1735. if (Hw[iBoard].DacType == DacTypePX2085)
  1736. {
  1737. pVideoPointerAttributes->Flags = VIDEO_MODE_MONO_POINTER | RAMDAC_PX2085;
  1738. pVideoPointerAttributes->Width = 64;
  1739. pVideoPointerAttributes->Height = 64;
  1740. }
  1741. if (Hw[iBoard].DacType == DacTypeVIEWPOINT)
  1742. {
  1743. pVideoPointerAttributes->Flags = VIDEO_MODE_MONO_POINTER | RAMDAC_VIEWPOINT;
  1744. pVideoPointerAttributes->Width = 64;
  1745. pVideoPointerAttributes->Height = 64;
  1746. }
  1747. if (Hw[iBoard].DacType == DacTypeTVP3026)
  1748. {
  1749. pVideoPointerAttributes->Flags = VIDEO_MODE_MONO_POINTER | RAMDAC_TVP3026;
  1750. pVideoPointerAttributes->Width = 64;
  1751. pVideoPointerAttributes->Height = 64;
  1752. }
  1753. status = NO_ERROR;
  1754. }
  1755. break; // end MTX_QUERY_RAMDAC_INFO
  1756. /*------------------------------------------------------------------*\
  1757. | Required service: IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES
  1758. |
  1759. | This service will return the address ranges used by the user-mode
  1760. | drivers to program the video hardware directly, by filling out
  1761. | a VIDEO_PUBLIC_ACCESS_RANGES structure. A call to
  1762. | MTX_MAKE_BOARD_CURRENT must have been made previously to set
  1763. | which board is to be accessed.
  1764. |
  1765. \*------------------------------------------------------------------*/
  1766. case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES:
  1767. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - QUERY_PUBLIC_ACCESS_RANGES\n"));
  1768. //DbgBreakPoint();
  1769. // Make sure the output buffer is big enough.
  1770. if (RequestPacket->OutputBufferLength <
  1771. (RequestPacket->StatusBlock->Information =
  1772. sizeof(VIDEO_PUBLIC_ACCESS_RANGES)))
  1773. {
  1774. status = ERROR_INSUFFICIENT_BUFFER;
  1775. }
  1776. else
  1777. {
  1778. // Fill out the VIDEO_PUBLIC_ACCESS_RANGES buffer.
  1779. publicAccessRanges = RequestPacket->OutputBuffer;
  1780. ulWindowLength = MgaDriverAccessRange[iBoard*2].RangeLength;
  1781. publicAccessRanges->InIoSpace =
  1782. MgaDriverAccessRange[iBoard*2].RangeInIoSpace;
  1783. publicAccessRanges->MappedInIoSpace =
  1784. MgaDriverAccessRange[iBoard*2].RangeInIoSpace;
  1785. publicAccessRanges->VirtualAddress =
  1786. (PVOID) NULL; // Any virtual address
  1787. status = VideoPortMapMemory(
  1788. MgaDeviceExtension,
  1789. MgaDriverAccessRange[iBoard*2].RangeStart,
  1790. &ulWindowLength,
  1791. &(publicAccessRanges->InIoSpace),
  1792. &(publicAccessRanges->VirtualAddress)
  1793. );
  1794. MgaDeviceExtension->UserModeMappedBaseAddress[iBoard] =
  1795. publicAccessRanges->VirtualAddress;
  1796. }
  1797. break; // end QUERY_PUBLIC_ACCESS_RANGES
  1798. /*------------------------------------------------------------------*\
  1799. | Required service: IOCTL_VIDEO_SET_COLOR_REGISTERS
  1800. |
  1801. | This service sets the adapter's color registers to the specified
  1802. | RGB values.
  1803. |
  1804. \*------------------------------------------------------------------*/
  1805. case IOCTL_VIDEO_SET_COLOR_REGISTERS:
  1806. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - SET_COLOR_REGISTERS\n"));
  1807. //DbgBreakPoint();
  1808. if ((ModeInit = MgaDeviceExtension->SuperModeNumber) == 0xFFFFFFFF)
  1809. {
  1810. status = ERROR_DEV_NOT_EXIST;
  1811. break;
  1812. }
  1813. pclutBuffer = RequestPacket->InputBuffer;
  1814. // Save the current board, because this service will modify it.
  1815. iCurBoard = iBoard;
  1816. pCurBaseAddr = pMgaBaseAddr;
  1817. status = NO_ERROR;
  1818. // Point to the appropriate MULTI_MODE structure.
  1819. pCurMulti = &MgaDeviceExtension->pSuperModes[ModeInit];
  1820. if (pCurMulti == NULL)
  1821. {
  1822. status = ERROR_DEV_NOT_EXIST;
  1823. break;
  1824. }
  1825. // Number of boards involved in the current super-mode.
  1826. CurrentResNbBoards = pCurMulti->MulArrayWidth *
  1827. pCurMulti->MulArrayHeight;
  1828. // For each of them...
  1829. for (n = 0; n < CurrentResNbBoards; n++)
  1830. {
  1831. // Point to the mode information structure.
  1832. pMgaDispMode = pCurMulti->MulHwModes[n];
  1833. // Make the board current.
  1834. iBoard = pCurMulti->MulBoardNb[n];
  1835. pMgaBaseAddr = MgaDeviceExtension->KernelModeMappedBaseAddress[iBoard];
  1836. status |= MgaSetColorLookup(MgaDeviceExtension,
  1837. (PVIDEO_CLUT) RequestPacket->InputBuffer,
  1838. RequestPacket->InputBufferLength);
  1839. }
  1840. // Restore the current board to what it used to be.
  1841. iBoard = iCurBoard;
  1842. pMgaBaseAddr = pCurBaseAddr;
  1843. break; // end SET_COLOR_REGISTERS
  1844. /*------------------------------------------------------------------*\
  1845. | Required service: IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES
  1846. |
  1847. | This service will release the address ranges used by the user-mode
  1848. | drivers to program the video hardware. In the S3 code, and in
  1849. | the DDK reference, it is said that the input buffer should
  1850. | contain an array of VIDEO_PUBLIC_ACCESS_RANGES to be released.
  1851. | However, I did not get anything in the input buffer when I traced
  1852. | through the code. Instead, I have observed that SET_CURRENT_MODE
  1853. | had been called, so that there is a current valid mode. We will
  1854. | simply free the access ranges not required by the current mode.
  1855. |
  1856. \*------------------------------------------------------------------*/
  1857. case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES:
  1858. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - FREE_PUBLIC_ACCESS_RANGES\n"));
  1859. //DbgBreakPoint();
  1860. // Make sure the input buffer is big enough.
  1861. if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
  1862. {
  1863. // The input buffer is not large enough.
  1864. // Assume all will be right.
  1865. status = NO_ERROR;
  1866. ModeInit = MgaDeviceExtension->SuperModeNumber;
  1867. if(ModeInit == 0xFFFFFFFF)
  1868. {
  1869. // No mode has been selected yet, so we'll free everything.
  1870. // For every board...
  1871. for (i = 0; i< NbBoard; i++)
  1872. {
  1873. if (MgaDeviceExtension->UserModeMappedBaseAddress[i])
  1874. {
  1875. // This board has a non-null user-mode base address.
  1876. // Fill out the VIDEO_PUBLIC_ACCESS_RANGES buffer.
  1877. publicAccessRanges=RequestPacket->OutputBuffer;
  1878. publicAccessRanges->InIoSpace = 0; // Not in I/O space
  1879. publicAccessRanges->MappedInIoSpace = 0; // Not in I/O space
  1880. publicAccessRanges->VirtualAddress =
  1881. MgaDeviceExtension->UserModeMappedBaseAddress[i];
  1882. status |= VideoPortUnmapMemory(
  1883. MgaDeviceExtension,
  1884. publicAccessRanges->VirtualAddress,
  1885. 0);
  1886. // Reset the user-mode base address.
  1887. MgaDeviceExtension->UserModeMappedBaseAddress[i] = 0;
  1888. }
  1889. }
  1890. }
  1891. else
  1892. {
  1893. // We know our current mode.
  1894. // Point to the appropriate MULTI_MODE structure.
  1895. pCurMulti = &MgaDeviceExtension->pSuperModes[ModeInit];
  1896. if (pCurMulti == NULL)
  1897. {
  1898. status = ERROR_DEV_NOT_EXIST;
  1899. break;
  1900. }
  1901. // Number of boards involved in the current super-mode.
  1902. CurrentResNbBoards = pCurMulti->MulArrayWidth *
  1903. pCurMulti->MulArrayHeight;
  1904. // For every board...
  1905. for (i = 0; i< NbBoard; i++)
  1906. {
  1907. // Check whether it's used by the current mode.
  1908. n = 0;
  1909. while ((n < CurrentResNbBoards) &&
  1910. (pCurMulti->MulBoardNb[n] != i))
  1911. n++;
  1912. if ((n == CurrentResNbBoards) &&
  1913. (MgaDeviceExtension->UserModeMappedBaseAddress[i]))
  1914. {
  1915. // We went through the list, the board is not in use,
  1916. // and the board has a non-null user-mode base address.
  1917. // Fill out the VIDEO_PUBLIC_ACCESS_RANGES buffer.
  1918. publicAccessRanges=RequestPacket->OutputBuffer;
  1919. publicAccessRanges->InIoSpace = 0; // Not in I/O space
  1920. publicAccessRanges->MappedInIoSpace = 0; // Not in I/O space
  1921. publicAccessRanges->VirtualAddress =
  1922. MgaDeviceExtension->UserModeMappedBaseAddress[i];
  1923. status |= VideoPortUnmapMemory(
  1924. MgaDeviceExtension,
  1925. publicAccessRanges->VirtualAddress,
  1926. 0);
  1927. // Reset the user-mode base address.
  1928. MgaDeviceExtension->UserModeMappedBaseAddress[i] = 0;
  1929. }
  1930. }
  1931. }
  1932. }
  1933. else
  1934. {
  1935. // The input buffer is large enough, use it.
  1936. status = VideoPortUnmapMemory(MgaDeviceExtension,
  1937. ((PVIDEO_MEMORY)
  1938. (RequestPacket->InputBuffer))->
  1939. RequestedVirtualAddress,
  1940. 0);
  1941. }
  1942. break; // end FREE_PUBLIC_ACCESS_RANGES
  1943. /*------------------------------------------------------------------*\
  1944. | Required service: IOCTL_VIDEO_MAP_VIDEO_MEMORY
  1945. |
  1946. | This service maps the frame buffer and VRAM into the virtual
  1947. | address space of the requestor. For now, we'll just return NULL
  1948. | addresses and lengths.
  1949. |
  1950. \*------------------------------------------------------------------*/
  1951. case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
  1952. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - MAP_VIDEO_MEMORY\n"));
  1953. //DbgBreakPoint();
  1954. if ( (RequestPacket->OutputBufferLength <
  1955. (RequestPacket->StatusBlock->Information =
  1956. sizeof(VIDEO_MEMORY_INFORMATION))) ||
  1957. (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) )
  1958. {
  1959. status = ERROR_INSUFFICIENT_BUFFER;
  1960. }
  1961. else
  1962. {
  1963. memoryInformation = RequestPacket->OutputBuffer;
  1964. memoryInformation->VideoRamBase = 0;
  1965. memoryInformation->VideoRamLength = 0;
  1966. memoryInformation->FrameBufferBase = 0;
  1967. memoryInformation->FrameBufferLength = 0;
  1968. status = NO_ERROR;
  1969. }
  1970. break; // end MAP_VIDEO_MEMORY
  1971. /*------------------------------------------------------------------*\
  1972. | Required service: IOCTL_VIDEO_UNMAP_VIDEO_MEMORY
  1973. |
  1974. | This service releases mapping of the frame buffer and VRAM from
  1975. | the virtual address space of the requestor. For now, we'll just
  1976. | do nothing.
  1977. |
  1978. \*------------------------------------------------------------------*/
  1979. case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
  1980. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - UNMAP_VIDEO_MEMORY\n"));
  1981. //DbgBreakPoint();
  1982. if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
  1983. {
  1984. status = ERROR_INSUFFICIENT_BUFFER;
  1985. }
  1986. else
  1987. {
  1988. status = NO_ERROR;
  1989. }
  1990. break;
  1991. /*------------------------------------------------------------------*\
  1992. | Required service: IOCTL_VIDEO_QUERY_CURRENT_MODE
  1993. |
  1994. | This service returns information about the current video mode
  1995. | by filling out a VIDEO_MODE_INFORMATION structure.
  1996. |
  1997. \*------------------------------------------------------------------*/
  1998. case IOCTL_VIDEO_QUERY_CURRENT_MODE:
  1999. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - QUERY_CURRENT_MODE\n"));
  2000. //DbgBreakPoint();
  2001. if (RequestPacket->OutputBufferLength <
  2002. (RequestPacket->StatusBlock->Information =
  2003. sizeof(VIDEO_MODE_INFORMATION)) )
  2004. {
  2005. status = ERROR_INSUFFICIENT_BUFFER;
  2006. }
  2007. else
  2008. {
  2009. modeInformation = RequestPacket->OutputBuffer;
  2010. // Fill in a VIDEO_MODE_INFORMATION struc for the mode indicated
  2011. // by MgaDeviceExtension->SuperModeNumber
  2012. i = MgaDeviceExtension->SuperModeNumber;
  2013. if (i == 0xFFFFFFFF)
  2014. {
  2015. status = ERROR_DEV_NOT_EXIST;
  2016. break;
  2017. }
  2018. pCurMulti = &MgaDeviceExtension->pSuperModes[i];
  2019. if (pCurMulti == NULL)
  2020. {
  2021. status = ERROR_DEV_NOT_EXIST;
  2022. break;
  2023. }
  2024. // Fill in common values that apply to all modes.
  2025. *modeInformation=CommonVideoModeInformation;
  2026. // Fill in mode specific informations.
  2027. modeInformation->ModeIndex = pCurMulti->MulModeNumber;
  2028. modeInformation->VisScreenWidth = pCurMulti->MulWidth;
  2029. modeInformation->VisScreenHeight= pCurMulti->MulHeight;
  2030. modeInformation->ScreenStride =
  2031. pCurMulti->MulWidth * pCurMulti->MulPixWidth / 8;
  2032. modeInformation->BitsPerPlane = pCurMulti->MulPixWidth;
  2033. modeInformation->Frequency = pCurMulti->MulRefreshRate;
  2034. // If we're in TrueColor mode, then set RGB masks
  2035. if ((modeInformation[i].BitsPerPlane == 32) ||
  2036. (modeInformation[i].BitsPerPlane == 24))
  2037. {
  2038. modeInformation[i].RedMask = 0x00FF0000;
  2039. modeInformation[i].GreenMask = 0x0000FF00;
  2040. modeInformation[i].BlueMask = 0x000000FF;
  2041. modeInformation[i].AttributeFlags =
  2042. VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS;
  2043. }
  2044. else if (modeInformation[i].BitsPerPlane == 16)
  2045. {
  2046. modeInformation[i].AttributeFlags =
  2047. VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS;
  2048. if (pCurMulti->MulHwModes[0]->DispType & DISPTYPE_M565)
  2049. {
  2050. modeInformation[i].RedMask = 0x0000F800;
  2051. modeInformation[i].GreenMask = 0x000007E0;
  2052. modeInformation[i].BlueMask = 0x0000001F;
  2053. }
  2054. else
  2055. {
  2056. modeInformation[i].RedMask = 0x00007C00;
  2057. modeInformation[i].GreenMask = 0x000003E0;
  2058. modeInformation[i].BlueMask = 0x0000001F;
  2059. modeInformation[i].AttributeFlags |= VIDEO_MODE_555;
  2060. modeInformation[i].BitsPerPlane = 15;
  2061. }
  2062. }
  2063. else
  2064. {
  2065. modeInformation[i].AttributeFlags =
  2066. VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS |
  2067. VIDEO_MODE_PALETTE_DRIVEN |
  2068. VIDEO_MODE_MANAGED_PALETTE;
  2069. }
  2070. if (pCurMulti->MulHwModes[0]->ZBuffer)
  2071. {
  2072. // This is a 3D mode.
  2073. modeInformation[i].AttributeFlags |= VIDEO_MODE_3D;
  2074. }
  2075. // Number of boards involved in the current super-mode.
  2076. CurrentResNbBoards = pCurMulti->MulArrayWidth *
  2077. pCurMulti->MulArrayHeight;
  2078. // For each of them...
  2079. for (n = 0; n < CurrentResNbBoards; n++)
  2080. {
  2081. // Point to the mode information structure.
  2082. pMgaDispMode = pCurMulti->MulHwModes[n];
  2083. // For now, don't disclose whether we're interlaced.
  2084. //if (pMgaDispMode->DispType & TYPE_INTERLACED)
  2085. //{
  2086. // modeInformation[i].AttributeFlags |=
  2087. // VIDEO_MODE_INTERLACED;
  2088. //}
  2089. // Figure out the width and height of the video memory bitmap
  2090. MaxWidth = pMgaDispMode->DispWidth;
  2091. MaxHeight = pMgaDispMode->DispHeight;
  2092. pMgaOffScreenData = pMgaDispMode->pOffScr;
  2093. for (j = 0; j < pMgaDispMode->NumOffScr; j++)
  2094. {
  2095. if ((usTemp=(pMgaOffScreenData[j].XStart +
  2096. pMgaOffScreenData[j].Width)) > MaxWidth)
  2097. MaxWidth=usTemp;
  2098. if ((usTemp=(pMgaOffScreenData[j].YStart +
  2099. pMgaOffScreenData[j].Height)) > MaxHeight)
  2100. MaxHeight=usTemp;
  2101. }
  2102. modeInformation[i].VideoMemoryBitmapWidth = MaxWidth;
  2103. modeInformation[i].VideoMemoryBitmapHeight= MaxHeight;
  2104. }
  2105. status = NO_ERROR;
  2106. }
  2107. break; // end QUERY_CURRENT_MODE
  2108. /*------------------------------------------------------------------*\
  2109. | Required service: IOCTL_VIDEO_RESET_DEVICE
  2110. |
  2111. | This service resets the video hardware to the default mode, to
  2112. | which it was initialized at system boot.
  2113. |
  2114. \*------------------------------------------------------------------*/
  2115. case IOCTL_VIDEO_RESET_DEVICE:
  2116. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - RESET_DEVICE\n"));
  2117. //DbgBreakPoint();
  2118. if ((ModeInit = MgaDeviceExtension->SuperModeNumber) == 0xFFFFFFFF)
  2119. {
  2120. // RESET has been done already.
  2121. status = NO_ERROR;
  2122. break;
  2123. }
  2124. // Save the current board, because this service will modify it.
  2125. iCurBoard = iBoard;
  2126. pCurBaseAddr = pMgaBaseAddr;
  2127. // Point to the appropriate MULTI_MODE structure.
  2128. pCurMulti = &MgaDeviceExtension->pSuperModes[ModeInit];
  2129. if (pCurMulti == NULL)
  2130. {
  2131. status = ERROR_DEV_NOT_EXIST;
  2132. break;
  2133. }
  2134. // Number of boards involved in the current super-mode.
  2135. CurrentResNbBoards = pCurMulti->MulArrayWidth *
  2136. pCurMulti->MulArrayHeight;
  2137. // For each of them...
  2138. for (n = 0; n < CurrentResNbBoards; n++)
  2139. {
  2140. // Point to the mode information structure.
  2141. pMgaDispMode = pCurMulti->MulHwModes[n];
  2142. // Make the board current.
  2143. iBoard = pCurMulti->MulBoardNb[n];
  2144. pMgaBaseAddr = MgaDeviceExtension->KernelModeMappedBaseAddress[iBoard];
  2145. // Disable the hardware cursor.
  2146. mtxCursorEnable(0);
  2147. if(Hw[iBoard].VGAEnable)
  2148. {
  2149. // This board is VGA-enabled, reset it to VGA.
  2150. mtxSetVideoMode(mtxPASSTHRU);
  2151. }
  2152. else
  2153. {
  2154. // This board is not VGA-enabled.
  2155. // Just clear the screen, it will look nicer.
  2156. clutBufferOne.NumEntries = 1;
  2157. clutBufferOne.LookupTable[0].RgbLong = 0;
  2158. for (j = 0; j <= VIDEO_MAX_COLOR_REGISTER; j++)
  2159. {
  2160. clutBufferOne.FirstEntry = j;
  2161. MgaSetColorLookup(MgaDeviceExtension,
  2162. &clutBufferOne,
  2163. sizeof(VIDEO_CLUT));
  2164. }
  2165. // Make the cursor disappear.
  2166. // MgaSetCursorColour(MgaDeviceExtension, 0, 0);
  2167. }
  2168. }
  2169. // Signal that no mode is currently selected.
  2170. MgaDeviceExtension->SuperModeNumber = 0xFFFFFFFF;
  2171. if (MgaDeviceExtension->pSuperModes != (PMULTI_MODE) NULL)
  2172. {
  2173. // Free our allocated memory.
  2174. VideoPortReleaseBuffer(pMgaDeviceExtension, MgaDeviceExtension->pSuperModes);
  2175. MgaDeviceExtension->pSuperModes = (PMULTI_MODE) NULL;
  2176. }
  2177. MgaDeviceExtension->NumberOfSuperModes = 0;
  2178. // Memory might have been allocated for mgainf.
  2179. if (mgainf != DefaultVidset)
  2180. {
  2181. VideoPortReleaseBuffer(pMgaDeviceExtension, mgainf);
  2182. // And use the default set.
  2183. mgainf = adjustDefaultVidset();
  2184. }
  2185. // Restore the current board to what it used to be.
  2186. iBoard = iCurBoard;
  2187. pMgaBaseAddr = pCurBaseAddr;
  2188. status = NO_ERROR;
  2189. break; // end IOCTL_VIDEO_RESET_DEVICE
  2190. #if 0
  2191. case IOCTL_VIDEO_SAVE_HARDWARE_STATE:
  2192. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - SAVE_HARDWARE_STATE\n"));
  2193. status = ERROR_INVALID_FUNCTION;
  2194. break;
  2195. case IOCTL_VIDEO_RESTORE_HARDWARE_STATE:
  2196. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - RESTORE_HARDWARE_STATE\n"));
  2197. status = ERROR_INVALID_FUNCTION;
  2198. break;
  2199. case IOCTL_VIDEO_ENABLE_VDM:
  2200. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - ENABLE_VDM\n"));
  2201. status = ERROR_INVALID_FUNCTION;
  2202. break;
  2203. #endif
  2204. /*------------------------------------------------------------------*\
  2205. | If we get here, an invalid IoControlCode was specified.
  2206. \*------------------------------------------------------------------*/
  2207. default:
  2208. VideoDebugPrint((1, "MGA.SYS!MgaStartIO - Invalid service\n"));
  2209. status = ERROR_INVALID_FUNCTION;
  2210. break;
  2211. }
  2212. RequestPacket->StatusBlock->Status = status;
  2213. return TRUE;
  2214. } // end MgaStartIO()
  2215. /*--------------------------------------------------------------------------*\
  2216. | VP_STATUS
  2217. | MgaInitModeList(
  2218. | PMGA_DEVICE_EXTENSION MgaDeviceExtension)
  2219. |
  2220. | Routine Description:
  2221. |
  2222. | This routine builds the list of modes available for the detected boards.
  2223. |
  2224. | Arguments:
  2225. |
  2226. | HwDeviceExtension - Pointer to the miniport driver's device extension.
  2227. |
  2228. | Return Value:
  2229. |
  2230. | NO_ERROR, ERROR_DEV_NOT_EXIST, or ERROR_NOT_ENOUGH_MEMORY.
  2231. |
  2232. \*--------------------------------------------------------------------------*/
  2233. VP_STATUS
  2234. MgaInitModeList(
  2235. PMGA_DEVICE_EXTENSION MgaDeviceExtension)
  2236. {
  2237. HwModeData *pMgaDispMode, *pMgaModeData, *pCurrentMgaModeData;
  2238. HwModeData *Mga2dMode[16], *Mga3dMode[16];
  2239. MULTI_MODE *pCurMulti;
  2240. PULONG pulModeFlags;
  2241. ULONG ulNb2DRefreshRates, ulNb3DRefreshRates, ulNbRefreshRates;
  2242. ULONG VGABoard, VGABoardBit, ModePixDepth, ulModeListOffset,
  2243. NbSuperModes, ResTag, ModeInit;
  2244. ULONG CurrentResFlags, CurrentFlag,
  2245. CurrentResWidth, CurrentResHeight, CurrentRefreshRate,
  2246. CurrentResNbBoards, CurrentResNbBoards3D, CurrentPixWidth;
  2247. ULONG i, k, m, n, ir, ja, i2d, i3d;
  2248. VP_STATUS status;
  2249. USHORT j;
  2250. USHORT us2DRefreshRates, us3DRefreshRates, usRefreshRates;
  2251. UCHAR ValidBoard[NB_BOARD_MAX];
  2252. UCHAR ucTestFlags, ucRefreshBit;
  2253. UCHAR ucMask;
  2254. BOOLEAN bSupported2dMode, bSupported3dMode;
  2255. // Assume we won't have any problem.
  2256. status = NO_ERROR;
  2257. // Check whether we've already built a mode list. MgaDeviceExtension
  2258. // is assumed to have been zeroed out when it was first given us.
  2259. if (MgaDeviceExtension->NumberOfSuperModes != 0)
  2260. {
  2261. if (MgaDeviceExtension->pSuperModes != (PMULTI_MODE) NULL)
  2262. {
  2263. // Free our allocated memory.
  2264. VideoPortReleaseBuffer(pMgaDeviceExtension,
  2265. MgaDeviceExtension->pSuperModes);
  2266. MgaDeviceExtension->pSuperModes = (PMULTI_MODE) NULL;
  2267. }
  2268. // Memory might have been allocated for mgainf. It's all right,
  2269. // we'll want to use the current mgainf.
  2270. }
  2271. // Just in case we leave early...
  2272. MgaDeviceExtension->NumberOfSuperModes = 0;
  2273. // Get information on all the MGA boards currently installed in the
  2274. // system.
  2275. if ((pMgaBoardData = mtxCheckHwAll()) == NULL)
  2276. {
  2277. // mtxCheckHwAll should always return success, since MapBoard has
  2278. // already been executed.
  2279. // BUGBUG - if it never occurs, then this code isn't needed.
  2280. // a better answer would be to code an ASSERT() and
  2281. // write code that would handle the failure anyways
  2282. VideoDebugPrint((1, "MGA.SYS!MGAStartIO failed mtxCheckHwAll\n"));
  2283. status = ERROR_DEV_NOT_EXIST;
  2284. return(status);
  2285. }
  2286. else
  2287. {
  2288. // There may be several MGA boards installed. Look at all of
  2289. // them, and map their physical addresses into kernel space.
  2290. // While we're at it, find out if any of our boards is VGA enabled.
  2291. VGABoard = (ULONG)-1;
  2292. VGABoardBit = 0;
  2293. // No mode has been selected yet, so make this invalid.
  2294. MgaDeviceExtension->SuperModeNumber = 0xFFFFFFFF;
  2295. MgaDeviceExtension->pSuperModes = (PMULTI_MODE) NULL;
  2296. // We don't care whether the mode is interlaced or not, because
  2297. // the only modes that we'll get will be selected according to
  2298. // the monitor capabilities through the mga.inf file.
  2299. ucMask = (UCHAR)(~DISPTYPE_INTERLACED);
  2300. // pMgaBoardData is really the address of Hw[0].
  2301. for (i = 0; i < NbBoard; i++)
  2302. {
  2303. MgaDeviceExtension->NumberOfModes[i] = 0;
  2304. MgaDeviceExtension->NumberOfValidModes[i] = 0;
  2305. MgaDeviceExtension->ModeFlags2D[i] = 0;
  2306. MgaDeviceExtension->ModeFlags3D[i] = 0;
  2307. // Make it clean: initialize the ModeList to an invalid mode.
  2308. for (j = 0; j < 64; j++)
  2309. {
  2310. MgaDeviceExtension->ModeList[i][j] = 0xFF;
  2311. }
  2312. if (mtxSelectHw(&Hw[i]) == mtxFAIL)
  2313. {
  2314. // mtxSelectHw should always return success, since
  2315. // MapBoard has already been executed.
  2316. // BUGBUG - if it never occurs, then this code isn't needed.
  2317. // a better answer would be to code an ASSERT() and
  2318. // write code that would handle the failure anyways
  2319. VideoDebugPrint((1, "MGA.SYS!MGAStartIO failed mtxSelectHw for board %d\n", i));
  2320. MgaDeviceExtension->KernelModeMappedBaseAddress[i] =
  2321. (PVOID)0xffffffff;
  2322. continue;
  2323. }
  2324. // MGA board i has been selected.
  2325. //VideoDebugPrint((1, "MGA.SYS!MGAStartIO mapped board %d at 0x%x\n", i, pMgaBaseAddr));
  2326. //DbgPrint("MGA.SYS!MGAStartIO mapped board %d at 0x%x\n", i, pMgaBaseAddr);
  2327. MgaDeviceExtension->KernelModeMappedBaseAddress[i] =
  2328. pMgaBaseAddr;
  2329. if (Hw[i].VGAEnable)
  2330. {
  2331. VGABoard = i;
  2332. VGABoardBit = 1 << i;
  2333. }
  2334. // Set up the test flags. TITAN always supports
  2335. // double-buffering, while Atlas and Athena use different
  2336. // modes.
  2337. if ((Hw[i].ProductRev & 0x000000F0) == 0)
  2338. {
  2339. // This is TITAN.
  2340. ucTestFlags = DISPTYPE_DB;
  2341. }
  2342. else
  2343. {
  2344. // This is not TITAN.
  2345. ucTestFlags = 0;
  2346. }
  2347. // Get information on all the hardware modes available for
  2348. // the current MGA board.
  2349. if ((pMgaModeData = mtxGetHwModes()) == NULL)
  2350. {
  2351. // This case never occurs.
  2352. // BUGBUG - if it never occurs, then this code isn't needed.
  2353. // a better answer would be to code an ASSERT() and
  2354. // write code that would handle the failure anyways
  2355. VideoDebugPrint((1, "MGA.SYS!MGAStartIO failed mtxGetHwModes for board %d\n", i));
  2356. continue;
  2357. }
  2358. // Store it in the DeviceExtension structure.
  2359. MgaDeviceExtension->pMgaHwModes[i] = pMgaModeData;
  2360. // Modes we may want to support:
  2361. //
  2362. // 2D modes -------------------------------------------------
  2363. // 8bpp, LUT
  2364. // DispType = 14, ZBuffer = 0, PixWidth = 8 (Titan)
  2365. // DispType = 4, ZBuffer = 0, PixWidth = 8 (others)
  2366. // 16bpp, 565
  2367. // DispType = 8, ZBuffer = 0, PixWidth = 16
  2368. // 24bpp
  2369. // DispType = 0, ZBuffer = 0, PixWidth = 24 (Storm only)
  2370. // 32bpp
  2371. // DispType = 10, ZBuffer = 0, PixWidth = 32 (Titan)
  2372. // DispType = 0, ZBuffer = 0, PixWidth = 32 (others)
  2373. //
  2374. // 3D modes -------------------------------------------------
  2375. // 8bpp, no LUT
  2376. // DispType = 10, ZBuffer = 1, PixWidth = 8
  2377. // 16bpp, 555
  2378. // DispType = 10, ZBuffer = 1, PixWidth = 16 (Mga or Storm)
  2379. // OR
  2380. // 16bpp, 565
  2381. // DispType = 18, ZBuffer = 1, PixWidth = 16 (Storm only)
  2382. // 24bpp
  2383. // DispType = 10, ZBuffer = 1, PixWidth = 24 (Storm only)
  2384. // 32bpp
  2385. // DispType = 10, ZBuffer = 1, PixWidth = 32
  2386. // Calculate the number of available modes for this board.
  2387. // *IMPORTANT* We assume the last entry in the HwMode
  2388. // array has DispWidth equal to -1.
  2389. // NEW!
  2390. // We do not want to support 16bpp modes here. We'll
  2391. // support 5-5-5 modes, but the trick is that some of
  2392. // them will be 3D modes, and the other ones will be 2D.
  2393. // We have to examine the list for these.
  2394. i2d = 0;
  2395. i3d = 0;
  2396. for (pCurrentMgaModeData = pMgaModeData;
  2397. pCurrentMgaModeData->DispWidth != (word)-1;
  2398. pCurrentMgaModeData++)
  2399. {
  2400. if (pCurrentMgaModeData->PixWidth == 16)
  2401. {
  2402. if (pCurrentMgaModeData->ZBuffer)
  2403. {
  2404. // 16bpp, Z buffer.
  2405. if ((pCurrentMgaModeData->DispType & ucMask) ==
  2406. DISPTYPE_DB)
  2407. {
  2408. Mga3dMode[i3d] = pCurrentMgaModeData;
  2409. i3d++;
  2410. }
  2411. }
  2412. else
  2413. {
  2414. // 16bpp, no Z buffer.
  2415. if ((pCurrentMgaModeData->DispType & ucMask) ==
  2416. ucTestFlags)
  2417. {
  2418. Mga2dMode[i2d] = pCurrentMgaModeData;
  2419. i2d++;
  2420. }
  2421. }
  2422. }
  2423. }
  2424. for (m = 0; m < i2d; m++)
  2425. {
  2426. // Examine one of the 2D modes.
  2427. bSupported2dMode = TRUE;
  2428. pCurrentMgaModeData = Mga2dMode[m];
  2429. CurrentResWidth = pCurrentMgaModeData->DispWidth;
  2430. CurrentResHeight = pCurrentMgaModeData->DispHeight;
  2431. // Look for a similar 3D mode.
  2432. for (k = 0; k < i3d; k++)
  2433. {
  2434. pCurrentMgaModeData = Mga3dMode[k];
  2435. if ((pCurrentMgaModeData->DispWidth == CurrentResWidth ) &&
  2436. (pCurrentMgaModeData->DispHeight== CurrentResHeight))
  2437. {
  2438. // The current 2D mode is simlar to a 3D mode,
  2439. // we want to reject this 2D mode.
  2440. bSupported2dMode = FALSE;
  2441. break;
  2442. }
  2443. }
  2444. if (bSupported2dMode == TRUE)
  2445. {
  2446. // We want to keep this one, so remove it from the
  2447. // checklist.
  2448. Mga2dMode[m] = 0;
  2449. }
  2450. }
  2451. for (pCurrentMgaModeData = pMgaModeData;
  2452. pCurrentMgaModeData->DispWidth != (word)-1;
  2453. pCurrentMgaModeData++)
  2454. {
  2455. // Update the total number of modes supported.
  2456. MgaDeviceExtension->NumberOfModes[i]++;
  2457. for (m = 0; m < i2d; m++)
  2458. {
  2459. if (pCurrentMgaModeData == Mga2dMode[m])
  2460. {
  2461. // This one is on our black list, reject it.
  2462. goto IML_END_OF_LOOP;
  2463. }
  2464. }
  2465. // Assume this mode won't be supported.
  2466. bSupported2dMode = FALSE;
  2467. bSupported3dMode = FALSE;
  2468. // Update the number of valid modes supported.
  2469. ModePixDepth = pCurrentMgaModeData->PixWidth;
  2470. switch (ModePixDepth)
  2471. {
  2472. case 8: if (pCurrentMgaModeData->ZBuffer)
  2473. {
  2474. // 8bpp, Z buffer.
  2475. // We don't support any of these.
  2476. }
  2477. else
  2478. {
  2479. // 8bpp, no Z buffer.
  2480. if ((pCurrentMgaModeData->DispType & ucMask) ==
  2481. (ucTestFlags | DISPTYPE_LUT))
  2482. {
  2483. bSupported2dMode = TRUE;
  2484. }
  2485. }
  2486. break;
  2487. case 16:if (pCurrentMgaModeData->ZBuffer)
  2488. {
  2489. // 16bpp, Z buffer.
  2490. if ((pCurrentMgaModeData->DispType & ucMask) ==
  2491. DISPTYPE_DB)
  2492. {
  2493. bSupported3dMode = TRUE;
  2494. }
  2495. }
  2496. else
  2497. {
  2498. // 16bpp, no Z buffer.
  2499. //if ((pCurrentMgaModeData->DispType & ucMask) ==
  2500. // DISPTYPE_M565)
  2501. if ((pCurrentMgaModeData->DispType & ucMask) ==
  2502. ucTestFlags)
  2503. {
  2504. bSupported2dMode = TRUE;
  2505. }
  2506. }
  2507. break;
  2508. case 24:if (pCurrentMgaModeData->ZBuffer)
  2509. {
  2510. // 24bpp, Z buffer.
  2511. // We don't support any of these.
  2512. }
  2513. else
  2514. {
  2515. // 24bpp, no Z buffer.
  2516. // We don't support any of these.
  2517. }
  2518. break;
  2519. case 32:if (pCurrentMgaModeData->ZBuffer)
  2520. {
  2521. // 32bpp, Z buffer.
  2522. // We don't support any of these.
  2523. }
  2524. else
  2525. {
  2526. // 32bpp, no Z buffer.
  2527. if ((pCurrentMgaModeData->DispType & ucMask) ==
  2528. ucTestFlags)
  2529. {
  2530. bSupported2dMode = TRUE;
  2531. }
  2532. }
  2533. break;
  2534. default:
  2535. break;
  2536. }
  2537. if ((bSupported2dMode == FALSE) &&
  2538. (bSupported3dMode == FALSE))
  2539. {
  2540. // We don't support this mode, get out.
  2541. continue;
  2542. }
  2543. if (bSupported2dMode)
  2544. ulModeListOffset = 0;
  2545. else
  2546. ulModeListOffset = 32;
  2547. // We can do something with the current mode.
  2548. switch(pCurrentMgaModeData->DispWidth)
  2549. {
  2550. case 640: ResTag = BIT_640;
  2551. break;
  2552. case 768: ResTag = BIT_768;
  2553. break;
  2554. case 800: ResTag = BIT_800;
  2555. break;
  2556. case 1024: ResTag = BIT_1024;
  2557. break;
  2558. case 1152: ResTag = BIT_1152;
  2559. break;
  2560. case 1280: ResTag = BIT_1280;
  2561. break;
  2562. case 1600: ResTag = BIT_1600;
  2563. break;
  2564. default: ResTag = BIT_INVALID;
  2565. }
  2566. // Record the HW mode to be used for this mode.
  2567. // ModePixDepth is either 8, 16, 24, or 32.
  2568. if (ResTag != BIT_INVALID)
  2569. {
  2570. // We know this hardware mode is correct. Now find
  2571. // out how many refresh rates this mode supports.
  2572. usRefreshRates = mtxGetRefreshRates(pCurrentMgaModeData);
  2573. for (j = 0; j < 16; j++)
  2574. {
  2575. if (usRefreshRates & (1 << j))
  2576. {
  2577. MgaDeviceExtension->NumberOfValidModes[i]++;
  2578. }
  2579. }
  2580. MgaDeviceExtension->
  2581. ModeList[i][ResTag+ModePixDepth+ulModeListOffset-8]
  2582. = (UCHAR)(MgaDeviceExtension->NumberOfModes[i] - 1);
  2583. MgaDeviceExtension->
  2584. ModeFreqs[i][ResTag+ModePixDepth+ulModeListOffset-8]
  2585. = usRefreshRates;
  2586. }
  2587. // Make up the resolution tag from the bit field.
  2588. ResTag = 1 << ResTag;
  2589. // Shift the resolution tag into its pixel-depth field.
  2590. ResTag <<= (ModePixDepth - 8);
  2591. // Record the resolution/pixel-depth flag.
  2592. if (bSupported2dMode)
  2593. MgaDeviceExtension->ModeFlags2D[i] |= ResTag;
  2594. else
  2595. MgaDeviceExtension->ModeFlags3D[i] |= ResTag;
  2596. IML_END_OF_LOOP:
  2597. ;
  2598. }
  2599. }
  2600. // We have recorded information for each of our boards in the
  2601. // MgaDeviceExtension structure. For each board, we have set:
  2602. //
  2603. // NumberOfModes[n] The number of available modes
  2604. // NumberOfValidModes[n] The number of modes supported by the
  2605. // user-mode drivers
  2606. // ModeFlags2D[n] The bit flags describing the supported
  2607. // 2D modes
  2608. // ModeFlags3D[n] The bit flags describing the supported
  2609. // 3D modes
  2610. // KernelModeMappedBaseAddress[n]
  2611. // The board's registers window mapping,
  2612. // returned when VideoPortGetDeviceBase
  2613. // is called with Hw[n].MapAddress
  2614. // pMgaHwModes[n] The pointer to an array of HwModeData
  2615. // structures describing available modes
  2616. // ModeList[n][64] A list of hardware modes corresponding
  2617. // to the ModeFlags bits
  2618. //
  2619. //DbgBreakPoint();
  2620. #if DBG
  2621. // Display it so that we can see if it makes sense...
  2622. VideoDebugPrint((1, "# NbModes NbValid ModeFlg2D ModeFlg3D BaseAddr pHwModes ModeList\n"));
  2623. for (i = 0; i < NbBoard; i++)
  2624. {
  2625. VideoDebugPrint((1, "%d % 7d % 7d 0x%08x 0x%08x 0x%08x\n",i,
  2626. MgaDeviceExtension->NumberOfModes[i],
  2627. MgaDeviceExtension->NumberOfValidModes[i],
  2628. MgaDeviceExtension->ModeFlags2D[i],
  2629. MgaDeviceExtension->ModeFlags3D[i],
  2630. MgaDeviceExtension->KernelModeMappedBaseAddress[i],
  2631. MgaDeviceExtension->pMgaHwModes[i]));
  2632. for (j = 0; j < 64; j+=8)
  2633. {
  2634. VideoDebugPrint((1, " %02x %02x %02x %02x %02x %02x %02x %02x\n",
  2635. MgaDeviceExtension->ModeList[i][j],
  2636. MgaDeviceExtension->ModeList[i][j+1],
  2637. MgaDeviceExtension->ModeList[i][j+2],
  2638. MgaDeviceExtension->ModeList[i][j+3],
  2639. MgaDeviceExtension->ModeList[i][j+4],
  2640. MgaDeviceExtension->ModeList[i][j+5],
  2641. MgaDeviceExtension->ModeList[i][j+6],
  2642. MgaDeviceExtension->ModeList[i][j+7]));
  2643. }
  2644. }
  2645. #endif // #if DBG
  2646. // Now for the fun part: find out the resolutions and
  2647. // combinations of resolutions that we can support.
  2648. // First, run through the ModeFlags to determine how many modes
  2649. // we can make up from the single-board modes.
  2650. // For each bit in our ModeFlags...
  2651. NbSuperModes = 0;
  2652. for (i = 0; i < 32; i++)
  2653. {
  2654. // Find out which boards, if any, support this mode.
  2655. CurrentResNbBoards = 0;
  2656. CurrentResNbBoards3D = 0;
  2657. for (n = 0; n < (ULONG)NbBoard; n++)
  2658. {
  2659. ulNb2DRefreshRates = 0;
  2660. ulNb3DRefreshRates = 0;
  2661. us2DRefreshRates = MgaDeviceExtension->ModeFreqs[n][i];
  2662. us3DRefreshRates = MgaDeviceExtension->ModeFreqs[n][i+32];
  2663. for (j = 0; j < 16; j++)
  2664. {
  2665. if (us2DRefreshRates & (1 << j))
  2666. {
  2667. ulNb2DRefreshRates++;
  2668. }
  2669. if (us3DRefreshRates & (1 << j))
  2670. {
  2671. ulNb3DRefreshRates++;
  2672. }
  2673. }
  2674. if ((MgaDeviceExtension->ModeFlags2D[n] >> i) & 1)
  2675. {
  2676. // The mode is supported by the current board.
  2677. CurrentResNbBoards++;
  2678. NbSuperModes += (ulNb2DRefreshRates *
  2679. MultiModes[CurrentResNbBoards]);
  2680. }
  2681. if ((MgaDeviceExtension->ModeFlags3D[n] >> i) & 1)
  2682. {
  2683. // The mode is supported by the current board.
  2684. CurrentResNbBoards3D++;
  2685. NbSuperModes += (ulNb3DRefreshRates *
  2686. MultiModes[CurrentResNbBoards3D]);
  2687. }
  2688. }
  2689. }
  2690. if (NbSuperModes == 0)
  2691. {
  2692. // We did not find any mode!
  2693. status = ERROR_DEV_NOT_EXIST;
  2694. return(status);
  2695. }
  2696. // Now, allocate some memory to hold the new structures.
  2697. MgaDeviceExtension->pSuperModes =
  2698. pCurMulti = (MULTI_MODE*)
  2699. AllocateSystemMemory(NbSuperModes*sizeof(MULTI_MODE));
  2700. if (pCurMulti == NULL)
  2701. {
  2702. // The memory allocation failed. We won't be able to use
  2703. // our supermode list, so we'll fall back on the single-
  2704. // board code.
  2705. NbSuperModes = 0;
  2706. status = ERROR_NOT_ENOUGH_MEMORY;
  2707. return(status);
  2708. }
  2709. // And we're ready to go!
  2710. ModeInit = 0x00000000;
  2711. pulModeFlags = &MgaDeviceExtension->ModeFlags2D[0];
  2712. ulModeListOffset = 0;
  2713. MTX_INIT_MODE_LIST_LOOP:
  2714. // For each bit in our ModeFlags...
  2715. for (i = 0; i < 32; i++)
  2716. {
  2717. // Find out which boards, if any, support this
  2718. // resolution/pixel-depth.
  2719. CurrentResNbBoards = 0;
  2720. CurrentResFlags = 0;
  2721. k = 0;
  2722. for (n = 0; n < (ULONG)NbBoard; n++)
  2723. {
  2724. CurrentFlag = (pulModeFlags[n] >> i) & 1;
  2725. CurrentResNbBoards += CurrentFlag;
  2726. if (CurrentFlag)
  2727. {
  2728. // This one is valid.
  2729. usRefreshRates = MgaDeviceExtension->
  2730. ModeFreqs[n][i+ulModeListOffset];
  2731. CurrentResFlags |= (1 << n);
  2732. ValidBoard[k++] = (UCHAR)n;
  2733. }
  2734. }
  2735. // Nothing to do if no boards support this combination.
  2736. if (CurrentResNbBoards == 0)
  2737. continue;
  2738. // At least one board supports this resolution/pixel-depth.
  2739. CurrentResWidth = (ULONG)SingleWidths[i%8];
  2740. CurrentResHeight = (ULONG)SingleHeights[i%8];
  2741. CurrentPixWidth = (i/8 + 1)*8;
  2742. ulNbRefreshRates = 0;
  2743. for (j = 0; j < 16; j++)
  2744. {
  2745. if (usRefreshRates & (1 << j))
  2746. {
  2747. ulNbRefreshRates++;
  2748. }
  2749. }
  2750. ucRefreshBit = 0;
  2751. for (ir = 0; ir < ulNbRefreshRates; ir++)
  2752. {
  2753. while ((usRefreshRates & 1) == 0)
  2754. {
  2755. usRefreshRates >>= 1;
  2756. ucRefreshBit++;
  2757. }
  2758. CurrentRefreshRate = (ULONG)ConvBitToFreq(ucRefreshBit);
  2759. usRefreshRates >>= 1;
  2760. ucRefreshBit++;
  2761. // Set the 1x1 display.
  2762. pCurMulti->MulArrayWidth = 1;
  2763. pCurMulti->MulArrayHeight = 1;
  2764. pCurMulti->MulWidth = CurrentResWidth;
  2765. pCurMulti->MulHeight = CurrentResHeight;
  2766. pCurMulti->MulPixWidth = CurrentPixWidth;
  2767. pCurMulti->MulRefreshRate = CurrentRefreshRate;
  2768. // For 1x1, select the VGA-enabled board, if possible.
  2769. if (CurrentResFlags & VGABoardBit)
  2770. {
  2771. // The VGA-enabled board supports this resolution.
  2772. pCurMulti->MulBoardNb[0] = (UCHAR)VGABoard;
  2773. }
  2774. else
  2775. {
  2776. // Otherwise, pick board 0.
  2777. pCurMulti->MulBoardNb[0] = ValidBoard[0];
  2778. }
  2779. n = pCurMulti->MulBoardNb[0];
  2780. pCurMulti->MulBoardMode[0] =
  2781. MgaDeviceExtension->ModeList[n]
  2782. [i+ulModeListOffset];
  2783. // Record a pointer to the HwModeData structure.
  2784. pMgaDispMode = MgaDeviceExtension->pMgaHwModes[n];
  2785. pCurMulti->MulHwModes[0] =
  2786. &pMgaDispMode[pCurMulti->MulBoardMode[0]];
  2787. pCurMulti->MulModeNumber = ModeInit++;
  2788. pCurMulti++;
  2789. if (CurrentResNbBoards == 1)
  2790. continue;
  2791. // At least two boards support this resolution/pixel-depth.
  2792. // For each number of boards up to the maximum...
  2793. for (k = 2; k <= CurrentResNbBoards; k++)
  2794. {
  2795. // For each integer up to the maximum...
  2796. for (m = 1; m <= CurrentResNbBoards; m++)
  2797. {
  2798. if ((k % m) == 0)
  2799. {
  2800. // We can get a (k/m, m) desktop.
  2801. pCurMulti->MulArrayHeight = (USHORT)m;
  2802. pCurMulti->MulHeight = m*CurrentResHeight;
  2803. pCurMulti->MulArrayWidth = (USHORT)(k/m);
  2804. pCurMulti->MulWidth = pCurMulti->MulArrayWidth *
  2805. CurrentResWidth;
  2806. pCurMulti->MulPixWidth = CurrentPixWidth;
  2807. pCurMulti->MulRefreshRate = CurrentRefreshRate;
  2808. // Select the boards we'll be using.
  2809. // Select the VGA-enabled board as the first
  2810. // board, if possible. Except for that, we
  2811. // won't try to place the boards in any
  2812. // consistent way for now.
  2813. if (CurrentResFlags & VGABoardBit)
  2814. {
  2815. // The VGA-enabled board supports this mode.
  2816. pCurMulti->MulBoardNb[0] = (UCHAR)VGABoard;
  2817. ja = 0;
  2818. for (j = 1; j < k; j++)
  2819. {
  2820. if (ValidBoard[ja] == VGABoard)
  2821. ja++;
  2822. pCurMulti->MulBoardNb[j] =
  2823. ValidBoard[ja];
  2824. ja++;
  2825. }
  2826. }
  2827. else
  2828. {
  2829. // The VGA-enabled board won't be involved.
  2830. for (j = 0; j < k; j++)
  2831. {
  2832. pCurMulti->MulBoardNb[j] =
  2833. ValidBoard[j];
  2834. }
  2835. }
  2836. // For each board...
  2837. for (j = 0; j < k; j++)
  2838. {
  2839. // Record the hardware mode the board
  2840. // would use.
  2841. n = pCurMulti->MulBoardNb[j];
  2842. pCurMulti->MulBoardMode[j] =
  2843. MgaDeviceExtension->ModeList[n]
  2844. [i+ulModeListOffset];
  2845. // Record a ptr to the HwModeData structure.
  2846. pMgaDispMode =
  2847. MgaDeviceExtension->pMgaHwModes[n];
  2848. pCurMulti->MulHwModes[j] =
  2849. &pMgaDispMode[pCurMulti->MulBoardMode[j]];
  2850. }
  2851. pCurMulti->MulModeNumber = ModeInit++;
  2852. pCurMulti++;
  2853. } // If it's a valid desktop...
  2854. } // For each integer up to the maximum...
  2855. } // For each number of boards up to the maximum...
  2856. } // For the number of Refresh...
  2857. } // For each bit in our ModeFlags...
  2858. if (pulModeFlags == &MgaDeviceExtension->ModeFlags2D[0])
  2859. {
  2860. // We just looked at the 2D modes, now look at the 3D modes.
  2861. pulModeFlags = &MgaDeviceExtension->ModeFlags3D[0];
  2862. ulModeListOffset = 32;
  2863. goto MTX_INIT_MODE_LIST_LOOP;
  2864. }
  2865. MgaDeviceExtension->NumberOfSuperModes = NbSuperModes;
  2866. // At this point, we have a table of 'super-modes' (which includes
  2867. // all the regular modes also). All the modes in this table are
  2868. // supported, and each of them is unique. MgaDeviceExtension->
  2869. // pSuperModes points to the start of the mode list. Each entry
  2870. // in the list holds:
  2871. //
  2872. // MulModeNumber A unique mode Id
  2873. // MulWidth The total width for this mode
  2874. // MulHeight The total height for this mode
  2875. // MulPixWidth The pixel depth for this mode
  2876. // MulArrayWidth The number of boards arrayed along X
  2877. // MulArrayHeight The number of boards arrayed along Y
  2878. // MulBoardNb[n] The board numbers of the required boards
  2879. // MulBoardMode[n] The mode required from each board
  2880. // *MulHwModes[n] The pointers to the required HwModeData
  2881. //
  2882. // Moreover, MgaDeviceExtension->NumberOfSuperModes holds the
  2883. // number of entries in the list.
  2884. //DbgBreakPoint();
  2885. #if DBG
  2886. // Now display our results...
  2887. VideoDebugPrint((1, "ModeNumber Width Height PW X Y n mo pHwMode\n"));
  2888. pCurMulti = MgaDeviceExtension->pSuperModes;
  2889. for (i = 0; i < NbSuperModes; i++)
  2890. {
  2891. VideoDebugPrint((1, "0x%08x % 6d % 6d % 3d % 3d % 3d\n",
  2892. pCurMulti->MulModeNumber,
  2893. pCurMulti->MulWidth,
  2894. pCurMulti->MulHeight,
  2895. pCurMulti->MulPixWidth,
  2896. pCurMulti->MulArrayWidth,
  2897. pCurMulti->MulArrayHeight));
  2898. j = pCurMulti->MulArrayWidth * pCurMulti->MulArrayHeight;
  2899. for (n = 0; n < j; n++)
  2900. {
  2901. VideoDebugPrint((1, " %d %02x 0x%08x\n",
  2902. pCurMulti->MulBoardNb[n],
  2903. pCurMulti->MulBoardMode[n],
  2904. pCurMulti->MulHwModes[n]));
  2905. }
  2906. pCurMulti++;
  2907. }
  2908. #endif // #if DBG
  2909. }
  2910. return(status);
  2911. }
  2912. /*--------------------------------------------------------------------------*\
  2913. | VP_STATUS
  2914. | MgaSetColorLookup(
  2915. | PMGA_DEVICE_EXTENSION MgaDeviceExtension,
  2916. | PVIDEO_CLUT ClutBuffer,
  2917. | ULONG ClutBufferSize
  2918. | )
  2919. |
  2920. | Routine Description:
  2921. |
  2922. | This routine sets a specified portion of the color lookup table settings.
  2923. |
  2924. | Arguments:
  2925. |
  2926. | HwDeviceExtension - Pointer to the miniport driver's device extension.
  2927. |
  2928. | ClutBufferSize - Length of the input buffer supplied by the user.
  2929. |
  2930. | ClutBuffer - Pointer to the structure containing the color lookup table.
  2931. |
  2932. | Return Value:
  2933. |
  2934. | None.
  2935. |
  2936. \*--------------------------------------------------------------------------*/
  2937. VP_STATUS
  2938. MgaSetColorLookup(
  2939. PMGA_DEVICE_EXTENSION MgaDeviceExtension,
  2940. PVIDEO_CLUT ClutBuffer,
  2941. ULONG ClutBufferSize
  2942. )
  2943. {
  2944. ULONG ulVal;
  2945. PUCHAR pucPaletteDataReg, pucPaletteWriteReg;
  2946. LONG i, m, n, lNumEntries;
  2947. // DbgBreakPoint();
  2948. // Check if the size of the data in the input buffer is large enough.
  2949. if ( (ClutBufferSize < sizeof(VIDEO_CLUT) - sizeof(ULONG)) ||
  2950. (ClutBufferSize < sizeof(VIDEO_CLUT) +
  2951. (sizeof(ULONG) * (ClutBuffer->NumEntries - 1)) ) )
  2952. {
  2953. return ERROR_INSUFFICIENT_BUFFER;
  2954. }
  2955. // Check to see if the parameters are valid.
  2956. if ( (ClutBuffer->NumEntries == 0) ||
  2957. (ClutBuffer->FirstEntry > VIDEO_MAX_COLOR_REGISTER) ||
  2958. (ClutBuffer->FirstEntry + ClutBuffer->NumEntries >
  2959. VIDEO_MAX_COLOR_REGISTER + 1) )
  2960. {
  2961. return ERROR_INVALID_PARAMETER;
  2962. }
  2963. pucPaletteDataReg =
  2964. (PUCHAR)MgaDeviceExtension->KernelModeMappedBaseAddress[iBoard] +
  2965. PALETTE_DATA;
  2966. pucPaletteWriteReg=
  2967. (PUCHAR)MgaDeviceExtension->KernelModeMappedBaseAddress[iBoard] +
  2968. PALETTE_RAM_WRITE;
  2969. // Set CLUT registers directly on the hardware.
  2970. VideoPortWriteRegisterUchar(pucPaletteWriteReg,
  2971. (UCHAR)ClutBuffer->FirstEntry);
  2972. n = 0;
  2973. m = (LONG)ClutBuffer->NumEntries;
  2974. if (pMgaBoardData[iBoard].DacType == DacTypeTVP3026)
  2975. {
  2976. // TVP3026 cursor is very touchy.
  2977. #define TVP3026_PAL_BATCH_SIZE 64
  2978. m = TVP3026_PAL_BATCH_SIZE;
  2979. lNumEntries = (LONG)ClutBuffer->NumEntries;
  2980. while ((lNumEntries -= 64) > 0)
  2981. {
  2982. // Wait for VSYNC.
  2983. do
  2984. {
  2985. ulVal = VideoPortReadRegisterUlong((PULONG)
  2986. ((PUCHAR)pMgaBaseAddr + TITAN_OFFSET + TITAN_STATUS));
  2987. } while (!(ulVal & TITAN_VSYNCSTS_M));
  2988. for (i = n; i < m; i++)
  2989. {
  2990. VideoPortWriteRegisterUchar(pucPaletteDataReg,
  2991. (UCHAR) ClutBuffer->LookupTable[i].RgbArray.Red);
  2992. VideoPortWriteRegisterUchar(pucPaletteDataReg,
  2993. (UCHAR) ClutBuffer->LookupTable[i].RgbArray.Green);
  2994. VideoPortWriteRegisterUchar(pucPaletteDataReg,
  2995. (UCHAR) ClutBuffer->LookupTable[i].RgbArray.Blue);
  2996. }
  2997. n += TVP3026_PAL_BATCH_SIZE;
  2998. m += TVP3026_PAL_BATCH_SIZE;
  2999. }
  3000. m += lNumEntries;
  3001. // Wait for VSYNC.
  3002. do
  3003. {
  3004. ulVal = VideoPortReadRegisterUlong((PULONG)
  3005. ((PUCHAR)pMgaBaseAddr + TITAN_OFFSET + TITAN_STATUS));
  3006. } while (!(ulVal & TITAN_VSYNCSTS_M));
  3007. }
  3008. for (i = n; i < m; i++)
  3009. {
  3010. VideoPortWriteRegisterUchar(pucPaletteDataReg,
  3011. ((UCHAR) ClutBuffer->LookupTable[i].RgbArray.Red));
  3012. VideoPortWriteRegisterUchar(pucPaletteDataReg,
  3013. ((UCHAR) ClutBuffer->LookupTable[i].RgbArray.Green));
  3014. VideoPortWriteRegisterUchar(pucPaletteDataReg,
  3015. ((UCHAR) ClutBuffer->LookupTable[i].RgbArray.Blue));
  3016. }
  3017. return NO_ERROR;
  3018. } // end MgaSetColorLookup()
  3019. VOID MgaSetCursorColour(
  3020. PMGA_DEVICE_EXTENSION MgaDeviceExtension,
  3021. ULONG ulFgColour,
  3022. ULONG ulBgColour)
  3023. {
  3024. PUCHAR pucCursorDataReg, pucCursorWriteReg;
  3025. PUCHAR pucCmdRegA, pucPixRdMaskReg;
  3026. UCHAR ucOldCmdRegA, ucOldRdMask;
  3027. VideoDebugPrint((1, "MGA.SYS!MgaSetCursorColour\n"));
  3028. // DbgBreakPoint();
  3029. switch(pMgaBoardData[iBoard].DacType)
  3030. {
  3031. case DacTypeBT485:
  3032. case DacTypePX2085:
  3033. // Set cursor colour for Bt485.
  3034. pucCursorDataReg = (PUCHAR)MgaDeviceExtension->
  3035. KernelModeMappedBaseAddress[iBoard] +
  3036. RAMDAC_OFFSET + BT485_COL_OVL;
  3037. pucCursorWriteReg= (PUCHAR)MgaDeviceExtension->
  3038. KernelModeMappedBaseAddress[iBoard] +
  3039. RAMDAC_OFFSET + BT485_WADR_OVL;
  3040. VideoPortWriteRegisterUchar(pucCursorWriteReg, 1);
  3041. // Set Background Colour
  3042. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3043. (UCHAR)(ulBgColour & 0xFF));
  3044. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3045. (UCHAR)(ulBgColour>>8 & 0xFF));
  3046. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3047. (UCHAR)(ulBgColour>>16 & 0xFF));
  3048. // Set Foreground Colour
  3049. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3050. (UCHAR)(ulFgColour & 0xFF));
  3051. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3052. (UCHAR)(ulFgColour>>8 & 0xFF));
  3053. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3054. (UCHAR)(ulFgColour>>16 & 0xFF));
  3055. break;
  3056. case DacTypeBT482:
  3057. // Set cursor colour for Bt482.
  3058. pucCursorDataReg = (PUCHAR)MgaDeviceExtension->
  3059. KernelModeMappedBaseAddress[iBoard] +
  3060. RAMDAC_OFFSET + BT482_COL_OVL;
  3061. pucCmdRegA = (PUCHAR)MgaDeviceExtension->
  3062. KernelModeMappedBaseAddress[iBoard] +
  3063. RAMDAC_OFFSET + BT482_CMD_REGA;
  3064. pucPixRdMaskReg = (PUCHAR)MgaDeviceExtension->
  3065. KernelModeMappedBaseAddress[iBoard] +
  3066. RAMDAC_OFFSET + BT482_PIX_RD_MSK;
  3067. ucOldCmdRegA = VideoPortReadRegisterUchar(pucCmdRegA);
  3068. VideoPortWriteRegisterUchar(pucCmdRegA,
  3069. (UCHAR) (ucOldCmdRegA | BT482_EXT_REG_EN));
  3070. VideoPortWriteRegisterUchar((PUCHAR)MgaDeviceExtension->
  3071. KernelModeMappedBaseAddress[iBoard] +
  3072. RAMDAC_OFFSET + BT482_WADR_PAL,
  3073. BT482_CUR_REG);
  3074. ucOldRdMask = VideoPortReadRegisterUchar(pucPixRdMaskReg);
  3075. VideoPortWriteRegisterUchar(pucPixRdMaskReg, 0);
  3076. VideoPortWriteRegisterUchar((PUCHAR)MgaDeviceExtension->
  3077. KernelModeMappedBaseAddress[iBoard] +
  3078. RAMDAC_OFFSET + BT482_WADR_OVL,
  3079. 0x11);
  3080. // Set Colour 1
  3081. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3082. (UCHAR)(ulBgColour & 0xFF));
  3083. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3084. (UCHAR)(ulBgColour>>8 & 0xFF));
  3085. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3086. (UCHAR)(ulBgColour>>16 & 0xFF));
  3087. // Set Colour 2
  3088. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3089. (UCHAR)(ulFgColour & 0xFF));
  3090. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3091. (UCHAR)(ulFgColour>>8 & 0xFF));
  3092. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3093. (UCHAR)(ulFgColour>>16 & 0xFF));
  3094. // Restore old read mask and command register values
  3095. VideoPortWriteRegisterUchar((PUCHAR)MgaDeviceExtension->
  3096. KernelModeMappedBaseAddress[iBoard] +
  3097. RAMDAC_OFFSET + BT482_WADR_PAL,
  3098. BT482_CUR_REG);
  3099. VideoPortWriteRegisterUchar(pucPixRdMaskReg, ucOldRdMask);
  3100. VideoPortWriteRegisterUchar(pucCmdRegA, ucOldCmdRegA);
  3101. break;
  3102. case DacTypeVIEWPOINT:
  3103. // Set cursor colour for ViewPoint
  3104. pucCursorDataReg = (PUCHAR)MgaDeviceExtension->
  3105. KernelModeMappedBaseAddress[iBoard] +
  3106. RAMDAC_OFFSET + VPOINT_DATA;
  3107. pucCursorWriteReg= (PUCHAR)MgaDeviceExtension->
  3108. KernelModeMappedBaseAddress[iBoard] +
  3109. RAMDAC_OFFSET + VPOINT_INDEX;
  3110. // Set Background Colour
  3111. VideoPortWriteRegisterUchar(pucCursorWriteReg,VPOINT_CUR_COL0_RED);
  3112. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3113. (UCHAR)(ulBgColour & 0xFF));
  3114. VideoPortWriteRegisterUchar(pucCursorWriteReg,VPOINT_CUR_COL0_GREEN);
  3115. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3116. (UCHAR)(ulBgColour>>8 & 0xFF));
  3117. VideoPortWriteRegisterUchar(pucCursorWriteReg,VPOINT_CUR_COL0_BLUE);
  3118. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3119. (UCHAR)(ulBgColour>>16 & 0xFF));
  3120. // Set Foreground Colour
  3121. VideoPortWriteRegisterUchar(pucCursorWriteReg,VPOINT_CUR_COL1_RED);
  3122. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3123. (UCHAR)(ulFgColour & 0xFF));
  3124. VideoPortWriteRegisterUchar(pucCursorWriteReg,VPOINT_CUR_COL1_GREEN);
  3125. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3126. (UCHAR)(ulFgColour>>8 & 0xFF));
  3127. VideoPortWriteRegisterUchar(pucCursorWriteReg,VPOINT_CUR_COL1_BLUE);
  3128. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3129. (UCHAR)(ulFgColour>>16 & 0xFF));
  3130. break;
  3131. case DacTypeTVP3026:
  3132. // Set cursor colour for TVP3026
  3133. pucCursorDataReg = (PUCHAR)MgaDeviceExtension->
  3134. KernelModeMappedBaseAddress[iBoard] +
  3135. RAMDAC_OFFSET + TVP3026_CUR_COL_DATA;
  3136. pucCursorWriteReg= (PUCHAR)MgaDeviceExtension->
  3137. KernelModeMappedBaseAddress[iBoard] +
  3138. RAMDAC_OFFSET + TVP3026_CUR_COL_ADDR;
  3139. // Set Background Colour
  3140. VideoPortWriteRegisterUchar(pucCursorWriteReg,1);
  3141. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3142. (UCHAR)(ulBgColour & 0xFF));
  3143. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3144. (UCHAR)(ulBgColour>>8 & 0xFF));
  3145. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3146. (UCHAR)(ulBgColour>>16 & 0xFF));
  3147. // Set Foreground Colour
  3148. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3149. (UCHAR)(ulFgColour & 0xFF));
  3150. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3151. (UCHAR)(ulFgColour>>8 & 0xFF));
  3152. VideoPortWriteRegisterUchar(pucCursorDataReg,
  3153. (UCHAR)(ulFgColour>>16 & 0xFF));
  3154. break;
  3155. default:
  3156. break;
  3157. }
  3158. }
  3159. #if (_WIN32_WINNT >= 500)
  3160. //
  3161. // Routine to set a desired DPMS power management state.
  3162. //
  3163. VP_STATUS
  3164. MgaSetPower50(
  3165. PMGA_DEVICE_EXTENSION phwDeviceExtension,
  3166. ULONG HwDeviceId,
  3167. PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
  3168. )
  3169. {
  3170. if ((pVideoPowerMgmt->PowerState == VideoPowerOn) ||
  3171. (pVideoPowerMgmt->PowerState == VideoPowerHibernate)) {
  3172. return NO_ERROR;
  3173. } else {
  3174. return ERROR_INVALID_FUNCTION;
  3175. }
  3176. }
  3177. //
  3178. // Routine to retrieve possible DPMS power management states.
  3179. //
  3180. VP_STATUS
  3181. MgaGetPower50(
  3182. PMGA_DEVICE_EXTENSION phwDeviceExtension,
  3183. ULONG HwDeviceId,
  3184. PVIDEO_POWER_MANAGEMENT pVideoPowerMgmt
  3185. )
  3186. {
  3187. if ((pVideoPowerMgmt->PowerState == VideoPowerOn) ||
  3188. (pVideoPowerMgmt->PowerState == VideoPowerHibernate)) {
  3189. return NO_ERROR;
  3190. } else {
  3191. return ERROR_INVALID_FUNCTION;
  3192. }
  3193. }
  3194. //
  3195. // Routine to retrieve the Enhanced Display ID structure via DDC
  3196. //
  3197. ULONG
  3198. MgaGetVideoChildDescriptor(
  3199. PVOID HwDeviceExtension,
  3200. PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
  3201. PVIDEO_CHILD_TYPE pChildType,
  3202. PVOID pvChildDescriptor,
  3203. PULONG pHwId,
  3204. PULONG pUnused
  3205. )
  3206. {
  3207. PMGA_DEVICE_EXTENSION pHwDeviceExtension = HwDeviceExtension;
  3208. ULONG Status;
  3209. ASSERT(pHwDeviceExtension != NULL && pMoreChildren != NULL);
  3210. VideoDebugPrint((2, "mga.SYS mgaGetVideoChildDescriptor: *** Entry point ***\n"));
  3211. //
  3212. // Determine if the graphics adapter in the system supports
  3213. // DDC2 (our miniport only supports DDC2, not DDC1). This has
  3214. // the side effect (assuming both monitor and card support
  3215. // DDC2) of switching the monitor from DDC1 mode (repeated
  3216. // "blind" broadcast of EDID clocked by the vertical sync
  3217. // signal) to DDC2 mode (query/response not using any of the
  3218. // normal video lines - can transfer information rapidly
  3219. // without first disrupting the screen by switching into
  3220. // a pseudo-mode with a high vertical sync frequency).
  3221. //
  3222. // Since we must support hot-plugging of monitors, and our
  3223. // routine to obtain the EDID structure via DDC2 assumes that
  3224. // the monitor is in DDC2 mode, we must make this test each
  3225. // time this entry point is called.
  3226. //
  3227. switch (ChildEnumInfo->ChildIndex) {
  3228. case 0:
  3229. //
  3230. // Case 0 is used to enumerate devices found by the ACPI firmware.
  3231. //
  3232. // Since we do not support ACPI devices yet, we must return failure.
  3233. //
  3234. Status = ERROR_NO_MORE_DEVICES;
  3235. break;
  3236. case 1:
  3237. //
  3238. // We do not support monitor enumeration
  3239. //
  3240. Status = ERROR_NO_MORE_DEVICES;
  3241. break;
  3242. case DISPLAY_ADAPTER_HW_ID:
  3243. {
  3244. PUSHORT pPnpDeviceDescription = NULL;
  3245. ULONG stringSize = sizeof(L"*PNPXXXX");
  3246. //
  3247. // Special ID to handle return legacy PnP IDs for root enumerated
  3248. // devices.
  3249. //
  3250. *pChildType = VideoChip;
  3251. *pHwId = DISPLAY_ADAPTER_HW_ID;
  3252. //
  3253. // Figure out which card type and set pPnpDeviceDescription at
  3254. // associated string.
  3255. //
  3256. if (pHwDeviceExtension->BoardId == TYPE_QVISION_PCI)
  3257. pPnpDeviceDescription = L"*PNP0919";
  3258. else
  3259. pPnpDeviceDescription = L"*PNP0918";
  3260. //
  3261. // Now just copy the string into memory provided.
  3262. //
  3263. if (pPnpDeviceDescription)
  3264. memcpy(pvChildDescriptor, pPnpDeviceDescription, stringSize);
  3265. Status = ERROR_MORE_DATA;
  3266. break;
  3267. }
  3268. default:
  3269. Status = ERROR_NO_MORE_DEVICES;
  3270. break;
  3271. }
  3272. return Status;
  3273. }
  3274. #endif // _WIN32_WINNT >= 500