mirror of
https://github.com/reactos/reactos.git
synced 2026-09-09 02:44:55 +08:00
[FREELDR:PC] pcvideo.c: Fix the PcVideoGetDisplayMode() helper for regular video BIOS mode
Fix a regression introduced in commit b050a4544e (PR #8506), when
detecting the initial video mode FreeLoader has been started with.
- In `PcVideoGetDisplayMode()`, for text modes, the number of "bytes per
scan-line" is always equal to the screen width (number of characters)
*TIMES* 2: one byte for character, one byte for attribute.
- Systematically reset the `BytesPerScanLine` in each `PcVideoSetModeWWxHH()`
sub-routine.
- Make `PcVideoGetBiosMode()` return the screen width in characters, and
compare it with what's stored in the BIOS data area for consistency.
This commit is contained in:
@@ -117,7 +117,7 @@ static ULONG VideoCard = VIDEOCARD_CGA_OR_OTHER; /* Type of video card in
|
||||
static USHORT BiosVideoMode = VIDEOMODE_NORMAL_TEXT; /* Current video mode as known by BIOS */
|
||||
static ULONG ScreenWidth = 80; /* Screen Width in characters */
|
||||
static ULONG ScreenHeight = 25; /* Screen Height in characters */
|
||||
static ULONG BytesPerScanLine = 160; /* Number of bytes per scanline (delta) */
|
||||
static ULONG BytesPerScanLine = (80 * 2); /* Number of bytes per scanline (delta) */
|
||||
static VIDEODISPLAYMODE DisplayMode = VideoTextMode; /* Current display mode */
|
||||
static BOOLEAN VesaVideoMode = FALSE; /* Are we using a VESA mode? */
|
||||
static SVGA_MODE_INFORMATION VesaVideoModeInformation; /* Only valid when in VESA mode */
|
||||
@@ -333,7 +333,8 @@ PcVideoVesaGetCurrentSVGAMode(
|
||||
|
||||
static BOOLEAN
|
||||
PcVideoGetBiosMode(
|
||||
_Out_ PUSHORT Mode)
|
||||
_Out_ PUSHORT Mode,
|
||||
_Out_opt_ PUSHORT WidthInChars)
|
||||
{
|
||||
REGS Regs;
|
||||
|
||||
@@ -375,6 +376,7 @@ PcVideoGetBiosMode(
|
||||
return FALSE;
|
||||
|
||||
*Mode = Regs.b.al;
|
||||
*WidthInChars = Regs.b.ah;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -382,6 +384,7 @@ static VOID
|
||||
PcVideoGetDisplayMode(VOID)
|
||||
{
|
||||
USHORT Mode = 0;
|
||||
USHORT WidthInChars;
|
||||
|
||||
/* Is the current mode VESA? */
|
||||
if (PcVideoVesaGetCurrentSVGAMode(&Mode) &&
|
||||
@@ -396,49 +399,23 @@ PcVideoGetDisplayMode(VOID)
|
||||
VesaVideoMode = TRUE;
|
||||
}
|
||||
/* If not, it should be a regular BIOS mode */
|
||||
else if (PcVideoGetBiosMode(&Mode))
|
||||
else if (PcVideoGetBiosMode(&Mode, &WidthInChars))
|
||||
{
|
||||
/*
|
||||
* The BIOS data area 0x400 holds information about the current video mode.
|
||||
* Infos at: https://web.archive.org/web/20240119203029/http://www.bioscentral.com/misc/bda.htm
|
||||
* https://stanislavs.org/helppc/bios_data_area.html
|
||||
* http://www.techhelpmanual.com/93-rom_bios_variables.html
|
||||
*/
|
||||
|
||||
UCHAR BiosMode = (*(PUCHAR)0x449) & 0x7F; /* Current video mode */
|
||||
ASSERT(BiosMode == Mode);
|
||||
BiosVideoMode = Mode;
|
||||
TRACE("BIOS mode detected\n");
|
||||
|
||||
ScreenWidth = *(PUSHORT)0x44A; /* Number of screen columns */
|
||||
ASSERT(ScreenWidth == WidthInChars);
|
||||
ScreenHeight = 1 + *(PUCHAR)0x484; /* 1 + "Rows on the screen (less 1, EGA+)" */
|
||||
|
||||
/*
|
||||
* Select bits 7 and 4 of "Video display data area (MCGA and VGA)"
|
||||
* |7|6|5|4|3|2|1|0|
|
||||
* | `------ see table below
|
||||
* `--------- alphanumeric scan lines (see table below)
|
||||
*
|
||||
* then convert to a number and map it to the scanline number:
|
||||
* Bit7 Bit4 Scan Lines
|
||||
* 0 0 350 line mode
|
||||
* 0 1 400 line mode
|
||||
* 1 0 200 line mode
|
||||
* 1 1 reserved
|
||||
*/
|
||||
BytesPerScanLine = (*(PUCHAR)0x489) & 0x90;
|
||||
BytesPerScanLine = ((BytesPerScanLine & 0x80) >> 6) | ((BytesPerScanLine & 0x10) >> 4);
|
||||
switch (BytesPerScanLine)
|
||||
{
|
||||
case VERTRES_200_SCANLINES:
|
||||
BytesPerScanLine = 200; break;
|
||||
case VERTRES_350_SCANLINES:
|
||||
BytesPerScanLine = 350; break;
|
||||
case VERTRES_400_SCANLINES:
|
||||
BytesPerScanLine = 400; break;
|
||||
default:
|
||||
BytesPerScanLine = 160; break;
|
||||
}
|
||||
|
||||
BytesPerScanLine = (ScreenWidth * 2); /* Text mode: one byte for character, one byte for attribute */
|
||||
DisplayMode = VideoTextMode;
|
||||
VesaVideoMode = FALSE;
|
||||
}
|
||||
@@ -450,7 +427,7 @@ PcVideoGetDisplayMode(VOID)
|
||||
BiosVideoMode = VIDEOMODE_NORMAL_TEXT;
|
||||
ScreenWidth = 80;
|
||||
ScreenHeight = 25;
|
||||
BytesPerScanLine = 160;
|
||||
BytesPerScanLine = (ScreenWidth * 2);
|
||||
DisplayMode = VideoTextMode;
|
||||
VesaVideoMode = FALSE;
|
||||
}
|
||||
@@ -774,6 +751,7 @@ PcVideoSetMode80x25(VOID)
|
||||
PcVideoSetBiosMode(0x03);
|
||||
ScreenWidth = 80;
|
||||
ScreenHeight = 25;
|
||||
BytesPerScanLine = (ScreenWidth * 2);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -804,6 +782,7 @@ PcVideoSetMode80x50_80x43(VOID)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
BytesPerScanLine = (ScreenWidth * 2);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -817,6 +796,7 @@ PcVideoSetMode80x28(VOID)
|
||||
PcVideoDefineCursor(11, 12);
|
||||
ScreenWidth = 80;
|
||||
ScreenHeight = 28;
|
||||
BytesPerScanLine = (ScreenWidth * 2);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -828,6 +808,7 @@ PcVideoSetMode80x30(VOID)
|
||||
PcVideoSet480ScanLines();
|
||||
ScreenWidth = 80;
|
||||
ScreenHeight = 30;
|
||||
BytesPerScanLine = (ScreenWidth * 2);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -842,6 +823,7 @@ PcVideoSetMode80x34(VOID)
|
||||
PcVideoSetDisplayEnd();
|
||||
ScreenWidth = 80;
|
||||
ScreenHeight = 34;
|
||||
BytesPerScanLine = (ScreenWidth * 2);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -857,6 +839,7 @@ PcVideoSetMode80x43(VOID)
|
||||
PcVideoDefineCursor(6, 7);
|
||||
ScreenWidth = 80;
|
||||
ScreenHeight = 43;
|
||||
BytesPerScanLine = (ScreenWidth * 2);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -873,6 +856,7 @@ PcVideoSetMode80x60(VOID)
|
||||
PcVideoSetDisplayEnd();
|
||||
ScreenWidth = 80;
|
||||
ScreenHeight = 60;
|
||||
BytesPerScanLine = (ScreenWidth * 2);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -887,7 +871,7 @@ PcVideoSetMode(USHORT NewMode)
|
||||
BiosVideoMode = NewMode;
|
||||
ScreenWidth = 80;
|
||||
ScreenHeight = 25;
|
||||
BytesPerScanLine = 160;
|
||||
BytesPerScanLine = (ScreenWidth * 2);
|
||||
DisplayMode = VideoTextMode;
|
||||
VesaVideoMode = FALSE;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user