From 8d2a19ae5db11c4639781ee16e2ff4499ce31ee1 Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Tue, 15 Oct 2013 17:27:23 +0000 Subject: [PATCH] [SOFT386] Implement far jumps. svn path=/branches/ntvdm/; revision=60679 --- lib/soft386/opcodes.c | 59 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/lib/soft386/opcodes.c b/lib/soft386/opcodes.c index dad7182fb31..e2dac35583b 100644 --- a/lib/soft386/opcodes.c +++ b/lib/soft386/opcodes.c @@ -5690,10 +5690,63 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeJmp) SOFT386_OPCODE_HANDLER(Soft386OpcodeJmpAbs) { - // TODO: NOT IMPLEMENTED - UNIMPLEMENTED; + USHORT Segment = 0; + ULONG Offset = 0; + BOOLEAN Size = State->SegmentRegs[SOFT386_REG_CS].Size; - return FALSE; + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0xEA); + + if (State->PrefixFlags & SOFT386_PREFIX_OPSIZE) + { + /* The OPSIZE prefix toggles the size */ + Size = !Size; + } + + if (State->PrefixFlags & SOFT386_PREFIX_LOCK) + { + /* Invalid prefix */ + Soft386Exception(State, SOFT386_EXCEPTION_UD); + return FALSE; + } + + /* Fetch the offset */ + if (Size) + { + if (!Soft386FetchDword(State, &Offset)) + { + /* Exception occurred */ + return FALSE; + } + } + else + { + if (!Soft386FetchWord(State, (PUSHORT)&Offset)) + { + /* Exception occurred */ + return FALSE; + } + } + + /* Fetch the segment */ + if (!Soft386FetchWord(State, &Segment)) + { + /* Exception occurred */ + return FALSE; + } + + /* Load the new CS */ + if (!Soft386LoadSegment(State, SOFT386_REG_CS, Segment)) + { + /* Exception occurred */ + return FALSE; + } + + /* Load new (E)IP */ + if (Size) State->InstPtr.Long = Offset; + else State->InstPtr.LowWord = LOWORD(Offset); + + return TRUE; } SOFT386_OPCODE_HANDLER(Soft386OpcodeMovAlOffset) -- 2.17.1