Author: aandrejevic
Date: Wed Jul 3 23:38:51 2013
New Revision: 59421
URL:
http://svn.reactos.org/svn/reactos?rev=59421&view=rev
Log:
[NTVDM]
Fix bugs in video memory access emulation.
Implement several missing INT 10h functions.
Resize the console screen buffer on startup.
Modified:
branches/ntvdm/subsystems/ntvdm/bios.c
branches/ntvdm/subsystems/ntvdm/bios.h
branches/ntvdm/subsystems/ntvdm/dos.c
branches/ntvdm/subsystems/ntvdm/emulator.c
branches/ntvdm/subsystems/ntvdm/emulator.h
Modified: branches/ntvdm/subsystems/ntvdm/bios.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios.c?r…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] Wed Jul 3 23:38:51 2013
@@ -16,8 +16,6 @@
/* PRIVATE VARIABLES **********************************************************/
-static BYTE CursorRow, CursorCol;
-static WORD ConsoleWidth, ConsoleHeight;
static BYTE BiosKeyboardMap[256];
static WORD BiosKbdBuffer[BIOS_KBD_BUFFER_SIZE];
static UINT BiosKbdBufferStart = 0, BiosKbdBufferEnd = 0;
@@ -30,17 +28,9 @@
static COORD BiosVideoAddressToCoord(ULONG Address)
{
COORD Result = {0, 0};
- CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
- HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
-
- if (!GetConsoleScreenBufferInfo(ConsoleOutput, &ConsoleInfo))
- {
- 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;
+
+ Result.X = ((Address - CONSOLE_VIDEO_MEM_START) >> 1) % CONSOLE_WIDTH;
+ Result.Y = ((Address - CONSOLE_VIDEO_MEM_START) >> 1) / CONSOLE_WIDTH;
return Result;
}
@@ -92,9 +82,9 @@
{
INT i;
WORD Offset = 0;
+ COORD Size = { CONSOLE_WIDTH, CONSOLE_HEIGHT};
HANDLE ConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
- CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
LPWORD IntVecTable = (LPWORD)((ULONG_PTR)BaseAddress);
LPBYTE BiosCode = (LPBYTE)((ULONG_PTR)BaseAddress + TO_LINEAR(BIOS_SEGMENT, 0));
@@ -122,17 +112,8 @@
BiosCode[Offset++] = 0xCF; // iret
}
- /* Get the console buffer info */
- if (!GetConsoleScreenBufferInfo(ConsoleOutput, &ConsoleInfo))
- {
- 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 buffer size */
+ if (!SetConsoleScreenBufferSize(ConsoleOutput, Size)) return FALSE;
/* Set the console input mode */
SetConsoleMode(ConsoleInput, ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT);
@@ -168,34 +149,31 @@
{
ULONG i;
COORD Coordinates;
- DWORD CharsWritten;
+ COORD Origin = { 0, 0 };
+ COORD UnitSize = { 1, 1 };
+ CHAR_INFO Character;
+ SMALL_RECT Rect;
HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ /* Start from the character address */
+ StartAddress &= ~1;
+
/* Loop through all the addresses */
- for (i = StartAddress; i < EndAddress; i++)
+ for (i = StartAddress; i < EndAddress; i += 2)
{
/* Get the coordinates */
Coordinates = BiosVideoAddressToCoord(i);
- /* Check if this is a character byte or an attribute byte */
- if ((i - CONSOLE_VIDEO_MEM_START) % 2 == 0)
- {
- /* This is a regular character */
- FillConsoleOutputCharacterA(ConsoleOutput,
- *(PCHAR)((ULONG_PTR)BaseAddress + i),
- sizeof(CHAR),
- Coordinates,
- &CharsWritten);
- }
- else
- {
- /* This is an attribute */
- FillConsoleOutputAttribute(ConsoleOutput,
- *(PCHAR)((ULONG_PTR)BaseAddress + i),
- sizeof(CHAR),
- Coordinates,
- &CharsWritten);
- }
+ /* Fill the rectangle structure */
+ Rect.Left = Coordinates.X;
+ Rect.Top = Coordinates.Y;
+
+ /* Fill the character data */
+ Character.Char.AsciiChar = *((PCHAR)((ULONG_PTR)BaseAddress + i));
+ Character.Attributes = *((PBYTE)((ULONG_PTR)BaseAddress + i + 1));
+
+ /* Write the character */
+ WriteConsoleOutputA(ConsoleOutput, &Character, UnitSize, Origin, &Rect);
}
}
@@ -294,6 +272,7 @@
BOOLEAN Invisible = FALSE;
COORD Position;
CONSOLE_CURSOR_INFO CursorInfo;
+ CONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo;
CHAR_INFO Character;
SMALL_RECT Rect;
DWORD Eax = EmulatorGetRegister(EMULATOR_REG_AX);
@@ -327,6 +306,27 @@
Position.Y = HIBYTE(Edx);
SetConsoleCursorPosition(ConsoleOutput, Position);
+ 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;
}
@@ -355,18 +355,75 @@
/* Read Character And Attribute At Cursor Position */
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;
}
/* Write Character And Attribute At Cursor Position */
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;
}
/* Write Character Only At Cursor Position */
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;
}
Modified: branches/ntvdm/subsystems/ntvdm/bios.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios.h?r…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/bios.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/bios.h [iso-8859-1] Wed Jul 3 23:38:51 2013
@@ -26,6 +26,8 @@
#define BIOS_EQUIPMENT_INTERRUPT 0x11
#define BIOS_KBD_INTERRUPT 0x16
#define BIOS_TIME_INTERRUPT 0x1A
+#define CONSOLE_WIDTH 80
+#define CONSOLE_HEIGHT 25
#define CONSOLE_FONT_HEIGHT 8
#define BIOS_KBD_BUFFER_SIZE 256
#define BIOS_EQUIPMENT_LIST 0x3C // HACK: Disable FPU for now
Modified: branches/ntvdm/subsystems/ntvdm/dos.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos.c?re…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/dos.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/dos.c [iso-8859-1] Wed Jul 3 23:38:51 2013
@@ -943,6 +943,7 @@
}
/* Read Character Without Echo */
+ case 0x07:
case 0x08:
{
EmulatorSetRegister(EMULATOR_REG_AX,
Modified: branches/ntvdm/subsystems/ntvdm/emulator.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/emulator…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/emulator.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/emulator.c [iso-8859-1] Wed Jul 3 23:38:51 2013
@@ -36,8 +36,8 @@
&& (Address < CONSOLE_VIDEO_MEM_END))
{
/* Call the VDM BIOS to update the video memory */
- BiosUpdateConsole(max(Address, CONSOLE_VIDEO_MEM_START),
- min(Address + Size, CONSOLE_VIDEO_MEM_END));
+ BiosUpdateVideoMemory(max(Address, CONSOLE_VIDEO_MEM_START),
+ min(Address + Size, CONSOLE_VIDEO_MEM_END));
}
/* Read the data from the virtual address space and store it in the buffer */
Modified: branches/ntvdm/subsystems/ntvdm/emulator.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/emulator…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/emulator.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/emulator.h [iso-8859-1] Wed Jul 3 23:38:51 2013
@@ -47,7 +47,7 @@
EMULATOR_EXCEPTION_NO_FPU
};
-typedef enum
+enum
{
EMULATOR_REG_AX,
EMULATOR_REG_CX,
@@ -61,7 +61,7 @@
EMULATOR_REG_CS,
EMULATOR_REG_SS,
EMULATOR_REG_DS,
-} EMULATOR_REGISTER;
+};
/* FUNCTIONS ******************************************************************/