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.

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