* Fast486 386/486 CPU Emulation Library
* common.c
*
- * Copyright (C) 2013 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ * Copyright (C) 2014 Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
{
BOOLEAN GateSize = (GateType == FAST486_IDT_INT_GATE_32)
|| (GateType == FAST486_IDT_TRAP_GATE_32);
+ BOOLEAN Success = FALSE;
+ ULONG OldPrefixFlags = State->PrefixFlags;
/* Check for protected mode */
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
sizeof(Tss)))
{
/* Exception occurred */
- return FALSE;
+ goto Cleanup;
}
/* Check the new (higher) privilege level */
if (!Fast486LoadSegment(State, FAST486_REG_SS, Tss.Ss0))
{
/* Exception occurred */
- return FALSE;
+ goto Cleanup;
}
State->GeneralRegs[FAST486_REG_ESP].Long = Tss.Esp0;
if (!Fast486LoadSegment(State, FAST486_REG_SS, Tss.Ss1))
{
/* Exception occurred */
- return FALSE;
+ goto Cleanup;
}
State->GeneralRegs[FAST486_REG_ESP].Long = Tss.Esp1;
if (!Fast486LoadSegment(State, FAST486_REG_SS, Tss.Ss2))
{
/* Exception occurred */
- return FALSE;
+ goto Cleanup;
}
State->GeneralRegs[FAST486_REG_ESP].Long = Tss.Esp2;
}
/* Push SS selector */
- if (!Fast486StackPush(State, OldSs)) return FALSE;
+ if (!Fast486StackPush(State, OldSs)) goto Cleanup;
/* Push stack pointer */
- if (!Fast486StackPush(State, OldEsp)) return FALSE;
+ if (!Fast486StackPush(State, OldEsp)) goto Cleanup;
}
}
else
}
/* Push EFLAGS */
- if (!Fast486StackPush(State, State->Flags.Long)) return FALSE;
+ if (!Fast486StackPush(State, State->Flags.Long)) goto Cleanup;
/* Push CS selector */
- if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_CS].Selector)) return FALSE;
+ if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_CS].Selector)) goto Cleanup;
/* Push the instruction pointer */
- if (!Fast486StackPush(State, State->InstPtr.Long)) return FALSE;
+ if (!Fast486StackPush(State, State->InstPtr.Long)) goto Cleanup;
if ((GateType == FAST486_IDT_INT_GATE) || (GateType == FAST486_IDT_INT_GATE_32))
{
if (!Fast486LoadSegment(State, FAST486_REG_CS, SegmentSelector))
{
/* An exception occurred during the jump */
- return FALSE;
+ goto Cleanup;
}
if (GateSize)
State->InstPtr.LowWord = LOWORD(Offset);
}
- return TRUE;
+ Success = TRUE;
+
+Cleanup:
+ /* Restore the prefix flags */
+ State->PrefixFlags = OldPrefixFlags;
+
+ return Success;
}
VOID
/* Check if this is a triple fault */
if (State->ExceptionCount == 3)
{
+ DPRINT("Fast486ExceptionWithErrorCode(%04X:%08X) -- Triple fault\n",
+ State->SegmentRegs[FAST486_REG_CS].Selector,
+ State->InstPtr.Long);
+
/* Reset the CPU */
Fast486Reset(State);
return;