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.

1782 lines
63 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Copyright (c) 1993 Compaq Computer Corporation
  4. Module Name:
  5. modeset.c
  6. Abstract:
  7. This is the modeset code for the QVision miniport driver.
  8. Environment:
  9. kernel mode only
  10. Notes:
  11. Revision History:
  12. $0007
  13. MikeD: 06/17/1994
  14. . fixed switch statement in VgaSetMode() to set proper full-screen
  15. mode (problem found in Japanese NT)
  16. $0006
  17. miked: 02/17/1994
  18. . took out conditional debug code to satisfy MSBHPD
  19. $0005 - MikeD - 02/08/94
  20. . modified to work with build 547's new display.cpl
  21. $0004
  22. miked: 1/26/1994
  23. . Added debug print code without all the other DBG overhead
  24. . Added third party monitor support to force a 76Hz refresh rate
  25. --*/
  26. #include "dderror.h"
  27. #include "devioctl.h"
  28. #include "miniport.h"
  29. #include "ntddvdeo.h"
  30. #include "video.h"
  31. #include "qvision.h"
  32. #include "modeset.h"
  33. VOID
  34. VgaZeroVideoMemory(
  35. PHW_DEVICE_EXTENSION HwDeviceExtension
  36. );
  37. VOID
  38. SetQVisionBanking(
  39. PHW_DEVICE_EXTENSION HwDeviceExtension,
  40. ULONG BankNumber
  41. );
  42. //---------------------------------------------------------------------------
  43. VP_STATUS
  44. VgaInterpretCmdStream(
  45. PHW_DEVICE_EXTENSION HwDeviceExtension,
  46. PUSHORT pusCmdStream
  47. )
  48. /*++
  49. Routine Description:
  50. Interprets the appropriate command array to set up VGA registers for the
  51. requested mode. Typically used to set the VGA into a particular mode by
  52. programming all of the registers
  53. Arguments:
  54. HwDeviceExtension - Pointer to the miniport driver's device extension.
  55. pusCmdStream - array of commands to be interpreted.
  56. Return Value:
  57. The status of the operation (can only fail on a bad command); TRUE for
  58. success, FALSE for failure.
  59. --*/
  60. {
  61. ULONG ulCmd; /* OP code for the Cmd stream */
  62. ULONG ulPort; /* address port for the command */
  63. UCHAR jValue; /* byte value to use in operation */
  64. USHORT usValue; /* word value to use in operation */
  65. ULONG culCount; /* number of values in the command */
  66. ULONG ulIndex; /* index to start from in the indexed command */
  67. ULONG ulBase; /* base */
  68. // PUSHORT pusTempMonData; /* temporary CRTCData pointer */
  69. // ULONG ulEndOfMonData; // address of the end of the MonData array
  70. ULONG resIndex, monIndex; // indexes into MonData
  71. PMONRES pMonRes; // pointer to MONRES
  72. VideoDebugPrint((1, "QVision.sys: VgaInterpretCmdStream - ENTRY.\n"));
  73. if (pusCmdStream == NULL) {
  74. VideoDebugPrint((1, "\tInvalid pusCmdStream\n"));
  75. return TRUE;
  76. }
  77. ulBase = (ULONG)HwDeviceExtension->IOAddress;
  78. //
  79. // Now set the adapter to the desired mode.
  80. //
  81. while ((ulCmd = *pusCmdStream++) != EOD) {
  82. //
  83. // Determine major command type
  84. //
  85. switch (ulCmd & 0xF0) {
  86. //
  87. // Basic input/output command
  88. //
  89. case INOUT:
  90. VideoDebugPrint((2,"\tINOUT - "));
  91. //
  92. // Determine type of inout instruction
  93. //
  94. if (!(ulCmd & IO)) {
  95. //
  96. // Out instruction. Single or multiple outs?
  97. //
  98. if (!(ulCmd & MULTI)) {
  99. VideoDebugPrint((2,"SINGLE OUT - "));
  100. //
  101. // Single out. Byte or word out?
  102. //
  103. if (!(ulCmd & BW)) {
  104. VideoDebugPrint((2,"BYTE\n"));
  105. //
  106. // Single byte out
  107. //
  108. ulPort = *pusCmdStream++;
  109. jValue = (UCHAR) *pusCmdStream++;
  110. VideoPortWritePortUchar((PUCHAR)(ulBase+ulPort),
  111. jValue);
  112. if (ulPort == MISC_OUTPUT_REG_WRITE_PORT) {
  113. //
  114. // $0006 - MikeD - 03/04/94
  115. // Begin: add 10 millisecond delay after r/w
  116. // of 3c2
  117. //
  118. // 10000microsecs = 10ms
  119. //
  120. // I know I should not stall more than 50, but
  121. // there is no other way around this...
  122. VideoPortStallExecution( 10000 );
  123. }
  124. } else {
  125. VideoDebugPrint((2,"WORD\n"));
  126. //
  127. // Single word out
  128. //
  129. ulPort = *pusCmdStream++;
  130. usValue = *pusCmdStream++;
  131. VideoPortWritePortUshort((PUSHORT)(ulBase+ulPort),
  132. usValue);
  133. }
  134. } else {
  135. VideoDebugPrint((2,"MULTIPLE OUTS - "));
  136. //
  137. // Output a string of values
  138. // Byte or word outs?
  139. //
  140. if (!(ulCmd & BW)) {
  141. VideoDebugPrint((2,"BYTES\n"));
  142. //
  143. // String byte outs. Do in a loop; can't use
  144. // VideoPortWritePortBufferUchar because the data
  145. // is in USHORT form
  146. //
  147. ulPort = ulBase + *pusCmdStream++;
  148. culCount = *pusCmdStream++;
  149. while (culCount--) {
  150. jValue = (UCHAR) *pusCmdStream++;
  151. VideoPortWritePortUchar((PUCHAR)ulPort,
  152. jValue);
  153. }
  154. } else {
  155. VideoDebugPrint((2,"WORDS\n"));
  156. //
  157. // String word outs
  158. //
  159. ulPort = *pusCmdStream++;
  160. culCount = *pusCmdStream++;
  161. VideoPortWritePortBufferUshort((PUSHORT)
  162. (ulBase + ulPort), pusCmdStream, culCount);
  163. pusCmdStream += culCount;
  164. }
  165. }
  166. } else {
  167. VideoDebugPrint((2,"SINGLE IN - "));
  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. VideoDebugPrint((2,"BYTE\n"));
  177. //
  178. // Single byte in
  179. //
  180. ulPort = *pusCmdStream++;
  181. jValue = VideoPortReadPortUchar((PUCHAR)ulBase+ulPort);
  182. } else {
  183. VideoDebugPrint((2,"WORD\n"));
  184. //
  185. // Single word in
  186. //
  187. ulPort = *pusCmdStream++;
  188. usValue = VideoPortReadPortUshort((PUSHORT)
  189. (ulBase+ulPort));
  190. }
  191. }
  192. break;
  193. //
  194. // Higher-level input/output commands
  195. //
  196. case METAOUT:
  197. VideoDebugPrint((2,"\tMETAOUT - "));
  198. //
  199. // Determine type of metaout command, based on minor
  200. // command field
  201. //
  202. switch (ulCmd & 0x0F) {
  203. //
  204. // Indexed outs
  205. //
  206. case INDXOUT:
  207. VideoDebugPrint((2,"INDXOUT\n"));
  208. ulPort = ulBase + *pusCmdStream++;
  209. culCount = *pusCmdStream++;
  210. ulIndex = *pusCmdStream++;
  211. while (culCount--) {
  212. usValue = (USHORT) (ulIndex +
  213. (((ULONG)(*pusCmdStream++)) << 8));
  214. VideoPortWritePortUshort((PUSHORT)ulPort, usValue);
  215. ulIndex++;
  216. }
  217. break;
  218. //
  219. // Masked out (read, AND, XOR, write)
  220. //
  221. case MASKOUT:
  222. VideoDebugPrint((2,"MASKOUT\n"));
  223. ulPort = *pusCmdStream++;
  224. jValue = VideoPortReadPortUchar((PUCHAR)ulBase+ulPort);
  225. jValue &= *pusCmdStream++;
  226. jValue ^= *pusCmdStream++;
  227. VideoPortWritePortUchar((PUCHAR)ulBase + ulPort,
  228. jValue);
  229. break;
  230. //
  231. // Attribute Controller out
  232. //
  233. case ATCOUT:
  234. VideoDebugPrint((2,"ATCOUT\n"));
  235. ulPort = ulBase + *pusCmdStream++;
  236. culCount = *pusCmdStream++;
  237. ulIndex = *pusCmdStream++;
  238. while (culCount--) {
  239. // Write Attribute Controller index
  240. VideoPortWritePortUchar((PUCHAR)ulPort,
  241. (UCHAR)ulIndex);
  242. // Write Attribute Controller data
  243. jValue = (UCHAR) *pusCmdStream++;
  244. VideoPortWritePortUchar((PUCHAR)ulPort, jValue);
  245. ulIndex++;
  246. }
  247. break;
  248. default:
  249. return FALSE;
  250. }
  251. break;
  252. //
  253. // NOP
  254. //
  255. case NCMD:
  256. VideoDebugPrint((2,"\tNCMD\n"));
  257. break;
  258. case QVCMD:
  259. VideoDebugPrint((2,"\tQVCMDS - "));
  260. switch (ulCmd & 0x0F) {
  261. //
  262. // Set the CRTC registers based on the monitor which is currently
  263. // attached to the QVision card.
  264. // HwDeviceExtension->ModeIndex contains current mode index.
  265. // HwDeviceExtension->VideoHardware.MonClass = current monitor.
  266. //
  267. case SETMONCRTC:
  268. VideoDebugPrint((2,"SETMONCRTC\n"));
  269. ulPort = ulBase + CRTC_ADDRESS_PORT_COLOR;
  270. // $0005 - MikeD - 02/08/94
  271. // Begin:-
  272. //
  273. // implemented direct indexing...
  274. //
  275. // get resolution index from requested mode
  276. resIndex =
  277. ModesVGA[HwDeviceExtension->ModeIndex].ulResIndex;
  278. // get monitor index from monitor class
  279. monIndex =
  280. HwDeviceExtension->VideoHardware.MonClass;
  281. // set direct pointer to specific MONRES element
  282. // for clarity
  283. pMonRes = &MonData[monIndex].MonitorResolution[resIndex];
  284. //
  285. // set CRTC registers if necessary
  286. //
  287. if (pMonRes->bRegsPresent) {
  288. for (ulIndex = 0; ulIndex < 25; ulIndex++) {
  289. usValue = (USHORT) (ulIndex +
  290. (ULONG) (pMonRes->crtRegisters[ulIndex] << 8));
  291. VideoPortWritePortUshort((PUSHORT)ulPort, usValue);
  292. }
  293. }
  294. //
  295. // $0005 - MikeD - 02/08/94
  296. // End:
  297. //
  298. break;
  299. //
  300. // Set the Overflow2 register based on the monitor
  301. // which is currently attached to the QVision card.
  302. //
  303. case SETMONOVFLW:
  304. VideoDebugPrint((2,"SETMONOVFLW\n"));
  305. ulPort = ulBase + GRAPH_ADDRESS_PORT;
  306. ulIndex = OVERFLOW_REG_2;
  307. // $0005 - MikeD - 02/08/94
  308. // Begin:
  309. //
  310. // implemented direct indexing...
  311. //
  312. // get resolution index from requested mode
  313. resIndex =
  314. ModesVGA[HwDeviceExtension->ModeIndex].ulResIndex;
  315. // get monitor index from monitor class
  316. monIndex =
  317. HwDeviceExtension->VideoHardware.MonClass;
  318. // set direct pointer to specific MONRES element
  319. // for clarity
  320. pMonRes = &MonData[monIndex].MonitorResolution[resIndex];
  321. //
  322. // set Overflow register if necessary
  323. //
  324. if (pMonRes->bRegsPresent) {
  325. usValue = (USHORT) (ulIndex +
  326. (ULONG) (pMonRes->Overflow << 8));
  327. VideoPortWritePortUshort((PUSHORT)ulPort, usValue);
  328. }
  329. //
  330. // $0005 - MikeD - 02/08/94
  331. // End:
  332. //
  333. break;
  334. //
  335. // Set the Misc out register based on the monitor which
  336. // is currently attached to the QVision card.
  337. //
  338. case SETMISCOUT:
  339. VideoDebugPrint((2,"SETMISCOUT\n"));
  340. ulPort = ulBase + MISC_OUTPUT_REG_WRITE_PORT;
  341. // $0005 - MikeD - 02/08/94
  342. // Begin:
  343. //
  344. // implemented direct indexing...
  345. //
  346. // get resolution index from requested mode
  347. resIndex =
  348. ModesVGA[HwDeviceExtension->ModeIndex].ulResIndex;
  349. // get monitor index from monitor class
  350. monIndex =
  351. HwDeviceExtension->VideoHardware.MonClass;
  352. // set direct pointer to specific MONRES element
  353. // for clarity
  354. pMonRes = &MonData[monIndex].MonitorResolution[resIndex];
  355. //
  356. // set Misc OUT register if necessary
  357. //
  358. if (pMonRes->bRegsPresent) {
  359. VideoPortWritePortUshort(
  360. (PUSHORT)ulPort,
  361. pMonRes->MiscOut);
  362. //
  363. // $0006 - MikeD - 03/04/94
  364. // Begin: add 10 millisecond delay after r/w
  365. // of 3c2
  366. //
  367. // 10000microsecs = 10ms
  368. //
  369. // I know I should not stall more than 50, but
  370. // there is no other way around this...
  371. VideoPortStallExecution( 10000 );
  372. }
  373. //
  374. // $0005 - MikeD - 02/08/94
  375. // End:
  376. //
  377. break;
  378. //
  379. // None of the above; error
  380. //
  381. //
  382. // Write directly to the port provided. This is used for
  383. // writing to extended registers or to registers which are
  384. // not based on the IOAddress.
  385. // This can be used to write many bytes to a port if
  386. // it is auto-incremented.
  387. //
  388. case BYTE2PORT:
  389. VideoDebugPrint((2,"BYTE2PORT\n"));
  390. ulPort = *pusCmdStream++;
  391. culCount = *pusCmdStream++;
  392. while (culCount--) {
  393. jValue = (UCHAR) *pusCmdStream++;
  394. VideoPortWritePortUchar((PUCHAR)ulPort,
  395. jValue);
  396. } // switch minor
  397. break;
  398. } // switch major
  399. break;
  400. //
  401. // This command initializes the ARIES memory before
  402. // the adapter is configured.
  403. //
  404. case QVNEW:
  405. switch (ulCmd & 0x0F) {
  406. //
  407. // We know that this is an ARIES mode. The command set
  408. // before this command unlocked the extended registers by
  409. // writing a 0x05 to 3CF.0F and a 0x28 to 3CF.10.
  410. // We need to make sure that if we are on a Juniper
  411. // we set single clock, 1024 pitch, and we disable the
  412. // advanced Juniper modes.
  413. // We also disable the Juniper extended register decode.
  414. // After we do that, we must make sure that we unlock the
  415. // Aries extended registers for safety. I don't know
  416. // if they are being locked by disabling the Juniper regs.
  417. //
  418. case ARIES:
  419. VideoDebugPrint((2,"\t ARIES_MODE\n"));
  420. if ((HwDeviceExtension->VideoHardware.AdapterType == JuniperIsa) ||
  421. (HwDeviceExtension->VideoHardware.AdapterType == JuniperEisa))
  422. {
  423. VideoPortWritePortUchar((PUCHAR)ARIES_CTL_1, // 1 pixel = 1 byte
  424. 0x03);
  425. VideoPortWritePortUchar((PUCHAR)CTRL_REG_2, // ORION-12 register access
  426. 0x10);
  427. VideoPortWritePortUchar((PUCHAR)CTRL_REG_3, // 1024 pixel pitch
  428. 0x05); // 1MB memory decode
  429. jValue = VideoPortReadPortUchar((PUCHAR)DAC_CMD_1);
  430. VideoPortWritePortUchar((PUCHAR)DAC_CMD_1,
  431. (UCHAR)(jValue | 0x80));
  432. VideoPortWritePortUchar((PUCHAR)(HwDeviceExtension->IOAddress +
  433. DAC_ADDRESS_WRITE_PORT),
  434. (UCHAR)(DAC_CMD_3_INDEX));
  435. VideoPortWritePortUchar((PUCHAR)DAC_STATUS_REG,
  436. (UCHAR)(VideoPortReadPortUchar((PUCHAR)DAC_STATUS_REG) &
  437. ~DBL_CLK));
  438. VideoPortWritePortUchar((PUCHAR)CTRL_REG_2, // disable ext Juniper regs
  439. 0x00);
  440. jValue = VideoPortReadPortUchar((PUCHAR)DAC_CMD_0); // disable 485 modes.
  441. VideoPortWritePortUchar((PUCHAR)DAC_CMD_0,
  442. (UCHAR)(jValue & 0x7F));
  443. VideoPortWritePortUshort((PUSHORT)GRAPH_ADDRESS_PORT, // unlock ext. regs
  444. 0x050f);
  445. VideoPortWritePortUshort((PUSHORT)GRAPH_ADDRESS_PORT, // enable BitBlt
  446. 0x2810);
  447. } // if
  448. break;
  449. //
  450. // We know that his is a V32 mode. In this case
  451. // make sure that the clock is doubled, the pitch
  452. // is 2048 and the Juniper extended registers are accessible.
  453. //
  454. case V32:
  455. VideoDebugPrint((2,"\t JUNIPER_MODE\n"));
  456. // VidalL 04/25/93
  457. //
  458. // IMPORTANT:
  459. // ==========
  460. // The AQUILLA monitor REQUIRES pixel clock 2 (value 30h)
  461. // The 60Hz and 68Hz timings require pixel clock 1
  462. // (value 20h). If this value is not set correctly for
  463. // the correct monitor, then the 1280 screen WILL NOT
  464. // SYNC !!!!! So, determine the correct value here below.
  465. //
  466. // if (HwDeviceExtension->VideoHardware.MonClass==Monitor_1280)
  467. // VideoPortWritePortUchar((PUCHAR)DAC_CMD_2, 0x30);
  468. // else
  469. // VideoPortWritePortUchar((PUCHAR)DAC_CMD_2, 0x20);
  470. //
  471. //
  472. /*** $0004 ************ miked 1/26/1994 *****************************
  473. ***
  474. *** Added third party monitor support to force a 76Hz refresh rate
  475. *** using the same timings as the QV200 timings.
  476. ***
  477. *** Note: A new MonClass entry for 76Hz was used,
  478. *** See modeqv.h.
  479. ***
  480. ***********************************************************************/
  481. if (HwDeviceExtension->VideoHardware.MonClass==Monitor_1280 ||
  482. HwDeviceExtension->VideoHardware.MonClass==Monitor_76Hz)
  483. VideoPortWritePortUchar((PUCHAR)DAC_CMD_2, 0x30);
  484. else
  485. VideoPortWritePortUchar((PUCHAR)DAC_CMD_2, 0x20);
  486. /***********************************************************************/
  487. VideoPortWritePortUchar((PUCHAR)ARIES_CTL_1, // 1 pixel = 1 byte
  488. 0x03);
  489. VideoPortWritePortUchar((PUCHAR)CTRL_REG_2, // ORION-12 register access
  490. 0x10);
  491. VideoPortWritePortUchar((PUCHAR)CTRL_REG_3, // 2048 pixel pitch
  492. 0x09); // 2MB memory decode
  493. jValue = VideoPortReadPortUchar((PUCHAR)DAC_CMD_0);
  494. VideoPortWritePortUchar((PUCHAR)DAC_CMD_0,
  495. (UCHAR)(jValue | 0x80));
  496. VideoPortWritePortUchar((PUCHAR)(HwDeviceExtension->IOAddress +
  497. DAC_ADDRESS_WRITE_PORT),
  498. (UCHAR)(DAC_CMD_3_INDEX));
  499. VideoPortWritePortUchar((PUCHAR)DAC_STATUS_REG,
  500. (UCHAR)(VideoPortReadPortUchar((PUCHAR)DAC_STATUS_REG) |
  501. DBL_CLK));
  502. VideoPortWritePortUshort((PUSHORT)GRAPH_ADDRESS_PORT, // unlock ext. regs
  503. 0x050f);
  504. VideoPortWritePortUshort((PUSHORT)GRAPH_ADDRESS_PORT, // enable BitBlt
  505. 0x2810);
  506. break;
  507. //
  508. // For future V35 enhancements.
  509. //
  510. case V35:
  511. break;
  512. case SETRAM:
  513. VideoDebugPrint((2,"SETRAM\n"));
  514. VideoPortReadPortUchar((PUCHAR)0x03BA);
  515. VideoPortReadPortUchar((PUCHAR)0x03DA);
  516. VideoPortReadPortUchar((PUCHAR)(ulBase + ATT_ADDRESS_PORT));
  517. VideoPortWritePortUchar((PUCHAR)(ulBase + DAC_PIXEL_MASK_PORT), 0x00);
  518. // start sync reset for the sequencer
  519. VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_ADDRESS_PORT),
  520. IND_SYNC_RESET);
  521. VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_DATA_PORT),
  522. START_SYNC_RESET_VALUE);
  523. // set clock mode register 1 to 3c5.01 = 0x21 (turn off video and 8bit pixel
  524. VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_ADDRESS_PORT),
  525. 0x01);
  526. VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_DATA_PORT),
  527. 0x21);
  528. // set sequencer memory mode register 4 to 3c5.04 = 0x0e
  529. VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_ADDRESS_PORT),
  530. IND_MEMORY_MODE);
  531. VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_DATA_PORT),
  532. 0x0e);
  533. // end sync reset for the sequencer
  534. VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_ADDRESS_PORT),
  535. IND_SYNC_RESET);
  536. VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_DATA_PORT),
  537. END_SYNC_RESET_VALUE);
  538. // unlock graphics registers 3cf.0f = 0x05
  539. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
  540. 0x0f);
  541. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
  542. 0x05);
  543. // set aavga mode 3cf.40 = 0x01
  544. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
  545. 0x40);
  546. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
  547. 0x01);
  548. // set sequencer memory pixel write mask register 2 to 3c5.02 = 0xff
  549. VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_ADDRESS_PORT),
  550. 0x02);
  551. VideoPortWritePortUchar((PUCHAR)(ulBase + SEQ_DATA_PORT),
  552. 0xff);
  553. // unlock BITBLT registers 3cf.10 = 0x28;
  554. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
  555. 0x10);
  556. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
  557. 0x28);
  558. // control register 1 63ca = 0x03
  559. VideoPortWritePortUchar((PUCHAR)ARIES_CTL_1, 0x03);
  560. // misc output register 3c2 = 0x27
  561. VideoPortWritePortUchar((PUCHAR)((PUCHAR)ulBase + MISC_OUTPUT_REG_WRITE_PORT),
  562. 0x27);
  563. //
  564. // $0006 - MikeD - 03/04/94
  565. // Begin: add 10 millisecond delay after r/w
  566. // of 3c2
  567. //
  568. // 10000microsecs = 10ms
  569. //
  570. // I know I should not stall more than 50, but
  571. // there is no other way around this...
  572. VideoPortStallExecution( 10000 );
  573. // set high address registers
  574. //
  575. // adrianc 4/7/1993
  576. // We are starting off with Banking so we do not set
  577. // the HIGH ADDRESS register yet.
  578. //
  579. //$DEL$// VideoPortWritePortUchar((PUCHAR)GRAPH_ADDRESS_PORT, HIGH_ADDR_MAP);
  580. //$DEL$// VideoPortWritePortUchar((PUCHAR)GRAPH_DATA_PORT, (UCHAR)((HwDeviceExtension->PhysicalSaveAddress >> 20) & 0x0FF));
  581. //$DEL$// VideoPortWritePortUchar((PUCHAR)GRAPH_ADDRESS_PORT, HIGH_ADDR_MAP+1);
  582. //$DEL$// VideoPortWritePortUchar((PUCHAR)GRAPH_DATA_PORT, (UCHAR)((HwDeviceExtension->PhysicalSaveAddress >> 28) & 0x0FF));
  583. //
  584. // set DAC registers
  585. VideoPortWritePortUchar((PUCHAR)DAC_CMD_0, 0x00);
  586. VideoPortWritePortUchar((PUCHAR)DAC_CMD_1, 0x40);
  587. VideoPortWritePortUchar((PUCHAR)DAC_CMD_2, 0x20);
  588. // unlock ctrc registers
  589. VideoPortWritePortUchar((PUCHAR)((PUCHAR)ulBase + CRTC_ADDRESS_PORT_MONO + COLOR_ADJUSTMENT),
  590. (UCHAR)0x11);
  591. VideoPortWritePortUchar((PUCHAR)((PUCHAR)ulBase + CRTC_DATA_PORT_MONO + COLOR_ADJUSTMENT),
  592. 0x00);
  593. // set crtc registers
  594. { UCHAR *crtc_values = "\xA1\x7F\x7F\x84\x85\x9B\x2E\xF5\x0\x60\x0\x0\x0\x0\x0\x0\x7\x8B\xFF\x80\x0\xFF\x2E\xE3\xFF";
  595. for(culCount=0; culCount <= 0x18 ; culCount++, crtc_values++) {
  596. VideoPortWritePortUchar((PUCHAR)((PUCHAR)ulBase + CRTC_ADDRESS_PORT_MONO + COLOR_ADJUSTMENT),
  597. (UCHAR)culCount);
  598. VideoPortWritePortUchar((PUCHAR)((PUCHAR)ulBase + CRTC_DATA_PORT_MONO + COLOR_ADJUSTMENT),
  599. *crtc_values);
  600. }
  601. }
  602. // setup crt overflow regs
  603. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
  604. OVERFLOW_REG_1);
  605. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
  606. 0x00);
  607. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
  608. OVERFLOW_REG_2);
  609. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
  610. 0x00);
  611. // setup overscan color registers
  612. VideoPortWritePortUchar((PUCHAR)CO_COLOR_WRITE, 0x00);
  613. for (culCount=0; culCount<3; culCount++) {
  614. VideoPortWritePortUchar((PUCHAR)CO_COLOR_DATA, 0x00);
  615. }
  616. // setup attribute controller
  617. VideoPortReadPortUchar((PUCHAR)0x3da); // reset the latch
  618. for (culCount=0; culCount < 0x10; culCount++) {
  619. VideoPortWritePortUchar((PUCHAR)((PUCHAR)ulBase + ATT_ADDRESS_PORT),
  620. (UCHAR)culCount);
  621. VideoPortWritePortUchar((PUCHAR)((PUCHAR)ulBase + ATT_DATA_WRITE_PORT),
  622. (UCHAR)culCount);
  623. }
  624. VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_ADDRESS_PORT), 0x10);
  625. VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_DATA_WRITE_PORT),0x41);
  626. VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_ADDRESS_PORT),0x11);
  627. VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_DATA_WRITE_PORT),0x00);
  628. VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_ADDRESS_PORT), 0x12);
  629. VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_DATA_WRITE_PORT), 0x0f);
  630. VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_ADDRESS_PORT), 0x13);
  631. VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_DATA_WRITE_PORT), 0x00);
  632. VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_ADDRESS_PORT), 0x14);
  633. VideoPortWritePortUchar((PUCHAR)(ulBase + ATT_DATA_WRITE_PORT), 0x00);
  634. // setup graphics register
  635. for (culCount=0; culCount < 0x06; culCount++) {
  636. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
  637. (UCHAR)culCount);
  638. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
  639. 0x00);
  640. }
  641. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
  642. 0x06);
  643. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
  644. 0x05);
  645. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
  646. 0x07);
  647. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
  648. 0x0f);
  649. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
  650. 0x08);
  651. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
  652. 0xff);
  653. { /* FIX VGA BUG */
  654. USHORT Port = (USHORT)(ulBase + CRTC_ADDRESS_PORT_MONO);
  655. VideoPortWritePortUchar((PUCHAR)0x03C4, 0x07);
  656. if (VideoPortReadPortUchar((PUCHAR)(ulBase + MISC_OUTPUT_REG_READ_PORT)) & 0x01) {
  657. Port += COLOR_ADJUSTMENT;
  658. //
  659. // $0006 - MikeD - 03/04/94
  660. // Begin: add 10 millisecond delay after r/w
  661. // of 3c2
  662. //
  663. // 10000microsecs = 10ms
  664. //
  665. // I know I should not stall more than 50, but
  666. // there is no other way around this...
  667. VideoPortStallExecution( 10000 );
  668. }
  669. VideoPortWritePortUchar((PUCHAR)Port,
  670. 0x3F);
  671. VideoPortWritePortUchar((PUCHAR)Port + 1,
  672. 0x01);
  673. }
  674. // Enable BitBlt and disable IRQ 9
  675. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
  676. 0x10);
  677. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
  678. 0x68);
  679. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
  680. 0x28);
  681. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
  682. 0x5a);
  683. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
  684. 0x6);
  685. // reset the Pattern registers
  686. VideoPortWritePortUchar((PUCHAR)PREG_0, 0);
  687. VideoPortWritePortUchar((PUCHAR)PREG_1, 0);
  688. VideoPortWritePortUchar((PUCHAR)PREG_2, 0);
  689. VideoPortWritePortUchar((PUCHAR)PREG_3, 0);
  690. VideoPortWritePortUchar((PUCHAR)PREG_4, 0);
  691. VideoPortWritePortUchar((PUCHAR)PREG_5, 0);
  692. VideoPortWritePortUchar((PUCHAR)PREG_6, 0);
  693. VideoPortWritePortUchar((PUCHAR)PREG_7, 0);
  694. // Reset the BitBlt registers
  695. VideoPortWritePortUchar((PUCHAR)BLT_DEST_ADDR_LO, 0);
  696. VideoPortWritePortUchar((PUCHAR)BLT_DEST_ADDR_HI, 0);
  697. VideoPortWritePortUshort((PUSHORT)BITMAP_WIDTH, 0x400);
  698. VideoPortWritePortUshort((PUSHORT)BITMAP_HEIGHT, 0x3ff);
  699. VideoPortWritePortUchar((PUCHAR)BLT_CMD_1, 0xc0);
  700. VideoPortWritePortUchar((PUCHAR)BLT_CMD_0, 0x01);
  701. VideoPortReadPortUchar((PUCHAR)ARIES_CTL_1);
  702. // Enable BitBlt and disable IRQ 9
  703. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_ADDRESS_PORT),
  704. 0x10);
  705. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
  706. 0x68);
  707. VideoPortWritePortUchar((PUCHAR)(ulBase + GRAPH_DATA_PORT),
  708. 0x28);
  709. break;
  710. } // switch
  711. break;
  712. //
  713. // Unknown command; error
  714. //
  715. default:
  716. VideoDebugPrint((2,"\tdefault\n"));
  717. return FALSE;
  718. }
  719. }
  720. VideoDebugPrint((1, "QVision.sys: VgaInterpretCmdStream - EXIT.\n"));
  721. return TRUE;
  722. } // end VgaInterpretCmdStream()
  723. //---------------------------------------------------------------------------
  724. VP_STATUS
  725. VgaSetMode(
  726. PHW_DEVICE_EXTENSION HwDeviceExtension,
  727. PVIDEO_MODE Mode,
  728. ULONG ModeSize
  729. )
  730. /*++
  731. Routine Description:
  732. This routine sets the vga into the requested mode.
  733. Arguments:
  734. HwDeviceExtension - Pointer to the miniport driver's device extension.
  735. Mode - Pointer to the structure containing the information about the
  736. font to be set.
  737. ModeSize - Length of the input buffer supplied by the user.
  738. Return Value:
  739. ERROR_INSUFFICIENT_BUFFER if the input buffer was not large enough
  740. for the input data.
  741. ERROR_INVALID_PARAMETER if the mode number is invalid.
  742. NO_ERROR if the operation completed successfully.
  743. --*/
  744. {
  745. PVIDEOMODE pRequestedMode;
  746. PUSHORT pusCmdStream;
  747. VIDEO_X86_BIOS_ARGUMENTS biosArguments;
  748. UCHAR ucTemp; // temporary register storage
  749. UCHAR temp;
  750. UCHAR dummy;
  751. UCHAR bIsColor;
  752. VideoDebugPrint((1,"QVision.sys: VgaSetMode - ENTRY.\n"));
  753. VideoDebugPrint((1,"\tRequested Mode = 0x%x\n",Mode->RequestedMode));
  754. #ifdef QV_DBG
  755. DbgBreakPoint();
  756. #endif
  757. //
  758. // Check if the size of the data in the input buffer is large enough.
  759. //
  760. if (ModeSize < sizeof(VIDEO_MODE)) {
  761. return ERROR_INSUFFICIENT_BUFFER;
  762. }
  763. //
  764. // Blank the screen prior to clearing video memory
  765. //
  766. VideoPortWritePortUchar((PUCHAR)(HwDeviceExtension->IOAddress +
  767. SEQ_ADDRESS_PORT), (UCHAR) 0x01);
  768. ucTemp = VideoPortReadPortUchar((PUCHAR) HwDeviceExtension->IOAddress +
  769. SEQ_DATA_PORT);
  770. VideoPortWritePortUchar((PUCHAR)(HwDeviceExtension->IOAddress +
  771. SEQ_DATA_PORT), (UCHAR)(ucTemp | (UCHAR) 0x20));
  772. //
  773. // Extract the clear memory bit.
  774. //
  775. if (Mode->RequestedMode & VIDEO_MODE_NO_ZERO_MEMORY) {
  776. Mode->RequestedMode &= ~VIDEO_MODE_NO_ZERO_MEMORY;
  777. }
  778. else {
  779. VgaZeroVideoMemory(HwDeviceExtension);
  780. }
  781. //
  782. // Check to see if we are requesting a valid mode
  783. //
  784. if ( (Mode->RequestedMode >= NumVideoModes) ||
  785. (!ModesVGA[Mode->RequestedMode].ValidMode) ) {
  786. VideoDebugPrint((1,"\tERROR_INVALID_PARAMETER.\n"));
  787. return ERROR_INVALID_PARAMETER;
  788. }
  789. pRequestedMode = &ModesVGA[Mode->RequestedMode];
  790. //
  791. // Store the new mode value.
  792. //
  793. HwDeviceExtension->CurrentMode = pRequestedMode;
  794. HwDeviceExtension->ModeIndex = Mode->RequestedMode;
  795. //
  796. // $0005 - MikeD - 02/08/94
  797. // Begin:
  798. // Daytona - MikeD - 02/09/94 need to set MonClass based on requested
  799. // refresh rate.
  800. //
  801. HwDeviceExtension->VideoHardware.lFrequency = pRequestedMode->ulRefreshRate;
  802. GetMonClass(HwDeviceExtension);
  803. //
  804. // End:
  805. // Daytona - MikeD - 02/09/94
  806. //
  807. //
  808. // Select proper command array for adapter type
  809. //
  810. #ifdef INIT_INT10
  811. {
  812. VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  813. biosArguments.Eax = pRequestedMode->usInt10ModeNum;
  814. VideoPortInt10(HwDeviceExtension, &biosArguments);
  815. }
  816. #else
  817. /***********************************************************************
  818. *** There appears to be a problem with some application ***
  819. *** which reset the first 16 palette registers. ***
  820. *** Since the palette is not reset when going to and ***
  821. *** from text modes by doing a set mode (instead of ***
  822. *** the hardware save restore), some colors might not ***
  823. *** appear as expected in the text modes. The bios ***
  824. *** calls seem to reload the palette so Andre Vachon ***
  825. *** suggested that we implement an Int10 mode set for the ***
  826. *** text modes. ***
  827. *** To accomplish this, we need to hard code the first ***
  828. *** three modes in modeset.h in the following switch. ***
  829. *** If more text modes are added to modeset.h, their ***
  830. *** index must be added to this switch statement. ***
  831. ***********************************************************************/
  832. VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  833. //
  834. // $0007 - MikeD - 06/17/94
  835. // Must key off of ulResIndex instead of Mode->RequestedMode since its
  836. // not a one-to-one relationship anymore. The Mode->RequestedMode now
  837. // acts as an index into ModesVGA[] and therefore the index used for
  838. // each monitor refresh (i.e. QV_TEXT_720x400x4_INDEX) is duplicated
  839. // across each like mode (with different refresh rates). This was
  840. // found in Japanese NT because when the vdm requests full-screen, it
  841. // is a different mode than when the U.S. NT requests a full-screen.
  842. //
  843. // OLD WAY ===> switch (Mode->RequestedMode) {
  844. switch (pRequestedMode->ulResIndex) {
  845. case 0: // 720x400
  846. /***********************************************************************
  847. *** Prepare the card for the VGA mode 3+ instead of the CGA mode 3 ***
  848. ***********************************************************************/
  849. biosArguments.Eax = 0x1202; // Select Scan line number
  850. biosArguments.Ebx = 0x0030; // to be 400 scan lines
  851. VideoPortInt10(HwDeviceExtension, &biosArguments);
  852. /***********************************************************************
  853. *** Set the video mode to BIOS mode 3. ***
  854. ***********************************************************************/
  855. VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  856. biosArguments.Eax = 0x03; // bios mode 0x03
  857. VideoPortInt10(HwDeviceExtension, &biosArguments);
  858. break;
  859. case 1: // 640x350
  860. /***********************************************************************
  861. *** Prepare the card for the EGA mode 3* instead of the CGA mode 3 ***
  862. ***********************************************************************/
  863. biosArguments.Eax = 0x1201; // Select Scan line number
  864. biosArguments.Ebx = 0x0030; // to be 350 scan lines
  865. VideoPortInt10(HwDeviceExtension, &biosArguments);
  866. /***********************************************************************
  867. *** Set the video mode to BIOS mode 3. ***
  868. ***********************************************************************/
  869. VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
  870. biosArguments.Eax = 0x03; // bios mode 0x03
  871. VideoPortInt10(HwDeviceExtension, &biosArguments);
  872. break;
  873. case 2: // 640x480x4
  874. biosArguments.Eax = 0x12; // bios mode 0x12
  875. VideoPortInt10(HwDeviceExtension, &biosArguments);
  876. break;
  877. default: // all graphics modes are
  878. // handled by the default case
  879. pusCmdStream = pRequestedMode->CmdStrings.QVCmdStrings;
  880. VgaInterpretCmdStream(HwDeviceExtension, pusCmdStream);
  881. break;
  882. } // switch
  883. //
  884. // Fix to get 640x350 text mode
  885. //
  886. if (!(pRequestedMode->fbType & VIDEO_MODE_GRAPHICS)) {
  887. //
  888. // Fix to make sure we always set the colors in text mode to be
  889. // intensity, and not flashing
  890. // For this zero out the Mode Control Regsiter bit 3 (index 0x10
  891. // of the Attribute controller).
  892. //
  893. if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  894. MISC_OUTPUT_REG_READ_PORT) & 0x01) {
  895. bIsColor = TRUE;
  896. //
  897. // $0006 - MikeD - 03/04/94
  898. // Begin: add 10 millisecond delay after r/w
  899. // of 3c2
  900. //
  901. // 10000microsecs = 10ms
  902. //
  903. // I know I should not stall more than 50, but
  904. // there is no other way around this...
  905. VideoPortStallExecution( 10000 );
  906. } else {
  907. bIsColor = FALSE;
  908. }
  909. if (bIsColor) {
  910. dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  911. INPUT_STATUS_1_COLOR);
  912. } else {
  913. dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  914. INPUT_STATUS_1_MONO);
  915. } // else
  916. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  917. ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE));
  918. temp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  919. ATT_DATA_READ_PORT);
  920. temp &= 0xF7;
  921. if (bIsColor) {
  922. dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  923. INPUT_STATUS_1_COLOR);
  924. } else {
  925. dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  926. INPUT_STATUS_1_MONO);
  927. } // else
  928. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  929. ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE));
  930. VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
  931. ATT_DATA_WRITE_PORT, temp);
  932. } // if
  933. #endif
  934. //
  935. // Support 256 color modes by stretching the scan lines.
  936. //
  937. //
  938. // Update the location of the physical frame buffer within video memory.
  939. //
  940. HwDeviceExtension->PhysicalFrameLength =
  941. MemoryMaps[pRequestedMode->MemMap].MaxSize;
  942. HwDeviceExtension->PhysicalFrameBase.LowPart =
  943. MemoryMaps[pRequestedMode->MemMap].Start;
  944. //
  945. // Enable memory-mapped I/O if required
  946. //
  947. if ((Mode->RequestedMode != DEFAULT_MODE) &&
  948. (HwDeviceExtension->PhysicalMemoryMappedLength != 0)) {
  949. VideoPortWritePortUchar((PUCHAR) CTRL_REG_2, 0x10);
  950. VideoPortWritePortUchar((PUCHAR) MEMORY_MAP_BASE,
  951. (UCHAR) (HwDeviceExtension->PhysicalMemoryMappedBase.LowPart / 4096 - 0x80));
  952. VideoPortWritePortUchar((PUCHAR) CTRL_REG_2, 0x11);
  953. }
  954. //
  955. // Set the graphic cursor fg color (white)
  956. //
  957. VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_WRITE, CURSOR_COLOR_2);
  958. VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_DATA, 0xff);
  959. VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_DATA, 0xff);
  960. VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_DATA, 0xff);
  961. //
  962. // Set the graphic cursor bg color (black)
  963. //
  964. VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_WRITE, CURSOR_COLOR_1);
  965. VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_DATA, 0x00);
  966. VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_DATA, 0x00);
  967. VideoPortWritePortUchar( (PUCHAR) CURSOR_COLOR_DATA, 0x00);
  968. VideoDebugPrint((1,"QVision.sys: VgaSetMode - EXIT.\n"));
  969. return NO_ERROR;
  970. } //end VgaSetMode()
  971. //---------------------------------------------------------------------------
  972. VP_STATUS
  973. VgaQueryAvailableModes(
  974. PHW_DEVICE_EXTENSION HwDeviceExtension,
  975. PVIDEO_MODE_INFORMATION ModeInformation,
  976. ULONG ModeInformationSize,
  977. PULONG OutputSize
  978. )
  979. /*++
  980. Routine Description:
  981. This routine returns the list of all available available modes on the
  982. card.
  983. Arguments:
  984. HwDeviceExtension - Pointer to the miniport driver's device extension.
  985. ModeInformation - Pointer to the output buffer supplied by the user.
  986. This is where the list of all valid modes is stored.
  987. ModeInformationSize - Length of the output buffer supplied by the user.
  988. OutputSize - Pointer to a buffer in which to return the actual size of
  989. the data in the buffer. If the buffer was not large enough, this
  990. contains the minimum required buffer size.
  991. Return Value:
  992. ERROR_INSUFFICIENT_BUFFER if the output buffer was not large enough
  993. for the data being returned.
  994. NO_ERROR if the operation completed successfully.
  995. --*/
  996. {
  997. PVIDEO_MODE_INFORMATION videoModes = ModeInformation;
  998. ULONG i;
  999. VideoDebugPrint((1,"QVision.sys: VgaQueryAvailableModes - ENTRY.\n"));
  1000. //
  1001. // Find out the size of the data to be put in the buffer and return
  1002. // that in the status information (whether or not the information is
  1003. // there). If the buffer passed in is not large enough return an
  1004. // appropriate error code.
  1005. //
  1006. if (ModeInformationSize < (*OutputSize =
  1007. HwDeviceExtension->NumAvailableModes *
  1008. sizeof(VIDEO_MODE_INFORMATION)) ) {
  1009. VideoDebugPrint((1,"\tERROR_INSUFFICIENT_BUFFER.\n"));
  1010. VideoDebugPrint((1,"QVision.sys: VgaQueryAvailableModes - EXIT.\n"));
  1011. return ERROR_INSUFFICIENT_BUFFER;
  1012. }
  1013. //
  1014. // For each mode supported by the card, store the mode characteristics
  1015. // in the output buffer.
  1016. //
  1017. for (i = 0; i < NumVideoModes; i++) {
  1018. //
  1019. // $0005 - MikeD - 02/08/94
  1020. // Daytona support
  1021. //
  1022. VideoDebugPrint((2,"\tVideoMode = 0x%x (%ldHz) ",i,
  1023. ModesVGA[i].ulRefreshRate));
  1024. //
  1025. // If we have enough memory to support the mode, set all videoModes
  1026. // values according to the data in the mode table.
  1027. //
  1028. if (ModesVGA[i].ValidMode) {
  1029. VideoDebugPrint((2," - VALID MODE"));
  1030. videoModes->Length = sizeof(VIDEO_MODE_INFORMATION);
  1031. videoModes->ModeIndex = i;
  1032. videoModes->VisScreenWidth = ModesVGA[i].hres;
  1033. videoModes->ScreenStride = ModesVGA[i].wbytes;
  1034. videoModes->VisScreenHeight = ModesVGA[i].vres;
  1035. videoModes->NumberOfPlanes = ModesVGA[i].numPlanes;
  1036. videoModes->BitsPerPlane = ModesVGA[i].bitsPerPlane;
  1037. videoModes->Frequency = ModesVGA[i].ulRefreshRate;
  1038. videoModes->XMillimeter = 320; // temporary hardcoded constant
  1039. videoModes->YMillimeter = 240; // temporary hardcoded constant
  1040. switch (videoModes->BitsPerPlane) {
  1041. case 4:
  1042. VideoDebugPrint((2," - 4BPP\n"));
  1043. videoModes->NumberRedBits = 6;
  1044. videoModes->NumberGreenBits = 6;
  1045. videoModes->NumberBlueBits = 6;
  1046. videoModes->RedMask = 0;
  1047. videoModes->GreenMask = 0;
  1048. videoModes->BlueMask = 0;
  1049. videoModes->AttributeFlags = ModesVGA[i].fbType |
  1050. VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
  1051. break;
  1052. case 8:
  1053. VideoDebugPrint((2," - 8BPP\n"));
  1054. videoModes->NumberRedBits = 6;
  1055. videoModes->NumberGreenBits = 6;
  1056. videoModes->NumberBlueBits = 6;
  1057. videoModes->RedMask = 0;
  1058. videoModes->GreenMask = 0;
  1059. videoModes->BlueMask = 0;
  1060. videoModes->AttributeFlags = ModesVGA[i].fbType |
  1061. VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
  1062. break;
  1063. case 16:
  1064. VideoDebugPrint((2," - 16BPP\n"));
  1065. if ((HwDeviceExtension->VideoHardware.AdapterType != AriesEisa) &&
  1066. (HwDeviceExtension->VideoHardware.AdapterType != AriesIsa)) {
  1067. videoModes->ScreenStride = 2048;
  1068. } // if
  1069. // NOTE: hard coded to 5:5:5 color format
  1070. videoModes->NumberRedBits = 5;
  1071. videoModes->NumberGreenBits = 5;
  1072. videoModes->NumberBlueBits = 5;
  1073. videoModes->RedMask = 0x7C00;
  1074. videoModes->GreenMask = 0x03E0;
  1075. videoModes->BlueMask = 0x001F;
  1076. videoModes->AttributeFlags = ModesVGA[i].fbType;
  1077. break;
  1078. case 32:
  1079. VideoDebugPrint((2," - 32BPP\n"));
  1080. if ((HwDeviceExtension->VideoHardware.AdapterType != AriesEisa) &&
  1081. (HwDeviceExtension->VideoHardware.AdapterType != AriesIsa)) {
  1082. videoModes->ScreenStride = 2048;
  1083. } // if
  1084. videoModes->NumberRedBits = 8;
  1085. videoModes->NumberGreenBits = 8;
  1086. videoModes->NumberBlueBits = 8;
  1087. videoModes->RedMask = 0x000000ff;
  1088. videoModes->GreenMask = 0x0000ff00;
  1089. videoModes->BlueMask = 0x00ff0000;
  1090. videoModes->AttributeFlags = ModesVGA[i].fbType;
  1091. break;
  1092. default:
  1093. VideoDebugPrint((2," - default\n"));
  1094. videoModes->NumberRedBits = 6;
  1095. videoModes->NumberGreenBits = 6;
  1096. videoModes->NumberBlueBits = 6;
  1097. videoModes->RedMask = 0;
  1098. videoModes->GreenMask = 0;
  1099. videoModes->BlueMask = 0;
  1100. videoModes->AttributeFlags = ModesVGA[i].fbType |
  1101. VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
  1102. break;
  1103. } // switch
  1104. videoModes++; // next mode
  1105. } // end if
  1106. #ifdef QV_DBG
  1107. else {
  1108. VideoDebugPrint((2," - INVALID MODE\n"));
  1109. } // else
  1110. #endif
  1111. } // end for i
  1112. VideoDebugPrint((1,"QVision.sys: VgaQueryAvailableModes - EXIT.\n"));
  1113. return NO_ERROR;
  1114. } // end VgaGetAvailableModes()
  1115. //---------------------------------------------------------------------------
  1116. VP_STATUS
  1117. VgaQueryNumberOfAvailableModes(
  1118. PHW_DEVICE_EXTENSION HwDeviceExtension,
  1119. PVIDEO_NUM_MODES NumModes,
  1120. ULONG NumModesSize,
  1121. PULONG OutputSize
  1122. )
  1123. /*++
  1124. Routine Description:
  1125. This routine returns the number of available modes for this particular
  1126. video card.
  1127. Arguments:
  1128. HwDeviceExtension - Pointer to the miniport driver's device extension.
  1129. NumModes - Pointer to the output buffer supplied by the user. This is
  1130. where the number of modes is stored.
  1131. NumModesSize - Length of the output buffer supplied by the user.
  1132. OutputSize - Pointer to a buffer in which to return the actual size of
  1133. the data in the buffer.
  1134. Return Value:
  1135. ERROR_INSUFFICIENT_BUFFER if the output buffer was not large enough
  1136. for the data being returned.
  1137. NO_ERROR if the operation completed successfully.
  1138. --*/
  1139. {
  1140. USHORT i;
  1141. VideoDebugPrint((1,"QVision.sys: VgaQueryNumberOfAvailableModes - ENTRY.\n"));
  1142. //
  1143. // Find out the size of the data to be put in the the buffer and return
  1144. // that in the status information (whether or not the information is
  1145. // there). If the buffer passed in is not large enough return an
  1146. // appropriate error code.
  1147. //
  1148. if (NumModesSize < (*OutputSize = sizeof(VIDEO_NUM_MODES)) ) {
  1149. VideoDebugPrint((1,"QVision.sys: VgaQueryNumberOfAvailableModes - EXIT.\n"));
  1150. return ERROR_INSUFFICIENT_BUFFER;
  1151. }
  1152. HwDeviceExtension->NumAvailableModes = 0; // init the number avail modes
  1153. // for the current configuration
  1154. for (i = 0; i < NumVideoModes; i++) {
  1155. //
  1156. // First find out if we have enough memory for the
  1157. // mode we are checking.
  1158. // We also need to check if the current monitor supports
  1159. // the current mode.
  1160. // If both conditions are TRUE then this mode is valid.
  1161. // We need to make sure that if this is the 1280 mode and
  1162. // we have 2MB of RAM, the card is a Juniper and not a
  1163. // FIR with a twig. FIR does not support 1280 modes.
  1164. //
  1165. // if ((HwDeviceExtension->InstalledVmem >= ModesVGA[i].VmemRequired) &&
  1166. // (fValidMode[HwDeviceExtension->VideoHardware.MonClass][i])) {
  1167. //
  1168. // $0005 - MikeD - 02/08/94
  1169. // Daytona changes.
  1170. if (HwDeviceExtension->InstalledVmem >= ModesVGA[i].VmemRequired) {
  1171. if (ModesVGA[i].hres < 1280) {
  1172. VideoDebugPrint((2,"\tVALID VideoMode = 0x%x\n",i));
  1173. ModesVGA[i].ValidMode = TRUE;
  1174. HwDeviceExtension->NumAvailableModes++;
  1175. } // if
  1176. else if ((HwDeviceExtension->VideoHardware.AdapterType >= JuniperEisa) ||
  1177. (HwDeviceExtension->VideoHardware.AdapterType >= JuniperIsa)) {
  1178. VideoDebugPrint((2,"\tVALID VideoMode = 0x%x\n",i));
  1179. ModesVGA[i].ValidMode = TRUE;
  1180. HwDeviceExtension->NumAvailableModes++;
  1181. } // else
  1182. } // if
  1183. } // for
  1184. //
  1185. // Store the number of modes into the buffer.
  1186. //
  1187. NumModes->NumModes = HwDeviceExtension->NumAvailableModes;
  1188. NumModes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
  1189. VideoDebugPrint((2,"\tNumModes = 0x%x\n",NumModes->NumModes));
  1190. VideoDebugPrint((1,"QVision.sys: VgaQueryNumberOfAvailableModes - EXIT.\n"));
  1191. return NO_ERROR;
  1192. } // end VgaGetNumberOfAvailableModes()
  1193. //---------------------------------------------------------------------------
  1194. VP_STATUS
  1195. VgaQueryCurrentMode(
  1196. PHW_DEVICE_EXTENSION HwDeviceExtension,
  1197. PVIDEO_MODE_INFORMATION ModeInformation,
  1198. ULONG ModeInformationSize,
  1199. PULONG OutputSize
  1200. )
  1201. /*++
  1202. Routine Description:
  1203. This routine returns a description of the current video mode.
  1204. Arguments:
  1205. HwDeviceExtension - Pointer to the miniport driver's device extension.
  1206. ModeInformation - Pointer to the output buffer supplied by the user.
  1207. This is where the current mode information is stored.
  1208. ModeInformationSize - Length of the output buffer supplied by the user.
  1209. OutputSize - Pointer to a buffer in which to return the actual size of
  1210. the data in the buffer. If the buffer was not large enough, this
  1211. contains the minimum required buffer size.
  1212. Return Value:
  1213. ERROR_INSUFFICIENT_BUFFER if the output buffer was not large enough
  1214. for the data being returned.
  1215. NO_ERROR if the operation completed successfully.
  1216. --*/
  1217. {
  1218. VideoDebugPrint((1,"QVision.sys: VgaQueryCurrentMode - ENTRY.\n"));
  1219. //
  1220. //
  1221. // check if a mode has been set
  1222. //
  1223. if (HwDeviceExtension->CurrentMode == NULL) {
  1224. return ERROR_INVALID_FUNCTION;
  1225. }
  1226. // Find out the size of the data to be put in the the buffer and return
  1227. // that in the status information (whether or not the information is
  1228. // there). If the buffer passed in is not large enough return an
  1229. // appropriate error code.
  1230. //
  1231. if (ModeInformationSize < (*OutputSize = sizeof(VIDEO_MODE_INFORMATION))) {
  1232. VideoDebugPrint((1,"QVision.sys: VgaQueryCurrentMode - EXIT.\n"));
  1233. return ERROR_INSUFFICIENT_BUFFER;
  1234. }
  1235. //
  1236. // Store the characteristics of the current mode into the buffer.
  1237. //
  1238. ModeInformation->Length = sizeof(VIDEO_MODE_INFORMATION);
  1239. ModeInformation->ModeIndex = HwDeviceExtension->ModeIndex;
  1240. ModeInformation->VisScreenWidth = HwDeviceExtension->CurrentMode->hres;
  1241. ModeInformation->ScreenStride = HwDeviceExtension->CurrentMode->wbytes;
  1242. ModeInformation->VisScreenHeight = HwDeviceExtension->CurrentMode->vres;
  1243. ModeInformation->NumberOfPlanes = HwDeviceExtension->CurrentMode->numPlanes;
  1244. ModeInformation->BitsPerPlane = HwDeviceExtension->CurrentMode->bitsPerPlane;
  1245. ModeInformation->Frequency = HwDeviceExtension->VideoHardware.lFrequency;
  1246. ModeInformation->XMillimeter = 320; // temporary hardcoded constant
  1247. ModeInformation->YMillimeter = 240; // temporary hardcoded constant
  1248. ModeInformation->NumberRedBits = 6;
  1249. ModeInformation->NumberGreenBits = 6;
  1250. ModeInformation->NumberBlueBits = 6;
  1251. ModeInformation->RedMask = 0;
  1252. ModeInformation->GreenMask = 0;
  1253. ModeInformation->BlueMask = 0;
  1254. ModeInformation->AttributeFlags = HwDeviceExtension->CurrentMode->fbType |
  1255. VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE;
  1256. VideoDebugPrint((1,"QVision.sys: VgaQueryCurrentMode - EXIT.\n"));
  1257. return NO_ERROR;
  1258. } // end VgaQueryCurrentMode()
  1259. //---------------------------------------------------------------------------
  1260. VOID
  1261. VgaZeroVideoMemory(
  1262. PHW_DEVICE_EXTENSION HwDeviceExtension
  1263. )
  1264. /*++
  1265. Routine Description:
  1266. This routine zeros the first 256K on the VGA.
  1267. Arguments:
  1268. HwDeviceExtension - Pointer to the miniport driver's device extension.
  1269. Return Value:
  1270. None.
  1271. --*/
  1272. {
  1273. UCHAR temp;
  1274. ULONG i;
  1275. ULONG max;
  1276. VideoDebugPrint((1,"QVision.sys: VgaZeroVideoMemory - ENTRY.\n"));
  1277. //
  1278. // Map font buffer at A0000
  1279. //
  1280. VgaInterpretCmdStream(HwDeviceExtension, EnableA000Data);
  1281. //
  1282. // Enable all planes.
  1283. //
  1284. VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_ADDRESS_PORT,
  1285. IND_MAP_MASK);
  1286. temp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
  1287. SEQ_DATA_PORT) | (UCHAR)0x0F;
  1288. VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_DATA_PORT,
  1289. temp);
  1290. //
  1291. // Zero the memory for all pages.
  1292. //
  1293. //
  1294. max = 4; // for QVision we assume 4 banks
  1295. for (i = 0; i < max; i++) {
  1296. SetQVisionBanking(HwDeviceExtension,i);// setup next 256k bank
  1297. VideoPortZeroMemory(HwDeviceExtension->VideoMemoryAddress,
  1298. 0xFFFF);
  1299. } // end for
  1300. SetQVisionBanking(HwDeviceExtension,0); // reset the banks
  1301. VgaInterpretCmdStream(HwDeviceExtension, DisableA000Color);
  1302. VideoDebugPrint((1,"QVision.sys: VgaZeroVideoMemory - EXIT.\n"));
  1303. }
  1304. //---------------------------------------------------------------------------
  1305. VOID
  1306. SetQVisionBanking(
  1307. PHW_DEVICE_EXTENSION HwDeviceExtension,
  1308. ULONG BankNumber
  1309. )
  1310. /*++
  1311. Routine Description:
  1312. Arguments:
  1313. HwDeviceExtension - Pointer to the miniport driver's device extension.
  1314. BankNumber - the 64k bank number to set in 1RW mode(we will set this mode).
  1315. Return Value:
  1316. vmem256k, vmem512k, or vmem1Meg ONLY ( these are defined in cirrus.h).
  1317. --*/
  1318. {
  1319. VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress +
  1320. GRAPH_ADDRESS_PORT), 0x030d);
  1321. VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress +
  1322. GRAPH_ADDRESS_PORT), (USHORT)(0x000e + (BankNumber << (8+4))) );
  1323. } // SetQVisionBanking()