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/soft3... ============================================================================== --- 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 ******************************************************************/