Author: aandrejevic
Date: Fri May 2 21:17:05 2014
New Revision: 63119
URL:
http://svn.reactos.org/svn/reactos?rev=63119&view=rev
Log:
[NTVDM]
Restore the console to normal size while no DOS task is running and keep track
of the cursor position.
Adapted from a patch by Hermès Bélusca-Maïto.
Modified:
branches/ntvdm/subsystems/ntvdm/dos/dem.c
branches/ntvdm/subsystems/ntvdm/hardware/vga.c
branches/ntvdm/subsystems/ntvdm/hardware/vga.h
branches/ntvdm/subsystems/ntvdm/ntvdm.c
Modified: branches/ntvdm/subsystems/ntvdm/dos/dem.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos/dem.…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/dos/dem.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/dos/dem.c [iso-8859-1] Fri May 2 21:17:05 2014
@@ -20,6 +20,9 @@
#include "dem.h"
#include "bop.h"
+#include "bios/bios.h"
+#include "hardware/vga.h"
+
/* Extra PSDK/NDK Headers */
#include <ndk/obtypes.h>
@@ -117,7 +120,7 @@
STARTUPINFOA StartupInfo;
PROCESS_INFORMATION ProcessInformation;
- /* Remove return carriage character */
+ /* NULL-terminate the command by removing the return carriage character */
while (*CmdPtr != '\r') CmdPtr++;
*CmdPtr = '\0';
@@ -135,7 +138,8 @@
StartupInfo.cb = sizeof(StartupInfo);
- DosPrintCharacter('\n');
+ VgaRefreshDisplay();
+ VgaDetachFromConsole(FALSE);
Result = CreateProcessA(NULL,
CommandLine,
@@ -166,8 +170,10 @@
DPRINT1("Failed when launched command '%s'\n");
dwExitCode = GetLastError();
}
-
- DosPrintCharacter('\n');
+
+ VgaAttachToConsole();
+ VgaRefreshDisplay();
+ VidBiosSyncCursorPosition();
setAL((UCHAR)dwExitCode);
Modified: branches/ntvdm/subsystems/ntvdm/hardware/vga.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/hardware…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/hardware/vga.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/hardware/vga.c [iso-8859-1] Fri May 2 21:17:05 2014
@@ -12,6 +12,7 @@
#include "emulator.h"
#include "vga.h"
+#include "../bios/vidbios.h"
#include "io.h"
@@ -189,6 +190,10 @@
static HANDLE EndEvent = NULL;
static HANDLE AnotherEvent = NULL;
+static CONSOLE_CURSOR_INFO OrgConsoleCursorInfo;
+static CONSOLE_SCREEN_BUFFER_INFO OrgConsoleBufferInfo;
+
+
/*
* Text mode -- we always keep a valid text mode framebuffer
* even if we are in graphics mode. This is needed in order to
@@ -403,8 +408,24 @@
/* PRIVATE FUNCTIONS **********************************************************/
static inline DWORD VgaGetAddressSize(VOID);
-
-static BOOL VgaAttachToConsole(PCOORD Resolution)
+static VOID VgaUpdateTextCursor(VOID);
+
+static VOID VgaUpdateCursorPosition(VOID)
+{
+ /*
+ * Update the cursor position in the VGA registers.
+ */
+ WORD Offset = ConsoleInfo.dwCursorPosition.Y * TextResolution.X +
+ ConsoleInfo.dwCursorPosition.X;
+
+ VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_LOW_REG] = LOBYTE(Offset);
+ VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_HIGH_REG] = HIBYTE(Offset);
+
+ VidBiosSyncCursorPosition();
+ VgaUpdateTextCursor();
+}
+
+static BOOL VgaAttachToConsoleInternal(PCOORD Resolution)
{
BOOL Success;
ULONG Length = 0;
@@ -414,12 +435,10 @@
DWORD AddressSize, ScanlineSize;
DWORD Address = 0;
DWORD CurrentAddr;
- SMALL_RECT ScreenRect; // ConRect;
+ SMALL_RECT ConRect;
COORD Origin = { 0, 0 };
ASSERT(TextFramebuffer == NULL);
-
- // ResetEvent(AnotherEvent);
TextResolution = *Resolution;
@@ -454,504 +473,9 @@
return FALSE;
}
- /* Copy console data into VGA memory */
-
- /* Get the data */
- AddressSize = VgaGetAddressSize();
- ScreenRect.Left = ScreenRect.Top = 0;
- ScreenRect.Right = TextResolution.X;
- ScreenRect.Bottom = TextResolution.Y;
-
- // ConRect.Left = 0;
- // ConRect.Top = ConsoleSize->Y - BufferSize.Y;
- // ConRect.Right = ConRect.Left + BufferSize.X - 1;
- // ConRect.Bottom = ConRect.Top + BufferSize.Y - 1;
-
- ScanlineSize = (DWORD)VgaCrtcRegisters[VGA_CRTC_OFFSET_REG] * 2;
-
- /* Read the data from the console into the framebuffer... */
- ReadConsoleOutputA(TextConsoleBuffer,
- CharBuff,
- TextResolution,
- Origin,
- &ScreenRect); // &ConRect);
-
- /* ... and copy the framebuffer into the VGA memory */
-
- /* Loop through the scanlines */
- for (i = 0; i < TextResolution.Y; i++)
- {
- /* Loop through the characters */
- for (j = 0; j < TextResolution.X; j++)
- {
- CurrentAddr = LOWORD((Address + j) * AddressSize);
-
- /* Store the character in plane 0 */
- VgaMemory[CurrentAddr] = CharBuff[i * TextResolution.X + j].Char.AsciiChar;
-
- /* Store the attribute in plane 1 */
- VgaMemory[CurrentAddr + VGA_BANK_SIZE] = (BYTE)CharBuff[i * TextResolution.X
+ j].Attributes;
- }
-
- /* Move to the next scanline */
- Address += ScanlineSize;
- }
-
- return TRUE;
-}
-
-static VOID VgaDetachFromConsole(VOID)
-{
- ULONG dummyLength;
- PVOID dummyPtr;
- COORD dummySize = {0};
-
- __RegisterConsoleVDM(0,
- NULL,
- NULL,
- NULL,
- 0,
- &dummyLength,
- &dummyPtr,
- NULL,
- 0,
- dummySize,
- (PCHAR*)&dummyPtr);
-
- TextFramebuffer = NULL;
-}
-
-static BOOL IsConsoleHandle(HANDLE hHandle)
-{
- DWORD dwMode;
-
- /* Check whether the handle may be that of a console... */
- if ((GetFileType(hHandle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR)
- return FALSE;
-
/*
- * It may be. Perform another test... The idea comes from the
- * MSDN description of the WriteConsole API:
- *
- * "WriteConsole fails if it is used with a standard handle
- * that is redirected to a file. If an application processes
- * multilingual output that can be redirected, determine whether
- * the output handle is a console handle (one method is to call
- * the GetConsoleMode function and check whether it succeeds).
- * If the handle is a console handle, call WriteConsole. If the
- * handle is not a console handle, the output is redirected and
- * you should call WriteFile to perform the I/O."
+ * Resize the console
*/
- return GetConsoleMode(hHandle, &dwMode);
-}
-
-static inline DWORD VgaGetAddressSize(VOID)
-{
- if (VgaCrtcRegisters[VGA_CRTC_UNDERLINE_REG] & VGA_CRTC_UNDERLINE_DWORD)
- {
- /* Double-word addressing */
- return 4; // sizeof(DWORD)
- }
- else if (VgaCrtcRegisters[VGA_CRTC_MODE_CONTROL_REG] &
VGA_CRTC_MODE_CONTROL_BYTE)
- {
- /* Byte addressing */
- return 1; // sizeof(BYTE)
- }
- else
- {
- /* Word addressing */
- return 2; // sizeof(WORD)
- }
-}
-
-static inline DWORD VgaTranslateReadAddress(DWORD Address)
-{
- DWORD Offset = Address - VgaGetVideoBaseAddress();
- BYTE Plane;
-
- /* Check for chain-4 and odd-even mode */
- if (VgaSeqRegisters[VGA_SEQ_MEM_REG] & VGA_SEQ_MEM_C4)
- {
- /* The lowest two bits are the plane number */
- Plane = Offset & 3;
- Offset >>= 2;
- }
- else if (VgaGcRegisters[VGA_GC_MODE_REG] & VGA_GC_MODE_OE)
- {
- /* The LSB is the plane number */
- Plane = Offset & 1;
- Offset >>= 1;
- }
- else
- {
- /* Use the read mode */
- Plane = VgaGcRegisters[VGA_GC_READ_MAP_SEL_REG] & 0x03;
- }
-
- /* Multiply the offset by the address size */
- Offset *= VgaGetAddressSize();
-
- return Offset + Plane * VGA_BANK_SIZE;
-}
-
-static inline DWORD VgaTranslateWriteAddress(DWORD Address)
-{
- DWORD Offset = Address - VgaGetVideoBaseAddress();
-
- /* Check for chain-4 and odd-even mode */
- if (VgaSeqRegisters[VGA_SEQ_MEM_REG] & VGA_SEQ_MEM_C4)
- {
- /* Shift the offset to the right by 2 */
- Offset >>= 2;
- }
- else if (VgaGcRegisters[VGA_GC_MODE_REG] & VGA_GC_MODE_OE)
- {
- /* Shift the offset to the right by 1 */
- Offset >>= 1;
- }
-
- /* Multiply the offset by the address size */
- Offset *= VgaGetAddressSize();
-
- /* Return the offset on plane 0 */
- return Offset;
-}
-
-static inline BYTE VgaTranslateByteForWriting(BYTE Data, BYTE Plane)
-{
- BYTE WriteMode = VgaGcRegisters[VGA_GC_MODE_REG] & 3;
- BYTE BitMask = VgaGcRegisters[VGA_GC_BITMASK_REG];
-
- if (WriteMode == 1)
- {
- /* In write mode 1 just return the latch register */
- return VgaLatchRegisters[Plane];
- }
-
- if (WriteMode != 2)
- {
- /* Write modes 0 and 3 rotate the data to the right first */
- BYTE RotateCount = VgaGcRegisters[VGA_GC_ROTATE_REG] & 7;
- Data = LOBYTE(((DWORD)Data >> RotateCount) | ((DWORD)Data << (8 -
RotateCount)));
- }
- else
- {
- /* Write mode 2 expands the appropriate bit to all 8 bits */
- Data = (Data & (1 << Plane)) ? 0xFF : 0x00;
- }
-
- if (WriteMode == 0)
- {
- /*
- * In write mode 0, the enable set/reset register decides if the
- * set/reset bit should be expanded to all 8 bits.
- */
- if (VgaGcRegisters[VGA_GC_ENABLE_RESET_REG] & (1 << Plane))
- {
- /* Copy the bit from the set/reset register to all 8 bits */
- Data = (VgaGcRegisters[VGA_GC_RESET_REG] & (1 << Plane)) ? 0xFF :
0x00;
- }
- }
-
- if (WriteMode != 3)
- {
- /* Write modes 0 and 2 then perform a logical operation on the data and latch */
- BYTE LogicalOperation = (VgaGcRegisters[VGA_GC_ROTATE_REG] >> 3) & 3;
-
- if (LogicalOperation == 1) Data &= VgaLatchRegisters[Plane];
- else if (LogicalOperation == 2) Data |= VgaLatchRegisters[Plane];
- else if (LogicalOperation == 3) Data ^= VgaLatchRegisters[Plane];
- }
- else
- {
- /* For write mode 3, we AND the bitmask with the data, which is used as the new
bitmask */
- BitMask &= Data;
-
- /* Then we expand the bit in the set/reset field */
- Data = (VgaGcRegisters[VGA_GC_RESET_REG] & (1 << Plane)) ? 0xFF :
0x00;
- }
-
- /* Bits cleared in the bitmask are replaced with latch register bits */
- Data = (Data & BitMask) | (VgaLatchRegisters[Plane] & (~BitMask));
-
- /* Return the byte */
- return Data;
-}
-
-static inline VOID VgaMarkForUpdate(SHORT Row, SHORT Column)
-{
- /* Check if this is the first time the rectangle is updated */
- if (!NeedsUpdate)
- {
- UpdateRectangle.Left = UpdateRectangle.Top = MAXSHORT;
- UpdateRectangle.Right = UpdateRectangle.Bottom = MINSHORT;
- }
-
- /* Expand the rectangle to include the point */
- UpdateRectangle.Left = min(UpdateRectangle.Left, Column);
- UpdateRectangle.Right = max(UpdateRectangle.Right, Column);
- UpdateRectangle.Top = min(UpdateRectangle.Top, Row);
- UpdateRectangle.Bottom = max(UpdateRectangle.Bottom, Row);
-
- /* Set the update request flag */
- NeedsUpdate = TRUE;
-}
-
-static VOID VgaWriteSequencer(BYTE Data)
-{
- ASSERT(VgaSeqIndex < VGA_SEQ_MAX_REG);
-
- /* Save the value */
- VgaSeqRegisters[VgaSeqIndex] = Data;
-}
-
-static VOID VgaWriteGc(BYTE Data)
-{
- ASSERT(VgaGcIndex < VGA_GC_MAX_REG);
-
- /* Save the value */
- VgaGcRegisters[VgaGcIndex] = Data;
-
- /* Check the index */
- switch (VgaGcIndex)
- {
- case VGA_GC_MISC_REG:
- {
- /* The GC misc register decides if it's text or graphics mode */
- ModeChanged = TRUE;
- break;
- }
- }
-}
-
-static VOID VgaWriteCrtc(BYTE Data)
-{
- ASSERT(VgaGcIndex < VGA_CRTC_MAX_REG);
-
- /* Save the value */
- VgaCrtcRegisters[VgaCrtcIndex] = Data;
-
- /* Check the index */
- switch (VgaCrtcIndex)
- {
- case VGA_CRTC_END_HORZ_DISP_REG:
- case VGA_CRTC_VERT_DISP_END_REG:
- case VGA_CRTC_OVERFLOW_REG:
- {
- /* The video mode has changed */
- ModeChanged = TRUE;
- break;
- }
-
- case VGA_CRTC_CURSOR_LOC_LOW_REG:
- case VGA_CRTC_CURSOR_LOC_HIGH_REG:
- case VGA_CRTC_CURSOR_START_REG:
- case VGA_CRTC_CURSOR_END_REG:
- {
- /* Set the cursor moved flag */
- CursorMoved = TRUE;
- break;
- }
- }
-}
-
-static VOID VgaWriteDac(BYTE Data)
-{
- INT PaletteIndex;
- PALETTEENTRY Entry;
-
- /* Set the value */
- VgaDacRegisters[VgaDacIndex] = Data;
-
- /* Find the palette index */
- PaletteIndex = VgaDacIndex / 3;
-
- /* Fill the entry structure */
- Entry.peRed = VGA_DAC_TO_COLOR(VgaDacRegisters[PaletteIndex * 3]);
- Entry.peGreen = VGA_DAC_TO_COLOR(VgaDacRegisters[PaletteIndex * 3 + 1]);
- Entry.peBlue = VGA_DAC_TO_COLOR(VgaDacRegisters[PaletteIndex * 3 + 2]);
- Entry.peFlags = 0;
-
- /* Update the palette entry and set the palette change flag */
- SetPaletteEntries(PaletteHandle, PaletteIndex, 1, &Entry);
- PaletteChanged = TRUE;
-
- /* Update the index */
- VgaDacIndex++;
- VgaDacIndex %= VGA_PALETTE_SIZE;
-}
-
-static VOID VgaWriteAc(BYTE Data)
-{
- ASSERT(VgaAcIndex < VGA_AC_MAX_REG);
-
- /* Save the value */
- if (VgaAcIndex <= VGA_AC_PAL_F_REG)
- {
- if (VgaAcPalDisable) return;
-
- // DbgPrint(" AC Palette Writing %d to index %d\n", Data,
VgaAcIndex);
- if (VgaAcRegisters[VgaAcIndex] != Data)
- {
- /* Update the AC register and set the palette change flag */
- VgaAcRegisters[VgaAcIndex] = Data;
- PaletteChanged = TRUE;
- }
- }
- else
- {
- VgaAcRegisters[VgaAcIndex] = Data;
- }
-}
-
-static VOID VgaRestoreDefaultPalette(PPALETTEENTRY Entries, USHORT NumOfEntries)
-{
- USHORT i;
-
- /* Copy the colors of the default palette to the DAC and console palette */
- for (i = 0; i < NumOfEntries; i++)
- {
- /* Set the palette entries */
- Entries[i].peRed = GetRValue(VgaDefaultPalette[i]);
- Entries[i].peGreen = GetGValue(VgaDefaultPalette[i]);
- Entries[i].peBlue = GetBValue(VgaDefaultPalette[i]);
- Entries[i].peFlags = 0;
-
- /* Set the DAC registers */
- VgaDacRegisters[i * 3] = VGA_COLOR_TO_DAC(GetRValue(VgaDefaultPalette[i]));
- VgaDacRegisters[i * 3 + 1] = VGA_COLOR_TO_DAC(GetGValue(VgaDefaultPalette[i]));
- VgaDacRegisters[i * 3 + 2] = VGA_COLOR_TO_DAC(GetBValue(VgaDefaultPalette[i]));
- }
-}
-
-static BOOLEAN VgaInitializePalette(VOID)
-{
- LPLOGPALETTE Palette;
-
- /* Allocate storage space for the palette */
- Palette = (LPLOGPALETTE)HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY,
- sizeof(LOGPALETTE) +
- VGA_MAX_COLORS * sizeof(PALETTEENTRY));
- if (Palette == NULL) return FALSE;
-
- /* Initialize the palette */
- Palette->palVersion = 0x0300;
- Palette->palNumEntries = VGA_MAX_COLORS;
-
- /* Restore the default palette */
- VgaRestoreDefaultPalette(Palette->palPalEntry, Palette->palNumEntries);
-
- /* Create the palette */
- PaletteHandle = CreatePalette(Palette);
-
- /* Free the palette */
- HeapFree(GetProcessHeap(), 0, Palette);
-
- /* Fail if the palette wasn't successfully created... */
- if (PaletteHandle == NULL) return FALSE;
-
- /* ... otherwise return success */
- return TRUE;
-}
-
-static BOOL VgaEnterGraphicsMode(PCOORD Resolution)
-{
- DWORD i;
- CONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo;
- BYTE BitmapInfoBuffer[VGA_BITMAP_INFO_SIZE];
- LPBITMAPINFO BitmapInfo = (LPBITMAPINFO)BitmapInfoBuffer;
- LPWORD PaletteIndex = (LPWORD)(BitmapInfo->bmiColors);
-
- LONG Width = Resolution->X;
- LONG Height = Resolution->Y;
-
- /* Use DoubleVision mode if the resolution is too small */
- if (Width < VGA_MINIMUM_WIDTH && Height < VGA_MINIMUM_HEIGHT)
- {
- DoubleVision = TRUE;
- Width *= 2;
- Height *= 2;
- }
- else
- {
- DoubleVision = FALSE;
- }
-
- /* Fill the bitmap info header */
- ZeroMemory(&BitmapInfo->bmiHeader, sizeof(BITMAPINFOHEADER));
- BitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- BitmapInfo->bmiHeader.biWidth = Width;
- BitmapInfo->bmiHeader.biHeight = Height;
- BitmapInfo->bmiHeader.biBitCount = 8;
- BitmapInfo->bmiHeader.biPlanes = 1;
- BitmapInfo->bmiHeader.biCompression = BI_RGB;
- BitmapInfo->bmiHeader.biSizeImage = Width * Height /* * 1 == biBitCount / 8 */;
-
- /* Fill the palette data */
- for (i = 0; i < (VGA_PALETTE_SIZE / 3); i++) PaletteIndex[i] = (WORD)i;
-
- /* Fill the console graphics buffer info */
- GraphicsBufferInfo.dwBitMapInfoLength = VGA_BITMAP_INFO_SIZE;
- GraphicsBufferInfo.lpBitMapInfo = BitmapInfo;
- GraphicsBufferInfo.dwUsage = DIB_PAL_COLORS;
-
- /* Create the buffer */
- GraphicsConsoleBuffer = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ |
FILE_SHARE_WRITE,
- NULL,
- CONSOLE_GRAPHICS_BUFFER,
- &GraphicsBufferInfo);
- if (GraphicsConsoleBuffer == INVALID_HANDLE_VALUE) return FALSE;
-
- /* Save the framebuffer address and mutex */
- ConsoleFramebuffer = GraphicsBufferInfo.lpBitMap;
- ConsoleMutex = GraphicsBufferInfo.hMutex;
-
- /* Clear the framebuffer */
- ZeroMemory(ConsoleFramebuffer, BitmapInfo->bmiHeader.biSizeImage);
-
- /* Set the active buffer */
- SetConsoleActiveScreenBuffer(GraphicsConsoleBuffer);
-
- /* Set the graphics mode palette */
- SetConsolePalette(GraphicsConsoleBuffer,
- PaletteHandle,
- SYSPAL_NOSTATIC256);
-
- /* Set the screen mode flag */
- ScreenMode = GRAPHICS_MODE;
-
- return TRUE;
-}
-
-static VOID VgaLeaveGraphicsMode(VOID)
-{
- /* Release the console framebuffer mutex */
- ReleaseMutex(ConsoleMutex);
-
- /* Switch back to the default console text buffer */
- // SetConsoleActiveScreenBuffer(TextConsoleBuffer);
-
- /* Cleanup the video data */
- CloseHandle(ConsoleMutex);
- ConsoleMutex = NULL;
- ConsoleFramebuffer = NULL;
- CloseHandle(GraphicsConsoleBuffer);
- GraphicsConsoleBuffer = NULL;
- DoubleVision = FALSE;
-}
-
-static BOOL VgaEnterTextMode(PCOORD Resolution)
-{
- SMALL_RECT ConRect;
-
- DPRINT1("VgaEnterTextMode\n");
-
- /* Switch to the text buffer */
- SetConsoleActiveScreenBuffer(TextConsoleBuffer);
-
- /* Resize the console */
ConRect.Left = 0;
ConRect.Top = ConsoleInfo.srWindow.Top;
ConRect.Right = ConRect.Left + Resolution->X - 1;
@@ -970,30 +494,551 @@
/* Update the saved console information */
GetConsoleScreenBufferInfo(TextConsoleBuffer, &ConsoleInfo);
- /* Adjust the text framebuffer if we changed resolution */
+ /*
+ * Copy console data into VGA memory
+ */
+
+ /* Get the data */
+ AddressSize = VgaGetAddressSize();
+ 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,
+ Origin,
+ &ConRect);
+
+ /* ... and copy the framebuffer into the VGA memory */
+
+ /* Loop through the scanlines */
+ for (i = 0; i < TextResolution.Y; i++)
+ {
+ /* Loop through the characters */
+ for (j = 0; j < TextResolution.X; j++)
+ {
+ CurrentAddr = LOWORD((Address + j) * AddressSize);
+
+ /* Store the character in plane 0 */
+ VgaMemory[CurrentAddr] = CharBuff[i * TextResolution.X + j].Char.AsciiChar;
+
+ /* Store the attribute in plane 1 */
+ VgaMemory[CurrentAddr + VGA_BANK_SIZE] = (BYTE)CharBuff[i * TextResolution.X
+ j].Attributes;
+ }
+
+ /* Move to the next scanline */
+ Address += ScanlineSize;
+ }
+
+ VgaUpdateCursorPosition();
+
+ return TRUE;
+}
+
+BOOL VgaAttachToConsole(VOID)
+{
+ if (TextResolution.X == 0 || TextResolution.Y == 0)
+ DPRINT1("VgaAttachToConsole -- TextResolution uninitialized\n");
+
+ if (TextResolution.X == 0) TextResolution.X = 80;
+ if (TextResolution.Y == 0) TextResolution.Y = 25;
+
+ return VgaAttachToConsoleInternal(&TextResolution);
+}
+
+VOID VgaDetachFromConsole(BOOL ChangingMode)
+{
+ ULONG dummyLength;
+ PVOID dummyPtr;
+ COORD dummySize = {0};
+
+ __RegisterConsoleVDM(0,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ &dummyLength,
+ &dummyPtr,
+ NULL,
+ 0,
+ dummySize,
+ (PCHAR*)&dummyPtr);
+
+ TextFramebuffer = NULL;
+
+ if (!ChangingMode)
+ {
+ SMALL_RECT ConRect;
+
+ /* Restore the old screen buffer */
+ SetConsoleActiveScreenBuffer(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);
+ }
+}
+
+static BOOL IsConsoleHandle(HANDLE hHandle)
+{
+ DWORD dwMode;
+
+ /* Check whether the handle may be that of a console... */
+ if ((GetFileType(hHandle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR)
+ return FALSE;
+
+ /*
+ * It may be. Perform another test... The idea comes from the
+ * MSDN description of the WriteConsole API:
+ *
+ * "WriteConsole fails if it is used with a standard handle
+ * that is redirected to a file. If an application processes
+ * multilingual output that can be redirected, determine whether
+ * the output handle is a console handle (one method is to call
+ * the GetConsoleMode function and check whether it succeeds).
+ * If the handle is a console handle, call WriteConsole. If the
+ * handle is not a console handle, the output is redirected and
+ * you should call WriteFile to perform the I/O."
+ */
+ return GetConsoleMode(hHandle, &dwMode);
+}
+
+static inline DWORD VgaGetAddressSize(VOID)
+{
+ if (VgaCrtcRegisters[VGA_CRTC_UNDERLINE_REG] & VGA_CRTC_UNDERLINE_DWORD)
+ {
+ /* Double-word addressing */
+ return 4; // sizeof(DWORD)
+ }
+ else if (VgaCrtcRegisters[VGA_CRTC_MODE_CONTROL_REG] &
VGA_CRTC_MODE_CONTROL_BYTE)
+ {
+ /* Byte addressing */
+ return 1; // sizeof(BYTE)
+ }
+ else
+ {
+ /* Word addressing */
+ return 2; // sizeof(WORD)
+ }
+}
+
+static inline DWORD VgaTranslateReadAddress(DWORD Address)
+{
+ DWORD Offset = Address - VgaGetVideoBaseAddress();
+ BYTE Plane;
+
+ /* Check for chain-4 and odd-even mode */
+ if (VgaSeqRegisters[VGA_SEQ_MEM_REG] & VGA_SEQ_MEM_C4)
+ {
+ /* The lowest two bits are the plane number */
+ Plane = Offset & 3;
+ Offset >>= 2;
+ }
+ else if (VgaGcRegisters[VGA_GC_MODE_REG] & VGA_GC_MODE_OE)
+ {
+ /* The LSB is the plane number */
+ Plane = Offset & 1;
+ Offset >>= 1;
+ }
+ else
+ {
+ /* Use the read mode */
+ Plane = VgaGcRegisters[VGA_GC_READ_MAP_SEL_REG] & 0x03;
+ }
+
+ /* Multiply the offset by the address size */
+ Offset *= VgaGetAddressSize();
+
+ return Offset + Plane * VGA_BANK_SIZE;
+}
+
+static inline DWORD VgaTranslateWriteAddress(DWORD Address)
+{
+ DWORD Offset = Address - VgaGetVideoBaseAddress();
+
+ /* Check for chain-4 and odd-even mode */
+ if (VgaSeqRegisters[VGA_SEQ_MEM_REG] & VGA_SEQ_MEM_C4)
+ {
+ /* Shift the offset to the right by 2 */
+ Offset >>= 2;
+ }
+ else if (VgaGcRegisters[VGA_GC_MODE_REG] & VGA_GC_MODE_OE)
+ {
+ /* Shift the offset to the right by 1 */
+ Offset >>= 1;
+ }
+
+ /* Multiply the offset by the address size */
+ Offset *= VgaGetAddressSize();
+
+ /* Return the offset on plane 0 */
+ return Offset;
+}
+
+static inline BYTE VgaTranslateByteForWriting(BYTE Data, BYTE Plane)
+{
+ BYTE WriteMode = VgaGcRegisters[VGA_GC_MODE_REG] & 3;
+ BYTE BitMask = VgaGcRegisters[VGA_GC_BITMASK_REG];
+
+ if (WriteMode == 1)
+ {
+ /* In write mode 1 just return the latch register */
+ return VgaLatchRegisters[Plane];
+ }
+
+ if (WriteMode != 2)
+ {
+ /* Write modes 0 and 3 rotate the data to the right first */
+ BYTE RotateCount = VgaGcRegisters[VGA_GC_ROTATE_REG] & 7;
+ Data = LOBYTE(((DWORD)Data >> RotateCount) | ((DWORD)Data << (8 -
RotateCount)));
+ }
+ else
+ {
+ /* Write mode 2 expands the appropriate bit to all 8 bits */
+ Data = (Data & (1 << Plane)) ? 0xFF : 0x00;
+ }
+
+ if (WriteMode == 0)
+ {
+ /*
+ * In write mode 0, the enable set/reset register decides if the
+ * set/reset bit should be expanded to all 8 bits.
+ */
+ if (VgaGcRegisters[VGA_GC_ENABLE_RESET_REG] & (1 << Plane))
+ {
+ /* Copy the bit from the set/reset register to all 8 bits */
+ Data = (VgaGcRegisters[VGA_GC_RESET_REG] & (1 << Plane)) ? 0xFF :
0x00;
+ }
+ }
+
+ if (WriteMode != 3)
+ {
+ /* Write modes 0 and 2 then perform a logical operation on the data and latch */
+ BYTE LogicalOperation = (VgaGcRegisters[VGA_GC_ROTATE_REG] >> 3) & 3;
+
+ if (LogicalOperation == 1) Data &= VgaLatchRegisters[Plane];
+ else if (LogicalOperation == 2) Data |= VgaLatchRegisters[Plane];
+ else if (LogicalOperation == 3) Data ^= VgaLatchRegisters[Plane];
+ }
+ else
+ {
+ /* For write mode 3, we AND the bitmask with the data, which is used as the new
bitmask */
+ BitMask &= Data;
+
+ /* Then we expand the bit in the set/reset field */
+ Data = (VgaGcRegisters[VGA_GC_RESET_REG] & (1 << Plane)) ? 0xFF :
0x00;
+ }
+
+ /* Bits cleared in the bitmask are replaced with latch register bits */
+ Data = (Data & BitMask) | (VgaLatchRegisters[Plane] & (~BitMask));
+
+ /* Return the byte */
+ return Data;
+}
+
+static inline VOID VgaMarkForUpdate(SHORT Row, SHORT Column)
+{
+ /* Check if this is the first time the rectangle is updated */
+ if (!NeedsUpdate)
+ {
+ UpdateRectangle.Left = UpdateRectangle.Top = MAXSHORT;
+ UpdateRectangle.Right = UpdateRectangle.Bottom = MINSHORT;
+ }
+
+ /* Expand the rectangle to include the point */
+ UpdateRectangle.Left = min(UpdateRectangle.Left, Column);
+ UpdateRectangle.Right = max(UpdateRectangle.Right, Column);
+ UpdateRectangle.Top = min(UpdateRectangle.Top, Row);
+ UpdateRectangle.Bottom = max(UpdateRectangle.Bottom, Row);
+
+ /* Set the update request flag */
+ NeedsUpdate = TRUE;
+}
+
+static VOID VgaWriteSequencer(BYTE Data)
+{
+ ASSERT(VgaSeqIndex < VGA_SEQ_MAX_REG);
+
+ /* Save the value */
+ VgaSeqRegisters[VgaSeqIndex] = Data;
+}
+
+static VOID VgaWriteGc(BYTE Data)
+{
+ ASSERT(VgaGcIndex < VGA_GC_MAX_REG);
+
+ /* Save the value */
+ VgaGcRegisters[VgaGcIndex] = Data;
+
+ /* Check the index */
+ switch (VgaGcIndex)
+ {
+ case VGA_GC_MISC_REG:
+ {
+ /* The GC misc register decides if it's text or graphics mode */
+ ModeChanged = TRUE;
+ break;
+ }
+ }
+}
+
+static VOID VgaWriteCrtc(BYTE Data)
+{
+ ASSERT(VgaGcIndex < VGA_CRTC_MAX_REG);
+
+ /* Save the value */
+ VgaCrtcRegisters[VgaCrtcIndex] = Data;
+
+ /* Check the index */
+ switch (VgaCrtcIndex)
+ {
+ case VGA_CRTC_END_HORZ_DISP_REG:
+ case VGA_CRTC_VERT_DISP_END_REG:
+ case VGA_CRTC_OVERFLOW_REG:
+ {
+ /* The video mode has changed */
+ ModeChanged = TRUE;
+ break;
+ }
+
+ case VGA_CRTC_CURSOR_LOC_LOW_REG:
+ case VGA_CRTC_CURSOR_LOC_HIGH_REG:
+ case VGA_CRTC_CURSOR_START_REG:
+ case VGA_CRTC_CURSOR_END_REG:
+ {
+ /* Set the cursor moved flag */
+ CursorMoved = TRUE;
+ break;
+ }
+ }
+}
+
+static VOID VgaWriteDac(BYTE Data)
+{
+ INT PaletteIndex;
+ PALETTEENTRY Entry;
+
+ /* Set the value */
+ VgaDacRegisters[VgaDacIndex] = Data;
+
+ /* Find the palette index */
+ PaletteIndex = VgaDacIndex / 3;
+
+ /* Fill the entry structure */
+ Entry.peRed = VGA_DAC_TO_COLOR(VgaDacRegisters[PaletteIndex * 3]);
+ Entry.peGreen = VGA_DAC_TO_COLOR(VgaDacRegisters[PaletteIndex * 3 + 1]);
+ Entry.peBlue = VGA_DAC_TO_COLOR(VgaDacRegisters[PaletteIndex * 3 + 2]);
+ Entry.peFlags = 0;
+
+ /* Update the palette entry and set the palette change flag */
+ SetPaletteEntries(PaletteHandle, PaletteIndex, 1, &Entry);
+ PaletteChanged = TRUE;
+
+ /* Update the index */
+ VgaDacIndex++;
+ VgaDacIndex %= VGA_PALETTE_SIZE;
+}
+
+static VOID VgaWriteAc(BYTE Data)
+{
+ ASSERT(VgaAcIndex < VGA_AC_MAX_REG);
+
+ /* Save the value */
+ if (VgaAcIndex <= VGA_AC_PAL_F_REG)
+ {
+ if (VgaAcPalDisable) return;
+
+ // DbgPrint(" AC Palette Writing %d to index %d\n", Data,
VgaAcIndex);
+ if (VgaAcRegisters[VgaAcIndex] != Data)
+ {
+ /* Update the AC register and set the palette change flag */
+ VgaAcRegisters[VgaAcIndex] = Data;
+ PaletteChanged = TRUE;
+ }
+ }
+ else
+ {
+ VgaAcRegisters[VgaAcIndex] = Data;
+ }
+}
+
+static VOID VgaRestoreDefaultPalette(PPALETTEENTRY Entries, USHORT NumOfEntries)
+{
+ USHORT i;
+
+ /* Copy the colors of the default palette to the DAC and console palette */
+ for (i = 0; i < NumOfEntries; i++)
+ {
+ /* Set the palette entries */
+ Entries[i].peRed = GetRValue(VgaDefaultPalette[i]);
+ Entries[i].peGreen = GetGValue(VgaDefaultPalette[i]);
+ Entries[i].peBlue = GetBValue(VgaDefaultPalette[i]);
+ Entries[i].peFlags = 0;
+
+ /* Set the DAC registers */
+ VgaDacRegisters[i * 3] = VGA_COLOR_TO_DAC(GetRValue(VgaDefaultPalette[i]));
+ VgaDacRegisters[i * 3 + 1] = VGA_COLOR_TO_DAC(GetGValue(VgaDefaultPalette[i]));
+ VgaDacRegisters[i * 3 + 2] = VGA_COLOR_TO_DAC(GetBValue(VgaDefaultPalette[i]));
+ }
+}
+
+static BOOLEAN VgaInitializePalette(VOID)
+{
+ LPLOGPALETTE Palette;
+
+ /* Allocate storage space for the palette */
+ Palette = (LPLOGPALETTE)HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(LOGPALETTE) +
+ VGA_MAX_COLORS * sizeof(PALETTEENTRY));
+ if (Palette == NULL) return FALSE;
+
+ /* Initialize the palette */
+ Palette->palVersion = 0x0300;
+ Palette->palNumEntries = VGA_MAX_COLORS;
+
+ /* Restore the default palette */
+ VgaRestoreDefaultPalette(Palette->palPalEntry, Palette->palNumEntries);
+
+ /* Create the palette */
+ PaletteHandle = CreatePalette(Palette);
+
+ /* Free the palette */
+ HeapFree(GetProcessHeap(), 0, Palette);
+
+ /* Fail if the palette wasn't successfully created... */
+ if (PaletteHandle == NULL) return FALSE;
+
+ /* ... otherwise return success */
+ return TRUE;
+}
+
+static BOOL VgaEnterGraphicsMode(PCOORD Resolution)
+{
+ DWORD i;
+ CONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo;
+ BYTE BitmapInfoBuffer[VGA_BITMAP_INFO_SIZE];
+ LPBITMAPINFO BitmapInfo = (LPBITMAPINFO)BitmapInfoBuffer;
+ LPWORD PaletteIndex = (LPWORD)(BitmapInfo->bmiColors);
+
+ LONG Width = Resolution->X;
+ LONG Height = Resolution->Y;
+
+ /* Use DoubleVision mode if the resolution is too small */
+ if (Width < VGA_MINIMUM_WIDTH && Height < VGA_MINIMUM_HEIGHT)
+ {
+ DoubleVision = TRUE;
+ Width *= 2;
+ Height *= 2;
+ }
+ else
+ {
+ DoubleVision = FALSE;
+ }
+
+ /* Fill the bitmap info header */
+ ZeroMemory(&BitmapInfo->bmiHeader, sizeof(BITMAPINFOHEADER));
+ BitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ BitmapInfo->bmiHeader.biWidth = Width;
+ BitmapInfo->bmiHeader.biHeight = Height;
+ BitmapInfo->bmiHeader.biBitCount = 8;
+ BitmapInfo->bmiHeader.biPlanes = 1;
+ BitmapInfo->bmiHeader.biCompression = BI_RGB;
+ BitmapInfo->bmiHeader.biSizeImage = Width * Height /* * 1 == biBitCount / 8 */;
+
+ /* Fill the palette data */
+ for (i = 0; i < (VGA_PALETTE_SIZE / 3); i++) PaletteIndex[i] = (WORD)i;
+
+ /* Fill the console graphics buffer info */
+ GraphicsBufferInfo.dwBitMapInfoLength = VGA_BITMAP_INFO_SIZE;
+ GraphicsBufferInfo.lpBitMapInfo = BitmapInfo;
+ GraphicsBufferInfo.dwUsage = DIB_PAL_COLORS;
+
+ /* Create the buffer */
+ GraphicsConsoleBuffer = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ |
FILE_SHARE_WRITE,
+ NULL,
+ CONSOLE_GRAPHICS_BUFFER,
+ &GraphicsBufferInfo);
+ if (GraphicsConsoleBuffer == INVALID_HANDLE_VALUE) return FALSE;
+
+ /* Save the framebuffer address and mutex */
+ ConsoleFramebuffer = GraphicsBufferInfo.lpBitMap;
+ ConsoleMutex = GraphicsBufferInfo.hMutex;
+
+ /* Clear the framebuffer */
+ ZeroMemory(ConsoleFramebuffer, BitmapInfo->bmiHeader.biSizeImage);
+
+ /* Set the active buffer */
+ SetConsoleActiveScreenBuffer(GraphicsConsoleBuffer);
+
+ /* Set the graphics mode palette */
+ SetConsolePalette(GraphicsConsoleBuffer,
+ PaletteHandle,
+ SYSPAL_NOSTATIC256);
+
+ /* Set the screen mode flag */
+ ScreenMode = GRAPHICS_MODE;
+
+ return TRUE;
+}
+
+static VOID VgaLeaveGraphicsMode(VOID)
+{
+ /* Release the console framebuffer mutex */
+ ReleaseMutex(ConsoleMutex);
+
+ /* Switch back to the default console text buffer */
+ // SetConsoleActiveScreenBuffer(TextConsoleBuffer);
+
+ /* Cleanup the video data */
+ CloseHandle(ConsoleMutex);
+ ConsoleMutex = NULL;
+ ConsoleFramebuffer = NULL;
+ CloseHandle(GraphicsConsoleBuffer);
+ GraphicsConsoleBuffer = NULL;
+ DoubleVision = FALSE;
+}
+
+static BOOL VgaEnterTextMode(PCOORD Resolution)
+{
+ DPRINT1("VgaEnterTextMode\n");
+
+ /* Switch to the text buffer */
+ SetConsoleActiveScreenBuffer(TextConsoleBuffer);
+
+ /* Adjust the text framebuffer if we changed the resolution */
if (TextResolution.X != Resolution->X ||
TextResolution.Y != Resolution->Y)
{
- WORD Offset;
-
- VgaDetachFromConsole();
-
- /* VgaAttachToConsole sets TextResolution to the new resolution */
- if (!VgaAttachToConsole(Resolution))
+ VgaDetachFromConsole(TRUE);
+
+ /*
+ * VgaAttachToConsoleInternal sets TextResolution to the
+ * new resolution and updates ConsoleInfo.
+ */
+ if (!VgaAttachToConsoleInternal(Resolution))
{
DisplayMessage(L"An unexpected error occurred!\n");
EmulatorTerminate();
return FALSE;
}
-
- /* Update the cursor position in the registers */
- Offset = ConsoleInfo.dwCursorPosition.Y * Resolution->X +
- ConsoleInfo.dwCursorPosition.X;
- DPRINT1("X = %d ; Y = %d\n", ConsoleInfo.dwCursorPosition.X,
ConsoleInfo.dwCursorPosition.Y);
- VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_LOW_REG] = LOBYTE(Offset);
- VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_HIGH_REG] = HIBYTE(Offset);
- CursorMoved = TRUE;
- }
+ }
+ else VgaUpdateCursorPosition();
/* The active framebuffer is now the text framebuffer */
ConsoleFramebuffer = TextFramebuffer;
@@ -1825,11 +1870,13 @@
if (!IsConsoleHandle(TextHandle)) return FALSE;
TextConsoleBuffer = TextHandle;
- /* Save the console information */
- if (!GetConsoleScreenBufferInfo(TextConsoleBuffer, &ConsoleInfo))
+ /* Save the original cursor and console screen buffer information */
+ if (!GetConsoleCursorInfo(TextConsoleBuffer, &OrgConsoleCursorInfo) ||
+ !GetConsoleScreenBufferInfo(TextConsoleBuffer, &OrgConsoleBufferInfo))
{
return FALSE;
}
+ ConsoleInfo = OrgConsoleBufferInfo;
/* Initialize the VGA palette and fail if it isn't successfully created */
if (!VgaInitializePalette()) return FALSE;
@@ -1873,7 +1920,7 @@
VgaLeaveTextMode();
}
- VgaDetachFromConsole();
+ VgaDetachFromConsole(FALSE);
CloseHandle(AnotherEvent);
CloseHandle(EndEvent);
Modified: branches/ntvdm/subsystems/ntvdm/hardware/vga.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/hardware…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/hardware/vga.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/hardware/vga.h [iso-8859-1] Fri May 2 21:17:05 2014
@@ -250,6 +250,9 @@
/* FUNCTIONS ******************************************************************/
+BOOL VgaAttachToConsole(VOID);
+VOID VgaDetachFromConsole(BOOL ChangeMode);
+
DWORD VgaGetVideoBaseAddress(VOID);
DWORD VgaGetVideoLimitAddress(VOID);
COORD VgaGetDisplayResolution(VOID);
Modified: branches/ntvdm/subsystems/ntvdm/ntvdm.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ntvdm.c?…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/ntvdm.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/ntvdm.c [iso-8859-1] Fri May 2 21:17:05 2014
@@ -32,8 +32,6 @@
static HANDLE ConsoleInput = INVALID_HANDLE_VALUE;
static HANDLE ConsoleOutput = INVALID_HANDLE_VALUE;
static DWORD OrgConsoleInputMode, OrgConsoleOutputMode;
-static CONSOLE_CURSOR_INFO OrgConsoleCursorInfo;
-static CONSOLE_SCREEN_BUFFER_INFO OrgConsoleBufferInfo;
static BOOLEAN AcceptCommands = TRUE;
static HANDLE CommandThread = NULL;
@@ -344,16 +342,6 @@
return FALSE;
}
- /* Save the original cursor and console screen buffer information */
- if (!GetConsoleCursorInfo(ConsoleOutput, &OrgConsoleCursorInfo) ||
- !GetConsoleScreenBufferInfo(ConsoleOutput, &OrgConsoleBufferInfo))
- {
- CloseHandle(ConsoleOutput);
- CloseHandle(ConsoleInput);
- wprintf(L"FATAL: Cannot save console cursor/screen-buffer info\n");
- return FALSE;
- }
-
/* Initialize the UI */
ConsoleInitUI();
@@ -362,26 +350,6 @@
VOID ConsoleCleanup(VOID)
{
- SMALL_RECT ConRect;
-
- /* Restore the old screen buffer */
- SetConsoleActiveScreenBuffer(ConsoleOutput);
-
- /* 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 vga.c:VgaEnterTextMode() .
- */
- SetConsoleScreenBufferSize(ConsoleOutput, OrgConsoleBufferInfo.dwSize);
- SetConsoleWindowInfo(ConsoleOutput, TRUE, &ConRect);
- SetConsoleScreenBufferSize(ConsoleOutput, OrgConsoleBufferInfo.dwSize);
-
- /* Restore the original cursor shape */
- SetConsoleCursorInfo(ConsoleOutput, &OrgConsoleCursorInfo);
-
/* Restore the original input and output console modes */
SetConsoleMode(ConsoleOutput, OrgConsoleOutputMode);
SetConsoleMode(ConsoleInput , OrgConsoleInputMode );
@@ -428,11 +396,7 @@
CommandInfo.Env = Env;
CommandInfo.EnvLen = sizeof(Env);
- if (First)
- {
- CommandInfo.VDMState |= VDM_FLAG_FIRST_TASK;
- First = FALSE;
- }
+ if (First) CommandInfo.VDMState |= VDM_FLAG_FIRST_TASK;
/* Wait for the next available VDM */
if (!GetNextVDMCommand(&CommandInfo)) break;
@@ -446,6 +410,12 @@
DisplayMessage(L"Could not start '%S'. Error: %u", AppName,
Result);
break;
}
+
+ /* Attach to the console */
+ if (!First) VgaAttachToConsole();
+
+ /* Perform a screen refresh */
+ VgaRefreshDisplay();
/* Start simulation */
SetEvent(VdmTaskEvent);
@@ -453,6 +423,11 @@
/* Perform another screen refresh */
VgaRefreshDisplay();
+
+ /* Detach from the console */
+ VgaDetachFromConsole(FALSE);
+
+ First = FALSE;
}
return 0;