Author: hbelusca Date: Sun Mar 2 01:45:57 2014 New Revision: 62373
URL: http://svn.reactos.org/svn/reactos?rev=62373&view=rev Log: [NTVDM] - 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).
Modified: branches/ntvdm/subsystems/ntvdm/bios/bios.c branches/ntvdm/subsystems/ntvdm/bios/bios.h branches/ntvdm/subsystems/ntvdm/bios/bios32/bios32.c branches/ntvdm/subsystems/ntvdm/bios/bios32/bios32.h branches/ntvdm/subsystems/ntvdm/bios/bios32/vidbios32.c branches/ntvdm/subsystems/ntvdm/bios/bios32/vidbios32.h branches/ntvdm/subsystems/ntvdm/emulator.c branches/ntvdm/subsystems/ntvdm/hardware/vga.c branches/ntvdm/subsystems/ntvdm/ntvdm.c
Modified: branches/ntvdm/subsystems/ntvdm/bios/bios.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios/bios... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/bios/bios.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/bios/bios.c [iso-8859-1] Sun Mar 2 01:45:57 2014 @@ -86,8 +86,7 @@ /* 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 @@ } else { - Bios32Loaded = Bios32Initialize(ConsoleOutput); + Bios32Loaded = Bios32Initialize(); return Bios32Loaded; } }
Modified: branches/ntvdm/subsystems/ntvdm/bios/bios.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios/bios... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/bios/bios.h [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/bios/bios.h [iso-8859-1] Sun Mar 2 01:45:57 2014 @@ -106,8 +106,7 @@ extern PBIOS_DATA_AREA Bda;
BOOLEAN -BiosInitialize(IN LPCSTR BiosFileName, - IN HANDLE ConsoleOutput); +BiosInitialize(IN LPCSTR BiosFileName);
VOID BiosCleanup(VOID);
Modified: branches/ntvdm/subsystems/ntvdm/bios/bios32/bios32.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios/bios... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/bios/bios32/bios32.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/bios/bios32/bios32.c [iso-8859-1] Sun Mar 2 01:45:57 2014 @@ -361,7 +361,7 @@ /* * The BIOS POST (Power On-Self Test) */ -BOOLEAN Bios32Initialize(IN HANDLE ConsoleOutput) +BOOLEAN Bios32Initialize(VOID) { BOOLEAN Success; UCHAR Low, High; @@ -403,7 +403,7 @@ if (!KbdBios32Initialize()) return FALSE;
/* Initialize the Video BIOS */ - if (!VidBios32Initialize(ConsoleOutput)) return FALSE; + if (!VidBios32Initialize()) return FALSE;
/* Enable interrupts */ setIF(1);
Modified: branches/ntvdm/subsystems/ntvdm/bios/bios32/bios32.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios/bios... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/bios/bios32/bios32.h [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/bios/bios32/bios32.h [iso-8859-1] Sun Mar 2 01:45:57 2014 @@ -129,7 +129,7 @@ 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_
Modified: branches/ntvdm/subsystems/ntvdm/bios/bios32/vidbios32.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios/bios... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/bios/bios32/vidbios32.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/bios/bios32/vidbios32.c [iso-8859-1] Sun Mar 2 01:45:57 2014 @@ -733,58 +733,6 @@ 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 @@ 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 @@ 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; @@ -1011,6 +978,9 @@ /* Set the cursor position for each page */ for (Page = 0; Page < BIOS_MAX_PAGES; ++Page) VidBiosSetCursorPosition(0, 0, Page); + + /* Refresh display */ + VgaRefreshDisplay();
return TRUE; } @@ -1533,8 +1503,10 @@
/* 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 @@ /* 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);
Modified: branches/ntvdm/subsystems/ntvdm/bios/bios32/vidbios32.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios/bios... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/bios/bios32/vidbios32.h [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/bios/bios32/vidbios32.h [iso-8859-1] Sun Mar 2 01:45:57 2014 @@ -36,7 +36,7 @@
/* FUNCTIONS ******************************************************************/
-BOOLEAN VidBios32Initialize(HANDLE BiosConsoleOutput); +BOOLEAN VidBios32Initialize(VOID); VOID VidBios32Cleanup(VOID);
#endif // _VIDBIOS32_H_
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] Sun Mar 2 01:45:57 2014 @@ -380,13 +380,14 @@ /* 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);
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] Sun Mar 2 01:45:57 2014 @@ -402,11 +402,20 @@
/* 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);
@@ -442,9 +451,53 @@ { DisplayMessage(L"RegisterConsoleVDM failed with error %d\n", GetLastError()); VdmRunning = FALSE; - } - - return Success; + 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) @@ -893,12 +946,14 @@ { 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 @@ if (TextResolution.X != Resolution->X || TextResolution.Y != Resolution->Y) { + WORD Offset; + VgaDetachFromConsole();
/* VgaAttachToConsole sets TextResolution to the new resolution */ @@ -928,6 +985,14 @@ 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 @@ 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 @@ 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);
Modified: branches/ntvdm/subsystems/ntvdm/ntvdm.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ntvdm.c?r... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/ntvdm.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/ntvdm.c [iso-8859-1] Sun Mar 2 01:45:57 2014 @@ -151,7 +151,16 @@ { 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 @@ }
/* Initialize the system BIOS */ - if (!BiosInitialize(NULL, ConsoleOutput)) + if (!BiosInitialize(NULL)) { wprintf(L"FATAL: Failed to initialize the VDM BIOS.\n"); goto Cleanup;