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?r…
==============================================================================
--- 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?re…
==============================================================================
--- 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?re…
==============================================================================
--- 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);