Author: aandrejevic
Date: Sun Jul 7 20:53:23 2013
New Revision: 59450
URL:
http://svn.reactos.org/svn/reactos?rev=59450&view=rev
Log:
[SOFTX86]
Fix jump conditions.
[NTVDM]
Implement BIOS teletype output command.
Start implementation of a new CPU emulator to replace softx86.
Modified:
branches/ntvdm/lib/3rdparty/softx86/softx86/jumpy.c
branches/ntvdm/subsystems/ntvdm/bios.c
branches/ntvdm/subsystems/ntvdm/emulator.c
branches/ntvdm/subsystems/ntvdm/emulator.h
Modified: branches/ntvdm/lib/3rdparty/softx86/softx86/jumpy.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/3rdparty/softx86/soft…
==============================================================================
--- branches/ntvdm/lib/3rdparty/softx86/softx86/jumpy.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/3rdparty/softx86/softx86/jumpy.c [iso-8859-1] Sun Jul 7 20:53:23
2013
@@ -86,22 +86,22 @@
tf = !(ctx->state->reg_flags.val & SX86_CPUFLAG_PARITY);
/* JL */
else if (opcode == 0x7C)
- tf = (ctx->state->reg_flags.val & SX86_CPUFLAG_SIGN) !=
- (ctx->state->reg_flags.val & SX86_CPUFLAG_OVERFLOW);
+ tf = (((ctx->state->reg_flags.val & SX86_CPUFLAG_SIGN) ? 1 : 0) !=
+ ((ctx->state->reg_flags.val & SX86_CPUFLAG_OVERFLOW) ? 1 : 0));
/* JGE */
else if (opcode == 0x7D)
- tf = (ctx->state->reg_flags.val & SX86_CPUFLAG_SIGN) ==
- (ctx->state->reg_flags.val & SX86_CPUFLAG_OVERFLOW);
+ tf = ((ctx->state->reg_flags.val & SX86_CPUFLAG_SIGN) ? 1 : 0) ==
+ ((ctx->state->reg_flags.val & SX86_CPUFLAG_OVERFLOW) ? 1 : 0);
/* JLE */
else if (opcode == 0x7E)
- tf = ((ctx->state->reg_flags.val & SX86_CPUFLAG_SIGN) !=
- (ctx->state->reg_flags.val & SX86_CPUFLAG_OVERFLOW)) ||
- (ctx->state->reg_flags.val & SX86_CPUFLAG_ZERO);
+ tf = (((ctx->state->reg_flags.val & SX86_CPUFLAG_SIGN) ? 1 : 0) !=
+ ((ctx->state->reg_flags.val & SX86_CPUFLAG_OVERFLOW) ? 1 : 0) ||
+ (ctx->state->reg_flags.val & SX86_CPUFLAG_ZERO));
/* JG */
else if (opcode == 0x7F)
- tf = ((ctx->state->reg_flags.val & SX86_CPUFLAG_SIGN) ==
- (ctx->state->reg_flags.val & SX86_CPUFLAG_OVERFLOW)) &&
- (!(ctx->state->reg_flags.val & SX86_CPUFLAG_ZERO));
+ tf = (((ctx->state->reg_flags.val & SX86_CPUFLAG_SIGN) ? 1 : 0) ==
+ ((ctx->state->reg_flags.val & SX86_CPUFLAG_OVERFLOW) ? 1 : 0) &&
+ (!(ctx->state->reg_flags.val & SX86_CPUFLAG_ZERO)));
/* should NOT be here !*/
else
return 0;
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] Sun Jul 7 20:53:23 2013
@@ -738,6 +738,28 @@
break;
}
+ /* Teletype Output */
+ case 0x0E:
+ {
+ CHAR Character = LOBYTE(Eax);
+ DWORD NumWritten;
+
+ /* Make sure the page exists */
+ if (HIBYTE(Ebx) >= VideoModes[CurrentVideoMode].Pages) break;
+
+ /* Set the attribute */
+ SetConsoleTextAttribute(ConsoleBuffers[HIBYTE(Ebx)], LOBYTE(Ebx));
+
+ /* Write the character */
+ WriteConsoleA(ConsoleBuffers[HIBYTE(Ebx)],
+ &Character,
+ sizeof(CHAR),
+ &NumWritten,
+ NULL);
+
+ break;
+ }
+
/* Get Current Video Mode */
case 0x0F:
{
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 Jul 7 20:53:23 2013
@@ -17,11 +17,18 @@
/* PRIVATE VARIABLES **********************************************************/
-static softx86_ctx EmulatorContext;
-static softx87_ctx FpuEmulatorContext;
+#ifndef NEW_EMULATOR
+softx86_ctx EmulatorContext;
+softx87_ctx FpuEmulatorContext;
+#else
+EMULATOR_CONTEXT EmulatorContext;
+#endif
+
static BOOLEAN A20Line = FALSE;
/* PRIVATE FUNCTIONS **********************************************************/
+
+#ifndef NEW_EMULATOR
static VOID EmulatorReadMemory(PVOID Context, UINT Address, LPBYTE Buffer, INT Size)
{
@@ -165,8 +172,13 @@
if (Number == SPECIAL_INT_NUM)
{
/* Get the SS:SP */
+#ifndef NEW_EMULATOR
StackSegment = EmulatorContext.state->segment_reg[SX86_SREG_SS].val;
StackPointer = EmulatorContext.state->general_reg[SX86_REG_SP].val;
+#else
+ StackSegment = EmulatorContext.Registers[EMULATOR_REG_SS].LowWord;
+ StackPointer = EmulatorContext.Registers[EMULATOR_REG_SP].LowWord;
+#endif
/* Get the interrupt number */
IntNum = *(LPBYTE)((ULONG_PTR)BaseAddress + TO_LINEAR(StackSegment,
StackPointer));
@@ -274,6 +286,8 @@
/* Do nothing */
}
+#endif
+
/* PUBLIC FUNCTIONS ***********************************************************/
BOOLEAN EmulatorInitialize()
@@ -282,6 +296,7 @@
BaseAddress = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_ADDRESS);
if (BaseAddress == NULL) return FALSE;
+#ifndef NEW_EMULATOR
/* Initialize the softx86 CPU emulator */
if (!softx86_init(&EmulatorContext, SX86_CPULEVEL_80286))
{
@@ -312,6 +327,9 @@
/* Connect the emulated FPU to the emulated CPU */
softx87_connect_to_CPU(&EmulatorContext, &FpuEmulatorContext);
+#else
+ // TODO: NOT IMPLEMENTED
+#endif
/* Enable interrupts */
EmulatorSetFlag(EMULATOR_FLAG_IF);
@@ -321,14 +339,22 @@
VOID EmulatorSetStack(WORD Segment, WORD Offset)
{
+#ifndef NEW_EMULATOR
/* Call the softx86 API */
softx86_set_stack_ptr(&EmulatorContext, Segment, Offset);
+#else
+ // TODO: NOT IMPLEMENTED
+#endif
}
VOID EmulatorExecute(WORD Segment, WORD Offset)
{
+#ifndef NEW_EMULATOR
/* Call the softx86 API */
softx86_set_instruction_ptr(&EmulatorContext, Segment, Offset);
+#else
+ // TODO: NOT IMPLEMENTED
+#endif
}
VOID EmulatorInterrupt(BYTE Number)
@@ -340,18 +366,27 @@
Segment = HIWORD(IntVecTable[Number]);
Offset = LOWORD(IntVecTable[Number]);
+#ifndef NEW_EMULATOR
/* Call the softx86 API */
softx86_make_simple_interrupt_call(&EmulatorContext, &Segment, &Offset);
+#else
+ UNREFERENCED_PARAMETER(Segment);
+ UNREFERENCED_PARAMETER(Offset);
+ // TODO: NOT IMPLEMENTED
+#endif
}
VOID EmulatorExternalInterrupt(BYTE Number)
{
+#ifndef NEW_EMULATOR
/* Call the softx86 API */
softx86_ext_hw_signal(&EmulatorContext, Number);
+#endif
}
ULONG EmulatorGetRegister(ULONG Register)
{
+#ifndef NEW_EMULATOR
if (Register < EMULATOR_REG_ES)
{
return EmulatorContext.state->general_reg[Register].val;
@@ -360,10 +395,14 @@
{
return EmulatorContext.state->segment_reg[Register - EMULATOR_REG_ES].val;
}
+#else
+ return EmulatorContext.Registers[Register].Long;
+#endif
}
VOID EmulatorSetRegister(ULONG Register, ULONG Value)
{
+#ifndef NEW_EMULATOR
if (Register < EMULATOR_REG_CS)
{
EmulatorContext.state->general_reg[Register].val = Value;
@@ -372,25 +411,41 @@
{
EmulatorContext.state->segment_reg[Register - EMULATOR_REG_ES].val = Value;
}
+#else
+ // TODO: NOT IMPLEMENTED
+#endif
}
BOOLEAN EmulatorGetFlag(ULONG Flag)
{
- return (EmulatorContext.state->reg_flags.val & Flag);
+#ifndef NEW_EMULATOR
+ return (EmulatorContext.state->reg_flags.val & Flag) ? TRUE : FALSE;
+#else
+ return (EmulatorContext.Flags.Long & Flag) ? TRUE : FALSE;
+#endif
}
VOID EmulatorSetFlag(ULONG Flag)
{
+#ifndef NEW_EMULATOR
EmulatorContext.state->reg_flags.val |= Flag;
+#else
+ EmulatorContext.Flags.Long |= Flag;
+#endif
}
VOID EmulatorClearFlag(ULONG Flag)
{
+#ifndef NEW_EMULATOR
EmulatorContext.state->reg_flags.val &= ~Flag;
+#else
+ EmulatorContext.Flags.Long &= ~Flag;
+#endif
}
VOID EmulatorStep()
{
+#ifndef NEW_EMULATOR
/* Print the current position - useful for debugging */
DPRINT("Executing at CS:IP = %04X:%04X\n",
EmulatorGetRegister(EMULATOR_REG_CS),
@@ -402,6 +457,9 @@
/* Invalid opcode */
EmulatorInterrupt(EMULATOR_EXCEPTION_INVALID_OPCODE);
}
+#else
+ // TODO: NOT IMPLEMENTED
+#endif
}
VOID EmulatorCleanup()
@@ -409,9 +467,11 @@
/* Free the memory allocated for the 16-bit address space */
if (BaseAddress != NULL) HeapFree(GetProcessHeap(), 0, BaseAddress);
+#ifndef NEW_EMULATOR
/* Free the softx86 CPU and FPU emulator */
softx86_free(&EmulatorContext);
softx87_free(&FpuEmulatorContext);
+#endif
}
VOID EmulatorSetA20(BOOLEAN Enabled)
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] Sun Jul 7 20:53:23 2013
@@ -12,11 +12,15 @@
/* INCLUDES *******************************************************************/
#include "ntvdm.h"
+
+#ifndef NEW_EMULATOR
#include <softx86/softx86.h>
#include <softx86/softx87.h>
+#endif
/* DEFINES ********************************************************************/
+/* FLAGS */
#define EMULATOR_FLAG_CF (1 << 0)
#define EMULATOR_FLAG_PF (1 << 2)
#define EMULATOR_FLAG_AF (1 << 4)
@@ -33,6 +37,39 @@
#define EMULATOR_FLAG_VIF (1 << 19)
#define EMULATOR_FLAG_VIP (1 << 20)
#define EMULATOR_FLAG_ID (1 << 21)
+
+/* CR0 */
+#define EMULATOR_CR0_PE (1 << 0)
+#define EMULATOR_CR0_MP (1 << 1)
+#define EMULATOR_CR0_EM (1 << 2)
+#define EMULATOR_CR0_TS (1 << 3)
+#define EMULATOR_CR0_ET (1 << 4)
+#define EMULATOR_CR0_NE (1 << 5)
+#define EMULATOR_CR0_WP (1 << 16)
+#define EMULATOR_CR0_AM (1 << 18)
+#define EMULATOR_CR0_NW (1 << 29)
+#define EMULATOR_CR0_CD (1 << 30)
+#define EMULATOR_CR0_PG (1 << 31)
+
+/* GDT Access byte */
+#define GDT_SEG_ACCESSED (1 << 0)
+#define GDT_DATA_WRITEABLE (1 << 1)
+#define GDT_CODE_READABLE (1 << 1)
+#define GDT_CONFORMING (1 << 2)
+#define GDT_DIRECTION (1 << 2)
+#define GDT_CODE_SEGMENT (1 << 3)
+#define GDT_PRESENT (1 << 7)
+
+/* GDT flags */
+#define GDT_32BIT_SEGMENT (1 << 2)
+#define GDT_PAGE_GRANULARITY (1 << 3)
+
+/* Common definitions */
+#define EMULATOR_NUM_GENERAL_REGS 8
+#define EMULATOR_NUM_SEGMENT_REGS 6
+#define EMULATOR_NUM_CONTROL_REGS 8
+#define EMULATOR_NUM_DEBUG_REGS 8
+#define MAX_GDT_ENTRIES 8192
#define SPECIAL_INT_NUM 0xFF
enum
@@ -44,7 +81,14 @@
EMULATOR_EXCEPTION_OVERFLOW,
EMULATOR_EXCEPTION_BOUND,
EMULATOR_EXCEPTION_INVALID_OPCODE,
- EMULATOR_EXCEPTION_NO_FPU
+ EMULATOR_EXCEPTION_NO_FPU,
+ EMULATOR_EXCEPTION_DOUBLE_FAULT,
+ EMULATOR_EXCEPTION_FPU_SEGMENT,
+ EMULATOR_EXCEPTION_INVALID_TSS,
+ EMULATOR_EXCEPTION_NO_SEGMENT,
+ EMULATOR_EXCEPTION_STACK_SEGMENT,
+ EMULATOR_EXCEPTION_GPF,
+ EMULATOR_EXCEPTION_PAGE_FAULT
};
enum
@@ -61,7 +105,63 @@
EMULATOR_REG_CS,
EMULATOR_REG_SS,
EMULATOR_REG_DS,
+ EMULATOR_REG_FS,
+ EMULATOR_REG_GS
};
+
+typedef union
+{
+ struct
+ {
+ BYTE LowByte;
+ BYTE HighByte;
+ };
+ WORD LowWord;
+ DWORD Long;
+} EMULATOR_REGISTER, *PEMULATOR_REGISTER;
+
+typedef struct
+{
+ ULONG Limit : 16;
+ ULONG Base : 24;
+ ULONG AccessByte : 8;
+ ULONG LimitHigh : 4;
+ ULONG Flags : 4;
+ ULONG BaseHigh : 8;
+} EMULATOR_GDT_ENTRY;
+
+typedef struct
+{
+ ULONG Offset : 16;
+ ULONG Selector : 16;
+ ULONG Zero : 8;
+ ULONG TypeAndAttributes : 8;
+ ULONG OffsetHigh : 16;
+} EMULATOR_IDT_ENTRY;
+
+typedef struct
+{
+ WORD Size;
+ DWORD Address;
+} EMULATOR_TABLE_REGISTER;
+
+typedef struct
+{
+ EMULATOR_REGISTER Registers[EMULATOR_NUM_GENERAL_REGS
+ + EMULATOR_NUM_SEGMENT_REGS];
+ EMULATOR_REGISTER Flags;
+ EMULATOR_REGISTER InstructionPointer;
+ EMULATOR_REGISTER ControlRegisters[EMULATOR_NUM_CONTROL_REGS];
+ EMULATOR_REGISTER DebugRegisters[EMULATOR_NUM_DEBUG_REGS];
+ ULONGLONG TimeStampCounter;
+ BOOLEAN OperandSizeOverload;
+ BOOLEAN AddressSizeOverload;
+ EMULATOR_TABLE_REGISTER Gdtr, Idtr;
+ EMULATOR_GDT_ENTRY CachedDescriptors[EMULATOR_NUM_SEGMENT_REGS];
+ UINT ExceptionCount;
+} EMULATOR_CONTEXT, *PEMULATOR_CONTEXT;
+
+typedef VOID (*EMULATOR_OPCODE_HANDLER)(PEMULATOR_CONTEXT Context, BYTE Opcode);
/* FUNCTIONS ******************************************************************/