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?re... ============================================================================== --- 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?re... ============================================================================== --- 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?rev... ============================================================================== --- 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 ******************************************************************/