https://git.reactos.org/?p=reactos.git;a=commitdiff;h=aca7ff54b0c908b431c05…
commit aca7ff54b0c908b431c05dc52444707e439e1468
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon Dec 23 17:58:57 2019 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Mon Dec 23 21:06:59 2019 +0100
[BOOTVID] Correctly fix scrolling and printing when the scroll region contains the
whole screen.
Addendum fixes to ca370b49 (r52239) and a965ca6b (r52409).
- Fix the comments to explain what is really happening.
- Fix the boundary calculations in VidDisplayString() so that we can
correctly display a character in the very last column before going
to the next line, and fix similarly the vertical boundary calculation.
- Port the fixes to the ARM code.
---
drivers/base/bootvid/arm/bootvid.c | 50 +++++++++++++++++++++-----------------
drivers/base/bootvid/i386/vga.c | 40 +++++++++++++++---------------
2 files changed, 49 insertions(+), 41 deletions(-)
diff --git a/drivers/base/bootvid/arm/bootvid.c b/drivers/base/bootvid/arm/bootvid.c
index 7a259885921..27e0e20af25 100644
--- a/drivers/base/bootvid/arm/bootvid.c
+++ b/drivers/base/bootvid/arm/bootvid.c
@@ -25,7 +25,7 @@
PUSHORT VgaArmBase;
PHYSICAL_ADDRESS VgaPhysical;
-BOOLEAN NextLine = FALSE;
+BOOLEAN ClearRow = FALSE;
UCHAR VidpTextColor = 0xF;
ULONG VidpCurrentX = 0;
ULONG VidpCurrentY = 0;
@@ -192,20 +192,21 @@ VOID
NTAPI
PreserveRow(IN ULONG CurrentTop,
IN ULONG TopDelta,
- IN BOOLEAN Direction)
+ IN BOOLEAN Restore)
{
PUSHORT Position1, Position2;
ULONG Count;
- /* Check which way we're preserving */
/* Calculate the position in memory for the row */
- if (Direction)
+ if (Restore)
{
+ /* Restore the row by copying back the contents saved off-screen */
Position1 = &VgaArmBase[CurrentTop * (SCREEN_WIDTH / 8)];
Position2 = &VgaArmBase[SCREEN_HEIGHT * (SCREEN_WIDTH / 8)];
}
else
{
+ /* Preserve the row by saving its contents off-screen */
Position1 = &VgaArmBase[SCREEN_HEIGHT * (SCREEN_WIDTH / 8)];
Position2 = &VgaArmBase[CurrentTop * (SCREEN_WIDTH / 8)];
}
@@ -415,38 +416,40 @@ VidDisplayString(IN PUCHAR String)
{
/* Modify Y position */
VidpCurrentY += TopDelta;
- if (VidpCurrentY >= VidpScrollRegion[3])
+ if (VidpCurrentY + TopDelta - 1 > VidpScrollRegion[3])
{
- /* Scroll the view */
+ /* Scroll the view and clear the current row */
VgaScroll(TopDelta);
VidpCurrentY -= TopDelta;
-
- /* Preserve row */
PreserveRow(VidpCurrentY, TopDelta, TRUE);
}
+ else
+ {
+ /* Preserve the current row */
+ PreserveRow(VidpCurrentY, TopDelta, FALSE);
+ }
/* Update current X */
VidpCurrentX = VidpScrollRegion[0];
- /* Preserve the current row */
- PreserveRow(VidpCurrentY, TopDelta, FALSE);
+ /* No need to clear this row */
+ ClearRow = FALSE;
}
else if (*String == '\r')
{
/* Update current X */
VidpCurrentX = VidpScrollRegion[0];
- /* Check if we're being followed by a new line */
- if (String[1] != '\n') NextLine = TRUE;
+ /* If a new-line does not follow we will clear the current row */
+ if (String[1] != '\n') ClearRow = TRUE;
}
else
{
- /* Check if we had a \n\r last time */
- if (NextLine)
+ /* Clear the current row if we had a return-carriage without a new-line */
+ if (ClearRow)
{
- /* We did, preserve the current row */
PreserveRow(VidpCurrentY, TopDelta, TRUE);
- NextLine = FALSE;
+ ClearRow = FALSE;
}
/* Display this character */
@@ -458,21 +461,24 @@ VidDisplayString(IN PUCHAR String)
VidpCurrentX += 8;
/* Check if we should scroll */
- if (VidpCurrentX > VidpScrollRegion[2])
+ if (VidpCurrentX + 7 > VidpScrollRegion[2])
{
/* Update Y position and check if we should scroll it */
VidpCurrentY += TopDelta;
- if (VidpCurrentY > VidpScrollRegion[3])
+ if (VidpCurrentY + TopDelta - 1 > VidpScrollRegion[3])
{
- /* Do the scroll */
+ /* Scroll the view and clear the current row */
VgaScroll(TopDelta);
VidpCurrentY -= TopDelta;
-
- /* Save the row */
PreserveRow(VidpCurrentY, TopDelta, TRUE);
}
+ else
+ {
+ /* Preserve the current row */
+ PreserveRow(VidpCurrentY, TopDelta, FALSE);
+ }
- /* Update X */
+ /* Update current X */
VidpCurrentX = VidpScrollRegion[0];
}
}
diff --git a/drivers/base/bootvid/i386/vga.c b/drivers/base/bootvid/i386/vga.c
index 2914200f246..99cd0dc7a9f 100644
--- a/drivers/base/bootvid/i386/vga.c
+++ b/drivers/base/bootvid/i386/vga.c
@@ -67,7 +67,7 @@ ULONG_PTR VgaBase = 0;
ULONG curr_x = 0;
ULONG curr_y = 0;
static ULONG VidTextColor = 0xF;
-static BOOLEAN CarriageReturn = FALSE;
+static BOOLEAN ClearRow = FALSE;
/* PRIVATE FUNCTIONS *********************************************************/
@@ -355,7 +355,7 @@ static VOID
NTAPI
PreserveRow(IN ULONG CurrentTop,
IN ULONG TopDelta,
- IN BOOLEAN Direction)
+ IN BOOLEAN Restore)
{
PUCHAR Position1, Position2;
ULONG Count;
@@ -369,15 +369,16 @@ PreserveRow(IN ULONG CurrentTop,
/* Set Mode 1 */
ReadWriteMode(1);
- /* Check which way we're preserving */
/* Calculate the position in memory for the row */
- if (Direction)
+ if (Restore)
{
+ /* Restore the row by copying back the contents saved off-screen */
Position1 = (PUCHAR)(VgaBase + CurrentTop * (SCREEN_WIDTH / 8));
Position2 = (PUCHAR)(VgaBase + SCREEN_HEIGHT * (SCREEN_WIDTH / 8));
}
else
{
+ /* Preserve the row by saving its contents off-screen */
Position1 = (PUCHAR)(VgaBase + SCREEN_HEIGHT * (SCREEN_WIDTH / 8));
Position2 = (PUCHAR)(VgaBase + CurrentTop * (SCREEN_WIDTH / 8));
}
@@ -760,40 +761,40 @@ VidDisplayString(IN PUCHAR String)
{
/* Modify Y position */
curr_y += TopDelta;
- if (curr_y + TopDelta >= ScrollRegion[3])
+ if (curr_y + TopDelta - 1 > ScrollRegion[3])
{
- /* Scroll the view */
+ /* Scroll the view and clear the current row */
VgaScroll(TopDelta);
curr_y -= TopDelta;
+ PreserveRow(curr_y, TopDelta, TRUE);
}
else
{
- /* Preserve row */
+ /* Preserve the current row */
PreserveRow(curr_y, TopDelta, FALSE);
}
/* Update current X */
curr_x = ScrollRegion[0];
- /* Do not clear line if "\r\n" is given */
- CarriageReturn = FALSE;
+ /* No need to clear this row */
+ ClearRow = FALSE;
}
else if (*String == '\r')
{
/* Update current X */
curr_x = ScrollRegion[0];
- /* Check if we're being followed by a new line */
- CarriageReturn = TRUE;
+ /* If a new-line does not follow we will clear the current row */
+ if (String[1] != '\n') ClearRow = TRUE;
}
else
{
- /* check if we had a '\r' last time */
- if (CarriageReturn)
+ /* Clear the current row if we had a return-carriage without a new-line */
+ if (ClearRow)
{
- /* We did, clear the current row */
PreserveRow(curr_y, TopDelta, TRUE);
- CarriageReturn = FALSE;
+ ClearRow = FALSE;
}
/* Display this character */
@@ -801,15 +802,16 @@ VidDisplayString(IN PUCHAR String)
curr_x += 8;
/* Check if we should scroll */
- if (curr_x + 8 > ScrollRegion[2])
+ if (curr_x + 7 > ScrollRegion[2])
{
/* Update Y position and check if we should scroll it */
curr_y += TopDelta;
- if (curr_y + TopDelta > ScrollRegion[3])
+ if (curr_y + TopDelta - 1 > ScrollRegion[3])
{
- /* Do the scroll */
+ /* Scroll the view and clear the current row */
VgaScroll(TopDelta);
curr_y -= TopDelta;
+ PreserveRow(curr_y, TopDelta, TRUE);
}
else
{
@@ -817,7 +819,7 @@ VidDisplayString(IN PUCHAR String)
PreserveRow(curr_y, TopDelta, FALSE);
}
- /* Update X */
+ /* Update current X */
curr_x = ScrollRegion[0];
}
}