Interrupts / Improve winedos infrastructure

Jukka Heinonen jhei at iki.fi
Sun Oct 27 10:14:31 CST 2002


This patch includes a bunch of latent infrastructure improvements.

Changelog:
  Add routines for manipulating protected mode interrupt handlers to
  winedos dll. Add routine for checking if process is Windows process.
  Fix DOSVM_IsDos32 interface. Move real mode interrupt handler 
  manipulation routines to interrupts.c.

Index: dlls/winedos/dosexe.h
===================================================================
RCS file: /home/wine/wine/dlls/winedos/dosexe.h,v
retrieving revision 1.11
diff -u -r1.11 dosexe.h
--- dlls/winedos/dosexe.h       23 Oct 2002 22:24:10 -0000      1.11
+++ dlls/winedos/dosexe.h       27 Oct 2002 15:46:29 -0000
@@ -64,9 +64,8 @@
 extern void WINAPI DOSVM_PIC_ioport_out( WORD port, BYTE val );
 extern void WINAPI DOSVM_SetTimer( UINT ticks );
 extern UINT WINAPI DOSVM_GetTimer( void );
-extern FARPROC16 DOSVM_GetRMHandler( BYTE intnum );
-extern void DOSVM_SetRMHandler( BYTE intnum, FARPROC16 handler );
 extern void DOSVM_RealModeInterrupt( BYTE intnum, CONTEXT86 *context );
+extern BOOL DOSVM_IsWin16(void);
 
 /* devices.c */
 extern void DOSDEV_InstallDOSDevices(void);
@@ -115,7 +114,7 @@
 
 /* int31.c */
 extern void WINAPI DOSVM_Int31Handler(CONTEXT86*);
-extern BOOL WINAPI DOSVM_IsDos32();
+extern BOOL DOSVM_IsDos32(void);
 
 /* int33.c */
 extern void WINAPI DOSVM_Int33Handler(CONTEXT86*);
@@ -125,6 +124,15 @@
 /* int67.c */
 extern void WINAPI DOSVM_Int67Handler(CONTEXT86*);
 extern void WINAPI EMS_Ioctl_Handler(CONTEXT86*);
+
+/* interrupts.c */
+extern FARPROC16 DOSVM_GetRMHandler( BYTE intnum );
+extern void DOSVM_SetRMHandler( BYTE intnum, FARPROC16 handler );
+extern FARPROC16 DOSVM_GetPMHandler16( BYTE intnum );
+extern void DOSVM_SetPMHandler16( BYTE intnum, FARPROC16 handler );
+extern FARPROC48 DOSVM_GetPMHandler48( BYTE intnum );
+extern void DOSVM_SetPMHandler48( BYTE intnum, FARPROC48 handler );
+extern INTPROC DOSVM_GetBuiltinHandler( BYTE intnum );
 
 /* soundblaster.c */
 extern void SB_ioport_out( WORD port, BYTE val );




Index: dlls/winedos/dosvm.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/dosvm.c,v
retrieving revision 1.26
diff -u -r1.26 dosvm.c
--- dlls/winedos/dosvm.c        23 Oct 2002 22:24:10 -0000      1.26
+++ dlls/winedos/dosvm.c        27 Oct 2002 15:47:40 -0000
@@ -624,30 +624,6 @@
 
 #endif
 
-/**********************************************************************
- *         DOSVM_GetRMHandler
- *
- * Return the real mode interrupt vector for a given interrupt.
- */
-FARPROC16 DOSVM_GetRMHandler( BYTE intnum )
-{
-    return ((FARPROC16*)0)[intnum];
-}
-
-
-/**********************************************************************
- *         DOSVM_SetRMHandler
- *
- * Set the real mode interrupt handler for a given interrupt.
- */
-void DOSVM_SetRMHandler( BYTE intnum, FARPROC16 handler )
-{
-    TRACE("Set real mode interrupt vector %02x <- %04x:%04x\n",
-                 intnum, HIWORD(handler), LOWORD(handler) );
-    ((FARPROC16*)0)[intnum] = handler;
-}
-
-
 static const INTPROC real_mode_handlers[] =
 {
     /* 00 */ 0, 0, 0, 0, 0, 0, 0, 0,




Index: dlls/winedos/int31.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/int31.c,v
retrieving revision 1.9
diff -u -r1.9 int31.c
--- dlls/winedos/int31.c        23 Oct 2002 22:24:10 -0000      1.9
+++ dlls/winedos/int31.c        27 Oct 2002 15:48:05 -0000
@@ -69,7 +69,7 @@
  * 
  * Return TRUE if we are in 32-bit protected mode DOS process.
  */
-BOOL DOSVM_IsDos32()
+BOOL DOSVM_IsDos32(void)
 {
   return (dpmi_flag & 1) ? TRUE : FALSE;
 }




Index: dlls/winedos/interrupts.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/interrupts.c,v
retrieving revision 1.1
diff -u -r1.1 interrupts.c
--- dlls/winedos/interrupts.c   23 Oct 2002 22:24:10 -0000      1.1
+++ dlls/winedos/interrupts.c   27 Oct 2002 15:48:48 -0000
@@ -20,9 +20,17 @@
 
 #include "dosexe.h"
 #include "wine/debug.h"
+#include "wine/winbase16.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(int);
 
+static FARPROC16 DOSVM_Vectors16[256];
+static FARPROC48 DOSVM_Vectors48[256];
+static INTPROC   DOSVM_VectorsBuiltin[256];
+
+/* Ordinal number for interrupt 0 handler in winedos.dll and winedos16.dll */
+#define FIRST_INTERRUPT 100
+
 /**********************************************************************
  *         DOSVM_EmulateInterruptPM
  *
@@ -46,15 +54,9 @@
   } else
     islong = FALSE;
 
-  /* FIXME: Remove this check when DPMI32 support has been added */
-  if(islong) {
-    ERR("Interrupts not supported in 32-bit DPMI\n");
-    islong = FALSE;
-  }
-
   if(islong)
   {
-    FARPROC48 addr = {0,0}; /* FIXME: INT_GetPMHandler48( intnum ); */
+    FARPROC48 addr = DOSVM_GetPMHandler48( intnum );
     DWORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp);
     /* Push the flags and return address on the stack */
     *(--stack) = context->EFlags;
@@ -66,7 +68,7 @@
   }
   else
   {
-    FARPROC16 addr = INT_GetPMHandler( intnum );
+    FARPROC16 addr = INT_GetPMHandler( intnum ); // FIXME: DOSVM_GetPMHandler16
     WORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp);
     /* Push the flags and return address on the stack */
     *(--stack) = LOWORD(context->EFlags);
@@ -81,4 +83,148 @@
     context->Esp += islong ? -12 : -6;
   else
     ADD_LOWORD( context->Esp, islong ? -12 : -6 );
+}
+
+/**********************************************************************
+ *          DOSVM_GetRMHandler
+ *
+ * Return the real mode interrupt vector for a given interrupt.
+ */
+FARPROC16 DOSVM_GetRMHandler( BYTE intnum )
+{
+  return ((FARPROC16*)0)[intnum];
+}
+
+/**********************************************************************
+ *          DOSVM_SetRMHandler
+ *
+ * Set the real mode interrupt handler for a given interrupt.
+ */
+void DOSVM_SetRMHandler( BYTE intnum, FARPROC16 handler )
+{
+  TRACE("Set real mode interrupt vector %02x <- %04x:%04x\n",
+       intnum, HIWORD(handler), LOWORD(handler) );
+  ((FARPROC16*)0)[intnum] = handler;
+}
+
+/**********************************************************************
+ *          DOSVM_GetPMHandler16
+ *
+ * Return the protected mode interrupt vector for a given interrupt.
+ */
+FARPROC16 DOSVM_GetPMHandler16( BYTE intnum )
+{
+  static HMODULE16 procs;
+  FARPROC16 handler = DOSVM_Vectors16[intnum];
+
+  if (!handler)
+  {
+    if (!procs &&
+        (procs = GetModuleHandle16( "winedos16" )) < 32 &&
+        (procs = LoadLibrary16( "winedos16" )) < 32)
+    {
+      ERR("could not load winedos16.dll\n");
+      procs = 0;
+      return 0;
+    }
+
+    handler = GetProcAddress16( procs, (LPCSTR)(FIRST_INTERRUPT + intnum));
+    if (!handler) 
+    {
+      WARN("int%x not implemented, returning dummy handler\n", intnum );
+      handler = GetProcAddress16( procs, (LPCSTR)(FIRST_INTERRUPT + 256));
+    }
+
+    DOSVM_Vectors16[intnum] = handler;
+  }
+
+  return handler;
+}
+
+
+/**********************************************************************
+ *          DOSVM_SetPMHandler
+ *
+ * Set the protected mode interrupt handler for a given interrupt.
+ */
+void DOSVM_SetPMHandler( BYTE intnum, FARPROC16 handler )
+{
+  TRACE("Set protected mode interrupt vector %02x <- %04x:%04x\n",
+       intnum, HIWORD(handler), LOWORD(handler) );
+  DOSVM_Vectors16[intnum] = handler;
+}
+
+/**********************************************************************
+ *         DOSVM_GetPMHandler48
+ *
+ * Return the protected mode interrupt vector for a given interrupt.
+ * Used to get 48-bit pointer for 32-bit interrupt handlers in DPMI32.
+ */
+FARPROC48 DOSVM_GetPMHandler48( BYTE intnum )
+{
+  if (!DOSVM_Vectors48[intnum].selector)
+  {
+    DOSVM_Vectors48[intnum].selector = DOSVM_dpmi_segments->int48_sel;
+    DOSVM_Vectors48[intnum].offset = 4 * intnum;
+  }
+  return DOSVM_Vectors48[intnum];
+}
+
+/**********************************************************************
+ *         DOSVM_SetPMHandler48
+ *
+ * Set the protected mode interrupt handler for a given interrupt.
+ * Used to set 48-bit pointer for 32-bit interrupt handlers in DPMI32.
+ */
+void DOSVM_SetPMHandler48( BYTE intnum, FARPROC48 handler )
+{
+  TRACE("Set 32-bit protected mode interrupt vector %02x <- %04x:%08lx\n",
+       intnum, handler.selector, handler.offset );
+  DOSVM_Vectors48[intnum] = handler;
+}
+
+/**********************************************************************
+ *         DOSVM_GetBuiltinHandler
+ *
+ * Return Wine interrupt handler procedure for a given interrupt.
+ */
+INTPROC DOSVM_GetBuiltinHandler( BYTE intnum )
+{
+  static HMODULE procs;
+  INTPROC handler = DOSVM_VectorsBuiltin[intnum];
+
+  if (!handler)
+  {
+    if (!procs)
+      procs = LoadLibraryA( "winedos.dll" );
+
+    if (!procs) 
+    {
+      ERR("could not load winedos.dll\n");
+      return 0;
+    }
+
+    handler = (INTPROC)GetProcAddress( procs, 
+                                      (LPCSTR)(FIRST_INTERRUPT + intnum));
+    if (!handler) 
+    {
+      WARN("int%x not implemented, returning dummy handler\n", intnum );
+      handler = (INTPROC)GetProcAddress( procs, 
+                                        (LPCSTR)(FIRST_INTERRUPT + 256));
+    }
+
+    DOSVM_VectorsBuiltin[intnum] = handler;
+  }
+
+  return handler;
+}
+
+/**********************************************************************
+ *         DOSVM_DefaultHandler
+ *
+ * Default interrupt handler. This will be used to emulate all
+ * interrupts that don't have their own interrupt handler.
+ */
+void WINAPI DOSVM_DefaultHandler( CONTEXT86 *context )
+{
 }




Index: dlls/winedos/module.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/module.c,v
retrieving revision 1.26
diff -u -r1.26 module.c
--- dlls/winedos/module.c       23 Oct 2002 23:35:34 -0000      1.26
+++ dlls/winedos/module.c       27 Oct 2002 15:50:05 -0000
@@ -53,6 +53,18 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(module);
 
+static BOOL DOSVM_isdosexe;
+
+/**********************************************************************
+ *          DOSVM_IsWin16
+ * 
+ * Return TRUE if we are in Windows process.
+ */
+BOOL DOSVM_IsWin16(void)
+{
+  return DOSVM_isdosexe ? FALSE : TRUE;
+}
+
 #ifdef MZ_SUPPORTED
 
 #ifdef HAVE_SYS_MMAN_H
@@ -332,9 +344,13 @@
 
 /***********************************************************************
  *             LoadDosExe (WINEDOS.@)
+ *
+ * Called from Wine loader when a new real-mode DOS process is started.
+ * Loads DOS program into memory and executes the program.
  */
 void WINAPI MZ_LoadImage( LPCSTR filename, HANDLE hFile )
 {
+  DOSVM_isdosexe = TRUE;
   if (MZ_DoLoadImage( hFile, filename, NULL )) MZ_Launch();
 }
 



-- 
Jukka Heinonen <http://www.iki.fi/jhei/>



More information about the wine-patches mailing list