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.

1484 lines
48 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: pointer.c
  3. *
  4. * This module contains the hardware pointer support for the display
  5. * driver.
  6. *
  7. * Copyright (c) 1993-1996 Microsoft Corporation
  8. * Copyright (c) 1993-1996 Matrox Electronic Systems, Ltd.
  9. \**************************************************************************/
  10. #include "precomp.h"
  11. #define BT485_CURSOR_SIZE 64
  12. #define BT482_CURSOR_SIZE 32
  13. #define VIEWPOINT_CURSOR_SIZE 64
  14. #define VIEWPOINT_OUT (VIEWPOINT_CURSOR_SIZE/2-1-VIEWPOINT_CURSOR_SIZE)
  15. #define TVP3026_CURSOR_SIZE 64
  16. #define TVP3026_OUT (TVP3026_CURSOR_SIZE-TVP3026_CURSOR_SIZE)
  17. #define OLD_TVP_SHIFT 2
  18. #define NEW_TVP_SHIFT 0
  19. BYTE Plane0LUT[] = { 0x00, 0x01, 0x04, 0x05,
  20. 0x10, 0x11, 0x14, 0x15,
  21. 0x40, 0x41, 0x44, 0x45,
  22. 0x50, 0x51, 0x54, 0x55 };
  23. BYTE Plane1LUT[] = { 0x00, 0x02, 0x08, 0x0a,
  24. 0x20, 0x22, 0x28, 0x2a,
  25. 0x80, 0x82, 0x88, 0x8a,
  26. 0xa0, 0xa2, 0xa8, 0xaa };
  27. /****************************************************************************\
  28. * SetBt48xPointerShape
  29. \****************************************************************************/
  30. ULONG SetBt48xPointerShape(
  31. SURFOBJ* pso,
  32. SURFOBJ* psoMsk,
  33. SURFOBJ* psoColor,
  34. XLATEOBJ* pxlo,
  35. LONG xHot,
  36. LONG yHot,
  37. LONG x,
  38. LONG y,
  39. RECTL* prcl,
  40. FLONG fl)
  41. {
  42. ULONG i;
  43. ULONG j;
  44. ULONG cxMask;
  45. ULONG cyMask;
  46. ULONG cMaskDimension;
  47. LONG lDelta;
  48. PDEV* ppdev;
  49. BYTE* pjBase;
  50. UCHAR ucTemp;
  51. UCHAR ucByteWidth;
  52. UCHAR ucOldCR;
  53. UCHAR ucOldCmdRegA;
  54. BYTE* pjAND;
  55. BYTE* pjXOR;
  56. LONG cjWidth;
  57. LONG cjSkip;
  58. LONG cjWidthRemainder;
  59. LONG cyHeightRemainder;
  60. LONG cjHeightRemainder;
  61. ppdev = (PDEV*) pso->dhpdev;
  62. pjBase = ppdev->pjBase;
  63. // Figure out the dimensions of the masks:
  64. cMaskDimension = (ppdev->RamDacFlags == RAMDAC_BT482) ? 32 : 64;
  65. // Get the bitmap dimensions.
  66. cxMask = psoMsk->sizlBitmap.cx;
  67. cyMask = psoMsk->sizlBitmap.cy >> 1; // Height includes AND and XOR masks
  68. // Set up pointers to the AND and XOR masks.
  69. lDelta = psoMsk->lDelta;
  70. pjAND = psoMsk->pvScan0;
  71. pjXOR = pjAND + (cyMask * lDelta);
  72. // Do some other download setup:
  73. cjWidth = cxMask >> 3;
  74. cjSkip = lDelta - cjWidth;
  75. cjWidthRemainder = (cMaskDimension / 8) - cjWidth;
  76. // Don't bother blanking the bottom part of the cursor if it is
  77. // already blank:
  78. cyHeightRemainder = min(ppdev->cyPointerHeight, (LONG) cMaskDimension)
  79. - cyMask;
  80. cyHeightRemainder = max(cyHeightRemainder, 0);
  81. cjHeightRemainder = cyHeightRemainder * (cMaskDimension / 8);
  82. ppdev->cyPointerHeight = cyMask;
  83. DrvMovePointer(pso, -1, -1, NULL); // Disable the H/W cursor
  84. if ((ppdev->RamDacFlags == RAMDAC_BT485) ||
  85. (ppdev->RamDacFlags == RAMDAC_PX2085))
  86. {
  87. // Set the cursor for 64 X 64, and set the 2 MSB's for the cursor
  88. // RAM addr to 0.
  89. // First get access to Command Register 3
  90. // Prepare to download AND mask to Bt485
  91. // Clear bit 7 of CR0 so we can access CR3
  92. ucTemp = CP_READ_REGISTER_BYTE(pjBase + BT485_COMMAND_REG0);
  93. ucTemp |= 0x80;
  94. CP_WRITE_REGISTER_BYTE(pjBase + BT485_COMMAND_REG0, ucTemp);
  95. // Turn on bit 0 to address register
  96. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_RAM_WRITE, 1);
  97. ucTemp = CP_READ_REGISTER_BYTE(pjBase + BT485_COMMAND_REG3);
  98. ucTemp &= 0xF8; // CR3 bit2=1 (64x64 cursor)
  99. ucTemp |= 0x06; // CR3 bit1-bit0=10 (AND mask)
  100. CP_WRITE_REGISTER_BYTE(pjBase + BT485_COMMAND_REG3, ucTemp);
  101. // Start at address 0x200 (AND mask)
  102. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_RAM_WRITE, 0);
  103. // Down load the AND mask:
  104. for (j = cyMask; j != 0; j--)
  105. {
  106. for (i = cjWidth; i != 0; i--)
  107. {
  108. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_RAM_DATA, *pjAND++);
  109. }
  110. pjAND += cjSkip;
  111. for (i = cjWidthRemainder; i != 0; i--)
  112. {
  113. pjBase = ppdev->pjBase; // Compiler work-around
  114. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_RAM_DATA, 0xff);
  115. }
  116. }
  117. for (j = cjHeightRemainder; j != 0; j--)
  118. {
  119. pjBase = ppdev->pjBase; // Compiler work-around
  120. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_RAM_DATA, 0xff);
  121. }
  122. // Prepare to download XOR mask to Bt485
  123. // Clear bit 7 of CR0 so we can access CR3
  124. ucTemp = CP_READ_REGISTER_BYTE(pjBase + BT485_COMMAND_REG0);
  125. ucTemp |= 0x80;
  126. CP_WRITE_REGISTER_BYTE(pjBase + BT485_COMMAND_REG0, ucTemp);
  127. // Turn on bit 0 to address register
  128. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_RAM_WRITE, 1);
  129. ucTemp = CP_READ_REGISTER_BYTE(pjBase + BT485_COMMAND_REG3);
  130. ucTemp &= 0xF8; // CR3 bit2=1 (64x64 cursor)
  131. ucTemp |= 0x04; // CR3 bit1-bit0=00 (XOR mask)
  132. CP_WRITE_REGISTER_BYTE(pjBase + BT485_COMMAND_REG3, ucTemp);
  133. // Start at address 0x200 (AND mask)
  134. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_RAM_WRITE, 0);
  135. // Down load the XOR mask
  136. for (j = cyMask; j != 0; j--)
  137. {
  138. for (i = cjWidth; i != 0; i--)
  139. {
  140. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_RAM_DATA, *pjXOR++);
  141. }
  142. pjXOR += cjSkip;
  143. for (i = cjWidthRemainder; i != 0; i--)
  144. {
  145. pjBase = ppdev->pjBase; // Compiler work-around
  146. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_RAM_DATA, 0);
  147. }
  148. }
  149. for (j = cjHeightRemainder; j != 0; j--)
  150. {
  151. pjBase = ppdev->pjBase; // Compiler work-around
  152. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_RAM_DATA, 0);
  153. }
  154. }
  155. else // Download to Bt482
  156. {
  157. // Prepare to download AND mask to Bt482
  158. // Store current REGA value, select extended registers
  159. ucOldCmdRegA = CP_READ_REGISTER_BYTE(pjBase + BT482_COMMAND_REGA);
  160. CP_WRITE_REGISTER_BYTE(pjBase + BT482_COMMAND_REGA,
  161. ucOldCmdRegA | BT482_EXTENDED_REG_SELECT);
  162. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PALETTE_RAM_WRITE, CURS_REG);
  163. ucOldCR = CP_READ_REGISTER_BYTE(pjBase + BT482_PEL_MASK);
  164. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PEL_MASK, ucOldCR | BT482_CURSOR_RAM_SELECT);
  165. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PALETTE_RAM_WRITE, 0x80);
  166. for (j = cyMask; j != 0; j--)
  167. {
  168. for (i = cjWidth; i != 0; i--)
  169. {
  170. CP_WRITE_REGISTER_BYTE(pjBase + BT482_OVRLAY_REGS, *pjAND++);
  171. CP_READ_REGISTER_BYTE(pjBase + HST_REV); // Need 600us delay
  172. CP_READ_REGISTER_BYTE(pjBase + HST_REV);
  173. }
  174. pjAND += cjSkip;
  175. for (i = cjWidthRemainder; i != 0; i--)
  176. {
  177. pjBase = ppdev->pjBase; // Compiler work-around
  178. CP_WRITE_REGISTER_BYTE(pjBase + BT482_OVRLAY_REGS, 0xff);
  179. CP_READ_REGISTER_BYTE(pjBase + HST_REV); // Need 600us delay
  180. CP_READ_REGISTER_BYTE(pjBase + HST_REV);
  181. }
  182. }
  183. for (j = cjHeightRemainder; j != 0; j--)
  184. {
  185. pjBase = ppdev->pjBase; // Compiler work-around
  186. CP_WRITE_REGISTER_BYTE(pjBase + BT482_OVRLAY_REGS, 0xff);
  187. CP_READ_REGISTER_BYTE(pjBase + HST_REV); // Need 600us delay
  188. CP_READ_REGISTER_BYTE(pjBase + HST_REV);
  189. }
  190. // Prepare to download XOR mask to Bt482
  191. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PALETTE_RAM_WRITE, 0x00);
  192. for (j = cyMask; j != 0; j--)
  193. {
  194. for (i = cjWidth; i != 0; i--)
  195. {
  196. CP_WRITE_REGISTER_BYTE(pjBase + BT482_OVRLAY_REGS, *pjXOR++);
  197. CP_READ_REGISTER_BYTE(pjBase + HST_REV); // Need 600us delay
  198. CP_READ_REGISTER_BYTE(pjBase + HST_REV);
  199. }
  200. pjXOR += cjSkip;
  201. for (i = cjWidthRemainder; i != 0; i--)
  202. {
  203. pjBase = ppdev->pjBase; // Compiler work-around
  204. CP_WRITE_REGISTER_BYTE(pjBase + BT482_OVRLAY_REGS, 0);
  205. CP_READ_REGISTER_BYTE(pjBase + HST_REV); // Need 600us delay
  206. CP_READ_REGISTER_BYTE(pjBase + HST_REV);
  207. }
  208. }
  209. for (j = cjHeightRemainder; j != 0; j--)
  210. {
  211. pjBase = ppdev->pjBase; // Compiler work-around
  212. CP_WRITE_REGISTER_BYTE(pjBase + BT482_OVRLAY_REGS, 0);
  213. CP_READ_REGISTER_BYTE(pjBase + HST_REV); // Need 600us delay
  214. CP_READ_REGISTER_BYTE(pjBase + HST_REV);
  215. }
  216. // Restore old Cursor Regsister and Command Register A values
  217. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PALETTE_RAM_WRITE, CURS_REG);
  218. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PEL_MASK, ucOldCR);
  219. CP_WRITE_REGISTER_BYTE(pjBase + BT482_COMMAND_REGA, ucOldCmdRegA);
  220. }
  221. // Set the position of the cursor (and enable it)
  222. DrvMovePointer(pso, x, y, NULL);
  223. return(SPS_ACCEPT_NOEXCLUDE);
  224. }
  225. /****************************************************************************\
  226. * SetViewPointPointerShape -
  227. \****************************************************************************/
  228. ULONG SetViewPointPointerShape(
  229. SURFOBJ* pso,
  230. SURFOBJ* psoMsk,
  231. SURFOBJ* psoColor,
  232. XLATEOBJ* pxlo,
  233. LONG xHot,
  234. LONG yHot,
  235. LONG x,
  236. LONG y,
  237. RECTL* prcl,
  238. FLONG fl)
  239. {
  240. ULONG i;
  241. ULONG j;
  242. ULONG cxAND;
  243. ULONG cyAND;
  244. ULONG cxRemaining;
  245. ULONG cyRemaining;
  246. BYTE* pjAND;
  247. BYTE* pjXOR;
  248. LONG lDelta;
  249. PDEV* ppdev;
  250. BYTE* pjBase;
  251. BYTE ViewPointTranspMask;
  252. ppdev = (PDEV*) pso->dhpdev;
  253. pjBase = ppdev->pjBase;
  254. // The ViewPoint requires that the AND mask (plane 1) and the XOR mask
  255. // (plane 0) be interleaved on a bit-by-bit basis:
  256. //
  257. // Plane1/AND: F E D C B A 9 8
  258. // Plane0/XOR: 7 6 5 4 3 2 1 0
  259. //
  260. // will be downloaded as: "B 3 A 2 9 1 8 0" and "F 7 E 6 D 5 C 4".
  261. // The fastest way to do that is probably to use a lookup table:
  262. //
  263. // Plane1: "B A 9 8" --> "B - A - 9 - 8 -"
  264. // Plane0: "3 2 1 0" --> "- 3 - 2 - 1 - 0"
  265. // OR --> "B 3 A 2 9 1 8 0"
  266. // Get the bitmap dimensions.
  267. // This assumes that the cursor width is an integer number of bytes!
  268. cxAND = psoMsk->sizlBitmap.cx / 8;
  269. cxRemaining = 2 * ((VIEWPOINT_CURSOR_SIZE/8) - cxAND);
  270. cyAND = psoMsk->sizlBitmap.cy / 2;
  271. cyRemaining = VIEWPOINT_CURSOR_SIZE - cyAND;
  272. // Set up pointers to the AND and XOR masks.
  273. pjAND = psoMsk->pvScan0;
  274. lDelta = psoMsk->lDelta;
  275. pjXOR = pjAND + (cyAND * lDelta);
  276. if (ppdev->bHwPointerActive)
  277. {
  278. // The hardware cursor is currently enabled.
  279. // Disable it.
  280. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_INDEX, VPOINT_CUR_CTL);
  281. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, VIEWPOINT_CURSOR_OFF);
  282. // Signal that the cursor is disabled.
  283. ppdev->bHwPointerActive = FALSE;
  284. }
  285. // The effect of this is to make the pointer pixels transparent.
  286. ViewPointTranspMask = 0xaa;
  287. // Setup for downloading the pointer masks.
  288. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_INDEX, VPOINT_CUR_RAM_LSB);
  289. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, 0);
  290. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_INDEX, VPOINT_CUR_RAM_MSB);
  291. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, 0);
  292. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_INDEX, VPOINT_CUR_RAM_DATA);
  293. // Build and copy the interleaved mask.
  294. for (i = 0; i < cyAND; i++)
  295. {
  296. // Copy over a line of the interleaved mask.
  297. for (j = 0; j < cxAND; j++)
  298. {
  299. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA,
  300. (Plane1LUT[pjAND[j] >> 4] | Plane0LUT[pjXOR[j] >> 4]));
  301. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA,
  302. (Plane1LUT[pjAND[j] & 0x0f] | Plane0LUT[pjXOR[j] & 0x0f]));
  303. }
  304. // Copy over transparent bytes for the remaining of the line.
  305. for (j = (VIEWPOINT_CURSOR_SIZE/8) - (psoMsk->sizlBitmap.cx >> 3);
  306. j != 0;
  307. j--)
  308. {
  309. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, ViewPointTranspMask);
  310. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, ViewPointTranspMask);
  311. }
  312. // Point to the next line of the source masks.
  313. pjAND += lDelta;
  314. pjXOR += lDelta;
  315. }
  316. // Copy over transparent bytes for the remaining of the mask.
  317. for (i = 0; i < cyRemaining; i++)
  318. {
  319. for (j = (VIEWPOINT_CURSOR_SIZE/8);
  320. j != 0;
  321. j--)
  322. {
  323. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, ViewPointTranspMask);
  324. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, ViewPointTranspMask);
  325. }
  326. }
  327. // Set the position of the cursor (and enable it).
  328. DrvMovePointer(pso, x, y, NULL);
  329. return(SPS_ACCEPT_NOEXCLUDE);
  330. }
  331. /****************************************************************************\
  332. * MilSetTVP3026PointerShape -
  333. \****************************************************************************/
  334. ULONG MilSetTVP3026PointerShape(
  335. SURFOBJ* pso,
  336. SURFOBJ* psoMsk,
  337. SURFOBJ* psoColor,
  338. XLATEOBJ* pxlo,
  339. LONG xHot,
  340. LONG yHot,
  341. LONG x,
  342. LONG y,
  343. RECTL* prcl,
  344. FLONG fl)
  345. {
  346. ULONG i;
  347. ULONG j;
  348. ULONG cxMask;
  349. ULONG cyMask;
  350. ULONG cMaskDimension;
  351. LONG lDelta;
  352. PDEV* ppdev;
  353. BYTE* pjBase;
  354. UCHAR ucTemp;
  355. UCHAR ucByteWidth;
  356. UCHAR ucOldCR;
  357. UCHAR ucOldCmdRegA;
  358. BYTE* pjAND;
  359. BYTE* pjXOR;
  360. LONG cjWidth;
  361. LONG cjSkip;
  362. LONG cjWidthRemainder;
  363. LONG cyHeightRemainder;
  364. LONG cyNextBank;
  365. BYTE jData;
  366. ULONG UlTvpIndirectIndex;
  367. ULONG UlTvpIndexedData;
  368. ULONG UlTvpCurAddrWr;
  369. ULONG UlTvpCurData;
  370. // The old MGA chips had direct register offsets that were multiples of
  371. // four, while the new Millenium uses increments of one. So, we define the
  372. // offsets as increments of one and shift for the older boards.
  373. // No scaling (shifting) of offsets
  374. // Note that the compiler is kind enough to recognize that these are
  375. // constant declarations:
  376. UlTvpIndirectIndex = TVP3026_INDIRECT_INDEX(NEW_TVP_SHIFT);
  377. UlTvpIndexedData = TVP3026_INDEXED_DATA(NEW_TVP_SHIFT);
  378. UlTvpCurAddrWr = TVP3026_CUR_ADDR_WR(NEW_TVP_SHIFT);
  379. UlTvpCurData = TVP3026_CUR_DATA(NEW_TVP_SHIFT);
  380. ppdev = (PDEV*) pso->dhpdev;
  381. pjBase = ppdev->pjBase;
  382. // Get the bitmap dimensions.
  383. cxMask = psoMsk->sizlBitmap.cx;
  384. cyMask = psoMsk->sizlBitmap.cy >> 1; // Height includes AND and XOR masks
  385. // Set up pointers to the AND and XOR masks.
  386. lDelta = psoMsk->lDelta;
  387. pjAND = psoMsk->pvScan0;
  388. pjXOR = pjAND + (cyMask * lDelta);
  389. // Do some other download setup:
  390. cjWidth = cxMask >> 3;
  391. cjSkip = lDelta - cjWidth;
  392. cjWidthRemainder = (64 / 8) - cjWidth;
  393. // Don't bother blanking the bottom part of the cursor if it is
  394. // already blank:
  395. cyHeightRemainder = min(ppdev->cyPointerHeight, (LONG) 64)
  396. - cyMask;
  397. cyHeightRemainder = max(cyHeightRemainder, 0);
  398. ppdev->cyPointerHeight = cyMask;
  399. // Disable the cursor, access bytes 200-2FF of cursor RAM.
  400. ppdev->bHwPointerActive = FALSE;
  401. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndirectIndex, TVP3026_I_CUR_CTL);
  402. jData = CP_READ_REGISTER_BYTE(pjBase + UlTvpIndexedData)
  403. & ~(TVP3026_D_CURSOR_RAM_MASK | TVP3026_D_CURSOR_MASK);
  404. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndexedData,
  405. jData | TVP3026_D_CURSOR_RAM_10);
  406. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurAddrWr, 0);
  407. // Down load the AND mask:
  408. cyNextBank = 32;
  409. for (j = cyMask; j != 0; j--)
  410. {
  411. for (i = cjWidth; i != 0; i--)
  412. {
  413. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurData, *pjAND++);
  414. }
  415. pjAND += cjSkip;
  416. for (i = cjWidthRemainder; i != 0; i--)
  417. {
  418. pjBase = ppdev->pjBase; // Compiler work-around
  419. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurData, 0xff);
  420. }
  421. if (--cyNextBank == 0)
  422. {
  423. // Access bytes 300-3FF of cursor RAM.
  424. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndirectIndex,
  425. TVP3026_I_CUR_CTL);
  426. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndexedData,
  427. jData | TVP3026_D_CURSOR_RAM_11);
  428. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurAddrWr, 0);
  429. }
  430. }
  431. for (j = cyHeightRemainder; j != 0; j--)
  432. {
  433. for (i = 8; i != 0; i--)
  434. {
  435. pjBase = ppdev->pjBase; // Compiler work-around
  436. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurData, 0xff);
  437. }
  438. if (--cyNextBank == 0)
  439. {
  440. // Access bytes 300-3FF of cursor RAM.
  441. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndirectIndex,
  442. TVP3026_I_CUR_CTL);
  443. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndexedData,
  444. jData | TVP3026_D_CURSOR_RAM_11);
  445. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurAddrWr, 0);
  446. }
  447. }
  448. // Access bytes 00-FF of cursor RAM.
  449. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndirectIndex,
  450. TVP3026_I_CUR_CTL);
  451. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndexedData,
  452. jData | TVP3026_D_CURSOR_RAM_00);
  453. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurAddrWr, 0);
  454. // Down load the XOR mask
  455. cyNextBank = 32;
  456. for (j = cyMask; j != 0; j--)
  457. {
  458. for (i = cjWidth; i != 0; i--)
  459. {
  460. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurData, *pjXOR++);
  461. }
  462. pjXOR += cjSkip;
  463. for (i = cjWidthRemainder; i != 0; i--)
  464. {
  465. pjBase = ppdev->pjBase; // Compiler work-around
  466. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurData, 0);
  467. }
  468. if (--cyNextBank == 0)
  469. {
  470. // Access bytes 100-1FF of cursor RAM.
  471. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndirectIndex,
  472. TVP3026_I_CUR_CTL);
  473. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndexedData,
  474. jData | TVP3026_D_CURSOR_RAM_01);
  475. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurAddrWr, 0);
  476. }
  477. }
  478. for (j = cyHeightRemainder; j != 0; j--)
  479. {
  480. for (i = 8; i != 0; i--)
  481. {
  482. pjBase = ppdev->pjBase; // Compiler work-around
  483. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurData, 0);
  484. }
  485. if (--cyNextBank == 0)
  486. {
  487. // Access bytes 100-1FF of cursor RAM.
  488. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndirectIndex,
  489. TVP3026_I_CUR_CTL);
  490. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndexedData,
  491. jData | TVP3026_D_CURSOR_RAM_01);
  492. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurAddrWr, 0);
  493. }
  494. }
  495. // Set the position of the cursor (and enable it)
  496. DrvMovePointer(pso, x, y, NULL);
  497. return(SPS_ACCEPT_NOEXCLUDE);
  498. }
  499. /****************************************************************************\
  500. * MgaSetTVP3026PointerShape -
  501. \****************************************************************************/
  502. ULONG MgaSetTVP3026PointerShape(
  503. SURFOBJ* pso,
  504. SURFOBJ* psoMsk,
  505. SURFOBJ* psoColor,
  506. XLATEOBJ* pxlo,
  507. LONG xHot,
  508. LONG yHot,
  509. LONG x,
  510. LONG y,
  511. RECTL* prcl,
  512. FLONG fl)
  513. {
  514. ULONG i;
  515. ULONG j;
  516. ULONG cxMask;
  517. ULONG cyMask;
  518. ULONG cMaskDimension;
  519. LONG lDelta;
  520. PDEV* ppdev;
  521. BYTE* pjBase;
  522. UCHAR ucTemp;
  523. UCHAR ucByteWidth;
  524. UCHAR ucOldCR;
  525. UCHAR ucOldCmdRegA;
  526. BYTE* pjAND;
  527. BYTE* pjXOR;
  528. LONG cjWidth;
  529. LONG cjSkip;
  530. LONG cjWidthRemainder;
  531. LONG cyHeightRemainder;
  532. LONG cyNextBank;
  533. BYTE jData;
  534. ULONG UlTvpIndirectIndex;
  535. ULONG UlTvpIndexedData;
  536. ULONG UlTvpCurAddrWr;
  537. ULONG UlTvpCurData;
  538. // The old MGA chips had direct register offsets that were multiples of
  539. // four, while the new Millenium uses increments of one. So, we define the
  540. // offsets as increments of one and shift for the older boards.
  541. // No scaling (shifting) of offsets
  542. // Note that the compiler is kind enough to recognize that these are
  543. // constant declarations:
  544. UlTvpIndirectIndex = TVP3026_INDIRECT_INDEX(OLD_TVP_SHIFT);
  545. UlTvpIndexedData = TVP3026_INDEXED_DATA(OLD_TVP_SHIFT);
  546. UlTvpCurAddrWr = TVP3026_CUR_ADDR_WR(OLD_TVP_SHIFT);
  547. UlTvpCurData = TVP3026_CUR_DATA(OLD_TVP_SHIFT);
  548. ppdev = (PDEV*) pso->dhpdev;
  549. pjBase = ppdev->pjBase;
  550. // Get the bitmap dimensions.
  551. cxMask = psoMsk->sizlBitmap.cx;
  552. cyMask = psoMsk->sizlBitmap.cy >> 1; // Height includes AND and XOR masks
  553. // Set up pointers to the AND and XOR masks.
  554. lDelta = psoMsk->lDelta;
  555. pjAND = psoMsk->pvScan0;
  556. pjXOR = pjAND + (cyMask * lDelta);
  557. // Do some other download setup:
  558. cjWidth = cxMask >> 3;
  559. cjSkip = lDelta - cjWidth;
  560. cjWidthRemainder = (64 / 8) - cjWidth;
  561. // Don't bother blanking the bottom part of the cursor if it is
  562. // already blank:
  563. cyHeightRemainder = min(ppdev->cyPointerHeight, (LONG) 64)
  564. - cyMask;
  565. cyHeightRemainder = max(cyHeightRemainder, 0);
  566. ppdev->cyPointerHeight = cyMask;
  567. // Disable the cursor, access bytes 200-2FF of cursor RAM.
  568. ppdev->bHwPointerActive = FALSE;
  569. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndirectIndex, TVP3026_I_CUR_CTL);
  570. jData = CP_READ_REGISTER_BYTE(pjBase + UlTvpIndexedData)
  571. & ~(TVP3026_D_CURSOR_RAM_MASK | TVP3026_D_CURSOR_MASK);
  572. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndexedData,
  573. jData | TVP3026_D_CURSOR_RAM_10);
  574. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurAddrWr, 0);
  575. // Down load the AND mask:
  576. cyNextBank = 32;
  577. for (j = cyMask; j != 0; j--)
  578. {
  579. for (i = cjWidth; i != 0; i--)
  580. {
  581. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurData, *pjAND++);
  582. }
  583. pjAND += cjSkip;
  584. for (i = cjWidthRemainder; i != 0; i--)
  585. {
  586. pjBase = ppdev->pjBase; // Compiler work-around
  587. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurData, 0xff);
  588. }
  589. if (--cyNextBank == 0)
  590. {
  591. // Access bytes 300-3FF of cursor RAM.
  592. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndirectIndex,
  593. TVP3026_I_CUR_CTL);
  594. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndexedData,
  595. jData | TVP3026_D_CURSOR_RAM_11);
  596. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurAddrWr, 0);
  597. }
  598. }
  599. for (j = cyHeightRemainder; j != 0; j--)
  600. {
  601. for (i = 8; i != 0; i--)
  602. {
  603. pjBase = ppdev->pjBase; // Compiler work-around
  604. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurData, 0xff);
  605. }
  606. if (--cyNextBank == 0)
  607. {
  608. // Access bytes 300-3FF of cursor RAM.
  609. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndirectIndex,
  610. TVP3026_I_CUR_CTL);
  611. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndexedData,
  612. jData | TVP3026_D_CURSOR_RAM_11);
  613. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurAddrWr, 0);
  614. }
  615. }
  616. // Access bytes 00-FF of cursor RAM.
  617. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndirectIndex,
  618. TVP3026_I_CUR_CTL);
  619. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndexedData,
  620. jData | TVP3026_D_CURSOR_RAM_00);
  621. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurAddrWr, 0);
  622. // Down load the XOR mask
  623. cyNextBank = 32;
  624. for (j = cyMask; j != 0; j--)
  625. {
  626. for (i = cjWidth; i != 0; i--)
  627. {
  628. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurData, *pjXOR++);
  629. }
  630. pjXOR += cjSkip;
  631. for (i = cjWidthRemainder; i != 0; i--)
  632. {
  633. pjBase = ppdev->pjBase; // Compiler work-around
  634. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurData, 0);
  635. }
  636. if (--cyNextBank == 0)
  637. {
  638. // Access bytes 100-1FF of cursor RAM.
  639. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndirectIndex,
  640. TVP3026_I_CUR_CTL);
  641. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndexedData,
  642. jData | TVP3026_D_CURSOR_RAM_01);
  643. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurAddrWr, 0);
  644. }
  645. }
  646. for (j = cyHeightRemainder; j != 0; j--)
  647. {
  648. for (i = 8; i != 0; i--)
  649. {
  650. pjBase = ppdev->pjBase; // Compiler work-around
  651. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurData, 0);
  652. }
  653. if (--cyNextBank == 0)
  654. {
  655. // Access bytes 100-1FF of cursor RAM.
  656. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndirectIndex,
  657. TVP3026_I_CUR_CTL);
  658. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpIndexedData,
  659. jData | TVP3026_D_CURSOR_RAM_01);
  660. CP_WRITE_REGISTER_BYTE(pjBase + UlTvpCurAddrWr, 0);
  661. }
  662. }
  663. // Set the position of the cursor (and enable it)
  664. DrvMovePointer(pso, x, y, NULL);
  665. return(SPS_ACCEPT_NOEXCLUDE);
  666. }
  667. /****************************************************************************\
  668. * DrvSetPointerShape
  669. \****************************************************************************/
  670. ULONG DrvSetPointerShape(
  671. SURFOBJ* pso,
  672. SURFOBJ* psoMsk,
  673. SURFOBJ* psoColor,
  674. XLATEOBJ* pxlo,
  675. LONG xHot,
  676. LONG yHot,
  677. LONG x,
  678. LONG y,
  679. RECTL* prcl,
  680. FLONG fl)
  681. {
  682. PDEV* ppdev;
  683. LONG cx;
  684. LONG cy;
  685. LONG cMax;
  686. ULONG ulRet;
  687. ppdev = (PDEV*) pso->dhpdev;
  688. // Because our DAC pointers usually flash when we set them, we'll
  689. // always decline animated pointers:
  690. if (fl & (SPS_ANIMATESTART | SPS_ANIMATEUPDATE))
  691. {
  692. goto HideAndDecline;
  693. }
  694. //
  695. // Bug: 412974. we have HW cursor corruption. Disable it by declining.
  696. //
  697. goto HideAndDecline;
  698. // We're not going to handle any colour pointers, pointers that
  699. // are larger than our hardware allows, or flags that we don't
  700. // understand.
  701. //
  702. // (Note that the spec says we should decline any flags we don't
  703. // understand, but we'll actually be declining if we don't see
  704. // the only flag we *do* understand...)
  705. //
  706. // Our old documentation says that 'psoMsk' may be NULL, which means
  707. // that the pointer is transparent. Well, trust me, that's wrong.
  708. // I've checked GDI's code, and it will never pass us a NULL psoMsk:
  709. cx = psoMsk->sizlBitmap.cx; // Note that 'sizlBitmap.cy' accounts
  710. cy = psoMsk->sizlBitmap.cy >> 1; // for the double height due to the
  711. // inclusion of both the AND masks
  712. // and the XOR masks. For now, we're
  713. // only interested in the true
  714. // pointer dimensions, so we divide
  715. // by 2.
  716. cMax = (ppdev->RamDacFlags == RAMDAC_BT482) ? BT482_CURSOR_SIZE : 64;
  717. if ((psoColor != NULL) ||
  718. (cx > cMax) || // Hardware pointer is cMax by cMax
  719. (cy > cMax) || // pixels
  720. (cx & 7) || // To simplify download routines, handle
  721. // only byte-aligned widths
  722. !(fl & SPS_CHANGE)) // Must have this flag set
  723. {
  724. goto HideAndDecline;
  725. }
  726. // Save the hot spot in the pdev.
  727. ppdev->ptlHotSpot.x = xHot;
  728. ppdev->ptlHotSpot.y = yHot;
  729. // Program the monochrome hardware pointer.
  730. switch (ppdev->RamDacFlags)
  731. {
  732. case RAMDAC_BT485:
  733. case RAMDAC_BT482:
  734. case RAMDAC_PX2085:
  735. ulRet = SetBt48xPointerShape(pso, psoMsk, psoColor,
  736. pxlo, xHot, yHot, x, y, prcl, fl);
  737. break;
  738. case RAMDAC_VIEWPOINT:
  739. ulRet = SetViewPointPointerShape(pso, psoMsk, psoColor,
  740. pxlo, xHot, yHot, x, y, prcl, fl);
  741. break;
  742. case RAMDAC_TVP3026:
  743. case RAMDAC_TVP3030:
  744. if (ppdev->ulBoardId == MGA_STORM)
  745. {
  746. ulRet = MilSetTVP3026PointerShape(pso, psoMsk, psoColor,
  747. pxlo, xHot, yHot, x, y, prcl, fl);
  748. }
  749. else
  750. {
  751. ulRet = MgaSetTVP3026PointerShape(pso, psoMsk, psoColor,
  752. pxlo, xHot, yHot, x, y, prcl, fl);
  753. }
  754. break;
  755. default:
  756. ulRet = SPS_DECLINE;
  757. break;
  758. }
  759. return(ulRet);
  760. HideAndDecline:
  761. // Since we're declining the new pointer, GDI will simulate it via
  762. // DrvCopyBits calls. So we should really hide the old hardware
  763. // pointer if it's visible. We can get DrvMovePointer to do this
  764. // for us:
  765. DrvMovePointer(pso, -1, -1, NULL);
  766. return(SPS_DECLINE);
  767. }
  768. /****************************************************************************\
  769. * DrvMovePointer
  770. *
  771. \****************************************************************************/
  772. VOID DrvMovePointer(
  773. SURFOBJ* pso,
  774. LONG x,
  775. LONG y,
  776. RECTL* prcl)
  777. {
  778. PDEV* ppdev;
  779. OH* poh;
  780. BYTE* pjBase;
  781. UCHAR ucTemp;
  782. UCHAR ucOldCmdRegA;
  783. ULONG ulDacScale;
  784. ppdev = (PDEV*) pso->dhpdev;
  785. poh = ((DSURF*) pso->dhsurf)->poh;
  786. pjBase = ppdev->pjBase;
  787. // Convert the pointer's position from relative to absolute
  788. // coordinates (this is only significant for multiple board
  789. // support).
  790. x += poh->x;
  791. y += poh->y;
  792. // If x is -1 after the offset then take down the cursor.
  793. if (x == -1)
  794. {
  795. if (!(ppdev->bHwPointerActive))
  796. {
  797. // The hardware cursor is disabled already.
  798. return;
  799. }
  800. // Disable the cursor.
  801. // We will set the cursor position outside the display to prevent
  802. // flickering when switching from software to hardware cursor.
  803. switch (ppdev->RamDacFlags)
  804. {
  805. case RAMDAC_BT485:
  806. // Disable the cursor, then fall through.
  807. ucTemp = CP_READ_REGISTER_BYTE(pjBase + BT485_COMMAND_REG2);
  808. CP_WRITE_REGISTER_BYTE(pjBase + BT485_COMMAND_REG2, ucTemp & 0xfc);
  809. case RAMDAC_PX2085:
  810. // Set the cursor position outside the display.
  811. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_X_LOW, 0);
  812. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_X_HIGH, 0);
  813. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_Y_LOW, 0);
  814. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_Y_HIGH, 0);
  815. break;
  816. case RAMDAC_BT482:
  817. ucOldCmdRegA = CP_READ_REGISTER_BYTE(pjBase + BT482_COMMAND_REGA);
  818. CP_WRITE_REGISTER_BYTE(pjBase + BT482_COMMAND_REGA, BT482_EXTENDED_REG_SELECT);
  819. // Set the cursor position outside the display.
  820. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PALETTE_RAM_WRITE, CURS_X_LOW_REG);
  821. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PEL_MASK, 0);
  822. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PALETTE_RAM_WRITE, CURS_X_HIGH_REG);
  823. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PEL_MASK, 0);
  824. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PALETTE_RAM_WRITE, CURS_Y_LOW_REG);
  825. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PEL_MASK, 0);
  826. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PALETTE_RAM_WRITE, CURS_Y_HIGH_REG);
  827. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PEL_MASK, 0);
  828. CP_WRITE_REGISTER_BYTE(pjBase + BT482_CURSOR_RAM_WRITE, CURS_REG);
  829. ucTemp = CP_READ_REGISTER_BYTE(pjBase + BT482_PEL_MASK);
  830. ucTemp &= ~(BT482_CURSOR_OP_DISABLED | BT482_CURSOR_FIELDS);
  831. ucTemp |= BT482_CURSOR_DISABLED;
  832. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PEL_MASK, ucTemp);
  833. CP_WRITE_REGISTER_BYTE(pjBase + BT482_COMMAND_REGA, ucOldCmdRegA);
  834. break;
  835. case RAMDAC_VIEWPOINT:
  836. // Set the cursor position outside the display.
  837. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_INDEX, VPOINT_CUR_X_LSB);
  838. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, VIEWPOINT_OUT & 0xff);
  839. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_INDEX, VPOINT_CUR_X_MSB);
  840. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, (VIEWPOINT_OUT >> 8));
  841. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_INDEX, VPOINT_CUR_Y_LSB);
  842. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, VIEWPOINT_OUT & 0xff);
  843. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_INDEX, VPOINT_CUR_Y_MSB);
  844. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, (VIEWPOINT_OUT >> 8));
  845. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_INDEX, VPOINT_CUR_CTL);
  846. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, VIEWPOINT_CURSOR_OFF);
  847. break;
  848. case RAMDAC_TVP3026:
  849. case RAMDAC_TVP3030:
  850. // Set the cursor position outside the display.
  851. if (ppdev->ulBoardId == MGA_STORM)
  852. {
  853. ulDacScale = 0;
  854. }
  855. else
  856. {
  857. ulDacScale = 2;
  858. }
  859. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_CUR_X_LSB(ulDacScale),TVP3026_OUT & 0xff);
  860. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_CUR_X_MSB(ulDacScale),(TVP3026_OUT >> 8));
  861. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_CUR_Y_LSB(ulDacScale),TVP3026_OUT & 0xff);
  862. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_CUR_Y_MSB(ulDacScale),(TVP3026_OUT >> 8));
  863. // Disable the cursor.
  864. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_INDIRECT_INDEX(ulDacScale),TVP3026_I_CUR_CTL);
  865. ucTemp = CP_READ_REGISTER_BYTE(pjBase + TVP3026_INDEXED_DATA(ulDacScale));
  866. ucTemp &= ~TVP3026_D_CURSOR_MASK;
  867. ucTemp |= TVP3026_D_CURSOR_OFF;
  868. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_INDEXED_DATA(ulDacScale),ucTemp);
  869. break;
  870. default:
  871. break;
  872. }
  873. // Signal that the hardware cursor is not currently enabled.
  874. ppdev->bHwPointerActive = FALSE;
  875. return;
  876. }
  877. else
  878. {
  879. // Calculate the actual (x,y) coordinate to send to Bt48x RamDac
  880. x -= ppdev->ptlHotSpot.x; // Adjust the (x,y) coordinate
  881. y -= ppdev->ptlHotSpot.y; // considering the hot-spot
  882. x += ppdev->szlPointerOverscan.cx;
  883. y += ppdev->szlPointerOverscan.cy;
  884. switch(ppdev->RamDacFlags)
  885. {
  886. case RAMDAC_BT485:
  887. case RAMDAC_PX2085:
  888. x += BT485_CURSOR_SIZE; // Bt48x origin is at the bottom
  889. y += BT485_CURSOR_SIZE;
  890. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_X_LOW, x & 0xff);
  891. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_X_HIGH, x >> 8);
  892. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_Y_LOW, y & 0xff);
  893. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_Y_HIGH, y >> 8);
  894. // Enable the cursor... We have a flag in the pdev
  895. // to indicate whether the cursor is already enabled.
  896. // We cannot read vsyncsts anymore, so we do it differently.
  897. // The code for disabling the hardware cursor set its
  898. // position to (0, 0), so any flickering should be less
  899. // obvious.
  900. if (!(ppdev->bHwPointerActive))
  901. {
  902. // The hardware cursor is disabled.
  903. ucTemp = CP_READ_REGISTER_BYTE(pjBase + BT485_COMMAND_REG2);
  904. ucTemp|=0x02;
  905. CP_WRITE_REGISTER_BYTE(pjBase + BT485_COMMAND_REG2, ucTemp);
  906. }
  907. break;
  908. case RAMDAC_VIEWPOINT:
  909. x += VIEWPOINT_CURSOR_SIZE/2-1; // Viewpoint origin is at the center
  910. y += VIEWPOINT_CURSOR_SIZE/2-1;
  911. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_INDEX, VPOINT_CUR_X_LSB);
  912. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, x & 0xff);
  913. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_INDEX, VPOINT_CUR_X_MSB);
  914. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, x >> 8);
  915. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_INDEX, VPOINT_CUR_Y_LSB);
  916. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, y & 0xff);
  917. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_INDEX, VPOINT_CUR_Y_MSB);
  918. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, y >> 8);
  919. // Enable the cursor... We have a flag in the pdev
  920. // to indicate whether the cursor is already enabled.
  921. // We cannot read vsyncsts anymore, so we do it differently.
  922. // The code for disabling the hardware cursor set its
  923. // position to (0, 0), so any flickering should be less
  924. // obvious.
  925. if (!(ppdev->bHwPointerActive))
  926. {
  927. // The hardware cursor is disabled.
  928. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_INDEX, VPOINT_CUR_CTL);
  929. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, VIEWPOINT_CURSOR_ON);
  930. }
  931. break;
  932. case RAMDAC_BT482:
  933. x += BT482_CURSOR_SIZE; // Bt48x origin is at the bottom
  934. y += BT482_CURSOR_SIZE;
  935. ucOldCmdRegA = CP_READ_REGISTER_BYTE(pjBase + BT482_COMMAND_REGA);
  936. CP_WRITE_REGISTER_BYTE(pjBase + BT482_COMMAND_REGA,
  937. ucOldCmdRegA | BT482_EXTENDED_REG_SELECT);
  938. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PALETTE_RAM_WRITE, CURS_X_LOW_REG);
  939. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PEL_MASK, x & 0xff);
  940. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PALETTE_RAM_WRITE, CURS_X_HIGH_REG);
  941. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PEL_MASK, x >> 8);
  942. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PALETTE_RAM_WRITE, CURS_Y_LOW_REG);
  943. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PEL_MASK, y & 0xff);
  944. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PALETTE_RAM_WRITE, CURS_Y_HIGH_REG);
  945. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PEL_MASK, y >> 8);
  946. CP_WRITE_REGISTER_BYTE(pjBase + BT482_COMMAND_REGA, ucOldCmdRegA);
  947. // Enable the Bt482 Cursor.
  948. // We cannot read vsyncsts anymore, so we do it differently.
  949. // The code for disabling the hardware cursor set its
  950. // position to (0, 0), so any flickering should be less
  951. // obvious.
  952. if (!(ppdev->bHwPointerActive))
  953. {
  954. // The hardware cursor is disabled.
  955. ucOldCmdRegA = CP_READ_REGISTER_BYTE(pjBase + BT482_COMMAND_REGA);
  956. CP_WRITE_REGISTER_BYTE(pjBase + BT482_COMMAND_REGA, BT482_EXTENDED_REG_SELECT);
  957. CP_WRITE_REGISTER_BYTE(pjBase + BT482_CURSOR_RAM_WRITE, CURS_REG);
  958. ucTemp = CP_READ_REGISTER_BYTE(pjBase + BT482_PEL_MASK);
  959. ucTemp &= ~(BT482_CURSOR_OP_DISABLED | BT482_CURSOR_FIELDS);
  960. ucTemp |= BT482_CURSOR_WINDOWS;
  961. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PEL_MASK, ucTemp);
  962. CP_WRITE_REGISTER_BYTE(pjBase + BT482_COMMAND_REGA, ucOldCmdRegA);
  963. }
  964. break;
  965. case RAMDAC_TVP3026:
  966. case RAMDAC_TVP3030:
  967. if (ppdev->ulBoardId == MGA_STORM)
  968. {
  969. ulDacScale = 0;
  970. }
  971. else
  972. {
  973. ulDacScale = 2;
  974. }
  975. x += TVP3026_CURSOR_SIZE;
  976. y += TVP3026_CURSOR_SIZE;
  977. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_CUR_X_LSB(ulDacScale), x & 0xff);
  978. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_CUR_X_MSB(ulDacScale), x >> 8);
  979. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_CUR_Y_LSB(ulDacScale), y & 0xff);
  980. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_CUR_Y_MSB(ulDacScale), y >> 8);
  981. // Enable the cursor... We have a flag in the pdev
  982. // to indicate whether the cursor is already enabled.
  983. // We cannot read vsyncsts anymore, so we do it differently.
  984. // The code for disabling the hardware cursor set its
  985. // position to (0, 0), so any flickering should be less
  986. // obvious.
  987. if (!(ppdev->bHwPointerActive))
  988. {
  989. // The hardware cursor is disabled.
  990. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_INDIRECT_INDEX(ulDacScale),TVP3026_I_CUR_CTL);
  991. ucTemp = CP_READ_REGISTER_BYTE(pjBase + TVP3026_INDEXED_DATA(ulDacScale));
  992. ucTemp &= ~TVP3026_D_CURSOR_MASK;
  993. ucTemp |= TVP3026_D_CURSOR_ON;
  994. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_INDEXED_DATA(ulDacScale),ucTemp);
  995. }
  996. break;
  997. default:
  998. break;
  999. }
  1000. // Signal that the hardware cursor is enabled.
  1001. ppdev->bHwPointerActive = TRUE;
  1002. }
  1003. }
  1004. /******************************Public*Routine******************************\
  1005. * VOID vDisablePointer
  1006. *
  1007. \**************************************************************************/
  1008. VOID vDisablePointer(
  1009. PDEV* ppdev)
  1010. {
  1011. // Nothing to do, really
  1012. }
  1013. /******************************Public*Routine******************************\
  1014. * VOID vAssertModePointer
  1015. *
  1016. \**************************************************************************/
  1017. VOID vAssertModePointer(
  1018. PDEV* ppdev,
  1019. BOOL bEnable)
  1020. {
  1021. BYTE* pjBase;
  1022. BYTE byte;
  1023. BYTE Bt48xCmdReg0;
  1024. BYTE Bt48xCmdReg1;
  1025. BYTE Bt48xCmdReg2;
  1026. BYTE Bt48xCmdReg3;
  1027. if (bEnable)
  1028. {
  1029. pjBase = ppdev->pjBase;
  1030. ppdev->bHwPointerActive = FALSE;
  1031. ppdev->cyPointerHeight = 1024; // A large number to ensure that the
  1032. // entire pointer is downloaded
  1033. // the first time
  1034. switch (ppdev->RamDacFlags)
  1035. {
  1036. case RAMDAC_BT482:
  1037. // Make sure our copy of RegA doesn't allow access to extended
  1038. // registers.
  1039. byte = CP_READ_REGISTER_BYTE(pjBase + BT482_COMMAND_REGA);
  1040. Bt48xCmdReg0 = byte & ~BT482_EXTENDED_REG_SELECT;
  1041. // Get access to extended registers.
  1042. CP_WRITE_REGISTER_BYTE(pjBase + BT482_COMMAND_REGA,
  1043. Bt48xCmdReg0 | BT482_EXTENDED_REG_SELECT);
  1044. // Record contents of RegB.
  1045. CP_WRITE_REGISTER_BYTE(pjBase + BT482_CURSOR_RAM_WRITE, COMMAND_B_REG);
  1046. Bt48xCmdReg1 = CP_READ_REGISTER_BYTE(pjBase + BT482_PEL_MASK);
  1047. // Make sure our copy of Cursor Reg has the cursor disabled
  1048. // and the cursor color palette selected.
  1049. CP_WRITE_REGISTER_BYTE(pjBase + BT482_CURSOR_RAM_WRITE, CURS_REG);
  1050. byte = CP_READ_REGISTER_BYTE(pjBase + BT482_PEL_MASK);
  1051. Bt48xCmdReg2 = (byte & ~(BT482_CURSOR_FIELDS |
  1052. BT482_CURSOR_RAM_SELECT)) |
  1053. (BT482_CURSOR_DISABLED |
  1054. BT482_CURSOR_COLOR_PALETTE_SELECT);
  1055. // Disable the cursor, and prepare to access the cursor palette.
  1056. CP_WRITE_REGISTER_BYTE(pjBase + BT482_PEL_MASK, Bt48xCmdReg2);
  1057. // Cursor colors have been set by IOCTL_VIDEO_SET_CURRENT_MODE.
  1058. // We don't need access to extended registers any more, for now.
  1059. CP_WRITE_REGISTER_BYTE(pjBase + BT482_COMMAND_REGA, Bt48xCmdReg0);
  1060. // Our color palette will be set later, by the miniport.
  1061. break;
  1062. case RAMDAC_BT485:
  1063. case RAMDAC_PX2085:
  1064. // Make sure our copy of Reg0 doesn't allow access to Reg3.
  1065. byte = CP_READ_REGISTER_BYTE(pjBase + BT485_COMMAND_REG0);
  1066. // There seems to be a problem with unselecting Command 3
  1067. // Bt48xCmdReg0 = byte & ~BT485_REG3_SELECT;
  1068. Bt48xCmdReg0 = byte;
  1069. Bt48xCmdReg1 = CP_READ_REGISTER_BYTE(pjBase + BT485_COMMAND_REG1);
  1070. // Make sure our copy of Reg2 has the cursor disabled.
  1071. byte = CP_READ_REGISTER_BYTE(pjBase + BT485_COMMAND_REG2);
  1072. Bt48xCmdReg2 = (byte & ~BT485_CURSOR_FIELDS) |
  1073. BT485_CURSOR_DISABLED;
  1074. // Disable the cursor.
  1075. CP_WRITE_REGISTER_BYTE(pjBase + BT485_COMMAND_REG2, Bt48xCmdReg2);
  1076. // Access and record contents of Reg3.
  1077. CP_WRITE_REGISTER_BYTE(pjBase + BT485_COMMAND_REG0, Bt48xCmdReg0 |
  1078. BT485_REG3_SELECT);
  1079. CP_WRITE_REGISTER_BYTE(pjBase + BT485_CURSOR_RAM_WRITE, 1);
  1080. byte = CP_READ_REGISTER_BYTE(pjBase + BT485_COMMAND_REG3);
  1081. // Make sure our copy of Reg3 has the 64x64 cursor selected
  1082. // and the 2MSBs for the 64x64 cursor set to zero.
  1083. Bt48xCmdReg3 = byte | BT485_CURSOR_64X64 &
  1084. ~BT485_CURSOR_64X64_FIELDS;
  1085. // Make sure we start out using the 64x64 cursor, and record
  1086. // the pointer size so that we know which one we're using.
  1087. CP_WRITE_REGISTER_BYTE(pjBase + BT485_COMMAND_REG3, Bt48xCmdReg3);
  1088. // There seems to be a problem with unselecting Command 3
  1089. // We don't need to access Reg3 any more, for now.
  1090. CP_WRITE_REGISTER_BYTE(pjBase + BT485_COMMAND_REG0, Bt48xCmdReg0);
  1091. // Cursor colors have been set by IOCTL_VIDEO_SET_CURRENT_MODE.
  1092. // Our color palette will be set later, by the miniport.
  1093. break;
  1094. case RAMDAC_VIEWPOINT:
  1095. // Disable the cursor.
  1096. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_INDEX, VPOINT_CUR_CTL);
  1097. CP_WRITE_REGISTER_BYTE(pjBase + VIEWPOINT_DATA, VIEWPOINT_CURSOR_OFF);
  1098. // Cursor colors have been set by IOCTL_VIDEO_SET_CURRENT_MODE.
  1099. // Our color palette will be set later, by the miniport.
  1100. break;
  1101. case RAMDAC_TVP3026:
  1102. case RAMDAC_TVP3030:
  1103. // Disable the cursor.
  1104. if (ppdev->ulBoardId == MGA_STORM)
  1105. {
  1106. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_INDIRECT_INDEX(NEW_TVP_SHIFT), TVP3026_I_CUR_CTL);
  1107. byte = CP_READ_REGISTER_BYTE(pjBase + TVP3026_INDEXED_DATA(NEW_TVP_SHIFT));
  1108. byte &= ~TVP3026_D_CURSOR_MASK;
  1109. byte |= TVP3026_D_CURSOR_OFF;
  1110. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_INDEXED_DATA(NEW_TVP_SHIFT), byte);
  1111. }
  1112. else
  1113. {
  1114. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_INDIRECT_INDEX(OLD_TVP_SHIFT), TVP3026_I_CUR_CTL);
  1115. byte = CP_READ_REGISTER_BYTE(pjBase + TVP3026_INDEXED_DATA(OLD_TVP_SHIFT));
  1116. byte &= ~TVP3026_D_CURSOR_MASK;
  1117. byte |= TVP3026_D_CURSOR_OFF;
  1118. CP_WRITE_REGISTER_BYTE(pjBase + TVP3026_INDEXED_DATA(OLD_TVP_SHIFT), byte);
  1119. }
  1120. // Cursor colors have been set by IOCTL_VIDEO_SET_CURRENT_MODE.
  1121. // Our color palette will be set later, by the miniport.
  1122. break;
  1123. }
  1124. }
  1125. }
  1126. /******************************Public*Routine******************************\
  1127. * BOOL bEnablePointer
  1128. *
  1129. \**************************************************************************/
  1130. BOOL bEnablePointer(
  1131. PDEV* ppdev)
  1132. {
  1133. RAMDAC_INFO VideoPointerAttr;
  1134. ULONG ReturnedDataLength;
  1135. // Query the MGA miniport about the hardware pointer, using a private
  1136. // IOCTL:
  1137. if (EngDeviceIoControl(ppdev->hDriver,
  1138. IOCTL_VIDEO_MTX_QUERY_RAMDAC_INFO,
  1139. NULL, // Input
  1140. 0,
  1141. &VideoPointerAttr,
  1142. sizeof(RAMDAC_INFO),
  1143. &ReturnedDataLength))
  1144. {
  1145. DISPDBG((0, "bEnablePointer -- failed MTX_QUERY_RAMDAC_INFO"));
  1146. return(FALSE);
  1147. }
  1148. ppdev->RamDacFlags = VideoPointerAttr.Flags & RAMDAC_FIELDS;
  1149. ppdev->szlPointerOverscan.cx = VideoPointerAttr.OverScanX;
  1150. ppdev->szlPointerOverscan.cy = VideoPointerAttr.OverScanY;
  1151. // Initialize the pointer:
  1152. vAssertModePointer(ppdev, TRUE);
  1153. return(TRUE);
  1154. }