[NTVDM]: Limit the number of CPU recursion calls (not more than 32).
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 23 Feb 2014 15:54:20 +0000 (15:54 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 23 Feb 2014 15:54:20 +0000 (15:54 +0000)
svn path=/branches/ntvdm/; revision=62305

subsystems/ntvdm/callback.c
subsystems/ntvdm/clock.c
subsystems/ntvdm/emulator.c

index e1aa80d..03e7f67 100644 (file)
@@ -102,7 +102,7 @@ Call16(IN USHORT Segment,
 
     DPRINT("Call16(0x%04X, 0x%04X)\n", Segment, Offset);
 
-    /* Start simulation */
+    /* Start CPU simulation */
     EmulatorSimulate();
 
     /* Restore CS:IP */
index a6d43f5..74e1fe4 100644 (file)
@@ -59,6 +59,7 @@ INT KeyboardIntCounter = 0;
 
 VOID ClockUpdate(VOID)
 {
+    extern BOOLEAN CpuSimulate;
     UINT i;
 
 #ifdef WORKING_TIMER
@@ -127,7 +128,7 @@ VOID ClockUpdate(VOID)
     VgaHorizontalRetrace();
 
     /* Continue CPU emulation */
-    for (i = 0; (i < STEPS_PER_CYCLE) && VdmRunning; i++)
+    for (i = 0; VdmRunning && CpuSimulate && (i < STEPS_PER_CYCLE); i++)
     {
         EmulatorStep();
 #ifdef IPS_DISPLAY
index 0e5cba8..40f12ed 100644 (file)
 /* PRIVATE VARIABLES **********************************************************/
 
 FAST486_STATE EmulatorContext;
+BOOLEAN CpuSimulate = FALSE;
+
+/* No more than 'MaxCpuCallLevel' recursive CPU calls are allowed */
+const static INT MaxCpuCallLevel = 32;
+static INT CpuCallLevel = 0;
+
 LPVOID  BaseAddress = NULL;
 BOOLEAN VdmRunning  = TRUE;
 
@@ -177,18 +183,31 @@ VOID EmulatorStep(VOID)
 
 VOID EmulatorSimulate(VOID)
 {
-    // FIXME: Do not mix VdmRunning (i.e. ntvdm running) and CpuSimulate!!
-    while (VdmRunning) ClockUpdate();
+    if (CpuCallLevel > MaxCpuCallLevel)
+    {
+        DisplayMessage(L"Too many CPU levels of recursion (%d, expected maximum %d)",
+                       CpuCallLevel, MaxCpuCallLevel);
+
+        /* Stop the VDM */
+        VdmRunning = FALSE;
+        return;
+    }
+    CpuCallLevel++;
+
+    CpuSimulate = TRUE;
+    while (VdmRunning && CpuSimulate) ClockUpdate();
+
+    CpuCallLevel--;
+    if (CpuCallLevel < 0) CpuCallLevel = 0;
 
     /* This takes into account for reentrance */
-    VdmRunning = TRUE;
+    CpuSimulate = TRUE;
 }
 
 VOID EmulatorUnsimulate(VOID)
 {
     /* Stop simulation */
-    // FIXME: Do not mix VdmRunning (i.e. ntvdm running) and CpuSimulate!!
-    VdmRunning = FALSE;
+    CpuSimulate = FALSE;
 }
 
 VOID EmulatorInterrupt(BYTE Number)