Author: hbelusca
Date: Wed Aug 26 01:26:33 2015
New Revision: 68827
URL:
http://svn.reactos.org/svn/reactos?rev=68827&view=rev
Log:
[NTVDM]
- Towards a complete fix of VGA console attach/detach: a lot of progress is made but few
little things need to be checked/adjusted.
- Fix text scroll (at least in text modes) by doing guest-to-guest moves, using the
EmulatorCopyMemory function introduced in r68826.
- Fix the computation of the screen rows/columns values stored in the BDA, in graphics
modes (in addition to the change of r68090), by dividing the graphics resolution by the
character heights & widths. Correct values are indeed needed by some programs, eg.
QBasic (I also add a CharacterWidth; normally it should be computable using the CRTC
registers, and is always == 8 or 9, but still...).
Modified:
trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.c
trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.h
trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/svga.c
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.c [iso-8859-1] Wed Aug 26 01:26:33
2015
@@ -1937,32 +1937,33 @@
{
PVGA_REGISTERS VgaRegisters;
WORD PageSize;
+ WORD CharacterWidth;
WORD CharacterHeight;
// PCOLORREF Palette;
} VGA_MODE, *PVGA_MODE;
static CONST VGA_MODE VideoModes[BIOS_MAX_VIDEO_MODE + 1] =
{
- {&VideoMode_40x25_text, 0x0800, 16}, /* Mode 00h - 16 color (mono)
*/
- {&VideoMode_40x25_text, 0x0800, 16}, /* Mode 01h - 16 color
*/
- {&VideoMode_80x25_text, 0x1000, 16}, /* Mode 02h - 16 color (mono)
*/
- {&VideoMode_80x25_text, 0x1000, 16}, /* Mode 03h - 16 color
*/
- {&VideoMode_320x200_4color, 0x4000, 8}, /* Mode 04h - CGA 4 color
*/
- {&VideoMode_320x200_4color, 0x4000, 8}, /* Mode 05h - CGA same (m) (uses
3rd CGA palette) */
- {&VideoMode_640x200_2color, 0x4000, 8}, /* Mode 06h - CGA 640*200 2 color
*/
- {NULL, 0x1000, 0}, /* Mode 07h - MDA monochrome text
80*25 */
- {NULL, 0x0000, 0}, /* Mode 08h - PCjr
*/
- {NULL, 0x0000, 0}, /* Mode 09h - PCjr
*/
- {NULL, 0x0000, 0}, /* Mode 0Ah - PCjr
*/
- {NULL, 0x0000, 0}, /* Mode 0Bh - Reserved
*/
- {NULL, 0x0000, 0}, /* Mode 0Ch - Reserved
*/
- {&VideoMode_320x200_16color, 0x2000, 8}, /* Mode 0Dh - EGA 320*200 16
color */
- {&VideoMode_640x200_16color, 0x4000, 8}, /* Mode 0Eh - EGA 640*200 16
color */
- {NULL, 0x8000, 0}, /* Mode 0Fh - EGA 640*350 mono
*/
- {&VideoMode_640x350_16color, 0x8000, 14}, /* Mode 10h - EGA 640*350 HiRes
16 color */
- {&VideoMode_640x480_2color, 0xA000, 16}, /* Mode 11h - VGA 640*480 mono
*/
- {&VideoMode_640x480_16color, 0xA000, 16}, /* Mode 12h - VGA
*/
- {&VideoMode_320x200_256color, 0x2000, 8}, /* Mode 13h - VGA
*/
+ {&VideoMode_40x25_text, 0x0800, 9, 16}, /* Mode 00h - 16 color (mono)
*/
+ {&VideoMode_40x25_text, 0x0800, 9, 16}, /* Mode 01h - 16 color
*/
+ {&VideoMode_80x25_text, 0x1000, 9, 16}, /* Mode 02h - 16 color (mono)
*/
+ {&VideoMode_80x25_text, 0x1000, 9, 16}, /* Mode 03h - 16 color
*/
+ {&VideoMode_320x200_4color, 0x4000, 8, 8}, /* Mode 04h - CGA 4 color
*/
+ {&VideoMode_320x200_4color, 0x4000, 8, 8}, /* Mode 05h - CGA same (m)
(uses 3rd CGA palette) */
+ {&VideoMode_640x200_2color, 0x4000, 8, 8}, /* Mode 06h - CGA 640*200 2
color */
+ {NULL, 0x1000, 1, 1}, /* Mode 07h - MDA monochrome text
80*25 */
+ {NULL, 0x0000, 1, 1}, /* Mode 08h - PCjr
*/
+ {NULL, 0x0000, 1, 1}, /* Mode 09h - PCjr
*/
+ {NULL, 0x0000, 1, 1}, /* Mode 0Ah - PCjr
*/
+ {NULL, 0x0000, 1, 1}, /* Mode 0Bh - Reserved
*/
+ {NULL, 0x0000, 1, 1}, /* Mode 0Ch - Reserved
*/
+ {&VideoMode_320x200_16color, 0x2000, 8, 8}, /* Mode 0Dh - EGA 320*200 16
color */
+ {&VideoMode_640x200_16color, 0x4000, 8, 8}, /* Mode 0Eh - EGA 640*200 16
color */
+ {NULL, 0x8000, 1, 1}, /* Mode 0Fh - EGA 640*350 mono
*/
+ {&VideoMode_640x350_16color, 0x8000, 8, 14}, /* Mode 10h - EGA 640*350
HiRes 16 color */
+ {&VideoMode_640x480_2color, 0xA000, 8, 16}, /* Mode 11h - VGA 640*480 mono
*/
+ {&VideoMode_640x480_16color, 0xA000, 8, 16}, /* Mode 12h - VGA
*/
+ {&VideoMode_320x200_256color, 0x2000, 8, 8}, /* Mode 13h - VGA
*/
};
#define IS_TEXT_MODE(ModeNumber) \
@@ -2021,10 +2022,10 @@
/* Move text lines up */
for (i = Rectangle.Top + Amount; i <= Rectangle.Bottom; i++)
{
- EmulatorWriteMemory(&EmulatorContext,
- VideoAddress + ((i - Amount) * Bda->ScreenColumns
+ Rectangle.Left) * sizeof(WORD),
- REAL_TO_PHYS(VideoAddress + ( i * Bda->ScreenColumns
+ Rectangle.Left) * sizeof(WORD)),
- (Rectangle.Right - Rectangle.Left + 1) *
sizeof(WORD));
+ EmulatorCopyMemory(&EmulatorContext,
+ VideoAddress + ((i - Amount) * Bda->ScreenColumns +
Rectangle.Left) * sizeof(WORD),
+ VideoAddress + ( i * Bda->ScreenColumns +
Rectangle.Left) * sizeof(WORD),
+ (Rectangle.Right - Rectangle.Left + 1) *
sizeof(WORD));
}
/* Fill the bottom of the rectangle */
@@ -2049,10 +2050,10 @@
/* Move text lines down */
for (i = Rectangle.Bottom - Amount; i >= Rectangle.Top; i--)
{
- EmulatorWriteMemory(&EmulatorContext,
- VideoAddress + ((i + Amount) * Bda->ScreenColumns
+ Rectangle.Left) * sizeof(WORD),
- REAL_TO_PHYS(VideoAddress + ( i * Bda->ScreenColumns
+ Rectangle.Left) * sizeof(WORD)),
- (Rectangle.Right - Rectangle.Left + 1) *
sizeof(WORD));
+ EmulatorCopyMemory(&EmulatorContext,
+ VideoAddress + ((i + Amount) * Bda->ScreenColumns +
Rectangle.Left) * sizeof(WORD),
+ VideoAddress + ( i * Bda->ScreenColumns +
Rectangle.Left) * sizeof(WORD),
+ (Rectangle.Right - Rectangle.Left + 1) *
sizeof(WORD));
}
/* Fill the top of the rectangle */
@@ -2076,10 +2077,10 @@
/* Move text lines left */
for (i = Rectangle.Top; i <= Rectangle.Bottom; i++)
{
- EmulatorWriteMemory(&EmulatorContext,
- VideoAddress + (i * Bda->ScreenColumns +
Rectangle.Left ) * sizeof(WORD),
- REAL_TO_PHYS(VideoAddress + (i * Bda->ScreenColumns +
Rectangle.Left + Amount) * sizeof(WORD)),
- (Rectangle.Right - Rectangle.Left - Amount + 1) *
sizeof(WORD));
+ EmulatorCopyMemory(&EmulatorContext,
+ VideoAddress + (i * Bda->ScreenColumns +
Rectangle.Left ) * sizeof(WORD),
+ VideoAddress + (i * Bda->ScreenColumns +
Rectangle.Left + Amount) * sizeof(WORD),
+ (Rectangle.Right - Rectangle.Left - Amount + 1) *
sizeof(WORD));
}
/* Fill the right of the rectangle */
@@ -2099,19 +2100,21 @@
case SCROLL_RIGHT:
{
+ INT Right;
+
/* Move text lines right */
for (i = Rectangle.Top; i <= Rectangle.Bottom; i++)
{
- EmulatorWriteMemory(&EmulatorContext,
- VideoAddress + (i * Bda->ScreenColumns +
Rectangle.Left + Amount) * sizeof(WORD),
- REAL_TO_PHYS(VideoAddress + (i * Bda->ScreenColumns +
Rectangle.Left ) * sizeof(WORD)),
- (Rectangle.Right - Rectangle.Left - Amount + 1) *
sizeof(WORD));
+ EmulatorCopyMemory(&EmulatorContext,
+ VideoAddress + (i * Bda->ScreenColumns +
Rectangle.Left + Amount) * sizeof(WORD),
+ VideoAddress + (i * Bda->ScreenColumns +
Rectangle.Left ) * sizeof(WORD),
+ (Rectangle.Right - Rectangle.Left - Amount + 1) *
sizeof(WORD));
}
/* Fill the left of the rectangle */
+ Right = Rectangle.Left + Amount - 1;
for (i = Rectangle.Top; i <= Rectangle.Bottom; i++)
{
- INT Right = Rectangle.Left + Amount - 1;
for (j = Rectangle.Left; j <= Right; j++)
{
EmulatorWriteMemory(&EmulatorContext,
@@ -2372,11 +2375,11 @@
IOWriteB(VGA_CRTC_DATA , LOBYTE(CursorStartEnd));
}
-VOID VidBiosSyncCursorPosition(VOID)
+static VOID VidBiosSyncCursorPosition(VOID)
{
BYTE Row, Column;
BYTE Low, High;
- SHORT ScreenColumns = VgaGetDisplayResolution().X;
+ SHORT ScreenColumns = Bda->ScreenColumns;
WORD Offset;
/* Get the cursor position */
@@ -2493,11 +2496,15 @@
/* Update the screen size */
Resolution = VgaGetDisplayResolution();
+ // This could be simplified if the VGA helper always returned the resolution
+ // in number of pixels, instead of in number of cells for text-modes only...
+ if (!IS_TEXT_MODE(ModeNumber))
+ {
+ Resolution.X /= VideoModes[ModeNumber].CharacterWidth ;
+ Resolution.Y /= VideoModes[ModeNumber].CharacterHeight;
+ }
Bda->ScreenColumns = Resolution.X;
Bda->ScreenRows = Resolution.Y - 1;
-
- /* Adjust the number of columns for graphics modes */
- if (!IS_TEXT_MODE(ModeNumber)) Bda->ScreenColumns >>= 3;
/* Update the current font */
Bda->CharacterHeight = VideoModes[ModeNumber].CharacterHeight;
@@ -2592,7 +2599,7 @@
* but we update the cursor position on the VGA side).
*/
VidBiosGetCursorPosition(&Row, &Column, PageNumber);
- VidBiosSetCursorPosition(Row, Column, PageNumber);
+ VidBiosSetCursorPosition( Row, Column, PageNumber);
return TRUE;
}
@@ -2814,11 +2821,11 @@
WORD i, j;
PUCHAR Font = (PUCHAR)FAR_POINTER(((PULONG)BaseAddress)[0x43]);
PUCHAR Glyph = &Font[LOBYTE(CharData) * Bda->CharacterHeight];
- BYTE PixelBuffer[8];
+ BYTE PixelBuffer[8]; // 8 == CharacterWidth
for (i = 0; i < Bda->CharacterHeight; i++)
{
- for (j = 0; j < 8; j++)
+ for (j = 0; j < ARRAYSIZE(PixelBuffer); j++)
{
PixelBuffer[j] = (Glyph[i] & (1 << (7 - j))) ?
HIBYTE(CharData) : 0;
}
@@ -2826,7 +2833,7 @@
EmulatorWriteMemory(&EmulatorContext,
TO_LINEAR(GRAPHICS_VIDEO_SEG,
((Row * Bda->CharacterHeight + i)
- * Bda->ScreenColumns + Column) <<
3),
+ * Bda->ScreenColumns + Column) * 8),
(LPVOID)PixelBuffer,
sizeof(PixelBuffer));
}
Modified: trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/bios…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/bios/vidbios.h [iso-8859-1] Wed Aug 26 01:26:33
2015
@@ -104,8 +104,6 @@
/* FUNCTIONS ******************************************************************/
-VOID VidBiosSyncCursorPosition(VOID);
-
VOID WINAPI VidBiosVideoService(LPWORD Stack);
VOID VidBiosDetachFromConsole(VOID);
Modified: trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/svga.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/hard…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/svga.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/hardware/video/svga.c [iso-8859-1] Wed Aug 26
01:26:33 2015
@@ -455,7 +455,6 @@
VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_LOW_REG] = LOBYTE(Offset);
VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_HIGH_REG] = HIBYTE(Offset);
- // VidBiosSyncCursorPosition();
VgaUpdateTextCursor();
}
@@ -519,13 +518,14 @@
ASSERT(CharBuff);
#endif
- /*
- * Resize the console
- */
+ /* Retrieve the latest console information */
+ GetConsoleScreenBufferInfo(TextConsoleBuffer, &ConsoleInfo);
+
+ /* Resize the console */
ConRect.Left = 0;
- ConRect.Top = ConsoleInfo.srWindow.Top;
ConRect.Right = ConRect.Left + Resolution->X - 1;
- ConRect.Bottom = ConRect.Top + Resolution->Y - 1;
+ ConRect.Bottom = max(ConsoleInfo.dwCursorPosition.Y, Resolution->Y - 1);
+ ConRect.Top = ConRect.Bottom - Resolution->Y + 1;
/*
* Use this trick to effectively resize the console buffer and window,
* because:
@@ -534,9 +534,13 @@
* - SetConsoleWindowInfo fails if the new console window size is larger
* than the current console screen buffer size.
*/
- SetConsoleScreenBufferSize(TextConsoleBuffer, *Resolution);
- SetConsoleWindowInfo(TextConsoleBuffer, TRUE, &ConRect);
- SetConsoleScreenBufferSize(TextConsoleBuffer, *Resolution);
+ Success = SetConsoleScreenBufferSize(TextConsoleBuffer, *Resolution);
+ DPRINT1("(attach) SetConsoleScreenBufferSize(1) %s with error %d\n",
Success ? "succeeded" : "failed", GetLastError());
+ Success = SetConsoleWindowInfo(TextConsoleBuffer, TRUE, &ConRect);
+ DPRINT1("(attach) SetConsoleWindowInfo %s with error %d\n", Success ?
"succeeded" : "failed", GetLastError());
+ Success = SetConsoleScreenBufferSize(TextConsoleBuffer, *Resolution);
+ DPRINT1("(attach) SetConsoleScreenBufferSize(2) %s with error %d\n",
Success ? "succeeded" : "failed", GetLastError());
+
/* Update the saved console information */
GetConsoleScreenBufferInfo(TextConsoleBuffer, &ConsoleInfo);
@@ -544,14 +548,11 @@
* Copy console data into VGA memory
*/
- /* Get the data */
- AddressSize = VgaGetAddressSize();
+ /* Read the data from the console into the framebuffer... */
ConRect.Left = ConRect.Top = 0;
ConRect.Right = TextResolution.X;
ConRect.Bottom = TextResolution.Y;
- ScanlineSize = (DWORD)VgaCrtcRegisters[VGA_CRTC_OFFSET_REG] * 2;
-
- /* Read the data from the console into the framebuffer... */
+
ReadConsoleOutputA(TextConsoleBuffer,
CharBuff,
TextResolution,
@@ -559,6 +560,8 @@
&ConRect);
/* ... and copy the framebuffer into the VGA memory */
+ AddressSize = VgaGetAddressSize();
+ ScanlineSize = (DWORD)VgaCrtcRegisters[VGA_CRTC_OFFSET_REG] * 2;
/* Loop through the scanlines */
for (i = 0; i < TextResolution.Y; i++)
@@ -1058,6 +1061,7 @@
static BOOL VgaEnterTextMode(PCOORD Resolution)
{
/* Switch to the text buffer */
+ // FIXME: Wouldn't it be preferrable to switch to it AFTER we reset everything??
VgaSetActiveScreenBuffer(TextConsoleBuffer);
/* Adjust the text framebuffer if we changed the resolution */
@@ -1067,8 +1071,8 @@
VgaDetachFromConsoleInternal();
/*
- * VgaAttachToConsoleInternal sets TextResolution to the
- * new resolution and updates ConsoleInfo.
+ * VgaAttachToConsoleInternal sets TextResolution
+ * to the new resolution and updates ConsoleInfo.
*/
if (!VgaAttachToConsoleInternal(Resolution))
{
@@ -1126,6 +1130,9 @@
{
goto Quit;
}
+
+ // FIXME: Wouldn't it be preferrable to switch to the new console SB
+ // *ONLY* if we succeeded in setting the new mode??
/* Leave the current video mode */
if (ScreenMode == GRAPHICS_MODE)
@@ -1495,7 +1502,7 @@
{
/* Hidden cursor */
CursorInfo.bVisible = FALSE;
- CursorInfo.dwSize = 1; // The size needs to be non-null in order
SetConsoleCursorInfo to succeed.
+ CursorInfo.dwSize = 1; // The size needs to be non-zero for
SetConsoleCursorInfo to succeed.
}
/* Add the cursor skew to the location */
@@ -2315,8 +2322,8 @@
// VgaDetachFromConsoleInternal();
/*
- * VgaAttachToConsoleInternal sets TextResolution to the
- * new resolution and updates ConsoleInfo.
+ * VgaAttachToConsoleInternal sets TextResolution
+ * to the new resolution and updates ConsoleInfo.
*/
if (!VgaAttachToConsoleInternal(&TextResolution))
{
@@ -2347,6 +2354,8 @@
VOID VgaDetachFromConsole(VOID)
{
+ BOOL Success;
+
SMALL_RECT ConRect;
VgaDetachFromConsoleInternal();
@@ -2361,23 +2370,33 @@
OldConsoleFramebuffer = ConsoleFramebuffer;
ConsoleFramebuffer = NULL;
+ /* Restore the original console size */
+ ConRect.Left = ConRect.Top = 0;
+ ConRect.Right = ConRect.Left + OrgConsoleBufferInfo.srWindow.Right -
OrgConsoleBufferInfo.srWindow.Left;
+ ConRect.Bottom = ConRect.Top + OrgConsoleBufferInfo.srWindow.Bottom -
OrgConsoleBufferInfo.srWindow.Top ;
+ /* See the following trick explanation in VgaAttachToConsoleInternal */
+ Success = SetConsoleScreenBufferSize(TextConsoleBuffer,
OrgConsoleBufferInfo.dwSize);
+ DPRINT1("(detach) SetConsoleScreenBufferSize(1) %s with error %d\n",
Success ? "succeeded" : "failed", GetLastError());
+ Success = SetConsoleWindowInfo(TextConsoleBuffer, TRUE, &ConRect);
+ DPRINT1("(detach) SetConsoleWindowInfo %s with error %d\n", Success ?
"succeeded" : "failed", GetLastError());
+ Success = SetConsoleScreenBufferSize(TextConsoleBuffer,
OrgConsoleBufferInfo.dwSize);
+ DPRINT1("(detach) SetConsoleScreenBufferSize(2) %s with error %d\n",
Success ? "succeeded" : "failed", GetLastError());
+
+ /* Restore the original cursor shape */
+ SetConsoleCursorInfo(TextConsoleBuffer, &OrgConsoleCursorInfo);
+
+ // FIXME: Should we copy back the screen data to the screen buffer??
+ // WriteConsoleOutputA(...);
+
+ // FIXME: Should we change cursor POSITION??
+ // VgaUpdateTextCursor();
+
+ ///* Update the physical cursor */
+ //SetConsoleCursorInfo(TextConsoleBuffer, &CursorInfo);
+ //SetConsoleCursorPosition(TextConsoleBuffer, Position
/*OrgConsoleBufferInfo.dwCursorPosition*/);
+
/* Restore the old text-mode screen buffer */
VgaSetActiveScreenBuffer(TextConsoleBuffer);
-
- /* Restore the original console size */
- ConRect.Left = 0;
- ConRect.Top = 0;
- ConRect.Right = ConRect.Left + OrgConsoleBufferInfo.srWindow.Right -
OrgConsoleBufferInfo.srWindow.Left;
- ConRect.Bottom = ConRect.Top + OrgConsoleBufferInfo.srWindow.Bottom -
OrgConsoleBufferInfo.srWindow.Top ;
- /*
- * See the following trick explanation in VgaAttachToConsoleInternal.
- */
- SetConsoleScreenBufferSize(TextConsoleBuffer, OrgConsoleBufferInfo.dwSize);
- SetConsoleWindowInfo(TextConsoleBuffer, TRUE, &ConRect);
- SetConsoleScreenBufferSize(TextConsoleBuffer, OrgConsoleBufferInfo.dwSize);
-
- /* Restore the original cursor shape */
- SetConsoleCursorInfo(TextConsoleBuffer, &OrgConsoleCursorInfo);
}
BOOLEAN VgaInitialize(HANDLE TextHandle)
@@ -2395,10 +2414,10 @@
ConsoleInfo = OrgConsoleBufferInfo;
/* Clear the SEQ, GC, CRTC and AC registers */
- RtlZeroMemory(VgaSeqRegisters, sizeof(VgaSeqRegisters));
- RtlZeroMemory(VgaGcRegisters, sizeof(VgaGcRegisters));
+ RtlZeroMemory(VgaSeqRegisters , sizeof(VgaSeqRegisters ));
+ RtlZeroMemory(VgaGcRegisters , sizeof(VgaGcRegisters ));
RtlZeroMemory(VgaCrtcRegisters, sizeof(VgaCrtcRegisters));
- RtlZeroMemory(VgaAcRegisters, sizeof(VgaAcRegisters));
+ RtlZeroMemory(VgaAcRegisters , sizeof(VgaAcRegisters ));
/* Initialize the VGA palette and fail if it isn't successfully created */
if (!VgaInitializePalette()) return FALSE;