Author: aandrejevic Date: Wed Sep 11 23:31:35 2013 New Revision: 60049
URL: http://svn.reactos.org/svn/reactos?rev=60049&view=rev Log: [SOFT386] Implement PUSHA and POPA.
Modified: branches/ntvdm/lib/soft386/opcodes.c
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] Wed Sep 11 23:31:35 2013 @@ -3485,18 +3485,92 @@
SOFT386_OPCODE_HANDLER(Soft386OpcodePushAll) { - // TODO: NOT IMPLEMENTED - UNIMPLEMENTED; - - return FALSE; + INT i; + BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; + SOFT386_REG SavedEsp = State->GeneralRegs[SOFT386_REG_ESP]; + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0x60); + + if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE) + { + /* The OPSIZE prefix toggles the size */ + Size = !Size; + } + else + { + /* Invalid prefix */ + Soft386Exception(State, SOFT386_EXCEPTION_UD); + return FALSE; + } + + /* Push all the registers in order */ + for (i = 0; i < SOFT386_NUM_GEN_REGS; i++) + { + if (i == SOFT386_REG_ESP) + { + /* Use the saved ESP instead */ + if (!Soft386StackPush(State, Size ? SavedEsp.Long : SavedEsp.LowWord)) + { + /* Exception occurred */ + return FALSE; + } + } + else + { + /* Push the register */ + if (!Soft386StackPush(State, Size ? State->GeneralRegs[i].Long + : State->GeneralRegs[i].LowWord)) + { + /* Exception occurred */ + return FALSE; + } + } + } + + return TRUE; }
SOFT386_OPCODE_HANDLER(Soft386OpcodePopAll) { - // TODO: NOT IMPLEMENTED - UNIMPLEMENTED; - - return FALSE; + INT i; + BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; + ULONG Value; + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0x61); + + if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE) + { + /* The OPSIZE prefix toggles the size */ + Size = !Size; + } + else + { + /* Invalid prefix */ + Soft386Exception(State, SOFT386_EXCEPTION_UD); + return FALSE; + } + + /* Pop all the registers in reverse order */ + for (i = SOFT386_NUM_GEN_REGS - 1; i >= 0; i--) + { + /* Pop the value */ + if (!Soft386StackPop(State, &Value)) + { + /* Exception occurred */ + return FALSE; + } + + /* Don't modify ESP */ + if (i != SOFT386_REG_ESP) + { + if (Size) State->GeneralRegs[i].Long = Value; + else State->GeneralRegs[i].LowWord = LOWORD(Value); + } + } + + return TRUE; }
SOFT386_OPCODE_HANDLER(Soft386OpcodeBound)