Author: aandrejevic Date: Wed Sep 18 21:13:40 2013 New Revision: 60201
URL: http://svn.reactos.org/svn/reactos?rev=60201&view=rev Log: [SOFT386] Implement the LEAVE instruction.
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 18 21:13:40 2013 @@ -4208,13 +4208,58 @@
SOFT386_OPCODE_HANDLER(Soft386OpcodeLeave) { + BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0xC9); + + if (State->PrefixFlags & SOFT386_PREFIX_LOCK) + { + /* Invalid prefix */ + Soft386Exception(State, SOFT386_EXCEPTION_UD); + return FALSE; + } + + if (State->PrefixFlags == SOFT386_PREFIX_OPSIZE) + { + /* The OPSIZE prefix toggles the size */ + Size = !Size; + } + + if (Size) + { + /* Set the stack pointer (ESP) to the base pointer (EBP) */ + State->GeneralRegs[SOFT386_REG_ESP].Long = State->GeneralRegs[SOFT386_REG_EBP].Long; + + /* Pop the saved base pointer from the stack */ + return Soft386StackPop(State, &State->GeneralRegs[SOFT386_REG_EBP].Long); + } + else + { + ULONG Value; + + /* Set the stack pointer (SP) to the base pointer (BP) */ + State->GeneralRegs[SOFT386_REG_ESP].LowWord = State->GeneralRegs[SOFT386_REG_EBP].LowWord; + + /* Pop the saved base pointer from the stack */ + if (Soft386StackPop(State, &Value)) + { + State->GeneralRegs[SOFT386_REG_EBP].LowWord = LOWORD(Value); + return TRUE; + } + else return FALSE; + } +} + +SOFT386_OPCODE_HANDLER(Soft386OpcodeRetFarImm) +{ // TODO: NOT IMPLEMENTED UNIMPLEMENTED;
return FALSE; }
-SOFT386_OPCODE_HANDLER(Soft386OpcodeRetFarImm) +SOFT386_OPCODE_HANDLER(Soft386OpcodeRetFar) { // TODO: NOT IMPLEMENTED UNIMPLEMENTED; @@ -4222,7 +4267,7 @@ return FALSE; }
-SOFT386_OPCODE_HANDLER(Soft386OpcodeRetFar) +SOFT386_OPCODE_HANDLER(Soft386OpcodeInt3) { // TODO: NOT IMPLEMENTED UNIMPLEMENTED; @@ -4230,7 +4275,7 @@ return FALSE; }
-SOFT386_OPCODE_HANDLER(Soft386OpcodeInt3) +SOFT386_OPCODE_HANDLER(Soft386OpcodeInt) { // TODO: NOT IMPLEMENTED UNIMPLEMENTED; @@ -4238,7 +4283,7 @@ return FALSE; }
-SOFT386_OPCODE_HANDLER(Soft386OpcodeInt) +SOFT386_OPCODE_HANDLER(Soft386OpcodeIntOverflow) { // TODO: NOT IMPLEMENTED UNIMPLEMENTED; @@ -4246,7 +4291,7 @@ return FALSE; }
-SOFT386_OPCODE_HANDLER(Soft386OpcodeIntOverflow) +SOFT386_OPCODE_HANDLER(Soft386OpcodeIret) { // TODO: NOT IMPLEMENTED UNIMPLEMENTED; @@ -4254,7 +4299,7 @@ return FALSE; }
-SOFT386_OPCODE_HANDLER(Soft386OpcodeIret) +SOFT386_OPCODE_HANDLER(Soft386OpcodeAam) { // TODO: NOT IMPLEMENTED UNIMPLEMENTED; @@ -4262,7 +4307,7 @@ return FALSE; }
-SOFT386_OPCODE_HANDLER(Soft386OpcodeAam) +SOFT386_OPCODE_HANDLER(Soft386OpcodeAad) { // TODO: NOT IMPLEMENTED UNIMPLEMENTED; @@ -4270,7 +4315,7 @@ return FALSE; }
-SOFT386_OPCODE_HANDLER(Soft386OpcodeAad) +SOFT386_OPCODE_HANDLER(Soft386OpcodeXlat) { // TODO: NOT IMPLEMENTED UNIMPLEMENTED; @@ -4278,7 +4323,7 @@ return FALSE; }
-SOFT386_OPCODE_HANDLER(Soft386OpcodeXlat) +SOFT386_OPCODE_HANDLER(Soft386OpcodeLoopnz) { // TODO: NOT IMPLEMENTED UNIMPLEMENTED; @@ -4286,7 +4331,7 @@ return FALSE; }
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLoopnz) +SOFT386_OPCODE_HANDLER(Soft386OpcodeLoopz) { // TODO: NOT IMPLEMENTED UNIMPLEMENTED; @@ -4294,7 +4339,7 @@ return FALSE; }
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLoopz) +SOFT386_OPCODE_HANDLER(Soft386OpcodeLoop) { // TODO: NOT IMPLEMENTED UNIMPLEMENTED; @@ -4302,7 +4347,7 @@ return FALSE; }
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLoop) +SOFT386_OPCODE_HANDLER(Soft386OpcodeJecxz) { // TODO: NOT IMPLEMENTED UNIMPLEMENTED; @@ -4310,127 +4355,119 @@ return FALSE; }
-SOFT386_OPCODE_HANDLER(Soft386OpcodeJecxz) +SOFT386_OPCODE_HANDLER(Soft386OpcodeCall) +{ + BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0xE8); + + 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; + } + + /* Push the current value of the instruction pointer */ + if (!Soft386StackPush(State, State->InstPtr.Long)) + { + /* Exception occurred */ + return FALSE; + } + + if (Size) + { + LONG Offset = 0; + + /* Fetch the offset */ + if (!Soft386FetchDword(State, (PULONG)&Offset)) + { + /* An exception occurred */ + return FALSE; + } + + /* Move the instruction pointer */ + State->InstPtr.Long += Offset; + } + else + { + SHORT Offset = 0; + + /* Fetch the offset */ + if (!Soft386FetchWord(State, (PUSHORT)&Offset)) + { + /* An exception occurred */ + return FALSE; + } + + /* Move the instruction pointer */ + State->InstPtr.LowWord += Offset; + } + + return TRUE; +} + +SOFT386_OPCODE_HANDLER(Soft386OpcodeJmp) +{ + BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0xE9); + + 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; + } + + if (Size) + { + LONG Offset = 0; + + /* Fetch the offset */ + if (!Soft386FetchDword(State, (PULONG)&Offset)) + { + /* An exception occurred */ + return FALSE; + } + + /* Move the instruction pointer */ + State->InstPtr.Long += Offset; + } + else + { + SHORT Offset = 0; + + /* Fetch the offset */ + if (!Soft386FetchWord(State, (PUSHORT)&Offset)) + { + /* An exception occurred */ + return FALSE; + } + + /* Move the instruction pointer */ + State->InstPtr.LowWord += Offset; + } + + return TRUE; +} + +SOFT386_OPCODE_HANDLER(Soft386OpcodeJmpAbs) { // TODO: NOT IMPLEMENTED UNIMPLEMENTED;
return FALSE; } - -SOFT386_OPCODE_HANDLER(Soft386OpcodeCall) -{ - BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; - - /* Make sure this is the right instruction */ - ASSERT(Opcode == 0xE8); - - 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; - } - - /* Push the current value of the instruction pointer */ - if (!Soft386StackPush(State, State->InstPtr.Long)) - { - /* Exception occurred */ - return FALSE; - } - - if (Size) - { - LONG Offset = 0; - - /* Fetch the offset */ - if (!Soft386FetchDword(State, (PULONG)&Offset)) - { - /* An exception occurred */ - return FALSE; - } - - /* Move the instruction pointer */ - State->InstPtr.Long += Offset; - } - else - { - SHORT Offset = 0; - - /* Fetch the offset */ - if (!Soft386FetchWord(State, (PUSHORT)&Offset)) - { - /* An exception occurred */ - return FALSE; - } - - /* Move the instruction pointer */ - State->InstPtr.LowWord += Offset; - } - - return TRUE; -} - -SOFT386_OPCODE_HANDLER(Soft386OpcodeJmp) -{ - BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; - - /* Make sure this is the right instruction */ - ASSERT(Opcode == 0xE9); - - 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; - } - - if (Size) - { - LONG Offset = 0; - - /* Fetch the offset */ - if (!Soft386FetchDword(State, (PULONG)&Offset)) - { - /* An exception occurred */ - return FALSE; - } - - /* Move the instruction pointer */ - State->InstPtr.Long += Offset; - } - else - { - SHORT Offset = 0; - - /* Fetch the offset */ - if (!Soft386FetchWord(State, (PUSHORT)&Offset)) - { - /* An exception occurred */ - return FALSE; - } - - /* Move the instruction pointer */ - State->InstPtr.LowWord += Offset; - } - - return TRUE; -} - -SOFT386_OPCODE_HANDLER(Soft386OpcodeJmpAbs) -{ - // TODO: NOT IMPLEMENTED - UNIMPLEMENTED; - - return FALSE; -}