PCem

changeset 99:9bc3bcf7c871

Register operands on BOUND/LEA/LDS/LES/LFS/LGS/LSS now cause invalid opcode faults. Fixes NTVDM.
author TomW
date Sun Apr 27 11:40:03 2014 +0100
parents 4c95696c27d6
children 6d9569f7c970
files src/386_ops.h src/x86_ops_misc.h src/x86_ops_mov.h src/x86_ops_mov_seg.h
diffstat 4 files changed, 31 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- a/src/386_ops.h	Fri Apr 18 11:54:52 2014 +0100
     1.2 +++ b/src/386_ops.h	Sun Apr 27 11:40:03 2014 +0100
     1.3 @@ -3,6 +3,17 @@
     1.4  OpFn *x86_opcodes;
     1.5  OpFn *x86_opcodes_0f;
     1.6  
     1.7 +#define ILLEGAL_ON(cond)                \
     1.8 +        do                              \
     1.9 +        {                               \
    1.10 +                if ((cond))             \
    1.11 +                {                       \
    1.12 +                        pc = oldpc;     \
    1.13 +                        x86illegal();   \
    1.14 +                        return 0;       \
    1.15 +                }                       \
    1.16 +        } while (0)
    1.17 +
    1.18  static inline void PUSH_W(uint16_t val)
    1.19  {
    1.20          if (stack32)
     2.1 --- a/src/x86_ops_misc.h	Fri Apr 18 11:54:52 2014 +0100
     2.2 +++ b/src/x86_ops_misc.h	Sun Apr 27 11:40:03 2014 +0100
     2.3 @@ -539,6 +539,7 @@
     2.4          int16_t low, high;
     2.5          
     2.6          fetch_ea_16(fetchdat);
     2.7 +        ILLEGAL_ON(mod == 3);
     2.8          low = geteaw();
     2.9          high = readmemw(easeg, eaaddr + 2);     if (abrt) return 0;
    2.10          
    2.11 @@ -555,6 +556,7 @@
    2.12          int16_t low, high;
    2.13          
    2.14          fetch_ea_32(fetchdat);
    2.15 +        ILLEGAL_ON(mod == 3);
    2.16          low = geteaw();
    2.17          high = readmemw(easeg, eaaddr + 2);     if (abrt) return 0;
    2.18          
    2.19 @@ -572,6 +574,7 @@
    2.20          int32_t low, high;
    2.21          
    2.22          fetch_ea_16(fetchdat);
    2.23 +        ILLEGAL_ON(mod == 3);
    2.24          low = geteal();
    2.25          high = readmeml(easeg, eaaddr + 4);     if (abrt) return 0;
    2.26          
    2.27 @@ -588,6 +591,7 @@
    2.28          int32_t low, high;
    2.29          
    2.30          fetch_ea_32(fetchdat);
    2.31 +        ILLEGAL_ON(mod == 3);
    2.32          low = geteal();
    2.33          high = readmeml(easeg, eaaddr + 4);     if (abrt) return 0;
    2.34          
     3.1 --- a/src/x86_ops_mov.h	Fri Apr 18 11:54:52 2014 +0100
     3.2 +++ b/src/x86_ops_mov.h	Sun Apr 27 11:40:03 2014 +0100
     3.3 @@ -306,6 +306,7 @@
     3.4  static int opLEA_w_a16(uint32_t fetchdat)
     3.5  {
     3.6          fetch_ea_16(fetchdat);
     3.7 +        ILLEGAL_ON(mod == 3);
     3.8          regs[reg].w = eaaddr;
     3.9          cycles -= timing_rr;
    3.10          return 0;
    3.11 @@ -313,6 +314,7 @@
    3.12  static int opLEA_w_a32(uint32_t fetchdat)
    3.13  {
    3.14          fetch_ea_32(fetchdat);
    3.15 +        ILLEGAL_ON(mod == 3);
    3.16          regs[reg].w = eaaddr;
    3.17          cycles -= timing_rr;
    3.18          return 0;
    3.19 @@ -321,6 +323,7 @@
    3.20  static int opLEA_l_a16(uint32_t fetchdat)
    3.21  {
    3.22          fetch_ea_16(fetchdat);
    3.23 +        ILLEGAL_ON(mod == 3);
    3.24          regs[reg].l = eaaddr & 0xffff;
    3.25          cycles -= timing_rr;
    3.26          return 0;
    3.27 @@ -328,6 +331,7 @@
    3.28  static int opLEA_l_a32(uint32_t fetchdat)
    3.29  {
    3.30          fetch_ea_32(fetchdat);
    3.31 +        ILLEGAL_ON(mod == 3);
    3.32          regs[reg].l = eaaddr;
    3.33          cycles -= timing_rr;
    3.34          return 0;
     4.1 --- a/src/x86_ops_mov_seg.h	Fri Apr 18 11:54:52 2014 +0100
     4.2 +++ b/src/x86_ops_mov_seg.h	Sun Apr 27 11:40:03 2014 +0100
     4.3 @@ -219,6 +219,7 @@
     4.4          uint16_t addr, seg;
     4.5  
     4.6          fetch_ea_16(fetchdat);
     4.7 +        ILLEGAL_ON(mod == 3);
     4.8          addr = readmemw(easeg, eaaddr);
     4.9          seg = readmemw(easeg, eaaddr + 2);      if (abrt) return 0;
    4.10          loadseg(seg, &_ds);                     if (abrt) return 0;
    4.11 @@ -233,6 +234,7 @@
    4.12          uint16_t addr, seg;
    4.13  
    4.14          fetch_ea_32(fetchdat);
    4.15 +        ILLEGAL_ON(mod == 3);
    4.16          addr = readmemw(easeg, eaaddr);
    4.17          seg = readmemw(easeg, eaaddr + 2);      if (abrt) return 0;
    4.18          loadseg(seg, &_ds);                     if (abrt) return 0;
    4.19 @@ -248,6 +250,7 @@
    4.20          uint16_t seg;
    4.21  
    4.22          fetch_ea_16(fetchdat);
    4.23 +        ILLEGAL_ON(mod == 3);
    4.24          addr = readmeml(easeg, eaaddr);
    4.25          seg = readmemw(easeg, eaaddr + 4);      if (abrt) return 0;
    4.26          loadseg(seg, &_ds);                     if (abrt) return 0;
    4.27 @@ -263,6 +266,7 @@
    4.28          uint16_t seg;
    4.29  
    4.30          fetch_ea_32(fetchdat);
    4.31 +        ILLEGAL_ON(mod == 3);
    4.32          addr = readmeml(easeg, eaaddr);
    4.33          seg = readmemw(easeg, eaaddr + 4);      if (abrt) return 0;
    4.34          loadseg(seg, &_ds);                     if (abrt) return 0;
    4.35 @@ -278,6 +282,7 @@
    4.36          uint16_t addr, seg;
    4.37  
    4.38          fetch_ea_16(fetchdat);
    4.39 +        ILLEGAL_ON(mod == 3);
    4.40          addr = readmemw(easeg, eaaddr);
    4.41          seg = readmemw(easeg, eaaddr + 2);      if (abrt) return 0;
    4.42          loadseg(seg, &_ss);                     if (abrt) return 0;
    4.43 @@ -292,6 +297,7 @@
    4.44          uint16_t addr, seg;
    4.45  
    4.46          fetch_ea_32(fetchdat);
    4.47 +        ILLEGAL_ON(mod == 3);
    4.48          addr = readmemw(easeg, eaaddr);
    4.49          seg = readmemw(easeg, eaaddr + 2);      if (abrt) return 0;
    4.50          loadseg(seg, &_ss);                     if (abrt) return 0;
    4.51 @@ -307,6 +313,7 @@
    4.52          uint16_t seg;
    4.53  
    4.54          fetch_ea_16(fetchdat);
    4.55 +        ILLEGAL_ON(mod == 3);
    4.56          addr = readmeml(easeg, eaaddr);
    4.57          seg = readmemw(easeg, eaaddr + 4);      if (abrt) return 0;
    4.58          loadseg(seg, &_ss);                     if (abrt) return 0;
    4.59 @@ -322,6 +329,7 @@
    4.60          uint16_t seg;
    4.61  
    4.62          fetch_ea_32(fetchdat);
    4.63 +        ILLEGAL_ON(mod == 3);
    4.64          addr = readmeml(easeg, eaaddr);
    4.65          seg = readmemw(easeg, eaaddr + 4);      if (abrt) return 0;
    4.66          loadseg(seg, &_ss);                     if (abrt) return 0;
    4.67 @@ -338,6 +346,7 @@
    4.68                  uint16_t addr, seg;                                             \
    4.69                                                                                  \
    4.70                  fetch_ea_16(fetchdat);                                          \
    4.71 +                ILLEGAL_ON(mod == 3);                                           \
    4.72                  addr = readmemw(easeg, eaaddr);                                 \
    4.73                  seg = readmemw(easeg, eaaddr + 2);      if (abrt) return 0;     \
    4.74                  loadseg(seg, &sel);                     if (abrt) return 0;     \
    4.75 @@ -352,6 +361,7 @@
    4.76                  uint16_t addr, seg;                                             \
    4.77                                                                                  \
    4.78                  fetch_ea_32(fetchdat);                                          \
    4.79 +                ILLEGAL_ON(mod == 3);                                           \
    4.80                  addr = readmemw(easeg, eaaddr);                                 \
    4.81                  seg = readmemw(easeg, eaaddr + 2);      if (abrt) return 0;     \
    4.82                  loadseg(seg, &sel);                     if (abrt) return 0;     \
    4.83 @@ -367,6 +377,7 @@
    4.84                  uint16_t seg;                                                   \
    4.85                                                                                  \
    4.86                  fetch_ea_16(fetchdat);                                          \
    4.87 +                ILLEGAL_ON(mod == 3);                                           \
    4.88                  addr = readmeml(easeg, eaaddr);                                 \
    4.89                  seg = readmemw(easeg, eaaddr + 4);      if (abrt) return 0;     \
    4.90                  loadseg(seg, &sel);                     if (abrt) return 0;     \
    4.91 @@ -382,6 +393,7 @@
    4.92                  uint16_t seg;                                                   \
    4.93                                                                                  \
    4.94                  fetch_ea_32(fetchdat);                                          \
    4.95 +                ILLEGAL_ON(mod == 3);                                           \
    4.96                  addr = readmeml(easeg, eaaddr);                                 \
    4.97                  seg = readmemw(easeg, eaaddr + 4);      if (abrt) return 0;     \
    4.98                  loadseg(seg, &sel);                     if (abrt) return 0;     \