Interrupts / Add handlers to winedos

Jukka Heinonen jhei at iki.fi
Tue Oct 29 13:17:15 CST 2002


After this patch winedos will contain entry points for all
interrupt handlers even though many of these entry points are just
functions that forward interrupt handling to other DLLs. A bit ugly
way of doing things but I believe this approach makes further interrupt 
work easier.

Next patches shall add winedos16.dll for PM 16-bit entry points and
a small patch after that shall start using interrupts.c tables for
PM and RM interrupts. Then the real work of migrating interrupt handlers
can be started...


Changelog: 
  Modify winedos interrupt handlers so that they work with PM interrupts.
  Add forwarding functions for handlers in other DLLs.
  Make DOSVM_GetBuiltinHandler use static table instead of GetProcAddress.  



Index: dlls/winedos/int20.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/int20.c,v
retrieving revision 1.2
diff -u -r1.2 int20.c
--- dlls/winedos/int20.c        9 Mar 2002 23:44:32 -0000       1.2
+++ dlls/winedos/int20.c        29 Oct 2002 18:53:10 -0000
@@ -30,5 +30,9 @@
  */
 void WINAPI DOSVM_Int20Handler( CONTEXT86 *context )
 {
-    MZ_Exit( context, TRUE, 0 );
+    // FIXME: Is this correct in DOS DPMI?
+    if (ISV86(context))
+        MZ_Exit( context, TRUE, 0 );
+    else
+        ExitThread(0);
 }



Index: dlls/winedos/int21.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/int21.c,v
retrieving revision 1.13
diff -u -r1.13 int21.c
--- dlls/winedos/int21.c        12 Sep 2002 22:07:04 -0000      1.13
+++ dlls/winedos/int21.c        29 Oct 2002 18:54:37 -0000
@@ -72,11 +72,17 @@
 /***********************************************************************
  *           DOSVM_Int21Handler
  *
- * int 21h real-mode handler. Most calls are passed directly to DOS3Call.
+ * int 21h handler. Most calls are passed directly to DOS3Call.
  */
 void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
 {
     BYTE ascii;
+
+    if (DOSVM_IsWin16()) {
+        DOS3Call( context );
+        return;
+    }
+
     RESET_CFLAG(context);  /* Not sure if this is a good idea */
 
     if(AH_reg(context) == 0x0c) /* FLUSH BUFFER AND READ STANDARD INPUT */



Index: dlls/winedos/int31.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/int31.c,v
retrieving revision 1.10
diff -u -r1.10 int31.c
--- dlls/winedos/int31.c        28 Oct 2002 20:12:40 -0000      1.10
+++ dlls/winedos/int31.c        29 Oct 2002 18:55:29 -0000
@@ -614,26 +614,37 @@
     }
 }
 
-
 /**********************************************************************
- *         DOSVM_Int31Handler
+ *         DOSVM_CheckWrappers
  *
- * Handler for real-mode int 31h (DPMI).
+ * Check if this was really a wrapper call instead of an interrupt.
+ * FIXME: Protected mode stuff does not work in 32-bit DPMI.
+ * FIXME: If int31 is called asynchronously (unlikely) 
+ *        wrapper checks are wrong (CS/IP must not be used).
  */
-void WINAPI DOSVM_Int31Handler( CONTEXT86 *context )
+static BOOL DOSVM_CheckWrappers( CONTEXT86 *context )
 {
+    /* Handle protected mode interrupts. */
+    if (!ISV86(context)) {
+        if (context->SegCs == DOSVM_dpmi_segments->dpmi_sel) {
+           INT_Int31Handler( context ); // FIXME: Call RawModeSwitch
+           return TRUE;
+       }
+       return FALSE;
+    }
+
     /* check if it's our wrapper */
     TRACE("called from real mode\n");
     if (context->SegCs==DOSVM_dpmi_segments->dpmi_seg) {
         /* This is the protected mode switch */
         StartPM(context);
-        return;
+        return TRUE;
     }
     else if (context->SegCs==DOSVM_dpmi_segments->xms_seg)
     {
         /* This is the XMS driver entry point */
         XMS_Handler(context);
-        return;
+        return TRUE;
     }
     else
     {
@@ -646,10 +657,57 @@
         if (CurrRMCB) {
             /* RMCB call, propagate to protected-mode handler */
             DPMI_CallRMCBProc(context, CurrRMCB, dpmi_flag);
-            return;
+            return TRUE;
         }
     }
 
-    /* chain to protected mode handler */
-    INT_Int31Handler( context );
+    return FALSE;
+}
+
+/**********************************************************************
+ *         DOSVM_Int31Handler
+ *
+ * Handler for int 31h (DPMI).
+ */
+void WINAPI DOSVM_Int31Handler( CONTEXT86 *context )
+{
+    if (DOSVM_CheckWrappers(context))
+        return;
+
+    RESET_CFLAG(context);
+    switch(AX_reg(context))
+    {
+    case 0x0204:  /* Get protected mode interrupt vector */
+        TRACE("get protected mode interrupt handler (0x%02x)\n",
+             BL_reg(context));
+        if (DOSVM_IsDos32()) {
+            FARPROC48 handler = DOSVM_GetPMHandler48( BL_reg(context) );
+            SET_CX( context, handler.selector );
+            context->Edx = handler.offset;
+        } else {
+            FARPROC16 handler = DOSVM_GetPMHandler16( BL_reg(context) );
+            SET_CX( context, SELECTOROF(handler) );
+            SET_DX( context, OFFSETOF(handler) );
+        }
+        break;
+
+    case 0x0205:  /* Set protected mode interrupt vector */
+        TRACE("set protected mode interrupt handler (0x%02x,0x%04x:0x%08lx)\n",
+             BL_reg(context), CX_reg(context), context->Edx);
+        if (DOSVM_IsDos32()) {
+            FARPROC48 handler;
+            handler.selector = CX_reg(context);
+            handler.offset = context->Edx;
+            DOSVM_SetPMHandler48( BL_reg(context), handler );
+        } else {
+            FARPROC16 handler;
+            handler = (FARPROC16)MAKESEGPTR( CX_reg(context), DX_reg(context)); 
+            DOSVM_SetPMHandler16( BL_reg(context), handler );
+        }
+        break;
+
+    default:
+        /* chain to protected mode handler */
+        INT_Int31Handler( context ); // FIXME: move DPMI code here
+    }  
 }



Index: dlls/winedos/interrupts.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/interrupts.c,v
retrieving revision 1.2
diff -u -r1.2 interrupts.c
--- dlls/winedos/interrupts.c   28 Oct 2002 20:12:40 -0000      1.2
+++ dlls/winedos/interrupts.c   29 Oct 2002 18:56:28 -0000
@@ -24,14 +24,81 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(int);
 
-static FARPROC16 DOSVM_Vectors16[256];
-static FARPROC48 DOSVM_Vectors48[256];
-static INTPROC   DOSVM_VectorsBuiltin[256];
+/*
+ * FIXME: Interrupt handlers for interrupts implemented in other DLLs.
+ *        These functions should be removed when the interrupt handlers have
+ *        been moved to winedos.
+ */
+void WINAPI DOSVM_Int11Handler( CONTEXT86 *context ) { INT_Int11Handler(context); }
+void WINAPI DOSVM_Int12Handler( CONTEXT86 *context ) { INT_Int12Handler(context); }
+void WINAPI DOSVM_Int13Handler( CONTEXT86 *context ) { INT_Int13Handler(context); }
+void WINAPI DOSVM_Int15Handler( CONTEXT86 *context ) { INT_Int15Handler(context); }
+void WINAPI DOSVM_Int1aHandler( CONTEXT86 *context ) { INT_Int1aHandler(context); }
+void WINAPI DOSVM_Int25Handler( CONTEXT86 *context ) { INT_Int25Handler(context); }
+void WINAPI DOSVM_Int26Handler( CONTEXT86 *context ) { INT_Int26Handler(context); }
+void WINAPI DOSVM_Int2aHandler( CONTEXT86 *context ) { INT_Int2aHandler(context); }
+void WINAPI DOSVM_Int2fHandler( CONTEXT86 *context ) { INT_Int2fHandler(context); }
+void WINAPI DOSVM_Int34Handler( CONTEXT86 *context ) { INT_Int34Handler(context); }
+void WINAPI DOSVM_Int35Handler( CONTEXT86 *context ) { INT_Int35Handler(context); }
+void WINAPI DOSVM_Int36Handler( CONTEXT86 *context ) { INT_Int36Handler(context); }
+void WINAPI DOSVM_Int37Handler( CONTEXT86 *context ) { INT_Int37Handler(context); }
+void WINAPI DOSVM_Int38Handler( CONTEXT86 *context ) { INT_Int38Handler(context); }
+void WINAPI DOSVM_Int39Handler( CONTEXT86 *context ) { INT_Int39Handler(context); }
+void WINAPI DOSVM_Int3aHandler( CONTEXT86 *context ) { INT_Int3aHandler(context); }
+void WINAPI DOSVM_Int3bHandler( CONTEXT86 *context ) { INT_Int3bHandler(context); }
+void WINAPI DOSVM_Int3cHandler( CONTEXT86 *context ) { INT_Int3cHandler(context); }
+void WINAPI DOSVM_Int3dHandler( CONTEXT86 *context ) { INT_Int3dHandler(context); }
+void WINAPI DOSVM_Int3eHandler( CONTEXT86 *context ) { INT_Int3eHandler(context); }
+void WINAPI DOSVM_Int41Handler( CONTEXT86 *context ) { INT_Int41Handler(context); }
+void WINAPI DOSVM_Int4bHandler( CONTEXT86 *context ) { INT_Int4bHandler(context); }
+void WINAPI DOSVM_Int5cHandler( CONTEXT86 *context ) { NetBIOSCall16(context); }
+
+static FARPROC16     DOSVM_Vectors16[256];
+static FARPROC48     DOSVM_Vectors48[256];
+static const INTPROC DOSVM_VectorsBuiltin[] =
+{
+  /* 00 */ 0,                  0,                  0,                  0,
+  /* 04 */ 0,                  0,                  0,                  0,
+  /* 08 */ 0,                  DOSVM_Int09Handler, 0,                  0,
+  /* 0C */ 0,                  0,                  0,                  0,
+  /* 10 */ DOSVM_Int10Handler, DOSVM_Int11Handler, DOSVM_Int12Handler, DOSVM_Int13Handler,
+  /* 14 */ 0,                  DOSVM_Int15Handler, DOSVM_Int16Handler, DOSVM_Int17Handler,
+  /* 18 */ 0,                  0,                  DOSVM_Int1aHandler, 0,
+  /* 1C */ 0,                  0,                  0,                  0,
+  /* 20 */ DOSVM_Int20Handler, DOSVM_Int21Handler, 0,                  0,
+  /* 24 */ 0,                  DOSVM_Int25Handler, DOSVM_Int26Handler, 0,
+  /* 28 */ 0,                  DOSVM_Int29Handler, DOSVM_Int2aHandler, 0,
+  /* 2C */ 0,                  0,                  0,                  DOSVM_Int2fHandler,
+  /* 30 */ 0,                  DOSVM_Int31Handler, 0,                  DOSVM_Int33Handler,
+  /* 34 */ DOSVM_Int34Handler, DOSVM_Int35Handler, DOSVM_Int36Handler, DOSVM_Int37Handler,
+  /* 38 */ DOSVM_Int38Handler, DOSVM_Int39Handler, DOSVM_Int3aHandler, DOSVM_Int3bHandler,
+  /* 3C */ DOSVM_Int3cHandler, DOSVM_Int3dHandler, DOSVM_Int3eHandler, 0,
+  /* 40 */ 0,                  DOSVM_Int41Handler, 0,                  0,
+  /* 44 */ 0,                  0,                  0,                  0,
+  /* 48 */ 0,                  0,                  0,                  DOSVM_Int4bHandler,
+  /* 4C */ 0,                  0,                  0,                  0,
+  /* 50 */ 0,                  0,                  0,                  0,
+  /* 54 */ 0,                  0,                  0,                  0,
+  /* 58 */ 0,                  0,                  0,                  0,
+  /* 5C */ DOSVM_Int5cHandler, 0,                  0,                  0,
+  /* 60 */ 0,                  0,                  0,                  0,
+  /* 64 */ 0,                  0,                  0,                  DOSVM_Int67Handler
+};
 
-/* Ordinal number for interrupt 0 handler in winedos.dll and winedos16.dll */
+/* Ordinal number for interrupt 0 handler in winedos16.dll */
 #define FIRST_INTERRUPT 100
 
 /**********************************************************************
+ *         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 )
+{
+}
+
+/**********************************************************************
  *         DOSVM_EmulateInterruptPM
  *
  * Emulate software interrupt in 16-bit or 32-bit protected mode.
@@ -143,11 +210,11 @@
 
 
 /**********************************************************************
- *          DOSVM_SetPMHandler
+ *          DOSVM_SetPMHandler16
  *
  * Set the protected mode interrupt handler for a given interrupt.
  */
-void DOSVM_SetPMHandler( BYTE intnum, FARPROC16 handler )
+void DOSVM_SetPMHandler16( BYTE intnum, FARPROC16 handler )
 {
   TRACE("Set protected mode interrupt vector %02x <- %04x:%04x\n",
        intnum, HIWORD(handler), LOWORD(handler) );
@@ -190,41 +257,12 @@
  */
 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;
+  if (intnum < sizeof(DOSVM_VectorsBuiltin)/sizeof(INTPROC)) {
+    INTPROC proc = DOSVM_VectorsBuiltin[intnum];
+    if(proc)
+      return proc;
   }
 
-  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 )
-{
+  WARN("int%x not implemented, returning dummy handler\n", intnum );
+  return DOSVM_DefaultHandler;
 }



Index: include/miscemu.h
===================================================================
RCS file: /home/wine/wine/include/miscemu.h,v
retrieving revision 1.55
diff -u -r1.55 miscemu.h
--- include/miscemu.h   23 Oct 2002 22:24:10 -0000      1.55
+++ include/miscemu.h   29 Oct 2002 19:00:47 -0000
@@ -240,6 +240,15 @@
 /* msdos/int2f.c */
 extern void WINAPI INT_Int2fHandler(CONTEXT86*);
 
+/* msdos/int41.c */
+extern void WINAPI INT_Int41Handler(CONTEXT86*);
+
+/* msdos/int4b.c */
+extern void WINAPI INT_Int4bHandler(CONTEXT86*);
+
+/* msdos/int5c.c */
+extern void WINAPI NetBIOSCall16(CONTEXT86*);
+
 /* fpu.c */
 extern void WINAPI INT_Int34Handler(CONTEXT86*);
 extern void WINAPI INT_Int35Handler(CONTEXT86*);



Index: dlls/kernel/kernel32.spec
===================================================================
RCS file: /home/wine/wine/dlls/kernel/kernel32.spec,v
retrieving revision 1.66
diff -u -r1.66 kernel32.spec
--- dlls/kernel/kernel32.spec   18 Oct 2002 00:29:33 -0000      1.66
+++ dlls/kernel/kernel32.spec   29 Oct 2002 19:01:29 -0000
@@ -1049,6 +1049,7 @@
 @ stdcall INT_Int15Handler(ptr) INT_Int15Handler
 @ stdcall INT_Int1aHandler(ptr) INT_Int1aHandler
 @ stdcall INT_Int25Handler(ptr) INT_Int25Handler
+@ stdcall INT_Int26Handler(ptr) INT_Int26Handler  
 @ stdcall INT_Int2aHandler(ptr) INT_Int2aHandler
 @ stdcall INT_Int2fHandler(ptr) INT_Int2fHandler
 @ stdcall INT_Int31Handler(ptr) INT_Int31Handler
@@ -1063,6 +1064,9 @@
 @ stdcall INT_Int3cHandler(ptr) INT_Int3cHandler
 @ stdcall INT_Int3dHandler(ptr) INT_Int3dHandler
 @ stdcall INT_Int3eHandler(ptr) INT_Int3eHandler
+@ stdcall INT_Int41Handler(ptr) INT_Int41Handler 
+@ stdcall INT_Int4bHandler(ptr) INT_Int4bHandler 
+@ stdcall NetBIOSCall16(ptr) NetBIOSCall16
 @ cdecl INT_SetPMHandler(long long) INT_SetPMHandler
 @ cdecl LOCAL_Alloc(long long long) LOCAL_Alloc
 @ cdecl LOCAL_Compact(long long long) LOCAL_Compact



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



More information about the wine-patches mailing list