Author: aandrejevic Date: Thu Oct 3 20:56:36 2013 New Revision: 60515
URL: http://svn.reactos.org/svn/reactos?rev=60515&view=rev Log: [SOFT386] Halfplement MOVS, STOS and LODS. Stubplement CMPS and SCAS.
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] Thu Oct 3 20:56:36 2013 @@ -203,18 +203,18 @@ Soft386OpcodeMovEaxOffset, Soft386OpcodeMovOffsetAl, Soft386OpcodeMovOffsetEax, - NULL, // TODO: OPCODE 0xA4 NOT SUPPORTED - NULL, // TODO: OPCODE 0xA5 NOT SUPPORTED - NULL, // TODO: OPCODE 0xA6 NOT SUPPORTED - NULL, // TODO: OPCODE 0xA7 NOT SUPPORTED + Soft386OpcodeMovs, + Soft386OpcodeMovs, + Soft386OpcodeCmps, + Soft386OpcodeCmps, Soft386OpcodeTestAl, Soft386OpcodeTestEax, - NULL, // TODO: OPCODE 0xAA NOT SUPPORTED - NULL, // TODO: OPCODE 0xAB NOT SUPPORTED - NULL, // TODO: OPCODE 0xAC NOT SUPPORTED - NULL, // TODO: OPCODE 0xAD NOT SUPPORTED - NULL, // TODO: OPCODE 0xAE NOT SUPPORTED - NULL, // TODO: OPCODE 0xAF NOT SUPPORTED + Soft386OpcodeStos, + Soft386OpcodeStos, + Soft386OpcodeLods, + Soft386OpcodeLods, + Soft386OpcodeScas, + Soft386OpcodeScas, Soft386OpcodeMovByteRegImm, Soft386OpcodeMovByteRegImm, Soft386OpcodeMovByteRegImm, @@ -5606,3 +5606,263 @@
return TRUE; } + +SOFT386_OPCODE_HANDLER(Soft386OpcodeMovs) +{ + ULONG Data, DataSize; + BOOLEAN OperandSize, AddressSize; + + OperandSize = AddressSize = State->SegmentRegs[SOFT386_REG_CS].Size; + + /* Make sure this is the right instruction */ + ASSERT((Opcode & 0xFE) == 0xA4); + + if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE) + { + /* The OPSIZE prefix toggles the size */ + OperandSize = !OperandSize; + } + + if (State->PrefixFlags & SOFT386_PREFIX_ADSIZE) + { + /* The ADSIZE prefix toggles the size */ + AddressSize = !AddressSize; + } + + if ((State->PrefixFlags & SOFT386_PREFIX_REP) + || (State->PrefixFlags & SOFT386_PREFIX_REPNZ)) + { + // TODO: The REP/REPZ/REPNZ prefixes need to be implemented! + Soft386Exception(State, SOFT386_EXCEPTION_UD); + return FALSE; + } + + /* Calculate the size */ + if (Opcode == 0xA4) DataSize = sizeof(UCHAR); + else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT); + + /* Read from the source operand */ + if (!Soft386ReadMemory(State, + SOFT386_REG_DS, + AddressSize ? State->GeneralRegs[SOFT386_REG_ESI].Long + : State->GeneralRegs[SOFT386_REG_ESI].LowWord, + FALSE, + &Data, + DataSize)) + { + /* Exception occurred */ + return FALSE; + } + + /* Write to the destination operand */ + if (!Soft386WriteMemory(State, + SOFT386_REG_ES, + AddressSize ? State->GeneralRegs[SOFT386_REG_EDI].Long + : State->GeneralRegs[SOFT386_REG_EDI].LowWord, + &Data, + DataSize)) + { + /* Exception occurred */ + return FALSE; + } + + /* Increment/decrement ESI and EDI */ + if (OperandSize) + { + if (State->Flags.Df) + { + State->GeneralRegs[SOFT386_REG_ESI].Long += DataSize; + State->GeneralRegs[SOFT386_REG_EDI].Long += DataSize; + } + else + { + State->GeneralRegs[SOFT386_REG_ESI].Long -= DataSize; + State->GeneralRegs[SOFT386_REG_EDI].Long -= DataSize; + } + } + else + { + if (State->Flags.Df) + { + State->GeneralRegs[SOFT386_REG_ESI].LowWord += DataSize; + State->GeneralRegs[SOFT386_REG_EDI].LowWord += DataSize; + } + else + { + State->GeneralRegs[SOFT386_REG_ESI].LowWord -= DataSize; + State->GeneralRegs[SOFT386_REG_EDI].LowWord -= DataSize; + } + } + + /* Return success */ + return TRUE; +} + +SOFT386_OPCODE_HANDLER(Soft386OpcodeCmps) +{ + UNIMPLEMENTED; + return FALSE; // TODO: NOT IMPLEMENTED +} + +SOFT386_OPCODE_HANDLER(Soft386OpcodeStos) +{ + ULONG DataSize; + BOOLEAN OperandSize, AddressSize; + + OperandSize = AddressSize = State->SegmentRegs[SOFT386_REG_CS].Size; + + /* Make sure this is the right instruction */ + ASSERT((Opcode & 0xFE) == 0xAA); + + if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE) + { + /* The OPSIZE prefix toggles the size */ + OperandSize = !OperandSize; + } + + if (State->PrefixFlags & SOFT386_PREFIX_ADSIZE) + { + /* The ADSIZE prefix toggles the size */ + AddressSize = !AddressSize; + } + + if ((State->PrefixFlags & SOFT386_PREFIX_REP) + || (State->PrefixFlags & SOFT386_PREFIX_REPNZ)) + { + // TODO: The REP/REPZ/REPNZ prefixes need to be implemented! + Soft386Exception(State, SOFT386_EXCEPTION_UD); + return FALSE; + } + + /* Calculate the size */ + if (Opcode == 0xAA) DataSize = sizeof(UCHAR); + else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT); + + /* Write to the destination operand */ + if (!Soft386WriteMemory(State, + SOFT386_REG_ES, + AddressSize ? State->GeneralRegs[SOFT386_REG_EDI].Long + : State->GeneralRegs[SOFT386_REG_EDI].LowWord, + &State->GeneralRegs[SOFT386_REG_EAX].Long, + DataSize)) + { + /* Exception occurred */ + return FALSE; + } + + /* Increment/decrement ESI and EDI */ + if (OperandSize) + { + if (State->Flags.Df) + { + State->GeneralRegs[SOFT386_REG_ESI].Long += DataSize; + State->GeneralRegs[SOFT386_REG_EDI].Long += DataSize; + } + else + { + State->GeneralRegs[SOFT386_REG_ESI].Long -= DataSize; + State->GeneralRegs[SOFT386_REG_EDI].Long -= DataSize; + } + } + else + { + if (State->Flags.Df) + { + State->GeneralRegs[SOFT386_REG_ESI].LowWord += DataSize; + State->GeneralRegs[SOFT386_REG_EDI].LowWord += DataSize; + } + else + { + State->GeneralRegs[SOFT386_REG_ESI].LowWord -= DataSize; + State->GeneralRegs[SOFT386_REG_EDI].LowWord -= DataSize; + } + } + + /* Return success */ + return TRUE; +} + +SOFT386_OPCODE_HANDLER(Soft386OpcodeLods) +{ + ULONG DataSize; + BOOLEAN OperandSize, AddressSize; + + OperandSize = AddressSize = State->SegmentRegs[SOFT386_REG_CS].Size; + + /* Make sure this is the right instruction */ + ASSERT((Opcode & 0xFE) == 0xAC); + + if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE) + { + /* The OPSIZE prefix toggles the size */ + OperandSize = !OperandSize; + } + + if (State->PrefixFlags & SOFT386_PREFIX_ADSIZE) + { + /* The ADSIZE prefix toggles the size */ + AddressSize = !AddressSize; + } + + if ((State->PrefixFlags & SOFT386_PREFIX_REP) + || (State->PrefixFlags & SOFT386_PREFIX_REPNZ)) + { + // TODO: The REP/REPZ/REPNZ prefixes need to be implemented! + Soft386Exception(State, SOFT386_EXCEPTION_UD); + return FALSE; + } + + /* Calculate the size */ + if (Opcode == 0xAC) DataSize = sizeof(UCHAR); + else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT); + + /* Read from the source operand */ + if (!Soft386ReadMemory(State, + SOFT386_REG_DS, + AddressSize ? State->GeneralRegs[SOFT386_REG_ESI].Long + : State->GeneralRegs[SOFT386_REG_ESI].LowWord, + FALSE, + &State->GeneralRegs[SOFT386_REG_EAX].Long, + DataSize)) + { + /* Exception occurred */ + return FALSE; + } + + /* Increment/decrement ESI and EDI */ + if (OperandSize) + { + if (State->Flags.Df) + { + State->GeneralRegs[SOFT386_REG_ESI].Long += DataSize; + State->GeneralRegs[SOFT386_REG_EDI].Long += DataSize; + } + else + { + State->GeneralRegs[SOFT386_REG_ESI].Long -= DataSize; + State->GeneralRegs[SOFT386_REG_EDI].Long -= DataSize; + } + } + else + { + if (State->Flags.Df) + { + State->GeneralRegs[SOFT386_REG_ESI].LowWord += DataSize; + State->GeneralRegs[SOFT386_REG_EDI].LowWord += DataSize; + } + else + { + State->GeneralRegs[SOFT386_REG_ESI].LowWord -= DataSize; + State->GeneralRegs[SOFT386_REG_EDI].LowWord -= DataSize; + } + } + + /* Return success */ + return TRUE; +} + +SOFT386_OPCODE_HANDLER(Soft386OpcodeScas) +{ + UNIMPLEMENTED; + return FALSE; // TODO: NOT IMPLEMENTED +}
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] Thu Oct 3 20:56:36 2013 @@ -148,5 +148,10 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeMovOffsetAl); SOFT386_OPCODE_HANDLER(Soft386OpcodeMovOffsetEax); SOFT386_OPCODE_HANDLER(Soft386OpcodeSalc); +SOFT386_OPCODE_HANDLER(Soft386OpcodeMovs); +SOFT386_OPCODE_HANDLER(Soft386OpcodeCmps); +SOFT386_OPCODE_HANDLER(Soft386OpcodeStos); +SOFT386_OPCODE_HANDLER(Soft386OpcodeLods); +SOFT386_OPCODE_HANDLER(Soft386OpcodeScas);
#endif // _OPCODES_H_