mirror of
https://github.com/reactos/reactos.git
synced 2024-10-20 16:06:27 +00:00
[NTVDM]
Fix bugs in video memory access emulation. Implement several missing INT 10h functions. Resize the console screen buffer on startup. svn path=/branches/ntvdm/; revision=59421
This commit is contained in:
parent
c4ef9b6f44
commit
988c4490a8
|
@ -16,8 +16,6 @@
|
||||||
|
|
||||||
/* PRIVATE VARIABLES **********************************************************/
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
|
|
||||||
static BYTE CursorRow, CursorCol;
|
|
||||||
static WORD ConsoleWidth, ConsoleHeight;
|
|
||||||
static BYTE BiosKeyboardMap[256];
|
static BYTE BiosKeyboardMap[256];
|
||||||
static WORD BiosKbdBuffer[BIOS_KBD_BUFFER_SIZE];
|
static WORD BiosKbdBuffer[BIOS_KBD_BUFFER_SIZE];
|
||||||
static UINT BiosKbdBufferStart = 0, BiosKbdBufferEnd = 0;
|
static UINT BiosKbdBufferStart = 0, BiosKbdBufferEnd = 0;
|
||||||
|
@ -30,17 +28,9 @@ static BOOLEAN BiosPassedMidnight = FALSE;
|
||||||
static COORD BiosVideoAddressToCoord(ULONG Address)
|
static COORD BiosVideoAddressToCoord(ULONG Address)
|
||||||
{
|
{
|
||||||
COORD Result = {0, 0};
|
COORD Result = {0, 0};
|
||||||
CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
|
|
||||||
HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
|
|
||||||
if (!GetConsoleScreenBufferInfo(ConsoleOutput, &ConsoleInfo))
|
Result.X = ((Address - CONSOLE_VIDEO_MEM_START) >> 1) % CONSOLE_WIDTH;
|
||||||
{
|
Result.Y = ((Address - CONSOLE_VIDEO_MEM_START) >> 1) / CONSOLE_WIDTH;
|
||||||
ASSERT(FALSE);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result.X = ((Address - CONSOLE_VIDEO_MEM_START) >> 1) % ConsoleInfo.dwSize.X;
|
|
||||||
Result.Y = ((Address - CONSOLE_VIDEO_MEM_START) >> 1) / ConsoleInfo.dwSize.X;
|
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -92,9 +82,9 @@ BOOLEAN BiosInitialize()
|
||||||
{
|
{
|
||||||
INT i;
|
INT i;
|
||||||
WORD Offset = 0;
|
WORD Offset = 0;
|
||||||
|
COORD Size = { CONSOLE_WIDTH, CONSOLE_HEIGHT};
|
||||||
HANDLE ConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
|
HANDLE ConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
|
|
||||||
LPWORD IntVecTable = (LPWORD)((ULONG_PTR)BaseAddress);
|
LPWORD IntVecTable = (LPWORD)((ULONG_PTR)BaseAddress);
|
||||||
LPBYTE BiosCode = (LPBYTE)((ULONG_PTR)BaseAddress + TO_LINEAR(BIOS_SEGMENT, 0));
|
LPBYTE BiosCode = (LPBYTE)((ULONG_PTR)BaseAddress + TO_LINEAR(BIOS_SEGMENT, 0));
|
||||||
|
|
||||||
|
@ -122,17 +112,8 @@ BOOLEAN BiosInitialize()
|
||||||
BiosCode[Offset++] = 0xCF; // iret
|
BiosCode[Offset++] = 0xCF; // iret
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the console buffer info */
|
/* Set the console buffer size */
|
||||||
if (!GetConsoleScreenBufferInfo(ConsoleOutput, &ConsoleInfo))
|
if (!SetConsoleScreenBufferSize(ConsoleOutput, Size)) return FALSE;
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the initial cursor position and console size */
|
|
||||||
CursorCol = ConsoleInfo.dwCursorPosition.X;
|
|
||||||
CursorRow = ConsoleInfo.dwCursorPosition.Y;
|
|
||||||
ConsoleWidth = ConsoleInfo.dwSize.X;
|
|
||||||
ConsoleHeight = ConsoleInfo.dwSize.Y;
|
|
||||||
|
|
||||||
/* Set the console input mode */
|
/* Set the console input mode */
|
||||||
SetConsoleMode(ConsoleInput, ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT);
|
SetConsoleMode(ConsoleInput, ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT);
|
||||||
|
@ -168,34 +149,31 @@ VOID BiosUpdateConsole(ULONG StartAddress, ULONG EndAddress)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
COORD Coordinates;
|
COORD Coordinates;
|
||||||
DWORD CharsWritten;
|
COORD Origin = { 0, 0 };
|
||||||
|
COORD UnitSize = { 1, 1 };
|
||||||
|
CHAR_INFO Character;
|
||||||
|
SMALL_RECT Rect;
|
||||||
HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
/* Start from the character address */
|
||||||
|
StartAddress &= ~1;
|
||||||
|
|
||||||
/* Loop through all the addresses */
|
/* Loop through all the addresses */
|
||||||
for (i = StartAddress; i < EndAddress; i++)
|
for (i = StartAddress; i < EndAddress; i += 2)
|
||||||
{
|
{
|
||||||
/* Get the coordinates */
|
/* Get the coordinates */
|
||||||
Coordinates = BiosVideoAddressToCoord(i);
|
Coordinates = BiosVideoAddressToCoord(i);
|
||||||
|
|
||||||
/* Check if this is a character byte or an attribute byte */
|
/* Fill the rectangle structure */
|
||||||
if ((i - CONSOLE_VIDEO_MEM_START) % 2 == 0)
|
Rect.Left = Coordinates.X;
|
||||||
{
|
Rect.Top = Coordinates.Y;
|
||||||
/* This is a regular character */
|
|
||||||
FillConsoleOutputCharacterA(ConsoleOutput,
|
/* Fill the character data */
|
||||||
*(PCHAR)((ULONG_PTR)BaseAddress + i),
|
Character.Char.AsciiChar = *((PCHAR)((ULONG_PTR)BaseAddress + i));
|
||||||
sizeof(CHAR),
|
Character.Attributes = *((PBYTE)((ULONG_PTR)BaseAddress + i + 1));
|
||||||
Coordinates,
|
|
||||||
&CharsWritten);
|
/* Write the character */
|
||||||
}
|
WriteConsoleOutputA(ConsoleOutput, &Character, UnitSize, Origin, &Rect);
|
||||||
else
|
|
||||||
{
|
|
||||||
/* This is an attribute */
|
|
||||||
FillConsoleOutputAttribute(ConsoleOutput,
|
|
||||||
*(PCHAR)((ULONG_PTR)BaseAddress + i),
|
|
||||||
sizeof(CHAR),
|
|
||||||
Coordinates,
|
|
||||||
&CharsWritten);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,6 +272,7 @@ VOID BiosVideoService()
|
||||||
BOOLEAN Invisible = FALSE;
|
BOOLEAN Invisible = FALSE;
|
||||||
COORD Position;
|
COORD Position;
|
||||||
CONSOLE_CURSOR_INFO CursorInfo;
|
CONSOLE_CURSOR_INFO CursorInfo;
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo;
|
||||||
CHAR_INFO Character;
|
CHAR_INFO Character;
|
||||||
SMALL_RECT Rect;
|
SMALL_RECT Rect;
|
||||||
DWORD Eax = EmulatorGetRegister(EMULATOR_REG_AX);
|
DWORD Eax = EmulatorGetRegister(EMULATOR_REG_AX);
|
||||||
|
@ -330,6 +309,27 @@ VOID BiosVideoService()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get Cursor Position */
|
||||||
|
case 0x03:
|
||||||
|
{
|
||||||
|
INT StartLine;
|
||||||
|
|
||||||
|
/* Retrieve the data */
|
||||||
|
GetConsoleCursorInfo(ConsoleOutput, &CursorInfo);
|
||||||
|
GetConsoleScreenBufferInfo(ConsoleOutput, &ScreenBufferInfo);
|
||||||
|
|
||||||
|
/* Find the first line */
|
||||||
|
StartLine = 32 - ((CursorInfo.dwSize * 32) / 100);
|
||||||
|
|
||||||
|
/* Return the result */
|
||||||
|
EmulatorSetRegister(EMULATOR_REG_AX, 0);
|
||||||
|
EmulatorSetRegister(EMULATOR_REG_CX, (StartLine << 8) | 0x1F);
|
||||||
|
EmulatorSetRegister(EMULATOR_REG_DX,
|
||||||
|
LOWORD(ScreenBufferInfo.dwCursorPosition.Y) << 8
|
||||||
|
|| LOWORD(ScreenBufferInfo.dwCursorPosition.X));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Scroll Up/Down Window */
|
/* Scroll Up/Down Window */
|
||||||
case 0x06:
|
case 0x06:
|
||||||
case 0x07:
|
case 0x07:
|
||||||
|
@ -355,18 +355,75 @@ VOID BiosVideoService()
|
||||||
/* Read Character And Attribute At Cursor Position */
|
/* Read Character And Attribute At Cursor Position */
|
||||||
case 0x08:
|
case 0x08:
|
||||||
{
|
{
|
||||||
|
COORD BufferSize = { 1, 1 }, Origin = { 0, 0 };
|
||||||
|
|
||||||
|
/* Get the cursor position */
|
||||||
|
GetConsoleScreenBufferInfo(ConsoleOutput, &ScreenBufferInfo);
|
||||||
|
|
||||||
|
/* Read at cursor position */
|
||||||
|
Rect.Left = ScreenBufferInfo.dwCursorPosition.X;
|
||||||
|
Rect.Top = ScreenBufferInfo.dwCursorPosition.Y;
|
||||||
|
|
||||||
|
/* Read the console output */
|
||||||
|
ReadConsoleOutput(ConsoleOutput, &Character, BufferSize, Origin, &Rect);
|
||||||
|
|
||||||
|
/* Return the result */
|
||||||
|
EmulatorSetRegister(EMULATOR_REG_AX,
|
||||||
|
(LOBYTE(Character.Attributes) << 8)
|
||||||
|
| Character.Char.AsciiChar);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write Character And Attribute At Cursor Position */
|
/* Write Character And Attribute At Cursor Position */
|
||||||
case 0x09:
|
case 0x09:
|
||||||
{
|
{
|
||||||
|
DWORD CharsWritten;
|
||||||
|
|
||||||
|
/* Get the cursor position */
|
||||||
|
GetConsoleScreenBufferInfo(ConsoleOutput, &ScreenBufferInfo);
|
||||||
|
|
||||||
|
/* Write the attribute to the output */
|
||||||
|
FillConsoleOutputAttribute(ConsoleOutput,
|
||||||
|
LOBYTE(Ebx),
|
||||||
|
LOWORD(Ecx),
|
||||||
|
ScreenBufferInfo.dwCursorPosition,
|
||||||
|
&CharsWritten);
|
||||||
|
|
||||||
|
/* Write the character to the output */
|
||||||
|
FillConsoleOutputCharacterA(ConsoleOutput,
|
||||||
|
LOBYTE(Eax),
|
||||||
|
LOWORD(Ecx),
|
||||||
|
ScreenBufferInfo.dwCursorPosition,
|
||||||
|
&CharsWritten);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write Character Only At Cursor Position */
|
/* Write Character Only At Cursor Position */
|
||||||
case 0x0A:
|
case 0x0A:
|
||||||
{
|
{
|
||||||
|
DWORD CharsWritten;
|
||||||
|
|
||||||
|
/* Get the cursor position */
|
||||||
|
GetConsoleScreenBufferInfo(ConsoleOutput, &ScreenBufferInfo);
|
||||||
|
|
||||||
|
/* Write the character to the output */
|
||||||
|
FillConsoleOutputCharacterA(ConsoleOutput,
|
||||||
|
LOBYTE(Eax),
|
||||||
|
LOWORD(Ecx),
|
||||||
|
ScreenBufferInfo.dwCursorPosition,
|
||||||
|
&CharsWritten);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x0F:
|
||||||
|
{
|
||||||
|
/* Return just text mode information, for now */
|
||||||
|
EmulatorSetRegister(EMULATOR_REG_AX, 0x5003);
|
||||||
|
EmulatorSetRegister(EMULATOR_REG_BX, 0x0000);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#define BIOS_EQUIPMENT_INTERRUPT 0x11
|
#define BIOS_EQUIPMENT_INTERRUPT 0x11
|
||||||
#define BIOS_KBD_INTERRUPT 0x16
|
#define BIOS_KBD_INTERRUPT 0x16
|
||||||
#define BIOS_TIME_INTERRUPT 0x1A
|
#define BIOS_TIME_INTERRUPT 0x1A
|
||||||
|
#define CONSOLE_WIDTH 80
|
||||||
|
#define CONSOLE_HEIGHT 25
|
||||||
#define CONSOLE_FONT_HEIGHT 8
|
#define CONSOLE_FONT_HEIGHT 8
|
||||||
#define BIOS_KBD_BUFFER_SIZE 256
|
#define BIOS_KBD_BUFFER_SIZE 256
|
||||||
#define BIOS_EQUIPMENT_LIST 0x3C // HACK: Disable FPU for now
|
#define BIOS_EQUIPMENT_LIST 0x3C // HACK: Disable FPU for now
|
||||||
|
|
|
@ -943,6 +943,7 @@ VOID DosInt21h(WORD CodeSegment)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read Character Without Echo */
|
/* Read Character Without Echo */
|
||||||
|
case 0x07:
|
||||||
case 0x08:
|
case 0x08:
|
||||||
{
|
{
|
||||||
EmulatorSetRegister(EMULATOR_REG_AX,
|
EmulatorSetRegister(EMULATOR_REG_AX,
|
||||||
|
|
|
@ -36,7 +36,7 @@ static VOID EmulatorReadMemory(PVOID Context, UINT Address, LPBYTE Buffer, INT S
|
||||||
&& (Address < CONSOLE_VIDEO_MEM_END))
|
&& (Address < CONSOLE_VIDEO_MEM_END))
|
||||||
{
|
{
|
||||||
/* Call the VDM BIOS to update the video memory */
|
/* Call the VDM BIOS to update the video memory */
|
||||||
BiosUpdateConsole(max(Address, CONSOLE_VIDEO_MEM_START),
|
BiosUpdateVideoMemory(max(Address, CONSOLE_VIDEO_MEM_START),
|
||||||
min(Address + Size, CONSOLE_VIDEO_MEM_END));
|
min(Address + Size, CONSOLE_VIDEO_MEM_END));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ enum
|
||||||
EMULATOR_EXCEPTION_NO_FPU
|
EMULATOR_EXCEPTION_NO_FPU
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum
|
enum
|
||||||
{
|
{
|
||||||
EMULATOR_REG_AX,
|
EMULATOR_REG_AX,
|
||||||
EMULATOR_REG_CX,
|
EMULATOR_REG_CX,
|
||||||
|
@ -61,7 +61,7 @@ typedef enum
|
||||||
EMULATOR_REG_CS,
|
EMULATOR_REG_CS,
|
||||||
EMULATOR_REG_SS,
|
EMULATOR_REG_SS,
|
||||||
EMULATOR_REG_DS,
|
EMULATOR_REG_DS,
|
||||||
} EMULATOR_REGISTER;
|
};
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue