diff --git a/boot/freeldr/freeldr/arch/i386/pc/pcvideo.c b/boot/freeldr/freeldr/arch/i386/pc/pcvideo.c index a523cfe257d..4c44a68ccd6 100644 --- a/boot/freeldr/freeldr/arch/i386/pc/pcvideo.c +++ b/boot/freeldr/freeldr/arch/i386/pc/pcvideo.c @@ -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;