winedos / Fix CPU flag handling when branching to internal interrupts

Jukka Heinonen jhei at iki.fi
Sat Aug 16 11:20:15 CDT 2003


This patch fixes a bug where branching to internal interrupts caused
original flags to be lost (and modified flags to be lost in case
of real mode). This for example made asynchronous interrupts
change original application flags every now and then which caused quite
a few DOS programs to fail.




Changelog:
  Fix CPU flag handling when internal interrupts are branched to.




Index: dlls/winedos/interrupts.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/interrupts.c,v
retrieving revision 1.17
diff -u -r1.17 interrupts.c
--- dlls/winedos/interrupts.c	1 Jul 2003 03:37:41 -0000	1.17
+++ dlls/winedos/interrupts.c	16 Aug 2003 16:03:53 -0000
@@ -261,6 +261,11 @@
     }
     else if (context->SegCs == DOSVM_dpmi_segments->int48_sel)
     {
+        /* Restore original flags stored into the stack by the caller. */
+        DWORD *stack = CTX_SEG_OFF_TO_LIN(context, 
+                                          context->SegSs, context->Esp);
+        context->EFlags = stack[2];
+
         if (intnum != context->Eip / DOSVM_STUB_PM48)
             WARN( "interrupt stub has been modified "
                   "(interrupt is %02x, interrupt stub is %02lx)\n",
@@ -277,6 +282,11 @@
     }
     else if (context->SegCs == DOSVM_dpmi_segments->int16_sel)
     {
+        /* Restore original flags stored into the stack by the caller. */
+        WORD *stack = CTX_SEG_OFF_TO_LIN(context, 
+                                         context->SegSs, context->Esp);
+        context->EFlags = (DWORD)MAKELONG( stack[2], HIWORD(context->EFlags) );
+
         if (intnum != context->Eip / DOSVM_STUB_PM16)
             WARN( "interrupt stub has been modified "
                   "(interrupt is %02x, interrupt stub is %02lx)\n",
@@ -436,6 +446,11 @@
     /* check if the call is from our fake BIOS interrupt stubs */
     if (context->SegCs==0xf000)
     {
+        /* Restore original flags stored into the stack by the caller. */
+        WORD *stack = CTX_SEG_OFF_TO_LIN(context, 
+                                         context->SegSs, context->Esp);
+        context->EFlags = (DWORD)MAKELONG( stack[2], HIWORD(context->EFlags) );
+
         if (intnum != context->Eip / DOSVM_STUB_RM)
             WARN( "interrupt stub has been modified "
                   "(interrupt is %02x, interrupt stub is %02lx)\n",
@@ -444,6 +459,9 @@
         TRACE( "builtin interrupt %02x has been branched to\n", intnum );
         
         DOSVM_CallBuiltinHandler( context, intnum );
+
+        /* Real mode stubs use IRET so we must put flags back into stack. */
+        stack[2] = LOWORD(context->EFlags);
     }
     else
     {




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



More information about the wine-patches mailing list