Author: aandrejevic Date: Sat Sep 21 18:44:59 2013 New Revision: 60289
URL: http://svn.reactos.org/svn/reactos?rev=60289&view=rev Log: [SOFT386] Implement the MOV AL/AX/EAX, off16/32 and MOV off16/32, AL/AX/EAX instructions.
Modified: branches/ntvdm/lib/soft386/opcodes.c branches/ntvdm/lib/soft386/opcodes.h
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 21 18:44:59 2013 @@ -184,10 +184,10 @@ Soft386OpcodePopFlags, Soft386OpcodeSahf, Soft386OpcodeLahf, - NULL, // TODO: OPCODE 0xA0 NOT SUPPORTED - NULL, // TODO: OPCODE 0xA1 NOT SUPPORTED - NULL, // TODO: OPCODE 0xA2 NOT SUPPORTED - NULL, // TODO: OPCODE 0xA3 NOT SUPPORTED + Soft386OpcodeMovAlOffset, + Soft386OpcodeMovEaxOffset, + Soft386OpcodeMovOffsetAl, + Soft386OpcodeMovOffsetEax, NULL, // TODO: OPCODE 0xA4 NOT SUPPORTED NULL, // TODO: OPCODE 0xA5 NOT SUPPORTED NULL, // TODO: OPCODE 0xA6 NOT SUPPORTED @@ -4639,3 +4639,196 @@
return FALSE; } + +SOFT386_OPCODE_HANDLER(Soft386OpcodeMovAlOffset) +{ + BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; + ULONG Offset; + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0xA0); + + if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE) + { + /* The OPSIZE prefix toggles the size */ + Size = !Size; + } + + if (Size) + { + if (!Soft386FetchDword(State, &Offset)) + { + /* Exception occurred */ + return FALSE; + } + } + else + { + USHORT WordOffset; + + if (!Soft386FetchWord(State, &WordOffset)) + { + /* Exception occurred */ + return FALSE; + } + + Offset = (ULONG)WordOffset; + } + + /* Read from memory */ + return Soft386ReadMemory(State, + (State->PrefixFlags & SOFT386_PREFIX_SEG) ? + State->SegmentOverride : SOFT386_REG_DS, + Offset, + FALSE, + &State->GeneralRegs[SOFT386_REG_EAX].LowByte, + sizeof(UCHAR)); +} + +SOFT386_OPCODE_HANDLER(Soft386OpcodeMovEaxOffset) +{ + BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0xA1); + + if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE) + { + /* The OPSIZE prefix toggles the size */ + Size = !Size; + } + + if (Size) + { + ULONG Offset; + + if (!Soft386FetchDword(State, &Offset)) + { + /* Exception occurred */ + return FALSE; + } + + /* Read from memory */ + return Soft386ReadMemory(State, + (State->PrefixFlags & SOFT386_PREFIX_SEG) ? + State->SegmentOverride : SOFT386_REG_DS, + Offset, + FALSE, + &State->GeneralRegs[SOFT386_REG_EAX].Long, + sizeof(ULONG)); + } + else + { + USHORT Offset; + + if (!Soft386FetchWord(State, &Offset)) + { + /* Exception occurred */ + return FALSE; + } + + /* Read from memory */ + return Soft386ReadMemory(State, + (State->PrefixFlags & SOFT386_PREFIX_SEG) ? + State->SegmentOverride : SOFT386_REG_DS, + Offset, + FALSE, + &State->GeneralRegs[SOFT386_REG_EAX].LowWord, + sizeof(USHORT)); + } +} + +SOFT386_OPCODE_HANDLER(Soft386OpcodeMovOffsetAl) +{ + BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; + ULONG Offset; + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0xA2); + + if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE) + { + /* The OPSIZE prefix toggles the size */ + Size = !Size; + } + + if (Size) + { + if (!Soft386FetchDword(State, &Offset)) + { + /* Exception occurred */ + return FALSE; + } + } + else + { + USHORT WordOffset; + + if (!Soft386FetchWord(State, &WordOffset)) + { + /* Exception occurred */ + return FALSE; + } + + Offset = (ULONG)WordOffset; + } + + /* Write to memory */ + return Soft386WriteMemory(State, + (State->PrefixFlags & SOFT386_PREFIX_SEG) ? + State->SegmentOverride : SOFT386_REG_DS, + Offset, + &State->GeneralRegs[SOFT386_REG_EAX].LowByte, + sizeof(UCHAR)); +} + +SOFT386_OPCODE_HANDLER(Soft386OpcodeMovOffsetEax) +{ + BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0xA3); + + if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE) + { + /* The OPSIZE prefix toggles the size */ + Size = !Size; + } + + if (Size) + { + ULONG Offset; + + if (!Soft386FetchDword(State, &Offset)) + { + /* Exception occurred */ + return FALSE; + } + + /* Write to memory */ + return Soft386WriteMemory(State, + (State->PrefixFlags & SOFT386_PREFIX_SEG) ? + State->SegmentOverride : SOFT386_REG_DS, + Offset, + &State->GeneralRegs[SOFT386_REG_EAX].Long, + sizeof(ULONG)); + } + else + { + USHORT Offset; + + if (!Soft386FetchWord(State, &Offset)) + { + /* Exception occurred */ + return FALSE; + } + + /* Write to memory */ + return Soft386WriteMemory(State, + (State->PrefixFlags & SOFT386_PREFIX_SEG) ? + State->SegmentOverride : SOFT386_REG_DS, + Offset, + &State->GeneralRegs[SOFT386_REG_EAX].LowWord, + sizeof(USHORT)); + } +}
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 21 18:44:59 2013 @@ -132,5 +132,9 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeCall); SOFT386_OPCODE_HANDLER(Soft386OpcodeJmp); SOFT386_OPCODE_HANDLER(Soft386OpcodeJmpAbs); +SOFT386_OPCODE_HANDLER(Soft386OpcodeMovAlOffset); +SOFT386_OPCODE_HANDLER(Soft386OpcodeMovEaxOffset); +SOFT386_OPCODE_HANDLER(Soft386OpcodeMovOffsetAl); +SOFT386_OPCODE_HANDLER(Soft386OpcodeMovOffsetEax);
#endif // _OPCODES_H_