Author: aandrejevic Date: Thu Oct 24 01:01:49 2013 New Revision: 60739
URL: http://svn.reactos.org/svn/reactos?rev=60739&view=rev Log: [NTVDM] Remove the code that performs waiting in 32-bit mode since that blocks the emulator and prevents interrupts from working. Implement a 16-bit waiting system in the interrupt handlers. Fix the PS/2 interrupt code.
Modified: branches/ntvdm/subsystems/ntvdm/bios.c branches/ntvdm/subsystems/ntvdm/dos.c branches/ntvdm/subsystems/ntvdm/emulator.c branches/ntvdm/subsystems/ntvdm/emulator.h branches/ntvdm/subsystems/ntvdm/ps2.c
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] Thu Oct 24 01:01:49 2013 @@ -267,14 +267,14 @@
static BOOLEAN BiosKbdBufferPush(WORD Data) { - /* Get the location of the element after the head */ - WORD NextElement = Bda->KeybdBufferHead + 2; + /* Get the location of the element after the tail */ + WORD NextElement = Bda->KeybdBufferTail + 2;
/* Wrap it around if it's at or beyond the end */ if (NextElement >= Bda->KeybdBufferEnd) NextElement = Bda->KeybdBufferStart;
/* If it's full, fail */ - if (NextElement == Bda->KeybdBufferTail) return FALSE; + if (NextElement == Bda->KeybdBufferHead) return FALSE;
/* Put the value in the queue */ *((LPWORD)((ULONG_PTR)Bda + Bda->KeybdBufferTail)) = Data; @@ -468,18 +468,33 @@ IntVecTable[i * 2] = Offset; IntVecTable[i * 2 + 1] = BIOS_SEGMENT;
- BiosCode[Offset++] = 0xFA; // cli + BiosCode[Offset++] = 0xFB; // sti
BiosCode[Offset++] = 0x6A; // push i BiosCode[Offset++] = (BYTE)i; + + BiosCode[Offset++] = 0x6A; // push 0 + BiosCode[Offset++] = 0x00; + + BiosCode[Offset++] = 0xF8; // clc
BiosCode[Offset++] = LOBYTE(EMULATOR_BOP); // BOP sequence BiosCode[Offset++] = HIBYTE(EMULATOR_BOP); BiosCode[Offset++] = LOBYTE(EMULATOR_INT_BOP); BiosCode[Offset++] = HIBYTE(EMULATOR_INT_BOP);
- BiosCode[Offset++] = 0x44; // inc sp - BiosCode[Offset++] = 0x44; // inc sp + BiosCode[Offset++] = 0x73; // jnc +3 + BiosCode[Offset++] = 0x03; + + // HACK: The following instruction should be HLT! + BiosCode[Offset++] = 0x90; // nop + + BiosCode[Offset++] = 0xEB; // jmp -10 + BiosCode[Offset++] = 0xF6; + + BiosCode[Offset++] = 0x83; // add sp, 4 + BiosCode[Offset++] = 0xC4; + BiosCode[Offset++] = 0x04;
BiosCode[Offset++] = 0xCF; // iret } @@ -590,9 +605,7 @@
WORD BiosGetCharacter(VOID) { - WORD CharacterData; - INPUT_RECORD InputRecord; - DWORD Count; + WORD CharacterData = 0;
/* Check if there is a key available */ if (Bda->KeybdBufferHead != Bda->KeybdBufferTail) @@ -603,24 +616,8 @@ } else { - VgaRefreshDisplay(); // HACK: Waiting here blocks the emulator!!! - - while (TRUE) - { - /* Wait for a console event */ - WaitForSingleObject(BiosConsoleInput, INFINITE); - - /* Read the event, and make sure it's a keypress */ - if (!ReadConsoleInput(BiosConsoleInput, &InputRecord, 1, &Count)) continue; - if (InputRecord.EventType != KEY_EVENT) continue; - if (!InputRecord.Event.KeyEvent.bKeyDown) continue; - - /* Save the scan code and end the loop */ - CharacterData = (InputRecord.Event.KeyEvent.wVirtualScanCode << 8) - | InputRecord.Event.KeyEvent.uChar.AsciiChar; - - break; - } + /* Set the handler CF to repeat the BOP */ + EmulatorSetFlag(EMULATOR_FLAG_CF); }
return CharacterData;
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] Thu Oct 24 01:01:49 2013 @@ -684,30 +684,17 @@ WORD Result = ERROR_SUCCESS; DWORD BytesRead32 = 0; HANDLE Handle = DosGetRealHandle(FileHandle); - WORD i;
DPRINT("DosReadFile: FileHandle 0x%04X, Count 0x%04X\n", FileHandle, Count);
/* Make sure the handle is valid */ if (Handle == INVALID_HANDLE_VALUE) return ERROR_INVALID_HANDLE;
- if (IsConsoleHandle(Handle)) - { - for (i = 0; i < Count; i++) - { - /* Call the BIOS function to read the character */ - ((LPBYTE)Buffer)[i] = LOBYTE(BiosGetCharacter()); - BytesRead32++; - } - } - else - { - /* Read the file */ - if (!ReadFile(Handle, Buffer, Count, &BytesRead32, NULL)) - { - /* Store the error code */ - Result = (WORD)GetLastError(); - } + /* Read the file */ + if (!ReadFile(Handle, Buffer, Count, &BytesRead32, NULL)) + { + /* Store the error code */ + Result = (WORD)GetLastError(); }
/* The number of bytes read is always 16-bit */ @@ -1283,8 +1270,16 @@ CHAR Character = '\0'; WORD BytesRead;
- /* Use the file reading function */ - DosReadFile(DOS_INPUT_HANDLE, &Character, sizeof(CHAR), &BytesRead); + if (IsConsoleHandle(DosGetRealHandle(DOS_INPUT_HANDLE))) + { + /* Call the BIOS */ + Character = LOBYTE(BiosGetCharacter()); + } + else + { + /* Use the file reading function */ + DosReadFile(DOS_INPUT_HANDLE, &Character, sizeof(CHAR), &BytesRead); + }
return Character; } @@ -1381,7 +1376,12 @@ { Character = DosReadCharacter(); DosPrintCharacter(Character); - EmulatorSetRegister(EMULATOR_REG_AX, (Eax & 0xFFFFFF00) | Character); + + if (!EmulatorGetFlag(EMULATOR_FLAG_CF)) + { + EmulatorSetRegister(EMULATOR_REG_AX, (Eax & 0xFFFFFF00) | Character); + } + break; }
@@ -1396,8 +1396,13 @@ case 0x07: case 0x08: { - EmulatorSetRegister(EMULATOR_REG_AX, - (Eax & 0xFFFFFF00) | DosReadCharacter()); + Character = DosReadCharacter(); + + if (!EmulatorGetFlag(EMULATOR_FLAG_CF)) + { + EmulatorSetRegister(EMULATOR_REG_AX, (Eax & 0xFFFFFF00) | Character); + } + break; }
@@ -1419,6 +1424,8 @@ /* Read Buffered Input */ case 0x0A: { + DPRINT1("FIXME: This function is still not adapted to the new system!\n"); + InputBuffer = (PDOS_INPUT_BUFFER)((ULONG_PTR)BaseAddress + TO_LINEAR(DataSegment, LOWORD(Edx))); @@ -1725,23 +1732,45 @@ /* Read File */ case 0x3F: { + WORD Handle = LOWORD(Ebx); + LPBYTE Buffer = (LPBYTE)((ULONG_PTR)BaseAddress + TO_LINEAR(DataSegment, LOWORD(Edx))); + WORD Count = LOWORD(Ecx); WORD BytesRead = 0; - WORD ErrorCode = DosReadFile(LOWORD(Ebx), - (LPVOID)((ULONG_PTR)BaseAddress - + TO_LINEAR(DataSegment, LOWORD(Edx))), - LOWORD(Ecx), - &BytesRead); + WORD ErrorCode = ERROR_SUCCESS; + + if (IsConsoleHandle(DosGetRealHandle(Handle))) + { + while (Stack[STACK_COUNTER] < Count) + { + /* Read a character from the BIOS */ + Buffer[Stack[STACK_COUNTER]] = LOBYTE(BiosGetCharacter()); // FIXME: Security checks! + + /* Stop if the BOP needs to be repeated */ + if (EmulatorGetFlag(EMULATOR_FLAG_CF)) break; + + /* Increment the counter */ + Stack[STACK_COUNTER]++; + } + + if (Stack[STACK_COUNTER] < Count) ErrorCode = ERROR_NOT_READY; + else BytesRead = Count; + } + else + { + /* Use the file reading function */ + ErrorCode = DosReadFile(Handle, Buffer, Count, &BytesRead); + }
if (ErrorCode == 0) { - /* Clear CF */ - Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; - - /* Return the number of bytes read in AX */ - EmulatorSetRegister(EMULATOR_REG_AX, - (Eax & 0xFFFF0000) | BytesRead); - } - else + /* Clear CF */ + Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; + + /* Return the number of bytes read in AX */ + EmulatorSetRegister(EMULATOR_REG_AX, + (Eax & 0xFFFF0000) | BytesRead); + } + else if (ErrorCode != ERROR_NOT_READY) { /* Set CF */ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
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] Thu Oct 24 01:01:49 2013 @@ -590,9 +590,6 @@ /* Skip the opcodes */ EmulatorContext.state->reg_ip += 4;
- // HACK: Refresh the display because the called function may wait. - VgaRefreshDisplay(); - /* Call the BOP handler */ EmulatorBop(Instruction[1]); }
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] Thu Oct 24 01:01:49 2013 @@ -43,10 +43,11 @@ /* Common definitions */ #define EMULATOR_BOP 0xC4C4 #define EMULATOR_INT_BOP 0xBEEF -#define STACK_INT_NUM 0 -#define STACK_IP 1 -#define STACK_CS 2 -#define STACK_FLAGS 3 +#define STACK_COUNTER 0 +#define STACK_INT_NUM 1 +#define STACK_IP 2 +#define STACK_CS 3 +#define STACK_FLAGS 4
enum {
Modified: branches/ntvdm/subsystems/ntvdm/ps2.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ps2.c?rev... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/ps2.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/ps2.c [iso-8859-1] Thu Oct 24 01:01:49 2013 @@ -271,6 +271,7 @@ HANDLE ConsoleInput = GetStdHandle(STD_INPUT_HANDLE); DWORD i, j, Count, TotalEvents; BYTE ScanCode; + BOOLEAN Interrupt = FALSE;
/* Get the number of input events */ if (!GetNumberOfConsoleInputEvents(ConsoleInput, &Count)) return; @@ -300,12 +301,10 @@ KeyboardQueuePush(ScanCode); }
- /* Yes, IRQ 1 */ - PicInterruptRequest(1); - - /* Stop the loop */ - break; - } + Interrupt = TRUE; + } + + if (Interrupt) PicInterruptRequest(1);
Cleanup: HeapFree(GetProcessHeap(), 0, Buffer);