0x1111,
};
-ULONG TextColor = 0xF;
+ULONG VidTextColor = 0xF;
ULONG curr_x = 0;
ULONG curr_y = 0;
-BOOLEAN NextLine = FALSE;
+BOOLEAN CarriageReturn = FALSE;
ULONG_PTR VgaRegisterBase = 0;
ULONG_PTR VgaBase = 0;
+#define __outpb(Port, Value) \
+ WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + Port, (UCHAR)Value)
+
+#define __outpw(Port, Value) \
+ WRITE_PORT_USHORT((PUSHORT)(VgaRegisterBase + Port), (USHORT)Value)
+
/* PRIVATE FUNCTIONS *********************************************************/
VOID
UCHAR Value;
/* Switch to graphics mode register */
- WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 5);
+ __outpb(0x3CE, 5);
/* Get the current register value, minus the current mode */
Value = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) & 0xF4;
/* Set the new mode */
- WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, Mode | Value);
-}
-
-VOID
-NTAPI
-__outpb(IN ULONG Port,
- IN ULONG Value)
-{
- /* Write to the VGA Register */
- WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + Port, (UCHAR)Value);
+ __outpb(0x3CF, Mode | Value);
}
-VOID
-NTAPI
-__outpw(IN ULONG Port,
- IN ULONG Value)
-{
- /* Write to the VGA Register */
- WRITE_PORT_USHORT((PUSHORT)(VgaRegisterBase + Port), (USHORT)Value);
-}
+FORCEINLINE
VOID
-NTAPI
SetPixel(IN ULONG Left,
IN ULONG Top,
IN UCHAR Color)
/* Calculate the pixel position. */
PixelPosition = (PUCHAR)VgaBase + (Left >> 3) + (Top * 80);
- /* Switch to mode 10 */
- ReadWriteMode(10);
-
- /* Clear the 4 planes (we're already in unchained mode here) */
- __outpw(0x3C4, 0xF02);
-
- /* Select the color don't care register */
- __outpw(0x3CE, 7);
-
/* Select the bitmask register and write the mask */
__outpw(0x3CE, (PixelMask[Left & 7] << 8) | 8);
READ_REGISTER_UCHAR(PixelPosition) & Color);
}
+#ifdef CHAR_GEN_UPSIDE_DOWN
+# define GetFontPtr(_Char) &FontData[_Char * BOOTCHAR_HEIGHT] + BOOTCHAR_HEIGHT - 1;
+# define FONT_PTR_DELTA (-1)
+#else
+# define GetFontPtr(_Char) &FontData[_Char * BOOTCHAR_HEIGHT];
+# define FONT_PTR_DELTA (1)
+#endif
+
+#define SET_PIXELS(_PixelPtr, _PixelMask, _TextColor) \
+ /* Select the bitmask register and write the mask */ \
+ __outpw(0x3CE, (_PixelMask << 8) | 8); \
+\
+ /* Set the new color */ \
+ WRITE_REGISTER_UCHAR(_PixelPtr, (UCHAR)_TextColor);\
+
VOID
NTAPI
DisplayCharacter(CHAR Character,
ULONG Left,
ULONG Top,
ULONG TextColor,
- ULONG BackTextColor)
+ ULONG BackColor)
{
- PUCHAR FontChar;
- ULONG i, j, XOffset;
+ PUCHAR FontChar, PixelPtr;
+ ULONG Height;
+ UCHAR Shift;
+
+ /* Switch to mode 10 */
+ ReadWriteMode(10);
+
+ /* Clear the 4 planes (we're already in unchained mode here) */
+ __outpw(0x3C4, 0xF02);
+
+ /* Select the color don't care register */
+ __outpw(0x3CE, 7);
- /* Get the font line for this character */
- FontChar = &FontData[Character * BOOTCHAR_HEIGHT];
+ /* Calculate shift */
+ Shift = Left & 7;
- /* Loop each pixel height */
- i = BOOTCHAR_HEIGHT;
+ /* Get the font and pixel pointer */
+ FontChar = GetFontPtr(Character);
+ PixelPtr = (PUCHAR)VgaBase + (Left >> 3) + (Top * 80);
+
+ /* Loop all pixel rows */
+ Height = BOOTCHAR_HEIGHT;
do
{
- /* Loop each pixel width */
- j = 128;
- XOffset = Left;
+ SET_PIXELS(PixelPtr, *FontChar >> Shift, TextColor);
+ PixelPtr += 80;
+ FontChar += FONT_PTR_DELTA;
+ } while (--Height);
+
+ /* Check if we need to update neighbor bytes */
+ if (Shift)
+ {
+ /* Calculate shift for 2nd byte */
+ Shift = 8 - Shift;
+
+ /* Get the font and pixel pointer (2nd byte) */
+ FontChar = GetFontPtr(Character);
+ PixelPtr = (PUCHAR)VgaBase + (Left >> 3) + (Top * 80) + 1;
+
+ /* Loop all pixel rows */
+ Height = BOOTCHAR_HEIGHT;
do
{
- /* Check if we should draw this pixel */
-#ifdef CHAR_GEN_UPSIDE_DOWN
- if (FontChar[i] & (UCHAR)j)
-#else
- /* Normal character generator (top of char is first element) */
- if (FontChar[BOOTCHAR_HEIGHT - i] & (UCHAR)j)
-#endif
- {
- /* We do, use the given Text Color */
- SetPixel(XOffset, Top, (UCHAR)TextColor);
- }
- else if (BackTextColor < 16)
- {
- /* This is a background pixel. */
- /* We're drawing it unless it's transparent. */
- SetPixel(XOffset, Top, (UCHAR)BackTextColor);
- }
+ SET_PIXELS(PixelPtr, *FontChar << Shift, TextColor);
+ PixelPtr += 80;
+ FontChar += FONT_PTR_DELTA;
+ } while (--Height);
+ }
+
+ /* Check if the background color is transparent */
+ if (BackColor >= 16)
+ {
+ /* We are done */
+ return;
+ }
+
+ /* Calculate shift */
+ Shift = Left & 7;
- /* Increase X Offset */
- XOffset++;
- } while (j >>= 1);
+ /* Get the font and pixel pointer */
+ FontChar = GetFontPtr(Character);
+ PixelPtr = (PUCHAR)VgaBase + (Left >> 3) + (Top * 80);
+
+ /* Loop all pixel rows */
+ Height = BOOTCHAR_HEIGHT;
+ do
+ {
+ SET_PIXELS(PixelPtr, ~*FontChar >> Shift, BackColor);
+ PixelPtr += 80;
+ FontChar += FONT_PTR_DELTA;
+ } while (--Height);
- /* Move to the next Y ordinate */
- Top++;
- } while (--i);
+ /* Check if we need to update neighbor bytes */
+ if (Shift)
+ {
+ /* Calculate shift for 2nd byte */
+ Shift = 8 - Shift;
+
+ /* Get the font and pixel pointer (2nd byte) */
+ FontChar = GetFontPtr(Character);
+ PixelPtr = (PUCHAR)VgaBase + (Left >> 3) + (Top * 80) + 1;
+
+ /* Loop all pixel rows */
+ Height = BOOTCHAR_HEIGHT;
+ do
+ {
+ SET_PIXELS(PixelPtr, ~*FontChar << Shift, BackColor);
+ PixelPtr += 80;
+ FontChar += FONT_PTR_DELTA;
+ } while (--Height);
+ }
}
VOID
NTAPI
VgaScroll(ULONG Scroll)
{
- ULONG Top;
- ULONG SourceOffset, DestOffset;
- ULONG Offset;
- ULONG i, j;
-
- /* Set memory positions of the scroll */
- SourceOffset = VgaBase + (ScrollRegion[1] * 80) + (ScrollRegion[0] >> 3);
- DestOffset = SourceOffset + (Scroll * 80);
+ ULONG Top, RowSize;
+ PUCHAR OldPosition, NewPosition;
/* Clear the 4 planes */
__outpw(0x3C4, 0xF02);
/* Set Mode 1 */
ReadWriteMode(1);
- /* Save top and check if it's above the bottom */
- Top = ScrollRegion[1];
- if (Top > ScrollRegion[3]) return;
+ RowSize = (ScrollRegion[2] - ScrollRegion[0] + 1) / 8;
+
+ /* Calculate the position in memory for the row */
+ OldPosition = (PUCHAR)VgaBase + (ScrollRegion[1] + Scroll) * 80 + ScrollRegion[0] / 8;
+ NewPosition = (PUCHAR)VgaBase + ScrollRegion[1] * 80 + ScrollRegion[0] / 8;
/* Start loop */
- do
+ for(Top = ScrollRegion[1]; Top <= ScrollRegion[3]; ++Top)
{
- /* Set number of bytes to loop and start offset */
- Offset = ScrollRegion[0] >> 3;
- j = SourceOffset;
-
- /* Check if this is part of the scroll region */
- if (Offset <= (ScrollRegion[2] >> 3))
- {
- /* Update position */
- i = DestOffset - SourceOffset;
-
- /* Loop the X axis */
- do
- {
- /* Write value in the new position so that we can do the scroll */
- WRITE_REGISTER_UCHAR(UlongToPtr(j),
- READ_REGISTER_UCHAR(UlongToPtr(j + i)));
-
- /* Move to the next memory location to write to */
- j++;
-
- /* Move to the next byte in the region */
- Offset++;
-
- /* Make sure we don't go past the scroll region */
- } while (Offset <= (ScrollRegion[2] >> 3));
- }
-
- /* Move to the next line */
- SourceOffset += 80;
- DestOffset += 80;
-
- /* Increase top */
- Top++;
+#if defined(_M_IX86) || defined(_M_AMD64)
+ __movsb(NewPosition, OldPosition, RowSize);
+#else
+ ULONG i;
- /* Make sure we don't go past the scroll region */
- } while (Top <= ScrollRegion[3]);
+ /* Scroll the row */
+ for(i = 0; i < RowSize; ++i)
+ WRITE_REGISTER_UCHAR(NewPosition + i, READ_REGISTER_UCHAR(OldPosition + i));
+#endif
+ OldPosition += 80;
+ NewPosition += 80;
+ }
}
VOID
/* Set the count and make sure it's above 0 */
Count = TopDelta * 80;
- if (Count)
+
+#if defined(_M_IX86) || defined(_M_AMD64)
+ __movsb(Position1, Position2, Count);
+#else
+ /* Loop every pixel */
+ while (Count--)
{
- /* Loop every pixel */
- do
- {
- /* Write the data back on the other position */
- WRITE_REGISTER_UCHAR(Position1, READ_REGISTER_UCHAR(Position2));
+ /* Write the data back on the other position */
+ WRITE_REGISTER_UCHAR(Position1, READ_REGISTER_UCHAR(Position2));
- /* Increase both positions */
- Position2++;
- Position1++;
- } while (--Count);
+ /* Increase both positions */
+ Position2++;
+ Position1++;
}
+#endif
}
VOID
return;
}
+ /* Switch to mode 10 */
+ ReadWriteMode(10);
+
+ /* Clear the 4 planes (we're already in unchained mode here) */
+ __outpw(0x3C4, 0xF02);
+
+ /* Select the color don't care register */
+ __outpw(0x3CE, 7);
+
/* 4bpp blitting */
dy = Top;
do
ULONG i, j;
ULONG Code;
+ /* Switch to mode 10 */
+ ReadWriteMode(10);
+
+ /* Clear the 4 planes (we're already in unchained mode here) */
+ __outpw(0x3C4, 0xF02);
+
+ /* Select the color don't care register */
+ __outpw(0x3CE, 7);
+
/* Set Y height and current X value and start loop */
YDelta = Top + Height - 1;
x = Left;
ULONG OldColor;
/* Save the old color and set the new one */
- OldColor = TextColor;
- TextColor = Color;
+ OldColor = VidTextColor;
+ VidTextColor = Color;
return OldColor;
}
NTAPI
VidDisplayString(PUCHAR String)
{
- ULONG TopDelta = 14;
+ ULONG TopDelta = BOOTCHAR_HEIGHT + 1;
/* Start looping the string */
while (*String)
{
/* Modify Y position */
curr_y += TopDelta;
- if (curr_y >= ScrollRegion[3])
+ if (curr_y + TopDelta >= ScrollRegion[3])
{
/* Scroll the view */
VgaScroll(TopDelta);
curr_y -= TopDelta;
-
+ }
+ else
+ {
/* Preserve row */
- PreserveRow(curr_y, TopDelta, TRUE);
+ PreserveRow(curr_y, TopDelta, FALSE);
}
/* Update current X */
curr_x = ScrollRegion[0];
- /* Preseve the current row */
- PreserveRow(curr_y, TopDelta, FALSE);
+ /* Do not clear line if "\r\n" is given */
+ CarriageReturn = FALSE;
}
else if (*String == '\r')
{
curr_x = ScrollRegion[0];
/* Check if we're being followed by a new line */
- if (String[1] != '\n') NextLine = TRUE;
+ CarriageReturn = TRUE;
}
else
{
- /* Check if we had a \n\r last time */
- if (NextLine)
+ /* check if we had a '\r' last time */
+ if (CarriageReturn)
{
- /* We did, preserve the current row */
+ /* We did, clear the current row */
PreserveRow(curr_y, TopDelta, TRUE);
- NextLine = FALSE;
+ CarriageReturn = FALSE;
}
/* Display this character */
- DisplayCharacter(*String, curr_x, curr_y, TextColor, 16);
+ DisplayCharacter(*String, curr_x, curr_y, VidTextColor, 16);
curr_x += 8;
/* Check if we should scroll */
- if (curr_x > ScrollRegion[2])
+ if (curr_x + 8 > ScrollRegion[2])
{
/* Update Y position and check if we should scroll it */
curr_y += TopDelta;
- if (curr_y > ScrollRegion[3])
+ if (curr_y + TopDelta > ScrollRegion[3])
{
/* Do the scroll */
VgaScroll(TopDelta);
curr_y -= TopDelta;
-
- /* Save the row */
- PreserveRow(curr_y, TopDelta, TRUE);
+ }
+ else
+ {
+ /* Preserve the current row */
+ PreserveRow(curr_y, TopDelta, FALSE);
}
/* Update X */
}
}
}
-