[NTVDM]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 23 Feb 2014 16:09:35 +0000 (16:09 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 23 Feb 2014 16:09:35 +0000 (16:09 +0000)
- Use callbacks in BIOS/DOS (and disable int32.c)
- Move DOS bops to dem.c

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

subsystems/ntvdm/CMakeLists.txt
subsystems/ntvdm/bios/bios32/bios32.c
subsystems/ntvdm/bios/bios32/bios32.h
subsystems/ntvdm/bios/bios32/kbdbios32.c
subsystems/ntvdm/bios/bios32/vidbios32.c
subsystems/ntvdm/dos/dem.c
subsystems/ntvdm/dos/dos32krnl/bios.c
subsystems/ntvdm/dos/dos32krnl/dos.c
subsystems/ntvdm/dos/dos32krnl/dos.h
subsystems/ntvdm/emulator.c

index 2784397..4351ef5 100644 (file)
@@ -22,7 +22,7 @@ list(APPEND SOURCE
     bop.c
     clock.c
     emulator.c
-    int32.c
+    callback.c
     io.c
     registers.c
     vddsup.c
index e375367..6379c9b 100644 (file)
@@ -11,6 +11,8 @@
 #define NDEBUG
 
 #include "emulator.h"
+#include "callback.h"
+
 #include "bios32.h"
 
 #include "io.h"
 #include "hardware/pic.h"
 #include "hardware/timer.h"
 
-#include "int32.h"
-
 /* PRIVATE VARIABLES **********************************************************/
 
+CALLBACK16 BiosContext;
 PBIOS_DATA_AREA Bda;
 
 /* PRIVATE FUNCTIONS **********************************************************/
@@ -190,7 +191,7 @@ VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func)
     else
         vector = BIOS_PIC_SLAVE_INT  + hwirq - 8;
 
-    RegisterInt32(vector, func);
+    RegisterBiosInt32(vector, func);
 }
 
 
@@ -250,7 +251,8 @@ static VOID WINAPI BiosTimerIrq(LPWORD Stack)
      * because some programs may hook only BIOS_SYS_TIMER_INTERRUPT
      * for their purpose...
      */
-    EmulatorInterrupt(BIOS_SYS_TIMER_INTERRUPT);
+    /** EmulatorInterrupt(BIOS_SYS_TIMER_INTERRUPT); **/
+    Int32Call(&BiosContext, BIOS_SYS_TIMER_INTERRUPT);
     PicIRQComplete(Stack);
 }
 
@@ -303,6 +305,48 @@ static VOID BiosHwSetup(VOID)
     EnableHwIRQ(0, BiosTimerIrq);
 }
 
+static VOID InitializeBiosInt32(VOID)
+{
+    USHORT i;
+    // USHORT Offset = 0;
+
+    /* Initialize the callback context */
+    InitializeContext(&BiosContext, BIOS_SEGMENT, 0x0000);
+
+    /* Register the BIOS 32-bit Interrupts */
+    for (i = 0x00; i <= 0xFF; i++)
+    {
+        // Offset += RegisterInt32(MAKELONG(Offset, BIOS_SEGMENT), i, NULL, NULL);
+        BiosContext.NextOffset += RegisterInt32(MAKELONG(BiosContext.NextOffset,
+                                                         BiosContext.Segment),
+                                                i, NULL, NULL);
+    }
+
+    /* Initialize the exception vector interrupts to a default Exception handler */
+    for (i = 0; i < 8; i++)
+        RegisterBiosInt32(i, BiosException);
+
+    /* Initialize HW vector interrupts to a default HW handler */
+    for (i = BIOS_PIC_MASTER_INT; i < BIOS_PIC_MASTER_INT + 8; i++)
+        RegisterBiosInt32(i, BiosHandleMasterPicIRQ);
+    for (i = BIOS_PIC_SLAVE_INT ; i < BIOS_PIC_SLAVE_INT  + 8; i++)
+        RegisterBiosInt32(i, BiosHandleSlavePicIRQ);
+
+    /* Initialize software vector handlers */
+    RegisterBiosInt32(BIOS_EQUIPMENT_INTERRUPT, BiosEquipmentService    );
+    RegisterBiosInt32(BIOS_MEMORY_SIZE        , BiosGetMemorySize       );
+    RegisterBiosInt32(BIOS_MISC_INTERRUPT     , BiosMiscService         );
+    RegisterBiosInt32(BIOS_TIME_INTERRUPT     , BiosTimeService         );
+    RegisterBiosInt32(BIOS_SYS_TIMER_INTERRUPT, BiosSystemTimerInterrupt);
+
+    /* Some interrupts are in fact addresses to tables */
+    ((PULONG)BaseAddress)[0x1E] = (ULONG)NULL;
+    ((PULONG)BaseAddress)[0x41] = (ULONG)NULL;
+    ((PULONG)BaseAddress)[0x46] = (ULONG)NULL;
+    ((PULONG)BaseAddress)[0x48] = (ULONG)NULL;
+    ((PULONG)BaseAddress)[0x49] = (ULONG)NULL;
+}
+
 /* PUBLIC FUNCTIONS ***********************************************************/
 
 /*
@@ -312,7 +356,6 @@ BOOLEAN Bios32Initialize(IN HANDLE ConsoleInput,
                          IN HANDLE ConsoleOutput)
 {
     UCHAR Low, High;
-    UCHAR i;
 
     /* Initialize the BDA */
     Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0);
@@ -328,34 +371,8 @@ BOOLEAN Bios32Initialize(IN HANDLE ConsoleInput,
     High = IOReadB(CMOS_DATA_PORT);
     Bda->MemorySize = MAKEWORD(Low, High);
 
-    /* Initialize the 32-bit Interrupt system */
-    InitializeInt32(BIOS_SEGMENT);
-
     /* Register the BIOS 32-bit Interrupts */
-
-    /* Initialize the exception vector interrupts to a default Exception handler */
-    for (i = 0; i < 8; i++)
-        RegisterInt32(i, BiosException);
-
-    /* Initialize HW vector interrupts to a default HW handler */
-    for (i = BIOS_PIC_MASTER_INT; i < BIOS_PIC_MASTER_INT + 8; i++)
-        RegisterInt32(i, BiosHandleMasterPicIRQ);
-    for (i = BIOS_PIC_SLAVE_INT ; i < BIOS_PIC_SLAVE_INT  + 8; i++)
-        RegisterInt32(i, BiosHandleSlavePicIRQ);
-
-    /* Initialize software vector handlers */
-    RegisterInt32(BIOS_EQUIPMENT_INTERRUPT, BiosEquipmentService    );
-    RegisterInt32(BIOS_MEMORY_SIZE        , BiosGetMemorySize       );
-    RegisterInt32(BIOS_MISC_INTERRUPT     , BiosMiscService         );
-    RegisterInt32(BIOS_TIME_INTERRUPT     , BiosTimeService         );
-    RegisterInt32(BIOS_SYS_TIMER_INTERRUPT, BiosSystemTimerInterrupt);
-
-    /* Some interrupts are in fact addresses to tables */
-    ((PDWORD)BaseAddress)[0x1E] = (DWORD)NULL;
-    ((PDWORD)BaseAddress)[0x41] = (DWORD)NULL;
-    ((PDWORD)BaseAddress)[0x46] = (DWORD)NULL;
-    ((PDWORD)BaseAddress)[0x48] = (DWORD)NULL;
-    ((PDWORD)BaseAddress)[0x49] = (DWORD)NULL;
+    InitializeBiosInt32();
 
     /* Initialize platform hardware (PIC/PIT chips, ...) */
     BiosHwSetup();
index ba1f69b..8f15381 100644 (file)
@@ -15,6 +15,8 @@
 #include "kbdbios32.h"
 #include "vidbios32.h"
 
+/**/ #include "callback.h" /**/
+
 /* DEFINES ********************************************************************/
 
 #define BIOS_PIC_MASTER_INT 0x08
@@ -115,6 +117,14 @@ C_ASSERT(sizeof(BIOS_DATA_AREA) == 0x133);
 
 /* FUNCTIONS ******************************************************************/
 
+extern CALLBACK16 BiosContext;
+#define RegisterBiosInt32(IntNumber, IntHandler) \
+do { \
+    BiosContext.NextOffset += RegisterInt32(MAKELONG(BiosContext.NextOffset,  \
+                                                     BiosContext.Segment),    \
+                                            (IntNumber), (IntHandler), NULL); \
+} while(0);
+
 extern PBIOS_DATA_AREA Bda;
 
 /**HACK!!**/typedef VOID (WINAPI *EMULATOR_INT32_PROC)(LPWORD Stack);/**HACK!!**/
index 6444004..4f55161 100644 (file)
 #define NDEBUG
 
 #include "emulator.h"
+#include "callback.h"
+
 // #include "kbdbios32.h"
 #include "bios32.h"
 
 #include "io.h"
 #include "hardware/ps2.h"
 
-#include "int32.h"
-
 /* PRIVATE VARIABLES **********************************************************/
 
 static BYTE BiosKeyboardMap[256];
@@ -271,7 +271,7 @@ BOOLEAN KbdBios32Initialize(HANDLE ConsoleInput)
     /* Register the BIOS 32-bit Interrupts */
 
     /* Initialize software vector handlers */
-    RegisterInt32(BIOS_KBD_INTERRUPT, BiosKeyboardService);
+    RegisterBiosInt32(BIOS_KBD_INTERRUPT, BiosKeyboardService);
 
     /* Set up the HW vector interrupts */
     EnableHwIRQ(1, BiosKeyboardIrq);
index 4734f10..e848145 100644 (file)
 #define NDEBUG
 
 #include "emulator.h"
+#include "callback.h"
+
 // #include "vidbios32.h"
 #include "bios32.h"
 
 #include "io.h"
 #include "hardware/vga.h"
 
-#include "int32.h"
-
 /* MACROS *********************************************************************/
 
 //
@@ -1536,11 +1536,11 @@ static VOID WINAPI VidBiosVideoService(LPWORD Stack)
 BOOLEAN VidBios32Initialize(HANDLE ConsoleOutput)
 {
     /* Some interrupts are in fact addresses to tables */
-    ((PDWORD)BaseAddress)[0x1D] = (DWORD)NULL;
-    ((PDWORD)BaseAddress)[0x1F] = (DWORD)NULL;
-    // ((PDWORD)BaseAddress)[0x42] = (DWORD)NULL;
-    ((PDWORD)BaseAddress)[0x43] = (DWORD)NULL;
-    ((PDWORD)BaseAddress)[0x44] = (DWORD)NULL;
+    ((PULONG)BaseAddress)[0x1D] = (ULONG)NULL;
+    ((PULONG)BaseAddress)[0x1F] = (ULONG)NULL;
+    // ((PULONG)BaseAddress)[0x42] = (ULONG)NULL;
+    ((PULONG)BaseAddress)[0x43] = (ULONG)NULL;
+    ((PULONG)BaseAddress)[0x44] = (ULONG)NULL;
 
     /* Set the default video mode */
     VidBiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE);
@@ -1562,7 +1562,7 @@ BOOLEAN VidBios32Initialize(HANDLE ConsoleOutput)
     }
 
     /* Register the BIOS 32-bit Interrupts */
-    RegisterInt32(BIOS_VIDEO_INTERRUPT, VidBiosVideoService);
+    RegisterBiosInt32(BIOS_VIDEO_INTERRUPT, VidBiosVideoService);
 
     return TRUE;
 }
index 64ea854..b7f0179 100644 (file)
 
 #define NDEBUG
 
+#include "emulator.h"
+
 #include "dem.h"
+#include "bop.h"
 
 /* Extra PSDK/NDK Headers */
 #include <ndk/obtypes.h>
 
+/* PRIVATE VARIABLES **********************************************************/
+
 /**/extern BYTE CurrentDrive;/**/
 
+/* DEFINES ********************************************************************/
+
+/* BOP Identifiers */
+#define BOP_DOS 0x50    // DOS System BOP (for NTIO.SYS and NTDOS.SYS)
+#define BOP_CMD 0x54    // DOS Command Interpreter BOP (for COMMAND.COM)
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+static VOID WINAPI DosSystemBop(LPWORD Stack)
+{
+    /* Get the Function Number and skip it */
+    BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
+    setIP(getIP() + 1);
+
+    DPRINT1("Unknown DOS System BOP Function: 0x%02X\n", FuncNum);
+}
+
+static VOID WINAPI DosCmdInterpreterBop(LPWORD Stack)
+{
+    /* Get the Function Number and skip it */
+    BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
+    setIP(getIP() + 1);
+
+    switch (FuncNum)
+    {
+        case 0x08: // Launch external command
+        {
+#define CMDLINE_LENGTH  1024
+
+            BOOL Result;
+            DWORD dwExitCode;
+
+            LPSTR Command = (LPSTR)SEG_OFF_TO_PTR(getDS(), getSI());
+            LPSTR CmdPtr  = Command;
+            CHAR CommandLine[CMDLINE_LENGTH] = "";
+            STARTUPINFOA StartupInfo;
+            PROCESS_INFORMATION ProcessInformation;
+
+            /* Remove return carriage character */
+            while (*CmdPtr != '\r') CmdPtr++;
+            *CmdPtr = '\0';
+
+            DPRINT1("CMD Run Command '%s'\n", Command);
+
+            /* Spawn a user-defined 32-bit command preprocessor */
+
+            /* Build the command line */
+            // FIXME: Use COMSPEC env var!!
+            strcpy(CommandLine, "cmd.exe /c ");
+            strcat(CommandLine, Command);
+
+            ZeroMemory(&StartupInfo, sizeof(StartupInfo));
+            ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
+
+            StartupInfo.cb = sizeof(StartupInfo);
+
+            DosPrintCharacter('\n');
+
+            Result = CreateProcessA(NULL,
+                                    CommandLine,
+                                    NULL,
+                                    NULL,
+                                    TRUE,
+                                    0,
+                                    NULL,
+                                    NULL,
+                                    &StartupInfo,
+                                    &ProcessInformation);
+            if (Result)
+            {
+                DPRINT1("Command '%s' launched successfully\n", Command);
+
+                /* Wait for process termination */
+                WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
+
+                /* Get the exit code */
+                GetExitCodeProcess(ProcessInformation.hProcess, &dwExitCode);
+
+                /* Close handles */
+                CloseHandle(ProcessInformation.hThread);
+                CloseHandle(ProcessInformation.hProcess);
+            }
+            else
+            {
+                DPRINT1("Failed when launched command '%s'\n");
+                dwExitCode = GetLastError();
+            }
+            
+            DosPrintCharacter('\n');
+
+            setAL((UCHAR)dwExitCode);
+
+            break;
+        }
+
+        default:
+        {
+            DPRINT1("Unknown DOS CMD Interpreter BOP Function: 0x%02X\n", FuncNum);
+            // setCF(1); // Disable, otherwise we enter an infinite loop
+            break;
+        }
+    }
+}
+
 /* PUBLIC FUNCTIONS ***********************************************************/
 
 BOOLEAN DosInitialize(IN LPCSTR DosKernelFileNames)
 {
+    /* Register the DOS BOPs */
+    RegisterBop(BOP_DOS, DosSystemBop        );
+    RegisterBop(BOP_CMD, DosCmdInterpreterBop);
+
     if (DosKernelFileNames)
     {
         DisplayMessage(L"NTVDM: Loading DOS kernel from external files is currently unsupported");
@@ -35,7 +148,7 @@ BOOLEAN DosInitialize(IN LPCSTR DosKernelFileNames)
         BOOLEAN Result;
 
         Result  = DosBIOSInitialize();
-        Result &= DosKRNLInitialize();
+        // Result &= DosKRNLInitialize();
 
         return Result;
     }
index e219e82..d3cc392 100644 (file)
 #define NDEBUG
 
 #include "emulator.h"
+#include "callback.h"
+
 #include "dos.h"
 
 #include "bios/bios.h"
-#include "bop.h"
-// #include "int32.h"
 
 /* PRIVATE VARIABLES **********************************************************/
 
 // static BYTE CurrentDrive;
 // static CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
 
-/* BOP Identifiers */
-#define BOP_DOS 0x50    // DOS System BOP (for NTIO.SYS and NTDOS.SYS)
-#define BOP_CMD 0x54    // DOS Command Interpreter BOP (for COMMAND.COM)
-
 /* PRIVATE FUNCTIONS **********************************************************/
 
 #if 0
@@ -119,94 +115,6 @@ VOID DosPrintCharacter(CHAR Character)
     DosWriteFile(DOS_OUTPUT_HANDLE, &Character, sizeof(CHAR), &BytesWritten);
 }
 
-VOID WINAPI DosSystemBop(LPWORD Stack)
-{
-    /* Get the Function Number and skip it */
-    BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
-    setIP(getIP() + 1);
-
-    DPRINT1("Unknown DOS System BOP Function: 0x%02X\n", FuncNum);
-}
-
-VOID WINAPI DosCmdInterpreterBop(LPWORD Stack)
-{
-    /* Get the Function Number and skip it */
-    BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
-    setIP(getIP() + 1);
-
-    switch (FuncNum)
-    {
-        case 0x08: // Launch external command
-        {
-#define CMDLINE_LENGTH  1024
-
-            BOOL Result;
-            DWORD dwExitCode;
-
-            LPSTR Command = (LPSTR)SEG_OFF_TO_PTR(getDS(), getSI());
-            CHAR CommandLine[CMDLINE_LENGTH] = "";
-            STARTUPINFOA StartupInfo;
-            PROCESS_INFORMATION ProcessInformation;
-            DPRINT1("CMD Run Command '%s'\n", Command);
-
-            Command[strlen(Command)-1] = 0;
-            
-            strcpy(CommandLine, "cmd.exe /c ");
-            strcat(CommandLine, Command);
-
-            ZeroMemory(&StartupInfo, sizeof(StartupInfo));
-            ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
-
-            StartupInfo.cb = sizeof(StartupInfo);
-
-            DosPrintCharacter('\n');
-
-            Result = CreateProcessA(NULL,
-                                    CommandLine,
-                                    NULL,
-                                    NULL,
-                                    TRUE,
-                                    0,
-                                    NULL,
-                                    NULL,
-                                    &StartupInfo,
-                                    &ProcessInformation);
-            if (Result)
-            {
-                DPRINT1("Command '%s' launched successfully\n");
-
-                /* Wait for process termination */
-                WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
-
-                /* Get the exit code */
-                GetExitCodeProcess(ProcessInformation.hProcess, &dwExitCode);
-
-                /* Close handles */
-                CloseHandle(ProcessInformation.hThread);
-                CloseHandle(ProcessInformation.hProcess);
-            }
-            else
-            {
-                DPRINT1("Failed when launched command '%s'\n");
-                dwExitCode = GetLastError();
-            }
-            
-            DosPrintCharacter('\n');
-
-            setAL((UCHAR)dwExitCode);
-
-            break;
-        }
-
-        default:
-        {
-            DPRINT1("Unknown DOS CMD Interpreter BOP Function: 0x%02X\n", FuncNum);
-            // setCF(1); // Disable, otherwise we enter an infinite loop
-            break;
-        }
-    }
-}
-
 BOOLEAN DosBIOSInitialize(VOID)
 {
     PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
@@ -345,16 +253,11 @@ BOOLEAN DosBIOSInitialize(VOID)
 #endif
 
 
-    /* Register the DOS BOPs */
-    RegisterBop(BOP_DOS, DosSystemBop        );
-    RegisterBop(BOP_CMD, DosCmdInterpreterBop);
-
     /* Register the DOS 32-bit Interrupts */
-    // RegisterInt32(0x20, DosInt20h);
-
-    /* TODO: Initialize the DOS kernel */
+    // RegisterDosInt32(0x20, DosInt20h);
 
-    return TRUE;
+    /* Initialize the DOS kernel */
+    return DosKRNLInitialize();
 }
 
 /* EOF */
index 4789c41..c86594d 100644 (file)
 #define NDEBUG
 
 #include "emulator.h"
+#include "callback.h"
+
 #include "dos.h"
 #include "dos/dem.h"
 
 #include "bios/bios.h"
-#include "int32.h"
 #include "registers.h"
 
 /* PRIVATE VARIABLES **********************************************************/
 
+CALLBACK16 DosContext;
+
 static WORD CurrentPsp = SYSTEM_PSP;
 static WORD DosLastError = 0;
 static DWORD DiskTransferArea;
@@ -1669,11 +1672,11 @@ VOID WINAPI DosInt21h(LPWORD Stack)
         /* Set Interrupt Vector */
         case 0x25:
         {
-            DWORD FarPointer = MAKELONG(getDX(), getDS());
+            ULONG FarPointer = MAKELONG(getDX(), getDS());
             DPRINT1("Setting interrupt 0x%x ...\n", getAL());
 
             /* Write the new far pointer to the IDT */
-            ((PDWORD)BaseAddress)[getAL()] = FarPointer;
+            ((PULONG)BaseAddress)[getAL()] = FarPointer;
             break;
         }
 
@@ -2480,6 +2483,7 @@ VOID WINAPI DosFastConOut(LPWORD Stack)
      * for more information.
      */
 
+#if 0
     if (Stack[STACK_COUNTER] == 0)
     {
         Stack[STACK_COUNTER]++;
@@ -2504,6 +2508,20 @@ VOID WINAPI DosFastConOut(LPWORD Stack)
         setAX(Stack[STACK_VAR_A]);
         setBX(Stack[STACK_VAR_B]);
     }
+#else
+    /* Save AX and BX */
+    USHORT AX = getAX();
+    USHORT BX = getBX();
+
+    setBL(DOS_CHAR_ATTRIBUTE);
+    setBH(Bda->VideoPage);
+    setAH(0x0E);
+    Int32Call(&DosContext, 0x10);
+
+    /* Restore AX and BX */
+    setAX(AX);
+    setBX(BX);
+#endif
 }
 
 VOID WINAPI DosInt2Fh(LPWORD Stack)
@@ -2585,15 +2603,17 @@ BOOLEAN DosKRNLInitialize(VOID)
 
 #endif
 
+    /* Initialize the callback context */
+    InitializeContext(&DosContext, 0x0070, 0x0000);
 
     /* Register the DOS 32-bit Interrupts */
-    RegisterInt32(0x20, DosInt20h        );
-    RegisterInt32(0x21, DosInt21h        );
-//  RegisterInt32(0x22, DosInt22h        ); // Termination
-    RegisterInt32(0x23, DosBreakInterrupt); // Ctrl-C / Ctrl-Break
-//  RegisterInt32(0x24, DosInt24h        ); // Critical Error
-    RegisterInt32(0x29, DosFastConOut    ); // DOS 2+ Fast Console Output
-    RegisterInt32(0x2F, DosInt2Fh        );
+    RegisterDosInt32(0x20, DosInt20h        );
+    RegisterDosInt32(0x21, DosInt21h        );
+//  RegisterDosInt32(0x22, DosInt22h        ); // Termination
+    RegisterDosInt32(0x23, DosBreakInterrupt); // Ctrl-C / Ctrl-Break
+//  RegisterDosInt32(0x24, DosInt24h        ); // Critical Error
+    RegisterDosInt32(0x29, DosFastConOut    ); // DOS 2+ Fast Console Output
+    RegisterDosInt32(0x2F, DosInt2Fh        );
 
     return TRUE;
 }
index d122d2d..d82bb1a 100644 (file)
@@ -13,6 +13,8 @@
 
 #include "ntvdm.h"
 
+/**/ #include "callback.h" /**/
+
 /* DEFINES ********************************************************************/
 
 //
@@ -138,6 +140,14 @@ typedef struct _DOS_FIND_FILE_BLOCK
 
 /* FUNCTIONS ******************************************************************/
 
+extern CALLBACK16 DosContext;
+#define RegisterDosInt32(IntNumber, IntHandler) \
+do { \
+    DosContext.NextOffset += RegisterInt32(MAKELONG(DosContext.NextOffset,   \
+                                                    DosContext.Segment),     \
+                                           (IntNumber), (IntHandler), NULL); \
+} while(0);
+
 /*
  * DOS BIOS Functions
  * See bios.c
index 40f12ed..f296719 100644 (file)
@@ -388,7 +388,8 @@ BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
     // if (!VgaInitialize(ConsoleOutput)) return FALSE;
     VgaInitialize(ConsoleOutput);
 
-    /* Register the emulator BOPs */
+    /* Initialize the software callback system and register the emulator BOPs */
+    InitializeCallbacks();
     RegisterBop(BOP_DEBUGGER  , EmulatorDebugBreakBop);
     RegisterBop(BOP_UNSIMULATE, EmulatorUnsimulateBop);