Backup and restore registers when calling out to user funcs.
authorKevin O'Connor <kevin@koconnor.net>
Sun, 14 Mar 2010 03:29:55 +0000 (22:29 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Sun, 14 Mar 2010 03:29:55 +0000 (22:29 -0500)
Make sure to fully backup and restore register state when calling out
to other interrupts and functions.  Some old DOS programs don't fully
restore state.

Also, make sure to enable irqs in call16_simpint().

src/mouse.c
src/util.h

index 8389d2a093d1c847286b2bbd00726f3296ee761f..aba12adad9c5703cfd33c2d49b021e8dafe80b81 100644 (file)
@@ -305,15 +305,17 @@ process_mouse(u8 data)
         return;
     }
 
-    //BX_DEBUG_INT74("int74_function: make_farcall=1\n");
     u16 status = GET_EBDA2(ebda_seg, mouse_data[0]);
     u16 X      = GET_EBDA2(ebda_seg, mouse_data[1]);
     u16 Y      = GET_EBDA2(ebda_seg, mouse_data[2]);
     SET_EBDA2(ebda_seg, mouse_flag1, 0);
 
     struct segoff_s func = GET_EBDA2(ebda_seg, far_call_pointer);
+    dprintf(16, "mouse farcall s=%04x x=%04x y=%04x func=%04x:%04x\n"
+            , status, X, Y, func.seg, func.offset);
 
     asm volatile(
+        "pushl %%ebp\n"
         "sti\n"
 
         "pushl %0\n"
@@ -326,8 +328,8 @@ process_mouse(u8 data)
 
         "cli\n"
         "cld\n"
+        "popl %%ebp"
+        : "+a"(func.segoff), "+c"(status), "+d"(X), "+b"(Y)
         :
-        : "r"(func.segoff), "r"(status), "r"(X), "r"(Y)
-        : "cc"
-        );
+        : "edi", "esi", "cc", "memory");
 }
index 9b4fd3ab3c649f94e5617d29638037cf07ec7729..7c7c6980d87ab30d0bc2a7346fa73a12e6723680 100644 (file)
@@ -144,15 +144,18 @@ static inline u8 readb(const void *addr) {
 #define call16_simpint(nr, peax, pflags) do {                           \
         ASSERT16();                                                     \
         asm volatile(                                                   \
+            "pushl %%ebp\n"                                             \
+            "sti\n"                                                     \
             "stc\n"                                                     \
             "int %2\n"                                                  \
             "pushfl\n"                                                  \
             "popl %1\n"                                                 \
             "cli\n"                                                     \
-            "cld"                                                       \
-            : "+a"(*peax), "=r"(*pflags)                                \
+            "cld\n"                                                     \
+            "popl %%ebp"                                                \
+            : "+a"(*peax), "=c"(*pflags)                                \
             : "i"(nr)                                                   \
-            : "cc", "memory");                                          \
+            : "ebx", "edx", "esi", "edi", "cc", "memory");              \
     } while (0)
 
 // GDT bit manipulation