PCem

changeset 5:fe9cf232a465

Fixed ESP value in CALL far when page fault occurs between selector and PC push. Fixes MS Plus!.
author TomW
date Tue Jun 25 21:46:25 2013 +0100
parents 342c3f6cee85
children 83ee72aa1453
files src/x86_ops_call.h
diffstat 1 files changed, 13 insertions(+), 7 deletions(-) [+]
line diff
     1.1 --- a/src/x86_ops_call.h	Mon Jun 24 20:42:35 2013 +0100
     1.2 +++ b/src/x86_ops_call.h	Tue Jun 25 21:46:25 2013 +0100
     1.3 @@ -13,13 +13,15 @@
     1.4          oldss = ss;                                                             \
     1.5          if (cgate32)                                                            \
     1.6          {                                                                       \
     1.7 +                uint32_t old_esp = ESP;                                         \
     1.8                  PUSH_L(old_cs);                         if (abrt) { cgate16 = cgate32 = 0; return 0; }     \
     1.9 -                PUSH_L(old_pc);                                                 \
    1.10 +                PUSH_L(old_pc);                         if (abrt) ESP = old_esp; \
    1.11          }                                                                       \
    1.12          else                                                                    \
    1.13          {                                                                       \
    1.14 +                uint32_t old_esp = ESP;                                         \
    1.15                  PUSH_W(old_cs);                         if (abrt) { cgate16 = cgate32 = 0; return 0; }     \
    1.16 -                PUSH_W(old_pc);                                                 \
    1.17 +                PUSH_W(old_pc);                         if (abrt) ESP = old_esp; \
    1.18          }
    1.19          
    1.20  #define CALL_FAR_l(new_seg, new_pc)                                             \
    1.21 @@ -37,13 +39,15 @@
    1.22          oldss = ss;                                                             \
    1.23          if (cgate16)                                                            \
    1.24          {                                                                       \
    1.25 +                uint32_t old_esp = ESP;                                         \
    1.26                  PUSH_W(old_cs);                         if (abrt) { cgate16 = cgate32 = 0; return 0; }     \
    1.27 -                PUSH_W(old_pc);                                                 \
    1.28 +                PUSH_W(old_pc);                         if (abrt) ESP = old_esp; \
    1.29          }                                                                       \
    1.30          else                                                                    \
    1.31          {                                                                       \
    1.32 +                uint32_t old_esp = ESP;                                         \
    1.33                  PUSH_L(old_cs);                         if (abrt) { cgate16 = cgate32 = 0; return 0; }     \
    1.34 -                PUSH_L(old_pc);                                                 \
    1.35 +                PUSH_L(old_pc);                         if (abrt) ESP = old_esp; \
    1.36          }
    1.37          
    1.38  
    1.39 @@ -58,17 +62,19 @@
    1.40          if (msw & 1) loadcscall(new_seg);                                       \
    1.41          else         loadcs(new_seg);                                           \
    1.42          optype = 0;                                                             \
    1.43 -        if (abrt) { cgate16 = cgate32 = 0; break; }                          \
    1.44 +        if (abrt) { cgate16 = cgate32 = 0; break; }                             \
    1.45          oldss = ss;                                                             \
    1.46          if (cgate32)                                                            \
    1.47          {                                                                       \
    1.48 +                uint32_t old_esp = ESP;                                         \
    1.49                  PUSH_L(old_cs);                         if (abrt) { cgate16 = cgate32 = 0; break; }     \
    1.50 -                PUSH_L(old_pc);                                                 \
    1.51 +                PUSH_L(old_pc);                         if (abrt) ESP = old_esp; \
    1.52          }                                                                       \
    1.53          else                                                                    \
    1.54          {                                                                       \
    1.55 +                uint32_t old_esp = ESP;                                         \
    1.56                  PUSH_W(old_cs);                         if (abrt) { cgate16 = cgate32 = 0; break; }     \
    1.57 -                PUSH_W(old_pc);                                                 \
    1.58 +                PUSH_W(old_pc);                         if (abrt) ESP = old_esp; \
    1.59          }                                                                       \
    1.60          
    1.61  static int opCALL_far_w(uint32_t fetchdat)