Get rid of Fast486Interrupt, since it's not used anywhere. Also we can now remove
workarounds for all of the bugs that it caused.
Implement the "single-instruction interrupt delay" for instructions that load the
stack segment only.
svn path=/trunk/; revision=65061
FAST486_EXCEPTION_MC = 0x12
} FAST486_EXCEPTIONS, *PFAST486_EXCEPTIONS;
-typedef enum _FAST486_INT_STATUS
-{
- FAST486_INT_NONE = 0,
- FAST486_INT_EXECUTE = 1,
- FAST486_INT_SIGNAL = 2,
- FAST486_INT_DELAYED = 3
-} FAST486_INT_STATUS, *PFAST486_INT_STATUS;
-
typedef
VOID
(NTAPI *FAST486_MEM_READ_PROC)
ULONG PrefixFlags;
FAST486_SEG_REGS SegmentOverride;
BOOLEAN Halted;
- FAST486_INT_STATUS IntStatus;
- UCHAR PendingIntNum;
+ BOOLEAN IntSignaled;
+ BOOLEAN DoNotInterrupt;
PULONG Tlb;
#ifndef FAST486_NO_PREFETCH
BOOLEAN PrefetchValid;
NTAPI
Fast486DumpState(PFAST486_STATE State);
-VOID
-NTAPI
-Fast486Interrupt(PFAST486_STATE State, UCHAR Number);
-
VOID
NTAPI
Fast486InterruptSignal(PFAST486_STATE State);
* Check if there is an interrupt to execute, or a hardware interrupt signal
* while interrupts are enabled.
*/
- if (State->Flags.Tf && !State->Halted)
+ if (State->DoNotInterrupt)
+ {
+ /* Clear the interrupt delay flag */
+ State->DoNotInterrupt = FALSE;
+ }
+ else if (State->Flags.Tf && !State->Halted)
{
/* Perform the interrupt */
Fast486PerformInterrupt(State, 0x01);
*/
State->Flags.Tf = FALSE;
}
- else if (State->IntStatus == FAST486_INT_EXECUTE)
+ else if (State->Flags.If && State->IntSignaled)
{
/* No longer halted */
State->Halted = FALSE;
- /* Perform the interrupt */
- Fast486PerformInterrupt(State, State->PendingIntNum);
+ /* Acknowledge the interrupt and perform it */
+ Fast486PerformInterrupt(State, State->IntAckCallback(State));
/* Clear the interrupt status */
- State->IntStatus = FAST486_INT_NONE;
- }
- else if (State->Flags.If && (State->IntStatus == FAST486_INT_SIGNAL))
- {
- /* Acknowledge the interrupt to get the number */
- State->PendingIntNum = State->IntAckCallback(State);
-
- /* Set the interrupt status to execute on the next instruction */
- State->IntStatus = FAST486_INT_EXECUTE;
- }
- else if (State->IntStatus == FAST486_INT_DELAYED)
- {
- /* Restore the old state */
- State->IntStatus = FAST486_INT_EXECUTE;
+ State->IntSignaled = FALSE;
}
}
while ((Command == FAST486_CONTINUE) ||
State->Tlb = Tlb;
}
-VOID
-NTAPI
-Fast486Interrupt(PFAST486_STATE State, UCHAR Number)
-{
- /* Set the interrupt status and the number */
- State->IntStatus = FAST486_INT_EXECUTE;
- State->PendingIntNum = Number;
-}
-
VOID
NTAPI
Fast486InterruptSignal(PFAST486_STATE State)
{
- /* Set the interrupt status */
- State->IntStatus = FAST486_INT_SIGNAL;
+ State->IntSignaled = TRUE;
}
VOID
}
/* Call the internal API */
- Fast486LoadSegment(State, FAST486_REG_SS, LOWORD(NewSelector));
+ if (Fast486LoadSegment(State, FAST486_REG_SS, LOWORD(NewSelector)))
+ {
+ /* Inhibit all interrupts until the next instruction */
+ State->DoNotInterrupt = TRUE;
+ }
}
FAST486_OPCODE_HANDLER(Fast486OpcodeSbbByteModrm)
return;
}
- Fast486LoadSegment(State, ModRegRm.Register, LOWORD(Selector));
+ if (!Fast486LoadSegment(State, ModRegRm.Register, LOWORD(Selector)))
+ {
+ /* Exception occurred */
+ return;
+ }
}
else
{
return;
}
- Fast486LoadSegment(State, ModRegRm.Register, Selector);
+ if (Fast486LoadSegment(State, ModRegRm.Register, Selector))
+ {
+ /* Exception occurred */
+ return;
+ }
+ }
+
+ if ((INT)ModRegRm.Register == FAST486_REG_SS)
+ {
+ /* Inhibit all interrupts until the next instruction */
+ State->DoNotInterrupt = TRUE;
}
}
* changes the CS:IP, the interrupt handler won't execute and the
* stack pointer will never be restored.
*/
- if (State->IntStatus == FAST486_INT_EXECUTE)
- {
- State->IntStatus = FAST486_INT_DELAYED;
- }
+ State->DoNotInterrupt = TRUE;
return;
}
VdmRunning = FALSE;
}
-VOID EmulatorInterrupt(BYTE Number)
-{
- /* Call the Fast486 API */
- Fast486Interrupt(&EmulatorContext, Number);
-}
-
VOID EmulatorInterruptSignal(VOID)
{
/* Call the Fast486 API */
VOID EmulatorTerminate(VOID);
-VOID EmulatorInterrupt(BYTE Number);
VOID EmulatorInterruptSignal(VOID);
VOID EmulatorSetA20(BOOLEAN Enabled);
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
{
- /* Call INT 23h */
- DPRINT1("Ctrl-C/Break: Call INT 23h\n");
- EmulatorInterrupt(0x23);
+ /* HACK: Stop the VDM */
+ EmulatorTerminate();
+
break;
}
case CTRL_LAST_CLOSE_EVENT: