Author: aandrejevic Date: Sat Aug 24 21:32:45 2013 New Revision: 59814
URL: http://svn.reactos.org/svn/reactos?rev=59814&view=rev Log: [SOFT386] Implement the following opcodes: INC reg16/reg32 DEC reg16/reg32
Modified: branches/ntvdm/lib/soft386/common.c branches/ntvdm/lib/soft386/common.h branches/ntvdm/lib/soft386/opcodes.c branches/ntvdm/lib/soft386/opcodes.h
Modified: branches/ntvdm/lib/soft386/common.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/common.c?rev=5... ============================================================================== --- branches/ntvdm/lib/soft386/common.c [iso-8859-1] (original) +++ branches/ntvdm/lib/soft386/common.c [iso-8859-1] Sat Aug 24 21:32:45 2013 @@ -754,4 +754,14 @@ } }
+inline +BOOLEAN +Soft386CalculateParity(UCHAR Number) +{ + Number ^= Number >> 1; + Number ^= Number >> 2; + Number ^= Number >> 4; + return !(Number & 1); +} + /* EOF */
Modified: branches/ntvdm/lib/soft386/common.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/common.h?rev=5... ============================================================================== --- branches/ntvdm/lib/soft386/common.h [iso-8859-1] (original) +++ branches/ntvdm/lib/soft386/common.h [iso-8859-1] Sat Aug 24 21:32:45 2013 @@ -15,6 +15,9 @@ #define FASTCALL __fastcall #endif
+#define SIGN_FLAG_BYTE 0x80 +#define SIGN_FLAG_WORD 0x8000 +#define SIGN_FLAG_LONG 0x80000000 #define GET_SEGMENT_RPL(s) ((s) & 3) #define GET_SEGMENT_INDEX(s) ((s) & 0xFFF8)
@@ -119,6 +122,13 @@ INT ExceptionCode );
+inline +BOOLEAN +Soft386CalculateParity +( + UCHAR Number +); + #endif // _COMMON_H_
/* EOF */
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 Aug 24 21:32:45 2013 @@ -88,22 +88,22 @@ NULL, // TODO: OPCODE 0x3D NOT SUPPORTED Soft386OpcodePrefix, NULL, // TODO: OPCODE 0x3F NOT SUPPORTED - NULL, // TODO: OPCODE 0x40 NOT SUPPORTED - NULL, // TODO: OPCODE 0x41 NOT SUPPORTED - NULL, // TODO: OPCODE 0x42 NOT SUPPORTED - NULL, // TODO: OPCODE 0x43 NOT SUPPORTED - NULL, // TODO: OPCODE 0x44 NOT SUPPORTED - NULL, // TODO: OPCODE 0x45 NOT SUPPORTED - NULL, // TODO: OPCODE 0x46 NOT SUPPORTED - NULL, // TODO: OPCODE 0x47 NOT SUPPORTED - NULL, // TODO: OPCODE 0x48 NOT SUPPORTED - NULL, // TODO: OPCODE 0x49 NOT SUPPORTED - NULL, // TODO: OPCODE 0x4A NOT SUPPORTED - NULL, // TODO: OPCODE 0x4B NOT SUPPORTED - NULL, // TODO: OPCODE 0x4C NOT SUPPORTED - NULL, // TODO: OPCODE 0x4D NOT SUPPORTED - NULL, // TODO: OPCODE 0x4E NOT SUPPORTED - NULL, // TODO: OPCODE 0x4F NOT SUPPORTED + Soft386OpcodeIncrement, + Soft386OpcodeIncrement, + Soft386OpcodeIncrement, + Soft386OpcodeIncrement, + Soft386OpcodeIncrement, + Soft386OpcodeIncrement, + Soft386OpcodeIncrement, + Soft386OpcodeIncrement, + Soft386OpcodeDecrement, + Soft386OpcodeDecrement, + Soft386OpcodeDecrement, + Soft386OpcodeDecrement, + Soft386OpcodeDecrement, + Soft386OpcodeDecrement, + Soft386OpcodeDecrement, + Soft386OpcodeDecrement, NULL, // TODO: OPCODE 0x50 NOT SUPPORTED NULL, // TODO: OPCODE 0x51 NOT SUPPORTED NULL, // TODO: OPCODE 0x52 NOT SUPPORTED @@ -444,3 +444,93 @@
return TRUE; } + +BOOLEAN +FASTCALL +Soft386OpcodeIncrement(PSOFT386_STATE State, UCHAR Opcode) +{ + ULONG Value; + BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; + + if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE) + { + /* The OPSIZE prefix toggles the size */ + Size = !Size; + } + else if (State->PrefixFlags != 0) + { + /* Invalid prefix */ + Soft386Exception(State, SOFT386_EXCEPTION_UD); + return FALSE; + } + + /* Make sure this is the right instruction */ + ASSERT((Opcode & 0xF8) == 0x40); + + if (Size) + { + Value = ++State->GeneralRegs[Opcode & 0x07].Long; + + State->Flags.Of = (Value == SIGN_FLAG_LONG) ? TRUE : FALSE; + State->Flags.Sf = (Value & SIGN_FLAG_LONG) ? TRUE : FALSE; + } + else + { + Value = ++State->GeneralRegs[Opcode & 0x07].LowWord; + + State->Flags.Of = (Value == SIGN_FLAG_WORD) ? TRUE : FALSE; + State->Flags.Sf = (Value & SIGN_FLAG_WORD) ? TRUE : FALSE; + } + + State->Flags.Zf = (Value == 0) ? TRUE : FALSE; + State->Flags.Af = ((Value & 0x0F) == 0) ? TRUE : FALSE; + State->Flags.Pf = Soft386CalculateParity(LOBYTE(Value)); + + /* Return success */ + return TRUE; +} + +BOOLEAN +FASTCALL +Soft386OpcodeDecrement(PSOFT386_STATE State, UCHAR Opcode) +{ + ULONG Value; + BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; + + if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE) + { + /* The OPSIZE prefix toggles the size */ + Size = !Size; + } + else if (State->PrefixFlags != 0) + { + /* Invalid prefix */ + Soft386Exception(State, SOFT386_EXCEPTION_UD); + return FALSE; + } + + /* Make sure this is the right instruction */ + ASSERT((Opcode & 0xF8) == 0x48); + + if (Size) + { + Value = --State->GeneralRegs[Opcode & 0x07].Long; + + State->Flags.Of = (Value == (SIGN_FLAG_LONG - 1)) ? TRUE : FALSE; + State->Flags.Sf = (Value & SIGN_FLAG_LONG) ? TRUE : FALSE; + } + else + { + Value = --State->GeneralRegs[Opcode & 0x07].LowWord; + + State->Flags.Of = (Value == (SIGN_FLAG_WORD - 1)) ? TRUE : FALSE; + State->Flags.Sf = (Value & SIGN_FLAG_WORD) ? TRUE : FALSE; + } + + State->Flags.Zf = (Value == 0) ? TRUE : FALSE; + State->Flags.Af = ((Value & 0x0F) == 0x0F) ? TRUE : FALSE; + State->Flags.Pf = Soft386CalculateParity(LOBYTE(Value)); + + /* Return success */ + return TRUE; +}
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 Aug 24 21:32:45 2013 @@ -31,4 +31,20 @@ UCHAR Opcode );
+BOOLEAN +FASTCALL +Soft386OpcodeIncrement +( + PSOFT386_STATE State, + UCHAR Opcode +); + +BOOLEAN +FASTCALL +Soft386OpcodeDecrement +( + PSOFT386_STATE State, + UCHAR Opcode +); + #endif // _OPCODES_H_