Leaked source code of windows server 2003
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.

486 lines
17 KiB

  1. /***************************************************************************\
  2. *
  3. * ************************
  4. * * MINIPORT SAMPLE CODE *
  5. * ************************
  6. *
  7. * Module Name:
  8. *
  9. * p3rd.h
  10. *
  11. * Abstract:
  12. *
  13. * This module contains the definitions for the 3Dlabs P3 RAMDAC
  14. *
  15. * Environment:
  16. *
  17. * Kernel mode
  18. *
  19. *
  20. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  21. * Copyright (c) 1995-2003 Microsoft Corporation. All Rights Reserved.
  22. *
  23. \***************************************************************************/
  24. //
  25. // RAMDAC registers live on 64 bit boundaries. Leave it up to individual
  26. // RAMDAC definitions to determine what registers are available and how
  27. // many bits wide the registers really are.
  28. //
  29. typedef struct {
  30. volatile ULONG reg;
  31. volatile ULONG pad;
  32. } RAMDAC_REG;
  33. //
  34. // structure with all the direct access registers
  35. //
  36. typedef struct _p3rd_regs {
  37. RAMDAC_REG RDPaletteWriteAddress;
  38. RAMDAC_REG RDPaletteData;
  39. RAMDAC_REG RDPixelMask;
  40. RAMDAC_REG RDPaletteAddressRead;
  41. RAMDAC_REG RDIndexLow;
  42. RAMDAC_REG RDIndexHigh;
  43. RAMDAC_REG RDIndexedData;
  44. RAMDAC_REG RDIndexControl;
  45. } P3RDRAMDAC;
  46. //
  47. // Use the following macros as the address to pass to the
  48. // VideoPortWriteRegisterUlong function
  49. //
  50. #define P3RD_PAL_WR_ADDR ((PULONG)&(pP3RDRegs->RDPaletteWriteAddress.reg))
  51. #define P3RD_PAL_RD_ADDR ((PULONG)&(pP3RDRegs->RDPaletteAddressRead.reg))
  52. #define P3RD_PAL_DATA ((PULONG)&(pP3RDRegs->RDPaletteData.reg))
  53. #define P3RD_PIXEL_MASK ((PULONG)&(pP3RDRegs->RDPixelMask.reg))
  54. #define P3RD_INDEX_ADDR_LO ((PULONG)&(pP3RDRegs->RDIndexLow.reg))
  55. #define P3RD_INDEX_ADDR_HI ((PULONG)&(pP3RDRegs->RDIndexHigh.reg))
  56. #define P3RD_INDEX_DATA ((PULONG)&(pP3RDRegs->RDIndexedData.reg))
  57. #define P3RD_INDEX_CONTROL ((PULONG)&(pP3RDRegs->RDIndexControl.reg))
  58. //
  59. // bit field definitions for the direct access registers
  60. //
  61. #define P3RD_IDX_CTL_AUTOINCREMENT_ENABLED 0x01
  62. //
  63. // Indexed register definitions accessed via P3RD_LOAD_INDEX_REG()
  64. // and P3RD_READ_INDEX_REG()
  65. //
  66. #define P3RD_MISC_CONTROL 0x0000
  67. #define P3RD_SYNC_CONTROL 0x0001
  68. #define P3RD_DAC_CONTROL 0x0002
  69. #define P3RD_PIXEL_SIZE 0x0003
  70. #define P3RD_COLOR_FORMAT 0x0004
  71. #define P3RD_CURSOR_MODE 0x0005
  72. #define P3RD_CURSOR_CONTROL 0x0006
  73. #define P3RD_CURSOR_X_LOW 0x0007
  74. #define P3RD_CURSOR_X_HIGH 0x0008
  75. #define P3RD_CURSOR_Y_LOW 0x0009
  76. #define P3RD_CURSOR_Y_HIGH 0x000a
  77. #define P3RD_CURSOR_HOTSPOT_X 0x000b
  78. #define P3RD_CURSOR_HOTSPOT_Y 0x000c
  79. #define P3RD_OVERLAY_KEY 0x000d
  80. #define P3RD_PAN 0x000e
  81. #define P3RD_SENSE 0x000f
  82. #define P3RD_CHECK_CONTROL 0x0018
  83. #define P3RD_CHECK_PIXEL_RED 0x0019
  84. #define P3RD_CHECK_PIXEL_GREEN 0x001a
  85. #define P3RD_CHECK_PIXEL_BLUE 0x001b
  86. #define P3RD_CHECK_LUT_RED 0x001c
  87. #define P3RD_CHECK_LUT_GREEN 0x001d
  88. #define P3RD_CHECK_LUT_BLUE 0x001e
  89. #define P3RD_SCRATCH 0x001f
  90. #define P3RD_VIDEO_OVERLAY_CONTROL 0x0020
  91. #define P3RD_VIDEO_OVERLAY_X_START_LOW 0x0021
  92. #define P3RD_VIDEO_OVERLAY_X_START_HIGH 0x0022
  93. #define P3RD_VIDEO_OVERLAY_Y_START_LOW 0x0023
  94. #define P3RD_VIDEO_OVERLAY_Y_START_HIGH 0x0024
  95. #define P3RD_VIDEO_OVERLAY_X_END_LOW 0x0025
  96. #define P3RD_VIDEO_OVERLAY_X_END_HIGH 0x0026
  97. #define P3RD_VIDEO_OVERLAY_Y_END_LOW 0x0027
  98. #define P3RD_VIDEO_OVERLAY_Y_END_HIGH 0x0028
  99. #define P3RD_VIDEO_OVERLAY_KEY_R 0x0029
  100. #define P3RD_VIDEO_OVERLAY_KEY_G 0x002A
  101. #define P3RD_VIDEO_OVERLAY_KEY_B 0x002B
  102. #define P3RD_VIDEO_OVERLAY_BLEND 0x002C
  103. #define P3RD_DCLK_SETUP_1 0x01f0
  104. #define P3RD_DCLK_SETUP_2 0x01f1
  105. #define P3RD_KCLK_SETUP_1 0x01f2
  106. #define P3RD_KCLK_SETUP_2 0x01f3
  107. #define P3RD_DCLK_CONTROL 0x0200
  108. #define P3RD_DCLK0_PRE_SCALE 0x0201
  109. #define P3RD_DCLK0_FEEDBACK_SCALE 0x0202
  110. #define P3RD_DCLK0_POST_SCALE 0x0203
  111. #define P3RD_DCLK1_PRE_SCALE 0x0204
  112. #define P3RD_DCLK1_FEEDBACK_SCALE 0x0205
  113. #define P3RD_DCLK1_POST_SCALE 0x0206
  114. #define P3RD_DCLK2_PRE_SCALE 0x0207
  115. #define P3RD_DCLK2_FEEDBACK_SCALE 0x0208
  116. #define P3RD_DCLK2_POST_SCALE 0x0209
  117. #define P3RD_DCLK3_PRE_SCALE 0x020a
  118. #define P3RD_DCLK3_FEEDBACK_SCALE 0x020b
  119. #define P3RD_DCLK3_POST_SCALE 0x020c
  120. #define P3RD_KCLK_CONTROL 0x020d
  121. #define P3RD_KCLK_PRE_SCALE 0x020e
  122. #define P3RD_KCLK_FEEDBACK_SCALE 0x020f
  123. #define P3RD_KCLK_POST_SCALE 0x0210
  124. #define P3RD_MCLK_CONTROL 0x0211
  125. #define P3RD_SCLK_CONTROL 0x0215
  126. #define P3RD_CURSOR_PALETTE_START 0x0303 // 303..32f
  127. #define P3RD_CURSOR_PATTERN_START 0x0400 // 400..7ff
  128. //
  129. // Defaults for the MCLK and KCLK clock source registers
  130. //
  131. #define P3RD_DEFAULT_MCLK_SRC P3RD_MCLK_CONTROL_KCLK
  132. #define P3RD_DEFAULT_SCLK_SRC P3RD_SCLK_CONTROL_KCLK
  133. //
  134. // Bit field definitions for the indexed registers
  135. //
  136. #define P3RD_MISC_CONTROL_STEREO_DBL_BUFFER_ENABLED 0x80
  137. #define P3RD_MISC_CONTROL_VSB_OUTPUT_ENABLED 0x40
  138. #define P3RD_MISC_CONTROL_PIXEL_DBL_BUFFER_ENABLED 0x20
  139. #define P3RD_MISC_CONTROL_OVERLAYS_ENABLED 0x10
  140. #define P3RD_MISC_CONTROL_DIRECT_COLOR_ENABLED 0x08
  141. #define P3RD_MISC_CONTROL_LAST_READ_ADDRESS_ENABLED 0x04
  142. #define P3RD_MISC_CONTROL_PIXEL_DOUBLE 0x02
  143. #define P3RD_MISC_CONTROL_HIGHCOLORRES 0x01
  144. #define P3RD_SYNC_CONTROL_VSYNC_ACTIVE_LOW 0x00
  145. #define P3RD_SYNC_CONTROL_VSYNC_ACTIVE_HIGH 0x08
  146. #define P3RD_SYNC_CONTROL_VSYNC_INACTIVE 0x20
  147. #define P3RD_SYNC_CONTROL_HSYNC_ACTIVE_LOW 0x00
  148. #define P3RD_SYNC_CONTROL_HSYNC_ACTIVE_HIGH 0x01
  149. #define P3RD_SYNC_CONTROL_HSYNC_INACTIVE 0x04
  150. #define P3RD_DAC_CONTROL_BLANK_PEDESTAL_ENABLED 0x80
  151. #define P3RD_PIXEL_SIZE_8BPP 0x00
  152. #define P3RD_PIXEL_SIZE_16BPP 0x01
  153. #define P3RD_PIXEL_SIZE_24_BPP 0x04
  154. #define P3RD_PIXEL_SIZE_32BPP 0x02
  155. #define P3RD_COLOR_FORMAT_CI8 0x0e
  156. #define P3RD_COLOR_FORMAT_8BPP 0x05
  157. #define P3RD_COLOR_FORMAT_15BPP 0x01
  158. #define P3RD_COLOR_FORMAT_16BPP 0x10
  159. #define P3RD_COLOR_FORMAT_32BPP 0x00
  160. #define P3RD_COLOR_FORMAT_LINEAR_EXT 0x40
  161. #define P3RD_COLOR_FORMAT_RGB 0x20
  162. #define P3RD_CURSOR_MODE_REVERSE 0x40
  163. #define P3RD_CURSOR_MODE_WINDOWS 0x00
  164. #define P3RD_CURSOR_MODE_X 0x10
  165. #define P3RD_CURSOR_MODE_3COLOR 0x20
  166. #define P3RD_CURSOR_MODE_15COLOR 0x30
  167. #define P3RD_CURSOR_MODE_64x64 0x00
  168. #define P3RD_CURSOR_MODE_P0_32x32x2 0x02
  169. #define P3RD_CURSOR_MODE_P1_32x32x2 0x04
  170. #define P3RD_CURSOR_MODE_P2_32x32x2 0x06
  171. #define P3RD_CURSOR_MODE_P3_32x32x2 0x08
  172. #define P3RD_CURSOR_MODE_P01_32x32x4 0x0a
  173. #define P3RD_CURSOR_MODE_P23_32x32x4 0x0c
  174. #define P3RD_CURSOR_MODE_ENABLED 0x01
  175. #define P3RD_CURSOR_CONTROL_RPOS_ENABLED 0x04
  176. #define P3RD_CURSOR_CONTROL_DOUBLE_Y 0x02
  177. #define P3RD_CURSOR_CONTROL_DOUBLE_X 0x01
  178. #define P3RD_DCLK_CONTROL_LOCKED 0x02 // read-only
  179. #define P3RD_DCLK_CONTROL_ENABLED 0x01
  180. #define P3RD_DCLK_CONTROL_RUN 0x08
  181. #define P3RD_KCLK_CONTROL_LOCKED 0x02 // read-only
  182. #define P3RD_KCLK_CONTROL_ENABLED 0x01
  183. #define P3RD_KCLK_CONTROL_RUN (0x2<<2)
  184. #define P3RD_KCLK_CONTROL_PCLK (0x0<<4)
  185. #define P3RD_KCLK_CONTROL_HALF_PCLK (0x1<<4)
  186. #define P3RD_KCLK_CONTROL_PLL (0x2<<4)
  187. #define P3RD_MCLK_CONTROL_ENABLED 0x01
  188. #define P3RD_MCLK_CONTROL_DRIVE_LOW (0x0<<2)
  189. #define P3RD_MCLK_CONTROL_DRIVE_HIGH (0x1<<2)
  190. #define P3RD_MCLK_CONTROL_RUN (0x2<<2)
  191. #define P3RD_MCLK_CONTROL_LOW_POWER (0x3<<2)
  192. #define P3RD_MCLK_CONTROL_HALF_PCLK (0x1<<4)
  193. #define P3RD_MCLK_CONTROL_PCLK (0x0<<4)
  194. #define P3RD_MCLK_CONTROL_HALF_EXTMCLK (0x3<<4)
  195. #define P3RD_MCLK_CONTROL_EXTMCLK (0x4<<4)
  196. #define P3RD_MCLK_CONTROL_HALF_KCLK (0x5<<4)
  197. #define P3RD_MCLK_CONTROL_KCLK (0x6<<4)
  198. #define P3RD_SCLK_CONTROL_ENABLED 0x01
  199. #define P3RD_SCLK_CONTROL_DRIVE_LOW (0x0<<2)
  200. #define P3RD_SCLK_CONTROL_DRIVE_HIGH (0x1<<2)
  201. #define P3RD_SCLK_CONTROL_RUN (0x2<<2)
  202. #define P3RD_SCLK_CONTROL_LOW_POWER (0x3<<2)
  203. #define P3RD_SCLK_CONTROL_HALF_PCLK (0x1<<4)
  204. #define P3RD_SCLK_CONTROL_PCLK (0x0<<4)
  205. #define P3RD_SCLK_CONTROL_HALF_EXTSCLK (0x3<<4)
  206. #define P3RD_SCLK_CONTROL_EXTSCLK (0x4<<4)
  207. #define P3RD_SCLK_CONTROL_HALF_KCLK (0x5<<4)
  208. #define P3RD_SCLK_CONTROL_KCLK (0x6<<4)
  209. #define P3RD_CURSOR_PALETTE_CURSOR_RGB(RGBIndex, Red, Green, Blue) \
  210. { \
  211. P3RD_LOAD_INDEX_REG(P3RD_CURSOR_PALETTE_START+3*(int)RGBIndex+0, Red); \
  212. P3RD_LOAD_INDEX_REG(P3RD_CURSOR_PALETTE_START+3*(int)RGBIndex+1, Green); \
  213. P3RD_LOAD_INDEX_REG(P3RD_CURSOR_PALETTE_START+3*(int)RGBIndex+2, Blue); \
  214. }
  215. #if 0
  216. //
  217. // Need a delay between each write to the P3RD. The only way to guarantee
  218. // that the write has completed is to read from a Permedia 3 control register.
  219. // Reading forces any posted writes to be flushed out. PPC needs 2 reads
  220. // to give us enough time.
  221. //
  222. #define P3RD_DELAY \
  223. { \
  224. volatile LONG __junk; \
  225. __junk = VideoPortReadRegisterUlong (FB_MODE_SEL); \
  226. __junk = VideoPortReadRegisterUlong (FB_MODE_SEL); \
  227. }
  228. #else
  229. #define P3RD_DELAY
  230. #endif
  231. //
  232. // Macro to load a given data value into an internal P3RD register. The
  233. // second macro loads an internal index register assuming that we have
  234. // already zeroed the high address register.
  235. //
  236. #define P3RD_INDEX_REG(index) \
  237. { \
  238. /*VideoDebugPrint((0, "*(0x%x) <-- 0x%x\n", P3RD_INDEX_ADDR_LO, (index) & 0xff)); */\
  239. VideoPortWriteRegisterUlong(P3RD_INDEX_ADDR_LO, (ULONG)((index) & 0xff)); \
  240. P3RD_DELAY; \
  241. /*VideoDebugPrint((0, "*(0x%x) <-- 0x%x\n", P3RD_INDEX_ADDR_HI, (index) >> 8)); */\
  242. VideoPortWriteRegisterUlong(P3RD_INDEX_ADDR_HI, (ULONG)((index) >> 8)); \
  243. P3RD_DELAY; \
  244. }
  245. #define P3RD_LOAD_DATA(data) \
  246. { \
  247. VideoPortWriteRegisterUlong(P3RD_INDEX_DATA, (ULONG)((data) & 0xff)); \
  248. P3RD_DELAY; \
  249. }
  250. #define P3RD_LOAD_INDEX_REG(index, data) \
  251. { \
  252. P3RD_INDEX_REG(index); \
  253. /*VideoDebugPrint((0, "*(0x%x) <-- 0x%x\n", P3RD_INDEX_DATA, (data) & 0xff)); */\
  254. VideoPortWriteRegisterUlong(P3RD_INDEX_DATA, (ULONG)((data) & 0xff)); \
  255. P3RD_DELAY; \
  256. }
  257. #define P3RD_READ_INDEX_REG(index, data) \
  258. { \
  259. P3RD_INDEX_REG(index); \
  260. data = VideoPortReadRegisterUlong(P3RD_INDEX_DATA) & 0xff; \
  261. P3RD_DELAY; \
  262. /*VideoDebugPrint((0, "0x%x <-- *(0x%x)\n", data, P3RD_INDEX_DATA));*/ \
  263. }
  264. #define P3RD_LOAD_INDEX_REG_LO(index, data) \
  265. { \
  266. VideoPortWriteRegisterUlong(P3RD_INDEX_ADDR_LO, (ULONG)(index)); \
  267. P3RD_DELAY; \
  268. VideoPortWriteRegisterUlong(P3RD_INDEX_DATA, (ULONG)(data)); \
  269. P3RD_DELAY; \
  270. }
  271. //
  272. // Macros to load a given RGB triple into the P3RD palette. Send the starting
  273. // index and then send RGB triples. Auto-increment is turned on.
  274. // Use P3RD_PALETTE_START and multiple P3RD_LOAD_PALETTE calls to load
  275. // a contiguous set of entries. Use P3RD_LOAD_PALETTE_INDEX to load a set
  276. // of sparse entries.
  277. //
  278. #define P3RD_PALETTE_START_WR(index) \
  279. { \
  280. VideoPortWriteRegisterUlong(P3RD_PAL_WR_ADDR, (ULONG)(index)); \
  281. P3RD_DELAY; \
  282. }
  283. #define P3RD_PALETTE_START_RD(index) \
  284. { \
  285. VideoPortWriteRegisterUlong(P3RD_PAL_RD_ADDR, (ULONG)(index)); \
  286. P3RD_DELAY; \
  287. }
  288. #define P3RD_LOAD_PALETTE(red, green, blue) \
  289. { \
  290. VideoPortWriteRegisterUlong(P3RD_PAL_DATA, (ULONG)(red)); \
  291. P3RD_DELAY; \
  292. VideoPortWriteRegisterUlong(P3RD_PAL_DATA, (ULONG)(green)); \
  293. P3RD_DELAY; \
  294. VideoPortWriteRegisterUlong(P3RD_PAL_DATA, (ULONG)(blue)); \
  295. P3RD_DELAY; \
  296. }
  297. #define P3RD_LOAD_PALETTE_INDEX(index, red, green, blue) \
  298. { \
  299. VideoPortWriteRegisterUlong(P3RD_PAL_WR_ADDR, (ULONG)(index)); \
  300. P3RD_DELAY; \
  301. VideoPortWriteRegisterUlong(P3RD_PAL_DATA, (ULONG)(red)); \
  302. P3RD_DELAY; \
  303. VideoPortWriteRegisterUlong(P3RD_PAL_DATA, (ULONG)(green)); \
  304. P3RD_DELAY; \
  305. VideoPortWriteRegisterUlong(P3RD_PAL_DATA, (ULONG)(blue)); \
  306. P3RD_DELAY; \
  307. }
  308. //
  309. // Macro to read back a given RGB triple from the P3RD palette. Use after
  310. // a call to P3RD_PALETTE_START_RD
  311. //
  312. #define P3RD_READ_PALETTE(red, green, blue) \
  313. { \
  314. red = (UCHAR)(VideoPortReadRegisterUlong(P3RD_PAL_DATA) & 0xff); \
  315. P3RD_DELAY; \
  316. green = (UCHAR)(VideoPortReadRegisterUlong(P3RD_PAL_DATA) & 0xff); \
  317. P3RD_DELAY; \
  318. blue = (UCHAR)(VideoPortReadRegisterUlong(P3RD_PAL_DATA) & 0xff); \
  319. P3RD_DELAY; \
  320. }
  321. //
  322. // Macros to set/get the pixel read mask. The mask is 8 bits wide and gets
  323. // replicated across all bytes that make up a pixel.
  324. //
  325. #define P3RD_SET_PIXEL_READMASK(mask) \
  326. { \
  327. VideoPortWriteRegisterUlong(P3RD_PIXEL_MASK, (ULONG)(mask)); \
  328. P3RD_DELAY; \
  329. }
  330. #define P3RD_READ_PIXEL_READMASK(mask) \
  331. { \
  332. mask = VideoPortReadRegisterUlong(P3RD_PIXEL_MASK) & 0xff; \
  333. }
  334. //
  335. // Macros to load values into the cursor array usage is
  336. // P3RD_CURSOR_ARRAR_START() followed by n iterations of
  337. // P3RD_LOAD_CURSOR_ARRAY() or P3RD_READ_CURSOR_ARRAY()
  338. //
  339. #define P3RD_CURSOR_ARRAY_START(offset) \
  340. { \
  341. P3RD_DELAY; \
  342. VideoPortWriteRegisterUlong(P3RD_INDEX_ADDR_LO, (ULONG)(((offset)+P3RD_CURSOR_PATTERN_START) & 0xff)); \
  343. P3RD_DELAY; \
  344. VideoPortWriteRegisterUlong(P3RD_INDEX_ADDR_HI, (ULONG)(((offset)+P3RD_CURSOR_PATTERN_START) >> 8)); \
  345. P3RD_DELAY; \
  346. }
  347. #define P3RD_LOAD_CURSOR_ARRAY(data) \
  348. { \
  349. VideoPortWriteRegisterUlong(P3RD_INDEX_DATA, (ULONG)(data)); \
  350. P3RD_DELAY; \
  351. }
  352. #define P3RD_READ_CURSOR_ARRAY(data) \
  353. { \
  354. data = VideoPortReadRegisterUlong(P3RD_INDEX_DATA) & 0xff; \
  355. P3RD_DELAY; \
  356. }
  357. #define P3RD_SET_CURSOR_MODE(data) \
  358. { \
  359. VideoPortWriteRegisterUlong(P3RD_INDEX_ADDR_LO, (ULONG)((P3RD_CURSOR_MODE) & 0xff)); \
  360. VideoPortWriteRegisterUlong(P3RD_INDEX_ADDR_HI, (ULONG)((P3RD_CURSOR_MODE) >> 8)); \
  361. VideoPortWriteRegisterUlong(P3RD_INDEX_DATA, (ULONG)((data) & 0xff)); \
  362. }
  363. //
  364. // Macro to move the cursor
  365. //
  366. #define P3RD_MOVE_CURSOR(x, y) \
  367. { \
  368. VideoPortWriteRegisterUlong(P3RD_INDEX_ADDR_HI, (ULONG)0); \
  369. P3RD_DELAY; \
  370. P3RD_LOAD_INDEX_REG_LO(P3RD_CURSOR_X_LOW, (ULONG)((x) & 0xff)); \
  371. P3RD_LOAD_INDEX_REG_LO(P3RD_CURSOR_X_HIGH, (ULONG)((x) >> 8)); \
  372. P3RD_LOAD_INDEX_REG_LO(P3RD_CURSOR_Y_LOW, (ULONG)((y) & 0xff)); \
  373. P3RD_LOAD_INDEX_REG_LO(P3RD_CURSOR_Y_HIGH, (ULONG)((y) >> 8)); \
  374. }
  375. //
  376. // Macro to change the cursor hotspot
  377. //
  378. #define P3RD_CURSOR_HOTSPOT(x, y) \
  379. { \
  380. VideoPortWriteRegisterUlong(P3RD_INDEX_ADDR_HI, (ULONG)(0)); \
  381. P3RD_DELAY; \
  382. P3RD_LOAD_INDEX_REG_LO(P3RD_CURSOR_HOTSPOT_X, (ULONG)(x)); \
  383. P3RD_LOAD_INDEX_REG_LO(P3RD_CURSOR_HOTSPOT_Y, (ULONG)(y)); \
  384. }
  385. //
  386. // Macro to change the cursor color
  387. //
  388. #define P3RD_CURSOR_COLOR(red, green, blue) \
  389. { \
  390. VideoPortWriteRegisterUlong(P3RD_INDEX_ADDR_HI, (ULONG)(0)); \
  391. P3RD_DELAY; \
  392. P3RD_LOAD_INDEX_REG_LO(P3RD_CURSOR_HOTSPOT_X, (ULONG)(x)); \
  393. P3RD_LOAD_INDEX_REG_LO(P3RD_CURSOR_HOTSPOT_Y, (ULONG)(y)); \
  394. }
  395. //
  396. // Warning the Perm3 has an upside down cursor LUT, which means that
  397. // items read from LUT entry 0 are actually read from entry 14.
  398. // Therefore we have some macros to calculate the right value.
  399. //
  400. #define P3RD_REVERSE_LUT_INDEX 1
  401. #if P3RD_REVERSE_LUT_INDEX
  402. #define P3RD_CALCULATE_LUT_INDEX(x) (14 - x)
  403. #else
  404. #define P3RD_CALCULATE_LUT_INDEX(x) (x)
  405. #endif
  406. //
  407. // Check to see whether byte doubling is required. If, at 8BPP, any of the
  408. // VESA horizontal parameters have the bottom bit set then we need to put
  409. // the chip into 64-bit, byte-doubling mode.
  410. //
  411. #define P3RD_CHECK_8BPP_NEED64BITDAC(VESATmgs)((BOOLEAN)((GetHtotFromVESA(VESATmgs) | \
  412. GetHssFromVESA(VESATmgs) | \
  413. GetHseFromVESA(VESATmgs) | \
  414. GetHbeFromVESA(VESATmgs) ) & 0x1))
  415. //
  416. // Check whether the current mode needs to be pixel doubled (i.e are we at
  417. // 8BPP andwe fufill the above criteria.
  418. //
  419. #define P3RD_CHECK_BYTE_DOUBLING(hwDeviceExtension,pixelDepth,VESATmgs) \
  420. (pixelDepth <= 8 && \
  421. P3RD_CHECK_8BPP_NEED64BITDAC(&VESATimings))