[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.
This commit is contained in:
Hermès Bélusca-Maïto 2019-12-23 17:58:57 +01:00
parent 93e9877225
commit aca7ff54b0
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
2 changed files with 49 additions and 41 deletions

View file

@ -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];
}
}

View file

@ -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];
}
}