- Finally get rid of console output handles in the BIOS.
- Move console text buffer copy from BIOS back into VGA memory (~= revert part of r61542), but do it ONLY when attaching the VGA emulation to the console.
- Fix cursor positioning in BIOS & VGA (work in progress).

- Initialize PS/2 after having setting basic console modes.
- Showing/hiding mouse cursor (see the option in the console menu) is done in while() loops to be sure the cursor is really shown/hidden (based on the return value of ShowConsoleCursor).

svn path=/branches/ntvdm/; revision=62373
This commit is contained in:
Hermès Bélusca-Maïto
2014-03-02 01:45:57 +00:00
parent b152f5cf43
commit ab9978f190
9 changed files with 125 additions and 90 deletions
+2 -3
View File
@@ -86,8 +86,7 @@ static VOID WINAPI BiosInitBop(LPWORD Stack)
/* PUBLIC FUNCTIONS ***********************************************************/
BOOLEAN
BiosInitialize(IN LPCSTR BiosFileName,
IN HANDLE ConsoleOutput)
BiosInitialize(IN LPCSTR BiosFileName)
{
/* Register the BIOS support BOPs */
RegisterBop(BOP_BIOSINIT, BiosInitBop);
@@ -143,7 +142,7 @@ BiosInitialize(IN LPCSTR BiosFileName,
}
else
{
Bios32Loaded = Bios32Initialize(ConsoleOutput);
Bios32Loaded = Bios32Initialize();
return Bios32Loaded;
}
}
+1 -2
View File
@@ -106,8 +106,7 @@ C_ASSERT(sizeof(BIOS_DATA_AREA) == 0x133);
extern PBIOS_DATA_AREA Bda;
BOOLEAN
BiosInitialize(IN LPCSTR BiosFileName,
IN HANDLE ConsoleOutput);
BiosInitialize(IN LPCSTR BiosFileName);
VOID
BiosCleanup(VOID);
+2 -2
View File
@@ -361,7 +361,7 @@ static VOID InitializeBiosInt32(VOID)
/*
* The BIOS POST (Power On-Self Test)
*/
BOOLEAN Bios32Initialize(IN HANDLE ConsoleOutput)
BOOLEAN Bios32Initialize(VOID)
{
BOOLEAN Success;
UCHAR Low, High;
@@ -403,7 +403,7 @@ BOOLEAN Bios32Initialize(IN HANDLE ConsoleOutput)
if (!KbdBios32Initialize()) return FALSE;
/* Initialize the Video BIOS */
if (!VidBios32Initialize(ConsoleOutput)) return FALSE;
if (!VidBios32Initialize()) return FALSE;
/* Enable interrupts */
setIF(1);
+1 -1
View File
@@ -129,7 +129,7 @@ extern PBIOS_DATA_AREA Bda;
VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func);
VOID PicIRQComplete(LPWORD Stack);
BOOLEAN Bios32Initialize(IN HANDLE ConsoleOutput);
BOOLEAN Bios32Initialize(VOID);
VOID Bios32Cleanup(VOID);
#endif // _BIOS32_H_
+29 -69
View File
@@ -733,58 +733,6 @@ Done:
return TRUE;
}
static VOID VidBiosCopyTextConsoleToVgaMemory(HANDLE ConsoleOutput, PCOORD ConsoleSize)
{
PCHAR_INFO CharBuffer;
COORD BufferSize = {Bda->ScreenColumns, Bda->ScreenRows + 1};
COORD Origin = { 0, 0 };
SMALL_RECT ConRect;
INT i, j;
INT Counter = 0;
WORD Character;
DWORD VideoAddress = TO_LINEAR(TEXT_VIDEO_SEG, Bda->VideoPage * Bda->VideoPageSize);
/* Allocate a temporary buffer for ReadConsoleOutput */
CharBuffer = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
BufferSize.X * BufferSize.Y
* sizeof(CHAR_INFO));
if (CharBuffer == NULL) return;
ConRect.Left = 0;
ConRect.Top = ConsoleSize->Y - BufferSize.Y;
ConRect.Right = ConRect.Left + BufferSize.X - 1;
ConRect.Bottom = ConRect.Top + BufferSize.Y - 1;
/* Read the data from the console into the temporary buffer... */
ReadConsoleOutputA(ConsoleOutput,
CharBuffer,
BufferSize,
Origin,
&ConRect);
/* ... and copy the temporary buffer into the VGA memory */
for (i = 0; i < BufferSize.Y; i++)
{
for (j = 0; j < BufferSize.X; j++)
{
Character = MAKEWORD(CharBuffer[Counter].Char.AsciiChar,
(BYTE)CharBuffer[Counter].Attributes);
++Counter;
/* Write to video memory */
EmulatorWriteMemory(&EmulatorContext,
VideoAddress + (i * Bda->ScreenColumns + j) * sizeof(WORD),
(LPVOID)&Character,
sizeof(WORD));
}
}
/* Free the temporary buffer */
HeapFree(GetProcessHeap(), 0, CharBuffer);
}
static BOOLEAN VgaSetRegisters(PVGA_REGISTERS Registers)
{
INT i;
@@ -925,6 +873,24 @@ static VOID VgaChangePalette(BYTE ModeNumber)
VgaSetPalette(Palette, Size);
}
static VOID VgaGetCursorPosition(PBYTE Row, PBYTE Column)
{
SHORT ScreenColumns = VgaGetDisplayResolution().X;
BYTE OffsetLow, OffsetHigh;
WORD Offset;
/* Get the cursor location */
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_LOW_REG);
OffsetLow = IOReadB(VGA_CRTC_DATA);
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_HIGH_REG);
OffsetHigh = IOReadB(VGA_CRTC_DATA);
Offset = MAKEWORD(OffsetLow, OffsetHigh);
*Row = (BYTE)(Offset / ScreenColumns);
*Column = (BYTE)(Offset % ScreenColumns);
}
static VOID VidBiosGetCursorPosition(PBYTE Row, PBYTE Column, BYTE Page)
{
/* Make sure the selected video page is valid */
@@ -1000,10 +966,11 @@ static BOOLEAN VidBiosSetVideoMode(BYTE ModeNumber)
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_START_ADDR_HIGH_REG);
IOWriteB(VGA_CRTC_DATA , HIBYTE(Bda->VideoPageOffset));
/* Get the character height */
/* Update the character height */
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_MAX_SCAN_LINE_REG);
Bda->CharacterHeight = 1 + (IOReadB(VGA_CRTC_DATA) & 0x1F);
/* Update the screen size */
Resolution = VgaGetDisplayResolution();
Bda->ScreenColumns = Resolution.X;
Bda->ScreenRows = Resolution.Y - 1;
@@ -1012,6 +979,9 @@ static BOOLEAN VidBiosSetVideoMode(BYTE ModeNumber)
for (Page = 0; Page < BIOS_MAX_PAGES; ++Page)
VidBiosSetCursorPosition(0, 0, Page);
/* Refresh display */
VgaRefreshDisplay();
return TRUE;
}
@@ -1533,8 +1503,10 @@ static VOID WINAPI VidBiosVideoService(LPWORD Stack)
/* PUBLIC FUNCTIONS ***********************************************************/
BOOLEAN VidBios32Initialize(HANDLE ConsoleOutput)
BOOLEAN VidBios32Initialize(VOID)
{
BYTE Row, Column;
/* Some interrupts are in fact addresses to tables */
((PULONG)BaseAddress)[0x1D] = (ULONG)NULL;
((PULONG)BaseAddress)[0x1F] = (ULONG)NULL;
@@ -1545,21 +1517,9 @@ BOOLEAN VidBios32Initialize(HANDLE ConsoleOutput)
/* Set the default video mode */
VidBiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE);
/* Set some screen properties if the console output handle is valid */
if (ConsoleOutput != INVALID_HANDLE_VALUE)
{
CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
GetConsoleScreenBufferInfo(ConsoleOutput, &ConsoleInfo);
/* Copy console data into VGA memory */
VidBiosCopyTextConsoleToVgaMemory(ConsoleOutput, &ConsoleInfo.dwSize);
/* Update the cursor position for the current page */
VidBiosSetCursorPosition(ConsoleInfo.dwCursorPosition.Y,
ConsoleInfo.dwCursorPosition.X,
Bda->VideoPage);
}
/* Update cursor position */
VgaGetCursorPosition(&Row, &Column);
VidBiosSetCursorPosition(Row, Column, Bda->VideoPage);
/* Register the BIOS 32-bit Interrupts */
RegisterBiosInt32(BIOS_VIDEO_INTERRUPT, VidBiosVideoService);
+1 -1
View File
@@ -36,7 +36,7 @@ enum
/* FUNCTIONS ******************************************************************/
BOOLEAN VidBios32Initialize(HANDLE BiosConsoleOutput);
BOOLEAN VidBios32Initialize(VOID);
VOID VidBios32Cleanup(VOID);
#endif // _VIDBIOS32_H_
+4 -3
View File
@@ -380,13 +380,14 @@ BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
/* Register the I/O Ports */
RegisterIoPort(CONTROL_SYSTEM_PORT61H, Port61hRead, Port61hWrite);
/* Initialize the PS2 port */
PS2Initialize(ConsoleInput);
/* Set the console input mode */
// FIXME: Activate ENABLE_WINDOW_INPUT when we will want to perform actions
// upon console window events (screen buffer resize, ...).
SetConsoleMode(ConsoleInput, ENABLE_PROCESSED_INPUT /* | ENABLE_WINDOW_INPUT */);
// SetConsoleMode(ConsoleOutput, ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
/* Initialize the PS2 port */
PS2Initialize(ConsoleInput);
/* Start the input thread */
InputThread = CreateThread(NULL, 0, &PumpConsoleInput, ConsoleInput, 0, NULL);
+74 -7
View File
@@ -402,12 +402,21 @@ __InvalidateConsoleDIBits(IN HANDLE hConsoleOutput,
/* PRIVATE FUNCTIONS **********************************************************/
static inline DWORD VgaGetAddressSize(VOID);
static BOOL VgaAttachToConsole(PCOORD Resolution)
{
BOOL Success = FALSE;
BOOL Success;
ULONG Length = 0;
PVIDEO_HARDWARE_STATE_HEADER State;
SHORT i, j;
DWORD AddressSize, ScanlineSize;
DWORD Address = 0;
DWORD CurrentAddr;
SMALL_RECT ScreenRect; // ConRect;
COORD Origin = { 0, 0 };
ASSERT(TextFramebuffer == NULL);
// ResetEvent(AnotherEvent);
@@ -442,9 +451,53 @@ static BOOL VgaAttachToConsole(PCOORD Resolution)
{
DisplayMessage(L"RegisterConsoleVDM failed with error %d\n", GetLastError());
VdmRunning = FALSE;
return FALSE;
}
return Success;
/* 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)
@@ -893,12 +946,14 @@ static BOOL VgaEnterTextMode(PCOORD Resolution)
{
SMALL_RECT ConRect;
DPRINT1("VgaEnterTextMode\n");
/* Switch to the text buffer */
SetConsoleActiveScreenBuffer(TextConsoleBuffer);
/* Resize the console */
ConRect.Left = 0; // ConsoleInfo.srWindow.Left;
ConRect.Top = ConsoleInfo.srWindow.Top;
ConRect.Top = ConsoleInfo.srWindow.Top; // ConsoleSize->Y - Resolution->Y;
ConRect.Right = ConRect.Left + Resolution->X - 1;
ConRect.Bottom = ConRect.Top + Resolution->Y - 1;
/*
@@ -919,6 +974,8 @@ static BOOL VgaEnterTextMode(PCOORD Resolution)
if (TextResolution.X != Resolution->X ||
TextResolution.Y != Resolution->Y)
{
WORD Offset;
VgaDetachFromConsole();
/* VgaAttachToConsole sets TextResolution to the new resolution */
@@ -928,6 +985,14 @@ static BOOL VgaEnterTextMode(PCOORD Resolution)
VdmRunning = FALSE;
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;
}
/* The active framebuffer is now the text framebuffer */
@@ -1217,8 +1282,8 @@ static VOID VgaUpdateFramebuffer(VOID)
CharInfo.Attributes = VgaMemory[CurrentAddr + VGA_BANK_SIZE];
/* Now check if the resulting character data has changed */
if ((CharBuffer[i * Resolution.X + j].Char != CharInfo.Char)
|| (CharBuffer[i * Resolution.X + j].Attributes != CharInfo.Attributes))
if ((CharBuffer[i * Resolution.X + j].Char != CharInfo.Char) ||
(CharBuffer[i * Resolution.X + j].Attributes != CharInfo.Attributes))
{
/* Yes, write the new value */
CharBuffer[i * Resolution.X + j] = CharInfo;
@@ -1265,8 +1330,10 @@ static VOID VgaUpdateTextCursor(VOID)
Location += (VgaCrtcRegisters[VGA_CRTC_CURSOR_END_REG] >> 5) & 3;
/* Find the coordinates of the new position */
Position.X = (WORD)(Location % ScanlineSize);
Position.Y = (WORD)(Location / ScanlineSize);
Position.X = (SHORT)(Location % ScanlineSize);
Position.Y = (SHORT)(Location / ScanlineSize);
DPRINT1("VgaUpdateTextCursor: X = %d ; Y = %d\n", Position.X, Position.Y);
/* Update the physical cursor */
SetConsoleCursorInfo(TextConsoleBuffer, &CursorInfo);
+11 -2
View File
@@ -151,7 +151,16 @@ static VOID ShowHideMousePointer(HANDLE ConOutHandle, BOOLEAN ShowPtr)
{
WCHAR szMenuString[255] = L"";
ShowConsoleCursor(ConOutHandle, ShowPtr);
if (ShowPtr)
{
/* Be sure the cursor will be shown */
while (ShowConsoleCursor(ConOutHandle, TRUE) < 0) ;
}
else
{
/* Be sure the cursor will be hidden */
while (ShowConsoleCursor(ConOutHandle, FALSE) >= 0) ;
}
if (LoadStringW(GetModuleHandle(NULL),
(!ShowPtr ? IDS_SHOW_MOUSE : IDS_HIDE_MOUSE),
@@ -400,7 +409,7 @@ INT wmain(INT argc, WCHAR *argv[])
}
/* Initialize the system BIOS */
if (!BiosInitialize(NULL, ConsoleOutput))
if (!BiosInitialize(NULL))
{
wprintf(L"FATAL: Failed to initialize the VDM BIOS.\n");
goto Cleanup;