From: Aleksandar Andrejevic Date: Wed, 16 Oct 2013 03:14:12 +0000 (+0000) Subject: [SOFT386] X-Git-Tag: backups/0.3.17@66124~1365^2~371 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=40ed113494fdbbfeaec2b853835008d0f7b112cf;hp=489dfb314e545b3afe420783fcf3fb4b71a05bf6 [SOFT386] Implement the far absolute indirect JMP/CALL instructions in group 0xFF. svn path=/branches/ntvdm/; revision=60688 --- diff --git a/lib/soft386/opgroups.c b/lib/soft386/opgroups.c index ae40a316b41..c450200ee67 100644 --- a/lib/soft386/opgroups.c +++ b/lib/soft386/opgroups.c @@ -1508,11 +1508,93 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupFF) /* Set the EIP to the address */ State->InstPtr.Long = Value; } + else if (ModRegRm.Register == 3) + { + USHORT Selector; + INT Segment = SOFT386_REG_DS; + + /* Check for the segment override */ + if (State->PrefixFlags & SOFT386_PREFIX_SEG) + { + /* Use the override segment instead */ + Segment = State->SegmentOverride; + } + + /* Read the selector */ + if (!Soft386ReadMemory(State, + Segment, + ModRegRm.MemoryAddress + sizeof(ULONG), + FALSE, + &Selector, + sizeof(USHORT))) + { + /* Exception occurred */ + return FALSE; + } + + /* Push the current value of CS */ + if (!Soft386StackPush(State, State->SegmentRegs[SOFT386_REG_CS].Selector)) + { + /* Exception occurred */ + return FALSE; + } + + /* Push the current value of EIP */ + if (!Soft386StackPush(State, State->InstPtr.Long)) + { + /* Exception occurred */ + return FALSE; + } + + /* Load the new code segment */ + if (!Soft386LoadSegment(State, SOFT386_REG_CS, Selector)) + { + /* Exception occurred */ + return FALSE; + } + + /* Set the EIP to the address */ + State->InstPtr.Long = Value; + } else if (ModRegRm.Register == 4) { /* Set the EIP to the address */ State->InstPtr.Long = Value; } + else if (ModRegRm.Register == 5) + { + USHORT Selector; + INT Segment = SOFT386_REG_DS; + + /* Check for the segment override */ + if (State->PrefixFlags & SOFT386_PREFIX_SEG) + { + /* Use the override segment instead */ + Segment = State->SegmentOverride; + } + + /* Read the selector */ + if (!Soft386ReadMemory(State, + Segment, + ModRegRm.MemoryAddress + sizeof(ULONG), + FALSE, + &Selector, + sizeof(USHORT))) + { + /* Exception occurred */ + return FALSE; + } + + /* Load the new code segment */ + if (!Soft386LoadSegment(State, SOFT386_REG_CS, Selector)) + { + /* Exception occurred */ + return FALSE; + } + + /* Set the EIP to the address */ + State->InstPtr.Long = Value; + } else if (ModRegRm.Register == 6) { /* Push the value on to the stack */ @@ -1569,16 +1651,105 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupFF) /* Set the IP to the address */ State->InstPtr.LowWord = Value; } + else if (ModRegRm.Register == 3) + { + USHORT Selector; + INT Segment = SOFT386_REG_DS; + + /* Check for the segment override */ + if (State->PrefixFlags & SOFT386_PREFIX_SEG) + { + /* Use the override segment instead */ + Segment = State->SegmentOverride; + } + + /* Read the selector */ + if (!Soft386ReadMemory(State, + Segment, + ModRegRm.MemoryAddress + sizeof(USHORT), + FALSE, + &Selector, + sizeof(USHORT))) + { + /* Exception occurred */ + return FALSE; + } + + /* Push the current value of CS */ + if (!Soft386StackPush(State, State->SegmentRegs[SOFT386_REG_CS].Selector)) + { + /* Exception occurred */ + return FALSE; + } + + /* Push the current value of IP */ + if (!Soft386StackPush(State, State->InstPtr.LowWord)) + { + /* Exception occurred */ + return FALSE; + } + + /* Load the new code segment */ + if (!Soft386LoadSegment(State, SOFT386_REG_CS, Selector)) + { + /* Exception occurred */ + return FALSE; + } + + /* Set the IP to the address */ + State->InstPtr.LowWord = Value; + + } else if (ModRegRm.Register == 4) { /* Set the IP to the address */ State->InstPtr.LowWord = Value; } + else if (ModRegRm.Register == 5) + { + USHORT Selector; + INT Segment = SOFT386_REG_DS; + + /* Check for the segment override */ + if (State->PrefixFlags & SOFT386_PREFIX_SEG) + { + /* Use the override segment instead */ + Segment = State->SegmentOverride; + } + + /* Read the selector */ + if (!Soft386ReadMemory(State, + Segment, + ModRegRm.MemoryAddress + sizeof(USHORT), + FALSE, + &Selector, + sizeof(USHORT))) + { + /* Exception occurred */ + return FALSE; + } + + /* Load the new code segment */ + if (!Soft386LoadSegment(State, SOFT386_REG_CS, Selector)) + { + /* Exception occurred */ + return FALSE; + } + + /* Set the IP to the address */ + State->InstPtr.LowWord = Value; + } else if (ModRegRm.Register == 6) { /* Push the value on to the stack */ return Soft386StackPush(State, Value); } + else + { + /* Invalid */ + Soft386Exception(State, SOFT386_EXCEPTION_UD); + return FALSE; + } if (ModRegRm.Register <= 1) { @@ -1595,14 +1766,6 @@ SOFT386_OPCODE_HANDLER(Soft386OpcodeGroupFF) } } - if ((ModRegRm.Register == 3) - || (ModRegRm.Register == 5) - || (ModRegRm.Register == 7)) - { - UNIMPLEMENTED; - return FALSE; // NOT IMPLEMENTED - } - return TRUE; }