- Implement Ctrl-C using interrupt 0x23.
- Fix INT 21h, AH = 0Ah to detect special characters.
- When attaching to / detaching from the console, adjust the console mode
  and attach/detach the UI.
- Do not translate scancodes to characters while ALT is held down.


svn path=/trunk/; revision=67002
This commit is contained in:
Aleksandar Andrejevic 2015-03-31 21:28:40 +00:00
parent 8c6b9e9841
commit d5976d2739
5 changed files with 119 additions and 70 deletions

View file

@ -245,12 +245,16 @@ static VOID WINAPI BiosKeyboardIrq(LPWORD Stack)
/* Set the highest bit */
BiosKeyboardMap[VirtualKey] |= (1 << 7);
/* Find out which character this is */
Character = 0;
if (ToAscii(VirtualKey, ScanCode, BiosKeyboardMap, &Character, 0) == 0)
/* If ALT isn't held down, find out which character this is */
if (!((BiosKeyboardMap[VK_MENU] | BiosKeyboardMap[VK_RMENU] | BiosKeyboardMap[VK_LMENU]) & (1 << 7)))
{
/* Not ASCII */
Character = 0;
if (ToAscii(VirtualKey, ScanCode, BiosKeyboardMap, &Character, 0) == 0)
{
/* Not ASCII */
Character = 0;
}
}
/* Push it onto the BIOS keyboard queue */

View file

@ -650,6 +650,22 @@ static BOOLEAN DosChangeDirectory(LPSTR Directory)
return TRUE;
}
static BOOLEAN DosControlBreak(VOID)
{
setCF(0);
/* Call interrupt 0x23 */
Int32Call(&DosContext, 0x23);
if (getCF())
{
DosTerminateProcess(CurrentPsp, 0, 0);
return TRUE;
}
return FALSE;
}
/* PUBLIC FUNCTIONS ***********************************************************/
PDOS_SFT_ENTRY DosGetSftEntry(WORD DosHandle)
@ -981,7 +997,8 @@ DWORD DosStartProcess(IN LPCSTR ExecutablePath,
if (Result != ERROR_SUCCESS) goto Quit;
/* Attach to the console */
VidBiosAttachToConsole(); // FIXME: And in fact, attach the full NTVDM UI to the console
ConsoleAttach();
VidBiosAttachToConsole();
// HACK: Simulate a ENTER key release scancode on the PS/2 port because
// some apps expect to read a key release scancode (> 0x80) when they
@ -994,7 +1011,8 @@ DWORD DosStartProcess(IN LPCSTR ExecutablePath,
CpuSimulate();
/* Detach from the console */
VidBiosDetachFromConsole(); // FIXME: And in fact, detach the full NTVDM UI from the console
VidBiosDetachFromConsole();
ConsoleDetach();
Quit:
return Result;
@ -1125,9 +1143,10 @@ VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode, WORD KeepResident)
LPDWORD IntVecTable = (LPDWORD)((ULONG_PTR)BaseAddress);
PDOS_PSP PspBlock = SEGMENT_TO_PSP(Psp);
DPRINT("DosTerminateProcess: Psp 0x%04X, ReturnCode 0x%02X\n",
DPRINT("DosTerminateProcess: Psp 0x%04X, ReturnCode 0x%02X, KeepResident 0x%04X\n",
Psp,
ReturnCode);
ReturnCode,
KeepResident);
/* Check if this PSP is it's own parent */
if (PspBlock->ParentPsp == Psp) goto Done;
@ -1464,16 +1483,12 @@ VOID WINAPI DosInt21h(LPWORD Stack)
{
DPRINT("Char input without echo\n");
// FIXME: Under DOS 2+, input handle may be redirected!!!!
Character = DosReadCharacter(DOS_INPUT_HANDLE);
// FIXME: For 0x07, do not check Ctrl-C/Break.
// For 0x08, do check those control sequences and if needed,
// call INT 0x23.
// /* Let the BOP repeat if needed */
// if (getCF()) break;
setAL(Character);
break;
}
@ -1508,18 +1523,55 @@ VOID WINAPI DosInt21h(LPWORD Stack)
while (Count < InputBuffer->MaxLength)
{
// FIXME!! This function should interpret backspaces etc...
/* Try to read a character (wait) */
Character = DosReadCharacter(DOS_INPUT_HANDLE);
// FIXME: Check whether Ctrl-C / Ctrl-Break is pressed, and call INT 23h if so.
switch (Character)
{
/* Extended character */
case '\0':
{
/* Read the scancode */
DosReadCharacter(DOS_INPUT_HANDLE);
break;
}
/* Echo the character and append it to the buffer */
DosPrintCharacter(DOS_OUTPUT_HANDLE, Character);
InputBuffer->Buffer[Count] = Character;
/* Ctrl-C */
case 0x03:
{
if (DosControlBreak()) return;
break;
}
Count++; /* Carriage returns are also counted */
/* Backspace */
case '\b':
{
if (Count > 0)
{
Count--;
/* Erase the character */
DosPrintCharacter(DOS_OUTPUT_HANDLE, '\b');
DosPrintCharacter(DOS_OUTPUT_HANDLE, ' ');
DosPrintCharacter(DOS_OUTPUT_HANDLE, '\b');
}
break;
}
default:
{
if (Character == 0x0A || Character == 0x0D
|| (Character >= 0x20 && Character <= 0x7F))
{
/* Echo the character and append it to the buffer */
DosPrintCharacter(DOS_OUTPUT_HANDLE, Character);
InputBuffer->Buffer[Count] = Character;
Count++; /* Carriage returns are also counted */
}
}
}
if (Character == '\r') break;
}
@ -2836,11 +2888,8 @@ VOID WINAPI DosInt21h(LPWORD Stack)
VOID WINAPI DosBreakInterrupt(LPWORD Stack)
{
UNREFERENCED_PARAMETER(Stack);
/* Stop the VDM task */
ResetEvent(VdmTaskEvent);
CpuUnsimulate();
/* Set CF to terminate the running process */
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
}
VOID WINAPI DosFastConOut(LPWORD Stack)

View file

@ -316,34 +316,6 @@ PumpConsoleInput(LPVOID Parameter)
return 0;
}
static VOID EnableExtraHardware(HANDLE ConsoleInput)
{
DWORD ConInMode;
if (GetConsoleMode(ConsoleInput, &ConInMode))
{
#if 0
// GetNumberOfConsoleMouseButtons();
// GetSystemMetrics(SM_CMOUSEBUTTONS);
// GetSystemMetrics(SM_MOUSEPRESENT);
if (MousePresent)
{
#endif
/* Support mouse input events if there is a mouse on the system */
ConInMode |= ENABLE_MOUSE_INPUT;
#if 0
}
else
{
/* Do not support mouse input events if there is no mouse on the system */
ConInMode &= ~ENABLE_MOUSE_INPUT;
}
#endif
SetConsoleMode(ConsoleInput, ConInMode);
}
}
/* PUBLIC FUNCTIONS ***********************************************************/
static VOID
@ -498,14 +470,6 @@ BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
/* Register the I/O Ports */
RegisterIoPort(CONTROL_SYSTEM_PORT61H, Port61hRead, Port61hWrite);
/* 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);
/**/EnableExtraHardware(ConsoleInput);/**/
/* Initialize the PS/2 port */
PS2Initialize();

View file

@ -176,6 +176,34 @@ static VOID ShowHideMousePointer(HANDLE ConOutHandle, BOOLEAN ShowPtr)
}
}
static VOID EnableExtraHardware(HANDLE ConsoleInput)
{
DWORD ConInMode;
if (GetConsoleMode(ConsoleInput, &ConInMode))
{
#if 0
// GetNumberOfConsoleMouseButtons();
// GetSystemMetrics(SM_CMOUSEBUTTONS);
// GetSystemMetrics(SM_MOUSEPRESENT);
if (MousePresent)
{
#endif
/* Support mouse input events if there is a mouse on the system */
ConInMode |= ENABLE_MOUSE_INPUT;
#if 0
}
else
{
/* Do not support mouse input events if there is no mouse on the system */
ConInMode &= ~ENABLE_MOUSE_INPUT;
}
#endif
SetConsoleMode(ConsoleInput, ConInMode);
}
}
/* PUBLIC FUNCTIONS ***********************************************************/
VOID
@ -232,14 +260,6 @@ ConsoleCtrlHandler(DWORD ControlType)
{
switch (ControlType)
{
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
{
/* HACK: Stop the VDM */
DPRINT1("Ctrl-C/Break: Stop the VDM\n");
EmulatorTerminate();
break;
}
case CTRL_LAST_CLOSE_EVENT:
{
if (WaitForSingleObject(VdmTaskEvent, 0) == WAIT_TIMEOUT)
@ -260,6 +280,7 @@ ConsoleCtrlHandler(DWORD ControlType)
break;
}
default:
{
/* Stop the VDM if the user logs out or closes the console */
@ -284,7 +305,7 @@ ConsoleCleanupUI(VOID)
DestroyVdmMenu();
}
static BOOL
BOOL
ConsoleAttach(VOID)
{
/* Save the original input and output console modes */
@ -297,13 +318,22 @@ ConsoleAttach(VOID)
// return FALSE;
}
/* 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, 0 /* | ENABLE_WINDOW_INPUT */);
EnableExtraHardware(ConsoleInput);
/* Set the console output mode */
// SetConsoleMode(ConsoleOutput, ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
/* Initialize the UI */
ConsoleInitUI();
return TRUE;
}
static VOID
VOID
ConsoleDetach(VOID)
{
/* Restore the original input and output console modes */

View file

@ -68,6 +68,8 @@ CreateVdmMenu(HANDLE ConOutHandle);
/*static*/ VOID
DestroyVdmMenu(VOID);
BOOL ConsoleAttach(VOID);
VOID ConsoleDetach(VOID);
VOID MenuEventHandler(PMENU_EVENT_RECORD MenuEvent);
VOID FocusEventHandler(PFOCUS_EVENT_RECORD FocusEvent);