https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5f2ca473dc4fb464633936...
commit 5f2ca473dc4fb464633936c406fd9f49f39f9562 Author: Dmitry Borisov di.sean@protonmail.com AuthorDate: Wed Apr 8 11:42:05 2020 +0600 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org CommitDate: Thu Apr 9 15:56:16 2020 +0200
[BOOTVID] Code refactoring. (#2510)
- Abstract the VGA and LCD code. - Create a common file for all platforms. --- drivers/base/bootvid/CMakeLists.txt | 1 + drivers/base/bootvid/arm/arm.h | 75 ++++ drivers/base/bootvid/arm/bootvid.c | 172 +-------- drivers/base/bootvid/common.c | 412 +++++++++++++++++++++ drivers/base/bootvid/i386/pc/bootvid.c | 8 +- drivers/base/bootvid/i386/pc/pc.h | 39 ++ drivers/base/bootvid/i386/pc/vga.c | 506 ++------------------------ drivers/base/bootvid/precomp.h | 64 ++-- sdk/include/reactos/drivers/bootvid/bootvid.h | 2 +- 9 files changed, 622 insertions(+), 657 deletions(-)
diff --git a/drivers/base/bootvid/CMakeLists.txt b/drivers/base/bootvid/CMakeLists.txt index e344d53fc14..10052eb2128 100644 --- a/drivers/base/bootvid/CMakeLists.txt +++ b/drivers/base/bootvid/CMakeLists.txt @@ -12,6 +12,7 @@ elseif(ARCH STREQUAL "arm") endif()
list(APPEND SOURCE + common.c fontdata.c precomp.h)
diff --git a/drivers/base/bootvid/arm/arm.h b/drivers/base/bootvid/arm/arm.h new file mode 100644 index 00000000000..2f46aa8fff6 --- /dev/null +++ b/drivers/base/bootvid/arm/arm.h @@ -0,0 +1,75 @@ + +#pragma once + +extern PUSHORT VgaArmBase; + +#define LCDTIMING0_PPL(x) ((((x) / 16 - 1) & 0x3f) << 2) +#define LCDTIMING1_LPP(x) (((x) & 0x3ff) - 1) +#define LCDCONTROL_LCDPWR (1 << 11) +#define LCDCONTROL_LCDEN (1) +#define LCDCONTROL_LCDBPP(x) (((x) & 7) << 1) +#define LCDCONTROL_LCDTFT (1 << 5) + +#define PL110_LCDTIMING0 (PVOID)0xE0020000 +#define PL110_LCDTIMING1 (PVOID)0xE0020004 +#define PL110_LCDTIMING2 (PVOID)0xE0020008 +#define PL110_LCDUPBASE (PVOID)0xE0020010 +#define PL110_LCDLPBASE (PVOID)0xE0020014 +#define PL110_LCDCONTROL (PVOID)0xE0020018 + +#define READ_REGISTER_ULONG(r) (*(volatile ULONG * const)(r)) +#define WRITE_REGISTER_ULONG(r, v) (*(volatile ULONG *)(r) = (v)) + +#define READ_REGISTER_USHORT(r) (*(volatile USHORT * const)(r)) +#define WRITE_REGISTER_USHORT(r, v) (*(volatile USHORT *)(r) = (v)) + +PALETTE_ENTRY VidpVga8To16BitTransform[16] = +{ + {0x00, 0x00, 0x00}, // Black + {0x00, 0x00, 0x08}, // Blue + {0x00, 0x08, 0x00}, // Green + {0x00, 0x08, 0x08}, // Cyan + {0x08, 0x00, 0x00}, // Red + {0x08, 0x00, 0x08}, // Magenta + {0x0B, 0x0D, 0x0F}, // Brown + {0x10, 0x10, 0x10}, // Light Gray + {0x08, 0x08, 0x08}, // Dark Gray + {0x00, 0x00, 0x1F}, // Light Blue + {0x00, 0x1F, 0x00}, // Light Green + {0x00, 0x1F, 0x1F}, // Light Cyan + {0x1F, 0x00, 0x00}, // Light Red + {0x1F, 0x00, 0x1F}, // Light Magenta + {0x1F, 0x1F, 0x00}, // Yellow + {0x1F, 0x1F, 0x1F}, // White +}; + +FORCEINLINE +USHORT +VidpBuildColor(_In_ UCHAR Color) +{ + UCHAR Red, Green, Blue; + + /* Extract color components */ + Red = VidpVga8To16BitTransform[Color].Red; + Green = VidpVga8To16BitTransform[Color].Green; + Blue = VidpVga8To16BitTransform[Color].Blue; + + /* Build the 16-bit color mask */ + return ((Red & 0x1F) << 11) | ((Green & 0x1F) << 6) | ((Blue & 0x1F)); +} + +FORCEINLINE +VOID +SetPixel( + _In_ ULONG Left, + _In_ ULONG Top, + _In_ UCHAR Color) +{ + PUSHORT PixelPosition; + + /* Calculate the pixel position */ + PixelPosition = &VgaArmBase[Left + (Top * SCREEN_WIDTH)]; + + /* Set our color */ + WRITE_REGISTER_USHORT(PixelPosition, VidpBuildColor(Color)); +} diff --git a/drivers/base/bootvid/arm/bootvid.c b/drivers/base/bootvid/arm/bootvid.c index 27e0e20af25..c21ec620c9b 100644 --- a/drivers/base/bootvid/arm/bootvid.c +++ b/drivers/base/bootvid/arm/bootvid.c @@ -3,99 +3,12 @@ #define NDEBUG #include <debug.h>
-#define LCDTIMING0_PPL(x) ((((x) / 16 - 1) & 0x3f) << 2) -#define LCDTIMING1_LPP(x) (((x) & 0x3ff) - 1) -#define LCDCONTROL_LCDPWR (1 << 11) -#define LCDCONTROL_LCDEN (1) -#define LCDCONTROL_LCDBPP(x) (((x) & 7) << 1) -#define LCDCONTROL_LCDTFT (1 << 5) - -#define PL110_LCDTIMING0 (PVOID)0xE0020000 -#define PL110_LCDTIMING1 (PVOID)0xE0020004 -#define PL110_LCDTIMING2 (PVOID)0xE0020008 -#define PL110_LCDUPBASE (PVOID)0xE0020010 -#define PL110_LCDLPBASE (PVOID)0xE0020014 -#define PL110_LCDCONTROL (PVOID)0xE0020018 - -#define READ_REGISTER_ULONG(r) (*(volatile ULONG * const)(r)) -#define WRITE_REGISTER_ULONG(r, v) (*(volatile ULONG *)(r) = (v)) - -#define READ_REGISTER_USHORT(r) (*(volatile USHORT * const)(r)) -#define WRITE_REGISTER_USHORT(r, v) (*(volatile USHORT *)(r) = (v)) - PUSHORT VgaArmBase; PHYSICAL_ADDRESS VgaPhysical; BOOLEAN ClearRow = FALSE; -UCHAR VidpTextColor = 0xF; -ULONG VidpCurrentX = 0; -ULONG VidpCurrentY = 0; -ULONG VidpScrollRegion[4] = -{ - 0, - 0, - SCREEN_WIDTH - 1, - SCREEN_HEIGHT - 1 -}; - -typedef struct _VGA_COLOR -{ - UCHAR Red; - UCHAR Green; - UCHAR Blue; -} VGA_COLOR; - -VGA_COLOR VidpVga8To16BitTransform[16] = -{ - {0x00, 0x00, 0x00}, // Black - {0x00, 0x00, 0x08}, // Blue - {0x00, 0x08, 0x00}, // Green - {0x00, 0x08, 0x08}, // Cyan - {0x08, 0x00, 0x00}, // Red - {0x08, 0x00, 0x08}, // Magenta - {0x0B, 0x0D, 0x0F}, // Brown - {0x10, 0x10, 0x10}, // Light Gray - {0x08, 0x08, 0x08}, // Dark Gray - {0x00, 0x00, 0x1F}, // Light Blue - {0x00, 0x1F, 0x00}, // Light Green - {0x00, 0x1F, 0x1F}, // Light Cyan - {0x1F, 0x00, 0x00}, // Light Red - {0x1F, 0x00, 0x1F}, // Light Magenta - {0x1F, 0x1F, 0x00}, // Yellow - {0x1F, 0x1F, 0x1F}, // White -};
/* PRIVATE FUNCTIONS *********************************************************/
-FORCEINLINE -USHORT -VidpBuildColor(IN UCHAR Color) -{ - UCHAR Red, Green, Blue; - - /* Extract color components */ - Red = VidpVga8To16BitTransform[Color].Red; - Green = VidpVga8To16BitTransform[Color].Green; - Blue = VidpVga8To16BitTransform[Color].Blue; - - /* Build the 16-bit color mask */ - return ((Red & 0x1F) << 11) | ((Green & 0x1F) << 6) | ((Blue & 0x1F)); -} - -FORCEINLINE -VOID -VidpSetPixel(IN ULONG Left, - IN ULONG Top, - IN UCHAR Color) -{ - PUSHORT PixelPosition; - - /* Calculate the pixel position */ - PixelPosition = &VgaArmBase[Left + (Top * SCREEN_WIDTH)]; - - /* Set our color */ - WRITE_REGISTER_USHORT(PixelPosition, VidpBuildColor(Color)); -} - VOID NTAPI DisplayCharacter(IN CHAR Character, @@ -121,7 +34,7 @@ DisplayCharacter(IN CHAR Character, if (FontChar[Top] & (UCHAR)j) { /* We do, use the given Text Color */ - VidpSetPixel(XOffset, Top, (UCHAR)TextColor); + SetPixel(XOffset, Top, (UCHAR)TextColor); } else if (BackColor < 16) { @@ -129,7 +42,7 @@ DisplayCharacter(IN CHAR Character, * This is a background pixel. We're drawing it * unless it's transparent. */ - VidpSetPixel(XOffset, Top, (UCHAR)BackColor); + SetPixel(XOffset, Top, (UCHAR)BackColor); }
/* Increase X Offset */ @@ -250,6 +163,15 @@ VidpInitializeDisplay(VOID) LCDCONTROL_LCDBPP(4)); }
+VOID +NTAPI +InitPaletteWithTable( + _In_ PULONG Table, + _In_ ULONG Count) +{ + UNIMPLEMENTED; +} + /* PUBLIC FUNCTIONS **********************************************************/
/* @@ -333,45 +255,6 @@ VidSetTextColor(IN ULONG Color) return OldColor; }
-/* - * @implemented - */ -VOID -NTAPI -VidDisplayStringXY(IN PUCHAR String, - IN ULONG Left, - IN ULONG Top, - IN BOOLEAN Transparent) -{ - UNIMPLEMENTED; - while (TRUE); -} - -/* - * @implemented - */ -VOID -NTAPI -VidSetScrollRegion(IN ULONG Left, - IN ULONG Top, - IN ULONG Right, - IN ULONG Bottom) -{ - /* Assert alignment */ - ASSERT((Left & 0x7) == 0); - ASSERT((Right & 0x7) == 7); - - /* Set Scroll Region */ - VidpScrollRegion[0] = Left; - VidpScrollRegion[1] = Top; - VidpScrollRegion[2] = Right; - VidpScrollRegion[3] = Bottom; - - /* Set current X and Y */ - VidpCurrentX = Left; - VidpCurrentY = Top; -} - /* * @implemented */ @@ -383,22 +266,6 @@ VidCleanUp(VOID) while (TRUE); }
-/* - * @implemented - */ -VOID -NTAPI -VidBufferToScreenBlt(IN PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top, - IN ULONG Width, - IN ULONG Height, - IN ULONG Delta) -{ - UNIMPLEMENTED; - while (TRUE); -} - /* * @implemented */ @@ -490,20 +357,7 @@ VidDisplayString(IN PUCHAR String) */ VOID NTAPI -VidBitBlt(IN PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top) -{ - UNIMPLEMENTED; - //while (TRUE); -} - -/* - * @implemented - */ -VOID -NTAPI -VidScreenToBufferBlt(IN PUCHAR Buffer, +VidScreenToBufferBlt(OUT PUCHAR Buffer, IN ULONG Left, IN ULONG Top, IN ULONG Width, @@ -540,7 +394,7 @@ VidSolidColorFill(IN ULONG Left, // // Draw the pixel // - VidpSetPixel(x, y, Color); + SetPixel(x, y, Color); } } } diff --git a/drivers/base/bootvid/common.c b/drivers/base/bootvid/common.c new file mode 100644 index 00000000000..c82f8dd1bd1 --- /dev/null +++ b/drivers/base/bootvid/common.c @@ -0,0 +1,412 @@ + +/* GLOBALS ********************************************************************/ + +UCHAR VidpTextColor = 0x0F; + +ULONG VidpCurrentX = 0; +ULONG VidpCurrentY = 0; + +ULONG VidpScrollRegion[4] = +{ + 0, + 0, + SCREEN_WIDTH - 1, + SCREEN_HEIGHT - 1 +}; + +/* PRIVATE FUNCTIONS **********************************************************/ + +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) +{ + ULONG sx, dx, dy; + UCHAR color; + ULONG offset = 0; + const ULONG Bottom = Top + Height; + const ULONG Right = Left + Width; + + /* Check if the buffer isn't 4bpp */ + if (BitsPerPixel != 4) + { + /* FIXME: TODO */ + DbgPrint("Unhandled BitBlt\n" + "%lux%lu @ (%lu|%lu)\n" + "Bits Per Pixel %lu\n" + "Buffer: %p. Delta: %lu\n", + Width, + Height, + Left, + Top, + BitsPerPixel, + Buffer, + Delta); + return; + } + + PrepareForSetPixel(); + + /* 4bpp blitting */ + for (dy = Top; dy < Bottom; ++dy) + { + sx = 0; + do + { + /* Extract color */ + color = Buffer[offset + sx]; + + /* Calc destination x */ + dx = Left + (sx << 1); + + /* Set two pixels */ + SetPixel(dx, dy, color >> 4); + SetPixel(dx + 1, dy, color & 0x0F); + + sx++; + } while (dx < Right); + offset += Delta; + } +} + +static VOID +NTAPI +RleBitBlt( + _In_ ULONG Left, + _In_ ULONG Top, + _In_ ULONG Width, + _In_ ULONG Height, + _In_ PUCHAR Buffer) +{ + ULONG YDelta; + ULONG x; + ULONG RleValue, NewRleValue; + ULONG Color, Color2; + ULONG i, j; + ULONG Code; + + PrepareForSetPixel(); + + /* Set Y height and current X value and start loop */ + YDelta = Top + Height - 1; + x = Left; + for (;;) + { + /* Get the current value and advance in the buffer */ + RleValue = *Buffer; + Buffer++; + if (RleValue) + { + /* Check if we've gone past the edge */ + if ((x + RleValue) > (Width + Left)) + { + /* Fixup the pixel value */ + RleValue = Left - x + Width; + } + + /* Get the new value */ + NewRleValue = *Buffer; + + /* Get the two colors */ + Color = NewRleValue >> 4; + Color2 = NewRleValue & 0xF; + + /* Increase buffer position */ + Buffer++; + + /* Check if we need to do a fill */ + if (Color == Color2) + { + /* Do a fill and continue the loop */ + RleValue += x; + VidSolidColorFill(x, YDelta, RleValue - 1, YDelta, (UCHAR)Color); + x = RleValue; + continue; + } + + /* Check if the pixel value is 1 or below */ + if (RleValue > 1) + { + /* Set loop variables */ + for (i = (RleValue - 2) / 2 + 1; i > 0; --i) + { + /* Set the pixels */ + SetPixel(x, YDelta, (UCHAR)Color); + x++; + SetPixel(x, YDelta, (UCHAR)Color2); + x++; + + /* Decrease pixel value */ + RleValue -= 2; + } + } + + /* Check if there is any value at all */ + if (RleValue) + { + /* Set the pixel and increase position */ + SetPixel(x, YDelta, (UCHAR)Color); + x++; + } + + /* Start over */ + continue; + } + + /* Get the current pixel value */ + RleValue = *Buffer; + Code = RleValue; + switch (Code) + { + /* Case 0 */ + case 0: + { + /* Set new x value, decrease distance and restart */ + x = Left; + YDelta--; + Buffer++; + continue; + } + + /* Case 1 */ + case 1: + { + /* Done */ + return; + } + + /* Case 2 */ + case 2: + { + /* Set new x value, decrease distance and restart */ + Buffer++; + x += *Buffer; + Buffer++; + YDelta -= *Buffer; + Buffer++; + continue; + } + + /* Other values */ + default: + { + Buffer++; + break; + } + } + + /* Check if we've gone past the edge */ + if ((x + RleValue) > (Width + Left)) + { + /* Set fixed up loop count */ + i = RleValue - Left - Width + x; + + /* Fixup pixel value */ + RleValue -= i; + } + else + { + /* Clear loop count */ + i = 0; + } + + /* Check the value now */ + if (RleValue > 1) + { + /* Set loop variables */ + for (j = (RleValue - 2) / 2 + 1; j > 0; --j) + { + /* Get the new value */ + NewRleValue = *Buffer; + + /* Get the two colors */ + Color = NewRleValue >> 4; + Color2 = NewRleValue & 0xF; + + /* Increase buffer position */ + Buffer++; + + /* Set the pixels */ + SetPixel(x, YDelta, (UCHAR)Color); + x++; + SetPixel(x, YDelta, (UCHAR)Color2); + x++; + + /* Decrease pixel value */ + RleValue -= 2; + } + } + + /* Check if there is any value at all */ + if (RleValue) + { + /* Set the pixel and increase position */ + Color = *Buffer >> 4; + Buffer++; + SetPixel(x, YDelta, (UCHAR)Color); + x++; + i--; + } + + /* Check loop count now */ + if ((LONG)i > 0) + { + /* Decrease it */ + i--; + + /* Set new position */ + Buffer = Buffer + (i / 2) + 1; + } + + /* Check if we need to increase the buffer */ + if ((ULONG_PTR)Buffer & 1) Buffer++; + } +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + +VOID +NTAPI +VidDisplayStringXY( + _In_ PUCHAR String, + _In_ ULONG Left, + _In_ ULONG Top, + _In_ BOOLEAN Transparent) +{ + ULONG BackColor; + + /* + * If the caller wanted transparent, then send the special value (16), + * else use our default and call the helper routine. + */ + BackColor = Transparent ? 16 : 14; + + /* Loop every character and adjust the position */ + for (; *String; ++String, Left += 8) + { + /* Display a character */ + DisplayCharacter(*String, Left, Top, 12, BackColor); + } +} + +VOID +NTAPI +VidSetScrollRegion( + _In_ ULONG Left, + _In_ ULONG Top, + _In_ ULONG Right, + _In_ ULONG Bottom) +{ + /* Assert alignment */ + ASSERT((Left & 0x7) == 0); + ASSERT((Right & 0x7) == 7); + + /* Set Scroll Region */ + VidpScrollRegion[0] = Left; + VidpScrollRegion[1] = Top; + VidpScrollRegion[2] = Right; + VidpScrollRegion[3] = Bottom; + + /* Set current X and Y */ + VidpCurrentX = Left; + VidpCurrentY = Top; +} + +VOID +NTAPI +VidBufferToScreenBlt( + _In_ PUCHAR Buffer, + _In_ ULONG Left, + _In_ ULONG Top, + _In_ ULONG Width, + _In_ ULONG Height, + _In_ ULONG Delta) +{ + /* Make sure we have a width and height */ + if (!Width || !Height) + return; + + /* Call the helper function */ + BitBlt(Left, Top, Width, Height, Buffer, 4, Delta); +} + +VOID +NTAPI +VidBitBlt( + _In_ PUCHAR Buffer, + _In_ ULONG Left, + _In_ ULONG Top) +{ + PBITMAPINFOHEADER BitmapInfoHeader; + LONG Delta; + PUCHAR BitmapOffset; + + /* Get the Bitmap Header */ + BitmapInfoHeader = (PBITMAPINFOHEADER)Buffer; + + /* Initialize the palette */ + InitPaletteWithTable((PULONG)(Buffer + BitmapInfoHeader->biSize), + (BitmapInfoHeader->biClrUsed) ? + BitmapInfoHeader->biClrUsed : 16); + + /* Make sure we can support this bitmap */ + ASSERT((BitmapInfoHeader->biBitCount * BitmapInfoHeader->biPlanes) <= 4); + + /* + * Calculate the delta and align it on 32-bytes, then calculate + * the actual start of the bitmap data. + */ + Delta = (BitmapInfoHeader->biBitCount * BitmapInfoHeader->biWidth) + 31; + Delta >>= 3; + Delta &= ~3; + BitmapOffset = Buffer + sizeof(BITMAPINFOHEADER) + 16 * sizeof(ULONG); + + /* Check the compression of the bitmap */ + if (BitmapInfoHeader->biCompression == BI_RLE4) + { + /* Make sure we have a width and a height */ + if ((BitmapInfoHeader->biWidth) && (BitmapInfoHeader->biHeight)) + { + /* We can use RLE Bit Blt */ + RleBitBlt(Left, + Top, + BitmapInfoHeader->biWidth, + BitmapInfoHeader->biHeight, + BitmapOffset); + } + } + else + { + /* Check if the height is negative */ + if (BitmapInfoHeader->biHeight < 0) + { + /* Make it positive in the header */ + BitmapInfoHeader->biHeight *= -1; + } + else + { + /* Update buffer offset */ + BitmapOffset += ((BitmapInfoHeader->biHeight - 1) * Delta); + Delta *= -1; + } + + /* Make sure we have a width and a height */ + if ((BitmapInfoHeader->biWidth) && (BitmapInfoHeader->biHeight)) + { + /* Do the BitBlt */ + BitBlt(Left, + Top, + BitmapInfoHeader->biWidth, + BitmapInfoHeader->biHeight, + BitmapOffset, + BitmapInfoHeader->biBitCount, + Delta); + } + } +} diff --git a/drivers/base/bootvid/i386/pc/bootvid.c b/drivers/base/bootvid/i386/pc/bootvid.c index afc3553e344..c80911d1aba 100644 --- a/drivers/base/bootvid/i386/pc/bootvid.c +++ b/drivers/base/bootvid/i386/pc/bootvid.c @@ -439,8 +439,8 @@ VidInitialize(IN BOOLEAN SetMode) if (SetMode) { /* Clear the current position */ - curr_x = 0; - curr_y = 0; + VidpCurrentX = 0; + VidpCurrentY = 0;
/* Reset the display and initialize it */ if (HalResetDisplay()) @@ -467,8 +467,8 @@ NTAPI VidResetDisplay(IN BOOLEAN HalReset) { /* Clear the current position */ - curr_x = 0; - curr_y = 0; + VidpCurrentX = 0; + VidpCurrentY = 0;
/* Clear the screen with HAL if we were asked to */ if (HalReset) diff --git a/drivers/base/bootvid/i386/pc/pc.h b/drivers/base/bootvid/i386/pc/pc.h new file mode 100644 index 00000000000..fef2324f8b4 --- /dev/null +++ b/drivers/base/bootvid/i386/pc/pc.h @@ -0,0 +1,39 @@ + +#pragma once + +extern ULONG_PTR VgaRegisterBase; +extern ULONG_PTR VgaBase; +extern USHORT AT_Initialization[]; +extern USHORT VGA_640x480[]; +extern UCHAR PixelMask[8]; + +#define __inpb(Port) \ + READ_PORT_UCHAR((PUCHAR)(VgaRegisterBase + (Port))) + +#define __inpw(Port) \ + READ_PORT_USHORT((PUSHORT)(VgaRegisterBase + (Port))) + +#define __outpb(Port, Value) \ + WRITE_PORT_UCHAR((PUCHAR)(VgaRegisterBase + (Port)), (UCHAR)(Value)) + +#define __outpw(Port, Value) \ + WRITE_PORT_USHORT((PUSHORT)(VgaRegisterBase + (Port)), (USHORT)(Value)) + +FORCEINLINE +VOID +SetPixel( + _In_ ULONG Left, + _In_ ULONG Top, + _In_ UCHAR Color) +{ + PUCHAR PixelPosition; + + /* Calculate the pixel position */ + PixelPosition = (PUCHAR)(VgaBase + (Left >> 3) + (Top * (SCREEN_WIDTH / 8))); + + /* Select the bitmask register and write the mask */ + __outpw(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, (PixelMask[Left & 7] << 8) | IND_BIT_MASK); + + /* Read the current pixel value and add our color */ + WRITE_REGISTER_UCHAR(PixelPosition, READ_REGISTER_UCHAR(PixelPosition) & Color); +} diff --git a/drivers/base/bootvid/i386/pc/vga.c b/drivers/base/bootvid/i386/pc/vga.c index 99cd0dc7a9f..b2d003657ee 100644 --- a/drivers/base/bootvid/i386/pc/vga.c +++ b/drivers/base/bootvid/i386/pc/vga.c @@ -2,13 +2,6 @@
/* GLOBALS *******************************************************************/
-static ULONG ScrollRegion[4] = -{ - 0, - 0, - SCREEN_WIDTH - 1, - SCREEN_HEIGHT - 1 -}; static UCHAR lMaskTable[8] = { (1 << 8) - (1 << 0), @@ -64,9 +57,6 @@ static ULONG lookup[16] =
ULONG_PTR VgaRegisterBase = 0; ULONG_PTR VgaBase = 0; -ULONG curr_x = 0; -ULONG curr_y = 0; -static ULONG VidTextColor = 0xF; static BOOLEAN ClearRow = FALSE;
/* PRIVATE FUNCTIONS *********************************************************/ @@ -87,7 +77,7 @@ ReadWriteMode(IN UCHAR Mode) __outpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT, Mode | Value); }
-static VOID +VOID PrepareForSetPixel(VOID) { /* Switch to mode 10 */ @@ -100,24 +90,6 @@ PrepareForSetPixel(VOID) __outpw(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, 7); }
-FORCEINLINE -VOID -SetPixel(IN ULONG Left, - IN ULONG Top, - IN UCHAR Color) -{ - PUCHAR PixelPosition; - - /* Calculate the pixel position */ - PixelPosition = (PUCHAR)(VgaBase + (Left >> 3) + (Top * (SCREEN_WIDTH / 8))); - - /* Select the bitmask register and write the mask */ - __outpw(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, (PixelMask[Left & 7] << 8) | IND_BIT_MASK); - - /* Read the current pixel value and add our color */ - WRITE_REGISTER_UCHAR(PixelPosition, READ_REGISTER_UCHAR(PixelPosition) & Color); -} - #define SET_PIXELS(_PixelPtr, _PixelMask, _TextColor) \ do { \ /* Select the bitmask register and write the mask */ \ @@ -134,13 +106,14 @@ do { \ # define FONT_PTR_DELTA (1) #endif
-static VOID +VOID NTAPI -DisplayCharacter(IN CHAR Character, - IN ULONG Left, - IN ULONG Top, - IN ULONG TextColor, - IN ULONG BackColor) +DisplayCharacter( + _In_ CHAR Character, + _In_ ULONG Left, + _In_ ULONG Top, + _In_ ULONG TextColor, + _In_ ULONG BackColor) { PUCHAR FontChar, PixelPtr; ULONG Height; @@ -224,22 +197,6 @@ DisplayCharacter(IN CHAR Character, } }
-static VOID -NTAPI -DisplayStringXY(IN PUCHAR String, - IN ULONG Left, - IN ULONG Top, - IN ULONG TextColor, - IN ULONG BackColor) -{ - /* Loop every character and adjust the position */ - for (; *String; ++String, Left += 8) - { - /* Display a character */ - DisplayCharacter(*String, Left, Top, TextColor, BackColor); - } -} - static VOID NTAPI SetPaletteEntryRGB(IN ULONG Id, @@ -256,10 +213,11 @@ SetPaletteEntryRGB(IN ULONG Id, __outpb(VGA_BASE_IO_PORT + DAC_DATA_REG_PORT, Colors[0] >> 2); }
-static VOID +VOID NTAPI -InitPaletteWithTable(IN PULONG Table, - IN ULONG Count) +InitPaletteWithTable( + _In_ PULONG Table, + _In_ ULONG Count) { ULONG i; PULONG Entry = Table; @@ -328,14 +286,14 @@ VgaScroll(IN ULONG Scroll) /* Set Mode 1 */ ReadWriteMode(1);
- RowSize = (ScrollRegion[2] - ScrollRegion[0] + 1) / 8; + RowSize = (VidpScrollRegion[2] - VidpScrollRegion[0] + 1) / 8;
/* Calculate the position in memory for the row */ - OldPosition = (PUCHAR)(VgaBase + (ScrollRegion[1] + Scroll) * (SCREEN_WIDTH / 8) + ScrollRegion[0] / 8); - NewPosition = (PUCHAR)(VgaBase + ScrollRegion[1] * (SCREEN_WIDTH / 8) + ScrollRegion[0] / 8); + OldPosition = (PUCHAR)(VgaBase + (VidpScrollRegion[1] + Scroll) * (SCREEN_WIDTH / 8) + VidpScrollRegion[0] / 8); + NewPosition = (PUCHAR)(VgaBase + VidpScrollRegion[1] * (SCREEN_WIDTH / 8) + VidpScrollRegion[0] / 8);
/* Start loop */ - for (Top = ScrollRegion[1]; Top <= ScrollRegion[3]; ++Top) + for (Top = VidpScrollRegion[1]; Top <= VidpScrollRegion[3]; ++Top) { #if defined(_M_IX86) || defined(_M_AMD64) __movsb(NewPosition, OldPosition, RowSize); @@ -400,257 +358,6 @@ PreserveRow(IN ULONG CurrentTop, #endif }
-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) -{ - ULONG sx, dx, dy; - UCHAR color; - ULONG offset = 0; - const ULONG Bottom = Top + Height; - const ULONG Right = Left + Width; - - /* Check if the buffer isn't 4bpp */ - if (BitsPerPixel != 4) - { - /* FIXME: TODO */ - DbgPrint("Unhandled BitBlt\n" - "%lux%lu @ (%lu|%lu)\n" - "Bits Per Pixel %lu\n" - "Buffer: %p. Delta: %lu\n", - Width, - Height, - Left, - Top, - BitsPerPixel, - Buffer, - Delta); - return; - } - - PrepareForSetPixel(); - - /* 4bpp blitting */ - for (dy = Top; dy < Bottom; ++dy) - { - sx = 0; - do - { - /* Extract color */ - color = Buffer[offset + sx]; - - /* Calc destination x */ - dx = Left + (sx << 1); - - /* Set two pixels */ - SetPixel(dx, dy, color >> 4); - SetPixel(dx + 1, dy, color & 0x0F); - - sx++; - } while (dx < Right); - offset += Delta; - } -} - -static VOID -NTAPI -RleBitBlt(IN ULONG Left, - IN ULONG Top, - IN ULONG Width, - IN ULONG Height, - IN PUCHAR Buffer) -{ - ULONG YDelta; - ULONG x; - ULONG RleValue, NewRleValue; - ULONG Color, Color2; - ULONG i, j; - ULONG Code; - - PrepareForSetPixel(); - - /* Set Y height and current X value and start loop */ - YDelta = Top + Height - 1; - x = Left; - for (;;) - { - /* Get the current value and advance in the buffer */ - RleValue = *Buffer; - Buffer++; - if (RleValue) - { - /* Check if we've gone past the edge */ - if ((x + RleValue) > (Width + Left)) - { - /* Fixup the pixel value */ - RleValue = Left - x + Width; - } - - /* Get the new value */ - NewRleValue = *Buffer; - - /* Get the two colors */ - Color = NewRleValue >> 4; - Color2 = NewRleValue & 0xF; - - /* Increase buffer position */ - Buffer++; - - /* Check if we need to do a fill */ - if (Color == Color2) - { - /* Do a fill and continue the loop */ - RleValue += x; - VidSolidColorFill(x, YDelta, RleValue - 1, YDelta, (UCHAR)Color); - x = RleValue; - continue; - } - - /* Check if the pixel value is 1 or below */ - if (RleValue > 1) - { - /* Set loop variables */ - for (i = (RleValue - 2) / 2 + 1; i > 0; --i) - { - /* Set the pixels */ - SetPixel(x, YDelta, (UCHAR)Color); - x++; - SetPixel(x, YDelta, (UCHAR)Color2); - x++; - - /* Decrease pixel value */ - RleValue -= 2; - } - } - - /* Check if there is any value at all */ - if (RleValue) - { - /* Set the pixel and increase position */ - SetPixel(x, YDelta, (UCHAR)Color); - x++; - } - - /* Start over */ - continue; - } - - /* Get the current pixel value */ - RleValue = *Buffer; - Code = RleValue; - switch (Code) - { - /* Case 0 */ - case 0: - { - /* Set new x value, decrease distance and restart */ - x = Left; - YDelta--; - Buffer++; - continue; - } - - /* Case 1 */ - case 1: - { - /* Done */ - return; - } - - /* Case 2 */ - case 2: - { - /* Set new x value, decrease distance and restart */ - Buffer++; - x += *Buffer; - Buffer++; - YDelta -= *Buffer; - Buffer++; - continue; - } - - /* Other values */ - default: - { - Buffer++; - break; - } - } - - /* Check if we've gone past the edge */ - if ((x + RleValue) > (Width + Left)) - { - /* Set fixed up loop count */ - i = RleValue - Left - Width + x; - - /* Fixup pixel value */ - RleValue -= i; - } - else - { - /* Clear loop count */ - i = 0; - } - - /* Check the value now */ - if (RleValue > 1) - { - /* Set loop variables */ - for (j = (RleValue - 2) / 2 + 1; j > 0; --j) - { - /* Get the new value */ - NewRleValue = *Buffer; - - /* Get the two colors */ - Color = NewRleValue >> 4; - Color2 = NewRleValue & 0xF; - - /* Increase buffer position */ - Buffer++; - - /* Set the pixels */ - SetPixel(x, YDelta, (UCHAR)Color); - x++; - SetPixel(x, YDelta, (UCHAR)Color2); - x++; - - /* Decrease pixel value */ - RleValue -= 2; - } - } - - /* Check if there is any value at all */ - if (RleValue) - { - /* Set the pixel and increase position */ - Color = *Buffer >> 4; - Buffer++; - SetPixel(x, YDelta, (UCHAR)Color); - x++; - i--; - } - - /* Check loop count now */ - if ((LONG)i > 0) - { - /* Decrease it */ - i--; - - /* Set new position */ - Buffer = Buffer + (i / 2) + 1; - } - - /* Check if we need to increase the buffer */ - if ((ULONG_PTR)Buffer & 1) Buffer++; - } -} - /* PUBLIC FUNCTIONS **********************************************************/
/* @@ -663,56 +370,11 @@ VidSetTextColor(IN ULONG Color) ULONG OldColor;
/* Save the old color and set the new one */ - OldColor = VidTextColor; - VidTextColor = Color; + OldColor = VidpTextColor; + VidpTextColor = Color; return OldColor; }
-/* - * @implemented - */ -VOID -NTAPI -VidDisplayStringXY(IN PUCHAR String, - IN ULONG Left, - IN ULONG Top, - IN BOOLEAN Transparent) -{ - ULONG BackColor; - - /* - * If the caller wanted transparent, then send the special value (16), - * else use our default and call the helper routine. - */ - BackColor = Transparent ? 16 : 14; - DisplayStringXY(String, Left, Top, 12, BackColor); -} - -/* - * @implemented - */ -VOID -NTAPI -VidSetScrollRegion(IN ULONG Left, - IN ULONG Top, - IN ULONG Right, - IN ULONG Bottom) -{ - /* Assert alignment */ - ASSERT((Left & 0x7) == 0); - ASSERT((Right & 0x7) == 7); - - /* Set Scroll Region */ - ScrollRegion[0] = Left; - ScrollRegion[1] = Top; - ScrollRegion[2] = Right; - ScrollRegion[3] = Bottom; - - /* Set current X and Y */ - curr_x = Left; - curr_y = Top; -} - /* * @implemented */ @@ -725,25 +387,6 @@ VidCleanUp(VOID) __outpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT, BIT_MASK_DEFAULT); }
-/* - * @implemented - */ -VOID -NTAPI -VidBufferToScreenBlt(IN PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top, - IN ULONG Width, - IN ULONG Height, - IN ULONG Delta) -{ - /* Make sure we have a width and height */ - if (!Width || !Height) return; - - /* Call the helper function */ - BitBlt(Left, Top, Width, Height, Buffer, 4, Delta); -} - /* * @implemented */ @@ -760,22 +403,22 @@ VidDisplayString(IN PUCHAR String) if (*String == '\n') { /* Modify Y position */ - curr_y += TopDelta; - if (curr_y + TopDelta - 1 > ScrollRegion[3]) + VidpCurrentY += TopDelta; + if (VidpCurrentY + TopDelta - 1 > VidpScrollRegion[3]) { /* Scroll the view and clear the current row */ VgaScroll(TopDelta); - curr_y -= TopDelta; - PreserveRow(curr_y, TopDelta, TRUE); + VidpCurrentY -= TopDelta; + PreserveRow(VidpCurrentY, TopDelta, TRUE); } else { /* Preserve the current row */ - PreserveRow(curr_y, TopDelta, FALSE); + PreserveRow(VidpCurrentY, TopDelta, FALSE); }
/* Update current X */ - curr_x = ScrollRegion[0]; + VidpCurrentX = VidpScrollRegion[0];
/* No need to clear this row */ ClearRow = FALSE; @@ -783,7 +426,7 @@ VidDisplayString(IN PUCHAR String) else if (*String == '\r') { /* Update current X */ - curr_x = ScrollRegion[0]; + VidpCurrentX = VidpScrollRegion[0];
/* If a new-line does not follow we will clear the current row */ if (String[1] != '\n') ClearRow = TRUE; @@ -793,34 +436,34 @@ VidDisplayString(IN PUCHAR String) /* Clear the current row if we had a return-carriage without a new-line */ if (ClearRow) { - PreserveRow(curr_y, TopDelta, TRUE); + PreserveRow(VidpCurrentY, TopDelta, TRUE); ClearRow = FALSE; }
/* Display this character */ - DisplayCharacter(*String, curr_x, curr_y, VidTextColor, 16); - curr_x += 8; + DisplayCharacter(*String, VidpCurrentX, VidpCurrentY, VidpTextColor, 16); + VidpCurrentX += 8;
/* Check if we should scroll */ - if (curr_x + 7 > ScrollRegion[2]) + if (VidpCurrentX + 7 > VidpScrollRegion[2]) { /* Update Y position and check if we should scroll it */ - curr_y += TopDelta; - if (curr_y + TopDelta - 1 > ScrollRegion[3]) + VidpCurrentY += TopDelta; + if (VidpCurrentY + TopDelta - 1 > VidpScrollRegion[3]) { /* Scroll the view and clear the current row */ VgaScroll(TopDelta); - curr_y -= TopDelta; - PreserveRow(curr_y, TopDelta, TRUE); + VidpCurrentY -= TopDelta; + PreserveRow(VidpCurrentY, TopDelta, TRUE); } else { /* Preserve the current row */ - PreserveRow(curr_y, TopDelta, FALSE); + PreserveRow(VidpCurrentY, TopDelta, FALSE); }
/* Update current X */ - curr_x = ScrollRegion[0]; + VidpCurrentX = VidpScrollRegion[0]; } } } @@ -831,84 +474,7 @@ VidDisplayString(IN PUCHAR String) */ VOID NTAPI -VidBitBlt(IN PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top) -{ - PBITMAPINFOHEADER BitmapInfoHeader; - LONG Delta; - PUCHAR BitmapOffset; - - /* Get the Bitmap Header */ - BitmapInfoHeader = (PBITMAPINFOHEADER)Buffer; - - /* Initialize the palette */ - InitPaletteWithTable((PULONG)(Buffer + BitmapInfoHeader->biSize), - (BitmapInfoHeader->biClrUsed) ? - BitmapInfoHeader->biClrUsed : 16); - - /* Make sure we can support this bitmap */ - ASSERT((BitmapInfoHeader->biBitCount * BitmapInfoHeader->biPlanes) <= 4); - - /* - * Calculate the delta and align it on 32-bytes, then calculate - * the actual start of the bitmap data. - */ - Delta = (BitmapInfoHeader->biBitCount * BitmapInfoHeader->biWidth) + 31; - Delta >>= 3; - Delta &= ~3; - BitmapOffset = Buffer + sizeof(BITMAPINFOHEADER) + 16 * sizeof(ULONG); - - /* Check the compression of the bitmap */ - if (BitmapInfoHeader->biCompression == BI_RLE4) - { - /* Make sure we have a width and a height */ - if ((BitmapInfoHeader->biWidth) && (BitmapInfoHeader->biHeight)) - { - /* We can use RLE Bit Blt */ - RleBitBlt(Left, - Top, - BitmapInfoHeader->biWidth, - BitmapInfoHeader->biHeight, - BitmapOffset); - } - } - else - { - /* Check if the height is negative */ - if (BitmapInfoHeader->biHeight < 0) - { - /* Make it positive in the header */ - BitmapInfoHeader->biHeight *= -1; - } - else - { - /* Update buffer offset */ - BitmapOffset += ((BitmapInfoHeader->biHeight - 1) * Delta); - Delta *= -1; - } - - /* Make sure we have a width and a height */ - if ((BitmapInfoHeader->biWidth) && (BitmapInfoHeader->biHeight)) - { - /* Do the BitBlt */ - BitBlt(Left, - Top, - BitmapInfoHeader->biWidth, - BitmapInfoHeader->biHeight, - BitmapOffset, - BitmapInfoHeader->biBitCount, - Delta); - } - } -} - -/* - * @implemented - */ -VOID -NTAPI -VidScreenToBufferBlt(IN PUCHAR Buffer, +VidScreenToBufferBlt(OUT PUCHAR Buffer, IN ULONG Left, IN ULONG Top, IN ULONG Width, diff --git a/drivers/base/bootvid/precomp.h b/drivers/base/bootvid/precomp.h index 0a55332643f..d89e93d359e 100644 --- a/drivers/base/bootvid/precomp.h +++ b/drivers/base/bootvid/precomp.h @@ -5,16 +5,22 @@ #include <ndk/halfuncs.h> #include <drivers/bootvid/bootvid.h>
+/* Arch specific includes */ +#if defined(_M_IX86) || defined(_M_AMD64) +#include "i386/pc/vga.h" +#include "i386/pc/pc.h" +#elif defined(_M_ARM) +#include "arm/arm.h" +#else +#error Unknown architecture +#endif + /* Define if FontData has upside down characters */ #undef CHAR_GEN_UPSIDE_DOWN
#define BOOTCHAR_HEIGHT 13 #define BOOTCHAR_WIDTH 8 // Each character line is encoded in a UCHAR.
-#ifndef _M_ARM -#include "i386/pc/vga.h" -#endif /* _M_ARM */ - /* Bitmap Header */ typedef struct tagBITMAPINFOHEADER { @@ -35,31 +41,43 @@ typedef struct tagBITMAPINFOHEADER #define BI_RGB 0 #define BI_RLE4 2
+typedef struct _PALETTE_ENTRY +{ + UCHAR Red; + UCHAR Green; + UCHAR Blue; +} PALETTE_ENTRY, *PPALETTE_ENTRY; + VOID NTAPI InitializePalette(VOID);
-/* Globals */ -#ifndef _M_ARM -extern ULONG curr_x; -extern ULONG curr_y; -extern ULONG_PTR VgaRegisterBase; -extern ULONG_PTR VgaBase; -extern USHORT AT_Initialization[]; -extern USHORT VGA_640x480[]; -#endif /* _M_ARM */ -extern UCHAR FontData[256 * BOOTCHAR_HEIGHT]; - -#define __inpb(Port) \ - READ_PORT_UCHAR((PUCHAR)(VgaRegisterBase + (Port))) +VOID +NTAPI +DisplayCharacter( + _In_ CHAR Character, + _In_ ULONG Left, + _In_ ULONG Top, + _In_ ULONG TextColor, + _In_ ULONG BackColor +);
-#define __inpw(Port) \ - READ_PORT_USHORT((PUSHORT)(VgaRegisterBase + (Port))) +VOID +PrepareForSetPixel(VOID);
-#define __outpb(Port, Value) \ - WRITE_PORT_UCHAR((PUCHAR)(VgaRegisterBase + (Port)), (UCHAR)(Value)) +VOID +NTAPI +InitPaletteWithTable( + _In_ PULONG Table, + _In_ ULONG Count);
-#define __outpw(Port, Value) \ - WRITE_PORT_USHORT((PUSHORT)(VgaRegisterBase + (Port)), (USHORT)(Value)) +/* + * Globals + */ +extern UCHAR VidpTextColor; +extern ULONG VidpCurrentX; +extern ULONG VidpCurrentY; +extern ULONG VidpScrollRegion[4]; +extern UCHAR FontData[256 * BOOTCHAR_HEIGHT];
#endif /* _BOOTVID_PCH_ */ diff --git a/sdk/include/reactos/drivers/bootvid/bootvid.h b/sdk/include/reactos/drivers/bootvid/bootvid.h index 80f0a485913..23971957f4d 100644 --- a/sdk/include/reactos/drivers/bootvid/bootvid.h +++ b/sdk/include/reactos/drivers/bootvid/bootvid.h @@ -63,7 +63,7 @@ VidBitBlt(IN PUCHAR Buffer,
VOID NTAPI -VidScreenToBufferBlt(IN PUCHAR Buffer, +VidScreenToBufferBlt(OUT PUCHAR Buffer, IN ULONG Left, IN ULONG Top, IN ULONG Width,