Author: aandrejevic
Date: Sat Sep 28 00:29:16 2013
New Revision: 60395
URL:
http://svn.reactos.org/svn/reactos?rev=60395&view=rev
Log:
[SOFT386]
Implement the LES and LDS instructions.
Add optional support for BOPs (NTVDM-specific).
Fix prefix handling in some functions.
[NTVDM]
Enable BOPs for Soft386 (when NEW_EMULATOR is defined).
Fix the calling convention issue (softx86 uses cdecl, soft386 uses stdcall).
Modified:
branches/ntvdm/include/reactos/libs/soft386/soft386.h
branches/ntvdm/lib/soft386/opcodes.c
branches/ntvdm/lib/soft386/opcodes.h
branches/ntvdm/lib/soft386/soft386.c
branches/ntvdm/subsystems/ntvdm/emulator.c
branches/ntvdm/subsystems/ntvdm/emulator.h
Modified: branches/ntvdm/include/reactos/libs/soft386/soft386.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/include/reactos/libs/soft…
==============================================================================
--- branches/ntvdm/include/reactos/libs/soft386/soft386.h [iso-8859-1] (original)
+++ branches/ntvdm/include/reactos/libs/soft386/soft386.h [iso-8859-1] Sat Sep 28 00:29:16
2013
@@ -155,6 +155,14 @@
(NTAPI *SOFT386_IDLE_PROC)
(
PSOFT386_STATE State
+);
+
+typedef
+VOID
+(NTAPI *SOFT386_BOP_PROC)
+(
+ PSOFT386_STATE State,
+ USHORT BopCode
);
typedef union _SOFT386_REG
@@ -295,6 +303,7 @@
SOFT386_IO_READ_PROC IoReadCallback;
SOFT386_IO_WRITE_PROC IoWriteCallback;
SOFT386_IDLE_PROC IdleCallback;
+ SOFT386_BOP_PROC BopCallback;
SOFT386_REG GeneralRegs[SOFT386_NUM_GEN_REGS];
SOFT386_SEG_REG SegmentRegs[SOFT386_NUM_SEG_REGS];
SOFT386_REG InstPtr;
Modified: branches/ntvdm/lib/soft386/opcodes.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/opcodes.c?rev…
==============================================================================
--- branches/ntvdm/lib/soft386/opcodes.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/soft386/opcodes.c [iso-8859-1] Sat Sep 28 00:29:16 2013
@@ -221,8 +221,8 @@
NULL, // TODO: OPCODE 0xC1 NOT SUPPORTED
Soft386OpcodeRet,
Soft386OpcodeRet,
- Soft386OpcodeLes,
- Soft386OpcodeLds,
+ Soft386OpcodeLdsLes,
+ Soft386OpcodeLdsLes,
NULL, // TODO: OPCODE 0xC6 NOT SUPPORTED
NULL, // TODO: OPCODE 0xC7 NOT SUPPORTED
Soft386OpcodeEnter,
@@ -4474,20 +4474,99 @@
return TRUE;
}
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLes)
-{
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- return FALSE;
-}
-
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLds)
-{
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- return FALSE;
+SOFT386_OPCODE_HANDLER(Soft386OpcodeLdsLes)
+{
+ UCHAR FarPointer[6];
+ BOOLEAN OperandSize, AddressSize;
+ SOFT386_MOD_REG_RM ModRegRm;
+
+ /* Make sure this is the right instruction */
+ ASSERT((Opcode & 0xFE) == 0xC4);
+
+ OperandSize = AddressSize = State->SegmentRegs[SOFT386_REG_CS].Size;
+
+ if (State->PrefixFlags & SOFT386_PREFIX_ADSIZE)
+ {
+ /* The ADSIZE prefix toggles the size */
+ AddressSize = !AddressSize;
+ }
+
+ /* Get the operands */
+ if (!Soft386ParseModRegRm(State, AddressSize, &ModRegRm))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ if (!ModRegRm.Memory)
+ {
+ /* Check if this is a BOP and the host supports BOPs */
+ if ((Opcode == 0xC4)
+ && (ModRegRm.Register == SOFT386_REG_EAX)
+ && (ModRegRm.SecondRegister == SOFT386_REG_EBP)
+ && (State->BopCallback != NULL))
+ {
+ USHORT BopCode;
+
+ /* Fetch the BOP code */
+ if (!Soft386FetchWord(State, &BopCode))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ /* Call the BOP handler */
+ State->BopCallback(State, BopCode);
+
+ /* Return success */
+ return TRUE;
+ }
+
+ /* Invalid */
+ Soft386Exception(State, SOFT386_EXCEPTION_UD);
+ return FALSE;
+ }
+
+ if (!Soft386ReadMemory(State,
+ (State->PrefixFlags & SOFT386_PREFIX_SEG)
+ ? State->SegmentOverride : SOFT386_REG_DS,
+ ModRegRm.MemoryAddress,
+ FALSE,
+ FarPointer,
+ OperandSize ? 6 : 4))
+ {
+ /* Exception occurred */
+ return FALSE;
+ }
+
+ if (OperandSize)
+ {
+ ULONG Offset = *((PULONG)FarPointer);
+ USHORT Segment = *((PUSHORT)&FarPointer[sizeof(ULONG)]);
+
+ /* Set the register to the offset */
+ State->GeneralRegs[ModRegRm.Register].Long = Offset;
+
+ /* Load the segment */
+ return Soft386LoadSegment(State,
+ (Opcode == 0xC4)
+ ? SOFT386_REG_ES : SOFT386_REG_DS,
+ Segment);
+ }
+ else
+ {
+ USHORT Offset = *((PUSHORT)FarPointer);
+ USHORT Segment = *((PUSHORT)&FarPointer[sizeof(USHORT)]);
+
+ /* Set the register to the offset */
+ State->GeneralRegs[ModRegRm.Register].LowWord = Offset;
+
+ /* Load the segment */
+ return Soft386LoadSegment(State,
+ (Opcode == 0xC4)
+ ? SOFT386_REG_ES : SOFT386_REG_DS,
+ Segment);
+ }
}
SOFT386_OPCODE_HANDLER(Soft386OpcodeEnter)
@@ -4508,7 +4587,7 @@
return FALSE;
}
- if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE)
+ if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE)
{
/* The OPSIZE prefix toggles the size */
Size = !Size;
@@ -4577,7 +4656,7 @@
return FALSE;
}
- if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE)
+ if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE)
{
/* The OPSIZE prefix toggles the size */
Size = !Size;
@@ -4705,7 +4784,7 @@
return FALSE;
}
- if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE)
+ if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE)
{
/* The OPSIZE prefix toggles the size */
Size = !Size;
@@ -5001,7 +5080,7 @@
return FALSE;
}
- if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE)
+ if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE)
{
/* The OPSIZE prefix toggles the size */
Size = !Size;
Modified: branches/ntvdm/lib/soft386/opcodes.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/opcodes.h?rev…
==============================================================================
--- branches/ntvdm/lib/soft386/opcodes.h [iso-8859-1] (original)
+++ branches/ntvdm/lib/soft386/opcodes.h [iso-8859-1] Sat Sep 28 00:29:16 2013
@@ -115,8 +115,7 @@
SOFT386_OPCODE_HANDLER(Soft386OpcodeSahf);
SOFT386_OPCODE_HANDLER(Soft386OpcodeLahf);
SOFT386_OPCODE_HANDLER(Soft386OpcodeRet);
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLes);
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLds);
+SOFT386_OPCODE_HANDLER(Soft386OpcodeLdsLes);
SOFT386_OPCODE_HANDLER(Soft386OpcodeEnter);
SOFT386_OPCODE_HANDLER(Soft386OpcodeLeave);
SOFT386_OPCODE_HANDLER(Soft386OpcodeRetFarImm);
Modified: branches/ntvdm/lib/soft386/soft386.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/soft386.c?rev…
==============================================================================
--- branches/ntvdm/lib/soft386/soft386.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/soft386/soft386.c [iso-8859-1] Sat Sep 28 00:29:16 2013
@@ -211,6 +211,7 @@
SOFT386_IO_READ_PROC IoReadCallback = State->IoReadCallback;
SOFT386_IO_WRITE_PROC IoWriteCallback = State->IoWriteCallback;
SOFT386_IDLE_PROC IdleCallback = State->IdleCallback;
+ SOFT386_BOP_PROC BopCallback = State->BopCallback;
/* Clear the entire structure */
RtlZeroMemory(State, sizeof(*State));
@@ -245,6 +246,7 @@
State->IoReadCallback = IoReadCallback;
State->IoWriteCallback = IoWriteCallback;
State->IdleCallback = IdleCallback;
+ State->BopCallback = BopCallback;
}
VOID
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] Sat Sep 28 00:29:16 2013
@@ -31,7 +31,7 @@
/* PRIVATE FUNCTIONS **********************************************************/
-static VOID EmulatorReadMemory(PVOID Context, UINT Address, LPBYTE Buffer, INT Size)
+static VOID NTVDMCALL EmulatorReadMemory(PVOID Context, UINT Address, LPBYTE Buffer, INT
Size)
{
UNREFERENCED_PARAMETER(Context);
@@ -56,7 +56,7 @@
}
}
-static VOID EmulatorWriteMemory(PVOID Context, UINT Address, LPBYTE Buffer, INT Size)
+static VOID NTVDMCALL EmulatorWriteMemory(PVOID Context, UINT Address, LPBYTE Buffer, INT
Size)
{
UNREFERENCED_PARAMETER(Context);
@@ -84,7 +84,7 @@
}
}
-static VOID EmulatorReadIo(PVOID Context, UINT Address, LPBYTE Buffer, INT Size)
+static VOID NTVDMCALL EmulatorReadIo(PVOID Context, UINT Address, LPBYTE Buffer, INT
Size)
{
UNREFERENCED_PARAMETER(Context);
UNREFERENCED_PARAMETER(Size);
@@ -152,7 +152,7 @@
}
}
-static VOID EmulatorWriteIo(PVOID Context, UINT Address, LPBYTE Buffer, INT Size)
+static VOID NTVDMCALL EmulatorWriteIo(PVOID Context, UINT Address, LPBYTE Buffer, INT
Size)
{
BYTE Byte = *Buffer;
@@ -228,8 +228,6 @@
}
}
-#ifndef NEW_EMULATOR
-
static VOID EmulatorBop(WORD Code)
{
WORD StackSegment, StackPointer, CodeSegment, InstructionPointer;
@@ -241,8 +239,8 @@
StackSegment = EmulatorContext.state->segment_reg[SX86_SREG_SS].val;
StackPointer = EmulatorContext.state->general_reg[SX86_REG_SP].val;
#else
- StackSegment = EmulatorContext.SegmentRegs[SOFT386_REG_SS].LowWord;
- StackPointer = EmulatorContext.SegmentRegs[SOFT386_REG_SP].LowWord;
+ StackSegment = EmulatorContext.SegmentRegs[SOFT386_REG_SS].Selector;
+ StackPointer = EmulatorContext.GeneralRegs[SOFT386_REG_ESP].LowWord;
#endif
/* Get the stack */
@@ -341,6 +339,21 @@
}
}
+#ifdef NEW_EMULATOR
+static VOID WINAPI EmulatorBiosOperation(PSOFT386_STATE State, WORD Code)
+{
+ /*
+ * HACK: To maintain softx86 compatbility, just call the old EmulatorBop here.
+ * Later on, when softx86 is no longer needed, the code from EmulatorBop should
+ * be moved here and should use the "State" variable.
+ */
+ EmulatorBop(Code);
+}
+
+#endif
+
+#ifndef NEW_EMULATOR
+
static VOID EmulatorSoftwareInt(PVOID Context, BYTE Number)
{
UNREFERENCED_PARAMETER(Context);
@@ -412,6 +425,7 @@
EmulatorContext.MemWriteCallback = (SOFT386_MEM_WRITE_PROC)EmulatorWriteMemory;
EmulatorContext.IoReadCallback = (SOFT386_IO_READ_PROC)EmulatorReadIo;
EmulatorContext.IoWriteCallback = (SOFT386_IO_WRITE_PROC)EmulatorWriteIo;
+ EmulatorContext.BopCallback = (SOFT386_BOP_PROC)EmulatorBiosOperation;
/* Reset the CPU */
Soft386Reset(&EmulatorContext);
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] Sat Sep 28 00:29:16 2013
@@ -86,10 +86,16 @@
};
#ifndef NEW_EMULATOR
+
+#define NTVDMCALL __cdecl
extern softx86_ctx EmulatorContext;
extern softx87_ctx FpuEmulatorContext;
+
#else
+
+#define NTVDMCALL __stdcall
extern SOFT386_STATE EmulatorContext;
+
#endif
/* FUNCTIONS ******************************************************************/