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.

1551 lines
38 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: pointer.c
  3. *
  4. * Copyright (c) 1992-1995 Microsoft Corporation
  5. \**************************************************************************/
  6. #include "precomp.h"
  7. //
  8. // This will disable the sync with vertical retrace. Stress tests are failing with v-sync enabled.
  9. //
  10. #define NO_VERTICAL_SYNC
  11. BOOL flag_shape;
  12. BYTE HardWareCursorShape [CURSOR_CX][CURSOR_CY] ;
  13. // BEGIN MACH32 ----------------------------------------------------------------
  14. VOID vI32SetCursorOffset(PDEV *ppdev)
  15. {
  16. BYTE mem;
  17. BYTE bytes_pp;
  18. ULONG vga_mem;
  19. LONG width;
  20. LONG height;
  21. LONG depth;
  22. height = ppdev->ppointer->hwCursor.y;
  23. depth = ppdev->cBitsPerPel;
  24. width = ppdev->lDelta / depth;
  25. mem = (BYTE) I32_IB(ppdev->pjIoBase, MEM_BNDRY);
  26. if(mem&0x10)
  27. {
  28. vga_mem=(ULONG)(mem&0xf);
  29. vga_mem=0x40000*vga_mem; /* vga boundary is enabled */
  30. }
  31. else
  32. {
  33. vga_mem=0;
  34. }
  35. switch(depth)
  36. {
  37. case 32:
  38. bytes_pp=8;
  39. break;
  40. case 24:
  41. bytes_pp=6;
  42. break;
  43. case 16:
  44. bytes_pp=4;
  45. break;
  46. case 8:
  47. bytes_pp=2;
  48. break;
  49. case 4:
  50. bytes_pp=1;
  51. break;
  52. }
  53. ppdev->ppointer->mono_offset = (vga_mem +
  54. ((ULONG)height*(ULONG)width*(ULONG)bytes_pp));
  55. #if 0
  56. DbgOut("Height %x\n", height);
  57. DbgOut("Height %x\n", width);
  58. DbgOut("Height %x\n", bytes_pp);
  59. DbgOut("Mono Offset %x\n", ppdev->ppointer->mono_offset);
  60. #endif
  61. }
  62. VOID vI32UpdateCursorOffset(
  63. PDEV *ppdev,
  64. LONG lXOffset,
  65. LONG lYOffset,
  66. LONG lCurOffset)
  67. {
  68. PBYTE pjIoBase = ppdev->pjIoBase;
  69. I32_OW_DIRECT(pjIoBase, CURSOR_OFFSET_HI, 0) ;
  70. I32_OW_DIRECT(pjIoBase, HORZ_CURSOR_OFFSET, (lXOffset & 0xff) | (lYOffset << 8));
  71. I32_OW_DIRECT(pjIoBase, CURSOR_OFFSET_LO, (WORD)lCurOffset) ;
  72. I32_OW_DIRECT(pjIoBase, CURSOR_OFFSET_HI, (lCurOffset >> 16) | 0x8000) ;
  73. }
  74. VOID vI32UpdateCursorPosition(
  75. PDEV *ppdev,
  76. LONG x,
  77. LONG y)
  78. {
  79. PBYTE pjIoBase = ppdev->pjIoBase;
  80. I32_OW_DIRECT(pjIoBase, HORZ_CURSOR_POSN, x); /* set base of cursor to X */
  81. I32_OW_DIRECT(pjIoBase, VERT_CURSOR_POSN, y); /* set base of cursor to Y */
  82. }
  83. VOID vI32CursorOff(PDEV *ppdev)
  84. {
  85. I32_OW_DIRECT(ppdev->pjIoBase, CURSOR_OFFSET_HI, 0);
  86. }
  87. VOID vI32CursorOn(PDEV *ppdev, LONG lCurOffset)
  88. {
  89. I32_OW_DIRECT(ppdev->pjIoBase, CURSOR_OFFSET_HI, (lCurOffset >> 16) | 0x8000) ;
  90. }
  91. VOID vI32PointerBlit(
  92. PDEV* ppdev,
  93. LONG x,
  94. LONG y,
  95. LONG cx,
  96. LONG cy,
  97. PBYTE pbsrc,
  98. LONG lDelta)
  99. {
  100. BYTE* pjIoBase = ppdev->pjIoBase;
  101. WORD wCmd;
  102. WORD wWords;
  103. WORD wPixels;
  104. UINT i;
  105. wWords = (WORD)(cx + 15) / 16;
  106. wPixels = (WORD) (wWords*16L/ppdev->cBitsPerPel);
  107. wCmd = FG_COLOR_SRC_HOST | DRAW | WRITE | DATA_WIDTH | LSB_FIRST;
  108. I32_CHECK_FIFO_SPACE(ppdev, pjIoBase, 7);
  109. I32_OW(pjIoBase, ALU_FG_FN, OVERPAINT);
  110. I32_OW(pjIoBase, DP_CONFIG, wCmd);
  111. I32_OW(pjIoBase, DEST_X_START, LOWORD(x));
  112. I32_OW(pjIoBase, CUR_X, LOWORD(x));
  113. I32_OW(pjIoBase, DEST_X_END, LOWORD(x) + wPixels);
  114. I32_OW(pjIoBase, CUR_Y, LOWORD(y));
  115. I32_OW(pjIoBase, DEST_Y_END, (LOWORD(y) + 1));
  116. for (i=0; i < (UINT) wWords; i++)
  117. {
  118. if (i % 8 == 0)
  119. I32_CHECK_FIFO_SPACE(ppdev, pjIoBase, 10);
  120. I32_OW(pjIoBase, PIX_TRANS, *((USHORT UNALIGNED *)pbsrc)++ );
  121. }
  122. }
  123. VOID vPointerBlitLFB(
  124. PDEV* ppdev,
  125. LONG x,
  126. LONG y,
  127. LONG cx,
  128. LONG cy,
  129. PBYTE pbsrc,
  130. LONG lDelta)
  131. {
  132. BYTE* pjDst;
  133. ASSERTDD(ppdev->iBitmapFormat == BMF_24BPP, "BMF should be 24 here\n");
  134. pjDst = ppdev->pjScreen + ppdev->lDelta * y + x * 3;
  135. //
  136. // Set cx equal to number of bytes.
  137. //
  138. cx >>= 3;
  139. while (cy-- > 0)
  140. {
  141. memcpy( pjDst, pbsrc, cx);
  142. pjDst += cx;
  143. pbsrc += lDelta;
  144. }
  145. }
  146. // END MACH32 ------------------------------------------------------------------
  147. // BEGIN MACH64 ----------------------------------------------------------------
  148. BOOLEAN flag_enable=FALSE;
  149. /*
  150. ----------------------------------------------------------------------
  151. -- NAME: vDacRegs
  152. --
  153. -- DESCRIPTION:
  154. -- Calculate DAC regsiter I/O locations
  155. --
  156. ----------------------------------------------------------------------
  157. */
  158. _inline VOID vDacRegs(PDEV* ppdev, UCHAR** ucReg, UCHAR** ucCntl)
  159. {
  160. if (ppdev->FeatureFlags & EVN_PACKED_IO)
  161. {
  162. *ucReg = (ppdev->pjIoBase + DAC_REGS*4);
  163. *ucCntl = (ppdev->pjIoBase + DAC_CNTL*4);
  164. }
  165. else
  166. {
  167. *ucReg = (ppdev->pjIoBase + ioDAC_REGS - ioBASE);
  168. *ucCntl = (ppdev->pjIoBase + ioDAC_CNTL - ioBASE);
  169. }
  170. }
  171. VOID vM64SetCursorOffset(PDEV* ppdev)
  172. {
  173. LONG bytes_pp;
  174. LONG width;
  175. LONG height;
  176. LONG depth;
  177. height = ppdev->ppointer->hwCursor.y;
  178. depth = ppdev->cBitsPerPel;
  179. width = ppdev->lDelta / depth;
  180. switch(depth)
  181. {
  182. case 32:
  183. bytes_pp=8;
  184. break;
  185. case 24:
  186. bytes_pp=6;
  187. break;
  188. case 16:
  189. bytes_pp=4;
  190. break;
  191. case 8:
  192. bytes_pp=2;
  193. break;
  194. case 4:
  195. bytes_pp=1;
  196. break;
  197. }
  198. ppdev->ppointer->mono_offset = (ULONG)height*(ULONG)width*(ULONG)bytes_pp;
  199. ppdev->ppointer->mono_offset += ppdev->ulVramOffset*2;
  200. }
  201. VOID vM64UpdateCursorOffset(
  202. PDEV* ppdev,
  203. LONG lXOffset,
  204. LONG lYOffset,
  205. LONG lCurOffset)
  206. {
  207. BYTE* pjMmBase = ppdev->pjMmBase;
  208. ppdev->pfnCursorOff(ppdev);
  209. M64_OD_DIRECT(pjMmBase,CUR_OFFSET, lCurOffset >> 1);
  210. M64_OD_DIRECT(pjMmBase,CUR_HORZ_VERT_OFF, lXOffset | (lYOffset << 16));
  211. ppdev->pfnCursorOn(ppdev, lCurOffset);
  212. }
  213. VOID vM64UpdateCursorPosition(
  214. PDEV* ppdev,
  215. LONG x,
  216. LONG y)
  217. {
  218. M64_OD_DIRECT(ppdev->pjMmBase, CUR_HORZ_VERT_POSN, x | (y << 16));
  219. }
  220. VOID vM64CursorOff(PDEV* ppdev)
  221. {
  222. BYTE* pjMmBase = ppdev->pjMmBase;
  223. ULONG ldata;
  224. #ifndef NO_VERTICAL_SYNC
  225. ULONG ldata1;
  226. // Read the no. of total verticales lines (including the overscan)
  227. ldata1 = M64_ID(pjMmBase,CRTC_V_TOTAL_DISP);
  228. ldata1 = ldata1&0x7ff;
  229. again:
  230. //read the current verticale line
  231. ldata = M64_ID(pjMmBase,CRTC_CRNT_VLINE);
  232. ldata = (ldata&0x7ff0000)>>16;
  233. //synchronise the drawing with the vertical line
  234. if (ldata >= (ldata1-3))
  235. {
  236. #endif // !NO_VERTICAL_SYNC
  237. //Disable the hardware cursor
  238. ldata = M64_ID(pjMmBase,GEN_TEST_CNTL);
  239. M64_OD_DIRECT(pjMmBase, GEN_TEST_CNTL, ldata & ~GEN_TEST_CNTL_CursorEna);
  240. #ifndef NO_VERTICAL_SYNC
  241. }
  242. else
  243. {
  244. goto again;
  245. }
  246. #endif // !NO_VERTICAL_SYNC
  247. }
  248. VOID vM64CursorOn(PDEV* ppdev, LONG lCurOffset)
  249. {
  250. BYTE* pjMmBase = ppdev->pjMmBase;
  251. ULONG ldata;
  252. #ifndef NO_VERTICAL_SYNC
  253. ULONG ldata1;
  254. #endif // !NO_VERTICAL_SYNC
  255. if (!flag_enable)
  256. {
  257. flag_enable=TRUE;
  258. ldata = M64_ID(pjMmBase,GEN_TEST_CNTL);
  259. M64_OD_DIRECT(pjMmBase, GEN_TEST_CNTL, ldata | GEN_TEST_CNTL_CursorEna);
  260. }
  261. #ifndef NO_VERTICAL_SYNC
  262. /*
  263. * Read the no. of total vertical lines (including the overscan)
  264. */
  265. ldata1 = M64_ID(pjMmBase,CRTC_V_TOTAL_DISP);
  266. ldata1 = ldata1&0x7ff;
  267. again:
  268. /*
  269. * read the current vertical line
  270. */
  271. ldata = M64_ID(pjMmBase,CRTC_CRNT_VLINE);
  272. ldata = (ldata&0x7ff0000)>>16;
  273. /*
  274. * Synchronise the drawing of cursor
  275. */
  276. if (ldata >= (ldata1-3))
  277. {
  278. #endif // !NO_VERTICAL_SYNC
  279. ppdev->pfnUpdateCursorPosition(ppdev,ppdev->ppointer->ptlLastPosition.x+0,ppdev->ppointer->ptlLastPosition.y+0);
  280. ldata = M64_ID(pjMmBase,GEN_TEST_CNTL);
  281. M64_OD_DIRECT(pjMmBase, GEN_TEST_CNTL, ldata | GEN_TEST_CNTL_CursorEna);
  282. #ifndef NO_VERTICAL_SYNC
  283. }
  284. else
  285. {
  286. goto again;
  287. }
  288. #endif // !NO_VERTICAL_SYNC
  289. }
  290. VOID vM64SetCursorOffset_TVP(PDEV* ppdev)
  291. {
  292. }
  293. VOID vM64UpdateCursorOffset_TVP(
  294. PDEV* ppdev,
  295. LONG lXOffset,
  296. LONG lYOffset,
  297. LONG lCurOffset)
  298. {
  299. ppdev->ppointer->ptlLastOffset.x=lXOffset;
  300. ppdev->ppointer->ptlLastOffset.y=lYOffset;
  301. /* Change the offset... used in UpdateCursorPosition */
  302. }
  303. VOID vM64UpdateCursorPosition_TVP(
  304. PDEV* ppdev,
  305. LONG x,
  306. LONG y)
  307. {
  308. BYTE* pjMmBase = ppdev->pjMmBase;
  309. ULONG dacRead;
  310. //DbgOut("\nvUpdateCursorPosition_TVP_M64 called");
  311. ppdev->ppointer->ptlLastPosition.y=y;
  312. ppdev->ppointer->ptlLastPosition.x=x;
  313. // Note: SetCursorOffset, UpdateCursorOffset must set ptlLastOffset
  314. x+= 64-ppdev->ppointer->ptlLastOffset.x;
  315. y+= 64-ppdev->ppointer->ptlLastOffset.y;
  316. // check for coordinate violations
  317. if (x < 0) x = 0;
  318. if (y < 0) y = 0;
  319. dacRead = M64_ID(pjMmBase,DAC_CNTL);
  320. M64_OD_DIRECT(pjMmBase, DAC_CNTL, (dacRead & 0xfffffffc) | 3);
  321. M64_OD_DIRECT(pjMmBase, DAC_REGS+REG_W, (y<<16) | x);
  322. dacRead = M64_ID(pjMmBase,DAC_CNTL);
  323. M64_OD_DIRECT(pjMmBase, DAC_CNTL, dacRead & 0xfffffffc);
  324. }
  325. VOID vM64CursorOff_TVP(PDEV* ppdev)
  326. {
  327. UCHAR * ucDacReg;
  328. UCHAR * ucDacCntl;
  329. // Initialize DAC registers
  330. vDacRegs(ppdev, &ucDacReg, &ucDacCntl);
  331. rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
  332. rioOB(ucDacReg+REG_W, 6); // register 6
  333. rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc) | 2);
  334. rioOB(ucDacReg+REG_M, 0); // (+Mask) disable
  335. rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
  336. }
  337. VOID vM64CursorOn_TVP(PDEV* ppdev, LONG lCurOffset)
  338. {
  339. UCHAR * ucDacReg;
  340. UCHAR * ucDacCntl;
  341. /*
  342. * Initialize DAC registers
  343. */
  344. vDacRegs(ppdev, &ucDacReg, &ucDacCntl);
  345. /*
  346. * Access cursor control register
  347. */
  348. rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
  349. rioOB(ucDacReg+REG_W, 6); // register 6
  350. rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc) | 2);
  351. rioOB(ucDacReg+REG_M, 2); // XGA cursor type
  352. rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
  353. }
  354. VOID vM64SetCursorOffset_IBM514(PDEV* ppdev)
  355. {
  356. }
  357. VOID vM64UpdateCursorOffset_IBM514(
  358. PDEV* ppdev,
  359. LONG lXOffset,
  360. LONG lYOffset,
  361. LONG lCurOffset)
  362. {
  363. ppdev->ppointer->ptlLastOffset.x=lXOffset ;//-64;
  364. ppdev->ppointer->ptlLastOffset.y=lYOffset ;//-64;
  365. /*
  366. * These two statements have been introduced in order to solve the ghost cursor on IBM Dac cards
  367. */
  368. ppdev->pfnUpdateCursorPosition(ppdev,ppdev->ppointer->ptlLastPosition.x+0,ppdev->ppointer->ptlLastPosition.y+0);
  369. ppdev->pfnCursorOn(ppdev, lCurOffset);
  370. /* Change the offset... used in UpdateCursorPosition */
  371. }
  372. VOID vM64UpdateCursorPosition_IBM514(
  373. PDEV* ppdev,
  374. LONG x,
  375. LONG y)
  376. {
  377. UCHAR * ucDacReg;
  378. UCHAR * ucDacCntl;
  379. // Initialize DAC registers
  380. vDacRegs(ppdev, &ucDacReg, &ucDacCntl);
  381. ppdev->ppointer->ptlLastPosition.y=y;
  382. ppdev->ppointer->ptlLastPosition.x=x;
  383. // Note: SetCursorOffset, UpdateCursorOffset must set ptlLastOffset
  384. x-= ppdev->ppointer->ptlLastOffset.x;
  385. y-= ppdev->ppointer->ptlLastOffset.y;
  386. rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc)| 1);
  387. rioOB(ucDacReg+REG_R, 1);
  388. rioOB(ucDacReg+REG_W, 0x31);
  389. rioOB(ucDacReg+REG_D, 0);
  390. rioOB(ucDacReg+REG_M, x&0xFF);
  391. rioOB(ucDacReg+REG_M, (UCHAR)(x>>8));
  392. rioOB(ucDacReg+REG_M, y&0xFF);
  393. rioOB(ucDacReg+REG_M, (UCHAR)(y>>8));
  394. rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
  395. }
  396. VOID vM64CursorOff_IBM514(PDEV* ppdev) // DONE
  397. {
  398. BYTE* pjMmBase = ppdev->pjMmBase;
  399. UCHAR * ucDacReg;
  400. UCHAR * ucDacCntl;
  401. #ifndef NO_VERTICAL_SYNC
  402. ULONG ldata;
  403. ULONG ldata1;
  404. /*
  405. * Read the no. of total vertical lines (including the overscan)
  406. */
  407. ldata1 = M64_ID(pjMmBase,CRTC_V_TOTAL_DISP);
  408. ldata1 = ldata1&0x7ff;
  409. again:
  410. /*
  411. * Read the current vertical line
  412. */
  413. ldata = M64_ID(pjMmBase,CRTC_CRNT_VLINE);
  414. ldata = (ldata&0x7ff0000)>>16;
  415. /*
  416. * Synchronise the drawing with the vertical line
  417. */
  418. if (ldata >= (ldata1-3))
  419. {
  420. #endif // !NO_VERTICAL_SYNC
  421. /*
  422. * Initialize DAC registers
  423. */
  424. vDacRegs(ppdev, &ucDacReg, &ucDacCntl);
  425. rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc)|1);
  426. rioOB(ucDacReg+REG_R, 1);
  427. rioOB(ucDacReg+REG_W, 0x30);
  428. rioOB(ucDacReg+REG_D, 0); // (+Data)
  429. rioOB(ucDacReg+REG_M, 0); // (+Mask)
  430. rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
  431. #ifndef NO_VERTICAL_SYNC
  432. }
  433. else
  434. {
  435. goto again;
  436. }
  437. #endif // !NO_VERTICAL_SYNC
  438. }
  439. VOID vM64CursorOn_IBM514(PDEV* ppdev, LONG lCurOffset) //DONE
  440. {
  441. BYTE* pjMmBase = ppdev->pjMmBase;
  442. UCHAR * ucDacReg;
  443. UCHAR * ucDacCntl;
  444. #ifndef NO_VERTICAL_SYNC
  445. ULONG ldata;
  446. ULONG ldata1;
  447. /*
  448. * Read the no. of total vertical lines (including the overscan)
  449. */
  450. ldata1 = M64_ID(pjMmBase,CRTC_V_TOTAL_DISP);
  451. ldata1 = ldata1&0x7ff;
  452. again:
  453. /*
  454. * Read the current verticale line
  455. */
  456. ldata = M64_ID(pjMmBase,CRTC_CRNT_VLINE);
  457. ldata = (ldata&0x7ff0000)>>16;
  458. /*
  459. * Synchronise the drawing of cursor
  460. */
  461. if (ldata >= (ldata1-3))
  462. {
  463. #endif // !NO_VERTICAL_SYNC
  464. // Initialize DAC registers
  465. vDacRegs(ppdev, &ucDacReg, &ucDacCntl);
  466. // access cursor control register
  467. rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc) | 1);
  468. rioOB(ucDacReg+REG_R, 1);
  469. rioOB(ucDacReg+REG_W, 0x30);
  470. rioOB(ucDacReg+REG_D, 0); // register 6
  471. rioOB(ucDacReg+REG_M, 0xE); // register 6
  472. rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
  473. #ifndef NO_VERTICAL_SYNC
  474. }
  475. else
  476. {
  477. goto again;
  478. }
  479. #endif // !NO_VERTICAL_SYNC
  480. }
  481. VOID vM64UpdateCursorOffset_CT(
  482. PDEV* ppdev,
  483. LONG lXOffset,
  484. LONG lYOffset,
  485. LONG lCurOffset)
  486. {
  487. BYTE* pjMmBase = ppdev->pjMmBase;
  488. ppdev->pfnCursorOff(ppdev);
  489. M64_OD_DIRECT(pjMmBase, CUR_OFFSET, lCurOffset >> 1);
  490. M64_OD_DIRECT(pjMmBase, CUR_HORZ_VERT_OFF, lXOffset | (lYOffset << 16));
  491. ppdev->pfnCursorOn(ppdev, lCurOffset);
  492. }
  493. VOID vM64CursorOff_CT(PDEV* ppdev)
  494. {
  495. BYTE* pjMmBase = ppdev->pjMmBase;
  496. #ifndef NO_VERTICAL_SYNC
  497. ULONG ldata;
  498. ULONG ldata1;
  499. // Read the no. of total verticales lines (including the overscan)
  500. ldata1 = M64_ID(pjMmBase,CRTC_V_TOTAL_DISP);
  501. ldata1 = ldata1&0x7ff;
  502. again:
  503. //read the current verticale line
  504. ldata = M64_ID(pjMmBase,CRTC_CRNT_VLINE);
  505. ldata = (ldata&0x7ff0000)>>16;
  506. //synchronise the drawing with the vertical line
  507. if (ldata >= (ldata1-3))
  508. {
  509. #endif // !NO_VERTICAL_SYNC
  510. ppdev->pfnUpdateCursorPosition(ppdev, -1, -1);
  511. #ifndef NO_VERTICAL_SYNC
  512. }
  513. else
  514. {
  515. goto again;
  516. }
  517. #endif // !NO_VERTICAL_SYNC
  518. }
  519. VOID vM64CursorOn_CT(PDEV* ppdev, LONG lCurOffset)
  520. {
  521. BYTE* pjMmBase = ppdev->pjMmBase;
  522. ULONG ldata;
  523. #ifndef NO_VERTICAL_SYNC
  524. ULONG ldata1;
  525. #endif // !NO_VERTICAL_SYNC
  526. if (!flag_enable)
  527. {
  528. flag_enable=TRUE;
  529. ldata = M64_ID(pjMmBase,GEN_TEST_CNTL);
  530. M64_OD_DIRECT(pjMmBase, GEN_TEST_CNTL, ldata | GEN_TEST_CNTL_CursorEna);
  531. }
  532. #ifndef NO_VERTICAL_SYNC
  533. /*
  534. * Read the no. of total vertical lines (including the overscan)
  535. */
  536. ldata1 = M64_ID(pjMmBase,CRTC_V_TOTAL_DISP);
  537. ldata1 = ldata1&0x7ff;
  538. again:
  539. /*
  540. * read the current vertical line
  541. */
  542. ldata = M64_ID(pjMmBase,CRTC_CRNT_VLINE);
  543. ldata = (ldata&0x7ff0000)>>16;
  544. /*
  545. * Synchronise the drawing of cursor
  546. */
  547. if (ldata >= (ldata1-3))
  548. {
  549. #endif // !NO_VERTICAL_SYNC
  550. ppdev->pfnUpdateCursorPosition(ppdev,ppdev->ppointer->ptlLastPosition.x+0,ppdev->ppointer->ptlLastPosition.y+0);
  551. #ifndef NO_VERTICAL_SYNC
  552. }
  553. else
  554. {
  555. goto again;
  556. }
  557. #endif // !NO_VERTICAL_SYNC
  558. }
  559. VOID vM64PointerBlit(
  560. PDEV *ppdev,
  561. LONG x,
  562. LONG y,
  563. LONG cx,
  564. LONG cy,
  565. PBYTE pbsrc,
  566. LONG lDelta)
  567. {
  568. BYTE* pjMmBase = ppdev->pjMmBase;
  569. LONG cxbytes;
  570. cxbytes = cx / 8;
  571. M64_CHECK_FIFO_SPACE(ppdev, pjMmBase, 7);
  572. //M64_OD(pjMmBase, CONTEXT_LOAD_CNTL, CONTEXT_LOAD_CmdLoad | ppdev->iDefContext );
  573. M64_OD(pjMmBase,DP_PIX_WIDTH, 0x020202); // assert 8 bpp
  574. M64_OD(pjMmBase,DST_OFF_PITCH,(ppdev->ulVramOffset + ((y*ppdev->lDelta) >> 3)) |
  575. (ROUND8(cxbytes) << 19));
  576. if (cxbytes >= (LONG)ppdev->cxScreen)
  577. {
  578. M64_OD(pjMmBase,SC_RIGHT, cxbytes);
  579. }
  580. M64_OD(pjMmBase,DP_MIX, (OVERPAINT << 16));
  581. M64_OD(pjMmBase,DP_SRC, DP_SRC_Host << 8);
  582. M64_OD(pjMmBase,DST_Y_X, 0L);
  583. M64_OD(pjMmBase,DST_HEIGHT_WIDTH, 1 | (cxbytes << 16));
  584. vM64DataPortOutB(ppdev, pbsrc, cxbytes);
  585. // Fix a timing problem that leaves a remnant line segment in the lower right
  586. // of the 64x64 cursor.
  587. vM64QuietDown(ppdev, pjMmBase);
  588. M64_CHECK_FIFO_SPACE(ppdev, pjMmBase, 3);
  589. M64_OD(pjMmBase, DP_PIX_WIDTH, ppdev->ulMonoPixelWidth);
  590. M64_OD(pjMmBase, DST_OFF_PITCH, ppdev->ulScreenOffsetAndPitch);
  591. M64_OD(pjMmBase, SC_RIGHT, M64_MAX_SCISSOR_R);
  592. }
  593. VOID vM64PointerBlit_TVP(
  594. PDEV *ppdev,
  595. LONG x,
  596. LONG y,
  597. LONG cx,
  598. LONG cy,
  599. PBYTE pbsrc,
  600. LONG lDelta)
  601. {
  602. PBYTE cur_data;
  603. ULONG i;
  604. UCHAR * ucDacReg;
  605. UCHAR * ucDacCntl;
  606. // Initialize DAC registers
  607. vDacRegs(ppdev, &ucDacReg, &ucDacCntl);
  608. cur_data=pbsrc;
  609. rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc); // Disable cursor
  610. rioOB(ucDacReg+REG_W, 6); // register 6
  611. rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc) | 2);
  612. rioOB(ucDacReg+REG_M, 0); // (+Mask) disable
  613. // set cursor RAM write address to 0
  614. rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
  615. rioOB(ucDacReg+REG_W, 0);
  616. // select cursor RAM data register - auto increments with each write
  617. rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc) | 2);
  618. for (i = 0; i < 1024; i++)
  619. {
  620. rioOB(ucDacReg+REG_R, *cur_data++);
  621. }
  622. // select default palette registers
  623. rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
  624. rioOB(ucDacReg+REG_W, 6); // register 6
  625. rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc) | 2);
  626. rioOB(ucDacReg+REG_M, 2); // XGA cursor type
  627. rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
  628. }
  629. VOID vM64PointerBlit_IBM514(
  630. PDEV *ppdev,
  631. LONG x,
  632. LONG y,
  633. LONG cx,
  634. LONG cy,
  635. PBYTE pbsrc,
  636. LONG lDelta)
  637. {
  638. PBYTE cur_data, pjMmBase = ppdev->pjMmBase;
  639. ULONG i;
  640. UCHAR * ucDacReg;
  641. UCHAR * ucDacCntl;
  642. #ifndef NO_VERTICAL_SYNC
  643. ULONG ldata;
  644. ULONG ldata1;
  645. #endif // !NO_VERTICAL_SYNC
  646. // Initialize DAC registers
  647. vDacRegs(ppdev, &ucDacReg, &ucDacCntl);
  648. cur_data=pbsrc;
  649. #ifndef NO_VERTICAL_SYNC
  650. /*
  651. * Read the no. of total vertical lines (including the overscan)
  652. */
  653. ldata1 = M64_ID(pjMmBase, CRTC_V_TOTAL_DISP);
  654. ldata1 = ldata1&0x7ff;
  655. again:
  656. /*
  657. * Read the current vertical line
  658. */
  659. ldata = M64_ID(pjMmBase, CRTC_CRNT_VLINE);
  660. ldata = (ldata&0x7ff0000)>>16;
  661. // synchronise the drawing of cursor
  662. if (ldata >= (ldata1-3))
  663. {
  664. #endif // !NO_VERTICAL_SYNC
  665. rioOB(ucDacCntl, (rioIB(ucDacCntl) & 0xfc)|1); // Disable cursor
  666. rioOB(ucDacReg+REG_R, 1);
  667. rioOB(ucDacReg+REG_W, 0);
  668. rioOB(ucDacReg+REG_D, 1);
  669. #ifndef NO_VERTICAL_SYNC
  670. }
  671. else
  672. {
  673. goto again;
  674. }
  675. #endif // !NO_VERTICAL_SYNC
  676. // select cursor RAM data register - auto increments with each write
  677. for (i = 0; i < 1024; i++)
  678. {
  679. rioOB(ucDacReg+REG_M, *cur_data++);
  680. }
  681. /* Set HOT SPOT registers.. RSL Important? */
  682. rioOB(ucDacReg+REG_W, 0x35);
  683. rioOB(ucDacReg+REG_D, 0);
  684. rioOB(ucDacReg+REG_M, 0);
  685. rioOB(ucDacReg+REG_M, 0);
  686. rioOB(ucDacCntl, rioIB(ucDacCntl) & 0xfc);
  687. }
  688. // END MACH64 ------------------------------------------------------------------
  689. /******************************Public*Routine******************************\
  690. * CopyMonoCursor
  691. *
  692. * Copies two monochrome masks into a 2bpp bitmap. Returns TRUE if it
  693. * can make a hardware cursor, FALSE if not.
  694. *
  695. * modified by Wendy Yee -1992-10-16- to accomodate 68800
  696. \**************************************************************************/
  697. BOOLEAN CopyMonoCursor(PDEV *ppdev, BYTE *pjSrcAnd, BYTE *pjSrcOr)
  698. {
  699. BYTE jSrcAnd;
  700. BYTE jSrcOr;
  701. LONG count;
  702. BYTE *pjDest;
  703. BYTE jDest = 0;
  704. LONG nbytes;
  705. pjDest = (PBYTE) HardWareCursorShape;
  706. if ( ppdev->FeatureFlags & EVN_TVP_DAC_CUR)
  707. {
  708. nbytes=CURSOR_CX*CURSOR_CY/8;
  709. for (count = 0; count < nbytes; count++)
  710. {
  711. *(pjDest )= *pjSrcOr; // Gives outline!
  712. *(pjDest+nbytes)= *pjSrcAnd;
  713. pjDest++;
  714. pjSrcOr++;
  715. pjSrcAnd++;
  716. }
  717. for (;count < 512; count++)
  718. {
  719. *pjDest=0;
  720. *(pjDest+nbytes)=0xFF;
  721. }
  722. return(TRUE);
  723. }
  724. for (count = 0; count < (CURSOR_CX * CURSOR_CY);)
  725. {
  726. if (!(count & 0x07)) // need new src byte every 8th count;
  727. { // each byte = 8 pixels
  728. jSrcAnd = *(pjSrcAnd++);
  729. jSrcOr = *(pjSrcOr++);
  730. }
  731. if (jSrcAnd & 0x80) // AND mask's white-1 background
  732. {
  733. if (jSrcOr & 0x80) // XOR mask's white-1 outline
  734. jDest |= 0xC0; // Complement
  735. else
  736. jDest |= 0x80; // Set destination to Transparent
  737. }
  738. else
  739. { // AND mask's cursor silhouette in black-0
  740. if (jSrcOr & 0x80)
  741. jDest |= 0x40; // Color 1 - white
  742. else
  743. jDest |= 0x00; // Color 0 - black
  744. }
  745. count++;
  746. if (!(count & 0x3)) // New DestByte every 4 times for 4 pixels per byte
  747. {
  748. *pjDest = jDest; // save pixel after rotating to right 3x
  749. pjDest++;
  750. jDest = 0;
  751. }
  752. else
  753. {
  754. jDest >>= 2; // Next Pixel
  755. }
  756. jSrcOr <<= 1;
  757. jSrcAnd <<= 1;
  758. }
  759. while (count++ < 64*64)
  760. if (!(count & 0x3)) // need new src byte every 8th count;
  761. { // each byte = 8 pixels
  762. *pjDest =0xaa;
  763. pjDest++;
  764. }
  765. return(TRUE);
  766. }
  767. ULONG lSetMonoHwPointerShape(
  768. SURFOBJ *pso,
  769. SURFOBJ *psoMask,
  770. SURFOBJ *psoColor,
  771. XLATEOBJ *pxlo,
  772. LONG xHot,
  773. LONG yHot,
  774. LONG x,
  775. LONG y,
  776. RECTL *prcl,
  777. FLONG fl)
  778. {
  779. LONG count;
  780. ULONG cy;
  781. PBYTE pjSrcAnd, pjSrcXor;
  782. LONG lDeltaSrc, lDeltaDst;
  783. LONG lSrcWidthInBytes;
  784. ULONG cxSrc = pso->sizlBitmap.cx;
  785. ULONG cySrc = pso->sizlBitmap.cy;
  786. ULONG cxSrcBytes;
  787. BYTE AndMask[CURSOR_CX][CURSOR_CX/8];
  788. BYTE XorMask[CURSOR_CY][CURSOR_CY/8];
  789. PBYTE pjDstAnd = (PBYTE)AndMask;
  790. PBYTE pjDstXor = (PBYTE)XorMask;
  791. PDEV* ppdev;
  792. PCUROBJ ppointer;
  793. ppdev=(PDEV*)pso->dhpdev;
  794. ppointer = ppdev->ppointer;
  795. // If the mask is NULL this implies the pointer is not
  796. // visible.
  797. if (psoMask == NULL)
  798. {
  799. if (ppointer->flPointer & MONO_POINTER_UP)
  800. {
  801. //DbgOut("\nThe cursor was disabled because of psoMask");
  802. ppdev->pfnCursorOff(ppdev);
  803. ppointer->flPointer &= ~MONO_POINTER_UP;
  804. }
  805. return (SPS_ACCEPT_NOEXCLUDE) ;
  806. }
  807. // Get the bitmap dimensions.
  808. cxSrc = psoMask->sizlBitmap.cx ;
  809. cySrc = psoMask->sizlBitmap.cy ;
  810. // set the dest and mask to 0xff
  811. memset(pjDstAnd, 0xFFFFFFFF, CURSOR_CX/8 * CURSOR_CY);
  812. // Zero the dest XOR mask
  813. memset(pjDstXor, 0, CURSOR_CX/8 * CURSOR_CY);
  814. cxSrcBytes = (cxSrc + 7) / 8;
  815. if ((lDeltaSrc = psoMask->lDelta) < 0)
  816. lSrcWidthInBytes = -lDeltaSrc;
  817. else
  818. lSrcWidthInBytes = lDeltaSrc;
  819. pjSrcAnd = (PBYTE) psoMask->pvScan0;
  820. // Height of just AND mask
  821. cySrc = cySrc / 2;
  822. // Point to XOR mask
  823. pjSrcXor = pjSrcAnd + (cySrc * lDeltaSrc);
  824. // Offset from end of one dest scan to start of next
  825. lDeltaDst = CURSOR_CX/8;
  826. for (cy = 0; cy < cySrc; ++cy)
  827. {
  828. memcpy(pjDstAnd, pjSrcAnd, cxSrcBytes);
  829. memcpy(pjDstXor, pjSrcXor, cxSrcBytes);
  830. // Point to next source and dest scans
  831. pjSrcAnd += lDeltaSrc;
  832. pjSrcXor += lDeltaSrc;
  833. pjDstAnd += lDeltaDst;
  834. pjDstXor += lDeltaDst;
  835. }
  836. if (CopyMonoCursor(ppdev, (PBYTE)AndMask, (PBYTE)XorMask))
  837. {
  838. // Down load the pointer shape to the engine.
  839. count = CURSOR_CX * CURSOR_CY * 2;
  840. if (ppdev->iAsic == ASIC_88800GX)
  841. {
  842. // double buffering used for Ghost EPR
  843. if (!ppdev->bAltPtrActive)
  844. {
  845. ppointer = ppdev->ppointer = &ppdev->pointer1;
  846. ppdev->pointer1.ptlHotSpot = ppdev->pointer2.ptlHotSpot;
  847. ppdev->pointer1.ptlLastPosition= ppdev->pointer2.ptlLastPosition;
  848. ppdev->pointer1.ptlLastOffset = ppdev->pointer2.ptlLastOffset;
  849. ppdev->pointer1.flPointer = ppdev->pointer2.flPointer;
  850. ppdev->pointer1.szlPointer = ppdev->pointer2.szlPointer;
  851. }
  852. else
  853. {
  854. ppointer = ppdev->ppointer = &ppdev->pointer2;
  855. ppdev->pointer2.ptlHotSpot = ppdev->pointer1.ptlHotSpot;
  856. ppdev->pointer2.ptlLastPosition= ppdev->pointer1.ptlLastPosition;
  857. ppdev->pointer2.ptlLastOffset = ppdev->pointer1.ptlLastOffset;
  858. ppdev->pointer2.flPointer = ppdev->pointer1.flPointer;
  859. ppdev->pointer2.szlPointer = ppdev->pointer1.szlPointer;
  860. }
  861. ppdev->bAltPtrActive = !ppdev->bAltPtrActive;
  862. }
  863. ppdev->pfnSetCursorOffset(ppdev);
  864. ppdev->pfnPointerBlit(ppdev,
  865. ppointer->hwCursor.x,
  866. ppointer->hwCursor.y,
  867. count,
  868. 1L,
  869. (PBYTE) &HardWareCursorShape,
  870. 0L);
  871. }
  872. else
  873. return(SPS_ERROR);
  874. // Set the position of the cursor.
  875. if (fl & SPS_ANIMATEUPDATE)
  876. {
  877. //DbgOut("animate cursor\n");
  878. if ( (ppointer->ptlLastPosition.x < 0) ||
  879. (ppointer->ptlLastPosition.y < 0) )
  880. {
  881. ppointer->ptlLastPosition.x = x - CURSOR_CX;
  882. ppointer->ptlLastPosition.y = y - CURSOR_CY;
  883. }
  884. }
  885. else
  886. {
  887. ppointer->ptlLastPosition.x = -x - 2;
  888. ppointer->ptlLastPosition.y = -y - 2;
  889. // DbgOut("See what last position we set in DrvSetPointerShape: x=%d y=%d\n",ppointer->ptlLastPosition.x,ppointer->ptlLastPosition.y);
  890. }
  891. if (x == -1)
  892. {
  893. ppointer->ptlLastPosition.x = x;
  894. ppointer->ptlLastPosition.y = y;
  895. return (SPS_ACCEPT_NOEXCLUDE) ;
  896. }
  897. //flag for enforcing a special approach from DrvMovePointer
  898. flag_shape=TRUE;
  899. DrvMovePointer(pso, x, y, NULL) ;
  900. if (!(ppointer->flPointer & MONO_POINTER_UP))
  901. {
  902. ppointer->ptlLastPosition.x = x;
  903. ppointer->ptlLastPosition.y = y;
  904. ppdev->pfnCursorOn(ppdev, ppointer->mono_offset);
  905. ppointer->flPointer |= MONO_POINTER_UP;
  906. }
  907. return (SPS_ACCEPT_NOEXCLUDE) ;
  908. }
  909. /******************************Public*Routine******************************\
  910. * VOID DrvSetPointerShape
  911. *
  912. * Sets the new pointer shape.
  913. *
  914. \**************************************************************************/
  915. ULONG DrvSetPointerShape(
  916. SURFOBJ* pso,
  917. SURFOBJ* psoMask,
  918. SURFOBJ* psoColor,
  919. XLATEOBJ* pxlo,
  920. LONG xHot,
  921. LONG yHot,
  922. LONG x,
  923. LONG y,
  924. RECTL* prcl,
  925. FLONG fl)
  926. {
  927. ULONG ulRet ;
  928. PDEV* ppdev ;
  929. LONG lX ;
  930. PCUROBJ ppointer;
  931. ppdev=(PDEV*)pso->dhpdev;
  932. ppointer = ppdev->ppointer;
  933. // Save the position and hot spot in pdev
  934. ppointer->ptlHotSpot.x = xHot ;
  935. ppointer->ptlHotSpot.y = yHot ;
  936. ppointer->szlPointer.cx = psoMask->sizlBitmap.cx ;
  937. ppointer->szlPointer.cy = psoMask->sizlBitmap.cy / 2;
  938. // The pointer may be larger than we can handle.
  939. // We don't want to draw colour cursors either - let GDI do it
  940. // If it is we must cleanup the screen and let the engine
  941. // take care of it.
  942. if (psoMask->sizlBitmap.cx > CURSOR_CX ||
  943. psoMask->sizlBitmap.cy > CURSOR_CY ||
  944. psoColor != NULL ||
  945. ppointer->flPointer & NO_HARDWARE_CURSOR)
  946. {
  947. // Disable the mono hardware pointer.
  948. if (ppointer->flPointer & MONO_POINTER_UP)
  949. {
  950. ppdev->pfnCursorOff(ppdev);
  951. ppointer->flPointer &= ~MONO_POINTER_UP;
  952. }
  953. return (SPS_DECLINE);
  954. }
  955. // odd cursor positions not displayed in 1280 mode
  956. lX = x-xHot;
  957. if (ppdev->cxScreen == 0x500)
  958. lX &= 0xfffffffe;
  959. if(ppdev->iAsic == ASIC_88800GX)
  960. {
  961. //disable the hardware cursor
  962. ppdev->pfnCursorOff(ppdev);
  963. #if MULTI_BOARDS
  964. {
  965. OH* poh;
  966. if (x != -1)
  967. {
  968. poh = ((DSURF*) pso->dhsurf)->poh;
  969. x += poh->x;
  970. y += poh->y;
  971. }
  972. }
  973. #endif
  974. }
  975. // Take care of the monochrome pointer.
  976. ulRet = lSetMonoHwPointerShape(pso, psoMask, psoColor, pxlo,
  977. xHot, yHot, x, y, prcl, fl) ;
  978. return (ulRet) ;
  979. }
  980. /******************************Public*Routine******************************\
  981. * VOID DrvMovePointer
  982. *
  983. * NOTE: Because we have set GCAPS_ASYNCMOVE, this call may occur at any
  984. * time, even while we're executing another drawing call!
  985. *
  986. * Consequently, we have to explicitly synchronize any shared
  987. * resources. In our case, since we touch the CRTC register here
  988. * and in the banking code, we synchronize access using a critical
  989. * section.
  990. *
  991. \**************************************************************************/
  992. VOID DrvMovePointer(
  993. SURFOBJ* pso,
  994. LONG x,
  995. LONG y,
  996. RECTL* prcl)
  997. {
  998. PDEV* ppdev ;
  999. PCUROBJ ppointer;
  1000. LONG lXOffset, lYOffset;
  1001. LONG lCurOffset;
  1002. BOOL bUpdatePtr = FALSE;
  1003. BOOL bUpdateOffset = FALSE;
  1004. ppdev=(PDEV*)pso->dhpdev;
  1005. ppointer = ppdev->ppointer;
  1006. // If x is -1 then take down the cursor.
  1007. if (x == -1)
  1008. {
  1009. ppointer->ptlLastPosition.x=-1;
  1010. ppointer->ptlLastPosition.y=y;
  1011. ppdev->pfnCursorOff(ppdev);
  1012. ppointer->flPointer &= ~MONO_POINTER_UP;
  1013. return;
  1014. }
  1015. #if MULTI_BOARDS
  1016. if (flag_shape!=TRUE)
  1017. {
  1018. OH* poh;
  1019. poh = ((DSURF*) pso->dhsurf)->poh;
  1020. x += poh->x;
  1021. y += poh->y;
  1022. }
  1023. #endif
  1024. // Adjust the actual pointer position depending upon
  1025. // the hot spot.
  1026. x -= ppointer->ptlHotSpot.x ;
  1027. y -= ppointer->ptlHotSpot.y ;
  1028. // odd cursor positions not displayed in 1280 mode
  1029. if (ppdev->cxScreen == 0x500)
  1030. x &= 0xfffffffe;
  1031. // get current offsets
  1032. lXOffset = ppointer->ptlLastOffset.x;
  1033. lYOffset = ppointer->ptlLastOffset.y;
  1034. lCurOffset = ppointer->mono_offset;
  1035. /*
  1036. ;
  1037. ;Deal with changes in X:
  1038. ;
  1039. */
  1040. if (x!=ppointer->ptlLastPosition.x) /* did our X coordinate change? */
  1041. {
  1042. bUpdatePtr = TRUE;
  1043. if (x<0) /* is cursor negative? */
  1044. {
  1045. bUpdateOffset = TRUE;
  1046. lXOffset = -x; /* reset size of cursor to < original */
  1047. x = 0; /* set cursor to origin */
  1048. }
  1049. else if (ppointer->ptlLastPosition.x<=0)
  1050. {
  1051. bUpdateOffset = TRUE; /* reset size of cursor to original */
  1052. lXOffset = 0;
  1053. }
  1054. }
  1055. /*
  1056. ;
  1057. ;Deal with changes in Y
  1058. ;
  1059. */
  1060. if (y!=ppointer->ptlLastPosition.y)
  1061. {
  1062. bUpdatePtr = TRUE;
  1063. if (y<0)
  1064. {
  1065. // Move start pointer of cursor down and cursor base up to
  1066. // compensate. The (-4) is the pitch if the cursor in dwords
  1067. bUpdateOffset = TRUE;
  1068. lYOffset = -y; /* reset size of cursor to < original */
  1069. lCurOffset -= 4*y;
  1070. y = 0; /* set base of cursor to Y */
  1071. }
  1072. else if (ppointer->ptlLastPosition.y<=0)
  1073. {
  1074. bUpdateOffset = TRUE; /* reset size of cursor to original */
  1075. lYOffset = 0;
  1076. }
  1077. }
  1078. if(ppdev->iAsic != ASIC_88800GX)
  1079. {
  1080. flag_shape=FALSE;
  1081. }
  1082. if (flag_shape)
  1083. {
  1084. flag_shape=FALSE;
  1085. ppointer->ptlLastPosition.x=x;
  1086. ppointer->ptlLastPosition.y=y;
  1087. if (bUpdateOffset)
  1088. {
  1089. ppdev->pfnUpdateCursorOffset(ppdev, lXOffset, lYOffset, lCurOffset);
  1090. ppointer->ptlLastOffset.x=lXOffset;
  1091. ppointer->ptlLastOffset.y=lYOffset;
  1092. ppointer->flPointer |= MONO_POINTER_UP;
  1093. }
  1094. else
  1095. {
  1096. if (ppdev->iAsic == ASIC_88800GX)
  1097. {
  1098. //this is a new statement imposed by double buffering
  1099. ppdev->pfnUpdateCursorOffset(ppdev, lXOffset, lYOffset, lCurOffset);
  1100. ppointer->flPointer |= MONO_POINTER_UP;
  1101. //only for no double buffering
  1102. //ppdev->_vCursorOn(ppdev, lCurOffset);
  1103. }
  1104. }
  1105. }
  1106. else
  1107. {
  1108. ppointer->ptlLastPosition.x=x;
  1109. ppointer->ptlLastPosition.y=y;
  1110. if (bUpdateOffset)
  1111. {
  1112. ppdev->pfnUpdateCursorOffset(ppdev, lXOffset, lYOffset, lCurOffset);
  1113. ppointer->ptlLastOffset.x=lXOffset;
  1114. ppointer->ptlLastOffset.y=lYOffset;
  1115. ppointer->flPointer |= MONO_POINTER_UP;
  1116. }
  1117. if (bUpdatePtr)
  1118. {
  1119. ppdev->pfnUpdateCursorPosition(ppdev, x, y);
  1120. }
  1121. }
  1122. }
  1123. /******************************Public*Routine******************************\
  1124. * VOID vDisablePointer
  1125. *
  1126. \**************************************************************************/
  1127. VOID vDisablePointer(
  1128. PDEV* ppdev)
  1129. {
  1130. // Nothing to do, really
  1131. }
  1132. /******************************Public*Routine******************************\
  1133. * VOID vAssertModePointer
  1134. *
  1135. \**************************************************************************/
  1136. VOID vAssertModePointer(
  1137. PDEV* ppdev,
  1138. BOOL bEnable)
  1139. {
  1140. if (!bEnable)
  1141. {
  1142. ppdev->pfnCursorOff(ppdev);
  1143. ppdev->ppointer->flPointer &= ~MONO_POINTER_UP;
  1144. }
  1145. else
  1146. {
  1147. flag_enable = FALSE; // force initial cursor enable
  1148. }
  1149. }
  1150. /******************************Public*Routine******************************\
  1151. * BOOL bEnablePointer
  1152. *
  1153. \**************************************************************************/
  1154. BOOL bEnablePointer(
  1155. PDEV* ppdev)
  1156. {
  1157. OH* poh;
  1158. ppdev->ppointer = &ppdev->pointer1;
  1159. ppdev->bAltPtrActive = FALSE;
  1160. // Allocate first buffer
  1161. poh = pohAllocate(ppdev, NULL,
  1162. ppdev->cxMemory,
  1163. (1024+(ppdev->lDelta-1))/ppdev->lDelta,
  1164. FLOH_MAKE_PERMANENT);
  1165. if (poh != NULL)
  1166. {
  1167. ppdev->ppointer->hwCursor.x = poh->x;
  1168. ppdev->ppointer->hwCursor.y = poh->y;
  1169. // Allocate second buffer
  1170. poh = pohAllocate(ppdev, NULL,
  1171. ppdev->cxMemory,
  1172. (1024+(ppdev->lDelta-1))/ppdev->lDelta,
  1173. FLOH_MAKE_PERMANENT);
  1174. if (poh != NULL)
  1175. {
  1176. ppdev->pointer2.hwCursor.x = poh->x;
  1177. ppdev->pointer2.hwCursor.y = poh->y;
  1178. if (ppdev->iMachType == MACH_MM_32 || ppdev->iMachType == MACH_IO_32)
  1179. {
  1180. ppdev->pfnSetCursorOffset = vI32SetCursorOffset;
  1181. ppdev->pfnUpdateCursorOffset = vI32UpdateCursorOffset;
  1182. ppdev->pfnUpdateCursorPosition = vI32UpdateCursorPosition;
  1183. ppdev->pfnCursorOff = vI32CursorOff;
  1184. ppdev->pfnCursorOn = vI32CursorOn;
  1185. // 24bpp on mach32 is only available with linear frame buffer.
  1186. // vI32PointerBlit can't handle 24bpp.
  1187. if (ppdev->iBitmapFormat == BMF_24BPP)
  1188. ppdev->pfnPointerBlit = vPointerBlitLFB;
  1189. else
  1190. ppdev->pfnPointerBlit = vI32PointerBlit;
  1191. }
  1192. else
  1193. {
  1194. if (ppdev->FeatureFlags & EVN_TVP_DAC_CUR)
  1195. {
  1196. /* TVP DAC Hardware Cursor is Buggy in Hardware */
  1197. ppdev->pfnSetCursorOffset = vM64SetCursorOffset_TVP;
  1198. ppdev->pfnUpdateCursorOffset = vM64UpdateCursorOffset_TVP;
  1199. ppdev->pfnUpdateCursorPosition = vM64UpdateCursorPosition_TVP;
  1200. ppdev->pfnCursorOff = vM64CursorOff_TVP;
  1201. ppdev->pfnCursorOn = vM64CursorOn_TVP;
  1202. ppdev->pfnPointerBlit = vM64PointerBlit_TVP;
  1203. }
  1204. else if (ppdev->FeatureFlags & EVN_IBM514_DAC_CUR)
  1205. {
  1206. /*
  1207. * On the DEC Alpha, the hardware cursor on the IBM 514
  1208. * DAC does not work properly.
  1209. */
  1210. #if defined(ALPHA)
  1211. ppdev->ppointer->flPointer |= NO_HARDWARE_CURSOR;
  1212. #endif
  1213. ppdev->pfnSetCursorOffset = vM64SetCursorOffset_IBM514;
  1214. ppdev->pfnUpdateCursorOffset = vM64UpdateCursorOffset_IBM514;
  1215. ppdev->pfnUpdateCursorPosition = vM64UpdateCursorPosition_IBM514;
  1216. ppdev->pfnCursorOff = vM64CursorOff_IBM514;
  1217. ppdev->pfnCursorOn = vM64CursorOn_IBM514;
  1218. ppdev->pfnPointerBlit = vM64PointerBlit_IBM514;
  1219. }
  1220. else if (ppdev->FeatureFlags & EVN_INT_DAC_CUR)
  1221. {
  1222. ppdev->pfnSetCursorOffset = vM64SetCursorOffset;
  1223. ppdev->pfnUpdateCursorOffset = vM64UpdateCursorOffset_CT;
  1224. ppdev->pfnUpdateCursorPosition = vM64UpdateCursorPosition;
  1225. ppdev->pfnCursorOff = vM64CursorOff_CT;
  1226. ppdev->pfnCursorOn = vM64CursorOn_CT;
  1227. ppdev->pfnPointerBlit = vM64PointerBlit;
  1228. }
  1229. else
  1230. {
  1231. ppdev->pfnSetCursorOffset = vM64SetCursorOffset;
  1232. ppdev->pfnUpdateCursorOffset = vM64UpdateCursorOffset;
  1233. ppdev->pfnUpdateCursorPosition = vM64UpdateCursorPosition;
  1234. ppdev->pfnCursorOff = vM64CursorOff;
  1235. ppdev->pfnCursorOn = vM64CursorOn;
  1236. ppdev->pfnPointerBlit = vM64PointerBlit;
  1237. }
  1238. }
  1239. if (ppdev->pModeInfo->ModeFlags & AMI_ODD_EVEN ||
  1240. ppdev->iAsic == ASIC_38800_1)
  1241. {
  1242. ppdev->ppointer->flPointer |= NO_HARDWARE_CURSOR;
  1243. }
  1244. return TRUE;
  1245. }
  1246. }
  1247. ppdev->ppointer->flPointer |= NO_HARDWARE_CURSOR;
  1248. return TRUE;
  1249. }