winedos / Fix CPU flag handling when branching to internal interrupts

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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/>


[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux