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.

979 lines
34 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: hw.h
  3. *
  4. * All the hardware specific driver file stuff. Parts are mirrored in
  5. * 'hw.inc'.
  6. *
  7. * Copyright (c) 1992-1995 Microsoft Corporation
  8. *
  9. \**************************************************************************/
  10. #define CP_TRACK DISPDBG((100,"CP access - File(%s) line(%d)", __FILE__, __LINE__))
  11. typedef struct _PDEV PDEV; // Handy forward declaration
  12. //////////////////////////////////////////////////////////////////////
  13. // private IOCTL info - if you touch this, do the same to the miniport
  14. #define IOCTL_VIDEO_GET_VIDEO_CARD_INFO \
  15. CTL_CODE (FILE_DEVICE_VIDEO, 2048, METHOD_BUFFERED, FILE_ANY_ACCESS)
  16. typedef struct _VIDEO_COPROCESSOR_INFORMATION {
  17. ULONG ulChipID; // ET3000, ET4000, W32, W32I, or W32P
  18. ULONG ulRevLevel; // REV_A, REV_B, REV_C, REV_D, REV_UNDEF
  19. ULONG ulVideoMemory; // in bytes
  20. } VIDEO_COPROCESSOR_INFORMATION, *PVIDEO_COPROCESSOR_INFORMATION;
  21. //////////////////////////////////////////////////////////////////////
  22. // The following are reflected in hw.inc. Don't change these
  23. // without changing that file.
  24. typedef enum _CHIP_TYPE {
  25. ET3000 = 1,
  26. ET4000,
  27. W32,
  28. W32I,
  29. W32P,
  30. ET6000
  31. } CHIP_TYPE;
  32. typedef enum _REV_TYPE {
  33. REV_UNDEF = 1,
  34. REV_A,
  35. REV_B,
  36. REV_C,
  37. REV_D,
  38. } REV_TYPE;
  39. //////////////////////////////////////////////////////////////////////
  40. // Ports
  41. #define SEG_SELECT_LO 0x03CD
  42. #define SEG_SELECT_HI 0x03CB
  43. #define CRTC_INDEX 0x03D4
  44. #define CRTC_DATA 0x03D5
  45. #define CRTCB_SPRITE_INDEX 0x217A
  46. #define CRTCB_SPRITE_DATA 0x217B
  47. //////////////////////////////////////////////////////////////////////
  48. // Memory Map
  49. // When we are banked
  50. #define BANKED_MMU_BUFFER_MEMORY_ADDR 0xB8000
  51. #define BANKED_MMU_BUFFER_MEMORY_LEN (0xBE000 - 0xB8000)
  52. #define BANKED_MMU_MEMORY_MAPPED_REGS_ADDR 0xBFF00
  53. #define BANKED_MMU_MEMORY_MAPPED_REGS_LEN (0xC0000 - 0xBFF00)
  54. #define BANKED_MMU_EXTERNAL_MAPPED_REGS_ADDR 0xBE000
  55. #define BANKED_MMU_EXTERNAL_MAPPED_REGS_LEN (0xBF000 - 0xBE000)
  56. #define BANKED_APERTURE_0_OFFSET 0x0000
  57. #define BANKED_APERTURE_1_OFFSET 0x2000
  58. #define BANKED_APERTURE_2_OFFSET 0x4000
  59. // When we are linear
  60. #define MMU_BUFFER_MEMORY_ADDR 0x200000
  61. #define MMU_BUFFER_MEMORY_LEN 0x17FFFF
  62. #define MMU_MEMORY_MAPPED_REGS_ADDR 0x3FFF00
  63. #define MMU_MEMORY_MAPPED_REGS_LEN 0x000100
  64. #define MMU_EXTERNAL_MAPPED_REGS_ADDR 0x3FE000
  65. #define MMU_EXTERNAL_MAPPED_REGS_LEN 0x001000
  66. #define APERTURE_0_OFFSET 0x000000
  67. #define APERTURE_1_OFFSET 0x080000
  68. #define APERTURE_2_OFFSET 0x100000
  69. // Always
  70. #define VGA_MEMORY_ADDR 0xA0000
  71. #define MMU_APERTURE_2_ACL_BIT 0x04
  72. #define MMU_PORT_IO_ADDR 0
  73. #define MMU_PORT_IO_LEN 0x10000
  74. //////////////////////////////////////////////////////////////////////
  75. // Alpha and PowerPC considerations
  76. //
  77. // Both the Alpha and the PowerPC do not guarantee that I/O to
  78. // separate addresses will be executed in order. The Alpha and
  79. // PowerPC differ, however, in that the PowerPC guarantees that
  80. // output to the same address will be executed in order, while the
  81. // Alpha may cache and 'collapse' consecutive output to become only
  82. // one output.
  83. //
  84. // Consequently, we use the following synchronization macros. They
  85. // are relatively expensive in terms of performance, so we try to avoid
  86. // them whereever possible.
  87. //
  88. // CP_EIEIO() 'Ensure In-order Execution of I/O'
  89. // - Used to flush any pending I/O in situations where we wish to
  90. // avoid out-of-order execution of I/O to separate addresses.
  91. //
  92. // CP_MEMORY_BARRIER()
  93. // - Used to flush any pending I/O in situations where we wish to
  94. // avoid out-of-order execution or 'collapsing' of I/O to
  95. // the same address. On the PowerPC, this will be defined as
  96. // a null operation.
  97. #if defined(PPC)
  98. // On PowerPC, CP_MEMORY_BARRIER doesn't do anything.
  99. #define CP_EIEIO() MEMORY_BARRIER()
  100. #define CP_MEMORY_BARRIER()
  101. #else
  102. // On Alpha, CP_EIEIO() is the same thing as a CP_MEMORY_BARRIER().
  103. // On other systems, both CP_EIEIO() and CP_MEMORY_BARRIER() don't
  104. // do anything.
  105. #define CP_EIEIO() MEMORY_BARRIER()
  106. #define CP_MEMORY_BARRIER() MEMORY_BARRIER()
  107. #endif
  108. //////////////////////////////////////////////////////////////////
  109. // Port access macros
  110. #define CP_OUT_DWORD(pjBase, cjOffset, ul)\
  111. {\
  112. CP_TRACK;\
  113. WRITE_PORT_ULONG((BYTE*) pjBase + (cjOffset), (DWORD) (ul));\
  114. CP_EIEIO();\
  115. }
  116. #define CP_OUT_WORD(pjBase, cjOffset, w)\
  117. {\
  118. CP_TRACK;\
  119. WRITE_PORT_USHORT((BYTE*) pjBase + (cjOffset), (WORD) (w));\
  120. CP_EIEIO();\
  121. }
  122. #define CP_OUT_BYTE(pjBase, cjOffset, j)\
  123. {\
  124. CP_TRACK;\
  125. WRITE_PORT_UCHAR((BYTE*) pjBase + (cjOffset), (BYTE) (j));\
  126. CP_EIEIO();\
  127. }
  128. #define CP_IN_DWORD(pjBase, cjOffset)\
  129. (\
  130. CP_TRACK,\
  131. READ_PORT_ULONG((BYTE*) pjBase + (cjOffset))\
  132. )
  133. #define CP_IN_WORD(pjBase, cjOffset)\
  134. (\
  135. CP_TRACK,\
  136. READ_PORT_USHORT((BYTE*) pjBase + (cjOffset))\
  137. )
  138. #define CP_IN_BYTE(pjBase, cjOffset)\
  139. (\
  140. CP_TRACK,\
  141. READ_PORT_UCHAR((BYTE*) pjBase + (cjOffset))\
  142. )
  143. //////////////////////////////////////////////////////////////////
  144. // Memory mapped register access macros
  145. #define CP_WRITE_DWORD(pjBase, cjOffset, ul)\
  146. CP_TRACK,\
  147. WRITE_REGISTER_ULONG((BYTE*) pjBase + (cjOffset), (DWORD) (ul))
  148. #define CP_WRITE_WORD(pjBase, cjOffset, w)\
  149. CP_TRACK,\
  150. WRITE_REGISTER_USHORT((BYTE*) pjBase + (cjOffset), (WORD) (w))
  151. #define CP_WRITE_BYTE(pjBase, cjOffset, j)\
  152. CP_TRACK,\
  153. WRITE_REGISTER_UCHAR((BYTE*) pjBase + (cjOffset), (BYTE) (j))
  154. #define CP_READ_DWORD(pjBase, cjOffset)\
  155. (\
  156. CP_TRACK,\
  157. READ_REGISTER_ULONG((BYTE*) pjBase + (cjOffset))\
  158. )
  159. #define CP_READ_WORD(pjBase, cjOffset)\
  160. (\
  161. CP_TRACK,\
  162. READ_REGISTER_USHORT((BYTE*) pjBase + (cjOffset))\
  163. )
  164. #define CP_READ_BYTE(pjBase, cjOffset)\
  165. (\
  166. CP_TRACK,\
  167. READ_REGISTER_UCHAR((BYTE*) pjBase + (cjOffset))\
  168. )
  169. //////////////////////////////////////////////////////////
  170. // W32 ACL register access macros
  171. //////////////////////////////////////////////////////////
  172. // Reads
  173. #define CP_ACL_STAT(ppdev, pjBase)\
  174. CP_READ_BYTE(pjBase, OFFSET_jAclStatus)
  175. //////////////////////////////////////////////////////////
  176. // Writes
  177. #define CP_WRITE_MMU_DWORD(ppdev, mmu, offset, x)\
  178. {\
  179. CP_WRITE_DWORD((ppdev->pjMmu##mmu), offset, (x));\
  180. CP_EIEIO();\
  181. }
  182. #define CP_WRITE_MMU_WORD(ppdev, mmu, offset, x)\
  183. {\
  184. CP_WRITE_WORD((ppdev->pjMmu##mmu), offset, (x));\
  185. CP_EIEIO();\
  186. }
  187. #define CP_WRITE_MMU_BYTE(ppdev, mmu, offset, x)\
  188. {\
  189. CP_WRITE_BYTE((ppdev->pjMmu##mmu), offset, (x));\
  190. CP_EIEIO();\
  191. }
  192. #define CP_MMU_BP0(ppdev, pjBase, x)\
  193. {\
  194. CP_WRITE_DWORD(pjBase, OFFSET_ulMmuBasePtr0, (x));\
  195. CP_EIEIO();\
  196. }
  197. #define CP_MMU_BP1(ppdev, pjBase, x)\
  198. {\
  199. CP_WRITE_DWORD(pjBase, OFFSET_ulMmuBasePtr1, (x));\
  200. CP_EIEIO();\
  201. }
  202. #define CP_MMU_BP2(ppdev, pjBase, x)\
  203. {\
  204. CP_WRITE_DWORD(pjBase, OFFSET_ulMmuBasePtr2, (x));\
  205. CP_EIEIO();\
  206. }
  207. #define CP_MMU_CTRL(ppdev, pjBase, x)\
  208. {\
  209. CP_WRITE_BYTE(pjBase, OFFSET_jMmuCtrl, (x));\
  210. CP_EIEIO();\
  211. }
  212. #define CP_STATE(ppdev, pjBase, x)\
  213. {\
  214. CP_WRITE_BYTE(pjBase, OFFSET_jOperationState, (x));\
  215. CP_EIEIO();\
  216. }
  217. #define CP_SYNC_ENABLE(ppdev, pjBase, x)\
  218. {\
  219. CP_WRITE_BYTE(pjBase, OFFSET_jSyncEnable, (x));\
  220. CP_EIEIO();\
  221. }
  222. #define CP_PAT_ADDR(ppdev, pjBase, x)\
  223. {\
  224. CP_WRITE_DWORD(pjBase, OFFSET_ulPatAddr, (x));\
  225. CP_EIEIO();\
  226. }
  227. #define CP_SRC_ADDR(ppdev, pjBase, x)\
  228. {\
  229. CP_WRITE_DWORD(pjBase, OFFSET_ulSrcAddr, (x));\
  230. CP_EIEIO();\
  231. }
  232. #define CP_DST_ADDR(ppdev, pjBase, x)\
  233. {\
  234. CP_WRITE_DWORD(pjBase, OFFSET_ulDstAddr, (x));\
  235. CP_EIEIO();\
  236. }
  237. #define CP_MIX_ADDR(ppdev, pjBase, x)\
  238. {\
  239. CP_WRITE_DWORD(pjBase, OFFSET_ulMixAddr, (x));\
  240. CP_EIEIO();\
  241. }
  242. #define CP_PAT_Y_OFFSET(ppdev, pjBase, x)\
  243. {\
  244. CP_WRITE_WORD(pjBase, OFFSET_wPatYOffset, (x));\
  245. CP_EIEIO();\
  246. }
  247. #define CP_SRC_Y_OFFSET(ppdev, pjBase, x)\
  248. {\
  249. CP_WRITE_WORD(pjBase, OFFSET_wSrcYOffset, (x));\
  250. CP_EIEIO();\
  251. }
  252. #define CP_DST_Y_OFFSET(ppdev, pjBase, x)\
  253. {\
  254. CP_WRITE_WORD(pjBase, OFFSET_wDstYOffset, (x));\
  255. CP_EIEIO();\
  256. }
  257. #define CP_MIX_Y_OFFSET(ppdev, pjBase, x)\
  258. {\
  259. CP_WRITE_WORD(pjBase, OFFSET_wMixYOffset, (x));\
  260. CP_EIEIO();\
  261. }
  262. #define CP_PEL_DEPTH(ppdev, pjBase, x)\
  263. {\
  264. CP_WRITE_BYTE(pjBase, OFFSET_jPixelDepthW32P, (x));\
  265. CP_EIEIO();\
  266. }
  267. #define CP_BUS_SIZE(ppdev, pjBase, x)\
  268. {\
  269. CP_WRITE_BYTE(pjBase, OFFSET_jBusSizeW32, (x));\
  270. CP_EIEIO();\
  271. }
  272. #define CP_XY_DIR(ppdev, pjBase, x)\
  273. {\
  274. CP_WRITE_BYTE(pjBase, OFFSET_jXYDir, (x));\
  275. CP_EIEIO();\
  276. }
  277. #define CP_PAT_WRAP(ppdev, pjBase, x)\
  278. {\
  279. CP_WRITE_BYTE(pjBase, OFFSET_jPatWrap, (x));\
  280. CP_EIEIO();\
  281. }
  282. #define CP_XFER_DISABLE(ppdev, pjBase, x)\
  283. {\
  284. CP_WRITE_BYTE(pjBase, OFFSET_jXferDisable, (x));\
  285. CP_EIEIO();\
  286. }
  287. #define CP_SRC_WRAP(ppdev, pjBase, x)\
  288. {\
  289. CP_WRITE_BYTE(pjBase, OFFSET_jSrcWrap, (x));\
  290. CP_EIEIO();\
  291. }
  292. #define CP_XCNT(ppdev, pjBase, x)\
  293. {\
  294. CP_WRITE_WORD(pjBase, OFFSET_wXCnt, (x));\
  295. CP_EIEIO();\
  296. }
  297. #define CP_YCNT(ppdev, pjBase, x)\
  298. {\
  299. CP_WRITE_WORD(pjBase, OFFSET_wYCnt, (x));\
  300. CP_EIEIO();\
  301. }
  302. #define CP_ROUTING_CTRL(ppdev, pjBase, x)\
  303. {\
  304. CP_WRITE_BYTE(pjBase, OFFSET_jRoutCtrl, (x));\
  305. CP_EIEIO();\
  306. }
  307. #define CP_RELOAD_CTRL(ppdev, pjBase, x)\
  308. {\
  309. CP_WRITE_BYTE(pjBase, OFFSET_jReloadCtrlW32, (x));\
  310. CP_EIEIO();\
  311. }
  312. #define CP_BK_ROP(ppdev, pjBase, x)\
  313. {\
  314. CP_WRITE_BYTE(pjBase, OFFSET_jBkRop, (x));\
  315. CP_EIEIO();\
  316. }
  317. #define CP_FG_ROP(ppdev, pjBase, x)\
  318. {\
  319. CP_WRITE_BYTE(pjBase, OFFSET_jFgRop, (x));\
  320. CP_EIEIO();\
  321. }
  322. #define CP_ERR_TERM(ppdev, pjBase, x)\
  323. {\
  324. CP_WRITE_WORD(pjBase, OFFSET_wErrTerm, (x));\
  325. CP_EIEIO();\
  326. }
  327. #define CP_DELTA_MINOR(ppdev, pjBase, x)\
  328. {\
  329. CP_WRITE_WORD(pjBase, OFFSET_wDeltaMinor, (x));\
  330. CP_EIEIO();\
  331. }
  332. #define CP_DELTA_MAJOR(ppdev, pjBase, x)\
  333. {\
  334. CP_WRITE_WORD(pjBase, OFFSET_wDeltaMajor, (x));\
  335. CP_EIEIO();\
  336. }
  337. #define CP_X_POS_W32P(ppdev, pjBase, x)\
  338. {\
  339. CP_WRITE_WORD(pjBase, OFFSET_wXPosW32P, (x));\
  340. CP_EIEIO();\
  341. }
  342. #define CP_Y_POS_W32P(ppdev, pjBase, x)\
  343. {\
  344. CP_WRITE_WORD(pjBase, OFFSET_wYPosW32P, (x));\
  345. CP_EIEIO();\
  346. }
  347. #define CP_X_POS_W32(ppdev, pjBase, x)\
  348. {\
  349. CP_WRITE_WORD(pjBase, OFFSET_wXPosW32, (x));\
  350. CP_EIEIO();\
  351. }
  352. #define CP_Y_POS_W32(ppdev, pjBase, x)\
  353. {\
  354. CP_WRITE_WORD(pjBase, OFFSET_wYPosW32, (x));\
  355. CP_EIEIO();\
  356. }
  357. #define CP_ACL_CONFIG(ppdev, pjBase, x)\
  358. {\
  359. CP_WRITE_WORD(pjBase, OFFSET_jConfig, (x));\
  360. CP_EIEIO();\
  361. }
  362. #define CP_ACL_POWER(ppdev, pjBase, x)\
  363. {\
  364. CP_WRITE_WORD(pjBase, OFFSET_jPowerCtrl, (x));\
  365. CP_EIEIO();\
  366. }
  367. #define CP_ACL_STEP(ppdev, pjBase, x)\
  368. {\
  369. CP_WRITE_WORD(pjBase, OFFSET_jSteppingCtrl, (x));\
  370. CP_EIEIO();\
  371. }
  372. //////////////////////////////////////////////////////////
  373. // W32 video coprocessor control register offsets
  374. #define OFFSET_ulMmuBasePtr0 0x00
  375. #define OFFSET_ulMmuBasePtr1 0x04
  376. #define OFFSET_ulMmuBasePtr2 0x08
  377. #define OFFSET_jMmuCtrl 0x13
  378. #define OFFSET_jSuspendTerminate 0x30
  379. #define OFFSET_jOperationState 0x31
  380. #define OFFSET_jSyncEnable 0x32
  381. #define OFFSET_jConfig 0x32 // ET6000
  382. #define OFFSET_jIntrMask 0x34
  383. #define OFFSET_jIntrStatus 0x35
  384. #define OFFSET_jAclStatus 0x36
  385. #define OFFSET_jPowerCtrl 0x37 // ET6000
  386. #define OFFSET_wXPosW32P 0x38 // W32p+ only
  387. #define OFFSET_wYPosW32P 0x3A // W32p+ only
  388. #define OFFSET_ulPatAddr 0x80
  389. #define OFFSET_ulSrcAddr 0x84
  390. #define OFFSET_wPatYOffset 0x88
  391. #define OFFSET_wSrcYOffset 0x8A
  392. #define OFFSET_wDstYOffset 0x8C
  393. #define OFFSET_jBusSizeW32 0x8E // W32 and W32i only
  394. #define OFFSET_jPixelDepthW32P 0x8E // W32p+ only
  395. #define OFFSET_jXYDir 0x8F
  396. #define OFFSET_jPatWrap 0x90
  397. #define OFFSET_jXferDisable 0x91 // ET6000
  398. #define OFFSET_jSrcWrap 0x92
  399. #define OFFSET_jSecondaryEdge 0x93 // ET6000
  400. #define OFFSET_wXPosW32 0x94 // W32 and W32i only
  401. #define OFFSET_wYPosW32 0x96 // W32 and W32i only
  402. #define OFFSET_wXCnt 0x98
  403. #define OFFSET_wYCnt 0x9A
  404. #define OFFSET_jRoutCtrl 0x9C
  405. #define OFFSET_jMixCtrl 0x9C // ET6000
  406. #define OFFSET_jReloadCtrlW32 0x9D // W32 and W32i only
  407. #define OFFSET_jSteppingCtrl 0x9D // ET6000
  408. #define OFFSET_jBkRop 0x9E
  409. #define OFFSET_jFgRop 0x9F
  410. #define OFFSET_ulDstAddr 0xA0
  411. #define OFFSET_ulMixAddr 0xA4
  412. #define OFFSET_wMixYOffset 0xA8
  413. #define OFFSET_wErrTerm 0xAA
  414. #define OFFSET_wDeltaMinor 0xAC
  415. #define OFFSET_wDeltaMajor 0xAE
  416. #define OFFSET_wSecErrTerm 0xB2 // ET6000
  417. #define OFFSET_wSecDeltaMinor 0xB4 // ET6000
  418. #define OFFSET_wSecDeltaMajor 0xB6 // ET6000
  419. typedef struct {
  420. ULONG ulVgaMemAddr;
  421. ULONG ulPhysMemAddr;
  422. ULONG ulPhysMemLen;
  423. ULONG ulPhysRegsAddr;
  424. ULONG ulPhysRegsLen;
  425. ULONG ulPhysPortsAddr;
  426. ULONG ulPhysPortsLen;
  427. ULONG ulPhysExtrnMapRegAddr;
  428. ULONG ulPhysExtrnMapRegLen;
  429. PVOID pvMemoryBufferVirtualAddr;
  430. PVOID pvMemoryMappedRegisterVirtualAddr;
  431. PVOID pvPortsVirtualAddr;
  432. PVOID pvExternalRegistersVirtualAddr;
  433. } W32MMUINFO, *PW32MMUINFO;
  434. //////////////////////////////////////////////////////////
  435. // Virtual bus size
  436. #define VIRTUAL_BUS_8_BIT 0x00
  437. #define VIRTUAL_BUS_16_BIT 0x01
  438. #define VIRTUAL_BUS_32_BIT 0x02
  439. #define HW_PEL_DEPTH_8BPP 0x00
  440. #define HW_PEL_DEPTH_16BPP 0x10
  441. #define HW_PEL_DEPTH_24BPP 0x20
  442. #define HW_PEL_DEPTH_32BPP 0x30
  443. //////////////////////////////////////////////////////////
  444. // Routing control
  445. #define CPU_SOURCE_DATA 0x01
  446. #define CPU_MIX_DATA 0x02
  447. #define CPU_X_COUNT 0x04
  448. #define CPU_Y_COUNT 0x05
  449. //////////////////////////////////////////////////////////
  450. // X/Y direction
  451. #define BOTTOM_TO_TOP 0x02
  452. #define RIGHT_TO_LEFT 0x01
  453. #define TBLR 0x00
  454. #define TBRL 0x01
  455. #define BTLR 0x02
  456. #define BTRL 0x03
  457. //////////////////////////////////////////////////////////
  458. // Pattern/Source wrap
  459. #define NO_PATTERN_WRAP 0x77
  460. #define SOLID_COLOR_PATTERN_WRAP 0x02
  461. #define SOLID_COLOR_PATTERN_OFFSET 0x04
  462. #define SOLID_COLOR_PATTERN_WRAP_24BPP 0x0A
  463. #define SOLID_COLOR_PATTERN_OFFSET_24BPP 0x03
  464. #define PATTERN_WRAP_8x8 0x33
  465. #define PATTERN_WRAP_16x8 0x34
  466. #define PATTERN_WRAP_32x8 0x35
  467. #define PATTERN_WIDTH 0x08
  468. #define PATTERN_HEIGHT 0x08
  469. #define PATTERN_SIZE (PATTERN_WIDTH*PATTERN_HEIGHT)
  470. #define PATTERN_OFFSET PATTERN_WIDTH
  471. //////////////////////////////////////////////////////////
  472. // W32 H/W pointer (sprite) data.
  473. typedef struct {
  474. POINTL ptlHot,
  475. ptlLast;
  476. SIZEL szlPointer;
  477. FLONG fl;
  478. } W32SPRITEDATA, *PW32SPRITEDATA;
  479. #define POINTER_DISABLED 0X01
  480. //////////////////////////////////////////////////////////
  481. // Some handy clipping control structures.
  482. typedef struct {
  483. ULONG c;
  484. RECTL arcl[8];
  485. } ENUMRECTS8, *PENUMRECTS8;
  486. ////////////////////////////////////////////////////////////////////////////
  487. // The following will spin until there is room in the ACL command queue for
  488. // another blt command.
  489. #define WAIT_FOR_EMPTY_ACL_QUEUE(ppdev, pjBase) \
  490. { \
  491. while (CP_ACL_STAT(ppdev, pjBase) & 0x01); \
  492. }
  493. ////////////////////////////////////////////////////////////////////////////
  494. // The following will spin until the ACL has processed all queued commands.
  495. #define WAIT_FOR_IDLE_ACL(ppdev, pjBase) \
  496. { \
  497. while (CP_ACL_STAT(ppdev, pjBase) & 0x02); \
  498. }
  499. ////////////////////////////////////////////////////////////////////////////
  500. // The following will return TRUE if the FIFO is full.
  501. #define FIFO_BUSY(ppdev, pjBase) \
  502. (CP_ACL_STAT(ppdev, pjBase) & 0x01) \
  503. ////////////////////////////////////////////////////////////////////////////
  504. // The following will return TRUE if the ACL is busy at the moment.
  505. #define IS_BUSY(ppdev, pjBase) \
  506. (CP_ACL_STAT(ppdev, pjBase) & 0x02) \
  507. ////////////////////////////////////////////////////////////////////////////
  508. // The following will spin until the ACL starts processing a command.
  509. #define WAIT_FOR_BUSY_ACL(ppdev, pjBase) \
  510. { \
  511. while (!(CP_ACL_STAT(ppdev, pjBase) & 0x02)); \
  512. }
  513. ////////////////////////////////////////////////////////////////////////////
  514. // The following will spin until the vertical retrace occurs.
  515. #define WAIT_FOR_VERTICAL_RETRACE \
  516. { \
  517. while ( (INP(0x3DA) & 0x08)); \
  518. while (!(INP(0x3DA) & 0x08)); \
  519. } \
  520. ////////////////////////////////////////////////////////////////////////////
  521. // The following synchronize framebuffer access with the accelerator
  522. #define START_DIRECT_ACCESS(ppdev, pjBase)\
  523. {\
  524. WAIT_FOR_IDLE_ACL(ppdev, pjBase);\
  525. }
  526. #define END_DIRECT_ACCESS(ppdev, pjBase)\
  527. {\
  528. CP_EIEIO();\
  529. }
  530. //////////////////////////////////////////////////////////
  531. // Made a change to check for >= W32P so that the ET6000 could be handled
  532. // correctly by this macro. It is more efficient than checking for both
  533. // chip types. Keep in mind that this macro may have to be modified to
  534. // properly handle future chips.
  535. #define SET_DEST_ADDR(ppdev, addr) \
  536. { \
  537. BYTE* pjBase = ppdev->pjBase; \
  538. \
  539. if (ppdev->ulChipID >= W32P) \
  540. { \
  541. CP_DST_ADDR(ppdev, pjBase, (addr)+ppdev->xyOffset); \
  542. } \
  543. else \
  544. { \
  545. CP_MMU_BP2(ppdev, pjBase, ((addr)+ppdev->xyOffset)); \
  546. } \
  547. }
  548. #define SET_DEST_ADDR_ABS(ppdev, addr) \
  549. { \
  550. BYTE* pjBase = ppdev->pjBase; \
  551. \
  552. if (ppdev->ulChipID >= W32P) \
  553. { \
  554. CP_DST_ADDR(ppdev, pjBase, (addr)); \
  555. } \
  556. else \
  557. { \
  558. CP_MMU_BP2(ppdev, pjBase, (addr)); \
  559. } \
  560. }
  561. #define START_ACL(ppdev) \
  562. { \
  563. if (ppdev->ulChipID < W32P) \
  564. { \
  565. CP_WRITE_MMU_BYTE(ppdev, 2, 0, 0); \
  566. } \
  567. }
  568. #define SET_FG_COLOR(ppdev,color) \
  569. { \
  570. BYTE* pjBase = ppdev->pjBase; \
  571. LONG cBpp = ppdev->cBpp; \
  572. \
  573. WAIT_FOR_EMPTY_ACL_QUEUE(ppdev, pjBase); \
  574. CP_PAT_WRAP(ppdev, pjBase, SOLID_COLOR_PATTERN_WRAP); \
  575. CP_PAT_Y_OFFSET(ppdev, pjBase, (SOLID_COLOR_PATTERN_OFFSET - 1)); \
  576. CP_PAT_ADDR(ppdev, pjBase, ppdev->ulSolidColorOffset); \
  577. \
  578. { \
  579. ULONG ulSolidColor; \
  580. \
  581. WAIT_FOR_IDLE_ACL(ppdev, pjBase); \
  582. CP_MMU_BP0(ppdev, pjBase, ppdev->ulSolidColorOffset); \
  583. \
  584. ulSolidColor = color; \
  585. \
  586. if (cBpp == 1) \
  587. { \
  588. ulSolidColor |= ulSolidColor << 8; \
  589. } \
  590. if (cBpp <= 2) \
  591. { \
  592. ulSolidColor |= ulSolidColor << 16; \
  593. } \
  594. \
  595. CP_WRITE_MMU_DWORD(ppdev, 0, 0, ulSolidColor); \
  596. } \
  597. }
  598. //////////////////////////////////////////////////////////
  599. // CRTCB/Sprite defines port definitions.
  600. #define CRTCB_SPRITE_HORZ_POSITION_LOW 0xE0
  601. #define CRTCB_SPRITE_HORZ_POSITION_HIGH 0xE1
  602. #define CRTCB_WIDTH_LOW_SPRITE_HORZ_PRESET 0xE2
  603. #define CRTCB_WIDTH_HIGH 0xE3
  604. #define CRTCB_SPRITE_VERT_POSITION_LOW 0xE4
  605. #define CRTCB_SPRITE_VERT_POSITION_HIGH 0xE5
  606. #define CRTCB_HEIGHT_LOW_SPRITE_VERT_PRESET 0xE6
  607. #define CRTCB_HEIGHT_HIGH 0xE7
  608. #define CRTCB_SPRITE_START_ADDR_LOW 0xE8
  609. #define CRTCB_SPRITE_START_ADDR_MEDIUM 0xE9
  610. #define CRTCB_SPRITE_START_ADDR_HIGH 0xEA
  611. #define CRTCB_SPRITE_ROW_OFFSET_LOW 0xEB
  612. #define CRTCB_SPRITE_ROW_OFFSET_HIGH 0xEC
  613. #define CRTCB_PIXEL_PANNING 0xED
  614. #define CRTCB_COLOR_DEPTH 0xEE
  615. #define CRTCB_SPRITE_CONTROL 0xEF
  616. // ET6000 specific sprite equates. These are offsets into the
  617. // PCI configuration space.
  618. //
  619. #define ET6K_SPRITE_HORZ_PRESET 0x82
  620. #define ET6K_SPRITE_VERT_PRESET 0x83
  621. #define ET6K_SPRITE_HORZ_POS_LOW 0x84
  622. #define ET6K_SPRITE_HORZ_POS_HIGH 0x85
  623. #define ET6K_SPRITE_VERT_POS_LOW 0x86
  624. #define ET6K_SPRITE_VERT_POS_HIGH 0x87
  625. #define ET6K_SPRITE_ADDR_LOW 0x0F
  626. #define ET6K_SPRITE_ADDR_HIGH 0x0E
  627. #define ET6K_SPRITE_ENABLE_PORT 0x46
  628. #define ET6K_SPRITE_ENABLE_BIT 0x01
  629. //////////////////////////////////////////////////////////
  630. // The following enable is documented as part of the IMA port.
  631. // It's true, the facts are stranger than fiction.
  632. #define CRTCB_SPRITE_ENABLE_PORT 0xF7
  633. #define CRTCB_SPRITE_ENABLE_BIT 0x80
  634. //////////////////////////////////////////////////////////
  635. // Some handy macros for sprite manipulation
  636. #define SPRITE_BUFFER_SIZE 0x4400
  637. //////////////////////////////////////////////////////////
  638. // There are bugs in the W32 that require enabling or
  639. // disabling the cursor during vertical retrace.
  640. #define ENABLE_SPRITE(ppdev) \
  641. { \
  642. BYTE byte; \
  643. ppdev->W32SpriteData.fl &= ~POINTER_DISABLED; \
  644. if (ppdev->ulChipID != ET6000) \
  645. { \
  646. if (ppdev->ulChipID == W32) \
  647. { \
  648. WAIT_FOR_VERTICAL_RETRACE; \
  649. } \
  650. OUTP(CRTCB_SPRITE_INDEX, CRTCB_SPRITE_ENABLE_PORT); \
  651. byte = INP(CRTCB_SPRITE_DATA); \
  652. byte |= CRTCB_SPRITE_ENABLE_BIT; \
  653. OUTP(CRTCB_SPRITE_DATA, byte); \
  654. }\
  655. else \
  656. { \
  657. byte = INP(ppdev->PCIConfigSpaceAddr + ET6K_SPRITE_ENABLE_PORT);\
  658. byte |= ET6K_SPRITE_ENABLE_BIT; \
  659. OUTP(ppdev->PCIConfigSpaceAddr + ET6K_SPRITE_ENABLE_PORT, byte);\
  660. } \
  661. }
  662. #define DISABLE_SPRITE(ppdev) \
  663. { \
  664. BYTE byte; \
  665. ppdev->W32SpriteData.fl |= POINTER_DISABLED; \
  666. if (ppdev->ulChipID != ET6000) \
  667. { \
  668. if (ppdev->ulChipID == W32) \
  669. { \
  670. WAIT_FOR_VERTICAL_RETRACE; \
  671. } \
  672. OUTP(CRTCB_SPRITE_INDEX, CRTCB_SPRITE_ENABLE_PORT); \
  673. byte = INP(CRTCB_SPRITE_DATA); \
  674. byte &= ~CRTCB_SPRITE_ENABLE_BIT; \
  675. OUTP(CRTCB_SPRITE_DATA, byte); \
  676. }\
  677. else \
  678. { \
  679. byte = INP(ppdev->PCIConfigSpaceAddr + ET6K_SPRITE_ENABLE_PORT);\
  680. byte &= ~ET6K_SPRITE_ENABLE_BIT; \
  681. OUTP(ppdev->PCIConfigSpaceAddr + ET6K_SPRITE_ENABLE_PORT, byte);\
  682. } \
  683. }
  684. #define SET_HORZ_POSITION(val) \
  685. { \
  686. OUTP(CRTCB_SPRITE_INDEX, CRTCB_SPRITE_HORZ_POSITION_LOW); \
  687. OUTP(CRTCB_SPRITE_DATA, LOBYTE(val)); \
  688. OUTP(CRTCB_SPRITE_INDEX, CRTCB_SPRITE_HORZ_POSITION_HIGH); \
  689. OUTP(CRTCB_SPRITE_DATA, HIBYTE(val)); \
  690. }
  691. #define SET_VERT_POSITION(val) \
  692. { \
  693. OUTP(CRTCB_SPRITE_INDEX, CRTCB_SPRITE_VERT_POSITION_LOW); \
  694. OUTP(CRTCB_SPRITE_DATA, LOBYTE(val)); \
  695. OUTP(CRTCB_SPRITE_INDEX, CRTCB_SPRITE_VERT_POSITION_HIGH); \
  696. OUTP(CRTCB_SPRITE_DATA, HIBYTE(val)); \
  697. }
  698. #define SET_HORZ_PRESET(val) \
  699. { \
  700. OUTP(CRTCB_SPRITE_INDEX, CRTCB_WIDTH_LOW_SPRITE_HORZ_PRESET); \
  701. OUTP(CRTCB_SPRITE_DATA, LOBYTE(val)); \
  702. OUTP(CRTCB_SPRITE_INDEX, CRTCB_WIDTH_HIGH); \
  703. OUTP(CRTCB_SPRITE_DATA, 0); \
  704. }
  705. #define SET_VERT_PRESET(val) \
  706. { \
  707. OUTP(CRTCB_SPRITE_INDEX, CRTCB_HEIGHT_LOW_SPRITE_VERT_PRESET); \
  708. OUTP(CRTCB_SPRITE_DATA, LOBYTE(val)); \
  709. OUTP(CRTCB_SPRITE_INDEX, CRTCB_HEIGHT_HIGH); \
  710. OUTP(CRTCB_SPRITE_DATA, 0); \
  711. }
  712. #define SET_SPRITE_START_ADDR(val) \
  713. { \
  714. ULONG ulAddr; \
  715. ulAddr = val >> 2; \
  716. OUTP(CRTCB_SPRITE_INDEX, CRTCB_SPRITE_START_ADDR_LOW); \
  717. OUTP(CRTCB_SPRITE_DATA, LOWORD(LOBYTE(ulAddr))); \
  718. OUTP(CRTCB_SPRITE_INDEX, CRTCB_SPRITE_START_ADDR_MEDIUM); \
  719. OUTP(CRTCB_SPRITE_DATA, LOWORD(HIBYTE(ulAddr))); \
  720. OUTP(CRTCB_SPRITE_INDEX, CRTCB_SPRITE_START_ADDR_HIGH); \
  721. OUTP(CRTCB_SPRITE_DATA, LOBYTE(HIWORD(ulAddr))); \
  722. }
  723. #define SET_SPRITE_ROW_OFFSET \
  724. { \
  725. OUTP(CRTCB_SPRITE_INDEX, CRTCB_SPRITE_ROW_OFFSET_LOW); \
  726. OUTP(CRTCB_SPRITE_DATA, 2); \
  727. OUTP(CRTCB_SPRITE_INDEX, CRTCB_SPRITE_ROW_OFFSET_HIGH); \
  728. OUTP(CRTCB_SPRITE_DATA, 0); \
  729. }
  730. #define ET6K_SPRITE_HORZ_POSITION(ppdev, x) \
  731. { \
  732. OUTP(ppdev->PCIConfigSpaceAddr + ET6K_SPRITE_HORZ_POS_LOW, (x & 0x00FF));\
  733. OUTP(ppdev->PCIConfigSpaceAddr + ET6K_SPRITE_HORZ_POS_HIGH, (x >> 8));\
  734. }
  735. #define ET6K_SPRITE_VERT_POSITION(ppdev, y) \
  736. { \
  737. OUTP(ppdev->PCIConfigSpaceAddr + ET6K_SPRITE_VERT_POS_LOW, (y & 0x00FF));\
  738. OUTP(ppdev->PCIConfigSpaceAddr + ET6K_SPRITE_VERT_POS_HIGH, (y >> 8));\
  739. }
  740. #define ET6K_HORZ_PRESET(ppdev, x); \
  741. { \
  742. OUTP(ppdev->PCIConfigSpaceAddr + ET6K_SPRITE_HORZ_PRESET, (x));\
  743. }
  744. #define ET6K_VERT_PRESET(ppdev, y) \
  745. { \
  746. OUTP(ppdev->PCIConfigSpaceAddr + ET6K_SPRITE_VERT_PRESET, (y));\
  747. }
  748. //
  749. // The ET6000 sprite start address is specified in DWORDS. We have a buffer
  750. // of 256 dwords at the end of video memory which contains the sprite data.
  751. // Since this aligns us to a 1K boundary, we can be sure that by simply
  752. // discarding the lower 10 bits of the address that we won't be losing
  753. // anything.
  754. //
  755. #define ET6K_SPRITE_START_ADDR(ppdev, addr) \
  756. { \
  757. OUTP(CRTC_INDEX, ET6K_SPRITE_ADDR_HIGH); \
  758. OUTP(CRTC_DATA, ((addr >> 18) & 0x0FF)); \
  759. OUTP(CRTC_INDEX, ET6K_SPRITE_ADDR_LOW); \
  760. OUTP(CRTC_DATA, ((addr >> 10) & 0x0FF)); \
  761. }
  762. #define ET6K_SPRITE_COLOR(ppdev, color) \
  763. { \
  764. OUTP(ppdev->PCIConfigSpaceAddr + 0x67, 9); \
  765. OUTP(ppdev->PCIConfigSpaceAddr + 0x69, color & 0x00FF); \
  766. OUTP(ppdev->PCIConfigSpaceAddr + 0x69, color >> 8); \
  767. }
  768. ////////////////////////////////////////////////////////////////////////
  769. // Chip equates
  770. #define STATUS_1 0x03DA
  771. #define VSY_NOT 0x0008
  772. #define ENABLE_KEY(ppdev) \
  773. { \
  774. CP_OUT_BYTE(ppdev->pjPorts,(0x03D8),(0x00)); \
  775. CP_OUT_BYTE(ppdev->pjPorts,(0x03BF),(0x01)); \
  776. }
  777. #define DISABLE_KEY(ppdev) \
  778. { \
  779. CP_OUT_BYTE(ppdev->pjPorts,(0x03BF),(0x03)); \
  780. CP_OUT_BYTE(ppdev->pjPorts,(0x03D8),(0xa0)); \
  781. }
  782. #define OUTPW(p, v) CP_OUT_WORD(ppdev->pjPorts,(p),(v))
  783. #define OUTP(p, v) CP_OUT_BYTE(ppdev->pjPorts,(p),(v))
  784. #define INPW(p) CP_IN_WORD(ppdev->pjPorts,(p))
  785. #define INP(p) CP_IN_BYTE(ppdev->pjPorts,(p))
  786. //////////////////////////////////////////////////////////
  787. // Rop definitions for the hardware
  788. #define R3_SRCCOPY 0xCC /* dest = source */
  789. #define R3_SRCPAINT 0xEE /* dest = source OR dest */
  790. #define R3_SRCAND 0x88 /* dest = source AND dest */
  791. #define R3_SRCINVERT 0x66 /* dest = source XOR dest */
  792. #define R3_SRCERASE 0x44 /* dest = source AND (NOT dest ) */
  793. #define R3_NOTSRCCOPY 0x33 /* dest = (NOT source) */
  794. #define R3_NOTSRCERASE 0x11 /* dest = (NOT src) AND (NOT dest) */
  795. #define R3_MERGECOPY 0xC0 /* dest = (source AND pattern) */
  796. #define R3_MERGEPAINT 0xBB /* dest = (NOT source) OR dest */
  797. #define R3_PATCOPY 0xF0 /* dest = pattern */
  798. #define R3_PATPAINT 0xFB /* dest = DPSnoo */
  799. #define R3_PATINVERT 0x5A /* dest = pattern XOR dest */
  800. #define R3_DSTINVERT 0x55 /* dest = (NOT dest) */
  801. #define R3_BLACKNESS 0x00 /* dest = BLACK */
  802. #define R3_WHITENESS 0xFF /* dest = WHITE */
  803. #define R4_SRCCOPY 0xCCCC /* dest = source */
  804. #define R4_SRCPAINT 0xEEEE /* dest = source OR dest */
  805. #define R4_SRCAND 0x8888 /* dest = source AND dest */
  806. #define R4_SRCINVERT 0x6666 /* dest = source XOR dest */
  807. #define R4_SRCERASE 0x4444 /* dest = source AND (NOT dest ) */
  808. #define R4_NOTSRCCOPY 0x3333 /* dest = (NOT source) */
  809. #define R4_NOTSRCERASE 0x1111 /* dest = (NOT src) AND (NOT dest) */
  810. #define R4_MERGECOPY 0xC0C0 /* dest = (source AND pattern) */
  811. #define R4_MERGEPAINT 0xBBBB /* dest = (NOT source) OR dest */
  812. #define R4_PATCOPY 0xF0F0 /* dest = pattern */
  813. #define R4_PATPAINT 0xFBFB /* dest = DPSnoo */
  814. #define R4_PATINVERT 0x5A5A /* dest = pattern XOR dest */
  815. #define R4_DSTINVERT 0x5555 /* dest = (NOT dest) */
  816. #define R4_BLACKNESS 0x0000 /* dest = BLACK */
  817. #define R4_WHITENESS 0xFFFF /* dest = WHITE */
  818. #define R3_NOP 0xAA /* dest = dest */
  819. #define R4_XPAR_EXPAND 0xCCAA /* dest = source (where src is 1) */