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.

680 lines
20 KiB

  1. /*++
  2. Copyright (c) 1993, 1994 Weitek Corporation
  3. Module Name:
  4. p9100.c
  5. Abstract:
  6. This module contains the code specific to the Weitek P9100.
  7. Environment:
  8. Kernel mode
  9. Revision History may be found at the end of this file.
  10. --*/
  11. #include "p9.h"
  12. #include "p9gbl.h"
  13. #include "p91regs.h"
  14. #include "vga.h"
  15. #include "wtkp9xvl.h"
  16. VOID
  17. InitP9100(
  18. PHW_DEVICE_EXTENSION HwDeviceExtension
  19. )
  20. /*++
  21. Routine Description:
  22. Initialize the P9100.
  23. Arguments:
  24. HwDeviceExtension - Pointer to the miniport driver's device extension.
  25. Return Value:
  26. None.
  27. --*/
  28. {
  29. VideoDebugPrint((2, "InitP9100------\n"));
  30. P9_WR_REG(P91_INTERRUPT_EN, 0x00000080L); //INTERRUPT-EN = disabled
  31. P9_WR_REG(P91_PREHRZC, 0x00000000L); //PREHRZC = 0
  32. P9_WR_REG(P91_PREVRTC, 0x00000000L); //PREVRTC = 0
  33. //
  34. // Initialize the P9100 registers.
  35. //
  36. P9_WR_REG(P91_RFPERIOD, 0x00000186L); //RFPERIOD =
  37. P9_WR_REG(P91_RLMAX, 0x000000FAL); //RLMAX =
  38. P9_WR_REG(P91_DE_PMASK, 0xFFFFFFFFL); //allow writing in all 8 planes
  39. P9_WR_REG(P91_DE_DRAW_MODE, P91_WR_INSIDE_WINDOW | P91_DE_DRAW_BUFF_0);
  40. P9_WR_REG(P91_PE_W_OFF_XY, 0x00000000L); //disable any co-ord offset
  41. return;
  42. }
  43. VOID
  44. P91_WriteTiming(
  45. PHW_DEVICE_EXTENSION HwDeviceExtension
  46. )
  47. /*++
  48. Routine Description:
  49. Initializes the P9100 Crtc timing registers.
  50. Arguments:
  51. HwDeviceExtension - Pointer to the miniport driver's device extension.
  52. Return Value:
  53. None.
  54. --*/
  55. {
  56. int num, den, bpp;
  57. ULONG ulValueRead, ulValueWritten;
  58. ULONG ulHRZSR;
  59. ULONG ulHRZBR;
  60. ULONG ulHRZBF;
  61. ULONG ulHRZT;
  62. VideoDebugPrint((2, "P91_WriteTiming - Entry\n"));
  63. bpp = HwDeviceExtension->usBitsPixel / 8; // Need bytes per pixel
  64. //
  65. // 24-bit color
  66. //
  67. if (bpp == 3)
  68. {
  69. num = 3;
  70. den = HwDeviceExtension->Dac.usRamdacWidth/8;
  71. }
  72. else
  73. {
  74. num = 1;
  75. den = HwDeviceExtension->Dac.usRamdacWidth/(bpp * 8);
  76. }
  77. //
  78. // Calculate HRZSR.
  79. //
  80. ulHRZSR = (ULONG) (HwDeviceExtension->VideoData.hsyncp /
  81. (ULONG) den) * (ULONG) num;
  82. ulHRZSR -= HwDeviceExtension->p91State.ulBlnkDlyAdj;
  83. //
  84. // Calculate HRZBR.
  85. //
  86. ulHRZBR = (ULONG) ((HwDeviceExtension->VideoData.hsyncp +
  87. HwDeviceExtension->VideoData.hbp) / (ULONG) den) *
  88. (ULONG) num;
  89. ulHRZBR -= HwDeviceExtension->p91State.ulBlnkDlyAdj;
  90. // ulHRZBR -= 4;
  91. ulHRZBF = (ULONG) ( (HwDeviceExtension->VideoData.hsyncp+
  92. HwDeviceExtension->VideoData.hbp+
  93. HwDeviceExtension->VideoData.XSize) / (ULONG) den) * (ULONG) num;
  94. //
  95. // Calculate HRZBF.
  96. //
  97. ulHRZBF -= HwDeviceExtension->p91State.ulBlnkDlyAdj;
  98. // ulHRZBF -= 4;
  99. ulHRZT = (ULONG) ( (HwDeviceExtension->VideoData.hsyncp+
  100. HwDeviceExtension->VideoData.hbp+
  101. HwDeviceExtension->VideoData.XSize+
  102. HwDeviceExtension->VideoData.hfp) /
  103. (ULONG) den) * (ULONG) num;
  104. --ulHRZT;
  105. //
  106. // Changes requested by Rober Embry, Jan 26 Spec.
  107. //
  108. if (HwDeviceExtension->Dac.ulDacId == DAC_ID_BT489)
  109. {
  110. //
  111. // Fix for fussy screen problem, Per Sam Jenson
  112. //
  113. ulHRZT = 2 * (ulHRZT>>1) + 1;
  114. }
  115. if ((HwDeviceExtension->Dac.ulDacId == DAC_ID_BT489) ||
  116. (HwDeviceExtension->Dac.ulDacId == DAC_ID_BT485))
  117. {
  118. if (bpp == 1)
  119. {
  120. ulHRZBR -= 12 * num / den;
  121. ulHRZBF -= 12 * num / den;
  122. }
  123. else
  124. {
  125. ulHRZBR -= 9 * num / den;
  126. ulHRZBF -= 9 * num / den;
  127. }
  128. }
  129. //
  130. // By robert embry 12/1/94
  131. //
  132. // The hardware configuration (Power 9100 version and DAC type) affects
  133. // the minimum horizontal back porch timing that a board can support.
  134. // The most flexible (able to support the smallest back porch)
  135. // configuration is with Power 9100 A4 with the IBM or ATT DAC.
  136. //
  137. // The Power 9100 A2 increases the front porch minimum by one.
  138. // The Brooktree DAC increases the front porch minimum by one, also.
  139. //
  140. // Configuration Min. Back Porch
  141. // ----------------- ---------------
  142. // P9100 A4, IBM/ATT DAC 40 pixels (5 CRTC clocks)
  143. // P9100 A2, IBM/ATT DAC 48 pixels (6 CRTC clocks)
  144. // P9100 A4, BT485/9 DAC 48 pixels (6 CRTC clocks)
  145. // P9100 A2, BT485/9 DAC 56 pixels (7 CRTC clocks)
  146. //
  147. // Since we want one P9x00RES.DAT file AND we don't want to penalize the
  148. // most common configuration, the driver needs to choose the best fit
  149. // when the P9x00RES.DAT file specifies a set of parameters that are not
  150. // supported.
  151. //
  152. // Algorithm for BEST FIT:
  153. //
  154. // First, time must be taken from something else. Either by shortening
  155. // the pulse width or the front porch (shifts line to right.) The
  156. // largest value of the two is decreased, sync pulse if equal.
  157. //
  158. // A given P9x00RES.DAT file will result in valid register values
  159. // in one hardware configuration, but not in another. This code
  160. // adjusts these register values so the P9x00RES.DAT file parameters
  161. // work for all boards, but not necesarily giving the requested timing.
  162. // The P9100 A4 silicon with an IBM or ATT DAC is the best case.
  163. // When the P9100 A2 or a Brooktree DAC is present then the
  164. // minimum supportable horizontal back porch is enlarged.
  165. //
  166. // psuedo BASIC code:
  167. //
  168. // This is parameter checking code for the Power 9100's hrzSR and hrzBR
  169. // registers. The following equation must be satisfied: hrzSR < hrzBR.
  170. //
  171. // If this equation is violated in the presence of the Power 9100 A2
  172. // silicon or a non-pipelined DAC (BT485/9) then these register values
  173. // are modified.
  174. //
  175. // This code should go just before the registers are written.
  176. // The register values may need to be modified by up to 2 counts.
  177. //
  178. // IF (DacType=BT485 OR DacType=BT485A OR DacType=BT489 OR _
  179. // SiliconVerion=A2) THEN {
  180. // WHILE hrzSR >= hrzBR {
  181. // IF hsp>hfp THEN DECR hrzSR _ ;shrink sync pulse width
  182. // ELSE INCR hrzBR :INCR hrzBF ;shorten front porch
  183. // } }
  184. //
  185. if ((HwDeviceExtension->Dac.ulDacId == DAC_ID_BT489) ||
  186. (HwDeviceExtension->Dac.ulDacId == DAC_ID_BT485) ||
  187. (HwDeviceExtension->p91State.usRevisionID < WTK_9100_REV3))
  188. {
  189. while (ulHRZSR >= ulHRZBR)
  190. {
  191. if (HwDeviceExtension->VideoData.hsyncp >
  192. HwDeviceExtension->VideoData.hfp)
  193. {
  194. ulHRZSR--;
  195. }
  196. else
  197. {
  198. ulHRZBR++;
  199. ulHRZBF++;
  200. }
  201. }
  202. }
  203. //
  204. // Write to the video timing registers
  205. //
  206. do
  207. {
  208. P9_WR_REG(P91_HRZSR, ulHRZSR);
  209. ulValueRead = (ULONG) P9_RD_REG(P91_HRZSR);
  210. } while (ulValueRead != ulHRZSR);
  211. do
  212. {
  213. P9_WR_REG(P91_HRZBR, ulHRZBR);
  214. ulValueRead = (ULONG) P9_RD_REG(P91_HRZBR);
  215. } while (ulValueRead != ulHRZBR);
  216. do
  217. {
  218. P9_WR_REG(P91_HRZBF, ulHRZBF);
  219. ulValueRead = (ULONG) P9_RD_REG(P91_HRZBF);
  220. } while (ulValueRead != ulHRZBF);
  221. do
  222. {
  223. P9_WR_REG(P91_HRZT, ulHRZT);
  224. ulValueRead = (ULONG) P9_RD_REG(P91_HRZT);
  225. } while (ulValueRead != ulHRZT);
  226. ulValueWritten = (ULONG) HwDeviceExtension->VideoData.vsp;
  227. do
  228. {
  229. P9_WR_REG(P91_VRTSR, ulValueWritten);
  230. ulValueRead = (ULONG) P9_RD_REG(P91_VRTSR);
  231. } while (ulValueRead != ulValueWritten);
  232. ulValueWritten = (ULONG) HwDeviceExtension->VideoData.vsp+
  233. HwDeviceExtension->VideoData.vbp;
  234. do
  235. {
  236. P9_WR_REG(P91_VRTBR, ulValueWritten);
  237. ulValueRead = (ULONG) P9_RD_REG(P91_VRTBR);
  238. } while (ulValueRead != ulValueWritten);
  239. ulValueWritten = (ULONG) HwDeviceExtension->VideoData.vsp+
  240. HwDeviceExtension->VideoData.vbp+
  241. HwDeviceExtension->VideoData.YSize;
  242. do
  243. {
  244. P9_WR_REG(P91_VRTBF, ulValueWritten);
  245. ulValueRead = (ULONG) P9_RD_REG(P91_VRTBF);
  246. } while (ulValueRead != ulValueWritten);
  247. ulValueWritten = (ULONG) HwDeviceExtension->VideoData.vsp+
  248. HwDeviceExtension->VideoData.vbp+
  249. HwDeviceExtension->VideoData.YSize+
  250. HwDeviceExtension->VideoData.vfp;
  251. do
  252. {
  253. P9_WR_REG(P91_VRTT, ulValueWritten);
  254. ulValueRead = (ULONG) P9_RD_REG(P91_VRTT);
  255. } while (ulValueRead != ulValueWritten);
  256. VideoDebugPrint((2, "P91_WriteTiming - Exit\n"));
  257. return;
  258. } // End of P91_WriteTimings()
  259. VOID
  260. P91_SysConf(
  261. PHW_DEVICE_EXTENSION HwDeviceExtension
  262. )
  263. /*++
  264. Routine Description:
  265. Syscon converts the ->XSize value into the correct bits in
  266. the System Configuration Register and writes the register
  267. (This register contains the XSize of the display.)
  268. Half-word and byte swapping are set via bits: 12 & 13;
  269. The shift control fields are set to the size of the scanline in bytes;
  270. And pixel size is set to bits per pixel.
  271. XSize and ulFrameBufferSize must be set prior to entering this routine.
  272. This routine also initializes the clipping registers.
  273. Arguments:
  274. HwDeviceExtension - Pointer to the miniport driver's device extension.
  275. Return Value:
  276. None.
  277. --*/
  278. {
  279. int i, j, iBytesPerPixel; // loop counters
  280. long sysval; // swap bytes and words for little endian PC
  281. int xtem = (int) HwDeviceExtension->VideoData.XSize;
  282. long ClipMax; // clipping register value for NotBusy to restore
  283. iBytesPerPixel = (int) HwDeviceExtension->usBitsPixel / 8; // Calc Bytes/pixel
  284. xtem *= iBytesPerPixel;
  285. VideoDebugPrint((2, "P91_SysConf------\n"));
  286. //
  287. // The following sets up the System Configuration Register
  288. // for BPP with byte and half-word swapping. This swapping
  289. // is usually what is needed since the frame-buffer is stored
  290. // in big endian pixel format and the 80x86 software usually
  291. // expects little endian pixel format.
  292. //
  293. if (iBytesPerPixel == 1)
  294. sysval = SYSCFG_BPP_8;
  295. else if (iBytesPerPixel == 2)
  296. sysval = SYSCFG_BPP_16;
  297. else if (iBytesPerPixel == 3)
  298. sysval = SYSCFG_BPP_24;
  299. else // if (iBytesPerPixel == 4)
  300. sysval = SYSCFG_BPP_32;
  301. //
  302. // Now set the Shift3, Shift0, Shift1 & Shift2 multipliers.
  303. //
  304. // Each field in the sysconfig can only set a limited
  305. // range of bits in the size.
  306. //
  307. if (xtem & 0x1c00) // 7168
  308. {
  309. //
  310. // Look at all the bits for shift control 3
  311. //
  312. j=3;
  313. for (i=4096;i>=1024;i>>=1)
  314. {
  315. //
  316. // If this bit is on...
  317. //
  318. if (i & xtem)
  319. {
  320. //
  321. // Use this field to set it and
  322. // remove the bit from the size. Each
  323. // field can only set one bit.
  324. //
  325. sysval |= ((long)j)<<29;
  326. xtem &= ~i;
  327. break;
  328. }
  329. j=j-1;
  330. }
  331. }
  332. if (xtem & 0xf80) // each field in the sysconreg can only set
  333. { // a limited range of bits in the size
  334. j = 7; // each field is 3 bits wide
  335. //
  336. // Look at all the bits for shift control 0
  337. //
  338. for (i = 2048; i >= 128;i >>= 1) // look at all the bits field 3 can effect
  339. {
  340. if (i & xtem) // if this bit is on,
  341. {
  342. sysval |= ((long) j) << 20; // use this field to set it
  343. xtem &= ~i; // and remove the bit from the size
  344. break; // each field can only set one bit
  345. }
  346. j -= 1;
  347. }
  348. }
  349. if (xtem & 0x7C0) // do the same thing for field 2
  350. {
  351. //
  352. // Do the same thing for shift control 1
  353. //
  354. j = 6; // each field is 3 bits wide
  355. for (i = 1024; i >= 64; i >>= 1) // look at all the bits field 2 can effect
  356. {
  357. if (i & xtem) // if this bit is on,
  358. {
  359. sysval |= ((long)j)<<17; // use this field to set it
  360. xtem &= ~i; // and remove the bit from the size
  361. break; // each field can only set one bit
  362. }
  363. j -= 1;
  364. }
  365. }
  366. if (xtem & 0x3E0) // do the same thing for field 1
  367. {
  368. j = 5; // each field is 3 bits wide
  369. //
  370. // do the same thing for shift control 2
  371. //
  372. for (i = 512; i >= 32;i >>= 1) // look at all the bits field 1 can effect
  373. {
  374. if (i & xtem) // if this bit is on,
  375. {
  376. sysval |= ((long) j) << 14; // use this field to set it
  377. xtem &= ~i; // and remove the bit from the size
  378. break; // each field can only set one bit
  379. }
  380. j -= 1;
  381. }
  382. }
  383. //
  384. // If there are bits left, it is an illegal x size. This just means
  385. // that we cannot handle it because we have not implemented a
  386. // full multiplier. However, the vast majority of screen sizes can be
  387. // expressed as a sum of few powers of two.
  388. //
  389. if (xtem != 0) // if there are bits left, it is an
  390. return; // illegal x size.
  391. VideoDebugPrint((2, "P91_SysConf:sysval = 0x%lx\n", sysval));
  392. P9_WR_REG(P91_SYSCONFIG, sysval); // send data to the register
  393. xtem = (int) (HwDeviceExtension->VideoData.XSize * (ULONG) iBytesPerPixel);
  394. //
  395. // Now calculate and set the max clipping to allow access to all of
  396. // the extra memory.
  397. //
  398. // There are two sets of clipping registers. The first takes the
  399. // horizontal diemnsion in pixels and the vertical dimension in
  400. // scanlines.
  401. //
  402. ClipMax=((long) HwDeviceExtension->VideoData.XSize - 1L) << 16 |
  403. (div32(HwDeviceExtension->FrameLength, (USHORT) xtem) - 1L);
  404. P9_WR_REG(P91_DE_P_W_MIN, 0L);
  405. P9_WR_REG(P91_DE_P_W_MAX, ClipMax);
  406. //
  407. // The second set takes the horizontal dimension in bytes and the
  408. // vertical dimension in scanlines.
  409. //
  410. ClipMax=((long) xtem -1L) << 16 |
  411. (div32(HwDeviceExtension->FrameLength, (USHORT) xtem) - 1L); // calc and set max
  412. P9_WR_REG(P91_DE_B_W_MIN, 0L);
  413. P9_WR_REG(P91_DE_B_W_MAX, ClipMax);
  414. return;
  415. } // End of P91_SysConf()
  416. #define RESTORE_DAC 1
  417. //#define SAVE_INDEX_REGS 1
  418. /***************************************************************************\
  419. * *
  420. * Save & Restore VGA registers routines *
  421. * *
  422. * this is to avoid "blind" boot end *
  423. * *
  424. \***************************************************************************/
  425. void P91SaveVGARegs(PHW_DEVICE_EXTENSION HwDeviceExtension,VGA_REGS * SaveVGARegisters)
  426. {
  427. UCHAR ucIndex ;
  428. ULONG ulIndex ;
  429. UCHAR temp;
  430. #ifdef SAVE_INDEX_REGS
  431. // Save index registers.
  432. temp = VGA_RD_REG(0x004);
  433. VideoDebugPrint((1, "Save, 3c4:%x\n", temp));
  434. temp = VGA_RD_REG(0x00e);
  435. VideoDebugPrint((1, "Save, 3ce:%x\n", temp));
  436. temp = VGA_RD_REG(0x014);
  437. VideoDebugPrint((1, "Save, 3d4:%x\n", temp));
  438. #endif
  439. /* Miscellaneous Output Register: [3C2]w, [3CC]r */
  440. SaveVGARegisters->MiscOut = VGA_RD_REG(0x00C) ;
  441. /* CRT Controller Registers 0-18: index [3D4], data [3D5] */
  442. for (ucIndex = 0 ; ucIndex < 0x18 ; ucIndex ++)
  443. {
  444. VGA_WR_REG(0x014 ,ucIndex) ;
  445. SaveVGARegisters->CR[ucIndex] = VGA_RD_REG(0x015) ;
  446. }
  447. /* Sequencer Registers 1-4: index [3C4], data [3C5] */
  448. for (ucIndex = 1 ; ucIndex < 4 ; ucIndex ++)
  449. {
  450. VGA_WR_REG(0x004 ,ucIndex) ;
  451. SaveVGARegisters->SR[ucIndex] = VGA_RD_REG(0x005) ;
  452. }
  453. /* Graphics Controller Registers 0-8: index [3CE], data [3CF] */
  454. for (ucIndex = 0 ; ucIndex < 8 ; ucIndex ++)
  455. {
  456. VGA_WR_REG(0x00E ,ucIndex) ;
  457. SaveVGARegisters->GR[ucIndex] = VGA_RD_REG(0x00F) ;
  458. }
  459. /* Attribute Controller Registers 0-14: index and data [3C0]w, [3C1]r */
  460. VGA_RD_REG(0x01A) ; /* set toggle to index mode */
  461. for (ucIndex = 0 ; ucIndex < 0x14 ; ucIndex ++)
  462. {
  463. VGA_WR_REG(0x000 ,ucIndex) ; /* write index */
  464. SaveVGARegisters->AR[ucIndex] = VGA_RD_REG(0x001) ; /* read data */
  465. VGA_WR_REG(0x000 ,SaveVGARegisters->AR[ucIndex]) ; /* toggle */
  466. }
  467. #ifdef RESTORE_DAC
  468. //Look-Up Table: Read Index [3C7]w, Write Index [3C8], Data [3C9]
  469. VGA_WR_REG(0x007 ,0) ; //set read index to 0
  470. for (ulIndex = 0 ; ulIndex < (3 * 256) ; ulIndex ++)
  471. {
  472. SaveVGARegisters->LUT[ulIndex] = VGA_RD_REG(0x009) ;
  473. }
  474. #endif //RESTORE_DAC
  475. }
  476. void P91RestoreVGAregs(PHW_DEVICE_EXTENSION HwDeviceExtension,VGA_REGS * SaveVGARegisters)
  477. {
  478. UCHAR ucIndex ;
  479. ULONG ulIndex ;
  480. UCHAR temp;
  481. WriteP9ConfigRegister(HwDeviceExtension,P91_CONFIG_MODE,0x2);
  482. /* Put the VGA back in color mode for our PROM */
  483. VGA_WR_REG(MISCOUT ,1) ;
  484. /* Enable VGA Registers: [3C3] = 1 */
  485. VGA_WR_REG(0x003 ,1) ;
  486. /* Miscellaneous Output Register: [3C2]w, [3CC]r */
  487. VGA_WR_REG(0x002 ,SaveVGARegisters->MiscOut) ;
  488. /* Enable CR0-CR7: CR11[7] = 0 */
  489. VGA_WR_REG(0x014 ,0x11) ;
  490. VGA_WR_REG(0x015 ,SaveVGARegisters->CR[0x11] & 0x7F) ;
  491. /* CRT Controller Registers 0-18: index [3D4], data [3D5] */
  492. for (ucIndex = 0 ; ucIndex < 0x18 ; ucIndex ++)
  493. {
  494. VGA_WR_REG(0x014 ,ucIndex) ;
  495. VGA_WR_REG(0x015 ,SaveVGARegisters->CR[ucIndex]) ;
  496. }
  497. /* Synchronous Reset: SR0 = 1 */
  498. VGA_WR_REG(0x004 ,0) ;
  499. VGA_WR_REG(0x005 ,1) ;
  500. /* ClockMode: SR1 */
  501. VGA_WR_REG(0x004 ,1) ;
  502. VGA_WR_REG(0x005 ,SaveVGARegisters->SR[1]) ;
  503. /* Non Reset Mode: SR0 = 0 */
  504. VGA_WR_REG(0x004 ,0) ;
  505. VGA_WR_REG(0x005 ,0) ;
  506. /* Sequencer Registers 2-4: index [3C4], data [3C5] */
  507. for (ucIndex = 2 ; ucIndex < 4 ; ucIndex ++)
  508. {
  509. VGA_WR_REG(0x004 ,ucIndex) ;
  510. VGA_WR_REG(0x005 ,SaveVGARegisters->SR[ucIndex]) ;
  511. }
  512. /* Graphics Controller Regs 0-8: index [3CE], data [3CF] */
  513. VGA_WR_REG(0x00E ,1) ;
  514. VGA_WR_REG(0x00F ,0x0F) ; /* enable all 4 planes for GR0 */
  515. for (ucIndex = 0 ; ucIndex < 8 ; ucIndex ++)
  516. {
  517. VGA_WR_REG(0x00E ,ucIndex) ;
  518. VGA_WR_REG(0x00F ,SaveVGARegisters->GR[ucIndex]) ;
  519. }
  520. /* Attrib Controller Regs 0-14:index and data [3C0]w,[3C1]r */
  521. VGA_RD_REG(0x01A) ; /* set toggle to index mode */
  522. for (ucIndex = 0 ; ucIndex < 0x14 ; ucIndex ++)
  523. {
  524. VGA_WR_REG(0x000 ,ucIndex) ; /* write index */
  525. VGA_WR_REG(0x000 ,SaveVGARegisters->AR[ucIndex]) ;
  526. /* write data */
  527. }
  528. VGA_WR_REG(0x000 ,0x20) ; /* set index[5] to 1 */
  529. #ifdef SAVE_INDEX_REGS
  530. // Restore index registers.
  531. VGA_WR_REG(0x004, 0x002);
  532. temp = VGA_RD_REG(0x004);
  533. VideoDebugPrint((1, "Restore: 3c4:%x\n", temp));
  534. VGA_WR_REG(0x00e, 0x005);
  535. temp = VGA_RD_REG(0x00e);
  536. VideoDebugPrint((1, "Restore: 3ce:%x\n", temp));
  537. VGA_WR_REG(0x014, 0x0011);
  538. temp = VGA_RD_REG(0x014);
  539. VideoDebugPrint((1, "Restore: 3d4:%x\n", temp));
  540. #endif
  541. #ifdef RESTORE_DAC
  542. //Look-Up Table:
  543. //Read Index [3C7]w, Write Index [3C8], Data [3C9]
  544. VGA_WR_REG(0x008 ,0) ; // set write index to 0
  545. for (ulIndex = 0 ; ulIndex < (3 * 256) ; ulIndex ++)
  546. {
  547. VGA_WR_REG(0x009 ,SaveVGARegisters->LUT[ulIndex]) ;
  548. }
  549. #endif //RESTORE_DAC
  550. }