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.

752 lines
16 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. vgadata.c
  5. Abstract:
  6. This module contains all the global data used by the VGA driver.
  7. Environment:
  8. Kernel mode
  9. Revision History:
  10. --*/
  11. #include "dderror.h"
  12. #include "devioctl.h"
  13. #include "miniport.h"
  14. #include "ntddvdeo.h"
  15. #include "video.h"
  16. #include "vga.h"
  17. #include "cmdcnst.h"
  18. #if defined(ALLOC_PRAGMA)
  19. #pragma data_seg("PAGE_DATA")
  20. #endif
  21. //
  22. // Global to make sure driver is only loaded once.
  23. //
  24. ULONG VgaLoaded = 0;
  25. #if DBG
  26. ULONG giControlCode;
  27. ULONG gaIOControlCode[MAX_CONTROL_HISTORY];
  28. #endif
  29. //
  30. // This structure describes to which ports access is required.
  31. //
  32. VIDEO_ACCESS_RANGE VgaAccessRange[] = {
  33. {
  34. VGA_BASE_IO_PORT, 0x00000000, // 64-bit linear base address
  35. // of range
  36. VGA_START_BREAK_PORT - VGA_BASE_IO_PORT + 1, // # of ports
  37. 1, // range is in I/O space
  38. 1, // range should be visible
  39. 1 // range should be shareable
  40. },
  41. {
  42. VGA_END_BREAK_PORT, 0x00000000,
  43. VGA_MAX_IO_PORT - VGA_END_BREAK_PORT + 1,
  44. 1,
  45. 1,
  46. 1
  47. },
  48. {
  49. MEM_VGA, 0x00000000,
  50. MEM_VGA_SIZE,
  51. 0,
  52. 1,
  53. 1
  54. },
  55. // HACK Allow our standard VGA to be used with ATI cards:
  56. // ATI uses an extra IO port at location 1CE on pretty much all of its
  57. // video boards
  58. {
  59. 0x000001CE, 0x00000000,
  60. 2,
  61. 1,
  62. 1,
  63. 1
  64. },
  65. // Another HACK to fix ATI problems. During GUI mode setup
  66. // Network detection may touch ports in the 0x2e8 to 0x2ef range. ATI
  67. // decodes these ports, and the video goes out of sync when network
  68. // detection runs.
  69. //
  70. // NOTE: We don't need to add this to validator routines since the
  71. // ATI bios won't touch these registers.
  72. {
  73. 0x000002E8, 0x00000000,
  74. 8,
  75. 1,
  76. 1,
  77. 1
  78. }
  79. };
  80. //
  81. // Validator Port list.
  82. // This structure describes all the ports that must be hooked out of the V86
  83. // emulator when a DOS app goes to full-screen mode.
  84. // The structure determines to which routine the data read or written to a
  85. // specific port should be sent.
  86. //
  87. EMULATOR_ACCESS_ENTRY VgaEmulatorAccessEntries[] = {
  88. //
  89. // Traps for byte OUTs.
  90. //
  91. {
  92. 0x000003b0, // range start I/O address
  93. 0xC, // range length
  94. Uchar, // access size to trap
  95. EMULATOR_READ_ACCESS | EMULATOR_WRITE_ACCESS, // types of access to trap
  96. FALSE, // does not support string accesses
  97. (PVOID)VgaValidatorUcharEntry // routine to which to trap
  98. },
  99. {
  100. 0x000003c0, // range start I/O address
  101. 0x20, // range length
  102. Uchar, // access size to trap
  103. EMULATOR_READ_ACCESS | EMULATOR_WRITE_ACCESS, // types of access to trap
  104. FALSE, // does not support string accesses
  105. (PVOID)VgaValidatorUcharEntry // routine to which to trap
  106. },
  107. //
  108. // Traps for word OUTs.
  109. //
  110. {
  111. 0x000003b0,
  112. 0x06,
  113. Ushort,
  114. EMULATOR_READ_ACCESS | EMULATOR_WRITE_ACCESS,
  115. FALSE,
  116. (PVOID)VgaValidatorUshortEntry
  117. },
  118. {
  119. 0x000003c0,
  120. 0x10,
  121. Ushort,
  122. EMULATOR_READ_ACCESS | EMULATOR_WRITE_ACCESS,
  123. FALSE,
  124. (PVOID)VgaValidatorUshortEntry
  125. },
  126. //
  127. // Traps for dword OUTs.
  128. //
  129. {
  130. 0x000003b0,
  131. 0x03,
  132. Ulong,
  133. EMULATOR_READ_ACCESS | EMULATOR_WRITE_ACCESS,
  134. FALSE,
  135. (PVOID)VgaValidatorUlongEntry
  136. },
  137. {
  138. 0x000003c0,
  139. 0x08,
  140. Ulong,
  141. EMULATOR_READ_ACCESS | EMULATOR_WRITE_ACCESS,
  142. FALSE,
  143. (PVOID)VgaValidatorUlongEntry
  144. },
  145. //
  146. // ATI hack for port 1CE
  147. //
  148. {
  149. 0x000001ce,
  150. 0x2,
  151. Uchar,
  152. EMULATOR_READ_ACCESS | EMULATOR_WRITE_ACCESS,
  153. FALSE,
  154. (PVOID)VgaValidatorUcharEntry
  155. },
  156. {
  157. 0x000001ce,
  158. 0x1,
  159. Ushort,
  160. EMULATOR_READ_ACCESS | EMULATOR_WRITE_ACCESS,
  161. FALSE,
  162. (PVOID)VgaValidatorUshortEntry
  163. }
  164. };
  165. //
  166. // Used to trap only the sequncer and the misc output registers
  167. //
  168. VIDEO_ACCESS_RANGE MinimalVgaValidatorAccessRange[] = {
  169. {
  170. VGA_BASE_IO_PORT, 0x00000000,
  171. VGA_START_BREAK_PORT - VGA_BASE_IO_PORT + 1,
  172. 1,
  173. 1, // <- enable range IOPM so that it is not trapped.
  174. 1
  175. },
  176. {
  177. VGA_END_BREAK_PORT, 0x00000000,
  178. VGA_MAX_IO_PORT - VGA_END_BREAK_PORT + 1,
  179. 1,
  180. 1,
  181. 1
  182. },
  183. {
  184. VGA_BASE_IO_PORT + MISC_OUTPUT_REG_WRITE_PORT, 0x00000000,
  185. 0x00000001,
  186. 1,
  187. 0,
  188. 1
  189. },
  190. {
  191. VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT, 0x00000000,
  192. 0x00000002,
  193. 1,
  194. 0,
  195. 1
  196. },
  197. // HACK Allow our standard VGA to be used with ATI cards:
  198. // ATI uses an extra IO port at location 1CE on pretty much all of its
  199. // video boards
  200. {
  201. 0x000001CE, 0x00000000,
  202. 2,
  203. 1,
  204. 1,
  205. 1
  206. }
  207. };
  208. //
  209. // Used to trap all registers
  210. //
  211. VIDEO_ACCESS_RANGE FullVgaValidatorAccessRange[] = {
  212. {
  213. VGA_BASE_IO_PORT, 0x00000000,
  214. VGA_START_BREAK_PORT - VGA_BASE_IO_PORT + 1,
  215. 1,
  216. 0, // <- disable range in the IOPM so that it is trapped.
  217. 1
  218. },
  219. {
  220. VGA_END_BREAK_PORT, 0x00000000,
  221. VGA_MAX_IO_PORT - VGA_END_BREAK_PORT + 1,
  222. 1,
  223. 0,
  224. 1
  225. },
  226. // HACK Allow our standard VGA to be used with ATI cards:
  227. // ATI uses an extra IO port at location 1CE on pretty much all of its
  228. // video boards
  229. {
  230. 0x000001CE, 0x00000000,
  231. 2,
  232. 1,
  233. 0,
  234. 1
  235. }
  236. };
  237. //
  238. // Color graphics mode 0x12, 640x480 16 colors.
  239. #ifndef INT10_MODE_SET
  240. //
  241. USHORT VGA_640x480[] = {
  242. OWM, // start sync reset program up sequencer
  243. SEQ_ADDRESS_PORT,
  244. 5,
  245. 0x0100,0x0101,0x0f02,0x0003,0x0604,
  246. OB,
  247. MISC_OUTPUT_REG_WRITE_PORT, // Misc output register
  248. 0xe3,
  249. OW, // Set chain mode in sync reset
  250. GRAPH_ADDRESS_PORT,
  251. 0x0506,
  252. OB, // EndSyncResetCmd
  253. SEQ_ADDRESS_PORT,
  254. IND_SYNC_RESET,
  255. OB,
  256. SEQ_DATA_PORT,
  257. END_SYNC_RESET_VALUE,
  258. OW, // Unlock CRTC registers 0-7
  259. CRTC_ADDRESS_PORT_COLOR,
  260. 0x0511,
  261. METAOUT+INDXOUT, // program crtc registers
  262. CRTC_ADDRESS_PORT_COLOR,
  263. VGA_NUM_CRTC_PORTS, // count
  264. 0, // start index
  265. 0x5F,0x4F,0x50,0x82,0x54,0x80,0x0B,0x3E,0x00,0x40,0x0,0x0,0x0,0x0,0x0,0x0,
  266. 0xEA,0x8C,0xDF,0x28,0x0,0xE7,0x4,0xE3,0xFF,
  267. IB, // prepare atc for writing
  268. INPUT_STATUS_1_COLOR,
  269. METAOUT+ATCOUT, // program attribute controller registers
  270. ATT_ADDRESS_PORT, // port
  271. VGA_NUM_ATTRIB_CONT_PORTS, // count
  272. 0, // start index
  273. 0x0,0x1,0x2,0x3,0x4,0x5,0x14,0x7,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
  274. 0x01,0x0,0x0F,0x0,0x0,
  275. METAOUT+INDXOUT, // program graphics controller registers
  276. GRAPH_ADDRESS_PORT, // port
  277. VGA_NUM_GRAPH_CONT_PORTS, // count
  278. 0, // start index
  279. 0x00,0x0,0x0,0x0,0x0,0x0,0x05,0x0F,0x0FF,
  280. OB, // DAC mask registers
  281. DAC_PIXEL_MASK_PORT,
  282. 0xFF,
  283. IB, // prepare atc for writing
  284. INPUT_STATUS_1_COLOR,
  285. OB, // turn video on.
  286. ATT_ADDRESS_PORT,
  287. VIDEO_ENABLE,
  288. EOD
  289. };
  290. //
  291. // Color text mode, 720x480
  292. //
  293. USHORT VGA_TEXT_0[] = {
  294. OWM,
  295. SEQ_ADDRESS_PORT,
  296. 5,
  297. 0x0100,0x0001,0x0302,0x0003,0x0204, // program up sequencer
  298. OB,
  299. MISC_OUTPUT_REG_WRITE_PORT,
  300. 0x67,
  301. OW,
  302. GRAPH_ADDRESS_PORT,
  303. 0x0e06,
  304. // EndSyncResetCmd
  305. OB,
  306. SEQ_ADDRESS_PORT,
  307. IND_SYNC_RESET,
  308. OB,
  309. SEQ_DATA_PORT,
  310. END_SYNC_RESET_VALUE,
  311. OW,
  312. CRTC_ADDRESS_PORT_COLOR,
  313. 0x0E11,
  314. METAOUT+INDXOUT, // program crtc registers
  315. CRTC_ADDRESS_PORT_COLOR,
  316. VGA_NUM_CRTC_PORTS, // count
  317. 0, // start index
  318. 0x5F,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,0x00,0x4f,0xd,0xe,0x0,0x0,0x0,0x0,
  319. 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,0xFF,
  320. IB, // prepare atc for writing
  321. INPUT_STATUS_1_COLOR,
  322. METAOUT+ATCOUT, //
  323. ATT_ADDRESS_PORT, // port
  324. VGA_NUM_ATTRIB_CONT_PORTS, // count
  325. 0, // start index
  326. 0x0,0x1,0x2,0x3,0x4,0x5,0x14,0x7,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
  327. 0x04,0x0,0x0F,0x8,0x0,
  328. METAOUT+INDXOUT, //
  329. GRAPH_ADDRESS_PORT, // port
  330. VGA_NUM_GRAPH_CONT_PORTS, // count
  331. 0, // start index
  332. 0x00,0x0,0x0,0x0,0x0,0x10,0x0e,0x0,0x0FF,
  333. OB,
  334. DAC_PIXEL_MASK_PORT,
  335. 0xFF,
  336. IB, // prepare atc for writing
  337. INPUT_STATUS_1_COLOR,
  338. OB, // turn video on.
  339. ATT_ADDRESS_PORT,
  340. VIDEO_ENABLE,
  341. EOD
  342. };
  343. #endif//!INT10_MODE_SET
  344. //
  345. // Color text mode, 640x480
  346. //
  347. USHORT VGA_TEXT_1[] = {
  348. OWM,
  349. SEQ_ADDRESS_PORT,
  350. 5,
  351. 0x0100,0x0101,0x0302,0x0003,0x0204, // program up sequencer
  352. OB,
  353. MISC_OUTPUT_REG_WRITE_PORT,
  354. 0xa3,
  355. OW,
  356. GRAPH_ADDRESS_PORT,
  357. 0x0e06,
  358. // EndSyncResetCmd
  359. OB,
  360. SEQ_ADDRESS_PORT,
  361. IND_SYNC_RESET,
  362. OB,
  363. SEQ_DATA_PORT,
  364. END_SYNC_RESET_VALUE,
  365. OW,
  366. CRTC_ADDRESS_PORT_COLOR,
  367. 0x0511,
  368. METAOUT+INDXOUT, // program crtc registers
  369. CRTC_ADDRESS_PORT_COLOR,
  370. VGA_NUM_CRTC_PORTS, // count
  371. 0, // start index
  372. 0x5F,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,0x00,0x4d,0xb,0xc,0x0,0x0,0x0,0x0,
  373. 0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,0xFF,
  374. IB, // prepare atc for writing
  375. INPUT_STATUS_1_COLOR,
  376. METAOUT+ATCOUT, //
  377. ATT_ADDRESS_PORT, // port
  378. VGA_NUM_ATTRIB_CONT_PORTS, // count
  379. 0, // start index
  380. 0x0,0x1,0x2,0x3,0x4,0x5,0x14,0x7,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
  381. 0x00,0x0,0x0F,0x0,0x0,
  382. METAOUT+INDXOUT, //
  383. GRAPH_ADDRESS_PORT, // port
  384. VGA_NUM_GRAPH_CONT_PORTS, // count
  385. 0, // start index
  386. 0x00,0x0,0x0,0x0,0x0,0x10,0x0e,0x0,0x0FF,
  387. OB,
  388. DAC_PIXEL_MASK_PORT,
  389. 0xFF,
  390. IB, // prepare atc for writing
  391. INPUT_STATUS_1_COLOR,
  392. OB, // turn video on.
  393. ATT_ADDRESS_PORT,
  394. VIDEO_ENABLE,
  395. EOD
  396. };
  397. USHORT ModeX200[] = {
  398. OW,
  399. SEQ_ADDRESS_PORT,
  400. 0x0604,
  401. OWM,
  402. CRTC_ADDRESS_PORT_COLOR,
  403. 2,
  404. 0xe317,
  405. 0x0014,
  406. EOD
  407. };
  408. USHORT ModeX240[] = {
  409. OWM,
  410. SEQ_ADDRESS_PORT,
  411. 2,
  412. 0x0604,
  413. 0x0100,
  414. OB,
  415. MISC_OUTPUT_REG_WRITE_PORT,
  416. 0xe3,
  417. OW,
  418. SEQ_ADDRESS_PORT,
  419. 0x0300,
  420. OB,
  421. CRTC_ADDRESS_PORT_COLOR,
  422. 0x11,
  423. METAOUT+MASKOUT,
  424. CRTC_DATA_PORT_COLOR,
  425. 0x7f, 0x00,
  426. OWM,
  427. CRTC_ADDRESS_PORT_COLOR,
  428. 10,
  429. 0x0d06,
  430. 0x3e07,
  431. 0x4109,
  432. 0xea10,
  433. 0xac11,
  434. 0xdf12,
  435. 0x0014,
  436. 0xe715,
  437. 0x0616,
  438. 0xe317,
  439. OW,
  440. SEQ_ADDRESS_PORT,
  441. 0x0f02,
  442. EOD
  443. };
  444. USHORT ModeXDoubleScans[] = {
  445. OW, CRTC_ADDRESS_PORT_COLOR, 0x4009,
  446. EOD
  447. };
  448. //
  449. // We will dynamically build a list of supported modes, based on the VESA
  450. // modes the card supports.
  451. //
  452. PVIDEOMODE VgaModeList;
  453. //
  454. // Video mode table - contains information and commands for initializing each
  455. // mode. These entries must correspond with those in VIDEO_MODE_VGA. The first
  456. // entry is commented; the rest follow the same format, but are not so
  457. // heavily commented.
  458. //
  459. VIDEOMODE ModesVGA[] = {
  460. //
  461. // Mode index 0
  462. // Color text mode 3, 720x400, 9x16 char cell (VGA).
  463. //
  464. {
  465. VIDEO_MODE_COLOR |
  466. VIDEO_MODE_BANKED, // flags that this mode is a color mode, but not graphics
  467. 4, // four planes
  468. 1, // one bit of color per plane
  469. 80, 25, // 80x25 text resolution
  470. 720, 400, // 720x400 pixels on screen
  471. 1, // Frequency in Hz
  472. 160, 0x10000, // 160 bytes per scan line, 64K of CPU-addressable bitmap
  473. NoBanking, // no banking supported or needed in this mode
  474. #ifdef INT10_MODE_SET
  475. 0x3,
  476. #else
  477. VGA_TEXT_0, // pointer to the command strings
  478. #endif
  479. MEM_VGA, 0x18000, 0x08000, MEM_VGA_SIZE,
  480. 720
  481. },
  482. //
  483. // Mode index 1.
  484. // Color text mode 3, 640x350, 8x14 char cell (EGA).
  485. //
  486. {
  487. VIDEO_MODE_COLOR | VIDEO_MODE_BANKED, 4, 1, 80, 25, 640, 350, 1, 160, 0x10000, NoBanking,
  488. #ifdef INT10_MODE_SET
  489. 0x3,
  490. #else
  491. VGA_TEXT_1, // pointer to the command strings
  492. #endif
  493. MEM_VGA, 0x18000, 0x08000, MEM_VGA_SIZE,
  494. 640
  495. },
  496. //
  497. //
  498. // Mode index 2
  499. // Standard VGA Color graphics mode 0x12, 640x480 16 colors.
  500. //
  501. {
  502. VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS | VIDEO_MODE_BANKED, 4, 1, 80, 30,
  503. 640, 480, 1, 80, 0x10000, NoBanking,
  504. #ifdef INT10_MODE_SET
  505. 0x12,
  506. #else
  507. VGA_640x480, // pointer to the command strings
  508. #endif
  509. MEM_VGA, 0x0000, MEM_VGA_SIZE, MEM_VGA_SIZE,
  510. 640
  511. },
  512. #ifdef INT10_MODE_SET
  513. //
  514. // 320x200 256 colors ModeX
  515. //
  516. { VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS | VIDEO_MODE_BANKED, 8, 1, 0, 0,
  517. 320, 200, 70, 80, 0x10000, NoBanking,
  518. 0x13,
  519. MEM_VGA, 0x0000, MEM_VGA_SIZE, MEM_VGA_SIZE,
  520. 320
  521. },
  522. //
  523. // 320x240 256 colors ModeX
  524. //
  525. { VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS | VIDEO_MODE_BANKED, 8, 1, 0, 0,
  526. 320, 240, 60, 80, 0x10000, NoBanking,
  527. 0x13,
  528. MEM_VGA, 0x0000, MEM_VGA_SIZE, MEM_VGA_SIZE,
  529. 320
  530. },
  531. //
  532. // 320x400 256 colors ModeX
  533. //
  534. { VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS | VIDEO_MODE_BANKED, 8, 1, 0, 0,
  535. 320, 400, 70, 80, 0x10000, NoBanking,
  536. 0x13,
  537. MEM_VGA, 0x0000, MEM_VGA_SIZE,
  538. 320
  539. },
  540. //
  541. // 320x480 256 colors ModeX
  542. //
  543. { VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS | VIDEO_MODE_BANKED, 8, 1, 0, 0,
  544. 320, 480, 60, 80, 0x10000, NoBanking,
  545. 0x13,
  546. MEM_VGA, 0x0000, MEM_VGA_SIZE,
  547. 320
  548. },
  549. //
  550. // 800x600 16 colors.
  551. //
  552. // NOTE: This must be the last mode in our static mode table.
  553. //
  554. { VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS | VIDEO_MODE_BANKED, 4, 1, 100, 37,
  555. 800, 600, 1, 100, 0x10000, NoBanking,
  556. 0x01024F02,
  557. MEM_VGA, 0x0000, MEM_VGA_SIZE, MEM_VGA_SIZE,
  558. 800
  559. },
  560. #endif
  561. };
  562. ULONG NumVideoModes = sizeof(ModesVGA) / sizeof(VIDEOMODE);
  563. //
  564. //
  565. // Data used to set the Graphics and Sequence Controllers to put the
  566. // VGA into a planar state at A0000 for 64K, with plane 2 enabled for
  567. // reads and writes, so that a font can be loaded, and to disable that mode.
  568. //
  569. // Settings to enable planar mode with plane 2 enabled.
  570. //
  571. USHORT EnableA000Data[] = {
  572. OWM,
  573. SEQ_ADDRESS_PORT,
  574. 1,
  575. 0x0100,
  576. OWM,
  577. GRAPH_ADDRESS_PORT,
  578. 3,
  579. 0x0204, // Read Map = plane 2
  580. 0x0005, // Graphics Mode = read mode 0, write mode 0
  581. 0x0406, // Graphics Miscellaneous register = A0000 for 64K, not odd/even,
  582. // graphics mode
  583. OWM,
  584. SEQ_ADDRESS_PORT,
  585. 3,
  586. 0x0402, // Map Mask = write to plane 2 only
  587. 0x0404, // Memory Mode = not odd/even, not full memory, graphics mode
  588. 0x0300, // end sync reset
  589. EOD
  590. };
  591. //
  592. // Settings to disable the font-loading planar mode.
  593. //
  594. USHORT DisableA000Color[] = {
  595. OWM,
  596. SEQ_ADDRESS_PORT,
  597. 1,
  598. 0x0100,
  599. OWM,
  600. GRAPH_ADDRESS_PORT,
  601. 3,
  602. 0x0004, 0x1005, 0x0E06,
  603. OWM,
  604. SEQ_ADDRESS_PORT,
  605. 3,
  606. 0x0302, 0x0204, 0x0300, // end sync reset
  607. EOD
  608. };
  609. #if defined(ALLOC_PRAGMA)
  610. #pragma data_seg()
  611. #endif