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.

1294 lines
30 KiB

  1. //
  2. // vga routines
  3. //
  4. #include "bldr.h"
  5. #include "vga.h"
  6. #include "cmdcnst.h"
  7. PUCHAR VgaBase = (PUCHAR)0xa0000;
  8. PUCHAR VgaRegisterBase = (PUCHAR)0;
  9. //
  10. // globals to track screen position
  11. //
  12. #define DELTA 80L
  13. BOOLEAN
  14. VgaInterpretCmdStream(
  15. PUSHORT pusCmdStream
  16. );
  17. UCHAR lMaskTable[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
  18. UCHAR rMaskTable[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
  19. UCHAR PixelMask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
  20. //
  21. // Initialize AT registers
  22. //
  23. USHORT AT_Initialization[] = {
  24. IB, // prepare atc for writing
  25. INPUT_STATUS_1_COLOR,
  26. METAOUT+ATCOUT, // program attribute controller registers
  27. ATT_ADDRESS_PORT, // port
  28. 16, // count
  29. 0, // start index
  30. 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
  31. IB, // prepare atc for writing
  32. INPUT_STATUS_1_COLOR,
  33. OB, // turn video on.
  34. ATT_ADDRESS_PORT,
  35. VIDEO_ENABLE,
  36. EOD
  37. };
  38. ULONG lookup[16] =
  39. {
  40. 0x00000000,
  41. 0x00000100,
  42. 0x00001000,
  43. 0x00001100,
  44. 0x00000001,
  45. 0x00000101,
  46. 0x00001001,
  47. 0x00001101,
  48. 0x00000010,
  49. 0x00000110,
  50. 0x00001010,
  51. 0x00001110,
  52. 0x00000011,
  53. 0x00000111,
  54. 0x00001011,
  55. 0x00001111
  56. };
  57. void __outpw(int p, int v)
  58. {
  59. WRITE_PORT_USHORT((PUSHORT)(p+VgaRegisterBase), (USHORT)v);
  60. }
  61. void __outpb(int p, int v)
  62. {
  63. WRITE_PORT_UCHAR((PUCHAR)(p+VgaRegisterBase), (UCHAR)v);
  64. }
  65. VOID
  66. ReadWriteMode(
  67. ULONG mode
  68. )
  69. {
  70. UCHAR value;
  71. WRITE_PORT_UCHAR((PUCHAR)(VgaRegisterBase+0x3ce), 5);
  72. value = READ_PORT_UCHAR((PUCHAR)(VgaRegisterBase+0x3cf));
  73. value &= 0xf4;
  74. value |= mode;
  75. WRITE_PORT_UCHAR((PUCHAR)(VgaRegisterBase+0x3cf), value);
  76. }
  77. VOID
  78. SetPixel(
  79. ULONG x,
  80. ULONG y,
  81. ULONG color
  82. )
  83. {
  84. PUCHAR pDst;
  85. ULONG bank;
  86. bank = x >> 3;
  87. pDst = (PUCHAR)(VgaBase + y * DELTA + bank);
  88. ReadWriteMode(0x8 | 0x2);
  89. __outpw(0x3c4, 0x0f02); // enable all write planes
  90. __outpw(0x3ce, 0x0007); // set color don't care register to zero
  91. __outpw(0x3ce, (PixelMask[x & 0x7] << 8) | 8);
  92. WRITE_REGISTER_UCHAR(pDst, (UCHAR)(READ_REGISTER_UCHAR(pDst) & ((UCHAR)color)));
  93. }
  94. VOID
  95. VidSolidColorFill(
  96. ULONG x1,
  97. ULONG y1,
  98. ULONG x2,
  99. ULONG y2,
  100. ULONG color
  101. )
  102. {
  103. PUCHAR pDst;
  104. ULONG x, y;
  105. ULONG bank1, bank2, count;
  106. ULONG lMask, rMask;
  107. lMask = (lMaskTable[x1 & 0x7] << 8) | 8;
  108. rMask = (rMaskTable[x2 & 0x7] << 8) | 8;
  109. bank1 = x1 >> 3;
  110. bank2 = x2 >> 3;
  111. count = bank2 - bank1;
  112. if (!count) {
  113. lMask = lMask & rMask;
  114. }
  115. ReadWriteMode(0x8 | 0x2);
  116. __outpw(0x3c4, 0x0f02); // enable writing to all color planes
  117. __outpw(0x3ce, 0x0007); // set color don't care register to zero
  118. //
  119. // Do the left edge
  120. //
  121. pDst = (PUCHAR)(VgaBase + y1 * DELTA + bank1);
  122. __outpw(0x3ce, lMask);
  123. for (y=y1; y<=y2; y++) {
  124. WRITE_REGISTER_UCHAR(pDst, (UCHAR)(READ_REGISTER_UCHAR(pDst) & (UCHAR) color));
  125. pDst += DELTA;
  126. }
  127. if (count) {
  128. //
  129. // Do the right edge
  130. //
  131. pDst = (PUCHAR)(VgaBase + y1 * DELTA + bank2);
  132. count--;
  133. __outpw(0x3ce, rMask);
  134. for (y=y1; y<=y2; y++) {
  135. WRITE_REGISTER_UCHAR(pDst, (UCHAR)(READ_REGISTER_UCHAR(pDst) & (UCHAR) color));
  136. pDst += DELTA;
  137. }
  138. //
  139. // Do the center section
  140. //
  141. if (count) {
  142. pDst = (PUCHAR)(VgaBase + y1 * DELTA + bank1 + 1);
  143. __outpw(0x3ce, 0xff08);
  144. for (y=y1; y<=y2; y++) {
  145. for (x=0; x<count; x++) {
  146. WRITE_REGISTER_UCHAR(pDst++, (unsigned char) color);
  147. }
  148. pDst += DELTA - count;
  149. }
  150. }
  151. }
  152. }
  153. VOID
  154. RleBitBlt(
  155. ULONG x,
  156. ULONG y,
  157. ULONG width,
  158. ULONG height,
  159. PUCHAR Buffer
  160. )
  161. /*++
  162. Routine Description:
  163. This routine displays an RLE 4 bitmap.
  164. Arguments:
  165. x, y - location at which to display the bitmap.
  166. width, height - height of the bitmap
  167. Buffer - Pointer to the compressed bitmap data.
  168. --*/
  169. {
  170. BOOLEAN Done = FALSE;
  171. PUCHAR p = Buffer;
  172. ULONG RunLength;
  173. LONG RunExtra;
  174. ULONG curr_x, curr_y;
  175. ULONG Color1, Color2;
  176. curr_x = x;
  177. curr_y = y + height - 1;
  178. while (!Done) {
  179. if (*p) {
  180. RunLength = (ULONG) *p++;
  181. //
  182. // Make sure we don't draw past end of scan.
  183. //
  184. if ((curr_x + RunLength) > (x + width))
  185. RunLength -= (curr_x + RunLength) - (width + x);
  186. Color1 = (*p & 0xf0) >> 4;
  187. Color2 = (*p++ & 0x0f);
  188. if (Color1 == Color2) {
  189. ULONG end_x = curr_x + RunLength - 1;
  190. VidSolidColorFill(curr_x,
  191. curr_y,
  192. end_x,
  193. curr_y,
  194. Color1);
  195. curr_x += RunLength;
  196. } else {
  197. while (RunLength > 1) {
  198. SetPixel(curr_x++, curr_y, Color1);
  199. SetPixel(curr_x++, curr_y, Color2);
  200. RunLength -= 2;
  201. }
  202. if (RunLength) {
  203. SetPixel(curr_x, curr_y, Color1);
  204. curr_x++;
  205. }
  206. }
  207. } else {
  208. p++;
  209. switch (*p) {
  210. case 0: curr_x = x;
  211. curr_y--;
  212. p++;
  213. break;
  214. case 1: Done = TRUE;
  215. p++;
  216. break;
  217. case 2: p++;
  218. curr_x += (ULONG) *p++;
  219. curr_y -= (ULONG) *p++;
  220. break;
  221. default: RunLength = (ULONG) *p++;
  222. //
  223. // Make sure we don't draw past end of scan.
  224. //
  225. if ((curr_x + RunLength) > (x + width)) {
  226. RunExtra = (curr_x + RunLength) - (width + x);
  227. RunLength -= RunExtra;
  228. } else {
  229. RunExtra = 0;
  230. }
  231. while (RunLength > 1) {
  232. Color1 = (*p & 0xf0) >> 4;
  233. Color2 = (*p++ & 0x0f);
  234. SetPixel(curr_x++, curr_y, Color1);
  235. SetPixel(curr_x++, curr_y, Color2);
  236. RunLength -= 2;
  237. }
  238. if (RunLength) {
  239. Color1 = (*p++ & 0xf0) >> 4;
  240. SetPixel(curr_x++, curr_y, Color1);
  241. RunExtra--;
  242. }
  243. //
  244. // Read any remaining "extra" run data.
  245. //
  246. while (RunExtra > 0) {
  247. p++;
  248. RunExtra -= 2;
  249. }
  250. if ((ULONG_PTR)p & 1) p++; // make sure we are word aligned
  251. break;
  252. }
  253. }
  254. }
  255. }
  256. VOID
  257. BitBlt(
  258. ULONG x,
  259. ULONG y,
  260. ULONG width,
  261. ULONG height,
  262. PUCHAR Buffer,
  263. ULONG bpp,
  264. LONG ScanWidth
  265. )
  266. {
  267. ULONG i, j;
  268. ULONG color=8;
  269. if (bpp == 4) {
  270. UCHAR Plane[81];
  271. ULONG lMask, rMask, count;
  272. ULONG bank1, bank2, bank;
  273. ULONG bRightEdge = FALSE, bCenterSection = FALSE;
  274. UCHAR value;
  275. ULONG plane;
  276. UCHAR Mask;
  277. ULONG toggle;
  278. PUCHAR pSrc, pSrcTemp;
  279. PUCHAR pDst, pDstTemp;
  280. UCHAR PlaneMask;
  281. lMask = lMaskTable[x & 0x7];
  282. rMask = rMaskTable[(x + width - 1) & 0x7];
  283. bank1 = x >> 3;
  284. bank2 = (x + width - 1) >> 3;
  285. count = bank2 - bank1;
  286. if (bank1 == bank2) {
  287. lMask = lMask & rMask;
  288. }
  289. if (count) {
  290. bRightEdge = TRUE;
  291. count--;
  292. if (count) {
  293. bCenterSection = TRUE;
  294. }
  295. }
  296. pDst = (PUCHAR)(VgaBase + (y * DELTA) + (x / 8));
  297. pSrc = Buffer;
  298. ReadWriteMode(0x0 | 0x0);
  299. for (j=0; j<height; j++) {
  300. for (plane=0; plane<4; plane++) {
  301. pSrcTemp = pSrc;
  302. pDstTemp = pDst;
  303. PlaneMask = (UCHAR) (1 << plane);
  304. //
  305. // Convert the packed bitmap data into planar data
  306. // for this plane.
  307. //
  308. // BUGBUG: My guess this is going to be a hot spot, so
  309. // I need to revist this and optimize!! But for now
  310. // make it work.
  311. //
  312. bank = bank1;
  313. Plane[bank] = 0;
  314. Mask = PixelMask[x & 0x7];
  315. toggle = 0;
  316. for (i=0; i<width; i++) {
  317. if (toggle++ & 0x1) {
  318. if (*pSrcTemp & PlaneMask) {
  319. Plane[bank] |= Mask;
  320. }
  321. pSrcTemp++;
  322. } else {
  323. if (((*pSrcTemp) >> 4) & PlaneMask) {
  324. Plane[bank] |= Mask;
  325. }
  326. }
  327. Mask >>= 1;
  328. if (!Mask) {
  329. bank++;
  330. Plane[bank] = 0;
  331. Mask = 0x80;
  332. }
  333. }
  334. //
  335. // Set up the vga so that we see the correct bit plane.
  336. //
  337. __outpw(0x3c4, (1 << (plane + 8)) | 2);
  338. //
  339. // bank will go from bank1 to bank2
  340. //
  341. bank = bank1;
  342. pDstTemp = pDst;
  343. //
  344. // Set Bitmask for left edge.
  345. //
  346. __outpw(0x3ce, (lMask << 8) | 8);
  347. value = READ_REGISTER_UCHAR(pDstTemp);
  348. value &= ~lMask;
  349. value |= Plane[bank++];
  350. WRITE_REGISTER_UCHAR(pDstTemp++, value);
  351. if (bCenterSection) {
  352. __outpw(0x3ce, 0xff08); // enable writing to all bits
  353. for (i=0; i<count; i++) {
  354. WRITE_REGISTER_UCHAR(pDstTemp++, Plane[bank++]);
  355. }
  356. }
  357. if (bRightEdge) {
  358. //
  359. // Set bitmask for right edge.
  360. //
  361. __outpw(0x3ce, (rMask << 8) | 8);
  362. value = READ_REGISTER_UCHAR(pDstTemp);
  363. value &= ~rMask;
  364. value |= Plane[bank];
  365. WRITE_REGISTER_UCHAR(pDstTemp, value);
  366. }
  367. }
  368. pDst += DELTA;
  369. pSrc += ScanWidth;
  370. }
  371. } else {
  372. PUCHAR pDst, pDstTemp;
  373. PUCHAR pSrc, pSrcTemp;
  374. ULONG count;
  375. UCHAR Value;
  376. ULONG lMask, rMask;
  377. ULONG bank1, bank2;
  378. ULONG plane;
  379. UCHAR colorMask;
  380. bank1 = x >> 8;
  381. bank2 = (x + width - 1) >> 8;
  382. lMask = lMaskTable[x & 7];
  383. rMask = rMaskTable[(x + width - 1) & 7];
  384. if (bank1 == bank2) {
  385. lMask &= rMask;
  386. }
  387. lMask = ~lMask;
  388. rMask = ~rMask;
  389. pSrc = Buffer;
  390. pDst = (PUCHAR)(VgaBase + (y * DELTA) + (x / 8));
  391. ReadWriteMode(0x0 | 0x0);
  392. for (j=0; j<height; j++) {
  393. plane = 1;
  394. for (i=0; i<4; i++) {
  395. pDstTemp = pDst;
  396. pSrcTemp = pSrc;
  397. __outpw(0x3c4, (plane << 8) | 2);
  398. colorMask = (UCHAR)((color & plane) ? 0xff : 0x00);
  399. plane <<= 1; // bump up each time through loop
  400. count = width;
  401. //
  402. // non aligned case
  403. //
  404. if (x & 7) {
  405. //
  406. // Left Edge.
  407. //
  408. Value = READ_REGISTER_UCHAR(pDstTemp);
  409. Value &= lMask;
  410. Value |= (*pSrcTemp >> x) & colorMask;
  411. WRITE_REGISTER_UCHAR(pDstTemp++, Value);
  412. count -= (8 - x);
  413. //
  414. // Now do center section
  415. //
  416. while (count > 7) {
  417. Value = (UCHAR) ((*pSrcTemp << (8 - x)) | (*(pSrcTemp+1) >> x));
  418. Value &= colorMask;
  419. WRITE_REGISTER_UCHAR(pDstTemp++, Value);
  420. pSrcTemp++;
  421. count -= 8;
  422. }
  423. //
  424. // Now do the right edge.
  425. //
  426. if (count) {
  427. Value = READ_REGISTER_UCHAR(pDstTemp);
  428. Value &= rMask;
  429. Value |= *pSrcTemp << (8 - x) & colorMask;
  430. WRITE_REGISTER_UCHAR(pDstTemp++, Value);
  431. }
  432. } else {
  433. //
  434. // Aligned case.
  435. //
  436. ULONG ulColorMask = colorMask ? 0xffffffff : 0x00000000;
  437. USHORT usColorMask = colorMask ? 0xffff : 0x0000;
  438. while (count > 31) {
  439. WRITE_REGISTER_ULONG((PULONG)pDstTemp, (ULONG)(*((PULONG)pSrcTemp) & ulColorMask));
  440. count -= 32;
  441. pDstTemp += sizeof(ULONG)/sizeof(UCHAR);
  442. pSrcTemp += sizeof(ULONG)/sizeof(UCHAR);
  443. }
  444. while (count > 15) {
  445. WRITE_REGISTER_USHORT((PUSHORT)pDstTemp, (USHORT)(*((PUSHORT)pSrcTemp) & usColorMask));
  446. count -= 16;
  447. pDstTemp += sizeof(USHORT)/sizeof(UCHAR);
  448. pSrcTemp += sizeof(USHORT)/sizeof(UCHAR);
  449. }
  450. if (count > 7) {
  451. WRITE_REGISTER_UCHAR(pDstTemp++, (UCHAR)(*pSrcTemp++ & colorMask));
  452. count -= 8;
  453. }
  454. //
  455. // Now do any remaining bits.
  456. //
  457. if (count) {
  458. Value = READ_REGISTER_UCHAR(pDstTemp);
  459. Value &= rMask;
  460. Value |= *pSrcTemp & colorMask;
  461. WRITE_REGISTER_UCHAR(pDstTemp++, Value);
  462. }
  463. }
  464. }
  465. pSrc += ScanWidth;
  466. pDst += DELTA;
  467. }
  468. }
  469. }
  470. VOID
  471. VidBitBlt(
  472. PUCHAR Buffer,
  473. ULONG x,
  474. ULONG y
  475. )
  476. /*++
  477. Routine Description:
  478. This routine takes a bitmap resource and displays it at a given
  479. location.
  480. Arguments:
  481. Buffer - Pointer to the bitmap resource.
  482. x, y - The position at which to display the bitmap.
  483. --*/
  484. {
  485. PBITMAPINFOHEADER bih;
  486. PRGBQUAD Palette;
  487. LONG lDelta;
  488. PUCHAR pBuffer;
  489. LONG cbScanLine;
  490. bih = (PBITMAPINFOHEADER) Buffer;
  491. Palette = (PRGBQUAD)(((PUCHAR)bih) + bih->biSize);
  492. //
  493. // BUGBUG: I need to add some bitmap validation code here!
  494. //
  495. cbScanLine = (((bih->biWidth * bih->biBitCount) + 31) & ~31) >> 3;
  496. pBuffer = (PUCHAR)(Buffer + sizeof(BITMAPINFOHEADER) + 64);
  497. if (bih->biCompression == BI_RLE4) {
  498. if (bih->biWidth && bih->biHeight) {
  499. RleBitBlt(x,
  500. y,
  501. bih->biWidth,
  502. bih->biHeight,
  503. pBuffer);
  504. }
  505. } else {
  506. if (bih->biHeight < 0) {
  507. // top down bitmap
  508. lDelta = cbScanLine;
  509. bih->biHeight = -bih->biHeight;
  510. } else {
  511. // bottom up bitmap
  512. pBuffer += cbScanLine * (bih->biHeight - 1);
  513. lDelta = -cbScanLine;
  514. }
  515. if (bih->biWidth && bih->biHeight) {
  516. BitBlt(x,
  517. y,
  518. bih->biWidth,
  519. bih->biHeight,
  520. pBuffer,
  521. bih->biBitCount,
  522. lDelta);
  523. }
  524. }
  525. }
  526. VOID
  527. VidScreenToBufferBlt(
  528. PUCHAR Buffer,
  529. ULONG x,
  530. ULONG y,
  531. ULONG width,
  532. ULONG height,
  533. ULONG lDelta
  534. )
  535. /*++
  536. Routine Description:
  537. This routine allows you to copy a portion of video memory into
  538. system memory.
  539. Arguments:
  540. Buffer - Points to system memory where the video image should be copied.
  541. x, y - X,Y coordinates in video memory of top-left portion of image.
  542. width, height - width and height of the image in pixels.
  543. lDelta - width of the buffer in bytes.
  544. Notes:
  545. Upon completion, the video memory image will be in system memory. Each
  546. plane of the image are stored seperately, so the first scan line of
  547. plane 0 will be followed by the first scan line of plane 1, etc. Then
  548. the second scan of plane 0, plane 1, and so on.
  549. --*/
  550. {
  551. ULONG Plane, i, j, BankStart, BankEnd;
  552. PUCHAR pSrc, pSrcTemp, pDst;
  553. PULONG pulDstTemp;
  554. UCHAR Val1, Val2;
  555. ULONG Shift1, Shift2;
  556. UCHAR ucCombined;
  557. ULONG ulCombined;
  558. BankStart = x >> 3;
  559. BankEnd = (x + width - 1) >> 3;
  560. Shift1 = x & 7;
  561. Shift2 = 8 - Shift1;
  562. //
  563. // Zero initialize the buffer so we can or in the bits later!
  564. //
  565. pDst = Buffer;
  566. memset(pDst, 0, lDelta * height);
  567. for (Plane=0; Plane<4; Plane++) {
  568. pSrc = (PUCHAR)(VgaBase + (DELTA * y) + BankStart);
  569. pDst = Buffer;
  570. ReadWriteMode(0x0 | 0x0); // set read mode 0
  571. __outpw(0x3ce, (Plane << 8) | 0x04); // read from given plane
  572. for (j=0; j<height; j++) {
  573. pSrcTemp = pSrc;
  574. pulDstTemp = (PULONG)pDst;
  575. Val1 = READ_REGISTER_UCHAR(pSrcTemp++);
  576. for (i=BankStart; i<=BankEnd; i++) {
  577. Val2 = READ_REGISTER_UCHAR(pSrcTemp++);
  578. ucCombined = (UCHAR) ((Val1 << Shift1) | (Val2 >> Shift2));
  579. ulCombined = ((lookup[(ucCombined & 0x0f) >> 0] << 16) |
  580. lookup[(ucCombined & 0xf0) >> 4]) << Plane;
  581. *pulDstTemp++ |= ulCombined;
  582. Val1 = Val2;
  583. }
  584. pSrc += DELTA; // go to next video memory scan line
  585. pDst += lDelta; // go to next scan for this plane in buffer
  586. }
  587. }
  588. }
  589. void VidBufferToScreenBlt(
  590. PUCHAR Buffer,
  591. ULONG x,
  592. ULONG y,
  593. ULONG width,
  594. ULONG height,
  595. ULONG lDelta
  596. )
  597. /*++
  598. Routine Description:
  599. This routine allows you to copy a portion of video memory into
  600. system memory.
  601. Arguments:
  602. Buffer - Points to system memory where the video image should be copied
  603. from.
  604. x, y - X,Y coordinates in video memory of top-left portion of image.
  605. width, height - width and height of the image in pixels.
  606. lDelta - width of the buffer in bytes.
  607. Notes:
  608. This routine will allow you to blt from a buffer filled by
  609. VidScreenToBufferBlt.
  610. --*/
  611. {
  612. if (width && height) {
  613. BitBlt(x,
  614. y,
  615. width,
  616. height,
  617. Buffer,
  618. 4,
  619. lDelta);
  620. }
  621. }
  622. #pragma optimize( "", off )
  623. VOID
  624. SetPaletteEntryRGB(
  625. ULONG index,
  626. RGBQUAD rgb
  627. )
  628. {
  629. __outpb(0x3c8, index);
  630. __outpb(0x3c9, rgb.rgbRed >> 2);
  631. __outpb(0x3c9, rgb.rgbGreen >> 2);
  632. __outpb(0x3c9, rgb.rgbBlue >> 2);
  633. }
  634. VOID
  635. VgaEnableVideo()
  636. {
  637. VgaInterpretCmdStream (AT_Initialization);
  638. }
  639. VOID
  640. InitPaletteConversionTable()
  641. {
  642. /*
  643. UCHAR n;
  644. READ_PORT_UCHAR((PUCHAR)(VgaRegisterBase+INPUT_STATUS_1_COLOR));
  645. for (n=0; n<16; n++) { // Initializing table of active palette entries.
  646. WRITE_PORT_UCHAR((PUCHAR)(VgaRegisterBase+ATT_ADDRESS_PORT), n);
  647. WRITE_PORT_UCHAR((PUCHAR)(VgaRegisterBase+ATT_ADDRESS_PORT), n);
  648. }
  649. */
  650. VgaEnableVideo();
  651. }
  652. VOID
  653. InitializePalette(
  654. VOID
  655. )
  656. {
  657. ULONG Palette[] =
  658. {
  659. 0x00000000,
  660. 0x00000020,
  661. 0x00002000,
  662. 0x00002020,
  663. 0x00200000,
  664. 0x00200020,
  665. 0x00202000,
  666. 0x00202020,
  667. 0x00303030,
  668. 0x0000003f,
  669. 0x00003f00,
  670. 0x00003f3f,
  671. 0x003f0000,
  672. 0x003f003f,
  673. 0x003f3f00,
  674. 0x003f3f3f,
  675. };
  676. ULONG i;
  677. for (i=0; i<16; i++) {
  678. PRGBQUAD p = (PRGBQUAD)(Palette+i);
  679. SetPaletteEntryRGB(i, *p);
  680. }
  681. }
  682. VOID
  683. InitPaletteWithTable(
  684. PRGBQUAD Palette,
  685. ULONG count
  686. )
  687. {
  688. UCHAR i;
  689. InitPaletteConversionTable();
  690. count = 16;
  691. for (i=0; i<count; i++)
  692. SetPaletteEntryRGB (i, *Palette++);
  693. }
  694. VOID
  695. InitPaletteWithBlack(
  696. VOID
  697. )
  698. {
  699. ULONG i;
  700. // RGBQUAD black = {0x3f,0x3f,0x3f,0x3f};
  701. RGBQUAD black = {0,0,0,0};
  702. InitPaletteConversionTable();
  703. //InitializePalette();
  704. for (i=0; i<16; i++)
  705. SetPaletteEntryRGB(i, black);
  706. }
  707. VOID
  708. WaitForVsync(
  709. VOID
  710. )
  711. /*++
  712. Routine Description:
  713. Wait for a v-sync
  714. --*/
  715. {
  716. //
  717. // Check to see if vsync's are being generated.
  718. //
  719. WRITE_PORT_UCHAR((VgaRegisterBase+0x3c4), 00);
  720. if (READ_PORT_UCHAR(VgaRegisterBase+0x3c5) & 0x2) {
  721. ULONG MaxDelay;
  722. //
  723. // Slight delay. Wait for one vsync.
  724. //
  725. MaxDelay = 100000;
  726. while (((READ_PORT_UCHAR(VgaRegisterBase+0x3da) & 0x08) == 0x08) && MaxDelay--);
  727. MaxDelay = 100000;
  728. while (((READ_PORT_UCHAR(VgaRegisterBase+0x3da) & 0x08) == 0x00) && MaxDelay--);
  729. }
  730. }
  731. BOOLEAN
  732. VgaInterpretCmdStream(
  733. PUSHORT pusCmdStream
  734. )
  735. /*++
  736. Routine Description:
  737. Interprets the appropriate command array to set up VGA registers for the
  738. requested mode. Typically used to set the VGA into a particular mode by
  739. programming all of the registers
  740. Arguments:
  741. pusCmdStream - array of commands to be interpreted.
  742. Return Value:
  743. The status of the operation (can only fail on a bad command); TRUE for
  744. success, FALSE for failure.
  745. --*/
  746. {
  747. ULONG ulCmd;
  748. ULONG_PTR ulPort;
  749. UCHAR jValue;
  750. USHORT usValue;
  751. ULONG culCount;
  752. ULONG ulIndex;
  753. ULONG_PTR ulBase;
  754. if (pusCmdStream == NULL) {
  755. //KdPrint(("VgaInterpretCmdStream: pusCmdStream == NULL\n"));
  756. return TRUE;
  757. }
  758. ulBase = (ULONG_PTR) VgaRegisterBase;
  759. //
  760. // Now set the adapter to the desired mode.
  761. //
  762. while ((ulCmd = *pusCmdStream++) != EOD) {
  763. WaitForVsync();
  764. //
  765. // Determine major command type
  766. //
  767. switch (ulCmd & 0xF0) {
  768. //
  769. // Basic input/output command
  770. //
  771. case INOUT:
  772. //
  773. // Determine type of inout instruction
  774. //
  775. if (!(ulCmd & IO)) {
  776. //
  777. // Out instruction. Single or multiple outs?
  778. //
  779. if (!(ulCmd & MULTI)) {
  780. //
  781. // Single out. Byte or word out?
  782. //
  783. if (!(ulCmd & BW)) {
  784. //
  785. // Single byte out
  786. //
  787. ulPort = *pusCmdStream++;
  788. jValue = (UCHAR) *pusCmdStream++;
  789. WRITE_PORT_UCHAR((PUCHAR)(ulBase+ulPort),
  790. jValue);
  791. } else {
  792. //
  793. // Single word out
  794. //
  795. ulPort = *pusCmdStream++;
  796. usValue = *pusCmdStream++;
  797. WRITE_PORT_USHORT((PUSHORT)(ulBase+ulPort),
  798. usValue);
  799. }
  800. } else {
  801. //
  802. // Output a string of values
  803. // Byte or word outs?
  804. //
  805. if (!(ulCmd & BW)) {
  806. //
  807. // String byte outs. Do in a loop; can't use
  808. // VideoPortWritePortBufferUchar because the data
  809. // is in USHORT form
  810. //
  811. ulPort = ulBase + *pusCmdStream++;
  812. culCount = *pusCmdStream++;
  813. while (culCount--) {
  814. jValue = (UCHAR) *pusCmdStream++;
  815. WRITE_PORT_UCHAR((PUCHAR)ulPort,
  816. jValue);
  817. }
  818. } else {
  819. //
  820. // String word outs
  821. //
  822. ulPort = *pusCmdStream++;
  823. culCount = *pusCmdStream++;
  824. WRITE_PORT_BUFFER_USHORT((PUSHORT)
  825. (ulBase + ulPort), pusCmdStream, culCount);
  826. pusCmdStream += culCount;
  827. }
  828. }
  829. } else {
  830. // In instruction
  831. //
  832. // Currently, string in instructions aren't supported; all
  833. // in instructions are handled as single-byte ins
  834. //
  835. // Byte or word in?
  836. //
  837. if (!(ulCmd & BW)) {
  838. //
  839. // Single byte in
  840. //
  841. ulPort = *pusCmdStream++;
  842. jValue = READ_PORT_UCHAR((PUCHAR)ulBase+ulPort);
  843. } else {
  844. //
  845. // Single word in
  846. //
  847. ulPort = *pusCmdStream++;
  848. usValue = READ_PORT_USHORT((PUSHORT)
  849. (ulBase+ulPort));
  850. }
  851. }
  852. break;
  853. //
  854. // Higher-level input/output commands
  855. //
  856. case METAOUT:
  857. //
  858. // Determine type of metaout command, based on minor
  859. // command field
  860. //
  861. switch (ulCmd & 0x0F) {
  862. //
  863. // Indexed outs
  864. //
  865. case INDXOUT:
  866. ulPort = ulBase + *pusCmdStream++;
  867. culCount = *pusCmdStream++;
  868. ulIndex = *pusCmdStream++;
  869. while (culCount--) {
  870. usValue = (USHORT) (ulIndex +
  871. (((ULONG)(*pusCmdStream++)) << 8));
  872. WRITE_PORT_USHORT((PUSHORT)ulPort, usValue);
  873. ulIndex++;
  874. }
  875. break;
  876. //
  877. // Masked out (read, AND, XOR, write)
  878. //
  879. case MASKOUT:
  880. ulPort = *pusCmdStream++;
  881. jValue = READ_PORT_UCHAR((PUCHAR)ulBase+ulPort);
  882. jValue &= *pusCmdStream++;
  883. jValue ^= *pusCmdStream++;
  884. WRITE_PORT_UCHAR((PUCHAR)ulBase + ulPort,
  885. jValue);
  886. break;
  887. //
  888. // Attribute Controller out
  889. //
  890. case ATCOUT:
  891. ulPort = ulBase + *pusCmdStream++;
  892. culCount = *pusCmdStream++;
  893. ulIndex = *pusCmdStream++;
  894. while (culCount--) {
  895. // Write Attribute Controller index
  896. WRITE_PORT_UCHAR((PUCHAR)ulPort,
  897. (UCHAR)ulIndex);
  898. // Write Attribute Controller data
  899. jValue = (UCHAR) *pusCmdStream++;
  900. WRITE_PORT_UCHAR((PUCHAR)ulPort, jValue);
  901. ulIndex++;
  902. }
  903. break;
  904. //
  905. // None of the above; error
  906. //
  907. default:
  908. return FALSE;
  909. }
  910. break;
  911. //
  912. // NOP
  913. //
  914. case NCMD:
  915. break;
  916. //
  917. // Unknown command; error
  918. //
  919. default:
  920. return FALSE;
  921. }
  922. }
  923. return TRUE;
  924. } // end VgaInterpretCmdStream()