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.

1988 lines
50 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. modeset.c
  5. Abstract:
  6. This is the modeset code for the et4000 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 "et4000.h"
  18. #include "cmdcnst.h"
  19. VP_STATUS
  20. VgaInterpretCmdStream(
  21. PHW_DEVICE_EXTENSION HwDeviceExtension,
  22. PUSHORT pusCmdStream
  23. );
  24. VP_STATUS
  25. VgaSetMode(
  26. PHW_DEVICE_EXTENSION HwDeviceExtension,
  27. PVIDEO_MODE Mode,
  28. ULONG ModeSize
  29. );
  30. VP_STATUS
  31. VgaQueryAvailableModes(
  32. PHW_DEVICE_EXTENSION HwDeviceExtension,
  33. PVIDEO_MODE_INFORMATION ModeInformation,
  34. ULONG ModeInformationSize,
  35. PULONG OutputSize
  36. );
  37. VP_STATUS
  38. VgaQueryNumberOfAvailableModes(
  39. PHW_DEVICE_EXTENSION HwDeviceExtension,
  40. PVIDEO_NUM_MODES NumModes,
  41. ULONG NumModesSize,
  42. PULONG OutputSize
  43. );
  44. VP_STATUS
  45. VgaQueryCurrentMode(
  46. PHW_DEVICE_EXTENSION HwDeviceExtension,
  47. PVIDEO_MODE_INFORMATION ModeInformation,
  48. ULONG ModeInformationSize,
  49. PULONG OutputSize
  50. );
  51. VOID
  52. VgaZeroVideoMemory(
  53. PHW_DEVICE_EXTENSION HwDeviceExtension
  54. );
  55. VOID
  56. VgaValidateModes(
  57. PHW_DEVICE_EXTENSION HwDeviceExtension
  58. );
  59. #if defined(ALLOC_PRAGMA)
  60. #pragma alloc_text(PAGE,VgaInterpretCmdStream)
  61. #pragma alloc_text(PAGE,VgaSetMode)
  62. #pragma alloc_text(PAGE,VgaQueryAvailableModes)
  63. #pragma alloc_text(PAGE,VgaQueryNumberOfAvailableModes)
  64. #pragma alloc_text(PAGE,VgaQueryCurrentMode)
  65. #pragma alloc_text(PAGE,VgaZeroVideoMemory)
  66. #pragma alloc_text(PAGE,VgaValidateModes)
  67. #endif
  68. VP_STATUS
  69. VgaInterpretCmdStream(
  70. PHW_DEVICE_EXTENSION HwDeviceExtension,
  71. PUSHORT pusCmdStream
  72. )
  73. /*++
  74. Routine Description:
  75. Interprets the appropriate command array to set up VGA registers for the
  76. requested mode. Typically used to set the VGA into a particular mode by
  77. programming all of the registers
  78. Arguments:
  79. HwDeviceExtension - Pointer to the miniport driver's device extension.
  80. pusCmdStream - array of commands to be interpreted.
  81. Return Value:
  82. The status of the operation (can only fail on a bad command); TRUE for
  83. success, FALSE for failure.
  84. --*/
  85. {
  86. ULONG ulCmd;
  87. ULONG ulPort;
  88. UCHAR jValue;
  89. USHORT usValue;
  90. ULONG culCount;
  91. ULONG ulIndex;
  92. ULONG ulBase;
  93. if (pusCmdStream == NULL) {
  94. VideoDebugPrint((1, "VgaInterpretCmdStream - Invalid pusCmdStream\n"));
  95. return TRUE;
  96. }
  97. ulBase = (ULONG)HwDeviceExtension->IOAddress;
  98. //
  99. // Now set the adapter to the desired mode.
  100. //
  101. while ((ulCmd = *pusCmdStream++) != EOD) {
  102. //
  103. // Determine major command type
  104. //
  105. switch (ulCmd & 0xF0) {
  106. //
  107. // Basic input/output command
  108. //
  109. case INOUT:
  110. //
  111. // Determine type of inout instruction
  112. //
  113. if (!(ulCmd & IO)) {
  114. //
  115. // Out instruction. Single or multiple outs?
  116. //
  117. if (!(ulCmd & MULTI)) {
  118. //
  119. // Single out. Byte or word out?
  120. //
  121. if (!(ulCmd & BW)) {
  122. //
  123. // Single byte out
  124. //
  125. ulPort = *pusCmdStream++;
  126. jValue = (UCHAR) *pusCmdStream++;
  127. VideoPortWritePortUchar((PUCHAR)(ulBase+ulPort),
  128. jValue);
  129. } else {
  130. //
  131. // Single word out
  132. //
  133. ulPort = *pusCmdStream++;
  134. usValue = *pusCmdStream++;
  135. VideoPortWritePortUshort((PUSHORT)(ulBase+ulPort),
  136. usValue);
  137. }
  138. } else {
  139. //
  140. // Output a string of values
  141. // Byte or word outs?
  142. //
  143. if (!(ulCmd & BW)) {
  144. //
  145. // String byte outs. Do in a loop; can't use
  146. // VideoPortWritePortBufferUchar because the data
  147. // is in USHORT form
  148. //
  149. ulPort = ulBase + *pusCmdStream++;
  150. culCount = *pusCmdStream++;
  151. while (culCount--) {
  152. jValue = (UCHAR) *pusCmdStream++;
  153. VideoPortWritePortUchar((PUCHAR)ulPort,
  154. jValue);
  155. }
  156. } else {
  157. //
  158. // String word outs
  159. //
  160. ulPort = *pusCmdStream++;
  161. culCount = *pusCmdStream++;
  162. VideoPortWritePortBufferUshort((PUSHORT)
  163. (ulBase + ulPort), pusCmdStream, culCount);
  164. pusCmdStream += culCount;
  165. }
  166. }
  167. } else {
  168. // In instruction
  169. //
  170. // Currently, string in instructions aren't supported; all
  171. // in instructions are handled as single-byte ins
  172. //
  173. // Byte or word in?
  174. //
  175. if (!(ulCmd & BW)) {
  176. //
  177. // Single byte in
  178. //
  179. ulPort = *pusCmdStream++;
  180. jValue = VideoPortReadPortUchar((PUCHAR)ulBase+ulPort);
  181. } else {
  182. //
  183. // Single word in
  184. //
  185. ulPort = *pusCmdStream++;
  186. usValue = VideoPortReadPortUshort((PUSHORT)
  187. (ulBase+ulPort));
  188. }
  189. }
  190. break;
  191. //
  192. // Higher-level input/output commands
  193. //
  194. case METAOUT:
  195. //
  196. // Determine type of metaout command, based on minor
  197. // command field
  198. //
  199. switch (ulCmd & 0x0F) {
  200. //
  201. // Indexed outs
  202. //
  203. case INDXOUT:
  204. ulPort = ulBase + *pusCmdStream++;
  205. culCount = *pusCmdStream++;
  206. ulIndex = *pusCmdStream++;
  207. while (culCount--) {
  208. usValue = (USHORT) (ulIndex +
  209. (((ULONG)(*pusCmdStream++)) << 8));
  210. VideoPortWritePortUshort((PUSHORT)ulPort, usValue);
  211. ulIndex++;
  212. }
  213. break;
  214. //
  215. // Masked out (read, AND, XOR, write)
  216. //
  217. case MASKOUT:
  218. ulPort = *pusCmdStream++;
  219. jValue = VideoPortReadPortUchar((PUCHAR)ulBase+ulPort);
  220. jValue &= *pusCmdStream++;
  221. jValue ^= *pusCmdStream++;
  222. VideoPortWritePortUchar((PUCHAR)ulBase + ulPort,
  223. jValue);
  224. break;
  225. //
  226. // Attribute Controller out
  227. //
  228. case ATCOUT:
  229. ulPort = ulBase + *pusCmdStream++;
  230. culCount = *pusCmdStream++;
  231. ulIndex = *pusCmdStream++;
  232. while (culCount--) {
  233. // Write Attribute Controller index
  234. VideoPortWritePortUchar((PUCHAR)ulPort,
  235. (UCHAR)ulIndex);
  236. // Write Attribute Controller data
  237. jValue = (UCHAR) *pusCmdStream++;
  238. VideoPortWritePortUchar((PUCHAR)ulPort, jValue);
  239. ulIndex++;
  240. }
  241. break;
  242. //
  243. // None of the above; error
  244. //
  245. default:
  246. return FALSE;
  247. }
  248. break;
  249. //
  250. // NOP
  251. //
  252. case NCMD:
  253. break;
  254. //
  255. // Unknown command; error
  256. //
  257. default:
  258. return FALSE;
  259. }
  260. }
  261. return TRUE;
  262. } // end VgaInterpretCmdStream()
  263. VP_STATUS
  264. VgaSetMode(
  265. PHW_DEVICE_EXTENSION HwDeviceExtension,
  266. PVIDEO_MODE Mode,
  267. ULONG ModeSize
  268. )
  269. /*++
  270. Routine Description:
  271. This routine sets the vga into the requested mode.
  272. Arguments:
  273. HwDeviceExtension - Pointer to the miniport driver's device extension.
  274. Mode - Pointer to the structure containing the information about the
  275. font to be set.
  276. ModeSize - Length of the input buffer supplied by the user.
  277. Return Value:
  278. ERROR_INSUFFICIENT_BUFFER if the input buffer was not large enough
  279. for the input data.
  280. ERROR_INVALID_PARAMETER if the mode number is invalid.
  281. NO_ERROR if the operation completed successfully.
  282. --*/
  283. {
  284. PVIDEOMODE pRequestedMode;
  285. VP_STATUS status;
  286. USHORT usDataSet, usTemp, usDataClr;
  287. PUSHORT pBios = NULL;
  288. VIDEO_X86_BIOS_ARGUMENTS biosArguments;
  289. VideoDebugPrint((1, "VgaSetMode - entry\n"));
  290. //
  291. // Check if the size of the data in the input buffer is large enough.
  292. //
  293. if (ModeSize < sizeof(VIDEO_MODE)) {
  294. VideoDebugPrint((1, "VgaSetMode - ERROR_INSUFFICIENT_BUFFER\n"));
  295. return ERROR_INSUFFICIENT_BUFFER;
  296. }
  297. //
  298. // Extract the map linear bits.
  299. //
  300. HwDeviceExtension->bInLinearMode = FALSE;
  301. if (Mode->RequestedMode & VIDEO_MODE_MAP_MEM_LINEAR)
  302. {
  303. if (!HwDeviceExtension->bLinearModeSupported)
  304. {
  305. return ERROR_INVALID_PARAMETER;
  306. }
  307. else
  308. {
  309. HwDeviceExtension->bInLinearMode = TRUE;
  310. Mode->RequestedMode &= ~VIDEO_MODE_MAP_MEM_LINEAR;
  311. }
  312. }
  313. //
  314. // Extract the clear memory bit.
  315. //
  316. if (Mode->RequestedMode & VIDEO_MODE_NO_ZERO_MEMORY) {
  317. Mode->RequestedMode &= ~VIDEO_MODE_NO_ZERO_MEMORY;
  318. } else {
  319. VgaZeroVideoMemory(HwDeviceExtension);
  320. }
  321. //
  322. // Check to see if we are requesting a valid mode
  323. //
  324. if ( (Mode->RequestedMode >= NumVideoModes) ||
  325. (!ModesVGA[Mode->RequestedMode].ValidMode) ) {
  326. VideoDebugPrint((1, "VgaSetMode - ERROR_INVALID_PARAMETER\n"));
  327. return ERROR_INVALID_PARAMETER;
  328. }
  329. pRequestedMode = &ModesVGA[Mode->RequestedMode];
  330. //
  331. // If the chip is a W32 and it's not a planar color so we're using the
  332. // accelerated W32 driver. We don't want stretched scans for that driver,
  333. // so... No stretched scans!
  334. //
  335. if ((HwDeviceExtension->ulChipID >= W32) &&
  336. (pRequestedMode->bitsPerPlane != 1)) {
  337. pRequestedMode->wbytes = (pRequestedMode->hres *
  338. pRequestedMode->bitsPerPlane *
  339. pRequestedMode->numPlanes) >> 3;
  340. pRequestedMode->CmdStrings = NULL;
  341. }
  342. //
  343. // Set the vertical refresh frequency
  344. //
  345. //
  346. // This code is used to determine if the BIOS call to set frequencies
  347. // is available. If you can, then after the BIOS call AL=12.
  348. // See page 233 of the W32p data book for details.
  349. //
  350. VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  351. biosArguments.Eax = 0x1200;
  352. biosArguments.Ebx = 0xf1;
  353. biosArguments.Ecx = 0x0;
  354. status = VideoPortInt10(HwDeviceExtension, &biosArguments);
  355. if (status != NO_ERROR) {
  356. VideoDebugPrint((1, "VgaSetMode - VideoPortInt10 failed (%d)\n", __LINE__));
  357. return status;
  358. }
  359. VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  360. biosArguments.Eax = 0x1200;
  361. biosArguments.Ebx = 0xf1;
  362. biosArguments.Ecx = 0x1;
  363. status = VideoPortInt10(HwDeviceExtension, &biosArguments);
  364. if (status != NO_ERROR) {
  365. VideoDebugPrint((1, "VgaSetMode - VideoPortInt10 failed (%d)\n", __LINE__));
  366. return status;
  367. }
  368. VideoDebugPrint((1, "VgaSetMode - BIOS returned %x in AL\n",
  369. (biosArguments.Eax & 0xff)));
  370. if ((biosArguments.Eax & 0xff) == 0x12) {
  371. VideoDebugPrint((1, "VgaSetMode - using BIOS to set refresh rate\n"));
  372. VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  373. biosArguments.Eax = 0x1200;
  374. switch (pRequestedMode->hres) {
  375. case 320:
  376. case 512:
  377. case 640:
  378. biosArguments.Ebx = 0xf1;
  379. if (pRequestedMode->Frequency == 60)
  380. biosArguments.Ecx = 0x0;
  381. else if (pRequestedMode->Frequency == 72)
  382. biosArguments.Ecx = 0x1;
  383. else if (pRequestedMode->Frequency == 75)
  384. biosArguments.Ecx = 0x2;
  385. else if (pRequestedMode->Frequency == 85)
  386. biosArguments.Ecx = 0x3;
  387. else if (pRequestedMode->Frequency == 90)
  388. biosArguments.Ecx = 0x4;
  389. break;
  390. case 800:
  391. biosArguments.Ebx = 0x1f1;
  392. if (pRequestedMode->Frequency == 56)
  393. biosArguments.Ecx = 0x0;
  394. else if (pRequestedMode->Frequency == 60)
  395. biosArguments.Ecx = 0x1;
  396. else if (pRequestedMode->Frequency == 72)
  397. biosArguments.Ecx = 0x2;
  398. else if (pRequestedMode->Frequency == 75)
  399. biosArguments.Ecx = 0x3;
  400. else if (pRequestedMode->Frequency == 85)
  401. biosArguments.Ecx = 0x4;
  402. else if (pRequestedMode->Frequency == 90)
  403. biosArguments.Ecx = 0x5;
  404. break;
  405. case 1024:
  406. biosArguments.Ebx = 0x2f1;
  407. if (pRequestedMode->Frequency == 45)
  408. biosArguments.Ecx = 0x0;
  409. else if (pRequestedMode->Frequency == 60)
  410. biosArguments.Ecx = 0x1;
  411. else if (pRequestedMode->Frequency == 70)
  412. biosArguments.Ecx = 0x2;
  413. // For some BIOS 3 will give us 72 Hz, and
  414. // on others, 3 will give us 75
  415. else if (pRequestedMode->Frequency == 72)
  416. biosArguments.Ecx = 0x3;
  417. else if (pRequestedMode->Frequency == 75)
  418. biosArguments.Ecx = 0x3;
  419. break;
  420. case 1280:
  421. biosArguments.Ebx = 0x3f1;
  422. if (pRequestedMode->Frequency == 45)
  423. biosArguments.Ecx = 0x0;
  424. else if (pRequestedMode->Frequency == 60)
  425. biosArguments.Ecx = 0x1;
  426. else if (pRequestedMode->Frequency == 70)
  427. biosArguments.Ecx = 0x2;
  428. // For some BIOS 3 will give us 72 Hz, and
  429. // on others, 3 will give us 75
  430. else if (pRequestedMode->Frequency == 72)
  431. biosArguments.Ecx = 0x3;
  432. else if (pRequestedMode->Frequency == 75)
  433. biosArguments.Ecx = 0x3;
  434. break;
  435. default:
  436. biosArguments.Ebx = 0xf1;
  437. biosArguments.Ecx = 0x0;
  438. break;
  439. }
  440. status = VideoPortInt10(HwDeviceExtension, &biosArguments);
  441. if (status != NO_ERROR) {
  442. VideoDebugPrint((1, "VgaSetMode - VideoPortInt10 failed (%d)\n", __LINE__));
  443. }
  444. VideoDebugPrint((1, "VgaSetMode - BIOS returned %x in CL\n",
  445. (biosArguments.Ecx & 0xff)));
  446. }
  447. else if (HwDeviceExtension->BoardID == STEALTH32) {
  448. usTemp = 0xffff; // flag value, this is reserved
  449. switch (pRequestedMode->hres) {
  450. case 640:
  451. if (pRequestedMode->Frequency == 90) {
  452. usTemp = 4;
  453. } else if (pRequestedMode->Frequency == 75) {
  454. usTemp = 2;
  455. } else if (pRequestedMode->Frequency == 72) {
  456. usTemp = 0;
  457. } else if (pRequestedMode->Frequency == 60) {
  458. usTemp = 8;
  459. }
  460. break;
  461. case 800:
  462. if (pRequestedMode->Frequency == 90) {
  463. usTemp = 4;
  464. } else if (pRequestedMode->Frequency == 75) {
  465. usTemp = 2;
  466. } else if (pRequestedMode->Frequency == 72) {
  467. usTemp = 1;
  468. } else if (pRequestedMode->Frequency == 60) {
  469. usTemp = 0;
  470. } else if (pRequestedMode->Frequency == 56) {
  471. usTemp = 8;
  472. }
  473. break;
  474. case 1024:
  475. if (pRequestedMode->Frequency == 75) {
  476. usTemp = 2;
  477. } else if (pRequestedMode->Frequency == 72) {
  478. usTemp = 4;
  479. } else if (pRequestedMode->Frequency == 70) {
  480. usTemp = 3;
  481. } else if (pRequestedMode->Frequency == 60) {
  482. usTemp = 5;
  483. } else if (pRequestedMode->Frequency == 43) {
  484. usTemp = 0;
  485. }
  486. break;
  487. case 1280:
  488. if (pRequestedMode->Frequency == 75) {
  489. usTemp = 2;
  490. } else if (pRequestedMode->Frequency == 72) {
  491. usTemp = 4;
  492. } else if (pRequestedMode->Frequency == 60) {
  493. usTemp = 5;
  494. } else if (pRequestedMode->Frequency == 43) {
  495. usTemp = 6;
  496. }
  497. break;
  498. default:
  499. //
  500. // !!! Reset for DOS modes?
  501. //
  502. // usDataSet = HwDeviceExtension->OriginalBiosData;
  503. break;
  504. }
  505. if (usTemp != 0xffff)
  506. {
  507. USHORT usOldBits;
  508. UnlockET4000ExtendedRegs(HwDeviceExtension);
  509. //
  510. // select CRTC.31 and write usTemp to bits 3-0
  511. //
  512. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  513. CRTC_ADDRESS_PORT_COLOR, 0x31);
  514. usOldBits = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  515. CRTC_DATA_PORT_COLOR);
  516. usTemp = ((usTemp & 0x0f) | (usOldBits & 0xf0));
  517. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  518. CRTC_DATA_PORT_COLOR, (UCHAR)usTemp);
  519. LockET4000ExtendedRegs(HwDeviceExtension);
  520. }
  521. } // HwDeviceExtension->BoardID == STEALTH32
  522. #if defined(i386)
  523. //
  524. // Ok, we'll try to stuff the right values in to the bios data
  525. // area so that the int10 modeset sets the freq for us.
  526. //
  527. else {
  528. //
  529. // NOTE :
  530. //
  531. // We assume an int10 was made as some point before we reach this code.
  532. // This ensures the BiosData got initialized properly.
  533. //
  534. //
  535. // Get the BiosData area value and save the original value.
  536. //
  537. if (!HwDeviceExtension->BiosArea) {
  538. switch (HwDeviceExtension->BoardID) {
  539. case PRODESIGNERIISEISA:
  540. //
  541. // Initialize this to something.
  542. // It is not used however, since we always use hardware defaults
  543. // for this card.
  544. //
  545. HwDeviceExtension->BiosArea = (PUSHORT)PRODESIGNER_BIOS_INFO;
  546. break;
  547. case PRODESIGNER2:
  548. case PRODESIGNERIIS:
  549. HwDeviceExtension->BiosArea = (PUSHORT)PRODESIGNER_BIOS_INFO;
  550. HwDeviceExtension->OriginalBiosData =
  551. VideoPortReadRegisterUshort(HwDeviceExtension->BiosArea);
  552. break;
  553. case SPEEDSTAR:
  554. case SPEEDSTARPLUS:
  555. case SPEEDSTAR24:
  556. case OTHER:
  557. default:
  558. HwDeviceExtension->BiosArea = (PUSHORT)BIOS_INFO_1;
  559. HwDeviceExtension->OriginalBiosData =
  560. VideoPortReadRegisterUshort(HwDeviceExtension->BiosArea);
  561. break;
  562. }
  563. }
  564. pBios = HwDeviceExtension->BiosArea;
  565. //
  566. // Set the refresh rates for the various boards
  567. //
  568. switch(HwDeviceExtension->BoardID) {
  569. case SPEEDSTAR:
  570. case SPEEDSTARPLUS:
  571. case SPEEDSTAR24:
  572. switch (pRequestedMode->hres) {
  573. case 640:
  574. if (pRequestedMode->Frequency == 72)
  575. usDataSet = 2;
  576. else usDataSet = 1;
  577. break;
  578. case 800:
  579. if (pRequestedMode->Frequency == 72)
  580. usDataSet = 2;
  581. else if (pRequestedMode->Frequency == 56)
  582. usDataSet = 1;
  583. else usDataSet = 3;
  584. break;
  585. case 1024:
  586. if (pRequestedMode->Frequency == 70)
  587. usDataSet = 4;
  588. else if (pRequestedMode->Frequency == 45)
  589. usDataSet = 1;
  590. else usDataSet = 2;
  591. break;
  592. default:
  593. usDataSet = 1;
  594. break;
  595. }
  596. //
  597. // now we got to unlock the CRTC extension registers!?!
  598. //
  599. UnlockET4000ExtendedRegs(HwDeviceExtension);
  600. if (HwDeviceExtension->BoardID == SPEEDSTAR24) {
  601. //
  602. // SpeedSTAR 24 uses 31.0 for LSB select CRTC.31 and read it
  603. //
  604. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  605. CRTC_ADDRESS_PORT_COLOR, 0x31);
  606. usTemp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  607. CRTC_DATA_PORT_COLOR) & ~0x01;
  608. //
  609. // CRTC.31 bit 0 is the LSB of the monitor type on SpeedSTAR 24
  610. //
  611. usTemp |= (usDataSet&1);
  612. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  613. CRTC_DATA_PORT_COLOR, (UCHAR)usTemp);
  614. } else { // SpeedSTAR and SpeedSTAR Plus use 37.4 for LSB
  615. //
  616. // select CRTC.37 and read it
  617. //
  618. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  619. CRTC_ADDRESS_PORT_COLOR, 0x37);
  620. usTemp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  621. CRTC_DATA_PORT_COLOR) & ~0x10;
  622. //
  623. // CRTC.37 bit 4 is the LSB of the monitor type on SpeedSTAR PLUS
  624. //
  625. usTemp |= (usDataSet&1)<<4;
  626. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  627. CRTC_DATA_PORT_COLOR, (UCHAR)usTemp);
  628. }
  629. LockET4000ExtendedRegs(HwDeviceExtension);
  630. //
  631. // these two bits are the rest of the monitor type...
  632. //
  633. usTemp = VideoPortReadRegisterUshort(pBios) & ~0x6000;
  634. usTemp |= (usDataSet&6)<<12;
  635. usTemp |= VideoPortReadRegisterUshort(pBios);
  636. VideoPortWriteRegisterUshort(pBios,usTemp);
  637. break;
  638. //
  639. // Do nothing for the EISA machine - use the default in the EISA config.
  640. //
  641. case PRODESIGNERIISEISA:
  642. break;
  643. //
  644. // The old prodesigner 2 is not able toset refresh rates
  645. //
  646. case PRODESIGNER2:
  647. break;
  648. case PRODESIGNERIIS:
  649. switch (pRequestedMode->hres) {
  650. case 640:
  651. //
  652. // Bit 0: 1=72Hz 0=60Hz
  653. //
  654. if (pRequestedMode->Frequency == 72) {
  655. usDataSet = 0x0001;
  656. } else { // 60 Hz
  657. usDataSet = 0x0000;
  658. }
  659. break;
  660. case 800:
  661. //
  662. // Bit 1-2: 10=72Hz 01=60Hz 00=56Hz
  663. //
  664. if (pRequestedMode->Frequency == 72) {
  665. usDataSet = 0x0004;
  666. } else {
  667. if (pRequestedMode->Frequency == 56) {
  668. usDataSet = 0x0000;
  669. } else { // 60 Hz
  670. usDataSet = 0x0002;
  671. }
  672. }
  673. break;
  674. case 1024:
  675. //
  676. // Bit 3-4: 10=70Hz 01=60Hz 00=45Hz
  677. //
  678. if (pRequestedMode->Frequency == 70) {
  679. usDataSet = 0x0010;
  680. } else {
  681. if (pRequestedMode->Frequency == 45) {
  682. usDataSet = 0x0000;
  683. } else { // 60 Hz
  684. usDataSet = 0x0008;
  685. }
  686. }
  687. break;
  688. // case 1280
  689. //
  690. // Bit 5 1=45Hz 0=43 Hz
  691. //
  692. default:
  693. //
  694. // Reset for DOS modes
  695. //
  696. usDataSet = HwDeviceExtension->OriginalBiosData;
  697. break;
  698. }
  699. VideoPortWriteRegisterUshort(pBios,usDataSet);
  700. break;
  701. case OTHER:
  702. default:
  703. {
  704. VideoDebugPrint((2, "### VgaSetMode - hres(%d) freq(%d)\n",
  705. pRequestedMode->hres,
  706. pRequestedMode->Frequency
  707. ));
  708. VideoDebugPrint((2, "### VgaSetMode - NOT using BIOS to set refresh rate\n"));
  709. switch (pRequestedMode->hres) {
  710. case 640:
  711. if (pRequestedMode->Frequency == 72) {
  712. usDataSet = 0x0040; // set bit 6
  713. usDataClr = (USHORT)~0; // no bits to be cleared
  714. } else { // 60 Hz
  715. usDataSet = 0; // no bits to set
  716. usDataClr = (USHORT)~0x0040; // clear bit 6
  717. }
  718. break;
  719. case 800:
  720. if (pRequestedMode->Frequency == 72) {
  721. usDataSet = 0x4020; // set bits 5 and 14
  722. usDataClr = (USHORT)~0; // no bits to clear
  723. } else {
  724. if (pRequestedMode->Frequency == 56) {
  725. usDataSet = 0x4000; // set bit 14
  726. usDataClr = (USHORT)~0x0020; // clr bit 5
  727. } else { // 60 Hz
  728. usDataSet = 0; // no bits to set
  729. usDataClr = (USHORT)~0x4020; // clr bits 5 and 14
  730. }
  731. }
  732. break;
  733. case 1024:
  734. if (pRequestedMode->Frequency == 70) {
  735. usDataSet = 0x2010; // set bits 4 and 13
  736. usDataClr = (USHORT)~0; // no bits to clear
  737. } else {
  738. if (pRequestedMode->Frequency == 45) { //interlaced
  739. usDataSet = 0; // no bits to set
  740. usDataClr = (USHORT)~0x2010; // clear bits 4 and 13
  741. } else { // 60 Hz
  742. usDataSet = 0x2000; // set bit 13
  743. usDataClr = (USHORT)~0x0010; // clear bit 4
  744. }
  745. }
  746. break;
  747. default:
  748. //
  749. // Restore to original Value
  750. //
  751. usDataSet = HwDeviceExtension->OriginalBiosData;
  752. usDataClr = 0x0000;
  753. break;
  754. }
  755. usTemp = VideoPortReadRegisterUshort(pBios) & usDataClr;
  756. usTemp |= usDataSet;
  757. VideoPortWriteRegisterUshort(pBios,usTemp);
  758. }
  759. break;
  760. }
  761. }
  762. #endif
  763. VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  764. biosArguments.Eax = pRequestedMode->Int10ModeNumber;
  765. status = VideoPortInt10(HwDeviceExtension, &biosArguments);
  766. if (status != NO_ERROR) {
  767. VideoDebugPrint((1, "VgaSetMode - VideoPortInt10 failed (%d)\n", __LINE__));
  768. return status;
  769. }
  770. if (HwDeviceExtension->ulChipID == ET4000 &&
  771. HwDeviceExtension->AdapterMemorySize < 0x100000) {
  772. //
  773. // ET4000 less than 1 meg set TLI mode in CRTC.36
  774. //
  775. UnlockET4000ExtendedRegs(HwDeviceExtension);
  776. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  777. CRTC_ADDRESS_PORT_COLOR, 0x36);
  778. usTemp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  779. CRTC_DATA_PORT_COLOR) | 0x20;
  780. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  781. CRTC_DATA_PORT_COLOR, (UCHAR)usTemp);
  782. LockET4000ExtendedRegs(HwDeviceExtension);
  783. }
  784. //
  785. // If this is a 16bpp or 24bpp mode, call the bios to switch it from
  786. // 8bpp to the new mode.
  787. //
  788. if (pRequestedMode->bitsPerPlane == 16) {
  789. VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  790. biosArguments.Eax = 0x10F0;
  791. biosArguments.Ebx = pRequestedMode->Int10ModeNumber;
  792. status = VideoPortInt10(HwDeviceExtension, &biosArguments);
  793. if (status != NO_ERROR) {
  794. VideoDebugPrint((1, "VgaSetMode - VideoPortInt10 failed (%d)\n", __LINE__));
  795. return status;
  796. }
  797. } else if (pRequestedMode->bitsPerPlane == 24) {
  798. VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  799. biosArguments.Eax = 0x10F0;
  800. biosArguments.Ebx = pRequestedMode->Int10ModeNumber;
  801. biosArguments.Ebx <<= 8;
  802. biosArguments.Ebx |= 0xff;
  803. status = VideoPortInt10(HwDeviceExtension, &biosArguments);
  804. if (status != NO_ERROR) {
  805. VideoDebugPrint((1, "VgaSetMode - VideoPortInt10 failed (%d)\n", __LINE__));
  806. return status;
  807. }
  808. }
  809. if (pRequestedMode->hres >= 800) {
  810. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  811. SEGMENT_SELECT_PORT,0);
  812. }
  813. if (pRequestedMode->CmdStrings != NULL) {
  814. VgaInterpretCmdStream(HwDeviceExtension, pRequestedMode->CmdStrings);
  815. }
  816. //
  817. // Reset the Bios Value to the default so DOS modes will work.
  818. // Do this for all cards except the EISA prodesigner
  819. //
  820. if ((pBios != NULL) &&
  821. (HwDeviceExtension->BoardID != PRODESIGNERIISEISA))
  822. {
  823. VideoPortWriteRegisterUshort(pBios,
  824. HwDeviceExtension->OriginalBiosData);
  825. }
  826. {
  827. UCHAR temp;
  828. UCHAR dummy;
  829. UCHAR bIsColor;
  830. if (!(pRequestedMode->fbType & VIDEO_MODE_GRAPHICS)) {
  831. //
  832. // Fix to make sure we always set the colors in text mode to be
  833. // intensity, and not flashing
  834. // For this zero out the Mode Control Regsiter bit 3 (index 0x10
  835. // of the Attribute controller).
  836. //
  837. if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  838. MISC_OUTPUT_REG_READ_PORT) & 0x01) {
  839. bIsColor = TRUE;
  840. } else {
  841. bIsColor = FALSE;
  842. }
  843. if (bIsColor) {
  844. dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  845. INPUT_STATUS_1_COLOR);
  846. } else {
  847. dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  848. INPUT_STATUS_1_MONO);
  849. }
  850. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  851. ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE));
  852. temp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  853. ATT_DATA_READ_PORT);
  854. temp &= 0xF7;
  855. if (bIsColor) {
  856. dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  857. INPUT_STATUS_1_COLOR);
  858. } else {
  859. dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  860. INPUT_STATUS_1_MONO);
  861. }
  862. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  863. ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE));
  864. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  865. ATT_DATA_WRITE_PORT, temp);
  866. }
  867. }
  868. //
  869. // Set up the card to use the linear address ranges
  870. //
  871. {
  872. UCHAR bits;
  873. VideoPortGetBusData(HwDeviceExtension,
  874. PCIConfiguration,
  875. HwDeviceExtension->ulSlot,
  876. (PVOID) &bits,
  877. 0x40,
  878. 1);
  879. bits &= ~0x6;
  880. if (HwDeviceExtension->bInLinearMode)
  881. {
  882. //
  883. // set low 4 bits to 1011
  884. //
  885. bits |= 0xb;
  886. }
  887. else
  888. {
  889. //
  890. // set low 4 bits to 0110
  891. //
  892. bits |= 0x6;
  893. }
  894. VideoPortSetBusData(HwDeviceExtension,
  895. PCIConfiguration,
  896. HwDeviceExtension->ulSlot,
  897. (PVOID) &bits,
  898. 0x40,
  899. 1);
  900. }
  901. //
  902. // Update the location of the physical frame buffer within video memory.
  903. //
  904. HwDeviceExtension->PhysicalFrameLength =
  905. MemoryMaps[pRequestedMode->MemMap].MaxSize;
  906. HwDeviceExtension->PhysicalFrameBase.HighPart = 0;
  907. HwDeviceExtension->PhysicalFrameBase.LowPart =
  908. MemoryMaps[pRequestedMode->MemMap].Start;
  909. //
  910. // Store the new mode value.
  911. //
  912. HwDeviceExtension->CurrentMode = pRequestedMode;
  913. HwDeviceExtension->ModeIndex = Mode->RequestedMode;
  914. VideoDebugPrint((1, "VgaSetMode - exit\n"));
  915. return NO_ERROR;
  916. } //end VgaSetMode()
  917. VP_STATUS
  918. VgaQueryAvailableModes(
  919. PHW_DEVICE_EXTENSION HwDeviceExtension,
  920. PVIDEO_MODE_INFORMATION ModeInformation,
  921. ULONG ModeInformationSize,
  922. PULONG OutputSize
  923. )
  924. /*++
  925. Routine Description:
  926. This routine returns the list of all available available modes on the
  927. card.
  928. Arguments:
  929. HwDeviceExtension - Pointer to the miniport driver's device extension.
  930. ModeInformation - Pointer to the output buffer supplied by the user.
  931. This is where the list of all valid modes is stored.
  932. ModeInformationSize - Length of the output buffer supplied by the user.
  933. OutputSize - Pointer to a buffer in which to return the actual size of
  934. the data in the buffer. If the buffer was not large enough, this
  935. contains the minimum required buffer size.
  936. Return Value:
  937. ERROR_INSUFFICIENT_BUFFER if the output buffer was not large enough
  938. for the data being returned.
  939. NO_ERROR if the operation completed successfully.
  940. --*/
  941. {
  942. PVIDEO_MODE_INFORMATION videoModes = ModeInformation;
  943. ULONG i;
  944. //
  945. // Find out the size of the data to be put in the buffer and return
  946. // that in the status information (whether or not the information is
  947. // there). If the buffer passed in is not large enough return an
  948. // appropriate error code.
  949. //
  950. if (ModeInformationSize < (*OutputSize =
  951. HwDeviceExtension->NumAvailableModes *
  952. sizeof(VIDEO_MODE_INFORMATION)) ) {
  953. VideoDebugPrint((1,"VgaQueryAvailableModes: ERROR_INSUFFICIENT_BUFFER\n"));
  954. return ERROR_INSUFFICIENT_BUFFER;
  955. }
  956. //
  957. // For each mode supported by the card, store the mode characteristics
  958. // in the output buffer.
  959. //
  960. for (i = 0; i < NumVideoModes; i++) {
  961. if (ModesVGA[i].ValidMode) {
  962. videoModes->Length = sizeof(VIDEO_MODE_INFORMATION);
  963. videoModes->ModeIndex = i;
  964. videoModes->VisScreenWidth = ModesVGA[i].hres;
  965. videoModes->ScreenStride = ModesVGA[i].wbytes;
  966. videoModes->VisScreenHeight = ModesVGA[i].vres;
  967. videoModes->NumberOfPlanes = ModesVGA[i].numPlanes;
  968. videoModes->BitsPerPlane = ModesVGA[i].bitsPerPlane;
  969. videoModes->Frequency = ModesVGA[i].Frequency;
  970. videoModes->XMillimeter = 320; // temporary hardcoded constant
  971. videoModes->YMillimeter = 240; // temporary hardcoded constant
  972. videoModes->NumberRedBits = 6;
  973. videoModes->NumberGreenBits = 6;
  974. videoModes->NumberBlueBits = 6;
  975. videoModes->AttributeFlags = ModesVGA[i].fbType;
  976. videoModes->AttributeFlags |= ModesVGA[i].Interlaced ?
  977. VIDEO_MODE_INTERLACED : 0;
  978. //
  979. // Calculate the VideoMemoryBitmapWidth
  980. //
  981. {
  982. LONG x;
  983. x = videoModes->BitsPerPlane;
  984. if( x == 15 ) x = 16;
  985. videoModes->VideoMemoryBitmapWidth =
  986. (videoModes->ScreenStride * 8 ) / x;
  987. }
  988. videoModes->VideoMemoryBitmapHeight =
  989. HwDeviceExtension->AdapterMemorySize / videoModes->ScreenStride;
  990. if (ModesVGA[i].bitsPerPlane == 16) {
  991. videoModes->RedMask = 0x7c00;
  992. videoModes->GreenMask = 0x03e0;
  993. videoModes->BlueMask = 0x001f;
  994. } else if (ModesVGA[i].bitsPerPlane == 24) {
  995. videoModes->RedMask = 0xff0000;
  996. videoModes->GreenMask = 0x00ff00;
  997. videoModes->BlueMask = 0x0000ff;
  998. } else {
  999. videoModes->RedMask = 0;
  1000. videoModes->GreenMask = 0;
  1001. videoModes->BlueMask = 0;
  1002. videoModes->AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN |
  1003. VIDEO_MODE_MANAGED_PALETTE;
  1004. }
  1005. videoModes++;
  1006. }
  1007. }
  1008. return NO_ERROR;
  1009. } // end VgaGetAvailableModes()
  1010. VP_STATUS
  1011. VgaQueryNumberOfAvailableModes(
  1012. PHW_DEVICE_EXTENSION HwDeviceExtension,
  1013. PVIDEO_NUM_MODES NumModes,
  1014. ULONG NumModesSize,
  1015. PULONG OutputSize
  1016. )
  1017. /*++
  1018. Routine Description:
  1019. This routine returns the number of available modes for this particular
  1020. video card.
  1021. Arguments:
  1022. HwDeviceExtension - Pointer to the miniport driver's device extension.
  1023. NumModes - Pointer to the output buffer supplied by the user. This is
  1024. where the number of modes is stored.
  1025. NumModesSize - Length of the output buffer supplied by the user.
  1026. OutputSize - Pointer to a buffer in which to return the actual size of
  1027. the data in the buffer.
  1028. Return Value:
  1029. ERROR_INSUFFICIENT_BUFFER if the output buffer was not large enough
  1030. for the data being returned.
  1031. NO_ERROR if the operation completed successfully.
  1032. --*/
  1033. {
  1034. //
  1035. // Find out the size of the data to be put in the the buffer and return
  1036. // that in the status information (whether or not the information is
  1037. // there). If the buffer passed in is not large enough return an
  1038. // appropriate error code.
  1039. //
  1040. if (NumModesSize < (*OutputSize = sizeof(VIDEO_NUM_MODES)) ) {
  1041. return ERROR_INSUFFICIENT_BUFFER;
  1042. }
  1043. //
  1044. // Store the number of modes into the buffer.
  1045. //
  1046. NumModes->NumModes = HwDeviceExtension->NumAvailableModes;
  1047. NumModes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
  1048. VideoDebugPrint((1,"NumAvailableModes = %d\n", HwDeviceExtension->NumAvailableModes));
  1049. return NO_ERROR;
  1050. } // end VgaGetNumberOfAvailableModes()
  1051. VP_STATUS
  1052. VgaQueryCurrentMode(
  1053. PHW_DEVICE_EXTENSION HwDeviceExtension,
  1054. PVIDEO_MODE_INFORMATION ModeInformation,
  1055. ULONG ModeInformationSize,
  1056. PULONG OutputSize
  1057. )
  1058. /*++
  1059. Routine Description:
  1060. This routine returns a description of the current video mode.
  1061. Arguments:
  1062. HwDeviceExtension - Pointer to the miniport driver's device extension.
  1063. ModeInformation - Pointer to the output buffer supplied by the user.
  1064. This is where the current mode information is stored.
  1065. ModeInformationSize - Length of the output buffer supplied by the user.
  1066. OutputSize - Pointer to a buffer in which to return the actual size of
  1067. the data in the buffer. If the buffer was not large enough, this
  1068. contains the minimum required buffer size.
  1069. Return Value:
  1070. ERROR_INSUFFICIENT_BUFFER if the output buffer was not large enough
  1071. for the data being returned.
  1072. NO_ERROR if the operation completed successfully.
  1073. --*/
  1074. {
  1075. //
  1076. // Find out the size of the data to be put in the the buffer and return
  1077. // that in the status information (whether or not the information is
  1078. // there). If the buffer passed in is not large enough return an
  1079. // appropriate error code.
  1080. //
  1081. if (ModeInformationSize < (*OutputSize = sizeof(VIDEO_MODE_INFORMATION))) {
  1082. return ERROR_INSUFFICIENT_BUFFER;
  1083. }
  1084. //
  1085. // Store the characteristics of the current mode into the buffer.
  1086. //
  1087. ModeInformation->Length = sizeof(VIDEO_MODE_INFORMATION);
  1088. ModeInformation->ModeIndex = HwDeviceExtension->ModeIndex;
  1089. ModeInformation->VisScreenWidth = HwDeviceExtension->CurrentMode->hres;
  1090. ModeInformation->ScreenStride = HwDeviceExtension->CurrentMode->wbytes;
  1091. ModeInformation->VisScreenHeight = HwDeviceExtension->CurrentMode->vres;
  1092. ModeInformation->NumberOfPlanes = HwDeviceExtension->CurrentMode->numPlanes;
  1093. ModeInformation->BitsPerPlane = HwDeviceExtension->CurrentMode->bitsPerPlane;
  1094. ModeInformation->Frequency = HwDeviceExtension->CurrentMode->Frequency;
  1095. ModeInformation->XMillimeter = 320; // temporary hardcoded constant
  1096. ModeInformation->YMillimeter = 240; // temporary hardcoded constant
  1097. ModeInformation->NumberRedBits = 6;
  1098. ModeInformation->NumberGreenBits = 6;
  1099. ModeInformation->NumberBlueBits = 6;
  1100. ModeInformation->RedMask = 0;
  1101. ModeInformation->GreenMask = 0;
  1102. ModeInformation->BlueMask = 0;
  1103. ModeInformation->AttributeFlags = HwDeviceExtension->CurrentMode->fbType |
  1104. VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
  1105. ModeInformation->AttributeFlags |= HwDeviceExtension->CurrentMode->Interlaced ?
  1106. VIDEO_MODE_INTERLACED : 0;
  1107. //
  1108. // Calculate the VideoMemoryBitmapWidth
  1109. //
  1110. {
  1111. LONG x;
  1112. x = ModeInformation->BitsPerPlane;
  1113. if( x == 15 ) x = 16;
  1114. ModeInformation->VideoMemoryBitmapWidth =
  1115. (ModeInformation->ScreenStride * 8 ) / x;
  1116. }
  1117. ModeInformation->VideoMemoryBitmapHeight =
  1118. HwDeviceExtension->AdapterMemorySize / ModeInformation->ScreenStride;
  1119. return NO_ERROR;
  1120. } // end VgaQueryCurrentMode()
  1121. VOID
  1122. VgaZeroVideoMemory(
  1123. PHW_DEVICE_EXTENSION HwDeviceExtension
  1124. )
  1125. /*++
  1126. Routine Description:
  1127. This routine zeros the first 256K on the VGA.
  1128. Arguments:
  1129. HwDeviceExtension - Pointer to the miniport driver's device extension.
  1130. Return Value:
  1131. None.
  1132. --*/
  1133. {
  1134. // return;
  1135. {
  1136. UCHAR temp;
  1137. VideoDebugPrint((1, "VgaZeroVideoMemory - entry et4000\n"));
  1138. //
  1139. // Map font buffer at A0000
  1140. //
  1141. VgaInterpretCmdStream(HwDeviceExtension, EnableA000Data);
  1142. //
  1143. // Enable all planes.
  1144. //
  1145. VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_ADDRESS_PORT,
  1146. IND_MAP_MASK);
  1147. temp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  1148. SEQ_DATA_PORT) | (UCHAR)0x0F;
  1149. VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_DATA_PORT,
  1150. temp);
  1151. //
  1152. // Zero the memory.
  1153. //
  1154. VideoPortZeroDeviceMemory(HwDeviceExtension->VideoMemoryAddress, 0xFFFF);
  1155. VgaInterpretCmdStream(HwDeviceExtension, DisableA000Color);
  1156. VideoDebugPrint((1, "VgaZeroVideoMemory - exit et4000\n"));
  1157. }
  1158. }
  1159. VOID
  1160. VgaValidateModes(
  1161. PHW_DEVICE_EXTENSION HwDeviceExtension
  1162. )
  1163. /*++
  1164. Routine Description:
  1165. Determines which modes are valid and which are not.
  1166. Arguments:
  1167. HwDeviceExtension - Pointer to the miniport driver's device extension.
  1168. Return Value:
  1169. None.
  1170. --*/
  1171. {
  1172. ULONG i;
  1173. HwDeviceExtension->NumAvailableModes = 0;
  1174. VideoDebugPrint((2, "NumVideoModes(%d)\n",NumVideoModes));
  1175. for (i = 0; i < NumVideoModes; i++) {
  1176. if (ModesVGA[i].fbType & VIDEO_MODE_GRAPHICS) {
  1177. #if !defined(i386)
  1178. if (ModesVGA[i].bitsPerPlane < 8) {
  1179. //
  1180. // no 16 color allowed on non x86
  1181. //
  1182. continue;
  1183. }
  1184. #endif
  1185. switch (HwDeviceExtension->ulChipID) {
  1186. case ET6000:
  1187. //
  1188. // can do all modes
  1189. //
  1190. break;
  1191. case W32P:
  1192. //
  1193. // Can't do 24bpp if banking, which this is.
  1194. // Can't do modes below 640x480.
  1195. //
  1196. if ((ModesVGA[i].bitsPerPlane == 24) ||
  1197. (ModesVGA[i].vres < 480)) {
  1198. continue;
  1199. }
  1200. break;
  1201. case W32I:
  1202. case W32:
  1203. //
  1204. // Can't do 24bpp if banking, which this is,
  1205. // or if resolution > 640x480.
  1206. // Can't do modes below 640x480.
  1207. //
  1208. //
  1209. // !!! fix this expression
  1210. //
  1211. if ((ModesVGA[i].bitsPerPlane == 24) ||
  1212. (ModesVGA[i].vres < 480) ||
  1213. ((ModesVGA[i].hres > 800) &&
  1214. (ModesVGA[i].bitsPerPlane > 8))) {
  1215. continue;
  1216. }
  1217. break;
  1218. default:
  1219. //
  1220. // Can't do 1280x1024 or 24bpp.
  1221. // Can't do modes below 640x480.
  1222. //
  1223. if ((ModesVGA[i].hres > 1024) ||
  1224. (ModesVGA[i].vres < 480) ||
  1225. (ModesVGA[i].bitsPerPlane > 16)) {
  1226. continue;
  1227. }
  1228. //
  1229. // can't do 16bpp if resolution > 640x480
  1230. //
  1231. if ((ModesVGA[i].hres > 640) &&
  1232. (ModesVGA[i].bitsPerPlane > 8)) {
  1233. continue;
  1234. }
  1235. break;
  1236. }
  1237. if ((HwDeviceExtension->ulChipID != ET6000) &&
  1238. (HwDeviceExtension->BoardID != STEALTH32)) {
  1239. switch (ModesVGA[i].hres) {
  1240. case 640:
  1241. if ((ModesVGA[i].Frequency == 90) ||
  1242. (ModesVGA[i].Frequency == 85) ||
  1243. (ModesVGA[i].Frequency == 75)) {
  1244. continue;
  1245. }
  1246. break;
  1247. case 800:
  1248. if ((ModesVGA[i].Frequency == 90) ||
  1249. (ModesVGA[i].Frequency == 85) ||
  1250. (ModesVGA[i].Frequency == 75)) {
  1251. continue;
  1252. }
  1253. break;
  1254. case 1024:
  1255. if ((ModesVGA[i].Frequency == 75) ||
  1256. (ModesVGA[i].Frequency == 72)) {
  1257. continue;
  1258. }
  1259. break;
  1260. case 1280:
  1261. if ((ModesVGA[i].Frequency == 75) ||
  1262. (ModesVGA[i].Frequency == 72)) {
  1263. continue;
  1264. }
  1265. break;
  1266. }
  1267. }
  1268. if (HwDeviceExtension->BoardID == PRODESIGNER2) {
  1269. //
  1270. // Original Pro designer 2 only supports
  1271. // 640x480x60Hz
  1272. // 800x600x56Hz
  1273. // 1024x768x60Hz
  1274. //
  1275. if (ModesVGA[i].bitsPerPlane >= 16) {
  1276. continue;
  1277. }
  1278. if ( ((ModesVGA[i].hres == 640) && (ModesVGA[i].Frequency != 60)) ||
  1279. ((ModesVGA[i].hres == 800) && (ModesVGA[i].Frequency != 56)) ||
  1280. ((ModesVGA[i].hres == 1024) && (ModesVGA[i].Frequency != 60)) ) {
  1281. continue;
  1282. }
  1283. }
  1284. }
  1285. //
  1286. // Do not support refresh rates with the EISA pro designer card.
  1287. //
  1288. if (HwDeviceExtension->BoardID == PRODESIGNERIISEISA) {
  1289. ModesVGA[i].Frequency = 1;
  1290. ModesVGA[i].Interlaced = 0;
  1291. }
  1292. //
  1293. // Make modes that fit in video memory valid.
  1294. //
  1295. if (HwDeviceExtension->AdapterMemorySize >=
  1296. ModesVGA[i].numPlanes * ModesVGA[i].sbytes) {
  1297. ModesVGA[i].ValidMode = TRUE;
  1298. HwDeviceExtension->NumAvailableModes++;
  1299. VideoDebugPrint((2, "mode[%d] valid\n",i));
  1300. VideoDebugPrint((2, " hres(%d)\n",ModesVGA[i].hres));
  1301. VideoDebugPrint((2, " bitsPerPlane(%d)\n",ModesVGA[i].bitsPerPlane));
  1302. VideoDebugPrint((2, " freq(%d)\n",ModesVGA[i].Frequency));
  1303. VideoDebugPrint((2, " interlace(%d)\n",ModesVGA[i].Interlaced));
  1304. VideoDebugPrint((2, " numPlanes(%d)\n",ModesVGA[i].numPlanes));
  1305. VideoDebugPrint((2, " sbytes(%d)\n",ModesVGA[i].sbytes));
  1306. VideoDebugPrint((2, " memory reqd(%d)\n",ModesVGA[i].numPlanes * ModesVGA[i].sbytes));
  1307. VideoDebugPrint((2, " memory pres(%d)\n",HwDeviceExtension->AdapterMemorySize));
  1308. } else {
  1309. VideoDebugPrint((2, "mode[%d] invalid\n",i));
  1310. VideoDebugPrint((2, " hres(%d)\n",ModesVGA[i].hres));
  1311. VideoDebugPrint((2, " bitsPerPlane(%d)\n",ModesVGA[i].bitsPerPlane));
  1312. VideoDebugPrint((2, " freq(%d)\n",ModesVGA[i].Frequency));
  1313. VideoDebugPrint((2, " interlace(%d)\n",ModesVGA[i].Interlaced));
  1314. VideoDebugPrint((2, " numPlanes(%d)\n",ModesVGA[i].numPlanes));
  1315. VideoDebugPrint((2, " sbytes(%d)\n",ModesVGA[i].sbytes));
  1316. VideoDebugPrint((2, " memory reqd(%d)\n",ModesVGA[i].numPlanes * ModesVGA[i].sbytes));
  1317. VideoDebugPrint((2, " memory pres(%d)\n",HwDeviceExtension->AdapterMemorySize));
  1318. }
  1319. }
  1320. }