Author: aandrejevic Date: Thu Sep 19 22:48:45 2013 New Revision: 60226
URL: http://svn.reactos.org/svn/reactos?rev=60226&view=rev Log: [SOFT386] Implement JECXZ, LOOP, LOOPZ and LOOPNZ.
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 Sep 19 22:48:45 2013 @@ -248,8 +248,8 @@ NULL, // TODO: OPCODE 0xDD NOT SUPPORTED NULL, // TODO: OPCODE 0xDE NOT SUPPORTED NULL, // TODO: OPCODE 0xDF NOT SUPPORTED - Soft386OpcodeLoopnz, - Soft386OpcodeLoopz, + Soft386OpcodeLoop, + Soft386OpcodeLoop, Soft386OpcodeLoop, Soft386OpcodeJecxz, Soft386OpcodeInByte, @@ -4323,151 +4323,213 @@ return FALSE; }
-SOFT386_OPCODE_HANDLER(Soft386OpcodeLoopnz) +SOFT386_OPCODE_HANDLER(Soft386OpcodeLoop) +{ + BOOLEAN Condition; + BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; + CHAR Offset = 0; + + /* Make sure this is the right instruction */ + ASSERT((Opcode >= 0xE0) && (Opcode <= 0xE2)); + + 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) Condition = ((--State->GeneralRegs[SOFT386_REG_ECX].Long) == 0); + else Condition = ((--State->GeneralRegs[SOFT386_REG_ECX].LowWord) == 0); + + if (Opcode == 0xE0) + { + /* Additional rule for LOOPNZ */ + if (State->Flags.Zf) Condition = FALSE; + } + + if (Opcode == 0xE1) + { + /* Additional rule for LOOPZ */ + if (!State->Flags.Zf) Condition = FALSE; + } + + /* Fetch the offset */ + if (!Soft386FetchByte(State, (PUCHAR)&Offset)) + { + /* An exception occurred */ + return FALSE; + } + + if (Condition) + { + /* Move the instruction pointer */ + State->InstPtr.Long += Offset; + } + + return TRUE; +} + +SOFT386_OPCODE_HANDLER(Soft386OpcodeJecxz) +{ + BOOLEAN Condition; + BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; + CHAR Offset = 0; + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0xE3); + + 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) Condition = (State->GeneralRegs[SOFT386_REG_ECX].Long == 0); + else Condition = (State->GeneralRegs[SOFT386_REG_ECX].LowWord == 0); + + /* Fetch the offset */ + if (!Soft386FetchByte(State, (PUCHAR)&Offset)) + { + /* An exception occurred */ + return FALSE; + } + + if (Condition) + { + /* Move the instruction pointer */ + State->InstPtr.Long += Offset; + } + + return TRUE; +} + +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(Soft386OpcodeLoopz) -{ - // TODO: NOT IMPLEMENTED - UNIMPLEMENTED; - - return FALSE; -} - -SOFT386_OPCODE_HANDLER(Soft386OpcodeLoop) -{ - // TODO: NOT IMPLEMENTED - UNIMPLEMENTED; - - return FALSE; -} - -SOFT386_OPCODE_HANDLER(Soft386OpcodeJecxz) -{ - // 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; -}
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 Sep 19 22:48:45 2013 @@ -130,8 +130,6 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeAam); SOFT386_OPCODE_HANDLER(Soft386OpcodeAad); SOFT386_OPCODE_HANDLER(Soft386OpcodeXlat); -SOFT386_OPCODE_HANDLER(Soft386OpcodeLoopnz); -SOFT386_OPCODE_HANDLER(Soft386OpcodeLoopz); SOFT386_OPCODE_HANDLER(Soft386OpcodeLoop); SOFT386_OPCODE_HANDLER(Soft386OpcodeJecxz); SOFT386_OPCODE_HANDLER(Soft386OpcodeCall);