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.

1534 lines
60 KiB

  1. /******************************Module*Header*******************************\
  2. *
  3. * *******************
  4. * * GDI SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: hw.h
  8. *
  9. * All the hardware specific driver file stuff. Parts are mirrored in
  10. * 'hw.inc'.
  11. *
  12. * Copyright (c) 1992-1998 Microsoft Corporation
  13. *
  14. \**************************************************************************/
  15. ////////////////////////////////////////////////////////////////////////
  16. // Chip equates:
  17. #define STATUS_1 0x03DA
  18. #define DISPLAY_MODE_INACTIVE 0x001
  19. #define VBLANK_ACTIVE 0x008
  20. #define CRTC_INDEX 0x03D4
  21. #define CRTC_DATA 0x03D5
  22. #define S3R8 0x038
  23. #define S3R9 0x039
  24. #define S3R1 0x031
  25. #define S3R5 0x035
  26. #define CR39 0x039
  27. #define CR4C 0x04C
  28. #define CR4D 0x04D
  29. #define HGC_MODE 0x045
  30. #define HGC_ENABLE 0x001
  31. #define HGC_DISABLE 0x000
  32. #define HGC_ORGX_LSB 0x047
  33. #define HGC_ORGX_MSB 0x046
  34. #define HGC_ORGY_LSB 0x049
  35. #define HGC_ORGY_MSB 0x048
  36. #define HGC_DX 0x04E
  37. #define HGC_DY 0x04F
  38. #define REG_UNLOCK_1 0x048
  39. #define CPUA_BASE 0x001
  40. #define SYSCTL_UNLOCK 0x0A0
  41. #define SYSCTL_LOCK 0x000
  42. #define SYS_CNFG 0x040
  43. #define LAW_CTL 0x058
  44. #define EX_SCTL_2 0x051
  45. #define EX_DAC_CT 0x055
  46. #define MISC_1 0x03A
  47. ///////////////////////////////////////////////////////////////////////
  48. // Brooktree 485 stuff:
  49. #define BT485_ADDR_CMD_REG0 0x03c6
  50. #define BT485_ADDR_CMD_REG1 0x03c8
  51. #define BT485_ADDR_CMD_REG2 0x03c9
  52. #define BT485_ADDR_CMD_REG3 0x03c6
  53. #define BT485_CMD_REG_3_ACCESS 0x080
  54. #define BT485_ADDR_CUR_COLOR_WRITE 0x03c8
  55. #define BT485_CUR_COLOR_DATA 0x03c9
  56. #define BT485_ADDR_CUR_RAM_WRITE 0x03c8
  57. #define BT485_CUR_RAM_ARRAY_DATA 0x03c7
  58. #define BT485_CURSOR_COLOR_1 0x01
  59. #define BT485_CURSOR_COLOR_2 0x02
  60. #define BT485_CURSOR_X_LOW 0x03c8
  61. #define BT485_CURSOR_X_HIGH 0x03c9
  62. #define BT485_CURSOR_Y_LOW 0x03c6
  63. #define BT485_CURSOR_Y_HIGH 0x03c7
  64. #define BT485_CURSOR_DISABLE (~0x03)
  65. #define BT485_CURSOR_MODE2 0x02
  66. #define BT485_64X64_CURSOR 0x04
  67. // Command types:
  68. #define DRAW_LINE 0x02000
  69. #define RECTANGLE_FILL 0x04000
  70. #define POLYGON_SOLID 0x06000
  71. #define FOUR_POINT_TRAPEZOID_SOLID 0x08000
  72. #define BRESENHAM_TRAPEZOID_SOLID 0x0A000
  73. #define BITBLT 0x0C000
  74. #define PATTERN_FILL 0x0E000
  75. #define POLYLINE 0x02800
  76. #define POLYGON_PATTERN 0x06800
  77. #define FOUR_POINT_TRAPEZOID_PATTERN 0x08800
  78. #define BRESENHAM_TRAPEZOID_PATTERN 0x0A800
  79. #define ROPBLT 0x0C800
  80. #define BYTE_SWAP 0x01000
  81. #define BUS_SIZE_NEW_32 0x00600
  82. #define BUS_SIZE_32 0x00400
  83. #define BUS_SIZE_16 0x00200
  84. #define BUS_SIZE_8 0x00000
  85. #define WAIT 0x00100
  86. // Drawing directions (radial):
  87. #define DRAWING_DIRECTION_0 0x0000
  88. #define DRAWING_DIRECTION_45 0x0020
  89. #define DRAWING_DIRECTION_90 0x0040
  90. #define DRAWING_DIRECTION_135 0x0060
  91. #define DRAWING_DIRECTION_180 0x0080
  92. #define DRAWING_DIRECTION_225 0x00A0
  93. #define DRAWING_DIRECTION_270 0x00C0
  94. #define DRAWING_DIRECTION_315 0x00E0
  95. // Drawing directions (x/y):
  96. #define DRAWING_DIR_BTRLXM 0x0000
  97. #define DRAWING_DIR_BTLRXM 0x0020
  98. #define DRAWING_DIR_BTRLYM 0x0040
  99. #define DRAWING_DIR_BTLRYM 0x0060
  100. #define DRAWING_DIR_TBRLXM 0x0080
  101. #define DRAWING_DIR_TBLRXM 0x00A0
  102. #define DRAWING_DIR_TBRLYM 0x00C0
  103. #define DRAWING_DIR_TBLRYM 0x00E0
  104. // Drawing direction bits:
  105. #define PLUS_X 0x0020
  106. #define PLUS_Y 0x0080
  107. #define MAJOR_Y 0x0040
  108. // Draw:
  109. #define DRAW 0x0010
  110. // Direction type:
  111. #define DIR_TYPE_RADIAL 0x0008
  112. #define DIR_TYPE_XY 0x0000
  113. // Last pixel:
  114. #define LAST_PIXEL_OFF 0x0004
  115. #define LAST_PIXEL_ON 0x0000
  116. // Pixel mode:
  117. #define MULTIPLE_PIXELS 0x0002
  118. #define SINGLE_PIXEL 0x0000
  119. // Read/write:
  120. #define READ 0x0000
  121. #define WRITE 0x0001
  122. // Graphics processor status:
  123. #define HARDWARE_BUSY 0x0200
  124. #define READ_DATA_AVAILABLE 0x0100
  125. #define GP_ALL_EMPTY 0x0400
  126. // S3 chips that support MM I/O and ALL_EMPTY have 16 FIFO slots:
  127. #define MM_ALL_EMPTY_FIFO_COUNT 16
  128. #define IO_ALL_EMPTY_FIFO_COUNT 8
  129. #define MULT_MISC_COLOR_COMPARE 0x0100
  130. // Fifo status in terms of empty entries:
  131. #define FIFO_1_EMPTY 0x080
  132. #define FIFO_2_EMPTY 0x040
  133. #define FIFO_3_EMPTY 0x020
  134. #define FIFO_4_EMPTY 0x010
  135. #define FIFO_5_EMPTY 0x008
  136. #define FIFO_6_EMPTY 0x004
  137. #define FIFO_7_EMPTY 0x002
  138. #define FIFO_8_EMPTY 0x001
  139. // These are the defines for the multifunction control register.
  140. // The 4 MSBs define the function of the register.
  141. #define RECT_HEIGHT 0x00000
  142. #define CLIP_TOP 0x01000
  143. #define CLIP_LEFT 0x02000
  144. #define CLIP_BOTTOM 0x03000
  145. #define CLIP_RIGHT 0x04000
  146. #define DATA_EXTENSION 0x0A000
  147. #define MULT_MISC_INDEX 0x0E000
  148. #define READ_SEL_INDEX 0x0F000
  149. #define ALL_ONES 0x00000
  150. #define CPU_DATA 0x00080
  151. #define DISPLAY_MEMORY 0x000C0
  152. // Colour source:
  153. #define BACKGROUND_COLOR 0x000
  154. #define FOREGROUND_COLOR 0x020
  155. #define SRC_CPU_DATA 0x040
  156. #define SRC_DISPLAY_MEMORY 0x060
  157. // Mix modes:
  158. #define NOT_SCREEN 0x00
  159. #define LOGICAL_0 0x01
  160. #define LOGICAL_1 0x02
  161. #define LEAVE_ALONE 0x03
  162. #define NOT_NEW 0x04
  163. #define SCREEN_XOR_NEW 0x05
  164. #define NOT_SCREEN_XOR_NEW 0x06
  165. #define OVERPAINT 0x07
  166. #define NOT_SCREEN_OR_NOT_NEW 0x08
  167. #define SCREEN_OR_NOT_NEW 0x09
  168. #define NOT_SCREEN_OR_NEW 0x0A
  169. #define SCREEN_OR_NEW 0x0B
  170. #define SCREEN_AND_NEW 0x0C
  171. #define NOT_SCREEN_AND_NEW 0x0D
  172. #define SCREEN_AND_NOT_NEW 0x0E
  173. #define NOT_SCREEN_AND_NOT_NEW 0x0F
  174. ////////////////////////////////////////////////////////////////////
  175. // S3 port control
  176. ////////////////////////////////////////////////////////////////////
  177. // Accelerator port addresses:
  178. #define CUR_Y 0x082E8
  179. #define CUR_X 0x086E8
  180. #define DEST_Y 0x08AE8
  181. #define DEST_X 0x08EE8
  182. #define AXSTP 0x08AE8
  183. #define DIASTP 0x08EE8
  184. #define ERR_TERM 0x092E8
  185. #define MAJ_AXIS_PCNT 0x096E8
  186. #define CMD 0x09AE8
  187. #define SHORT_STROKE 0x09EE8
  188. #define BKGD_COLOR 0x0A2E8
  189. #define FRGD_COLOR 0x0A6E8
  190. #define WRT_MASK 0x0AAE8
  191. #define RD_MASK 0x0AEE8
  192. #define COLOR_CMP 0x0B2E8
  193. #define BKGD_MIX 0x0B6E8
  194. #define FRGD_MIX 0x0BAE8
  195. #define MULTIFUNC_CNTL 0x0BEE8
  196. #define MIN_AXIS_PCNT 0x0BEE8
  197. #define SCISSORS 0x0BEE8
  198. #define PIX_CNTL 0x0BEE8
  199. #define PIX_TRANS 0x0E2E8
  200. // Packed addresses, for Trio64 or newer:
  201. #define ALT_CURXY 0x08100
  202. #define ALT_CURXY2 0x08104
  203. #define ALT_STEP 0x08108
  204. #define ALT_STEP2 0x0810C
  205. #define ALT_ERR 0x08110
  206. #define ALT_CMD 0x08118
  207. #define ALT_MIX 0x08134
  208. #define ALT_PCNT 0x08148
  209. #define ALT_PAT 0x08168
  210. #define SCISSORS_T 0x08138
  211. #define SCISSORS_L 0x0813A
  212. #define SCISSORS_B 0x0813C
  213. #define SCISSORS_R 0x0813E
  214. #define MULT_MISC_READ_SEL 0x08144
  215. ////////////////////////////////////////////////////////////////////
  216. // S3 streams processor
  217. ////////////////////////////////////////////////////////////////////
  218. // Stream processor register definitions
  219. #define P_CONTROL 0x8180 // Primary Stream Control register
  220. #define CKEY_LOW 0x8184 // Color/Chroma Key Control
  221. #define S_CONTROL 0x8190 // Secondary Stream Control
  222. #define CKEY_HI 0x8194 // Chroma Key Upper Bound
  223. #define S_HK1K2 0x8198 // Secondary Stream Stretch/Filter const
  224. #define BLEND_CONTROL 0x81a0 // Blend Control
  225. #define P_0 0x81c0 // Primary Stream Frame Buffer Address 0
  226. #define P_1 0x81c4 // Primary Stream Frame Buffer Address 1
  227. #define P_STRIDE 0x81c8 // Primary Stream Stride
  228. #define LPB_DB 0x81cc // Double buffer and LPB Support
  229. #define S_0 0x81d0 // Secondary Stream Frame Buffer Addr 0
  230. #define S_1 0x81d4 // Secondary Stream Frame Buffer Addr 1
  231. #define S_STRIDE 0x81d8 // Secondary Stream Stride
  232. #define OPAQUE_CONTROL 0x81dc // Opaque Overlay Control
  233. #define S_VK1 0x81e0 // K1 Vertical Scale Factor
  234. #define S_VK2 0x81e4 // K2 Vertical Scale Factor
  235. #define S_VDDA 0x81e8 // DDA Vertical Accumulator Init Value
  236. #define FIFO_CONTROL 0x81ec // Stream FIFO and RAS Controls
  237. #define P_XY 0x81f0 // Primary Stream Window Start Coord
  238. #define P_WH 0x81f4 // Primary Stream Window Size
  239. #define S_XY 0x81f8 // Secondary Stream Window Start Coord
  240. #define S_WH 0x81fc // Secondary Stream Window Size
  241. #define P_Format_Shift 24
  242. #define P_Format_Mask (7L << P_Format_Shift)
  243. #define P_RGB8 (0L << P_Format_Shift)
  244. #define P_RGB15 (3L << P_Format_Shift)
  245. #define P_RGB16 (5L << P_Format_Shift)
  246. #define P_RGB24 (6L << P_Format_Shift)
  247. #define P_RGB32 (7L << P_Format_Shift)
  248. #define P_Filter_Shift 28
  249. #define P_Filter_Mask (7L << P_Filter_Shift)
  250. #define P_1x (0L << P_Filter_Shift)
  251. #define P_2x (1L << P_Filter_Shift)
  252. #define P_2xBiLinear (2L << P_Filter_Shift)
  253. #define BVCr_Shift 0
  254. #define BVCr_Mask (255L << BVCr_Shift)
  255. #define GUCb_Shift 8
  256. #define GUCb_Mask (255L << GUCb_Shift)
  257. #define RY_Shift 16
  258. #define RY_Mask (255L << RY_Shift)
  259. #define Compare_Shift 24
  260. #define Compare_Mask (255L << Compare_Shift)
  261. #define CompareBits7 (0L << Compare_Shift)
  262. #define CompareBits6t7 (1L << Compare_Shift)
  263. #define CompareBits5t7 (2L << Compare_Shift)
  264. #define CompareBits4t7 (3L << Compare_Shift)
  265. #define CompareBits3t7 (4L << Compare_Shift)
  266. #define CompareBits2t7 (5L << Compare_Shift)
  267. #define CompareBits1t7 (6L << Compare_Shift)
  268. #define CompareBits0t7 (7L << Compare_Shift)
  269. #define KeyFrom_Shift 28
  270. #define KeyFrom_Mask (1L << KeyFrom_Shift)
  271. #define KeyFromStream (0L << KeyFrom_Shift)
  272. #define KeyFromCompare (1L << KeyFrom_Shift)
  273. #define HDDA_Shift 0
  274. #define HDDA_Mask (((1L << 12)-1) << HDDA_Shift)
  275. #define S_Format_Shift 24
  276. #define S_Format_Mask (7L << S_Format_Shift)
  277. #define S_YCrCb422 (1L << S_Format_Shift)
  278. #define S_YUV422 (2L << S_Format_Shift)
  279. #define S_RGB15 (3L << S_Format_Shift)
  280. #define S_YUV211 (4L << S_Format_Shift)
  281. #define S_RGB16 (5L << S_Format_Shift)
  282. #define S_RGB24 (6L << S_Format_Shift)
  283. #define S_RGB32 (7L << S_Format_Shift)
  284. #define S_Filter_Shift 28
  285. #define S_Filter_Mask (7L << S_Filter_Shift)
  286. #define S_1x (0L << S_Filter_Shift)
  287. #define S_Upto2x (1L << S_Filter_Shift)
  288. #define S_2xTo4x (2L << S_Filter_Shift)
  289. #define S_Beyond4x (3L << S_Filter_Shift)
  290. #define HighVCr_Shift 0
  291. #define HighVCr_Mask (255L << HighVCr_Shift)
  292. #define HighUCb_Shift 8
  293. #define HighUCb_Mask (255L << HighUCb_Shift)
  294. #define HighY_Shift 16
  295. #define HighY_Mask (255L << HighY_Shift)
  296. #define HK1_Shift 0
  297. #define HK1_Mask (((1L << 11) - 1) << HK1_Shift)
  298. #define HK2_Shift 16
  299. #define HK2_Mask (((1L << 11) - 1) << HK2_Shift)
  300. #define VK1_Shift 0
  301. #define VK1_Mask (((1L << 11) - 1) << VK1_Shift)
  302. #define VK2_Shift 0
  303. #define VK2_Mask (((1L << 11) - 1) << VK2_Shift)
  304. #define VDDA_Shift 0
  305. #define VDDA_Mask (((1L << 12) - 1) << VDDA_Shift)
  306. #define Ks_Shift 2
  307. #define Ks_Mask (7L << Ks_Shift)
  308. #define Kp_Shift 10
  309. #define Kp_Mask (7L << Kp_Shift)
  310. #define Compose_Shift 24
  311. #define Compose_Mask (7L << Compose_Shift)
  312. #define SOnP (0L << Compose_Shift)
  313. #define POnS (1L << Compose_Shift)
  314. #define Dissolve (2L << Compose_Shift)
  315. #define Fade (3L << Compose_Shift)
  316. #define KeyOnP (5L << Compose_Shift)
  317. #define KeyOnS (6L << Compose_Shift)
  318. #define FifoAlloc_Shift 0
  319. #define FifoAlloc_Mask (31L << StrFifoAlloc_Shift)
  320. #define FifoAlloc24_0 (0L << StrFifoAlloc_Shift)
  321. #define FifoAlloc16_8 (8L << StrFifoAlloc_Shift)
  322. #define FifoAlloc12_12 (12L << StrFifoAlloc_Shift)
  323. #define FifoAlloc8_16 (16L << StrFifoAlloc_Shift)
  324. #define FifoAlloc0_24 (24L << StrFifoAlloc_Shift)
  325. #define S_FifoThresh_Shift 5
  326. #define S_FifoThresh_Mask (31L << S_FifoThresh_Shift)
  327. #define P_FifoThresh_Shift 10
  328. #define P_FifoThresh_Mask (31L << P_FifoThresh_Shift)
  329. #define RASLowTime_Shift 15
  330. #define RASLowTime_Mask (1L << RASLowTime_Shift)
  331. #define RASLowTimeFromCR68 (0L << RASLowTime_Shift)
  332. #define RASLowTime2_5 (1L << RASLowTime_Shift)
  333. #define RASPreCharge_Shift 16
  334. #define RASPreCharge_Mask (1L << RASPreCharge_Shift)
  335. #define RASPreChargeFromCR68 (0L << RASPreCharge_Shift)
  336. #define RASPreCharge1_5 (1L << RASPreCharge_Shift)
  337. #define RASInactive_Shift 17
  338. #define RASInactive_Mask (1L << RASInactive_Shift)
  339. #define RASInactiveLow (0L << RASInactive_Shift)
  340. #define RASInactiveHigh (1L << RASInactive_Shift)
  341. #define MemoryCycle_Shift 18
  342. #define MemoryCycle_Mask (1L << MemoryCycle_Shift)
  343. #define MemoryCycle2 (0L << MemoryCycle_Shift)
  344. #define MemoryCycle1 (1L << MemoryCycle_Shift)
  345. #define H_Shift 0
  346. #define H_Mask (0x07ffL << H_Shift)
  347. #define W_Shift 16
  348. #define W_Mask (0x07ffL << W_Shift)
  349. #define Y_Shift 0
  350. #define Y_Mask (0x07ffL << Y_Shift)
  351. #define X_Shift 16
  352. #define X_Mask (0x07ffL << X_Shift)
  353. #define P_Select_Shift 0
  354. #define P_Select_Mask (1L << P_Select_Shift)
  355. #define P_Select0 (0L << P_Select_Shift)
  356. #define P_Select1 (1L << P_Select_Shift)
  357. #define S_Select_Shift 1
  358. #define S_Select_Mask (3L << S_Select_Shift)
  359. #define S_Select0 (0L << S_Select_Shift)
  360. #define S_Select1 (1L << S_Select_Shift)
  361. #define S_Select00Or11 (2L << S_Select_Shift)
  362. #define S_Select01Or10 (3L << S_Select_Shift)
  363. #define L_Select_Shift 4
  364. #define L_Select_Mask (1L << L_Select_Shift)
  365. #define L_Select0 (0L << L_Select_Shift)
  366. #define L_Select1 (1L << L_Select_Shift)
  367. #define L_SelWait_Shift 5
  368. #define L_SelWait_Mask (1L << L_SelWait_Shift)
  369. #define L_SelWaitNo (0L << L_SelWait_Shift)
  370. #define L_SelWaitYes (1L << L_SelWait_Shift)
  371. #define L_SelAutoToggle_Shift 6
  372. #define L_SelAutoToggle_Mask (1L << L_SelAutoToggle_Shift)
  373. #define L_SelAutoToggleNo (0L << L_SelAutoToggle_Shift)
  374. #define L_SelAutoToggleYes (1L << L_SelAutoToggle_Shift)
  375. #define L_FramesToDrop_Shift 8
  376. #define L_FramesToDrop_Mask (3L << L_FramesToDrop_Shift)
  377. #define OpqStart_Shift 3
  378. #define OpqStart_Mask (((1L << 10) - 1) << OpqStart_Shift)
  379. #define OpqEnd_Shift 19
  380. #define OpqEnd_Mask (((1L << 10) - 1) << OpqEnd_Shift)
  381. #define OpqTopSel_Shift 30
  382. #define OpqTopSel_Mask (1L << OpqTopSel_Shift)
  383. #define OpqTopSelS_ (0L << OpqTopSel_Shift)
  384. #define OpqTopSelP_ (1L << OpqTopSel_Shift)
  385. #define OpqCtrl_Shift 31
  386. #define OpqCtrl_Mask (1L << OpqCtrl_Shift)
  387. #define OpqDisabled (0L << OpqCtrl_Shift)
  388. #define OpqEnabled (1L << OpqCtrl_Shift)
  389. // The following defines are for VL and PCI system configuration
  390. #define K2V_SRD_LPB_MASK 0x03
  391. #define K2V_SRD_LPB 0x00
  392. #define K2V_SRD_FC K2V_SRD_LPB_MASK
  393. #define K2V_SRD_COMP 0x02
  394. #define K2V_CR5C_SRC_MASK 0x03
  395. #define K2V_CR5C_SRC_DIGITIZER 0x02
  396. #define K2V_CR5C_SRC_MPEG 0x01
  397. #define K2V_SR1C_MASK 0x03
  398. #define K2V_SR1C_VL 0x01
  399. #define K2V_SR1C_PCI 0x02
  400. // Useful macros
  401. #define HDDA(w0,w1) (((2*(w0-1)-(w1-1)) << HDDA_Shift) & HDDA_Mask )
  402. #define VDDA(h1) (((1-h1) << VDDA_Shift) & VDDA_Mask )
  403. #define HK1(w0) (((w0 - 1) << HK1_Shift) & HK1_Mask )
  404. #define HK2(w0,w1) (((w0 - w1) << HK2_Shift) & HK2_Mask )
  405. #define HK1K2(w0,w1) (HK1(w0) | HK2(w0, w1))
  406. #define VK1(h0) (((h0 - 1) << VK1_Shift) & VK1_Mask )
  407. #define VK2(h0,h1) (((h0 - h1) << VK2_Shift) & VK2_Mask )
  408. #define XY(x,y) ((((x+1)<<X_Shift)&X_Mask) | (((y+1)<<Y_Shift)&Y_Mask))
  409. #define WH(w,h) ((((w-1)<<W_Shift)&W_Mask) | (((h)<<H_Shift)&H_Mask))
  410. #define HWCODEC 0
  411. #define SWCODEC 1
  412. #define DIGITIZER 2
  413. #define MAX_DEVICE 3
  414. #define DSTWIN_SIZES 5
  415. ////////////////////////////////////////////////////////////////////
  416. // S3 pixel formatter
  417. ////////////////////////////////////////////////////////////////////
  418. // Equates for Pixel Formatter (Video Engine) 868/968
  419. #define INPUT_RGB8 0x00000000
  420. #define INPUT_RGB15 0x00600000
  421. #define INPUT_RGB16 0x00700000
  422. #define INPUT_RGB32 0x00300000
  423. #define INPUT_YUV422 0x00480000
  424. #define INPUT_YCrCb422 0x00400000
  425. #define INPUT_RAW 0x00500000
  426. #define OUTPUT_RGB8 0x00000000
  427. #define OUTPUT_RGB15 0x00060000
  428. #define OUTPUT_RGB16 0x00070000
  429. #define OUTPUT_RGB32 0x00030000
  430. #define OUTPUT_YUY2 0x000C0000
  431. #define OUTPUT_RAW 0x00050000
  432. #define CSCENABLE 0x40000000
  433. #define STRETCH 0x00000000
  434. #define SHRINK 0x80000000
  435. #define SCREEN 0x00000000
  436. #define HOST 0x40000000
  437. #define FILTERENABLE 0x80000000
  438. #define BILINEAR 0x00000000
  439. #define LINEAR02420 0x00004000
  440. #define LINEAR12221 0x00008000
  441. #define PF_BUSY 0x80000000
  442. #define PF_NOP 0x00018080
  443. #define PF_CONTROL 0x00018088
  444. #define PF_DDA 0x0001808C
  445. #define PF_STEP 0x00018090
  446. #define PF_CROP 0x00018094
  447. #define PF_SRCADDR 0x00018098
  448. #define PF_DSTADDR 0x0001809C
  449. //////////////////////////////////////////////////////////////////////
  450. // RISC considerations
  451. //
  452. // CP_EIEIO() 'Ensure In-order Execution of I/O'
  453. // - Used to flush any pending I/O in situations where we wish to
  454. // avoid out-of-order execution of I/O to separate addresses.
  455. //
  456. // CP_MEMORY_BARRIER()
  457. // - Used to flush any pending I/O in situations where we wish to
  458. // avoid out-of-order execution or 'collapsing' of I/O to
  459. // the same address. We used to have to do this separately for
  460. // the Alpha because unlike the PowerPC it did not guarantee that
  461. // output to the same address will be exectued in order. However,
  462. // with the move to kernel-mode, on Alpha we are now calling HAL
  463. // routines for every port I/O which ensure that this is not a
  464. // problem.
  465. #if defined(_ALPHA_)
  466. // On Alpha, since we must do all non-frame-buffer I/O through HAL
  467. // routines, which automatically do memory-barriers, we don't have
  468. // to do memory barriers ourselves (and should not, because it's a
  469. // performance hit).
  470. #define CP_EIEIO()
  471. #define CP_MEMORY_BARRIER()
  472. #else
  473. // On other systems, both CP_EIEIO and CP_MEMORY_BARRIER don't do anything.
  474. #define CP_EIEIO() MEMORY_BARRIER()
  475. #define CP_MEMORY_BARRIER() MEMORY_BARRIER()
  476. #endif
  477. ////////////////////////////////////////////////////////////////////
  478. // Macros for accessing accelerator registers:
  479. /////////////////////////////////////////////////////////////////////////
  480. // 32bpp Support
  481. //
  482. // The S3 has only 16 bit register operations. When running at 32bpp,
  483. // depth-related registers are written twice in succession in order to
  484. // convey 32 bit values.
  485. #define OUT_PSEUDO_DWORD(p, x) \
  486. { \
  487. WRITE_PORT_USHORT((p), (USHORT)(x)); \
  488. CP_MEMORY_BARRIER(); \
  489. WRITE_PORT_USHORT((p), (USHORT)((x) >> 16)); \
  490. }
  491. #define WRITE_PSEUDO_DWORD(p, x) \
  492. { \
  493. WRITE_REGISTER_USHORT((p), (USHORT) (x)); \
  494. CP_MEMORY_BARRIER(); \
  495. WRITE_REGISTER_USHORT((p), (USHORT) ((x) >> 16)); \
  496. }
  497. // DEPTH32(ppdev) returns TRUE if running at 32bpp, meaning that DEPTH32
  498. // macros must be used, and returns FALSE if running at 8 or 16bpp,
  499. // meaning that DEPTH macros must be used:
  500. #define DEPTH32(ppdev) (ppdev->iBitmapFormat == BMF_32BPP)
  501. #define IO_GP_BUSY(ppdev) (IO_GP_STAT(ppdev) & HARDWARE_BUSY)
  502. #define IO_FIFO_BUSY(ppdev, level) \
  503. (IO_GP_STAT(ppdev) & ((FIFO_1_EMPTY << 1) >> (level)))
  504. #if DBG
  505. /////////////////////////////////////////////////////////////////////////
  506. // Checked Build
  507. //
  508. // We hook some of the accelerator macros on checked (debug) builds
  509. // for sanity checking.
  510. VOID vOutFifoW(VOID*, ULONG);
  511. VOID vOutDepth(PDEV*, VOID*, ULONG);
  512. VOID vOutFifoPseudoD(PDEV*, VOID*, ULONG);
  513. VOID vWriteFifoW(VOID*, ULONG);
  514. VOID vWriteFifoD(VOID*, ULONG);
  515. VOID vWriteFifoPseudoD(PDEV*, VOID*, ULONG);
  516. VOID vIoFifoWait(PDEV*, LONG);
  517. VOID vIoGpWait(PDEV*);
  518. VOID vIoAllEmpty(PDEV*);
  519. VOID vCheckDataReady(PDEV*);
  520. VOID vCheckDataComplete(PDEV*);
  521. UCHAR jInp(BYTE*, ULONG);
  522. USHORT wInpW(BYTE*, ULONG);
  523. VOID vOutp(BYTE*, ULONG, ULONG);
  524. VOID vOutpW(BYTE*, ULONG, ULONG);
  525. VOID vAcquireCrtc(PDEV*);
  526. VOID vReleaseCrtc(PDEV*);
  527. #define OUT_FIFO_W(p, v) vOutFifoW((p), (ULONG) (v))
  528. #define OUT_FIFO_PSEUDO_D(ppdev, p, v) vOutFifoPseudoD((ppdev), (p), (ULONG) (v))
  529. #define WRITE_FIFO_W(p, v) vWriteFifoW((p), (ULONG) (v))
  530. #define WRITE_FIFO_D(p, v) vWriteFifoD((p), (ULONG) (v))
  531. #define IO_FIFO_WAIT(ppdev, level) vIoFifoWait((ppdev), (level))
  532. #define IO_GP_WAIT(ppdev) vIoGpWait(ppdev)
  533. #define IO_ALL_EMPTY(ppdev) vIoAllEmpty(ppdev)
  534. #define CHECK_DATA_READY(ppdev) vCheckDataReady(ppdev)
  535. #define CHECK_DATA_COMPLETE(ppdev) vCheckDataComplete(ppdev)
  536. #define OUTPW(pjIoBase, p, v) vOutpW((pjIoBase), (p), (ULONG) (v))
  537. #define OUTP(pjIoBase, p, v) vOutp((pjIoBase), (p), (ULONG) (v))
  538. #define INPW(pjIoBase, p) wInpW((pjIoBase), (p))
  539. #define INP(pjIoBase, p) jInp((pjIoBase), (p))
  540. // The CRTC register critical section must be acquired before
  541. // touching the CRTC register (because of async pointers):
  542. #define ACQUIRE_CRTC_CRITICAL_SECTION(ppdev) vAcquireCrtc(ppdev)
  543. #define RELEASE_CRTC_CRITICAL_SECTION(ppdev) vReleaseCrtc(ppdev)
  544. #else
  545. /////////////////////////////////////////////////////////////////////////
  546. // Free Build
  547. //
  548. // For a free (non-debug build), we make everything in-line.
  549. // Safe port access macros -- these macros automatically do memory
  550. // ----------------------- barriers, so you don't have to worry
  551. // about them:
  552. #if defined(_X86_)
  553. // x86 doesn't need 'pjIoBase' added in, so save some code space:
  554. #define OUTPW(pjIoBase, p, v) WRITE_PORT_USHORT((p), (v))
  555. #define OUTP(pjIoBase, p, v) WRITE_PORT_UCHAR((p), (v))
  556. #define INPW(pjIoBase, p) ((USHORT)READ_PORT_USHORT((p)))
  557. #define INP(pjIoBase, p) ((UCHAR)READ_PORT_UCHAR((p)))
  558. #else
  559. // Non-x86 platforms have the I/O range starting at 'pjIoBase':
  560. #define OUTPW(pjIoBase, p, v) \
  561. { \
  562. CP_EIEIO(); \
  563. WRITE_PORT_USHORT((pjIoBase) + (p), (USHORT)(v)); \
  564. CP_EIEIO(); \
  565. }
  566. #define OUTP(pjIoBase, p, v) \
  567. { \
  568. CP_EIEIO(); \
  569. WRITE_PORT_UCHAR((pjIoBase) + (p), (UCHAR)(v)); \
  570. CP_EIEIO(); \
  571. }
  572. __inline USHORT INPW(BYTE* pjIoBase, ULONG p)
  573. {
  574. CP_EIEIO();
  575. return(READ_PORT_USHORT(pjIoBase + p));
  576. }
  577. __inline UCHAR INP(BYTE* pjIoBase, ULONG p)
  578. {
  579. CP_EIEIO();
  580. return(READ_PORT_UCHAR(pjIoBase + p));
  581. }
  582. #endif
  583. // Not-so-safe port access macros -- for performance, the following macros
  584. // ------------------------------ do not automatically do memory
  585. // barriers, so you must do them yourself:
  586. #define OUT_FIFO_W(p, v) WRITE_PORT_USHORT((p), (USHORT) (v))
  587. #define OUT_FIFO_PSEUDO_D(ppdev, p, x) OUT_PSEUDO_DWORD((p), (ULONG) (x))
  588. #define WRITE_FIFO_W(p, v) \
  589. { \
  590. VPBYTE foo = (p); \
  591. WRITE_REGISTER_USHORT(foo, (USHORT) (v)); \
  592. }
  593. #define WRITE_FIFO_D(p, v) \
  594. { \
  595. VPBYTE foo = (p); \
  596. WRITE_REGISTER_ULONG((p), (ULONG) (v)); \
  597. }
  598. #define IO_FIFO_WAIT(ppdev, level) \
  599. do {;} while (IO_FIFO_BUSY(ppdev, (level)))
  600. #define IO_GP_WAIT(ppdev) \
  601. do {;} while (IO_GP_BUSY(ppdev))
  602. #define IO_ALL_EMPTY(ppdev) \
  603. do {;} while (!(IO_GP_STAT(ppdev) & GP_ALL_EMPTY))
  604. #define CHECK_DATA_READY(ppdev) // Expands to nothing
  605. #define CHECK_DATA_COMPLETE(ppdev) // Expands to nothing
  606. // The CRTC register critical section must be acquired before
  607. // touching the CRTC register (because of async pointers):
  608. #define ACQUIRE_CRTC_CRITICAL_SECTION(ppdev) \
  609. EngAcquireSemaphore(ppdev->csCrtc);
  610. // 80x/805i/928 and 928PCI chips have a bug where if I/O registers
  611. // are left unlocked after accessing them, writes to memory with
  612. // similar addresses can cause writes to I/O registers. The problem
  613. // registers are 0x40, 0x58, 0x59 and 0x5c. We will simply always
  614. // leave the index set to an innocuous register (namely, the text
  615. // mode cursor start scan line):
  616. #define RELEASE_CRTC_CRITICAL_SECTION(ppdev) \
  617. { \
  618. OUTP(ppdev->pjIoBase, CRTC_INDEX, 0xa); \
  619. EngReleaseSemaphore(ppdev->csCrtc); \
  620. }
  621. #endif
  622. ////////////////////////////////////////////////////////////////////
  623. // Port access using I/O
  624. // The following are ABSOLUTE positioning macros. They do NOT take
  625. // the surface's offset into account (for off-screen device-format
  626. // bitmaps):
  627. #define IO_ABS_CUR_Y(ppdev, y) \
  628. OUT_FIFO_W(ppdev->ioCur_y, (y))
  629. #define IO_ABS_CUR_X(ppdev, x) \
  630. OUT_FIFO_W(ppdev->ioCur_x, (x))
  631. #define IO_ABS_DEST_Y(ppdev, y) \
  632. OUT_FIFO_W(ppdev->ioDesty_axstp, (y))
  633. #define IO_ABS_DEST_X(ppdev, x) \
  634. OUT_FIFO_W(ppdev->ioDestx_diastp, (x))
  635. #define IO_ABS_SCISSORS_T(ppdev, y) \
  636. { \
  637. CP_MEMORY_BARRIER(); \
  638. OUT_FIFO_W(ppdev->ioMulti_function, (y) | CLIP_TOP); \
  639. }
  640. #define IO_ABS_SCISSORS_L(ppdev, x) \
  641. { \
  642. CP_MEMORY_BARRIER(); \
  643. OUT_FIFO_W(ppdev->ioMulti_function, (x) | CLIP_LEFT); \
  644. }
  645. #define IO_ABS_SCISSORS_B(ppdev, y) \
  646. { \
  647. CP_MEMORY_BARRIER(); \
  648. OUT_FIFO_W(ppdev->ioMulti_function, (y) | CLIP_BOTTOM); \
  649. }
  650. #define IO_ABS_SCISSORS_R(ppdev, x) \
  651. { \
  652. CP_MEMORY_BARRIER(); \
  653. OUT_FIFO_W(ppdev->ioMulti_function, (x) | CLIP_RIGHT); \
  654. }
  655. // The following are RELATIVE positioning macros. They DO take
  656. // the surface's offset into account:
  657. #define IO_CUR_Y(ppdev, y) \
  658. IO_ABS_CUR_Y(ppdev, (y) + ppdev->yOffset)
  659. #define IO_CUR_X(ppdev, x) \
  660. IO_ABS_CUR_X(ppdev, (x) + ppdev->xOffset)
  661. #define IO_DEST_Y(ppdev, y) \
  662. IO_ABS_DEST_Y(ppdev, (y) + ppdev->yOffset)
  663. #define IO_DEST_X(ppdev, x) \
  664. IO_ABS_DEST_X(ppdev, (x) + ppdev->xOffset)
  665. #define IO_SCISSORS_T(ppdev, y) \
  666. IO_ABS_SCISSORS_T(ppdev, (y) + ppdev->yOffset)
  667. #define IO_SCISSORS_L(ppdev, x) \
  668. IO_ABS_SCISSORS_L(ppdev, (x) + ppdev->xOffset)
  669. #define IO_SCISSORS_B(ppdev, y) \
  670. IO_ABS_SCISSORS_B(ppdev, (y) + ppdev->yOffset)
  671. #define IO_SCISSORS_R(ppdev, x) \
  672. IO_ABS_SCISSORS_R(ppdev, (x) + ppdev->xOffset)
  673. // The following are the rest of the S3 registers we use:
  674. #define IO_AXSTP(ppdev, x) \
  675. OUT_FIFO_W(ppdev->ioDesty_axstp, (x))
  676. #define IO_DIASTP(ppdev, x) \
  677. OUT_FIFO_W(ppdev->ioDestx_diastp, (x))
  678. #define IO_ERR_TERM(ppdev, x) \
  679. OUT_FIFO_W(ppdev->ioErr_term, (x))
  680. #define IO_MAJ_AXIS_PCNT(ppdev, x) \
  681. OUT_FIFO_W(ppdev->ioMaj_axis_pcnt, (x))
  682. __inline USHORT IO_GP_STAT(PDEV* ppdev)
  683. {
  684. CP_EIEIO();
  685. return(READ_PORT_USHORT(ppdev->ioGp_stat_cmd));
  686. }
  687. // Note that we have to put memory barriers before and after the
  688. // command output. The first memory barrier ensures that all the
  689. // settings registers have been set before the command is executed,
  690. // and the second ensures that no subsequent changes to the settings
  691. // registers will mess up the current command:
  692. #define IO_CMD(ppdev, x) \
  693. { \
  694. CP_EIEIO(); \
  695. OUT_FIFO_W(ppdev->ioGp_stat_cmd, (x)); \
  696. CP_EIEIO(); \
  697. }
  698. #define IO_SHORT_STROKE(ppdev, x) \
  699. { \
  700. CP_EIEIO(); \
  701. OUT_FIFO_W(ppdev->ioShort_stroke, (x)); \
  702. CP_EIEIO(); \
  703. }
  704. #define IO_BKGD_MIX(ppdev, x) \
  705. OUT_FIFO_W(ppdev->ioBkgd_mix, (x))
  706. #define IO_FRGD_MIX(ppdev, x) \
  707. OUT_FIFO_W(ppdev->ioFrgd_mix, (x))
  708. #define IO_MIN_AXIS_PCNT(ppdev, x) \
  709. { \
  710. CP_MEMORY_BARRIER(); \
  711. OUT_FIFO_W(ppdev->ioMulti_function, (x) | RECT_HEIGHT); \
  712. }
  713. #define IO_MULTIFUNC_CNTL(ppdev, x) \
  714. { \
  715. CP_MEMORY_BARRIER(); \
  716. OUT_FIFO_W(ppdev->ioMulti_function, (x) | MULT_MISC_INDEX); \
  717. }
  718. #define IO_PIX_CNTL(ppdev, x) \
  719. { \
  720. CP_MEMORY_BARRIER(); \
  721. OUT_FIFO_W(ppdev->ioMulti_function, (x) | DATA_EXTENSION); \
  722. }
  723. #define IO_READ_SEL(ppdev, x) \
  724. { \
  725. CP_MEMORY_BARRIER(); \
  726. OUT_FIFO_W(ppdev->ioMulti_function, (x) | READ_SEL_INDEX); \
  727. }
  728. #define IO_MULT_MISC(ppdev, x) \
  729. { \
  730. CP_MEMORY_BARRIER(); \
  731. OUT_FIFO_W(ppdev->ioMulti_function, (x) | MULT_MISC_INDEX); \
  732. }
  733. #define IO_RD_REG_DT(ppdev, x) \
  734. { \
  735. CP_EIEIO(); \
  736. x = READ_PORT_USHORT(ppdev->ioMulti_function); \
  737. CP_EIEIO(); \
  738. }
  739. #define IO_PIX_TRANS(ppdev, x) \
  740. { \
  741. CP_MEMORY_BARRIER(); \
  742. /* Can't use OUT_FIFO_W: */ \
  743. WRITE_PORT_USHORT(ppdev->ioPix_trans, (x)); \
  744. }
  745. // Macros for outputing colour-depth dependent values at 8bpp and 16bpp:
  746. #define IO_BKGD_COLOR(ppdev, x) \
  747. OUT_FIFO_W(ppdev->ioBkgd_color, (x))
  748. #define IO_FRGD_COLOR(ppdev, x) \
  749. OUT_FIFO_W(ppdev->ioFrgd_color, (x))
  750. #define IO_WRT_MASK(ppdev, x) \
  751. OUT_FIFO_W(ppdev->ioWrt_mask, (x))
  752. #define IO_RD_MASK(ppdev, x) \
  753. OUT_FIFO_W(ppdev->ioRd_mask, (x))
  754. #define IO_COLOR_CMP(ppdev, x) \
  755. OUT_FIFO_W(ppdev->ioColor_cmp, (x))
  756. // Macros for outputing colour-depth dependent values at 32bpp:
  757. #define IO_BKGD_COLOR32(ppdev, x) \
  758. OUT_FIFO_PSEUDO_D(ppdev, ppdev->ioBkgd_color, (x))
  759. #define IO_FRGD_COLOR32(ppdev, x) \
  760. OUT_FIFO_PSEUDO_D(ppdev, ppdev->ioFrgd_color, (x))
  761. #define IO_WRT_MASK32(ppdev, x) \
  762. OUT_FIFO_PSEUDO_D(ppdev, ppdev->ioWrt_mask, (x))
  763. #define IO_RD_MASK32(ppdev, x) \
  764. OUT_FIFO_PSEUDO_D(ppdev, ppdev->ioRd_mask, (x))
  765. #define IO_COLOR_CMP32(ppdev, x) \
  766. OUT_FIFO_PSEUDO_D(ppdev, ppdev->ioColor_cmp, (x))
  767. ////////////////////////////////////////////////////////////////////
  768. // Port access using memory-mapped I/O:
  769. // The following are ABSOLUTE positioning macros. They do NOT take
  770. // the surface's offset into account:
  771. #define MM_ABS_CUR_Y(ppdev, pjMmBase, y) \
  772. WRITE_FIFO_W((BYTE*) (pjMmBase) + CUR_Y, (y))
  773. #define MM_ABS_CUR_X(ppdev, pjMmBase, x) \
  774. WRITE_FIFO_W((BYTE*) (pjMmBase) + CUR_X, (x))
  775. #define MM_ABS_DEST_Y(ppdev, pjMmBase, y) \
  776. WRITE_FIFO_W((BYTE*) (pjMmBase) + DEST_Y, (y))
  777. #define MM_ABS_DEST_X(ppdev, pjMmBase, x) \
  778. WRITE_FIFO_W((BYTE*) (pjMmBase) + DEST_X, (x))
  779. #define MM_ABS_SCISSORS_T(ppdev, pjMmBase, y) \
  780. { \
  781. CP_MEMORY_BARRIER(); \
  782. WRITE_FIFO_W((BYTE*) (pjMmBase) + SCISSORS, (y) | CLIP_TOP); \
  783. }
  784. #define MM_ABS_SCISSORS_L(ppdev, pjMmBase, x) \
  785. { \
  786. CP_MEMORY_BARRIER(); \
  787. WRITE_FIFO_W((BYTE*) (pjMmBase) + SCISSORS, (x) | CLIP_LEFT); \
  788. }
  789. #define MM_ABS_SCISSORS_B(ppdev, pjMmBase, y) \
  790. { \
  791. CP_MEMORY_BARRIER(); \
  792. WRITE_FIFO_W((BYTE*) (pjMmBase) + SCISSORS, (y) | CLIP_BOTTOM); \
  793. }
  794. #define MM_ABS_SCISSORS_R(ppdev, pjMmBase, x) \
  795. { \
  796. CP_MEMORY_BARRIER(); \
  797. WRITE_FIFO_W((BYTE*) (pjMmBase) + SCISSORS, (x) | CLIP_RIGHT); \
  798. }
  799. // The following are RELATIVE positioning macros. They DO take
  800. // the surface's offset into account:
  801. #define MM_CUR_Y(ppdev, pjMmBase, y) \
  802. MM_ABS_CUR_Y(ppdev, pjMmBase, (y) + ppdev->yOffset)
  803. #define MM_CUR_X(ppdev, pjMmBase, x) \
  804. MM_ABS_CUR_X(ppdev, pjMmBase, (x) + ppdev->xOffset)
  805. #define MM_DEST_Y(ppdev, pjMmBase, y) \
  806. MM_ABS_DEST_Y(ppdev, pjMmBase, (y) + ppdev->yOffset)
  807. #define MM_DEST_X(ppdev, pjMmBase, x) \
  808. MM_ABS_DEST_X(ppdev, pjMmBase, (x) + ppdev->xOffset)
  809. #define MM_SCISSORS_T(ppdev, pjMmBase, y) \
  810. MM_ABS_SCISSORS_T(ppdev, pjMmBase, (y) + ppdev->yOffset)
  811. #define MM_SCISSORS_L(ppdev, pjMmBase, x) \
  812. MM_ABS_SCISSORS_L(ppdev, pjMmBase, (x) + ppdev->xOffset)
  813. #define MM_SCISSORS_B(ppdev, pjMmBase, y) \
  814. MM_ABS_SCISSORS_B(ppdev, pjMmBase, (y) + ppdev->yOffset)
  815. #define MM_SCISSORS_R(ppdev, pjMmBase, x) \
  816. MM_ABS_SCISSORS_R(ppdev, pjMmBase, (x) + ppdev->xOffset)
  817. // The following are the rest of the S3 registers we use:
  818. #define MM_AXSTP(ppdev, pjMmBase, x) \
  819. WRITE_FIFO_W((BYTE*) (pjMmBase) + AXSTP, (x))
  820. #define MM_DIASTP(ppdev, pjMmBase, x) \
  821. WRITE_FIFO_W((BYTE*) (pjMmBase) + DIASTP, (x))
  822. #define MM_ERR_TERM(ppdev, pjMmBase, x) \
  823. WRITE_FIFO_W((BYTE*) (pjMmBase) + ERR_TERM, (x))
  824. #define MM_MAJ_AXIS_PCNT(ppdev, pjMmBase, x) \
  825. WRITE_FIFO_W((BYTE*) (pjMmBase) + MAJ_AXIS_PCNT, (x))
  826. #define MM_CMD(ppdev, pjMmBase, x) \
  827. { \
  828. CP_EIEIO(); \
  829. WRITE_FIFO_W((BYTE*) (pjMmBase) + CMD, (x)); \
  830. CP_EIEIO(); \
  831. }
  832. #define MM_SHORT_STROKE(ppdev, pjMmBase, x) \
  833. { \
  834. CP_EIEIO(); \
  835. WRITE_FIFO_W((BYTE*) (pjMmBase) + SHORT_STROKE, (x)); \
  836. CP_EIEIO(); \
  837. }
  838. #define MM_BKGD_MIX(ppdev, pjMmBase, x) \
  839. WRITE_FIFO_W((BYTE*) (pjMmBase) + BKGD_MIX, (x))
  840. #define MM_FRGD_MIX(ppdev, pjMmBase, x) \
  841. WRITE_FIFO_W((BYTE*) (pjMmBase) + FRGD_MIX, (x))
  842. #define MM_MIN_AXIS_PCNT(ppdev, pjMmBase, x) \
  843. { \
  844. CP_MEMORY_BARRIER(); \
  845. WRITE_FIFO_W((BYTE*) (pjMmBase) + MIN_AXIS_PCNT, (x) | RECT_HEIGHT); \
  846. }
  847. #define MM_MULTIFUNC_CNTL(ppdev, pjMmBase, x) \
  848. { \
  849. CP_MEMORY_BARRIER(); \
  850. WRITE_FIFO_W((BYTE*) (pjMmBase) + MULTIFUNC_CNTL, (x) | MULT_MISC_INDEX); \
  851. }
  852. #define MM_PIX_CNTL(ppdev, pjMmBase, x) \
  853. { \
  854. CP_MEMORY_BARRIER(); \
  855. WRITE_FIFO_W((BYTE*) (pjMmBase) + PIX_CNTL, (x) | DATA_EXTENSION); \
  856. }
  857. #define MM_PIX_TRANS(ppdev, pjMmBase, x) \
  858. { \
  859. CP_MEMORY_BARRIER(); \
  860. /* Can't use WRITE_FIFO_W: */ \
  861. WRITE_REGISTER_USHORT((BYTE*) (pjMmBase) + PIX_TRANS, (x)); \
  862. }
  863. // Macros for outputing colour-depth dependent values at any colour depth:
  864. #define MM_BKGD_COLOR(ppdev, pjMmBase, x) \
  865. WRITE_FIFO_D((BYTE*) (pjMmBase) + BKGD_COLOR, (x))
  866. #define MM_FRGD_COLOR(ppdev, pjMmBase, x) \
  867. WRITE_FIFO_D((BYTE*) (pjMmBase) + FRGD_COLOR, (x))
  868. #define MM_WRT_MASK(ppdev, pjMmBase, x) \
  869. WRITE_FIFO_D((BYTE*) (pjMmBase) + WRT_MASK, (x))
  870. #define MM_RD_MASK(ppdev, pjMmBase, x) \
  871. WRITE_FIFO_D((BYTE*) (pjMmBase) + RD_MASK, (x))
  872. #define MM_COLOR_CMP(ppdev, pjMmBase, x) \
  873. WRITE_FIFO_D((BYTE*) (pjMmBase) + COLOR_CMP, (x))
  874. #define MM_FIFO_BUSY(ppdev, pjMmBase, level) \
  875. (((level) <= 8) ? IO_GP_STAT(ppdev) & (0x0080 >> ((level) - 1)) \
  876. : IO_GP_STAT(ppdev) & (0x8000 >> ((level) - 9)))
  877. #if DBG
  878. VOID vMmFifoWait(PDEV*, BYTE*, LONG);
  879. #define MM_FIFO_WAIT(ppdev, pjMmBase, level) \
  880. vMmFifoWait((ppdev), (pjMmBase), (level))
  881. #else
  882. #define MM_FIFO_WAIT(ppdev, pjMmBase, level) \
  883. do {;} while (MM_FIFO_BUSY(ppdev, pjMmBase, (level)))
  884. #endif
  885. //////////////////////////////////////////////////////////////////////
  886. // Note: The PACKXY_FAST macro is unsafe with negative coordinates
  887. #define PACKXY(x, y) (((x) << 16) | ((y) & 0xffff))
  888. #define PACKXY_FAST(x, y) (((x) << 16) | (y))
  889. #define NW_ABS_CURXY(ppdev, pjMmBase, x, y) \
  890. WRITE_FIFO_D((BYTE*) (pjMmBase) + ALT_CURXY, PACKXY((x), (y)))
  891. #define NW_ABS_CURXY_FAST(ppdev, pjMmBase, x, y) \
  892. WRITE_FIFO_D((BYTE*) (pjMmBase) + ALT_CURXY, PACKXY_FAST((x), (y)))
  893. #define NW_ABS_CURXY2(ppdev, pjMmBase, x, y) \
  894. WRITE_FIFO_D((BYTE*) (pjMmBase) + ALT_CURXY2, PACKXY((x), (y)))
  895. #define NW_ABS_STEPXY(ppdev, pjMmBase, x, y) \
  896. WRITE_FIFO_D((BYTE*) (pjMmBase) + ALT_STEP, PACKXY((x), (y)))
  897. #define NW_ALT_STEP(ppdev, pjMmBase, diastp, axstp) \
  898. WRITE_FIFO_D((BYTE*) (pjMmBase) + ALT_STEP, PACKXY((diastp), (axstp)))
  899. #define NW_ABS_DESTXY_FAST(ppdev, pjMmBase, x, y) \
  900. WRITE_FIFO_D((BYTE*) (pjMmBase) + ALT_STEP, PACKXY((x), (y)))
  901. #define NW_ALT_PCNT(ppdev, pjMmBase, cx, cy) \
  902. WRITE_FIFO_D((BYTE*) (pjMmBase) + ALT_PCNT, PACKXY_FAST((cx), (cy)))
  903. #define NW_ALT_PCNT_PACKED(ppdev, pjMmBase, cxcy) \
  904. WRITE_FIFO_D((BYTE*) (pjMmBase) + ALT_PCNT, cxcy)
  905. #define NW_ALT_CMD(ppdev, pjMmBase, x) \
  906. WRITE_FIFO_D((BYTE*) (pjMmBase) + ALT_CMD, (x))
  907. #define NW_ALT_MIX(ppdev, pjMmBase, fore, back) \
  908. WRITE_FIFO_D((BYTE*) (pjMmBase) + ALT_MIX, PACKXY((fore), (back)))
  909. #define NW_ALT_ERR(ppdev, pjMmBase, err2, err) \
  910. WRITE_FIFO_D((BYTE*) (pjMmBase) + ALT_ERR, PACKXY((err2), (err)))
  911. #define NW_FRGD_COLOR(ppdev, pjMmBase, x) \
  912. WRITE_FIFO_D((BYTE*) (pjMmBase) + FRGD_COLOR, (x))
  913. #define NW_BKGD_COLOR(ppdev, pjMmBase, x) \
  914. WRITE_FIFO_D((BYTE*) (pjMmBase) + BKGD_COLOR, (x))
  915. #define NW_ABS_SCISSORS_LT(ppdev, pjMmBase, x, y) \
  916. WRITE_FIFO_D((BYTE*) (pjMmBase) + SCISSORS_T, PACKXY((x), (y)))
  917. #define NW_ABS_SCISSORS_RB(ppdev, pjMmBase, x, y) \
  918. WRITE_FIFO_D((BYTE*) (pjMmBase) + SCISSORS_B, PACKXY((x), (y)))
  919. #define NW_MULT_MISC_READ_SEL(ppdev, pjMmBase, mult, read) \
  920. WRITE_FIFO_D((BYTE*) (pjMmBase) + MULT_MISC_READ_SEL, PACKXY((read), (mult)))
  921. __inline BOOL NW_FIFO_BUSY(PDEV* ppdev, BYTE* pjMmBase, ULONG level)
  922. {
  923. CP_EIEIO();
  924. return(((level) <= 8) ? (READ_REGISTER_USHORT((BYTE*) (pjMmBase) + CMD)
  925. & (0x0080 >> ((level) - 1)))
  926. : (READ_REGISTER_USHORT((BYTE*) (pjMmBase) + CMD)
  927. & (0x8000 >> ((level) - 9))));
  928. }
  929. __inline BOOL NW_GP_BUSY(PDEV* ppdev, BYTE* pjMmBase)
  930. {
  931. CP_EIEIO();
  932. return(READ_REGISTER_USHORT((BYTE*) (pjMmBase) + CMD) & HARDWARE_BUSY);
  933. }
  934. #define NW_PIX_CNTL MM_PIX_CNTL
  935. #define NW_COLOR_CMP MM_COLOR_CMP
  936. #if DBG
  937. VOID vNwGpWait(PDEV*, BYTE*);
  938. VOID vNwFifoWait(PDEV*, BYTE*, LONG);
  939. VOID vDbgFakeWait(PDEV*, BYTE*, LONG);
  940. #define NW_GP_WAIT(ppdev, pjMmBase) \
  941. vNwGpWait((ppdev), (pjMmBase))
  942. #define NW_FIFO_WAIT(ppdev, pjMmBase, level) \
  943. vNwFifoWait((ppdev), (pjMmBase), (level))
  944. // DBG_FAKE_WAIT is only relevant on checked builds, and updates the
  945. // current debug-only fifo-empty count to allow us to do FIFO writes
  946. // without waiting for FIFO empty, when we (hopefully) know what we're
  947. // doing:
  948. #define DBG_FAKE_WAIT(ppdev, pjMmBase, level) \
  949. vDbgFakeWait((ppdev), (pjMmBase), (level))
  950. #else
  951. #define NW_GP_WAIT(ppdev, pjMmBase) \
  952. do {;} while (NW_GP_BUSY(ppdev, pjMmBase))
  953. #define NW_FIFO_WAIT(ppdev, pjMmBase, level) \
  954. do {;} while (NW_FIFO_BUSY(ppdev, pjMmBase, (level)))
  955. #define DBG_FAKE_WAIT(ppdev, pjMmBase, level)
  956. #endif
  957. /////////////////////////////////////////////////////////////////////////////
  958. // MM_TRANSFER routines
  959. #define MM(pjMmBase, pjMmAlpha) (pjMmBase)
  960. #if defined(_X86_)
  961. #define VPBYTE BYTE volatile * volatile
  962. #else
  963. #define VPBYTE BYTE *
  964. #endif
  965. //////////////////////////
  966. // MM_TRANSFER_BYTE - Byte transfers using memory-mapped I/O transfers.
  967. //
  968. // NOTE: The first versions of the 868/968 have a bug where they can't do
  969. // byte-sized memory-mapped transfers. Consequently, we always do
  970. // word transfers.
  971. #define MM_TRANSFER_BYTE(ppdev, pjMmBase, p, c) \
  972. { \
  973. ULONG mcw = (c) >> 1; \
  974. BYTE* mpjSrc = (BYTE*) (p); \
  975. USHORT** mapwMmXfer = ppdev->apwMmXfer; \
  976. VPBYTE foo = pjMmBase; \
  977. \
  978. ASSERTDD((c) > 0, "Can't have a zero transfer count"); \
  979. CP_MEMORY_BARRIER(); \
  980. while (mcw-- != 0) \
  981. { \
  982. WRITE_REGISTER_USHORT(MM(foo, mapwMmXfer[mcw & XFER_MASK]), \
  983. *((USHORT UNALIGNED *) mpjSrc)); \
  984. mpjSrc += 2; \
  985. } \
  986. if ((c) & 1) \
  987. { \
  988. WRITE_REGISTER_USHORT(MM(foo, mapwMmXfer[XFER_MASK]), \
  989. (USHORT) (*mpjSrc)); \
  990. } \
  991. }
  992. //////////////////////////
  993. // MM_TRANSFER_BYTE_THIN - Glyph transfers using memory-mapped I/O transfers.
  994. //
  995. // NOTE: The first versions of the 868/968 have a bug where they can't do
  996. // byte-sized memory-mapped transfers. Consequently, we always do
  997. // word transfers.
  998. #define MM_TRANSFER_BYTE_THIN(ppdev, pjMmBase, p, c) \
  999. { \
  1000. ULONG mcj = (c); \
  1001. BYTE* mpjSrc = (BYTE*) (p); \
  1002. USHORT** mapwMmXfer = ppdev->apwMmXfer; \
  1003. VPBYTE foo = pjMmBase; \
  1004. \
  1005. ASSERTDD((c) > 0, "Can't have a zero transfer count"); \
  1006. CP_MEMORY_BARRIER(); \
  1007. do { \
  1008. WRITE_REGISTER_USHORT(MM(foo, mapwMmXfer[mcj & XFER_MASK]), \
  1009. (USHORT) (*mpjSrc)); \
  1010. mpjSrc++; \
  1011. } while (--mcj); \
  1012. }
  1013. //////////////////////////
  1014. // MM_TRANSFER_WORD_ALIGNED - Word transfers using memory-mapped transfers.
  1015. //
  1016. // Source must be dword aligned!
  1017. #define MM_TRANSFER_WORD_ALIGNED(ppdev, pjMmBase, p, c) \
  1018. { \
  1019. ULONG mcd = (c) >> 1; \
  1020. ULONG* mpdSrc = (ULONG*) (p); \
  1021. ULONG** mapdMmXfer = ppdev->apdMmXfer; \
  1022. VPBYTE foo = pjMmBase; \
  1023. ASSERTDD((((ULONG_PTR) p) & 3) == 0, "Transfer not dword aligned"); \
  1024. ASSERTDD((c) > 0, "Can't have a zero transfer count"); \
  1025. CP_MEMORY_BARRIER(); \
  1026. while (mcd-- != 0) \
  1027. { \
  1028. WRITE_REGISTER_ULONG(MM(foo, mapdMmXfer[mcd & XFER_MASK]), *mpdSrc++); \
  1029. } \
  1030. if ((c) & 1) \
  1031. { \
  1032. WRITE_REGISTER_USHORT(ppdev->apwMmXfer[XFER_MASK], \
  1033. *((USHORT*) mpdSrc)); \
  1034. } \
  1035. }
  1036. //////////////////////////
  1037. // MM_TRANSFER_WORD - Word transfers using memory-mapped transfers.
  1038. //
  1039. // Source does not have to be dword aligned.
  1040. #define MM_TRANSFER_WORD(ppdev, pjMmBase, p, c) \
  1041. { \
  1042. ULONG UNALIGNED * mpdSrc = (ULONG*) (p); \
  1043. ULONG mcd = (c) >> 1; \
  1044. VPBYTE foo = pjMmBase; \
  1045. ULONG** mapdMmXfer = ppdev->apdMmXfer; \
  1046. ASSERTDD((c) > 0, "Can't have a zero transfer count"); \
  1047. CP_MEMORY_BARRIER(); \
  1048. while (mcd-- != 0) \
  1049. { \
  1050. WRITE_REGISTER_ULONG(MM(foo, mapdMmXfer[mcd & XFER_MASK]), \
  1051. *mpdSrc++); \
  1052. } \
  1053. if ((c) & 1) \
  1054. { \
  1055. WRITE_REGISTER_USHORT(ppdev->apwMmXfer[XFER_MASK], \
  1056. *((USHORT UNALIGNED *) mpdSrc)); \
  1057. } \
  1058. }
  1059. //////////////////////////
  1060. // MM_TRANSFER_DWORD_ALIGNED - Dword transfers using memory-mapped transfers.
  1061. //
  1062. // Source must be dword aligned!
  1063. #define MM_TRANSFER_DWORD_ALIGNED(ppdev, pjMmBase, p, c) \
  1064. { \
  1065. ULONG mcd = (c); \
  1066. ULONG* mpdSrc = (ULONG*) (p); \
  1067. VPBYTE foo = pjMmBase; \
  1068. ULONG** mapdMmXfer = ppdev->apdMmXfer; \
  1069. ASSERTDD((((ULONG_PTR) p) & 3) == 0, "Transfer not dword aligned"); \
  1070. ASSERTDD(ppdev->flCaps & CAPS_MM_TRANSFER, "Must be MM I/O"); \
  1071. ASSERTDD((c) > 0, "Can't have a zero transfer count"); \
  1072. \
  1073. CP_MEMORY_BARRIER(); \
  1074. do { \
  1075. WRITE_REGISTER_ULONG(MM(foo, mapdMmXfer[mcd & XFER_MASK]), \
  1076. *mpdSrc++); \
  1077. } while (--mcd); \
  1078. }
  1079. //////////////////////////
  1080. // MM_TRANSFER_DWORD - Dword transfers using memory-mapped transfers.
  1081. //
  1082. // Source does not have to be dword aligned.
  1083. #define MM_TRANSFER_DWORD(ppdev, pjMmBase, p, c) \
  1084. { \
  1085. ULONG mcd = (c); \
  1086. ULONG UNALIGNED* mpdSrc = (ULONG*) (p); \
  1087. VPBYTE foo = pjMmBase; \
  1088. ULONG** mapdMmXfer = ppdev->apdMmXfer; \
  1089. ASSERTDD((c) > 0, "Can't have a zero transfer count"); \
  1090. \
  1091. CP_MEMORY_BARRIER(); \
  1092. do { \
  1093. WRITE_REGISTER_ULONG(MM(foo, mapdMmXfer[mcd & XFER_MASK]), \
  1094. *mpdSrc++); \
  1095. } while (--mcd); \
  1096. }
  1097. //////////////////////////
  1098. // MM_TRANSFER_WORD_ODD - Word transfers for glyphs of odd byte length
  1099. // and more than one byte wide.
  1100. //
  1101. // Source must be word aligned.
  1102. #define MM_TRANSFER_WORD_ODD(ppdev, pjMmBase, p, cjWidth, cy) \
  1103. { \
  1104. BYTE* mpjSrc = (BYTE*) (p); \
  1105. USHORT** mapwMmXfer = ppdev->apwMmXfer; \
  1106. LONG mi = 0; \
  1107. LONG mcy = (cy); \
  1108. LONG mcw = ((cjWidth) >> 1); \
  1109. LONG mc; \
  1110. VPBYTE foo = pjMmBase; \
  1111. \
  1112. ASSERTDD(((cjWidth) > 0) && ((cy) > 0), "Can't have a zero transfer count");\
  1113. ASSERTDD((cjWidth) & 1, "Must be odd byte width"); \
  1114. ASSERTDD((cjWidth) > 2, "Must be more than 2 bytes wide"); \
  1115. \
  1116. CP_MEMORY_BARRIER(); \
  1117. do { \
  1118. mc = mcw; \
  1119. do { \
  1120. WRITE_REGISTER_USHORT(MM(foo, mapwMmXfer[(mi++) & XFER_MASK]), \
  1121. *((USHORT UNALIGNED *) mpjSrc)); \
  1122. mpjSrc += 2; \
  1123. } while (--mc != 0); \
  1124. \
  1125. WRITE_REGISTER_USHORT(MM(foo, mapwMmXfer[(mi++) & XFER_MASK]), \
  1126. (USHORT) (*(mpjSrc))); \
  1127. mpjSrc++; \
  1128. } while (--mcy != 0); \
  1129. }
  1130. //////////////////////////
  1131. // IO_TRANSFER_WORD_ALIGNED - Word transfers using normal I/O.
  1132. #define IO_TRANSFER_WORD_ALIGNED(ppdev, p, c) \
  1133. { \
  1134. ULONG mcw = (c); \
  1135. USHORT* mpwSrc = (USHORT*) (p); \
  1136. ASSERTDD((((ULONG_PTR) p) & 3) == 0, "Transfer not dword aligned"); \
  1137. ASSERTDD((c) > 0, "Can't have a zero transfer count"); \
  1138. do { \
  1139. IO_PIX_TRANS(ppdev, *mpwSrc++); \
  1140. } while (--mcw); \
  1141. }
  1142. //////////////////////////
  1143. // IO_TRANSFER_WORD - Word transfers using normal I/O.
  1144. //
  1145. // Source does not have to be dword aligned.
  1146. #define IO_TRANSFER_WORD(ppdev, p, c) \
  1147. { \
  1148. ULONG mcw = (c); \
  1149. USHORT UNALIGNED * mpwSrc = (USHORT*) (p); \
  1150. ASSERTDD((c) > 0, "Can't have a zero transfer count"); \
  1151. do { \
  1152. IO_PIX_TRANS(ppdev, *mpwSrc++); \
  1153. } while (--mcw); \
  1154. }
  1155. /////////////////////////////////////////////////////////////////////////////
  1156. // DirectDraw stuff
  1157. #define IS_RGB15_R(flRed) \
  1158. (flRed == 0x7c00)
  1159. #define IS_RGB15(this) \
  1160. (((this)->dwRBitMask == 0x7c00) && \
  1161. ((this)->dwGBitMask == 0x03e0) && \
  1162. ((this)->dwBBitMask == 0x001f))
  1163. #define IS_RGB16(this) \
  1164. (((this)->dwRBitMask == 0xf800) && \
  1165. ((this)->dwGBitMask == 0x07e0) && \
  1166. ((this)->dwBBitMask == 0x001f))
  1167. #define IS_RGB24(this) \
  1168. (((this)->dwRBitMask == 0x00ff0000) && \
  1169. ((this)->dwGBitMask == 0x0000ff00) && \
  1170. ((this)->dwBBitMask == 0x000000ff))
  1171. #define IS_RGB32(this) \
  1172. (((this)->dwRBitMask == 0x00ff0000) && \
  1173. ((this)->dwGBitMask == 0x0000ff00) && \
  1174. ((this)->dwBBitMask == 0x000000ff))
  1175. #define RGB15to32(c) \
  1176. (((c & 0x7c00) << 9) | \
  1177. ((c & 0x03e0) << 6) | \
  1178. ((c & 0x001f) << 3))
  1179. #define RGB16to32(c) \
  1180. (((c & 0xf800) << 8) | \
  1181. ((c & 0x07e0) << 5) | \
  1182. ((c & 0x001f) << 3))
  1183. #define VBLANK_IS_ACTIVE(pjIoBase) \
  1184. (INP(pjIoBase, STATUS_1) & VBLANK_ACTIVE)
  1185. #define DISPLAY_IS_ACTIVE(pjIoBase) \
  1186. (!(INP(pjIoBase, STATUS_1) & DISPLAY_MODE_INACTIVE))
  1187. #define WAIT_FOR_VBLANK(pjIoBase) \
  1188. do {} while (!(VBLANK_IS_ACTIVE(pjIoBase)));
  1189. extern VOID vStreamsDelay(); // Work around 765 timing bug
  1190. #define WRITE_STREAM_D(pjMmBase, Register, x) \
  1191. { \
  1192. WRITE_REGISTER_ULONG((BYTE*) (pjMmBase) + Register, (x)); \
  1193. CP_EIEIO(); \
  1194. vStreamsDelay(); \
  1195. }
  1196. #define WRITE_FORMATTER_D(pjMmBase, Register, x) \
  1197. { \
  1198. if (Register == PF_NOP) \
  1199. CP_EIEIO(); \
  1200. WRITE_FIFO_D((BYTE*) (pjMmBase) + Register, (x)); \
  1201. }
  1202. #define NW_FORMATTER_WAIT(ppdev, pjMmBase) \
  1203. { \
  1204. CP_EIEIO(); \
  1205. do {} while (READ_REGISTER_ULONG((BYTE*) (pjMmBase) + PF_DSTADDR) & PF_BUSY); \
  1206. }
  1207. /////////////////////////////////////////////////////////////////////////////
  1208. // Private IOCTL for communicating S3 streams parameters. These definitions
  1209. // must match those in the miniport!
  1210. #define IOCTL_VIDEO_S3_QUERY_STREAMS_PARAMETERS \
  1211. CTL_CODE(FILE_DEVICE_VIDEO, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
  1212. typedef struct _VIDEO_QUERY_STREAMS_MODE {
  1213. ULONG ScreenWidth;
  1214. ULONG BitsPerPel;
  1215. ULONG RefreshRate;
  1216. } VIDEO_QUERY_STREAMS_MODE;
  1217. typedef struct _VIDEO_QUERY_STREAMS_PARAMETERS {
  1218. ULONG MinOverlayStretch;
  1219. ULONG FifoValue;
  1220. } VIDEO_QUERY_STREAMS_PARAMETERS;