ReactOS  0.4.12-dev-432-g3463b2d
vga.c
Go to the documentation of this file.
1 #include "precomp.h"
2 
3 /* GLOBALS *******************************************************************/
4 
5 static ULONG ScrollRegion[4] =
6 {
7  0,
8  0,
9  640 - 1,
10  480 - 1
11 };
12 static UCHAR lMaskTable[8] =
13 {
14  (1 << 8) - (1 << 0),
15  (1 << 7) - (1 << 0),
16  (1 << 6) - (1 << 0),
17  (1 << 5) - (1 << 0),
18  (1 << 4) - (1 << 0),
19  (1 << 3) - (1 << 0),
20  (1 << 2) - (1 << 0),
21  (1 << 1) - (1 << 0)
22 };
23 static UCHAR rMaskTable[8] =
24 {
25  (1 << 7),
26  (1 << 7)+ (1 << 6),
27  (1 << 7)+ (1 << 6) + (1 << 5),
28  (1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4),
29  (1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3),
30  (1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3) + (1 << 2),
31  (1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3) + (1 << 2) + (1 << 1),
32  (1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3) + (1 << 2) + (1 << 1) +
33  (1 << 0),
34 };
36 {
37  (1 << 7),
38  (1 << 6),
39  (1 << 5),
40  (1 << 4),
41  (1 << 3),
42  (1 << 2),
43  (1 << 1),
44  (1 << 0),
45 };
46 static ULONG lookup[16] =
47 {
48  0x0000,
49  0x0100,
50  0x1000,
51  0x1100,
52  0x0001,
53  0x0101,
54  0x1001,
55  0x1101,
56  0x0010,
57  0x0110,
58  0x1010,
59  0x1110,
60  0x0011,
61  0x0111,
62  0x1011,
63  0x1111,
64 };
65 
70 static ULONG VidTextColor = 0xF;
72 
73 #define __outpb(Port, Value) \
74  WRITE_PORT_UCHAR((PUCHAR)(VgaRegisterBase + (Port)), (UCHAR)(Value))
75 
76 #define __outpw(Port, Value) \
77  WRITE_PORT_USHORT((PUSHORT)(VgaRegisterBase + (Port)), (USHORT)(Value))
78 
79 /* PRIVATE FUNCTIONS *********************************************************/
80 
81 static VOID
82 NTAPI
84 {
85  UCHAR Value;
86 
87  /* Switch to graphics mode register */
88  __outpb(0x3CE, 5);
89 
90  /* Get the current register value, minus the current mode */
91  Value = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) & 0xF4;
92 
93  /* Set the new mode */
94  __outpb(0x3CF, Mode | Value);
95 }
96 
98 VOID
100  IN ULONG Top,
101  IN UCHAR Color)
102 {
103  PUCHAR PixelPosition;
104 
105  /* Calculate the pixel position. */
106  PixelPosition = (PUCHAR)(VgaBase + (Left >> 3) + (Top * 80));
107 
108  /* Select the bitmask register and write the mask */
109  __outpw(0x3CE, (PixelMask[Left & 7] << 8) | 8);
110 
111  /* Read the current pixel value and add our color */
112  WRITE_REGISTER_UCHAR(PixelPosition,
113  READ_REGISTER_UCHAR(PixelPosition) & Color);
114 }
115 
116 #define SET_PIXELS(_PixelPtr, _PixelMask, _TextColor) \
117 do { \
118  /* Select the bitmask register and write the mask */ \
119  __outpw(0x3CE, ((_PixelMask) << 8) | 8); \
120  /* Set the new color */ \
121  WRITE_REGISTER_UCHAR((_PixelPtr), (UCHAR)(_TextColor)); \
122 } while (0);
123 
124 #ifdef CHAR_GEN_UPSIDE_DOWN
125 # define GetFontPtr(_Char) &FontData[_Char * BOOTCHAR_HEIGHT] + BOOTCHAR_HEIGHT - 1;
126 # define FONT_PTR_DELTA (-1)
127 #else
128 # define GetFontPtr(_Char) &FontData[_Char * BOOTCHAR_HEIGHT];
129 # define FONT_PTR_DELTA (1)
130 #endif
131 
132 static VOID
133 NTAPI
135  IN ULONG Left,
136  IN ULONG Top,
137  IN ULONG TextColor,
138  IN ULONG BackColor)
139 {
140  PUCHAR FontChar, PixelPtr;
141  ULONG Height;
142  UCHAR Shift;
143 
144  /* Switch to mode 10 */
145  ReadWriteMode(10);
146 
147  /* Clear the 4 planes (we're already in unchained mode here) */
148  __outpw(0x3C4, 0xF02);
149 
150  /* Select the color don't care register */
151  __outpw(0x3CE, 7);
152 
153  /* Calculate shift */
154  Shift = Left & 7;
155 
156  /* Get the font and pixel pointer */
157  FontChar = GetFontPtr(Character);
158  PixelPtr = (PUCHAR)(VgaBase + (Left >> 3) + (Top * 80));
159 
160  /* Loop all pixel rows */
161  Height = BOOTCHAR_HEIGHT;
162  do
163  {
164  SET_PIXELS(PixelPtr, *FontChar >> Shift, TextColor);
165  PixelPtr += 80;
166  FontChar += FONT_PTR_DELTA;
167  } while (--Height);
168 
169  /* Check if we need to update neighbor bytes */
170  if (Shift)
171  {
172  /* Calculate shift for 2nd byte */
173  Shift = 8 - Shift;
174 
175  /* Get the font and pixel pointer (2nd byte) */
176  FontChar = GetFontPtr(Character);
177  PixelPtr = (PUCHAR)(VgaBase + (Left >> 3) + (Top * 80) + 1);
178 
179  /* Loop all pixel rows */
180  Height = BOOTCHAR_HEIGHT;
181  do
182  {
183  SET_PIXELS(PixelPtr, *FontChar << Shift, TextColor);
184  PixelPtr += 80;
185  FontChar += FONT_PTR_DELTA;
186  } while (--Height);
187  }
188 
189  /* Check if the background color is transparent */
190  if (BackColor >= 16)
191  {
192  /* We are done */
193  return;
194  }
195 
196  /* Calculate shift */
197  Shift = Left & 7;
198 
199  /* Get the font and pixel pointer */
200  FontChar = GetFontPtr(Character);
201  PixelPtr = (PUCHAR)(VgaBase + (Left >> 3) + (Top * 80));
202 
203  /* Loop all pixel rows */
204  Height = BOOTCHAR_HEIGHT;
205  do
206  {
207  SET_PIXELS(PixelPtr, ~*FontChar >> Shift, BackColor);
208  PixelPtr += 80;
209  FontChar += FONT_PTR_DELTA;
210  } while (--Height);
211 
212  /* Check if we need to update neighbor bytes */
213  if (Shift)
214  {
215  /* Calculate shift for 2nd byte */
216  Shift = 8 - Shift;
217 
218  /* Get the font and pixel pointer (2nd byte) */
219  FontChar = GetFontPtr(Character);
220  PixelPtr = (PUCHAR)(VgaBase + (Left >> 3) + (Top * 80) + 1);
221 
222  /* Loop all pixel rows */
223  Height = BOOTCHAR_HEIGHT;
224  do
225  {
226  SET_PIXELS(PixelPtr, ~*FontChar << Shift, BackColor);
227  PixelPtr += 80;
228  FontChar += FONT_PTR_DELTA;
229  } while (--Height);
230  }
231 }
232 
233 static VOID
234 NTAPI
236  IN ULONG Left,
237  IN ULONG Top,
238  IN ULONG TextColor,
239  IN ULONG BackColor)
240 {
241  /* Loop every character */
242  while (*String)
243  {
244  /* Display a character */
245  DisplayCharacter(*String, Left, Top, TextColor, BackColor);
246 
247  /* Move to next character and next position */
248  String++;
249  Left += 8;
250  }
251 }
252 
253 static VOID
254 NTAPI
256  IN ULONG Rgb)
257 {
258  PCHAR Colors = (PCHAR)&Rgb;
259 
260  /* Set the palette index */
261  __outpb(0x3C8, (UCHAR)Id);
262 
263  /* Set RGB colors */
264  __outpb(0x3C9, Colors[2] >> 2);
265  __outpb(0x3C9, Colors[1] >> 2);
266  __outpb(0x3C9, Colors[0] >> 2);
267 }
268 
269 static VOID
270 NTAPI
272  IN ULONG Count)
273 {
274  ULONG i;
275  PULONG Entry = Table;
276 
277  /* Loop every entry */
278  for (i = 0; i < Count; i++, Entry++)
279  {
280  /* Set the entry */
282  }
283 }
284 
285 static VOID
286 NTAPI
288  IN ULONG PaletteEntry)
289 {
290  /* Set the palette index */
291  __outpb(0x3C8, (UCHAR)Id);
292 
293  /* Set RGB colors */
294  __outpb(0x3C9, PaletteEntry & 0xFF);
295  __outpb(0x3C9, (PaletteEntry >>= 8) & 0xFF);
296  __outpb(0x3C9, (PaletteEntry >> 8) & 0xFF);
297 }
298 
299 VOID
300 NTAPI
302 {
303  ULONG PaletteEntry[16] = {0x000000,
304  0x000020,
305  0x002000,
306  0x002020,
307  0x200000,
308  0x200020,
309  0x202000,
310  0x202020,
311  0x303030,
312  0x00003F,
313  0x003F00,
314  0x003F3F,
315  0x3F0000,
316  0x3F003F,
317  0x3F3F00,
318  0x3F3F3F};
319  ULONG i;
320 
321  /* Loop all the entries and set their palettes */
322  for (i = 0; i < 16; i++) SetPaletteEntry(i, PaletteEntry[i]);
323 }
324 
325 static VOID
326 NTAPI
328 {
329  ULONG Top, RowSize;
330  PUCHAR OldPosition, NewPosition;
331 
332  /* Clear the 4 planes */
333  __outpw(0x3C4, 0xF02);
334 
335  /* Set the bitmask to 0xFF for all 4 planes */
336  __outpw(0x3CE, 0xFF08);
337 
338  /* Set Mode 1 */
339  ReadWriteMode(1);
340 
341  RowSize = (ScrollRegion[2] - ScrollRegion[0] + 1) / 8;
342 
343  /* Calculate the position in memory for the row */
344  OldPosition = (PUCHAR)(VgaBase + (ScrollRegion[1] + Scroll) * 80 + ScrollRegion[0] / 8);
345  NewPosition = (PUCHAR)(VgaBase + ScrollRegion[1] * 80 + ScrollRegion[0] / 8);
346 
347  /* Start loop */
348  for (Top = ScrollRegion[1]; Top <= ScrollRegion[3]; ++Top)
349  {
350 #if defined(_M_IX86) || defined(_M_AMD64)
351  __movsb(NewPosition, OldPosition, RowSize);
352 #else
353  ULONG i;
354 
355  /* Scroll the row */
356  for (i = 0; i < RowSize; ++i)
357  WRITE_REGISTER_UCHAR(NewPosition + i, READ_REGISTER_UCHAR(OldPosition + i));
358 #endif
359  OldPosition += 80;
360  NewPosition += 80;
361  }
362 }
363 
364 static VOID
365 NTAPI
366 PreserveRow(IN ULONG CurrentTop,
367  IN ULONG TopDelta,
369 {
370  PUCHAR Position1, Position2;
371  ULONG Count;
372 
373  /* Clear the 4 planes */
374  __outpw(0x3C4, 0xF02);
375 
376  /* Set the bitmask to 0xFF for all 4 planes */
377  __outpw(0x3CE, 0xFF08);
378 
379  /* Set Mode 1 */
380  ReadWriteMode(1);
381 
382  /* Check which way we're preserving */
383  if (Direction)
384  {
385  /* Calculate the position in memory for the row */
386  Position1 = (PUCHAR)(VgaBase + CurrentTop * 80);
387  Position2 = (PUCHAR)(VgaBase + 0x9600);
388  }
389  else
390  {
391  /* Calculate the position in memory for the row */
392  Position1 = (PUCHAR)(VgaBase + 0x9600);
393  Position2 = (PUCHAR)(VgaBase + CurrentTop * 80);
394  }
395 
396  /* Set the count and loop every pixel */
397  Count = TopDelta * 80;
398 
399 #if defined(_M_IX86) || defined(_M_AMD64)
400  __movsb(Position1, Position2, Count);
401 #else
402  while (Count--)
403  {
404  /* Write the data back on the other position */
405  WRITE_REGISTER_UCHAR(Position1, READ_REGISTER_UCHAR(Position2));
406 
407  /* Increase both positions */
408  Position1++;
409  Position2++;
410  }
411 #endif
412 }
413 
414 static VOID
415 NTAPI
417  IN ULONG Top,
418  IN ULONG Width,
419  IN ULONG Height,
420  IN PUCHAR Buffer,
421  IN ULONG BitsPerPixel,
422  IN ULONG Delta)
423 {
424  ULONG sx, dx, dy;
425  UCHAR color;
426  ULONG offset = 0;
427  const ULONG Bottom = Top + Height;
428  const ULONG Right = Left + Width;
429 
430  /* Check if the buffer isn't 4bpp */
431  if (BitsPerPixel != 4)
432  {
433  /* FIXME: TODO */
434  DbgPrint("Unhandled BitBlt\n"
435  "%lux%lu @ (%lu|%lu)\n"
436  "Bits Per Pixel %lu\n"
437  "Buffer: %p. Delta: %lu\n",
438  Width,
439  Height,
440  Left,
441  Top,
442  BitsPerPixel,
443  Buffer,
444  Delta);
445  return;
446  }
447 
448  /* Switch to mode 10 */
449  ReadWriteMode(10);
450 
451  /* Clear the 4 planes (we're already in unchained mode here) */
452  __outpw(0x3C4, 0xF02);
453 
454  /* Select the color don't care register */
455  __outpw(0x3CE, 7);
456 
457  /* 4bpp blitting */
458  dy = Top;
459  do
460  {
461  sx = 0;
462  do
463  {
464  /* Extract color */
465  color = Buffer[offset + sx];
466 
467  /* Calc destination x */
468  dx = Left + (sx << 1);
469 
470  /* Set two pixels */
471  SetPixel(dx, dy, color >> 4);
472  SetPixel(dx + 1, dy, color & 0x0F);
473 
474  sx++;
475  } while (dx < Right);
476  offset += Delta;
477  dy++;
478  } while (dy < Bottom);
479 }
480 
481 static VOID
482 NTAPI
484  IN ULONG Top,
485  IN ULONG Width,
486  IN ULONG Height,
487  IN PUCHAR Buffer)
488 {
489  ULONG YDelta;
490  ULONG x;
491  ULONG RleValue, NewRleValue;
492  ULONG Color, Color2;
493  ULONG i, j;
494  ULONG Code;
495 
496  /* Switch to mode 10 */
497  ReadWriteMode(10);
498 
499  /* Clear the 4 planes (we're already in unchained mode here) */
500  __outpw(0x3C4, 0xF02);
501 
502  /* Select the color don't care register */
503  __outpw(0x3CE, 7);
504 
505  /* Set Y height and current X value and start loop */
506  YDelta = Top + Height - 1;
507  x = Left;
508  for (;;)
509  {
510  /* Get the current value and advance in the buffer */
511  RleValue = *Buffer;
512  Buffer++;
513  if (RleValue)
514  {
515  /* Check if we've gone past the edge */
516  if ((x + RleValue) > (Width + Left))
517  {
518  /* Fixup the pixel value */
519  RleValue = Left - x + Width;
520  }
521 
522  /* Get the new value */
523  NewRleValue = *Buffer;
524 
525  /* Get the two colors */
526  Color = NewRleValue >> 4;
527  Color2 = NewRleValue & 0xF;
528 
529  /* Increase buffer position */
530  Buffer++;
531 
532  /* Check if we need to do a fill */
533  if (Color == Color2)
534  {
535  /* Do a fill and continue the loop */
536  RleValue += x;
537  VidSolidColorFill(x, YDelta, RleValue - 1, YDelta, (UCHAR)Color);
538  x = RleValue;
539  continue;
540  }
541 
542  /* Check if the pixel value is 1 or below */
543  if (RleValue > 1)
544  {
545  /* Set loop variables */
546  i = (RleValue - 2) / 2 + 1;
547  do
548  {
549  /* Set the pixels */
550  SetPixel(x, YDelta, (UCHAR)Color);
551  x++;
552  SetPixel(x, YDelta, (UCHAR)Color2);
553  x++;
554 
555  /* Decrease pixel value */
556  RleValue -= 2;
557  } while (--i);
558  }
559 
560  /* Check if there is any value at all */
561  if (RleValue)
562  {
563  /* Set the pixel and increase position */
564  SetPixel(x, YDelta, (UCHAR)Color);
565  x++;
566  }
567 
568  /* Start over */
569  continue;
570  }
571 
572  /* Get the current pixel value */
573  RleValue = *Buffer;
574  Code = RleValue;
575  switch (Code)
576  {
577  /* Case 0 */
578  case 0:
579  {
580  /* Set new x value, decrease distance and restart */
581  x = Left;
582  YDelta--;
583  Buffer++;
584  continue;
585  }
586 
587  /* Case 1 */
588  case 1:
589  {
590  /* Done */
591  return;
592  }
593 
594  /* Case 2 */
595  case 2:
596  {
597  /* Set new x value, decrease distance and restart */
598  Buffer++;
599  x += *Buffer;
600  Buffer++;
601  YDelta -= *Buffer;
602  Buffer++;
603  continue;
604  }
605 
606  /* Other values */
607  default:
608  {
609  Buffer++;
610  break;
611  }
612  }
613 
614  /* Check if we've gone past the edge */
615  if ((x + RleValue) > (Width + Left))
616  {
617  /* Set fixed up loop count */
618  i = RleValue - Left - Width + x;
619 
620  /* Fixup pixel value */
621  RleValue -= i;
622  }
623  else
624  {
625  /* Clear loop count */
626  i = 0;
627  }
628 
629  /* Check the value now */
630  if (RleValue > 1)
631  {
632  /* Set loop variables */
633  j = (RleValue - 2) / 2 + 1;
634  do
635  {
636  /* Get the new value */
637  NewRleValue = *Buffer;
638 
639  /* Get the two colors */
640  Color = NewRleValue >> 4;
641  Color2 = NewRleValue & 0xF;
642 
643  /* Increase buffer position */
644  Buffer++;
645 
646  /* Set the pixels */
647  SetPixel(x, YDelta, (UCHAR)Color);
648  x++;
649  SetPixel(x, YDelta, (UCHAR)Color2);
650  x++;
651 
652  /* Decrease pixel value */
653  RleValue -= 2;
654  } while (--j);
655  }
656 
657  /* Check if there is any value at all */
658  if (RleValue)
659  {
660  /* Set the pixel and increase position */
661  Color = *Buffer >> 4;
662  Buffer++;
663  SetPixel(x, YDelta, (UCHAR)Color);
664  x++;
665  i--;
666  }
667 
668  /* Check loop count now */
669  if ((LONG)i > 0)
670  {
671  /* Decrease it */
672  i--;
673 
674  /* Set new position */
675  Buffer = Buffer + (i / 2) + 1;
676  }
677 
678  /* Check if we need to increase the buffer */
679  if ((ULONG_PTR)Buffer & 1) Buffer++;
680  }
681 }
682 
683 /* PUBLIC FUNCTIONS **********************************************************/
684 
685 /*
686  * @implemented
687  */
688 ULONG
689 NTAPI
691 {
692  ULONG OldColor;
693 
694  /* Save the old color and set the new one */
695  OldColor = VidTextColor;
697  return OldColor;
698 }
699 
700 /*
701  * @implemented
702  */
703 VOID
704 NTAPI
706  IN ULONG Left,
707  IN ULONG Top,
708  IN BOOLEAN Transparent)
709 {
710  ULONG BackColor;
711 
712  /*
713  * If the caller wanted transparent, then send the special value (16),
714  * else use our default and call the helper routine.
715  */
716  BackColor = Transparent ? 16 : 14;
717  DisplayStringXY(String, Left, Top, 12, BackColor);
718 }
719 
720 /*
721  * @implemented
722  */
723 VOID
724 NTAPI
726  IN ULONG Top,
727  IN ULONG Right,
728  IN ULONG Bottom)
729 {
730  /* Assert alignment */
731  ASSERT((Left & 0x7) == 0);
732  ASSERT((Right & 0x7) == 7);
733 
734  /* Set Scroll Region */
735  ScrollRegion[0] = Left;
736  ScrollRegion[1] = Top;
737  ScrollRegion[2] = Right;
738  ScrollRegion[3] = Bottom;
739 
740  /* Set current X and Y */
741  curr_x = Left;
742  curr_y = Top;
743 }
744 
745 /*
746  * @implemented
747  */
748 VOID
749 NTAPI
751 {
752  /* Select bit mask register */
754 
755  /* Clear it */
756  WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 255);
757 }
758 
759 /*
760  * @implemented
761  */
762 VOID
763 NTAPI
765  IN ULONG Left,
766  IN ULONG Top,
767  IN ULONG Width,
768  IN ULONG Height,
769  IN ULONG Delta)
770 {
771  /* Make sure we have a width and height */
772  if (!Width || !Height) return;
773 
774  /* Call the helper function */
775  BitBlt(Left, Top, Width, Height, Buffer, 4, Delta);
776 }
777 
778 /*
779  * @implemented
780  */
781 VOID
782 NTAPI
784 {
785  ULONG TopDelta = BOOTCHAR_HEIGHT + 1;
786 
787  /* Start looping the string */
788  while (*String)
789  {
790  /* Treat new-line separately */
791  if (*String == '\n')
792  {
793  /* Modify Y position */
794  curr_y += TopDelta;
795  if (curr_y + TopDelta >= ScrollRegion[3])
796  {
797  /* Scroll the view */
798  VgaScroll(TopDelta);
799  curr_y -= TopDelta;
800  }
801  else
802  {
803  /* Preserve row */
804  PreserveRow(curr_y, TopDelta, FALSE);
805  }
806 
807  /* Update current X */
808  curr_x = ScrollRegion[0];
809 
810  /* Do not clear line if "\r\n" is given */
812  }
813  else if (*String == '\r')
814  {
815  /* Update current X */
816  curr_x = ScrollRegion[0];
817 
818  /* Check if we're being followed by a new line */
820  }
821  else
822  {
823  /* check if we had a '\r' last time */
824  if (CarriageReturn)
825  {
826  /* We did, clear the current row */
827  PreserveRow(curr_y, TopDelta, TRUE);
829  }
830 
831  /* Display this character */
833  curr_x += 8;
834 
835  /* Check if we should scroll */
836  if (curr_x + 8 > ScrollRegion[2])
837  {
838  /* Update Y position and check if we should scroll it */
839  curr_y += TopDelta;
840  if (curr_y + TopDelta > ScrollRegion[3])
841  {
842  /* Do the scroll */
843  VgaScroll(TopDelta);
844  curr_y -= TopDelta;
845  }
846  else
847  {
848  /* Preserve the current row */
849  PreserveRow(curr_y, TopDelta, FALSE);
850  }
851 
852  /* Update X */
853  curr_x = ScrollRegion[0];
854  }
855  }
856 
857  /* Get the next character */
858  String++;
859  }
860 }
861 
862 /*
863  * @implemented
864  */
865 VOID
866 NTAPI
868  IN ULONG Left,
869  IN ULONG Top)
870 {
871  PBITMAPINFOHEADER BitmapInfoHeader;
872  LONG Delta;
873  PUCHAR BitmapOffset;
874 
875  /* Get the Bitmap Header */
876  BitmapInfoHeader = (PBITMAPINFOHEADER)Buffer;
877 
878  /* Initialize the palette */
879  InitPaletteWithTable((PULONG)(Buffer + BitmapInfoHeader->biSize),
880  (BitmapInfoHeader->biClrUsed) ?
881  BitmapInfoHeader->biClrUsed : 16);
882 
883  /* Make sure we can support this bitmap */
884  ASSERT((BitmapInfoHeader->biBitCount * BitmapInfoHeader->biPlanes) <= 4);
885 
886  /*
887  * Calculate the delta and align it on 32-bytes, then calculate
888  * the actual start of the bitmap data.
889  */
890  Delta = (BitmapInfoHeader->biBitCount * BitmapInfoHeader->biWidth) + 31;
891  Delta >>= 3;
892  Delta &= ~3;
893  BitmapOffset = Buffer + sizeof(BITMAPINFOHEADER) + 16 * sizeof(ULONG);
894 
895  /* Check the compression of the bitmap */
896  if (BitmapInfoHeader->biCompression == BI_RLE4)
897  {
898  /* Make sure we have a width and a height */
899  if ((BitmapInfoHeader->biWidth) && (BitmapInfoHeader->biHeight))
900  {
901  /* We can use RLE Bit Blt */
902  RleBitBlt(Left,
903  Top,
904  BitmapInfoHeader->biWidth,
905  BitmapInfoHeader->biHeight,
906  BitmapOffset);
907  }
908  }
909  else
910  {
911  /* Check if the height is negative */
912  if (BitmapInfoHeader->biHeight < 0)
913  {
914  /* Make it positive in the header */
915  BitmapInfoHeader->biHeight *= -1;
916  }
917  else
918  {
919  /* Update buffer offset */
920  BitmapOffset += ((BitmapInfoHeader->biHeight - 1) * Delta);
921  Delta *= -1;
922  }
923 
924  /* Make sure we have a width and a height */
925  if ((BitmapInfoHeader->biWidth) && (BitmapInfoHeader->biHeight))
926  {
927  /* Do the BitBlt */
928  BitBlt(Left,
929  Top,
930  BitmapInfoHeader->biWidth,
931  BitmapInfoHeader->biHeight,
932  BitmapOffset,
933  BitmapInfoHeader->biBitCount,
934  Delta);
935  }
936  }
937 }
938 
939 /*
940  * @implemented
941  */
942 VOID
943 NTAPI
945  IN ULONG Left,
946  IN ULONG Top,
947  IN ULONG Width,
948  IN ULONG Height,
949  IN ULONG Delta)
950 {
951  ULONG Plane;
952  ULONG XDistance;
953  ULONG LeftDelta, RightDelta;
954  ULONG PixelOffset;
955  PUCHAR PixelPosition;
956  PUCHAR k, i;
957  PULONG m;
958  UCHAR Value, Value2;
959  UCHAR a;
960  ULONG b;
961  ULONG x, y;
962 
963  /* Calculate total distance to copy on X */
964  XDistance = Left + Width - 1;
965 
966  /* Start at plane 0 */
967  Plane = 0;
968 
969  /* Calculate the 8-byte left and right deltas */
970  LeftDelta = Left & 7;
971  RightDelta = 8 - LeftDelta;
972 
973  /* Clear the destination buffer */
974  RtlZeroMemory(Buffer, Delta * Height);
975 
976  /* Calculate the pixel offset and convert the X distance into byte form */
977  PixelOffset = Top * 80 + (Left >> 3);
978  XDistance >>= 3;
979 
980  /* Loop the 4 planes */
981  do
982  {
983  /* Set the current pixel position and reset buffer loop variable */
984  PixelPosition = (PUCHAR)(VgaBase + PixelOffset);
985  i = Buffer;
986 
987  /* Set Mode 0 */
988  ReadWriteMode(0);
989 
990  /* Set the current plane */
991  __outpw(0x3CE, (Plane << 8) | 4);
992 
993  /* Make sure we have a height */
994  if (Height > 0)
995  {
996  /* Start the outer Y loop */
997  y = Height;
998  do
999  {
1000  /* Read the current value */
1001  m = (PULONG)i;
1002  Value = READ_REGISTER_UCHAR(PixelPosition);
1003 
1004  /* Set Pixel Position loop variable */
1005  k = PixelPosition + 1;
1006 
1007  /* Check if we're still within bounds */
1008  if (Left <= XDistance)
1009  {
1010  /* Start X Inner loop */
1011  x = (XDistance - Left) + 1;
1012  do
1013  {
1014  /* Read the current value */
1015  Value2 = READ_REGISTER_UCHAR(k);
1016 
1017  /* Increase pixel position */
1018  k++;
1019 
1020  /* Do the blt */
1021  a = Value2 >> (UCHAR)RightDelta;
1022  a |= Value << (UCHAR)LeftDelta;
1023  b = lookup[a & 0xF];
1024  a >>= 4;
1025  b <<= 16;
1026  b |= lookup[a];
1027 
1028  /* Save new value to buffer */
1029  *m |= (b << Plane);
1030 
1031  /* Move to next destination location */
1032  m++;
1033 
1034  /* Write new value */
1035  Value = Value2;
1036  } while (--x);
1037  }
1038 
1039  /* Update pixel position */
1040  PixelPosition += 80;
1041  i += Delta;
1042  } while (--y);
1043  }
1044  } while (++Plane < 4);
1045 }
1046 
1047 /*
1048  * @implemented
1049  */
1050 VOID
1051 NTAPI
1053  IN ULONG Top,
1054  IN ULONG Right,
1055  IN ULONG Bottom,
1056  IN UCHAR Color)
1057 {
1058  ULONG rMask, lMask;
1059  ULONG LeftOffset, RightOffset, Distance;
1060  PUCHAR Offset;
1061  ULONG i, j;
1062 
1063  /* Get the left and right masks, shifts, and delta */
1064  LeftOffset = Left >> 3;
1065  lMask = (lMaskTable[Left & 0x7] << 8) | 8;
1066  RightOffset = Right >> 3;
1067  rMask = (rMaskTable[Right & 0x7] << 8) | 8;
1068  Distance = RightOffset - LeftOffset;
1069 
1070  /* If there is no distance, then combine the right and left masks */
1071  if (!Distance) lMask &= rMask;
1072 
1073  /* Switch to mode 10 */
1074  ReadWriteMode(10);
1075 
1076  /* Clear the 4 planes (we're already in unchained mode here) */
1077  __outpw(0x3C4, 0xF02);
1078 
1079  /* Select the color don't care register */
1080  __outpw(0x3CE, 7);
1081 
1082  /* Calculate pixel position for the read */
1083  Offset = (PUCHAR)(VgaBase + (Top * 80) + LeftOffset);
1084 
1085  /* Select the bitmask register and write the mask */
1086  __outpw(0x3CE, (USHORT)lMask);
1087 
1088  /* Check if the top coord is below the bottom one */
1089  if (Top <= Bottom)
1090  {
1091  /* Start looping each line */
1092  i = (Bottom - Top) + 1;
1093  do
1094  {
1095  /* Read the previous value and add our color */
1097 
1098  /* Move to the next line */
1099  Offset += 80;
1100  } while (--i);
1101  }
1102 
1103  /* Check if we have a delta */
1104  if (Distance)
1105  {
1106  /* Calculate new pixel position */
1107  Offset = (PUCHAR)(VgaBase + (Top * 80) + RightOffset);
1108  Distance--;
1109 
1110  /* Select the bitmask register and write the mask */
1111  __outpw(0x3CE, (USHORT)rMask);
1112 
1113  /* Check if the top coord is below the bottom one */
1114  if (Top <= Bottom)
1115  {
1116  /* Start looping each line */
1117  i = (Bottom - Top) + 1;
1118  do
1119  {
1120  /* Read the previous value and add our color */
1123 
1124  /* Move to the next line */
1125  Offset += 80;
1126  } while (--i);
1127  }
1128 
1129  /* Check if we still have a delta */
1130  if (Distance)
1131  {
1132  /* Calculate new pixel position */
1133  Offset = (PUCHAR)(VgaBase + (Top * 80) + LeftOffset + 1);
1134 
1135  /* Set the bitmask to 0xFF for all 4 planes */
1136  __outpw(0x3CE, 0xFF08);
1137 
1138  /* Check if the top coord is below the bottom one */
1139  if (Top <= Bottom)
1140  {
1141  /* Start looping each line */
1142  i = (Bottom - Top) + 1;
1143  do
1144  {
1145  /* Loop the shift delta */
1146  if (Distance > 0)
1147  {
1148  for (j = Distance; j; Offset++, j--)
1149  {
1150  /* Write the color */
1152  }
1153  }
1154 
1155  /* Update position in memory */
1156  Offset += (80 - Distance);
1157  } while (--i);
1158  }
1159  }
1160  }
1161 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
signed char * PCHAR
Definition: retypes.h:7
static VOID NTAPI SetPaletteEntryRGB(IN ULONG Id, IN ULONG Rgb)
Definition: vga.c:255
#define IN
Definition: typedefs.h:38
ASMGENDATA Table[]
Definition: genincdata.c:61
#define TRUE
Definition: types.h:120
static VOID NTAPI VgaScroll(IN ULONG Scroll)
Definition: vga.c:327
static UCHAR rMaskTable[8]
Definition: vga.c:23
USHORT biBitCount
Definition: precomp.h:25
_In_ ULONG Mode
Definition: hubbusif.h:303
VOID NTAPI VidBitBlt(IN PUCHAR Buffer, IN ULONG Left, IN ULONG Top)
Definition: vga.c:867
#define DbgPrint
Definition: loader.c:25
static ULONG VidTextColor
Definition: vga.c:70
VOID NTAPI VidDisplayStringXY(IN PUCHAR String, IN ULONG Left, IN ULONG Top, IN BOOLEAN Transparent)
Definition: vga.c:705
struct tagBITMAPINFOHEADER BITMAPINFOHEADER
#define GetFontPtr(_Char)
Definition: vga.c:128
unsigned char * PUCHAR
Definition: retypes.h:3
char CHAR
Definition: xmlstorage.h:175
UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address)
Definition: mach.c:535
VOID NTAPI VidDisplayString(IN PUCHAR String)
Definition: vga.c:783
GLintptr offset
Definition: glext.h:5920
INT dx
Definition: msvc.h:65
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
static ULONG lookup[16]
Definition: vga.c:46
ULONG biCompression
Definition: precomp.h:26
static WCHAR String[]
Definition: stringtable.c:55
static VOID NTAPI BitBlt(IN ULONG Left, IN ULONG Top, IN ULONG Width, IN ULONG Height, IN PUCHAR Buffer, IN ULONG BitsPerPixel, IN ULONG Delta)
Definition: vga.c:416
static VOID NTAPI RleBitBlt(IN ULONG Left, IN ULONG Top, IN ULONG Width, IN ULONG Height, IN PUCHAR Buffer)
Definition: vga.c:483
const GLfloat * m
Definition: glext.h:10848
struct Color Color
DWORD Id
uint32_t ULONG_PTR
Definition: typedefs.h:63
INT INT y
Definition: msvc.h:62
ULONG_PTR VgaRegisterBase
Definition: vga.c:66
#define BOOTCHAR_HEIGHT
Definition: precomp.h:10
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static VOID NTAPI DisplayStringXY(IN PUCHAR String, IN ULONG Left, IN ULONG Top, IN ULONG TextColor, IN ULONG BackColor)
Definition: vga.c:235
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
struct tagBITMAPINFOHEADER * PBITMAPINFOHEADER
long LONG
Definition: pedump.c:60
GLuint color
Definition: glext.h:6243
#define a
Definition: ke_i.h:78
#define __outpw(Port, Value)
Definition: vga.c:76
#define FONT_PTR_DELTA
Definition: vga.c:129
unsigned char BOOLEAN
static VOID NTAPI InitPaletteWithTable(IN PULONG Table, IN ULONG Count)
Definition: vga.c:271
#define SET_PIXELS(_PixelPtr, _PixelMask, _TextColor)
Definition: vga.c:116
#define FORCEINLINE
Definition: ntbasedef.h:221
Definition: bufpool.h:45
static VOID NTAPI PreserveRow(IN ULONG CurrentTop, IN ULONG TopDelta, IN BOOLEAN Direction)
Definition: vga.c:366
#define b
Definition: ke_i.h:79
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define PCHAR
Definition: match.c:90
ULONG NTAPI VidSetTextColor(IN ULONG Color)
Definition: vga.c:690
#define Code
Definition: deflate.h:80
FORCEINLINE VOID SetPixel(IN ULONG Left, IN ULONG Top, IN UCHAR Color)
Definition: vga.c:99
PPC_QUAL void __movsb(unsigned char *Destination, const unsigned char *Source, unsigned long Count)
Definition: intrin_ppc.h:323
VOID NTAPI VidCleanUp(VOID)
Definition: vga.c:750
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
static VOID NTAPI ReadWriteMode(IN UCHAR Mode)
Definition: vga.c:83
VOID NTAPI InitializePalette(VOID)
Definition: vga.c:301
Colors
Definition: ansiprsr.h:4
_Inout_ PSIZE_T _In_opt_ PMDLX _In_ MM_ROTATE_DIRECTION Direction
Definition: mmfuncs.h:773
#define __outpb(Port, Value)
Definition: vga.c:73
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID NTAPI VidScreenToBufferBlt(IN PUCHAR Buffer, IN ULONG Left, IN ULONG Top, IN ULONG Width, IN ULONG Height, IN ULONG Delta)
Definition: vga.c:944
static VOID NTAPI SetPaletteEntry(IN ULONG Id, IN ULONG PaletteEntry)
Definition: vga.c:287
NTKERNELAPI UCHAR NTAPI READ_REGISTER_UCHAR(IN PUCHAR Register)
VOID NTAPI VidSetScrollRegion(IN ULONG Left, IN ULONG Top, IN ULONG Right, IN ULONG Bottom)
Definition: vga.c:725
ULONG curr_y
Definition: vga.c:69
static LPHIST_ENTRY Bottom
Definition: history.c:54
static ULONG ScrollRegion[4]
Definition: vga.c:5
ULONG_PTR VgaBase
Definition: vga.c:67
UCHAR PixelMask[8]
Definition: vga.c:35
unsigned short USHORT
Definition: pedump.c:61
INT x
Definition: msvc.h:62
static ULONG Delta
Definition: xboxvideo.c:28
_In_ ULONG Shift
Definition: rtlfuncs.h:2683
unsigned int * PULONG
Definition: retypes.h:1
INT INT dy
Definition: msvc.h:65
#define BI_RLE4
Definition: precomp.h:36
VOID NTAPI VidSolidColorFill(IN ULONG Left, IN ULONG Top, IN ULONG Right, IN ULONG Bottom, IN UCHAR Color)
Definition: vga.c:1052
static UCHAR lMaskTable[8]
Definition: vga.c:12
static VOID NTAPI DisplayCharacter(IN CHAR Character, IN ULONG Left, IN ULONG Top, IN ULONG TextColor, IN ULONG BackColor)
Definition: vga.c:134
VOID NTAPI VidBufferToScreenBlt(IN PUCHAR Buffer, IN ULONG Left, IN ULONG Top, IN ULONG Width, IN ULONG Height, IN ULONG Delta)
Definition: vga.c:764
unsigned int ULONG
Definition: retypes.h:1
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:539
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
ULONG curr_x
Definition: vga.c:68
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
static LPHIST_ENTRY Top
Definition: history.c:53
static BOOLEAN CarriageReturn
Definition: vga.c:71
int k
Definition: mpi.c:3369
NTKERNELAPI VOID NTAPI WRITE_REGISTER_UCHAR(IN PUCHAR Register, IN UCHAR Value)
base of all file and directory entries
Definition: entries.h:82