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.

718 lines
13 KiB

  1. /*++
  2. Copyright (c) 1993, 1994 Weitek Corporation
  3. Module Name:
  4. p91bt489.c
  5. Abstract:
  6. This module contains code specific to the Bt489 DAC on P9x0x adapters.
  7. Environment:
  8. Kernel mode
  9. Revision History may be found at the end of this file.
  10. --*/
  11. #include "p9.h"
  12. #include "p9gbl.h"
  13. #include "p9000.h"
  14. #include "bt485.h"
  15. #include "p91regs.h"
  16. #include "p91dac.h"
  17. #define PIX_PORT_15 0x30
  18. //
  19. // external functions in p91bt485.c
  20. //
  21. extern UCHAR
  22. ReadDAC(
  23. PHW_DEVICE_EXTENSION HwDeviceExtension,
  24. ULONG ulIndex
  25. );
  26. extern VOID
  27. WriteDAC(
  28. PHW_DEVICE_EXTENSION HwDeviceExtension,
  29. ULONG ulIndex,
  30. UCHAR ucValue
  31. );
  32. //
  33. // Bt489 DAC specific functions.
  34. //
  35. VOID
  36. P91Bt489SetPalette(
  37. PHW_DEVICE_EXTENSION HwDeviceExtension,
  38. ULONG *pPal,
  39. ULONG StartIndex,
  40. ULONG Count
  41. );
  42. VOID
  43. P91Bt489SetPointerPos(
  44. PHW_DEVICE_EXTENSION HwDeviceExtension,
  45. ULONG ptlX,
  46. ULONG ptlY
  47. );
  48. VOID
  49. P91Bt489SetPointerShape(
  50. PHW_DEVICE_EXTENSION HwDeviceExtension,
  51. PUCHAR pHWCursorShape
  52. );
  53. VOID
  54. P91Bt489PointerOn(
  55. PHW_DEVICE_EXTENSION HwDeviceExtension
  56. );
  57. VOID
  58. P91Bt489PointerOff(
  59. PHW_DEVICE_EXTENSION HwDeviceExtension
  60. );
  61. VOID
  62. P91Bt489ClearPalette(
  63. PHW_DEVICE_EXTENSION HwDeviceExtension
  64. );
  65. BOOLEAN
  66. P91Bt489SetMode(
  67. PHW_DEVICE_EXTENSION HwDeviceExtension
  68. );
  69. VOID
  70. P91Bt489RestoreMode(
  71. PHW_DEVICE_EXTENSION HwDeviceExtension
  72. );
  73. VOID
  74. P91Bt489SetClkDoubler(
  75. PHW_DEVICE_EXTENSION HwDeviceExtension
  76. );
  77. VOID
  78. P91Bt489ClrClkDoubler(
  79. PHW_DEVICE_EXTENSION HwDeviceExtension
  80. );
  81. //
  82. // Define the DAC support routines structure for the Bt489 DAC.
  83. //
  84. DAC P91Bt489 = {
  85. DAC_ID_BT489,
  86. NUM_DAC_REGS,
  87. P91Bt489SetMode,
  88. P91Bt489RestoreMode,
  89. P91Bt489SetPalette,
  90. P91Bt489ClearPalette,
  91. P91Bt489PointerOn,
  92. P91Bt489PointerOff,
  93. P91Bt489SetPointerPos,
  94. P91Bt489SetPointerShape,
  95. CLK489_MAX_FREQ,
  96. P91Bt489SetClkDoubler,
  97. P91Bt489ClrClkDoubler,
  98. DAC_ID_BT489,
  99. 64,
  100. FALSE,
  101. FALSE,
  102. TRUE // TRUE == Supports 24BPP
  103. };
  104. VOID
  105. P91Bt489SetPalette(
  106. PHW_DEVICE_EXTENSION HwDeviceExtension,
  107. ULONG *pPal,
  108. ULONG StartIndex,
  109. ULONG Count
  110. )
  111. /*++
  112. Routine Description:
  113. Sets the Device palette
  114. Arguments:
  115. HwDeviceExtension - Pointer to the miniport driver's device extension.
  116. pPal - Pointer to the array of pallete entries.
  117. StartIndex - Specifies the first pallete entry provided in pPal.
  118. Count - Number of palette entries in pPal
  119. Return Value:
  120. None.
  121. --*/
  122. {
  123. UCHAR *pBytePal;
  124. PAL_WR_ADDR((UCHAR) StartIndex);
  125. pBytePal = (PUCHAR) pPal;
  126. //
  127. // Load the palette with RGB values. The input palette has 4 bytes
  128. // per entry, the last of which is ignored.
  129. //
  130. while (Count--)
  131. {
  132. PAL_WR_DATA(*pBytePal++);
  133. PAL_WR_DATA(*pBytePal++);
  134. PAL_WR_DATA(*pBytePal++);
  135. pBytePal++;
  136. }
  137. }
  138. VOID
  139. P91Bt489SetPointerPos(
  140. PHW_DEVICE_EXTENSION HwDeviceExtension,
  141. ULONG ptlX,
  142. ULONG ptlY
  143. )
  144. /*++
  145. Routine Description:
  146. Move Hardware Pointer.
  147. Arguments:
  148. HwDeviceExtension - Pointer to the miniport driver's device extension.
  149. ptlX, ptlY - Requested X,Y position for the pointer.
  150. Return Value:
  151. TRUE
  152. --*/
  153. {
  154. //
  155. // Strip off the invalid bits and update the cursor position regs.
  156. //
  157. WR_CURS_POS_X(((ptlX + CURSOR_WIDTH) & 0xFFF));
  158. WR_CURS_POS_Y(((ptlY + CURSOR_HEIGHT) & 0xFFF));
  159. return;
  160. }
  161. VOID
  162. P91Bt489SetPointerShape(
  163. PHW_DEVICE_EXTENSION HwDeviceExtension,
  164. PUCHAR pHWCursorShape
  165. )
  166. /*++
  167. Routine Description:
  168. Sets the hardware cursor shape.
  169. Arguments:
  170. HwDeviceExtension - Pointer to the miniport driver's device extension.
  171. pHWCursorShape - Pointer to the cursor bitmap.
  172. Return Value:
  173. None.
  174. --*/
  175. {
  176. ULONG iCount;
  177. //
  178. // The # of bytes of cursor bitmap data to send *= 2 for and/xor mask
  179. // *= 8 for 8bit/byte
  180. // *= 2 for 2 loops
  181. //
  182. ULONG iLoop = (CURSOR_WIDTH * CURSOR_HEIGHT * 2) / (8 * 2);
  183. //
  184. // AND mask will be loaded to plane 1.
  185. //
  186. PAL_WR_ADDR(0x80);
  187. iCount = iLoop;
  188. WAIT_FOR_RETRACE();
  189. while (iCount--)
  190. {
  191. WR_CURS_DATA(*pHWCursorShape++);
  192. }
  193. //
  194. // XOR mask will be loaded to plane 0.
  195. //
  196. PAL_WR_ADDR(0x00);
  197. iCount = iLoop;
  198. WAIT_FOR_RETRACE();
  199. while (iCount--)
  200. {
  201. WR_CURS_DATA(*pHWCursorShape++);
  202. }
  203. return;
  204. }
  205. VOID
  206. P91Bt489PointerOn(
  207. PHW_DEVICE_EXTENSION HwDeviceExtension
  208. )
  209. /*++
  210. Routine Description:
  211. Turn on the hardware cursor.
  212. Arguments:
  213. HwDeviceExtension - Pointer to the miniport driver's device extension.
  214. Return Value:
  215. None.
  216. --*/
  217. {
  218. //
  219. // Turn the cursor on only if it was disabled.
  220. //
  221. if (!CURS_IS_ON())
  222. {
  223. WAIT_FOR_RETRACE();
  224. CURS_ON();
  225. }
  226. return;
  227. }
  228. VOID
  229. P91Bt489PointerOff(
  230. PHW_DEVICE_EXTENSION HwDeviceExtension
  231. )
  232. /*++
  233. Routine Description:
  234. Turn off the hardware cursor.
  235. Arguments:
  236. HwDeviceExtension - Pointer to the miniport driver's device extension.
  237. Return Value:
  238. None.
  239. --*/
  240. {
  241. //
  242. // Turn the cursor off only if it was enabled.
  243. //
  244. if (CURS_IS_ON())
  245. {
  246. WAIT_FOR_RETRACE();
  247. CURS_OFF();
  248. }
  249. return;
  250. }
  251. VOID
  252. P91Bt489ClearPalette(
  253. PHW_DEVICE_EXTENSION HwDeviceExtension
  254. )
  255. /*++
  256. Routine Description:
  257. Clears the palette to all 0's
  258. Arguments:
  259. HwDeviceExtension - Pointer to the miniport driver's device extension.
  260. Return Value:
  261. None.
  262. --*/
  263. {
  264. int Count;
  265. //
  266. // Calculate the number of palette entries. It is assumed that the
  267. // caller has already determined that the current mode makes use
  268. // of the palette,
  269. //
  270. Count = 1 << HwDeviceExtension->usBitsPixel;
  271. //
  272. // Fill the palette with RGB values of 0.
  273. //
  274. while (Count--)
  275. {
  276. PAL_WR_DATA(0);
  277. PAL_WR_DATA(0);
  278. PAL_WR_DATA(0);
  279. }
  280. return;
  281. }
  282. BOOLEAN
  283. P91Bt489SetMode(
  284. PHW_DEVICE_EXTENSION HwDeviceExtension
  285. )
  286. /*++
  287. Routine Description:
  288. Initializes the DAC for the current mode.
  289. Arguments:
  290. HwDeviceExtension - Pointer to the miniport driver's device extension.
  291. Return Value:
  292. None.
  293. --*/
  294. {
  295. USHORT usLoadClock;
  296. UCHAR ucCurState;
  297. VideoDebugPrint((1, "P91Bt489SetMode----------\n"));
  298. // Added per code received from R. Embry
  299. WriteDAC(HwDeviceExtension, PIXEL_MSK_REG, 0xff);
  300. //
  301. // Enable 8bit dacs, allow access to Command Register 3.
  302. //
  303. //
  304. // Enable accesses to CMD_REG_3. For the Power 9100, to access command
  305. // register 3, you must have CR07 TRUE and you must load a one into
  306. // the address register.
  307. //
  308. if (IS_DEV_P9100)
  309. P9_WR_REG(P9100_RAMWRITE, 0x01);
  310. WriteDAC(HwDeviceExtension, CMD_REG_0, ENB_CMD_REG_3 | MODE_8_BIT);
  311. //
  312. // Set the DAC Pixel port value for the current bit depth.
  313. // Note: The BT485 does not support 24bpp mode.
  314. //
  315. switch (HwDeviceExtension->usBitsPixel)
  316. {
  317. case 8:
  318. WriteDAC(HwDeviceExtension, CMD_REG_1, PIX_PORT_8);
  319. WR_CMD_REG_4( CR4_MUX_81 );
  320. break;
  321. case 16: // This is really 555, not 565...
  322. WriteDAC(HwDeviceExtension, CMD_REG_1, PIX_PORT_15);
  323. WR_CMD_REG_4( CR4_MUX_41 );
  324. break;
  325. case 24:
  326. WriteDAC(HwDeviceExtension, CMD_REG_1, PIX_PORT_32);
  327. WR_CMD_REG_4(CR4_MUX_24BPP);
  328. break;
  329. case 32:
  330. WriteDAC(HwDeviceExtension, CMD_REG_1, PIX_PORT_32);
  331. WR_CMD_REG_4( CR4_MUX_21 );
  332. break;
  333. default:
  334. //
  335. // Oops..invalid BPP value. Use 8BPP value for now.
  336. //
  337. WriteDAC(HwDeviceExtension, CMD_REG_1, PIX_PORT_8);
  338. WR_CMD_REG_4( CR4_MUX_81 );
  339. break;
  340. };
  341. // This code added per R. Embry from ECR 2/95
  342. usLoadClock = (USHORT) ((HwDeviceExtension->VideoData.dotfreq1 /
  343. HwDeviceExtension->Dac.usRamdacWidth) *
  344. HwDeviceExtension->usBitsPixel);
  345. if ( usLoadClock > 4850 )
  346. {
  347. ucCurState = SCLK_INV; // Bt489 - invert SCLK if in forbidden region
  348. }
  349. else
  350. {
  351. ucCurState = 0;
  352. }
  353. //
  354. // Select P9x00 video clock, disable cursor
  355. //
  356. WriteDAC( HwDeviceExtension, CMD_REG_2,
  357. (UCHAR)(ucCurState | ((PORTSEL_MSKD | PCLK1_SEL) & DIS_CURS)) );
  358. //
  359. // Select 32x32x2 cursor mode, and clock doubler mode if neccessary.
  360. //
  361. RD_CMD_REG_3(ucCurState);
  362. if (HwDeviceExtension->VideoData.dotfreq1 >
  363. HwDeviceExtension->Dac.ulMaxClkFreq)
  364. {
  365. //
  366. // Enable the DAC clock doubler mode.
  367. //
  368. HwDeviceExtension->Dac.DACSetClkDblMode(HwDeviceExtension);
  369. }
  370. else
  371. {
  372. //
  373. // Disable the DAC clock doubler mode.
  374. //
  375. HwDeviceExtension->Dac.DACClrClkDblMode(HwDeviceExtension);
  376. }
  377. //
  378. // Set the pixel read mask.
  379. //
  380. WriteDAC(HwDeviceExtension, PIXEL_MSK_REG, 0xff);
  381. //
  382. // Set cursor colors 1 and 2.
  383. //
  384. WriteDAC(HwDeviceExtension, CURS_CLR_ADDR, 1);
  385. WriteDAC(HwDeviceExtension, CURS_CLR_DATA, 0x00);
  386. WriteDAC(HwDeviceExtension, CURS_CLR_DATA, 0x00);
  387. WriteDAC(HwDeviceExtension, CURS_CLR_DATA, 0x00);
  388. WriteDAC(HwDeviceExtension, CURS_CLR_DATA, 0xFF);
  389. WriteDAC(HwDeviceExtension, CURS_CLR_DATA, 0xFF);
  390. WriteDAC(HwDeviceExtension, CURS_CLR_DATA, 0xFF);
  391. return(TRUE);
  392. }
  393. VOID
  394. P91Bt489RestoreMode(
  395. PHW_DEVICE_EXTENSION HwDeviceExtension
  396. )
  397. /*++
  398. routine description:
  399. Restore the DAC to its pristine state.
  400. arguments:
  401. hwdeviceextension - pointer to the miniport driver's device extension.
  402. return value:
  403. --*/
  404. {
  405. UCHAR ucCurState;
  406. VideoDebugPrint((1, "P91Bt489RestoreMode----------\n"));
  407. //
  408. // Enable accesses to CMD_REG_3. For the Power 9100, to access command
  409. // register 3, you must have CR07 TRUE and you must load a one into
  410. // the address register.
  411. //
  412. if (IS_DEV_P9100)
  413. {
  414. // Added per code received from R. Embry
  415. WriteDAC(HwDeviceExtension, CMD_REG_0, ENB_CMD_REG_3);
  416. P9_WR_REG(P9100_RAMWRITE, 0x02);
  417. WR_CMD_REG_3(0x00);
  418. // end added code
  419. P9_WR_REG(P9100_RAMWRITE, 0x01);
  420. WriteDAC(HwDeviceExtension, CMD_REG_0, ENB_CMD_REG_3);
  421. // ucCurState = ReadDAC(HwDeviceExtension, CMD_REG_1);
  422. // ucCurState = ReadDAC(HwDeviceExtension, CMD_REG_2);
  423. // RD_CMD_REG_3(ucCurState);
  424. // RD_CMD_REG_4(ucCurState);
  425. WR_CMD_REG_4(0x00); // zero out cmd reg 4 on Bt489
  426. WriteDAC(HwDeviceExtension, CMD_REG_0, 0x00);
  427. WriteDAC(HwDeviceExtension, CMD_REG_1, 0x00);
  428. WriteDAC(HwDeviceExtension, CMD_REG_2, 0x00);
  429. return;
  430. }
  431. WriteDAC(HwDeviceExtension, CMD_REG_0, ENB_CMD_REG_3);
  432. //
  433. // Set pixel port for 8bit pixels.
  434. //
  435. WriteDAC(HwDeviceExtension, CMD_REG_1, PIX_PORT_8);
  436. //
  437. // Select VGA video clock, disable cursor.
  438. //
  439. WriteDAC(HwDeviceExtension, (ULONG) CMD_REG_2,
  440. (UCHAR)(ReadDAC(HwDeviceExtension, (ULONG) CMD_REG_2) & DIS_CURS));
  441. //
  442. // Select 32x32 cursor, clear clock doubler bit.
  443. //
  444. RD_CMD_REG_3(ucCurState);
  445. WR_CMD_REG_3(ucCurState & (~(DAC_CLK_2X | DAC_CLK_2X_489) & CUR_MODE_32));
  446. //
  447. // Set pixel read mask.
  448. //
  449. WriteDAC(HwDeviceExtension, PIXEL_MSK_REG, 0xff);
  450. return;
  451. }
  452. VOID
  453. P91Bt489SetClkDoubler(
  454. PHW_DEVICE_EXTENSION HwDeviceExtension
  455. )
  456. /*++
  457. routine description:
  458. Enable the DAC's internal clock doubler.
  459. arguments:
  460. hwdeviceextension - pointer to the miniport driver's device extension.
  461. return value:
  462. --*/
  463. {
  464. UCHAR ucCurState;
  465. VideoDebugPrint((1, "P91Bt489SetClkDoubler----------\n"));
  466. RD_CMD_REG_3(ucCurState);
  467. // per os/2 driver, write undocumented bit too
  468. if (HwDeviceExtension->usBitsPixel == 24 )
  469. {
  470. WR_CMD_REG_3(ucCurState | (DAC_CLK_2X | DAC_CLK_2X_489));
  471. }
  472. else
  473. {
  474. WR_CMD_REG_3(ucCurState | DAC_CLK_2X);
  475. }
  476. return;
  477. }
  478. VOID
  479. P91Bt489ClrClkDoubler(
  480. PHW_DEVICE_EXTENSION HwDeviceExtension
  481. )
  482. /*++
  483. routine description:
  484. Disable the DAC's internal clock doubler.
  485. arguments:
  486. hwdeviceextension - pointer to the miniport driver's device extension.
  487. return value:
  488. --*/
  489. {
  490. UCHAR ucCurState;
  491. VideoDebugPrint((1, "P91Bt489ClrClkDoubler----------\n"));
  492. RD_CMD_REG_3(ucCurState);
  493. WR_CMD_REG_3(ucCurState & ~(DAC_CLK_2X | DAC_CLK_2X_489));
  494. return;
  495. }