[NTVDM]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Tue, 30 Sep 2014 23:47:23 +0000 (23:47 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Tue, 30 Sep 2014 23:47:23 +0000 (23:47 +0000)
Code reorganization: Move CPU code to specific files for modularity (prepares ground for some future work).
We reintroduce also int32.c in which all the int32 handling code is moved to.
Part 1/2

svn path=/trunk/; revision=64429

28 files changed:
reactos/subsystems/ntvdm/CMakeLists.txt
reactos/subsystems/ntvdm/bios/bios.c
reactos/subsystems/ntvdm/bios/bios32/bios32.c
reactos/subsystems/ntvdm/bios/bios32/bios32p.h
reactos/subsystems/ntvdm/bios/bios32/kbdbios32.c
reactos/subsystems/ntvdm/bios/bios32/moubios32.c
reactos/subsystems/ntvdm/bios/bios32/vidbios32.c
reactos/subsystems/ntvdm/bios/kbdbios.c
reactos/subsystems/ntvdm/bios/rom.c
reactos/subsystems/ntvdm/bios/vidbios.c
reactos/subsystems/ntvdm/callback.c [deleted file]
reactos/subsystems/ntvdm/clock.c
reactos/subsystems/ntvdm/cpu/bop.c [moved from reactos/subsystems/ntvdm/bop.c with 100% similarity]
reactos/subsystems/ntvdm/cpu/bop.h [moved from reactos/subsystems/ntvdm/bop.h with 100% similarity]
reactos/subsystems/ntvdm/cpu/callback.c [new file with mode: 0644]
reactos/subsystems/ntvdm/cpu/callback.h [moved from reactos/subsystems/ntvdm/callback.h with 61% similarity]
reactos/subsystems/ntvdm/cpu/cpu.c [new file with mode: 0644]
reactos/subsystems/ntvdm/cpu/cpu.h [new file with mode: 0644]
reactos/subsystems/ntvdm/dos/dem.c
reactos/subsystems/ntvdm/dos/dos32krnl/bios.c
reactos/subsystems/ntvdm/dos/dos32krnl/dos.h
reactos/subsystems/ntvdm/dos/mouse32.c
reactos/subsystems/ntvdm/emulator.c
reactos/subsystems/ntvdm/emulator.h
reactos/subsystems/ntvdm/int32.c
reactos/subsystems/ntvdm/int32.h
reactos/subsystems/ntvdm/registers.c
reactos/subsystems/ntvdm/vddsup.c

index 92b03b4..2793b0b 100644 (file)
@@ -14,6 +14,9 @@ list(APPEND SOURCE
     bios/kbdbios.c
     bios/rom.c
     bios/vidbios.c
+    cpu/bop.c
+    cpu/callback.c
+    cpu/cpu.c
     hardware/cmos.c
     hardware/keyboard.c
     hardware/mouse.c
@@ -27,10 +30,9 @@ list(APPEND SOURCE
     dos/dos32krnl/dosfiles.c
     dos/mouse32.c
     dos/dem.c
-    bop.c
-    callback.c
     clock.c
     emulator.c
+    int32.c
     io.c
     registers.c
     utils.c
index accd3f1..ad04e48 100644 (file)
@@ -11,8 +11,8 @@
 #define NDEBUG
 
 #include "emulator.h"
-#include "callback.h"
-#include "bop.h"
+#include "cpu/callback.h"
+#include "cpu/bop.h"
 
 #include "bios.h"
 #include "bios32/bios32.h"
index f6138d9..46d139f 100644 (file)
@@ -14,8 +14,9 @@
 #include <reactos/buildno.h>
 
 #include "emulator.h"
-#include "callback.h"
-#include "bop.h"
+#include "cpu/cpu.h" // for EMULATOR_FLAG_CF
+#include "int32.h"
+// #include "bop.h"
 
 #include "../bios.h"
 #include "../rom.h"
index 3ffd39d..060f0f7 100644 (file)
@@ -14,7 +14,7 @@
 #include "ntvdm.h"
 #include "../bios.h"
 
-/**/ #include "callback.h" /**/
+/**/ #include "int32.h" /**/
 
 /* DEFINES ********************************************************************/
 
index 7ef9a8b..db9ba5a 100644 (file)
@@ -11,7 +11,8 @@
 #define NDEBUG
 
 #include "emulator.h"
-#include "callback.h"
+#include "cpu/cpu.h" // for EMULATOR_FLAG_ZF
+#include "int32.h"
 
 #include "kbdbios32.h"
 #include "../kbdbios.h"
index 720182c..235709e 100644 (file)
@@ -11,7 +11,6 @@
 #define NDEBUG
 
 #include "emulator.h"
-#include "callback.h"
 
 #include "moubios32.h"
 #include "bios32p.h"
index 732776c..9778381 100644 (file)
@@ -13,7 +13,7 @@
 #define NDEBUG
 
 #include "emulator.h"
-#include "callback.h"
+#include "int32.h"
 
 #include "vidbios32.h"
 #include "../vidbios.h"
index 7255086..007d256 100644 (file)
@@ -11,8 +11,7 @@
 #define NDEBUG
 
 #include "emulator.h"
-#include "callback.h"
-#include "bop.h"
+#include "cpu/bop.h"
 
 #include "bios.h"
 // #include "kbdbios.h"
index e4dbc6b..52864c1 100644 (file)
@@ -11,7 +11,7 @@
 #define NDEBUG
 
 #include "emulator.h"
-#include "callback.h"
+#include "cpu/callback.h"
 #include "utils.h"
 
 #include "rom.h"
index 444e7e1..b7ccc17 100644 (file)
@@ -12,8 +12,8 @@
 #define NDEBUG
 
 #include "emulator.h"
-#include "callback.h"
-#include "bop.h"
+#include "cpu/cpu.h"
+#include "cpu/bop.h"
 
 #include "bios.h"
 // #include "vidbios.h"
diff --git a/reactos/subsystems/ntvdm/callback.c b/reactos/subsystems/ntvdm/callback.c
deleted file mode 100644 (file)
index 47bacbb..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * COPYRIGHT:       GPL - See COPYING in the top level directory
- * PROJECT:         ReactOS Virtual DOS Machine
- * FILE:            callback.c
- * PURPOSE:         16 and 32-bit Callbacks Support
- * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
- *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
- */
-
-/******************************************************************************\
-|   WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
-|
-|   Callbacks support supposes implicitely that the callbacks are used
-|   in the SAME thread as the CPU thread, otherwise messing in parallel
-|   with the CPU registers is 100% prone to bugs!!
-\******************************************************************************/
-
-/* INCLUDES *******************************************************************/
-
-#define NDEBUG
-
-#include "emulator.h"
-#include "callback.h"
-
-#include "bop.h"
-#include <isvbop.h>
-
-/* PRIVATE VARIABLES **********************************************************/
-
-/*
- * This is the list of registered 32-bit Interrupt handlers.
- */
-static EMULATOR_INT32_PROC Int32Proc[EMULATOR_MAX_INT32_NUM] = { NULL };
-
-/* BOP Identifiers */
-#define BOP_CONTROL             0xFF    // Control BOP Handler
-    #define BOP_CONTROL_DEFFUNC 0x00    // Default Control BOP Function
-    #define BOP_CONTROL_INT32   0xFF    // 32-bit Interrupt dispatcher
-                                        // function code for the Control BOP Handler
-
-#define BOP(num)            LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), (num)
-#define UnSimulate16(trap)           \
-do {                                 \
-    *(PUSHORT)(trap) = EMULATOR_BOP; \
-    (trap) += sizeof(USHORT);        \
-    *(trap) = BOP_UNSIMULATE;        \
-} while(0)
-// #define UnSimulate16        MAKELONG(EMULATOR_BOP, BOP_UNSIMULATE) // BOP(BOP_UNSIMULATE)
-
-#define CALL16_TRAMPOLINE_SIZE  (1 * sizeof(ULONGLONG))
-#define  INT16_TRAMPOLINE_SIZE  (1 * sizeof(ULONGLONG))
-
-//
-// WARNING WARNING!!
-//
-// If you modify the code stubs here, think also
-// about updating them in int32.c too!!
-//
-
-/* 16-bit generic interrupt code for calling a 32-bit interrupt handler */
-static BYTE Int16To32[] =
-{
-    0xFA,               // cli
-
-    /* Push the value of the interrupt to be called */
-    0x6A, 0xFF,         // push i (patchable to 0x6A, 0xIntNum)
-
-    /* The BOP Sequence */
-// BOP_SEQ:
-    0xF8,               // clc
-    BOP(BOP_CONTROL),   // Control BOP
-    BOP_CONTROL_INT32,  // 32-bit Interrupt dispatcher
-
-    0x73, 0x04,         // jnc EXIT (offset +4)
-
-    0xFB,               // sti
-
-    // HACK: The following instruction should be HLT!
-    0x90,               // nop
-
-    0xEB, 0xF5,         // jmp BOP_SEQ (offset -11)
-
-// EXIT:
-    0x44, 0x44,         // inc sp, inc sp
-    0xCF,               // iret
-};
-const ULONG Int16To32StubSize = sizeof(Int16To32);
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-VOID
-InitializeContext(IN PCALLBACK16 Context,
-                  IN USHORT      Segment,
-                  IN USHORT      Offset)
-{
-    Context->TrampolineFarPtr = MAKELONG(Offset, Segment);
-    Context->TrampolineSize   = max(CALL16_TRAMPOLINE_SIZE,
-                                     INT16_TRAMPOLINE_SIZE);
-    Context->Segment          = Segment;
-    Context->NextOffset       = Offset + Context->TrampolineSize;
-}
-
-VOID
-Call16(IN USHORT Segment,
-       IN USHORT Offset)
-{
-    /* Save CS:IP */
-    USHORT OrgCS = getCS();
-    USHORT OrgIP = getIP();
-
-    /* Set the new CS:IP */
-    setCS(Segment);
-    setIP(Offset);
-
-    DPRINT("Call16(%04X:%04X)\n", Segment, Offset);
-
-    /* Start CPU simulation */
-    EmulatorSimulate();
-
-    /* Restore CS:IP */
-    setCS(OrgCS);
-    setIP(OrgIP);
-}
-
-
-
-ULONG
-RegisterCallback16(IN  ULONG   FarPtr,
-                   IN  LPBYTE  CallbackCode,
-                   IN  SIZE_T  CallbackSize,
-                   OUT PSIZE_T CodeSize OPTIONAL)
-{
-    LPBYTE CodeStart = (LPBYTE)FAR_POINTER(FarPtr);
-    LPBYTE Code      = CodeStart;
-
-    SIZE_T OurCodeSize = CallbackSize;
-
-    if (CallbackCode == NULL) CallbackSize = 0;
-
-    if (CallbackCode)
-    {
-        /* 16-bit interrupt code */
-        RtlCopyMemory(Code, CallbackCode, CallbackSize);
-        Code += CallbackSize;
-    }
-
-    /* Return the real size of the code if needed */
-    if (CodeSize) *CodeSize = OurCodeSize; // == (ULONG_PTR)Code - (ULONG_PTR)CodeStart;
-
-    // /* Return the entry-point address for 32-bit calls */
-    // return (ULONG_PTR)(CodeStart + CallbackSize);
-    return OurCodeSize;
-}
-
-VOID
-RunCallback16(IN PCALLBACK16 Context,
-              IN ULONG       FarPtr)
-{
-    PUCHAR TrampolineBase = (PUCHAR)FAR_POINTER(Context->TrampolineFarPtr);
-    PUCHAR Trampoline     = TrampolineBase;
-    UCHAR  OldTrampoline[CALL16_TRAMPOLINE_SIZE];
-
-    /* Save the old trampoline */
-    ((PULONGLONG)&OldTrampoline)[0] = ((PULONGLONG)TrampolineBase)[0];
-
-    DPRINT1("RunCallback16(0x%p)\n", FarPtr);
-
-    /* Build the generic entry-point for 16-bit far calls */
-    *Trampoline++ = 0x9A; // Call far seg:off
-    *(PULONG)Trampoline = FarPtr;
-    Trampoline += sizeof(ULONG);
-    UnSimulate16(Trampoline);
-
-    /* Perform the call */
-    Call16(HIWORD(Context->TrampolineFarPtr),
-           LOWORD(Context->TrampolineFarPtr));
-
-    /* Restore the old trampoline */
-    ((PULONGLONG)TrampolineBase)[0] = ((PULONGLONG)&OldTrampoline)[0];
-}
-
-
-
-ULONG
-RegisterInt16(IN  ULONG   FarPtr,
-              IN  BYTE    IntNumber,
-              IN  LPBYTE  CallbackCode,
-              IN  SIZE_T  CallbackSize,
-              OUT PSIZE_T CodeSize OPTIONAL)
-{
-    /* Get a pointer to the IVT and set the corresponding entry (far pointer) */
-    LPDWORD IntVecTable = (LPDWORD)SEG_OFF_TO_PTR(0x0000, 0x0000);
-    IntVecTable[IntNumber] = FarPtr;
-
-    /* Register the 16-bit callback */
-    return RegisterCallback16(FarPtr,
-                              CallbackCode,
-                              CallbackSize,
-                              CodeSize);
-}
-
-ULONG
-RegisterInt32(IN  ULONG   FarPtr,
-              IN  BYTE    IntNumber,
-              IN  EMULATOR_INT32_PROC IntHandler,
-              OUT PSIZE_T CodeSize OPTIONAL)
-{
-    /* Array for holding our copy of the 16-bit interrupt callback */
-    BYTE IntCallback[sizeof(Int16To32)/sizeof(BYTE)];
-
-    /* Check whether the 32-bit interrupt was already registered */
-#if 0
-    if (Int32Proc[IntNumber] != NULL)
-    {
-        DPRINT1("RegisterInt32: Interrupt 0x%02X already registered!\n", IntNumber);
-        return 0;
-    }
-#endif
-
-    /* Register the 32-bit interrupt handler */
-    Int32Proc[IntNumber] = IntHandler;
-
-    /* Copy the generic 16-bit interrupt callback and patch it */
-    RtlCopyMemory(IntCallback, Int16To32, sizeof(Int16To32));
-    IntCallback[2] = IntNumber;
-
-    /* Register the 16-bit interrupt callback */
-    return RegisterInt16(FarPtr,
-                         IntNumber,
-                         IntCallback,
-                         sizeof(IntCallback),
-                         CodeSize);
-}
-
-VOID
-Int32Call(IN PCALLBACK16 Context,
-          IN BYTE IntNumber)
-{
-    PUCHAR TrampolineBase = (PUCHAR)FAR_POINTER(Context->TrampolineFarPtr);
-    PUCHAR Trampoline     = TrampolineBase;
-    UCHAR  OldTrampoline[INT16_TRAMPOLINE_SIZE];
-
-    DPRINT("Int32Call(0x%02X)\n", IntNumber);
-
-    /* Save the old trampoline */
-    ((PULONGLONG)&OldTrampoline)[0] = ((PULONGLONG)TrampolineBase)[0];
-
-    /* Build the generic entry-point for 16-bit calls */
-    if (IntNumber == 0x03)
-    {
-        /* We are redefining for INT 03h */
-        *Trampoline++ = 0xCC; // Call INT 03h
-        /** *Trampoline++ = 0x90; // nop **/
-    }
-    else
-    {
-        /* Normal interrupt */
-        *Trampoline++ = 0xCD; // Call INT XXh
-        *Trampoline++ = IntNumber;
-    }
-    UnSimulate16(Trampoline);
-
-    /* Perform the call */
-    Call16(HIWORD(Context->TrampolineFarPtr),
-           LOWORD(Context->TrampolineFarPtr));
-
-    /* Restore the old trampoline */
-    ((PULONGLONG)TrampolineBase)[0] = ((PULONGLONG)&OldTrampoline)[0];
-}
-
-
-
-VOID WINAPI Int32Dispatch(LPWORD Stack)
-{
-    /* Get the interrupt number */
-    BYTE IntNum = LOBYTE(Stack[STACK_INT_NUM]);
-
-    /* Call the 32-bit Interrupt handler */
-    if (Int32Proc[IntNum] != NULL)
-        Int32Proc[IntNum](Stack);
-    else
-        DPRINT1("Unhandled 32-bit interrupt: 0x%02X, AX = 0x%04X\n", IntNum, getAX());
-}
-
-static VOID WINAPI ControlBop(LPWORD Stack)
-{
-    /* Get the Function Number and skip it */
-    BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
-    setIP(getIP() + 1);
-
-    switch (FuncNum)
-    {
-        case BOP_CONTROL_INT32:
-            Int32Dispatch(Stack);
-            break;
-
-        default:
-            // DPRINT1("Unassigned Control BOP Function: 0x%02X\n", FuncNum);
-            DisplayMessage(L"Unassigned Control BOP Function: 0x%02X", FuncNum);
-            break;
-    }
-}
-
-VOID InitializeCallbacks(VOID)
-{
-    /* Register the Control BOP */
-    RegisterBop(BOP_CONTROL, ControlBop);
-}
-
-/* EOF */
index c283d32..46241f4 100644 (file)
@@ -12,6 +12,7 @@
 #define NDEBUG
 
 #include "emulator.h"
+#include "cpu/cpu.h"
 
 // #include "clock.h"
 
@@ -62,7 +63,7 @@ UINT Irq12Counter = 0;
 
 VOID ClockUpdate(VOID)
 {
-    extern BOOLEAN CpuSimulate;
+    extern BOOLEAN CpuRunning;
     UINT i;
 
 #ifdef WORKING_TIMER
@@ -137,9 +138,9 @@ VOID ClockUpdate(VOID)
     VgaHorizontalRetrace();
 
     /* Continue CPU emulation */
-    for (i = 0; VdmRunning && CpuSimulate && (i < STEPS_PER_CYCLE); i++)
+    for (i = 0; VdmRunning && CpuRunning && (i < STEPS_PER_CYCLE); i++)
     {
-        EmulatorStep();
+        CpuStep();
 #ifdef IPS_DISPLAY
         Cycles++;
 #endif
diff --git a/reactos/subsystems/ntvdm/cpu/callback.c b/reactos/subsystems/ntvdm/cpu/callback.c
new file mode 100644 (file)
index 0000000..0a71e88
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * PROJECT:         ReactOS Virtual DOS Machine
+ * FILE:            callback.c
+ * PURPOSE:         16 and 32-bit Callbacks Support
+ * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
+ */
+
+/******************************************************************************\
+|   WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
+|
+|   Callbacks support supposes implicitely that the callbacks are used
+|   in the SAME thread as the CPU thread, otherwise messing in parallel
+|   with the CPU registers is 100% prone to bugs!!
+\******************************************************************************/
+
+/* INCLUDES *******************************************************************/
+
+#define NDEBUG
+
+#include "cpu.h"
+#include "callback.h"
+#include "emulator.h"
+
+#include "bop.h"
+#include <isvbop.h>
+
+/* PRIVATE VARIABLES **********************************************************/
+
+#define TRAMPOLINE_SIZE sizeof(ULONGLONG)
+
+static BYTE Yield[] =
+{
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90,         // 13x nop
+    BOP(BOP_UNSIMULATE),                        // UnSimulate16 BOP
+};
+C_ASSERT(sizeof(Yield) == 16 * sizeof(BYTE));
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+VOID
+InitializeContextEx(IN PCALLBACK16 Context,
+                    IN ULONG       TrampolineSize,
+                    IN USHORT      Segment,
+                    IN USHORT      Offset)
+{
+    Context->TrampolineFarPtr = MAKELONG(Offset, Segment);
+    Context->TrampolineSize   = max(TRAMPOLINE_SIZE, TrampolineSize);
+    Context->Segment          = Segment;
+    Context->NextOffset       = Offset + Context->TrampolineSize;
+}
+
+VOID
+InitializeContext(IN PCALLBACK16 Context,
+                  IN USHORT      Segment,
+                  IN USHORT      Offset)
+{
+    InitializeContextEx(Context,
+                        TRAMPOLINE_SIZE,
+                        Segment,
+                        Offset);
+}
+
+VOID
+Call16(IN USHORT Segment,
+       IN USHORT Offset)
+{
+    /* Save CS:IP */
+    USHORT OrgCS = getCS();
+    USHORT OrgIP = getIP();
+
+    /* Set the new CS:IP */
+    setCS(Segment);
+    setIP(Offset);
+
+    DPRINT("Call16(%04X:%04X)\n", Segment, Offset);
+
+    /* Start CPU simulation */
+    CpuSimulate();
+
+    /* Restore CS:IP */
+    setCS(OrgCS);
+    setIP(OrgIP);
+}
+
+VOID
+RunCallback16(IN PCALLBACK16 Context,
+              IN ULONG       FarPtr)
+{
+    PUCHAR TrampolineBase = (PUCHAR)FAR_POINTER(Context->TrampolineFarPtr);
+    PUCHAR Trampoline     = TrampolineBase;
+    UCHAR  OldTrampoline[TRAMPOLINE_SIZE];
+
+    /* Save the old trampoline */
+    ((PULONGLONG)&OldTrampoline)[0] = ((PULONGLONG)TrampolineBase)[0];
+
+    DPRINT("RunCallback16(0x%p)\n", FarPtr);
+
+    /* Build the generic entry-point for 16-bit far calls */
+    *Trampoline++ = 0x9A; // Call far seg:off
+    *(PULONG)Trampoline = FarPtr;
+    Trampoline += sizeof(ULONG);
+    UnSimulate16(Trampoline);
+
+    /* Perform the call */
+    Call16(HIWORD(Context->TrampolineFarPtr),
+           LOWORD(Context->TrampolineFarPtr));
+
+    /* Restore the old trampoline */
+    ((PULONGLONG)TrampolineBase)[0] = ((PULONGLONG)&OldTrampoline)[0];
+}
+
+ULONG
+RegisterCallback16(IN  ULONG   FarPtr,
+                   IN  LPBYTE  CallbackCode,
+                   IN  SIZE_T  CallbackSize,
+                   OUT PSIZE_T CodeSize OPTIONAL)
+{
+    LPBYTE CodeStart = (LPBYTE)FAR_POINTER(FarPtr);
+    LPBYTE Code      = CodeStart;
+
+    SIZE_T OurCodeSize = CallbackSize;
+
+    if (CallbackCode == NULL) CallbackSize = 0;
+
+    if (CallbackCode)
+    {
+        /* 16-bit interrupt code */
+        RtlCopyMemory(Code, CallbackCode, CallbackSize);
+        Code += CallbackSize;
+    }
+
+    /* Return the real size of the code if needed */
+    if (CodeSize) *CodeSize = OurCodeSize; // == (ULONG_PTR)Code - (ULONG_PTR)CodeStart;
+
+    // /* Return the entry-point address for 32-bit calls */
+    // return (ULONG_PTR)(CodeStart + CallbackSize);
+    return OurCodeSize;
+}
+
+/* EOF */
similarity index 61%
rename from reactos/subsystems/ntvdm/callback.h
rename to reactos/subsystems/ntvdm/cpu/callback.h
index 264e67f..265669f 100644 (file)
 
 /* DEFINES ********************************************************************/
 
-/* 32-bit Interrupt Identifiers */
-#define EMULATOR_MAX_INT32_NUM  0xFF + 1
+#define BOP(num)            LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), (num)
+#define UnSimulate16(trap)           \
+do {                                 \
+    *(PUSHORT)(trap) = EMULATOR_BOP; \
+    (trap) += sizeof(USHORT);        \
+    *(trap) = BOP_UNSIMULATE;        \
+} while(0)
+// #define UnSimulate16        MAKELONG(EMULATOR_BOP, BOP_UNSIMULATE) // BOP(BOP_UNSIMULATE)
 
 typedef struct _CALLBACK16
 {
@@ -23,11 +29,23 @@ typedef struct _CALLBACK16
     USHORT NextOffset;
 } CALLBACK16, *PCALLBACK16;
 
-extern const ULONG Int16To32StubSize;
+//
+// WARNING WARNING!!
+// If you're changing the indices here, you then need to
+// also fix the BOP code in callback.c !!!!!!!!!!!!!!!!!
+//
+#define STACK_INT_NUM   0
+#define STACK_IP        1
+#define STACK_CS        2
+#define STACK_FLAGS     3
 
 /* FUNCTIONS ******************************************************************/
 
-typedef VOID (WINAPI *EMULATOR_INT32_PROC)(LPWORD Stack);
+VOID
+InitializeContextEx(IN PCALLBACK16 Context,
+                    IN ULONG       TrampolineSize,
+                    IN USHORT      Segment,
+                    IN USHORT      Offset);
 
 VOID
 InitializeContext(IN PCALLBACK16 Context,
@@ -38,35 +56,15 @@ VOID
 Call16(IN USHORT Segment,
        IN USHORT Offset);
 
-ULONG
-RegisterCallback16(IN  ULONG   FarPtr,
-                   IN  LPBYTE  CallbackCode,
-                   IN  SIZE_T  CallbackSize,
-                   OUT PSIZE_T CodeSize OPTIONAL);
-
 VOID
 RunCallback16(IN PCALLBACK16 Context,
               IN ULONG       FarPtr);
 
 ULONG
-RegisterInt16(IN  ULONG   FarPtr,
-              IN  BYTE    IntNumber,
-              IN  LPBYTE  CallbackCode,
-              IN  SIZE_T  CallbackSize,
-              OUT PSIZE_T CodeSize OPTIONAL);
-
-ULONG
-RegisterInt32(IN  ULONG   FarPtr,
-              IN  BYTE    IntNumber,
-              IN  EMULATOR_INT32_PROC IntHandler,
-              OUT PSIZE_T CodeSize OPTIONAL);
-
-VOID
-Int32Call(IN PCALLBACK16 Context,
-          IN BYTE IntNumber);
-
-VOID WINAPI Int32Dispatch(LPWORD Stack);
-VOID InitializeCallbacks(VOID);
+RegisterCallback16(IN  ULONG   FarPtr,
+                   IN  LPBYTE  CallbackCode,
+                   IN  SIZE_T  CallbackSize,
+                   OUT PSIZE_T CodeSize OPTIONAL);
 
 #endif // _CALLBACK_H_
 
diff --git a/reactos/subsystems/ntvdm/cpu/cpu.c b/reactos/subsystems/ntvdm/cpu/cpu.c
new file mode 100644 (file)
index 0000000..bd74409
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * PROJECT:         ReactOS Virtual DOS Machine
+ * FILE:            emulator.c
+ * PURPOSE:         Minimal x86 machine emulator for the VDM
+ * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+/* INCLUDES *******************************************************************/
+
+#define NDEBUG
+
+#include "cpu.h"
+
+#include "emulator.h"
+#include "callback.h"
+#include "bop.h"
+#include <isvbop.h>
+
+#include "clock.h"
+#include "bios/rom.h"
+#include "hardware/cmos.h"
+#include "hardware/keyboard.h"
+#include "hardware/mouse.h"
+#include "hardware/pic.h"
+#include "hardware/ps2.h"
+#include "hardware/speaker.h"
+#include "hardware/timer.h"
+#include "hardware/vga.h"
+
+#include "io.h"
+
+/* PRIVATE VARIABLES **********************************************************/
+
+FAST486_STATE EmulatorContext;
+BOOLEAN CpuRunning = FALSE;
+
+/* No more than 'MaxCpuCallLevel' recursive CPU calls are allowed */
+static const INT MaxCpuCallLevel = 32;
+static INT CpuCallLevel = 0;
+
+// BOOLEAN VdmRunning  = TRUE;
+
+#if 0
+LPCWSTR ExceptionName[] =
+{
+    L"Division By Zero",
+    L"Debug",
+    L"Unexpected Error",
+    L"Breakpoint",
+    L"Integer Overflow",
+    L"Bound Range Exceeded",
+    L"Invalid Opcode",
+    L"FPU Not Available"
+};
+#endif
+
+// /* BOP Identifiers */
+// #define BOP_DEBUGGER    0x56    // Break into the debugger from a 16-bit app
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+#if 0
+VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack)
+{
+    WORD CodeSegment, InstructionPointer;
+    PBYTE Opcode;
+
+    ASSERT(ExceptionNumber < 8);
+
+    /* Get the CS:IP */
+    InstructionPointer = Stack[STACK_IP];
+    CodeSegment = Stack[STACK_CS];
+    Opcode = (PBYTE)SEG_OFF_TO_PTR(CodeSegment, InstructionPointer);
+
+    /* Display a message to the user */
+    DisplayMessage(L"Exception: %s occured at %04X:%04X\n"
+                   L"Opcode: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",
+                   ExceptionName[ExceptionNumber],
+                   CodeSegment,
+                   InstructionPointer,
+                   Opcode[0],
+                   Opcode[1],
+                   Opcode[2],
+                   Opcode[3],
+                   Opcode[4],
+                   Opcode[5],
+                   Opcode[6],
+                   Opcode[7],
+                   Opcode[8],
+                   Opcode[9]);
+
+    /* Stop the VDM */
+    EmulatorTerminate();
+    return;
+}
+#endif
+
+// FIXME: This function assumes 16-bit mode!!!
+VOID CpuExecute(WORD Segment, WORD Offset)
+{
+    /* Tell Fast486 to move the instruction pointer */
+    Fast486ExecuteAt(&EmulatorContext, Segment, Offset);
+}
+
+VOID CpuStep(VOID)
+{
+    /* Dump the state for debugging purposes */
+    // Fast486DumpState(&EmulatorContext);
+
+    /* Execute the next instruction */
+    Fast486StepInto(&EmulatorContext);
+}
+
+VOID CpuSimulate(VOID)
+{
+    if (CpuCallLevel > MaxCpuCallLevel)
+    {
+        DisplayMessage(L"Too many CPU levels of recursion (%d, expected maximum %d)",
+                       CpuCallLevel, MaxCpuCallLevel);
+
+        /* Stop the VDM */
+        EmulatorTerminate();
+        return;
+    }
+    CpuCallLevel++;
+
+    CpuRunning = TRUE;
+    while (VdmRunning && CpuRunning) ClockUpdate();
+
+    CpuCallLevel--;
+    if (CpuCallLevel < 0) CpuCallLevel = 0;
+
+    /* This takes into account for reentrance */
+    CpuRunning = TRUE;
+}
+
+VOID CpuUnsimulate(VOID)
+{
+    /* Stop simulation */
+    CpuRunning = FALSE;
+}
+
+static VOID WINAPI CpuUnsimulateBop(LPWORD Stack)
+{
+    CpuUnsimulate();
+}
+
+#if 0
+VOID EmulatorTerminate(VOID)
+{
+    /* Stop the VDM */
+    VdmRunning = FALSE;
+}
+#endif
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+BOOLEAN CpuInitialize(VOID)
+{
+    // /* Initialize the internal clock */
+    // if (!ClockInitialize())
+    // {
+        // wprintf(L"FATAL: Failed to initialize the clock\n");
+        // return FALSE;
+    // }
+
+    /* Initialize the CPU */
+    Fast486Initialize(&EmulatorContext,
+                      EmulatorReadMemory,
+                      EmulatorWriteMemory,
+                      EmulatorReadIo,
+                      EmulatorWriteIo,
+                      NULL,
+                      EmulatorBiosOperation,
+                      EmulatorIntAcknowledge,
+                      NULL /* TODO: Use a TLB */);
+
+    /* Initialize the software callback system and register the emulator BOPs */
+    // RegisterBop(BOP_DEBUGGER  , EmulatorDebugBreakBop);
+    RegisterBop(BOP_UNSIMULATE, CpuUnsimulateBop);
+
+    return TRUE;
+}
+
+VOID CpuCleanup(VOID)
+{
+    // Fast486Cleanup();
+}
+
+/* EOF */
diff --git a/reactos/subsystems/ntvdm/cpu/cpu.h b/reactos/subsystems/ntvdm/cpu/cpu.h
new file mode 100644 (file)
index 0000000..fd51b49
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * PROJECT:         ReactOS Virtual DOS Machine
+ * FILE:            emulator.h
+ * PURPOSE:         Minimal x86 machine emulator for the VDM
+ * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+#ifndef _CPU_H_
+#define _CPU_H_
+
+/* INCLUDES *******************************************************************/
+
+#include "ntvdm.h"
+#include <fast486.h>
+
+/* DEFINES ********************************************************************/
+
+/* FLAGS */
+#define EMULATOR_FLAG_CF    (1 << 0)
+#define EMULATOR_FLAG_PF    (1 << 2)
+#define EMULATOR_FLAG_AF    (1 << 4)
+#define EMULATOR_FLAG_ZF    (1 << 6)
+#define EMULATOR_FLAG_SF    (1 << 7)
+#define EMULATOR_FLAG_TF    (1 << 8)
+#define EMULATOR_FLAG_IF    (1 << 9)
+#define EMULATOR_FLAG_DF    (1 << 10)
+#define EMULATOR_FLAG_OF    (1 << 11)
+#define EMULATOR_FLAG_NT    (1 << 14)
+#define EMULATOR_FLAG_RF    (1 << 16)
+#define EMULATOR_FLAG_VM    (1 << 17)
+#define EMULATOR_FLAG_AC    (1 << 18)
+#define EMULATOR_FLAG_VIF   (1 << 19)
+#define EMULATOR_FLAG_VIP   (1 << 20)
+#define EMULATOR_FLAG_ID    (1 << 21)
+
+#if 0
+enum
+{
+    EMULATOR_EXCEPTION_DIVISION_BY_ZERO,
+    EMULATOR_EXCEPTION_DEBUG,
+    EMULATOR_EXCEPTION_NMI,
+    EMULATOR_EXCEPTION_BREAKPOINT,
+    EMULATOR_EXCEPTION_OVERFLOW,
+    EMULATOR_EXCEPTION_BOUND,
+    EMULATOR_EXCEPTION_INVALID_OPCODE,
+    EMULATOR_EXCEPTION_NO_FPU,
+    EMULATOR_EXCEPTION_DOUBLE_FAULT,
+    EMULATOR_EXCEPTION_FPU_SEGMENT,
+    EMULATOR_EXCEPTION_INVALID_TSS,
+    EMULATOR_EXCEPTION_NO_SEGMENT,
+    EMULATOR_EXCEPTION_STACK_SEGMENT,
+    EMULATOR_EXCEPTION_GPF,
+    EMULATOR_EXCEPTION_PAGE_FAULT
+};
+#endif
+extern FAST486_STATE EmulatorContext;
+// extern BOOLEAN VdmRunning;
+
+/* FUNCTIONS ******************************************************************/
+
+#if 0
+VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack);
+#endif
+
+VOID CpuExecute(WORD Segment, WORD Offset);
+VOID CpuStep(VOID);
+VOID CpuSimulate(VOID);
+VOID CpuUnsimulate(VOID);
+#if 0
+VOID EmulatorTerminate(VOID);
+#endif
+
+BOOLEAN CpuInitialize(VOID);
+VOID CpuCleanup(VOID);
+
+#endif // _CPU_H_
+
+/* EOF */
index 4b75d85..9e58d72 100644 (file)
@@ -18,7 +18,7 @@
 #include "utils.h"
 
 #include "dem.h"
-#include "bop.h"
+#include "cpu/bop.h"
 
 #include "bios/bios.h"
 #include "mouse32.h"
index b70be3b..428807e 100644 (file)
@@ -11,7 +11,7 @@
 #define NDEBUG
 
 #include "emulator.h"
-#include "callback.h"
+#include "int32.h"
 
 #include "dos.h"
 
index abbef7e..7e6e3c4 100644 (file)
@@ -13,7 +13,7 @@
 
 #include "ntvdm.h"
 
-/**/ #include "callback.h" /**/
+/**/ #include "int32.h" /**/
 
 /* DEFINES ********************************************************************/
 
index e825dfe..5b0a526 100644 (file)
@@ -11,7 +11,8 @@
 #define NDEBUG
 
 #include "emulator.h"
-#include "callback.h"
+#include "cpu/cpu.h"
+#include "int32.h"
 
 #include "mouse32.h"
 #include "bios/bios.h"
index 06d1e23..84e41bd 100644 (file)
 #define NDEBUG
 
 #include "emulator.h"
-#include "callback.h"
+
+#include "cpu/callback.h"
+#include "cpu/cpu.h"
+#include "cpu/bop.h"
+#include <isvbop.h>
+
+#include "int32.h"
 
 #include "clock.h"
 #include "bios/rom.h"
 #include "hardware/timer.h"
 #include "hardware/vga.h"
 
-#include "bop.h"
 #include "vddsup.h"
 #include "io.h"
 
-#include <isvbop.h>
-
 /* PRIVATE VARIABLES **********************************************************/
 
-FAST486_STATE EmulatorContext;
-BOOLEAN CpuSimulate = FALSE;
-
-/* No more than 'MaxCpuCallLevel' recursive CPU calls are allowed */
-static const INT MaxCpuCallLevel = 32;
-static INT CpuCallLevel = 0;
-
 LPVOID  BaseAddress = NULL;
 BOOLEAN VdmRunning  = TRUE;
 
@@ -176,51 +172,6 @@ VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack)
     return;
 }
 
-// FIXME: This function assumes 16-bit mode!!!
-VOID EmulatorExecute(WORD Segment, WORD Offset)
-{
-    /* Tell Fast486 to move the instruction pointer */
-    Fast486ExecuteAt(&EmulatorContext, Segment, Offset);
-}
-
-VOID EmulatorStep(VOID)
-{
-    /* Dump the state for debugging purposes */
-    // Fast486DumpState(&EmulatorContext);
-
-    /* Execute the next instruction */
-    Fast486StepInto(&EmulatorContext);
-}
-
-VOID EmulatorSimulate(VOID)
-{
-    if (CpuCallLevel > MaxCpuCallLevel)
-    {
-        DisplayMessage(L"Too many CPU levels of recursion (%d, expected maximum %d)",
-                       CpuCallLevel, MaxCpuCallLevel);
-
-        /* Stop the VDM */
-        EmulatorTerminate();
-        return;
-    }
-    CpuCallLevel++;
-
-    CpuSimulate = TRUE;
-    while (VdmRunning && CpuSimulate) ClockUpdate();
-
-    CpuCallLevel--;
-    if (CpuCallLevel < 0) CpuCallLevel = 0;
-
-    /* This takes into account for reentrance */
-    CpuSimulate = TRUE;
-}
-
-VOID EmulatorUnsimulate(VOID)
-{
-    /* Stop simulation */
-    CpuSimulate = FALSE;
-}
-
 VOID EmulatorTerminate(VOID)
 {
     /* Stop the VDM */
@@ -250,11 +201,6 @@ static VOID WINAPI EmulatorDebugBreakBop(LPWORD Stack)
     DebugBreak();
 }
 
-static VOID WINAPI EmulatorUnsimulateBop(LPWORD Stack)
-{
-    EmulatorUnsimulate();
-}
-
 static BYTE WINAPI Port61hRead(ULONG Port)
 {
     return Port61hState;
@@ -559,6 +505,8 @@ BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
     /* Initialize I/O ports */
     /* Initialize RAM */
 
+    /* Initialize the CPU */
+
     /* Initialize the internal clock */
     if (!ClockInitialize())
     {
@@ -567,15 +515,16 @@ BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
     }
 
     /* Initialize the CPU */
-    Fast486Initialize(&EmulatorContext,
-                      EmulatorReadMemory,
-                      EmulatorWriteMemory,
-                      EmulatorReadIo,
-                      EmulatorWriteIo,
-                      NULL,
-                      EmulatorBiosOperation,
-                      EmulatorIntAcknowledge,
-                      NULL /* TODO: Use a TLB */);
+    CpuInitialize();
+    // Fast486Initialize(&EmulatorContext,
+                      // EmulatorReadMemory,
+                      // EmulatorWriteMemory,
+                      // EmulatorReadIo,
+                      // EmulatorWriteIo,
+                      // NULL,
+                      // EmulatorBiosOperation,
+                      // EmulatorIntAcknowledge,
+                      // NULL /* TODO: Use a TLB */);
 
     /* Initialize DMA */
 
@@ -626,9 +575,9 @@ BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
     }
 
     /* Initialize the software callback system and register the emulator BOPs */
-    InitializeCallbacks();
+    InitializeInt32();
     RegisterBop(BOP_DEBUGGER  , EmulatorDebugBreakBop);
-    RegisterBop(BOP_UNSIMULATE, EmulatorUnsimulateBop);
+    // RegisterBop(BOP_UNSIMULATE, CpuUnsimulateBop);
 
     /* Initialize VDD support */
     VDDSupInitialize();
@@ -651,7 +600,7 @@ VOID EmulatorCleanup(VOID)
     // PitCleanup();
     // PicCleanup();
 
-    // Fast486Cleanup();
+    CpuCleanup();
 
     /* Free the memory allocated for the 16-bit address space */
     if (BaseAddress != NULL) HeapFree(GetProcessHeap(), 0, BaseAddress);
@@ -663,7 +612,7 @@ VOID
 WINAPI
 VDDSimulate16(VOID)
 {
-    EmulatorSimulate();
+    CpuSimulate();
 }
 
 VOID
index b405c00..4b4928e 100644 (file)
 
 /* DEFINES ********************************************************************/
 
-/* FLAGS */
-#define EMULATOR_FLAG_CF (1 << 0)
-#define EMULATOR_FLAG_PF (1 << 2)
-#define EMULATOR_FLAG_AF (1 << 4)
-#define EMULATOR_FLAG_ZF (1 << 6)
-#define EMULATOR_FLAG_SF (1 << 7)
-#define EMULATOR_FLAG_TF (1 << 8)
-#define EMULATOR_FLAG_IF (1 << 9)
-#define EMULATOR_FLAG_DF (1 << 10)
-#define EMULATOR_FLAG_OF (1 << 11)
-#define EMULATOR_FLAG_NT (1 << 14)
-#define EMULATOR_FLAG_RF (1 << 16)
-#define EMULATOR_FLAG_VM (1 << 17)
-#define EMULATOR_FLAG_AC (1 << 18)
-#define EMULATOR_FLAG_VIF (1 << 19)
-#define EMULATOR_FLAG_VIP (1 << 20)
-#define EMULATOR_FLAG_ID (1 << 21)
-
-//
-// WARNING WARNING!!
-// If you're changing the indices here, you then need to
-// also fix the BOP code in callback.c !!!!!!!!!!!!!!!!!
-//
-#define STACK_INT_NUM   0
-#define STACK_IP        1
-#define STACK_CS        2
-#define STACK_FLAGS     3
-
-
 /* Basic Memory Management */
 #define MEM_ALIGN_UP(ptr, align)    MEM_ALIGN_DOWN((ULONG_PTR)(ptr) + (align) - 1l, (align))
 #define MEM_ALIGN_DOWN(ptr, align)  (PVOID)((ULONG_PTR)(ptr) & ~((align) - 1l))
@@ -92,7 +63,7 @@ enum
     EMULATOR_EXCEPTION_PAGE_FAULT
 };
 
-extern FAST486_STATE EmulatorContext;
+// extern FAST486_STATE EmulatorContext;
 extern LPVOID  BaseAddress;
 extern BOOLEAN VdmRunning;
 
@@ -123,10 +94,6 @@ UCHAR WINAPI EmulatorIntAcknowledge
 
 VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack);
 
-VOID EmulatorExecute(WORD Segment, WORD Offset);
-VOID EmulatorStep(VOID);
-VOID EmulatorSimulate(VOID);
-VOID EmulatorUnsimulate(VOID);
 VOID EmulatorTerminate(VOID);
 
 VOID EmulatorInterrupt(BYTE Number);
index e139c85..72386ad 100644 (file)
 #include "emulator.h"
 #include "int32.h"
 
-#include "bop.h"
+#include "cpu/bop.h"
+#include <isvbop.h>
 
 /* PRIVATE VARIABLES **********************************************************/
 
 /*
  * This is the list of registered 32-bit Interrupt handlers.
  */
-EMULATOR_INT32_PROC Int32Proc[EMULATOR_MAX_INT32_NUM] = { NULL };
+static EMULATOR_INT32_PROC Int32Proc[EMULATOR_MAX_INT32_NUM] = { NULL };
 
 /* BOP Identifiers */
 #define BOP_CONTROL             0xFF    // Control BOP Handler
     #define BOP_CONTROL_DEFFUNC 0x00    // Default Control BOP Function
+    #define BOP_CONTROL_INT32   0xFF    // 32-bit Interrupt dispatcher
 
-/* 32-bit Interrupt dispatcher function code for the Control BOP Handler */
-#define BOP_CONTROL_INT32       0xFF
+#define INT16_TRAMPOLINE_SIZE   sizeof(ULONGLONG) // == TRAMPOLINE_SIZE
+
+/* 16-bit generic interrupt code for calling a 32-bit interrupt handler */
+static BYTE Int16To32[] =
+{
+    0xFA,               // cli
+
+    /* Push the value of the interrupt to be called */
+    0x6A, 0xFF,         // push i (patchable to 0x6A, 0xIntNum)
+
+    /* The BOP Sequence */
+// BOP_SEQ:
+    0xF8,               // clc
+    BOP(BOP_CONTROL),   // Control BOP
+    BOP_CONTROL_INT32,  // 32-bit Interrupt dispatcher
+
+    0x73, 0x04,         // jnc EXIT (offset +4)
+
+    0xFB,               // sti
+
+    // HACK: The following instruction should be HLT!
+    0x90,               // nop
+
+    0xEB, 0xF5,         // jmp BOP_SEQ (offset -11)
+
+// EXIT:
+    0x44, 0x44,         // inc sp, inc sp
+    0xCF,               // iret
+};
+const ULONG Int16To32StubSize = sizeof(Int16To32);
 
 /* PUBLIC FUNCTIONS ***********************************************************/
 
-VOID WINAPI Int32Dispatch(LPWORD Stack)
+static VOID WINAPI Int32Dispatch(LPWORD Stack)
 {
     /* Get the interrupt number */
     BYTE IntNum = LOBYTE(Stack[STACK_INT_NUM]);
@@ -41,88 +71,127 @@ VOID WINAPI Int32Dispatch(LPWORD Stack)
     if (Int32Proc[IntNum] != NULL)
         Int32Proc[IntNum](Stack);
     else
-        DPRINT("Unhandled 32-bit interrupt: 0x%02X, AX = 0x%04X\n", IntNum, getAX());
+        DPRINT1("Unhandled 32-bit interrupt: 0x%02X, AX = 0x%04X\n", IntNum, getAX());
 }
 
-VOID WINAPI ControlBop(LPWORD Stack)
+static VOID WINAPI ControlBop(LPWORD Stack)
 {
     /* Get the Function Number and skip it */
     BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
     setIP(getIP() + 1);
 
-    if (FuncNum == BOP_CONTROL_INT32)
-        Int32Dispatch(Stack);
-    else
-        DPRINT("Unassigned Control BOP Function: 0x%02X\n", FuncNum);
+    switch (FuncNum)
+    {
+        case BOP_CONTROL_INT32:
+            Int32Dispatch(Stack);
+            break;
+
+        default:
+            // DPRINT1("Unassigned Control BOP Function: 0x%02X\n", FuncNum);
+            DisplayMessage(L"Unassigned Control BOP Function: 0x%02X", FuncNum);
+            break;
+    }
 }
 
-VOID InitializeInt32(WORD BiosSegment)
+ULONG
+RegisterInt16(IN  ULONG   FarPtr,
+              IN  BYTE    IntNumber,
+              IN  LPBYTE  CallbackCode,
+              IN  SIZE_T  CallbackSize,
+              OUT PSIZE_T CodeSize OPTIONAL)
 {
-    //
-    // WARNING WARNING!!
-    //
-    // If you modify the code stubs here, think also
-    // about updating them in callback.c too!!
-    //
-
-    LPDWORD IntVecTable = (LPDWORD)BaseAddress;
-    LPBYTE  BiosCode    = (LPBYTE)SEG_OFF_TO_PTR(BiosSegment, 0);
-    USHORT i;
-    WORD BopSeqOffset, Offset = 0;
-
-    /* Generate ISR stubs and fill the IVT */
-    for (i = 0x00; i <= 0xFF; i++)
-    {
-        Offset = INT_HANDLER_OFFSET + (i << 4);
-        IntVecTable[i] = MAKELONG(Offset, BiosSegment);
-
-        BiosCode[Offset++] = 0xFA; // cli
-
-        BiosCode[Offset++] = 0x6A; // push i
-        BiosCode[Offset++] = (UCHAR)i;
+    /* Get a pointer to the IVT and set the corresponding entry (far pointer) */
+    LPDWORD IntVecTable = (LPDWORD)SEG_OFF_TO_PTR(0x0000, 0x0000);
+    IntVecTable[IntNumber] = FarPtr;
+
+    /* Register the 16-bit callback */
+    return RegisterCallback16(FarPtr,
+                              CallbackCode,
+                              CallbackSize,
+                              CodeSize);
+}
 
-        BopSeqOffset = COMMON_STUB_OFFSET - (Offset + 3);
+ULONG
+RegisterInt32(IN  ULONG   FarPtr,
+              IN  BYTE    IntNumber,
+              IN  EMULATOR_INT32_PROC IntHandler,
+              OUT PSIZE_T CodeSize OPTIONAL)
+{
+    /* Array for holding our copy of the 16-bit interrupt callback */
+    BYTE IntCallback[sizeof(Int16To32)/sizeof(BYTE)];
 
-        BiosCode[Offset++] = 0xE9; // jmp near BOP_SEQ
-        BiosCode[Offset++] = LOBYTE(BopSeqOffset);
-        BiosCode[Offset++] = HIBYTE(BopSeqOffset);
+    /* Check whether the 32-bit interrupt was already registered */
+#if 0
+    if (Int32Proc[IntNumber] != NULL)
+    {
+        DPRINT1("RegisterInt32: Interrupt 0x%02X already registered!\n", IntNumber);
+        return 0;
     }
+#endif
 
-    /* Write the common stub code */
-    Offset = COMMON_STUB_OFFSET;
+    /* Register the 32-bit interrupt handler */
+    Int32Proc[IntNumber] = IntHandler;
 
-// BOP_SEQ:
-    BiosCode[Offset++] = 0xF8; // clc
+    /* Copy the generic 16-bit interrupt callback and patch it */
+    RtlCopyMemory(IntCallback, Int16To32, sizeof(Int16To32));
+    IntCallback[2] = IntNumber;
 
-    BiosCode[Offset++] = LOBYTE(EMULATOR_BOP);  // BOP sequence
-    BiosCode[Offset++] = HIBYTE(EMULATOR_BOP);
-    BiosCode[Offset++] = BOP_CONTROL;           // Control BOP
-    BiosCode[Offset++] = BOP_CONTROL_INT32;     // 32-bit Interrupt dispatcher
+    /* Register the 16-bit interrupt callback */
+    return RegisterInt16(FarPtr,
+                         IntNumber,
+                         IntCallback,
+                         sizeof(IntCallback),
+                         CodeSize);
+}
 
-    BiosCode[Offset++] = 0x73; // jnc EXIT (offset +4)
-    BiosCode[Offset++] = 0x04;
+VOID
+Int32Call(IN PCALLBACK16 Context,
+          IN BYTE IntNumber)
+{
+    /*
+     * TODO: This function has almost the same code as RunCallback16.
+     * Something that may be nice is to have a common interface to
+     * build the trampoline...
+     */
 
-    BiosCode[Offset++] = 0xFB; // sti
+    PUCHAR TrampolineBase = (PUCHAR)FAR_POINTER(Context->TrampolineFarPtr);
+    PUCHAR Trampoline     = TrampolineBase;
+    UCHAR  OldTrampoline[INT16_TRAMPOLINE_SIZE];
 
-    // HACK: The following instruction should be HLT!
-    BiosCode[Offset++] = 0x90; // nop
+    DPRINT("Int32Call(0x%02X)\n", IntNumber);
 
-    BiosCode[Offset++] = 0xEB; // jmp BOP_SEQ (offset -11)
-    BiosCode[Offset++] = 0xF5;
+    ASSERT(Context->TrampolineSize == INT16_TRAMPOLINE_SIZE);
 
-// EXIT:
-    BiosCode[Offset++] = 0x44; // inc sp
-    BiosCode[Offset++] = 0x44; // inc sp
+    /* Save the old trampoline */
+    ((PULONGLONG)&OldTrampoline)[0] = ((PULONGLONG)TrampolineBase)[0];
 
-    BiosCode[Offset++] = 0xCF; // iret
+    /* Build the generic entry-point for 16-bit calls */
+    if (IntNumber == 0x03)
+    {
+        /* We are redefining for INT 03h */
+        *Trampoline++ = 0xCC; // Call INT 03h
+        /** *Trampoline++ = 0x90; // nop **/
+    }
+    else
+    {
+        /* Normal interrupt */
+        *Trampoline++ = 0xCD; // Call INT XXh
+        *Trampoline++ = IntNumber;
+    }
+    UnSimulate16(Trampoline);
 
-    /* Register the Control BOP */
-    RegisterBop(BOP_CONTROL, ControlBop);
+    /* Perform the call */
+    Call16(HIWORD(Context->TrampolineFarPtr),
+           LOWORD(Context->TrampolineFarPtr));
+
+    /* Restore the old trampoline */
+    ((PULONGLONG)TrampolineBase)[0] = ((PULONGLONG)&OldTrampoline)[0];
 }
 
-VOID RegisterInt32(BYTE IntNumber, EMULATOR_INT32_PROC IntHandler)
+VOID InitializeInt32(VOID)
 {
-    Int32Proc[IntNumber] = IntHandler;
+    /* Register the Control BOP */
+    RegisterBop(BOP_CONTROL, ControlBop);
 }
 
 /* EOF */
index d6cced2..d9dc9f8 100644 (file)
 #ifndef _INT32_H_
 #define _INT32_H_
 
+/* INCLUDES *******************************************************************/
+
+#include "cpu/callback.h"
+
 /* DEFINES ********************************************************************/
 
 /* 32-bit Interrupt Identifiers */
 #define EMULATOR_MAX_INT32_NUM  0xFF + 1
 
-#define INT_HANDLER_OFFSET 0x1000
-#define COMMON_STUB_OFFSET 0x2000
+extern const ULONG Int16To32StubSize;
 
 /* FUNCTIONS ******************************************************************/
 
 typedef VOID (WINAPI *EMULATOR_INT32_PROC)(LPWORD Stack);
 
-VOID WINAPI Int32Dispatch(LPWORD Stack);
-VOID InitializeInt32(WORD BiosSegment);
-VOID RegisterInt32(BYTE IntNumber, EMULATOR_INT32_PROC IntHandler);
+ULONG
+RegisterInt16(IN  ULONG   FarPtr,
+              IN  BYTE    IntNumber,
+              IN  LPBYTE  CallbackCode,
+              IN  SIZE_T  CallbackSize,
+              OUT PSIZE_T CodeSize OPTIONAL);
+
+ULONG
+RegisterInt32(IN  ULONG   FarPtr,
+              IN  BYTE    IntNumber,
+              IN  EMULATOR_INT32_PROC IntHandler,
+              OUT PSIZE_T CodeSize OPTIONAL);
+
+VOID
+Int32Call(IN PCALLBACK16 Context,
+          IN BYTE IntNumber);
+
+VOID InitializeInt32(VOID);
 
 #endif // _INT32_H_
 
index d3d5ce1..57aca7f 100644 (file)
 #define NDEBUG
 
 #include "emulator.h"
+#include "cpu/cpu.h"
 
 /* PUBLIC FUNCTIONS ***********************************************************/
 
-static inline BOOLEAN EmulatorGetFlag(ULONG Flag)
-{
-    return (EmulatorContext.Flags.Long & Flag) ? TRUE : FALSE;
-}
-
-static inline VOID EmulatorSetFlag(ULONG Flag)
-{
-    EmulatorContext.Flags.Long |= Flag;
-}
-
-static inline VOID EmulatorClearFlag(ULONG Flag)
-{
-    EmulatorContext.Flags.Long &= ~Flag;
-}
-
 VOID EmulatorSetStack(WORD Segment, DWORD Offset)
 {
     Fast486SetStack(&EmulatorContext, Segment, Offset);
@@ -405,7 +391,7 @@ VOID
 WINAPI
 setEIP(ULONG Value)
 {
-    EmulatorExecute(getCS(), Value);
+    CpuExecute(getCS(), Value);
 }
 
 USHORT
@@ -419,7 +405,7 @@ VOID
 WINAPI
 setIP(USHORT Value)
 {
-    EmulatorExecute(getCS(), Value);
+    CpuExecute(getCS(), Value);
 }
 
 
@@ -514,136 +500,112 @@ ULONG
 WINAPI
 getCF(VOID)
 {
-    return EmulatorGetFlag(EMULATOR_FLAG_CF);
+    return EmulatorContext.Flags.Cf;
 }
 
 VOID
 WINAPI
 setCF(ULONG Flag)
 {
-    if (Flag & 1)
-        EmulatorSetFlag(EMULATOR_FLAG_CF);
-    else
-        EmulatorClearFlag(EMULATOR_FLAG_CF);
+    EmulatorContext.Flags.Cf = !!(Flag & 1);
 }
 
 ULONG
 WINAPI
 getPF(VOID)
 {
-    return EmulatorGetFlag(EMULATOR_FLAG_PF);
+    return EmulatorContext.Flags.Pf;
 }
 
 VOID
 WINAPI
 setPF(ULONG Flag)
 {
-    if (Flag & 1)
-        EmulatorSetFlag(EMULATOR_FLAG_PF);
-    else
-        EmulatorClearFlag(EMULATOR_FLAG_PF);
+    EmulatorContext.Flags.Pf = !!(Flag & 1);
 }
 
 ULONG
 WINAPI
 getAF(VOID)
 {
-    return EmulatorGetFlag(EMULATOR_FLAG_AF);
+    return EmulatorContext.Flags.Af;
 }
 
 VOID
 WINAPI
 setAF(ULONG Flag)
 {
-    if (Flag & 1)
-        EmulatorSetFlag(EMULATOR_FLAG_AF);
-    else
-        EmulatorClearFlag(EMULATOR_FLAG_AF);
+    EmulatorContext.Flags.Af = !!(Flag & 1);
 }
 
 ULONG
 WINAPI
 getZF(VOID)
 {
-    return EmulatorGetFlag(EMULATOR_FLAG_ZF);
+    return EmulatorContext.Flags.Zf;
 }
 
 VOID
 WINAPI
 setZF(ULONG Flag)
 {
-    if (Flag & 1)
-        EmulatorSetFlag(EMULATOR_FLAG_ZF);
-    else
-        EmulatorClearFlag(EMULATOR_FLAG_ZF);
+    EmulatorContext.Flags.Zf = !!(Flag & 1);
 }
 
 ULONG
 WINAPI
 getSF(VOID)
 {
-    return EmulatorGetFlag(EMULATOR_FLAG_SF);
+    return EmulatorContext.Flags.Sf;
 }
 
 VOID
 WINAPI
 setSF(ULONG Flag)
 {
-    if (Flag & 1)
-        EmulatorSetFlag(EMULATOR_FLAG_SF);
-    else
-        EmulatorClearFlag(EMULATOR_FLAG_SF);
+    EmulatorContext.Flags.Sf = !!(Flag & 1);
 }
 
 ULONG
 WINAPI
 getIF(VOID)
 {
-    return EmulatorGetFlag(EMULATOR_FLAG_IF);
+    return EmulatorContext.Flags.If;
 }
 
 VOID
 WINAPI
 setIF(ULONG Flag)
 {
-    if (Flag & 1)
-        EmulatorSetFlag(EMULATOR_FLAG_IF);
-    else
-        EmulatorClearFlag(EMULATOR_FLAG_IF);
+    EmulatorContext.Flags.If = !!(Flag & 1);
 }
 
 ULONG
 WINAPI
 getDF(VOID)
 {
-    return EmulatorGetFlag(EMULATOR_FLAG_DF);
+    return EmulatorContext.Flags.Df;
 }
 
 VOID
 WINAPI
 setDF(ULONG Flag)
 {
-    if (Flag & 1)
-        EmulatorSetFlag(EMULATOR_FLAG_DF);
-    else
-        EmulatorClearFlag(EMULATOR_FLAG_DF);
+    EmulatorContext.Flags.Df = !!(Flag & 1);
 }
 
 ULONG
 WINAPI
 getOF(VOID)
 {
-    return EmulatorGetFlag(EMULATOR_FLAG_OF);
+    return EmulatorContext.Flags.Of;
 }
 
 VOID
 WINAPI
 setOF(ULONG Flag)
 {
-    if (Flag & 1)
-        EmulatorSetFlag(EMULATOR_FLAG_OF);
-    else
-        EmulatorClearFlag(EMULATOR_FLAG_OF);
+    EmulatorContext.Flags.Of = !!(Flag & 1);
 }
 
 
index 92a0ff1..0997216 100644 (file)
@@ -13,8 +13,7 @@
 #include "emulator.h"
 #include "vddsup.h"
 
-#include "bop.h"
-
+#include "cpu/bop.h"
 #include <isvbop.h>
 
 typedef VOID (WINAPI *VDD_PROC)(VOID);