[SOFT386]
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Fri, 18 Oct 2013 22:50:00 +0000 (22:50 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Fri, 18 Oct 2013 22:50:00 +0000 (22:50 +0000)
Implement the hardware interrupt system.
Modify Soft386Interrupt to assume hardware interrupts, because
software interrupts from outside the emulator may cause race conditions.

svn path=/branches/ntvdm/; revision=60696

include/reactos/libs/soft386/soft386.h
lib/soft386/soft386.c
subsystems/ntvdm/emulator.c

index e87810d..4e9bd0b 100644 (file)
@@ -342,6 +342,7 @@ struct _SOFT386_STATE
     ULONG PrefixFlags;
     SOFT386_SEG_REGS SegmentOverride;
     BOOLEAN HardwareInt;
+    UCHAR PendingIntNum;
 };
 
 /* FUNCTIONS ******************************************************************/
@@ -372,7 +373,7 @@ Soft386Reset(PSOFT386_STATE State);
 
 VOID
 NTAPI
-Soft386Interrupt(PSOFT386_STATE State, UCHAR Number, BOOLEAN Hardware);
+Soft386Interrupt(PSOFT386_STATE State, UCHAR Number);
 
 VOID
 NTAPI
index 060ac2c..feca579 100644 (file)
@@ -56,8 +56,30 @@ Soft386ExecutionControl(PSOFT386_STATE State, INT Command)
     /* Main execution loop */
     do
     {
-        /* If this is a new instruction, save the IP */
-        if (State->PrefixFlags == 0) State->SavedInstPtr = State->InstPtr;
+        /* Check if this is a new instruction */
+        if (State->PrefixFlags == 0)
+        {
+            State->SavedInstPtr = State->InstPtr;
+
+            /* Check if interrupts are enabled and there is an interrupt pending */
+            if (State->Flags.If && State->HardwareInt)
+            {
+                SOFT386_IDT_ENTRY IdtEntry;
+
+                /* Get the interrupt vector */
+                if (Soft386GetIntVector(State, State->PendingIntNum, &IdtEntry))
+                {
+                    /* Perform the interrupt */
+                    Soft386InterruptInternal(State,
+                                             IdtEntry.Selector,
+                                             MAKELONG(IdtEntry.Offset, IdtEntry.OffsetHigh),
+                                             IdtEntry.Type);
+                }
+
+                /* Clear the interrupt pending flag */
+                State->HardwareInt = FALSE;
+            }
+        }
 
         /* Perform an instruction fetch */
         if (!Soft386FetchByte(State, &Opcode)) continue;
@@ -273,27 +295,11 @@ Soft386Reset(PSOFT386_STATE State)
 
 VOID
 NTAPI
-Soft386Interrupt(PSOFT386_STATE State, UCHAR Number, BOOLEAN Hardware)
+Soft386Interrupt(PSOFT386_STATE State, UCHAR Number)
 {
-    SOFT386_IDT_ENTRY IdtEntry;
-
-    if (Hardware)
-    {
-        /* Set the hardware interrupt flag */
-        State->HardwareInt = TRUE;
-    }
-
-    if (!Soft386GetIntVector(State, Number, &IdtEntry))
-    {
-        /* An exception occurred, let the handler execute */
-        return;
-    }
-
-    /* Perform the interrupt */
-    Soft386InterruptInternal(State,
-                             IdtEntry.Selector,
-                             MAKELONG(IdtEntry.Offset, IdtEntry.OffsetHigh),
-                             IdtEntry.Type);
+    /* Set the hardware interrupt flag */
+    State->HardwareInt = TRUE;
+    State->PendingIntNum = Number;
 }
 
 VOID
index a9814e1..1c99b57 100644 (file)
@@ -473,7 +473,7 @@ VOID EmulatorInterrupt(BYTE Number)
     softx86_make_simple_interrupt_call(&EmulatorContext, &Segment, &Offset);
 #else
     /* Call the Soft386 API */
-    Soft386Interrupt(&EmulatorContext, Number, FALSE);
+    Soft386Interrupt(&EmulatorContext, Number);
 #endif
 }
 
@@ -484,7 +484,7 @@ VOID EmulatorExternalInterrupt(BYTE Number)
     softx86_ext_hw_signal(&EmulatorContext, Number);
 #else
     /* Call the Soft386 API */
-    Soft386Interrupt(&EmulatorContext, Number, TRUE);
+    Soft386Interrupt(&EmulatorContext, Number);
 #endif
 }