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

1023 lines
28 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. modeset.c
  5. Abstract:
  6. This is the modeset code for the VGA miniport driver.
  7. Environment:
  8. kernel mode only
  9. Notes:
  10. Revision History:
  11. --*/
  12. #include "dderror.h"
  13. #include "devioctl.h"
  14. #include "miniport.h"
  15. #include "ntddvdeo.h"
  16. #include "video.h"
  17. #include "vga.h"
  18. #include "vesa.h"
  19. #include "cmdcnst.h"
  20. #if defined(ALLOC_PRAGMA)
  21. #pragma alloc_text(PAGE,VgaQueryAvailableModes)
  22. #pragma alloc_text(PAGE,VgaQueryNumberOfAvailableModes)
  23. #pragma alloc_text(PAGE,VgaQueryCurrentMode)
  24. #pragma alloc_text(PAGE,VgaSetMode)
  25. #pragma alloc_text(PAGE,VgaInterpretCmdStream)
  26. #pragma alloc_text(PAGE,VgaZeroVideoMemory)
  27. #endif
  28. VP_STATUS
  29. VgaInterpretCmdStream(
  30. PHW_DEVICE_EXTENSION HwDeviceExtension,
  31. PUSHORT pusCmdStream
  32. )
  33. /*++
  34. Routine Description:
  35. Interprets the appropriate command array to set up VGA registers for the
  36. requested mode. Typically used to set the VGA into a particular mode by
  37. programming all of the registers
  38. Arguments:
  39. HwDeviceExtension - Pointer to the miniport driver's device extension.
  40. pusCmdStream - array of commands to be interpreted.
  41. Return Value:
  42. The status of the operation (can only fail on a bad command); TRUE for
  43. success, FALSE for failure.
  44. --*/
  45. {
  46. ULONG ulCmd;
  47. ULONG_PTR ulPort;
  48. UCHAR jValue;
  49. USHORT usValue;
  50. ULONG culCount;
  51. ULONG ulIndex;
  52. ULONG_PTR ulBase;
  53. if (pusCmdStream == NULL) {
  54. VideoDebugPrint((1, "VgaInterpretCmdStream - Invalid pusCmdStream\n"));
  55. return TRUE;
  56. }
  57. ulBase = (ULONG_PTR)HwDeviceExtension->IOAddress;
  58. //
  59. // Now set the adapter to the desired mode.
  60. //
  61. while ((ulCmd = *pusCmdStream++) != EOD) {
  62. //
  63. // Determine major command type
  64. //
  65. switch (ulCmd & 0xF0) {
  66. //
  67. // Basic input/output command
  68. //
  69. case INOUT:
  70. //
  71. // Determine type of inout instruction
  72. //
  73. if (!(ulCmd & IO)) {
  74. //
  75. // Out instruction. Single or multiple outs?
  76. //
  77. if (!(ulCmd & MULTI)) {
  78. //
  79. // Single out. Byte or word out?
  80. //
  81. if (!(ulCmd & BW)) {
  82. //
  83. // Single byte out
  84. //
  85. ulPort = *pusCmdStream++;
  86. jValue = (UCHAR) *pusCmdStream++;
  87. VideoPortWritePortUchar((PUCHAR)(ulBase+ulPort),
  88. jValue);
  89. } else {
  90. //
  91. // Single word out
  92. //
  93. ulPort = *pusCmdStream++;
  94. usValue = *pusCmdStream++;
  95. VideoPortWritePortUshort((PUSHORT)(ulBase+ulPort),
  96. usValue);
  97. }
  98. } else {
  99. //
  100. // Output a string of values
  101. // Byte or word outs?
  102. //
  103. if (!(ulCmd & BW)) {
  104. //
  105. // String byte outs. Do in a loop; can't use
  106. // VideoPortWritePortBufferUchar because the data
  107. // is in USHORT form
  108. //
  109. ulPort = ulBase + *pusCmdStream++;
  110. culCount = *pusCmdStream++;
  111. while (culCount--) {
  112. jValue = (UCHAR) *pusCmdStream++;
  113. VideoPortWritePortUchar((PUCHAR)ulPort,
  114. jValue);
  115. }
  116. } else {
  117. //
  118. // String word outs
  119. //
  120. ulPort = *pusCmdStream++;
  121. culCount = *pusCmdStream++;
  122. VideoPortWritePortBufferUshort((PUSHORT)
  123. (ulBase + ulPort), pusCmdStream, culCount);
  124. pusCmdStream += culCount;
  125. }
  126. }
  127. } else {
  128. // In instruction
  129. //
  130. // Currently, string in instructions aren't supported; all
  131. // in instructions are handled as single-byte ins
  132. //
  133. // Byte or word in?
  134. //
  135. if (!(ulCmd & BW)) {
  136. //
  137. // Single byte in
  138. //
  139. ulPort = *pusCmdStream++;
  140. jValue = VideoPortReadPortUchar((PUCHAR)ulBase+ulPort);
  141. } else {
  142. //
  143. // Single word in
  144. //
  145. ulPort = *pusCmdStream++;
  146. usValue = VideoPortReadPortUshort((PUSHORT)
  147. (ulBase+ulPort));
  148. }
  149. }
  150. break;
  151. //
  152. // Higher-level input/output commands
  153. //
  154. case METAOUT:
  155. //
  156. // Determine type of metaout command, based on minor
  157. // command field
  158. //
  159. switch (ulCmd & 0x0F) {
  160. //
  161. // Indexed outs
  162. //
  163. case INDXOUT:
  164. ulPort = ulBase + *pusCmdStream++;
  165. culCount = *pusCmdStream++;
  166. ulIndex = *pusCmdStream++;
  167. while (culCount--) {
  168. usValue = (USHORT) (ulIndex +
  169. (((ULONG)(*pusCmdStream++)) << 8));
  170. VideoPortWritePortUshort((PUSHORT)ulPort, usValue);
  171. ulIndex++;
  172. }
  173. break;
  174. //
  175. // Masked out (read, AND, XOR, write)
  176. //
  177. case MASKOUT:
  178. ulPort = *pusCmdStream++;
  179. jValue = VideoPortReadPortUchar((PUCHAR)ulBase+ulPort);
  180. jValue &= *pusCmdStream++;
  181. jValue ^= *pusCmdStream++;
  182. VideoPortWritePortUchar((PUCHAR)ulBase + ulPort,
  183. jValue);
  184. break;
  185. //
  186. // Attribute Controller out
  187. //
  188. case ATCOUT:
  189. ulPort = ulBase + *pusCmdStream++;
  190. culCount = *pusCmdStream++;
  191. ulIndex = *pusCmdStream++;
  192. while (culCount--) {
  193. // Write Attribute Controller index
  194. VideoPortWritePortUchar((PUCHAR)ulPort,
  195. (UCHAR)ulIndex);
  196. // Write Attribute Controller data
  197. jValue = (UCHAR) *pusCmdStream++;
  198. VideoPortWritePortUchar((PUCHAR)ulPort, jValue);
  199. ulIndex++;
  200. }
  201. break;
  202. //
  203. // None of the above; error
  204. //
  205. default:
  206. return FALSE;
  207. }
  208. break;
  209. //
  210. // NOP
  211. //
  212. case NCMD:
  213. break;
  214. //
  215. // Unknown command; error
  216. //
  217. default:
  218. return FALSE;
  219. }
  220. }
  221. return TRUE;
  222. } // end VgaInterpretCmdStream()
  223. VP_STATUS
  224. VgaSetMode(
  225. PHW_DEVICE_EXTENSION HwDeviceExtension,
  226. PVIDEO_MODE Mode,
  227. ULONG ModeSize,
  228. PULONG FrameBufferIsMoved
  229. )
  230. /*++
  231. Routine Description:
  232. This routine sets the VGA into the requested mode.
  233. Arguments:
  234. HwDeviceExtension - Pointer to the miniport driver's device extension.
  235. Mode - Pointer to the structure containing the information about the
  236. font to be set.
  237. ModeSize - Length of the input buffer supplied by the user.
  238. Return Value:
  239. ERROR_INSUFFICIENT_BUFFER if the input buffer was not large enough
  240. for the input data.
  241. ERROR_INVALID_PARAMETER if the mode number is invalid.
  242. NO_ERROR if the operation completed successfully.
  243. --*/
  244. {
  245. PVIDEOMODE pRequestedMode;
  246. //
  247. // Check if the size of the data in the input buffer is large enough.
  248. //
  249. if (ModeSize < sizeof(VIDEO_MODE)) {
  250. return ERROR_INSUFFICIENT_BUFFER;
  251. }
  252. *FrameBufferIsMoved = 0;
  253. //
  254. // Extract the clear memory bit.
  255. //
  256. if (Mode->RequestedMode & VIDEO_MODE_NO_ZERO_MEMORY) {
  257. Mode->RequestedMode &= ~VIDEO_MODE_NO_ZERO_MEMORY;
  258. } else {
  259. if (IS_LINEAR_MODE(&VgaModeList[Mode->RequestedMode]) == FALSE) {
  260. VgaZeroVideoMemory(HwDeviceExtension);
  261. }
  262. }
  263. //
  264. // Check to see if we are requesting a vlid mode
  265. //
  266. if (Mode->RequestedMode >= NumVideoModes) {
  267. ASSERT(FALSE);
  268. return ERROR_INVALID_PARAMETER;
  269. }
  270. pRequestedMode = &VgaModeList[Mode->RequestedMode];
  271. #ifdef INT10_MODE_SET
  272. {
  273. VIDEO_X86_BIOS_ARGUMENTS biosArguments;
  274. UCHAR temp;
  275. UCHAR dummy;
  276. UCHAR bIsColor;
  277. ULONG modeNumber;
  278. VP_STATUS status;
  279. VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  280. modeNumber = pRequestedMode->Int10ModeNumber;
  281. VideoDebugPrint((1, "Setting Mode: (%d,%d) @ %d bpp\n",
  282. pRequestedMode->hres,
  283. pRequestedMode->vres,
  284. pRequestedMode->bitsPerPlane * pRequestedMode->numPlanes));
  285. biosArguments.Eax = modeNumber & 0x0000FFFF;
  286. biosArguments.Ebx = modeNumber >> 16;
  287. status = VideoPortInt10(HwDeviceExtension, &biosArguments);
  288. if (status != NO_ERROR) {
  289. // HACK: If the resolution we tried to set was 640x480x4 we probably
  290. // have uncompatible basic VGA device like early McKinley so trying
  291. // other way
  292. ASSERT(FALSE);
  293. if (status == ERROR_INVALID_FUNCTION) { // HAL call failed
  294. if (!(pRequestedMode->CmdStrings &&
  295. VgaInterpretCmdStream(HwDeviceExtension, pRequestedMode->CmdStrings))) {
  296. return status;
  297. }
  298. }
  299. else {
  300. return status;
  301. }
  302. }
  303. else {
  304. //
  305. // If this was the VESA mode modeset, check the return value in eax
  306. //
  307. if (modeNumber >> 16) {
  308. if (!VESA_SUCCESS(biosArguments.Eax)) {
  309. VideoDebugPrint((0, "Mode set failed! AX = 0x%x\n", biosArguments.Eax));
  310. return ERROR_INVALID_PARAMETER;
  311. }
  312. //
  313. // Double check if the current mode is the mode we just set.
  314. // This is to workaround the BIOS problem of some cards.
  315. //
  316. biosArguments.Eax = 0x4F03;
  317. status = VideoPortInt10(HwDeviceExtension, &biosArguments);
  318. if ( (status == NO_ERROR) &&
  319. (VESA_SUCCESS(biosArguments.Eax)) &&
  320. ((biosArguments.Ebx & 0x1FF) != ((modeNumber >> 16) & 0x1FF))) {
  321. VideoDebugPrint((0, "VGA: The BIOS of this video card is buggy!\n"));
  322. return ERROR_INVALID_PARAMETER;
  323. }
  324. //
  325. // Set the scan line width if we are stretching scan lines to avoid
  326. // broken rasters.
  327. //
  328. if (pRequestedMode->PixelsPerScan != pRequestedMode->hres) {
  329. VideoDebugPrint((1, "Setting scan line length to %d pixels\n",
  330. pRequestedMode->PixelsPerScan));
  331. biosArguments.Eax = 0x4f06;
  332. biosArguments.Ebx = 0x00;
  333. biosArguments.Ecx = pRequestedMode->PixelsPerScan;
  334. status = VideoPortInt10(HwDeviceExtension, &biosArguments);
  335. if ((status != NO_ERROR) ||
  336. !(VESA_SUCCESS(biosArguments.Eax)) ||
  337. ((biosArguments.Ecx & 0xFFFF) != pRequestedMode->PixelsPerScan)) {
  338. VideoDebugPrint((1, "Scan line status: eax = 0x%x\n", biosArguments.Eax));
  339. return ERROR_INVALID_PARAMETER;
  340. }
  341. }
  342. }
  343. //
  344. // If we are trying to go into mode X, then we are now in
  345. // 320x200 256 color mode. Now let's finish the modeset
  346. // into MODE X.
  347. //
  348. if (pRequestedMode->hres == 320) {
  349. if ((pRequestedMode->vres == 240) || (pRequestedMode->vres == 480)) {
  350. VgaInterpretCmdStream(HwDeviceExtension, ModeX240);
  351. } else if ((pRequestedMode->vres == 200) || (pRequestedMode->vres == 400)) {
  352. VgaInterpretCmdStream(HwDeviceExtension, ModeX200);
  353. }
  354. if ((pRequestedMode->vres == 400) || (pRequestedMode->vres == 480)) {
  355. VgaInterpretCmdStream(HwDeviceExtension, ModeXDoubleScans);
  356. }
  357. }
  358. //
  359. // Fix to get 640x350 text mode
  360. //
  361. if (!(pRequestedMode->fbType & VIDEO_MODE_GRAPHICS)) {
  362. if ((pRequestedMode->hres == 640) &&
  363. (pRequestedMode->vres == 350)) {
  364. VgaInterpretCmdStream(HwDeviceExtension, VGA_TEXT_1);
  365. } else {
  366. //
  367. // Fix to make sure we always set the colors in text mode to be
  368. // intensity, and not flashing
  369. // For this zero out the Mode Control Regsiter bit 3 (index 0x10
  370. // of the Attribute controller).
  371. //
  372. if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  373. MISC_OUTPUT_REG_READ_PORT) & 0x01) {
  374. bIsColor = TRUE;
  375. } else {
  376. bIsColor = FALSE;
  377. }
  378. if (bIsColor) {
  379. dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  380. INPUT_STATUS_1_COLOR);
  381. } else {
  382. dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  383. INPUT_STATUS_1_MONO);
  384. }
  385. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  386. ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE));
  387. temp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  388. ATT_DATA_READ_PORT);
  389. temp &= 0xF7;
  390. if (bIsColor) {
  391. dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  392. INPUT_STATUS_1_COLOR);
  393. } else {
  394. dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  395. INPUT_STATUS_1_MONO);
  396. }
  397. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  398. ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE));
  399. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  400. ATT_DATA_WRITE_PORT, temp);
  401. }
  402. }
  403. #if !defined(PLUG_AND_PLAY)
  404. {
  405. //
  406. // Retrieve the base address again. This is to handle the case
  407. // when pci reprograms the bar. This should only happen on the
  408. // legacy version of vga driver
  409. //
  410. ULONG MemoryBase;
  411. MemoryBase = GetVideoMemoryBaseAddress(HwDeviceExtension, pRequestedMode);
  412. if (MemoryBase && pRequestedMode->MemoryBase != MemoryBase) {
  413. *FrameBufferIsMoved = 1;
  414. pRequestedMode->MemoryBase = MemoryBase;
  415. }
  416. }
  417. #endif
  418. }
  419. }
  420. #else
  421. VgaInterpretCmdStream(HwDeviceExtension, pRequestedMode->CmdStrings);
  422. #endif
  423. //
  424. // Update the location of the physical frame buffer within video memory.
  425. //
  426. HwDeviceExtension->PhysicalVideoMemoryBase.LowPart =
  427. pRequestedMode->MemoryBase;
  428. HwDeviceExtension->PhysicalVideoMemoryLength =
  429. pRequestedMode->MemoryLength;
  430. HwDeviceExtension->PhysicalFrameBaseOffset.LowPart =
  431. pRequestedMode->FrameOffset;
  432. HwDeviceExtension->PhysicalFrameLength =
  433. pRequestedMode->FrameLength;
  434. //
  435. // Store the new mode value.
  436. //
  437. HwDeviceExtension->CurrentMode = pRequestedMode;
  438. HwDeviceExtension->ModeIndex = Mode->RequestedMode;
  439. return NO_ERROR;
  440. } //end VgaSetMode()
  441. VP_STATUS
  442. VgaQueryAvailableModes(
  443. PHW_DEVICE_EXTENSION HwDeviceExtension,
  444. PVIDEO_MODE_INFORMATION ModeInformation,
  445. ULONG ModeInformationSize,
  446. PULONG OutputSize
  447. )
  448. /*++
  449. Routine Description:
  450. This routine returns the list of all available available modes on the
  451. card.
  452. Arguments:
  453. HwDeviceExtension - Pointer to the miniport driver's device extension.
  454. ModeInformation - Pointer to the output buffer supplied by the user.
  455. This is where the list of all valid modes is stored.
  456. ModeInformationSize - Length of the output buffer supplied by the user.
  457. OutputSize - Pointer to a buffer in which to return the actual size of
  458. the data in the buffer. If the buffer was not large enough, this
  459. contains the minimum required buffer size.
  460. Return Value:
  461. ERROR_INSUFFICIENT_BUFFER if the output buffer was not large enough
  462. for the data being returned.
  463. NO_ERROR if the operation completed successfully.
  464. --*/
  465. {
  466. PVIDEO_MODE_INFORMATION videoModes = ModeInformation;
  467. ULONG i;
  468. UNREFERENCED_PARAMETER(HwDeviceExtension);
  469. //
  470. // Find out the size of the data to be put in the buffer and return
  471. // that in the status information (whether or not the information is
  472. // there). If the buffer passed in is not large enough return an
  473. // appropriate error code.
  474. //
  475. if (ModeInformationSize < (*OutputSize =
  476. NumVideoModes * sizeof(VIDEO_MODE_INFORMATION)) ) {
  477. return ERROR_INSUFFICIENT_BUFFER;
  478. }
  479. //
  480. // For each mode supported by the card, store the mode characteristics
  481. // in the output buffer.
  482. //
  483. for (i = 0; i < NumVideoModes; i++, videoModes++) {
  484. videoModes->Length = sizeof(VIDEO_MODE_INFORMATION);
  485. videoModes->ModeIndex = i;
  486. videoModes->VisScreenWidth = VgaModeList[i].hres;
  487. videoModes->ScreenStride = VgaModeList[i].wbytes;
  488. videoModes->VisScreenHeight = VgaModeList[i].vres;
  489. videoModes->NumberOfPlanes = VgaModeList[i].numPlanes;
  490. videoModes->BitsPerPlane = VgaModeList[i].bitsPerPlane;
  491. videoModes->Frequency = VgaModeList[i].frequency;
  492. videoModes->XMillimeter = 320; // temporary hardcoded constant
  493. videoModes->YMillimeter = 240; // temporary hardcoded constant
  494. if (VgaModeList[i].bitsPerPlane < 15) {
  495. videoModes->NumberRedBits = 6;
  496. videoModes->NumberGreenBits = 6;
  497. videoModes->NumberBlueBits = 6;
  498. videoModes->RedMask = 0;
  499. videoModes->GreenMask = 0;
  500. videoModes->BlueMask = 0;
  501. } else if (VgaModeList[i].bitsPerPlane == 15) {
  502. videoModes->NumberRedBits = 6;
  503. videoModes->NumberGreenBits = 6;
  504. videoModes->NumberBlueBits = 6;
  505. videoModes->RedMask = 0x1F << 10;
  506. videoModes->GreenMask = 0x1F << 5;
  507. videoModes->BlueMask = 0x1F;
  508. } else if (VgaModeList[i].bitsPerPlane == 16) {
  509. videoModes->NumberRedBits = 6;
  510. videoModes->NumberGreenBits = 6;
  511. videoModes->NumberBlueBits = 6;
  512. videoModes->RedMask = 0x1F << 11;
  513. videoModes->GreenMask = 0x3F << 5;
  514. videoModes->BlueMask = 0x1F;
  515. } else {
  516. videoModes->NumberRedBits = 8;
  517. videoModes->NumberGreenBits = 8;
  518. videoModes->NumberBlueBits = 8;
  519. videoModes->RedMask = 0xff0000;
  520. videoModes->GreenMask = 0x00ff00;
  521. videoModes->BlueMask = 0x0000ff;
  522. }
  523. videoModes->AttributeFlags = VgaModeList[i].fbType |
  524. VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
  525. }
  526. return NO_ERROR;
  527. } // end VgaGetAvailableModes()
  528. VP_STATUS
  529. VgaQueryNumberOfAvailableModes(
  530. PHW_DEVICE_EXTENSION HwDeviceExtension,
  531. PVIDEO_NUM_MODES NumModes,
  532. ULONG NumModesSize,
  533. PULONG OutputSize
  534. )
  535. /*++
  536. Routine Description:
  537. This routine returns the number of available modes for this particular
  538. video card.
  539. Arguments:
  540. HwDeviceExtension - Pointer to the miniport driver's device extension.
  541. NumModes - Pointer to the output buffer supplied by the user. This is
  542. where the number of modes is stored.
  543. NumModesSize - Length of the output buffer supplied by the user.
  544. OutputSize - Pointer to a buffer in which to return the actual size of
  545. the data in the buffer.
  546. Return Value:
  547. ERROR_INSUFFICIENT_BUFFER if the output buffer was not large enough
  548. for the data being returned.
  549. NO_ERROR if the operation completed successfully.
  550. --*/
  551. {
  552. UNREFERENCED_PARAMETER(HwDeviceExtension);
  553. //
  554. // Find out the size of the data to be put in the the buffer and return
  555. // that in the status information (whether or not the information is
  556. // there). If the buffer passed in is not large enough return an
  557. // appropriate error code.
  558. //
  559. if (NumModesSize < (*OutputSize = sizeof(VIDEO_NUM_MODES)) ) {
  560. return ERROR_INSUFFICIENT_BUFFER;
  561. }
  562. //
  563. // Store the number of modes into the buffer.
  564. //
  565. NumModes->NumModes = NumVideoModes;
  566. NumModes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
  567. return NO_ERROR;
  568. } // end VgaGetNumberOfAvailableModes()
  569. VP_STATUS
  570. VgaQueryCurrentMode(
  571. PHW_DEVICE_EXTENSION HwDeviceExtension,
  572. PVIDEO_MODE_INFORMATION ModeInformation,
  573. ULONG ModeInformationSize,
  574. PULONG OutputSize
  575. )
  576. /*++
  577. Routine Description:
  578. This routine returns a description of the current video mode.
  579. Arguments:
  580. HwDeviceExtension - Pointer to the miniport driver's device extension.
  581. ModeInformation - Pointer to the output buffer supplied by the user.
  582. This is where the current mode information is stored.
  583. ModeInformationSize - Length of the output buffer supplied by the user.
  584. OutputSize - Pointer to a buffer in which to return the actual size of
  585. the data in the buffer. If the buffer was not large enough, this
  586. contains the minimum required buffer size.
  587. Return Value:
  588. ERROR_INSUFFICIENT_BUFFER if the output buffer was not large enough
  589. for the data being returned.
  590. NO_ERROR if the operation completed successfully.
  591. --*/
  592. {
  593. //
  594. //
  595. // check if a mode has been set
  596. //
  597. if (HwDeviceExtension->CurrentMode == NULL) {
  598. return ERROR_INVALID_FUNCTION;
  599. }
  600. //
  601. // Find out the size of the data to be put in the the buffer and return
  602. // that in the status information (whether or not the information is
  603. // there). If the buffer passed in is not large enough return an
  604. // appropriate error code.
  605. //
  606. if (ModeInformationSize < (*OutputSize = sizeof(VIDEO_MODE_INFORMATION))) {
  607. return ERROR_INSUFFICIENT_BUFFER;
  608. }
  609. //
  610. // Store the characteristics of the current mode into the buffer.
  611. //
  612. ModeInformation->Length = sizeof(VIDEO_MODE_INFORMATION);
  613. ModeInformation->ModeIndex = HwDeviceExtension->ModeIndex;
  614. ModeInformation->VisScreenWidth = HwDeviceExtension->CurrentMode->hres;
  615. ModeInformation->ScreenStride = HwDeviceExtension->CurrentMode->wbytes;
  616. ModeInformation->VisScreenHeight = HwDeviceExtension->CurrentMode->vres;
  617. ModeInformation->NumberOfPlanes = HwDeviceExtension->CurrentMode->numPlanes;
  618. ModeInformation->BitsPerPlane = HwDeviceExtension->CurrentMode->bitsPerPlane;
  619. ModeInformation->Frequency = HwDeviceExtension->CurrentMode->frequency;
  620. ModeInformation->XMillimeter = 320; // temporary hardcoded constant
  621. ModeInformation->YMillimeter = 240; // temporary hardcoded constant
  622. if (HwDeviceExtension->CurrentMode->bitsPerPlane < 15) {
  623. ModeInformation->NumberRedBits = 6;
  624. ModeInformation->NumberGreenBits = 6;
  625. ModeInformation->NumberBlueBits = 6;
  626. ModeInformation->RedMask = 0;
  627. ModeInformation->GreenMask = 0;
  628. ModeInformation->BlueMask = 0;
  629. } else if (HwDeviceExtension->CurrentMode->bitsPerPlane == 15) {
  630. ModeInformation->NumberRedBits = 6;
  631. ModeInformation->NumberGreenBits = 6;
  632. ModeInformation->NumberBlueBits = 6;
  633. ModeInformation->RedMask = 0x1F << 10;
  634. ModeInformation->GreenMask = 0x1F << 5;
  635. ModeInformation->BlueMask = 0x1F;
  636. } else if (HwDeviceExtension->CurrentMode->bitsPerPlane == 16) {
  637. ModeInformation->NumberRedBits = 6;
  638. ModeInformation->NumberGreenBits = 6;
  639. ModeInformation->NumberBlueBits = 6;
  640. ModeInformation->RedMask = 0x1F << 11;
  641. ModeInformation->GreenMask = 0x3F << 5;
  642. ModeInformation->BlueMask = 0x1F;
  643. } else {
  644. ModeInformation->NumberRedBits = 8;
  645. ModeInformation->NumberGreenBits = 8;
  646. ModeInformation->NumberBlueBits = 8;
  647. ModeInformation->RedMask = 0xff0000;
  648. ModeInformation->GreenMask = 0x00ff00;
  649. ModeInformation->BlueMask = 0x0000ff;
  650. }
  651. ModeInformation->AttributeFlags = HwDeviceExtension->CurrentMode->fbType |
  652. VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
  653. return NO_ERROR;
  654. } // end VgaQueryCurrentMode()
  655. VOID
  656. VgaZeroVideoMemory(
  657. PHW_DEVICE_EXTENSION HwDeviceExtension
  658. )
  659. /*++
  660. Routine Description:
  661. This routine zeros the first 256K on the VGA.
  662. Arguments:
  663. HwDeviceExtension - Pointer to the miniport driver's device extension.
  664. Return Value:
  665. None.
  666. --*/
  667. {
  668. UCHAR temp;
  669. //
  670. // Map font buffer at A0000
  671. //
  672. // We need the 2 calls below to VideoPortStallExecution because on
  673. // some old cards the machine would hard hang without this delay.
  674. //
  675. VgaInterpretCmdStream(HwDeviceExtension, EnableA000Data);
  676. VideoPortStallExecution(25);
  677. //
  678. // Enable all planes.
  679. //
  680. VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_ADDRESS_PORT,
  681. IND_MAP_MASK);
  682. temp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  683. SEQ_DATA_PORT) | (UCHAR)0x0F;
  684. VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_DATA_PORT,
  685. temp);
  686. //
  687. // Zero the memory.
  688. //
  689. VideoPortZeroDeviceMemory(HwDeviceExtension->VideoMemoryAddress, 0xFFFF);
  690. VideoPortStallExecution(25);
  691. VgaInterpretCmdStream(HwDeviceExtension, DisableA000Color);
  692. }