PCem

changeset 142:bd46c39a78e8

Implemented selector limits on some instructions - fixes LBA2. GPFs in real mode now work. Selectors correctly zeroed on far return to lower privilege.
author TomW
date Wed Aug 13 20:33:56 2014 +0100
parents 7734b12d55f0
children 8523e78e0e48
files src/386.c src/808x.c src/ibm.h src/x86.h src/x86_ops_call.h src/x86_ops_flag.h src/x86_ops_jump.h src/x86_ops_misc.h src/x86_ops_mmx_mov.h src/x86_ops_mov.h src/x86_ops_mov_seg.h src/x86_ops_prefix.h src/x86_ops_ret.h src/x86_ops_stack.h src/x86_ops_string.h src/x86seg.c
diffstat 16 files changed, 404 insertions(+), 462 deletions(-) [+]
line diff
     1.1 --- a/src/386.c	Sun Aug 03 20:38:04 2014 +0100
     1.2 +++ b/src/386.c	Wed Aug 13 20:33:56 2014 +0100
     1.3 @@ -10,6 +10,9 @@
     1.4  #include "timer.h"
     1.5  #include "video.h"
     1.6  
     1.7 +
     1.8 +x86seg *ea_seg;
     1.9 +
    1.10  int nmi_enable = 1;
    1.11  
    1.12  int inscounts[256];
    1.13 @@ -39,6 +42,27 @@
    1.14                                  } \
    1.15                          }
    1.16  
    1.17 +#define CHECK_READ(seg, low, high)  \
    1.18 +        if ((low < (seg)->limit_low) || (high > (seg)->limit_high))       \
    1.19 +        {                                       \
    1.20 +                x86gpf("Limit check", 0);       \
    1.21 +                return 0;                       \
    1.22 +        }
    1.23 +
    1.24 +#define CHECK_WRITE(seg, low, high)  \
    1.25 +        if ((low < (seg)->limit_low) || (high > (seg)->limit_high))       \
    1.26 +        {                                       \
    1.27 +                x86gpf("Limit check", 0);       \
    1.28 +                return 0;                       \
    1.29 +        }
    1.30 +
    1.31 +#define CHECK_WRITE_REP(seg, low, high)  \
    1.32 +        if ((low < (seg)->limit_low) || (high > (seg)->limit_high))       \
    1.33 +        {                                       \
    1.34 +                x86gpf("Limit check", 0);       \
    1.35 +                break;                       \
    1.36 +        }
    1.37 +
    1.38  
    1.39  int cpl_override=0;
    1.40  
    1.41 @@ -206,8 +230,8 @@
    1.42  static inline void fetch_ea_32_long(uint32_t rmdat)
    1.43  {
    1.44          eal_r = eal_w = NULL;
    1.45 -        easeg = ds;
    1.46 -        ea_rseg = DS;
    1.47 +        easeg = ea_seg->base;
    1.48 +        ea_rseg = ea_seg->seg;
    1.49          if (rm == 4)
    1.50          {
    1.51                  uint8_t sib = rmdat >> 8;
    1.52 @@ -231,10 +255,11 @@
    1.53                  /*SIB byte present*/
    1.54                  if ((sib & 7) == 5 && !mod) 
    1.55                          eaaddr = getlong();
    1.56 -                else if ((sib & 6) == 4)
    1.57 +                else if ((sib & 6) == 4 && !ssegs)
    1.58                  {
    1.59                          easeg = ss;
    1.60                          ea_rseg = SS;
    1.61 +                        ea_seg = &_ss;
    1.62                  }
    1.63                  if (((sib >> 3) & 7) != 4) 
    1.64                          eaaddr += regs[(sib >> 3) & 7].l << (sib >> 6);
    1.65 @@ -244,10 +269,11 @@
    1.66                  eaaddr = regs[rm].l;
    1.67                  if (mod) 
    1.68                  {
    1.69 -                        if (rm == 5)
    1.70 +                        if (rm == 5 && !ssegs)
    1.71                          {
    1.72                                  easeg = ss;
    1.73                                  ea_rseg = SS;
    1.74 +                                ea_seg = &_ss;
    1.75                          }
    1.76                          if (mod == 1) 
    1.77                          { 
    1.78 @@ -276,11 +302,11 @@
    1.79  static inline void fetch_ea_16_long(uint32_t rmdat)
    1.80  {
    1.81          eal_r = eal_w = NULL;
    1.82 +        easeg = ea_seg->base;
    1.83 +        ea_rseg = ea_seg->seg;
    1.84          if (!mod && rm == 6) 
    1.85          { 
    1.86                  eaaddr = getword();
    1.87 -                easeg = ds; 
    1.88 -                ea_rseg = DS; 
    1.89          }
    1.90          else
    1.91          {
    1.92 @@ -297,9 +323,12 @@
    1.93                          break;
    1.94                  }
    1.95                  eaaddr += (*mod1add[0][rm]) + (*mod1add[1][rm]);
    1.96 -                easeg = *mod1seg[rm];
    1.97 -                if (mod1seg[rm] == &ss) ea_rseg = SS;
    1.98 -                else                    ea_rseg = DS;
    1.99 +                if (mod1seg[rm] == &ss && !ssegs)
   1.100 +                {
   1.101 +                        easeg = ss;
   1.102 +                        ea_rseg = SS;
   1.103 +                        ea_seg = &_ss;
   1.104 +                }
   1.105                  eaaddr &= 0xFFFF;
   1.106          }
   1.107          if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC)
   1.108 @@ -328,7 +357,6 @@
   1.109          }
   1.110          else
   1.111          {
   1.112 -                if (ssegs) ss=oldss;
   1.113                  if (stack32)
   1.114                  {
   1.115                          writememw(ss,ESP-2,flags);
   1.116 @@ -365,7 +393,6 @@
   1.117          }
   1.118          else
   1.119          {
   1.120 -                if (ssegs) ss=oldss;
   1.121                  if (stack32)
   1.122                  {
   1.123                          writememw(ss,ESP-2,flags);
   1.124 @@ -418,7 +445,6 @@
   1.125          uint8_t temp2;
   1.126          uint16_t tempw,tempw2,of;
   1.127          uint32_t ipc=oldpc;//pc-1;
   1.128 -        int changeds=0;
   1.129          uint32_t oldds;
   1.130          uint32_t rep32=op32;
   1.131          uint32_t templ,templ2;
   1.132 @@ -446,43 +472,23 @@
   1.133                  pc=ipc+1;
   1.134                  break;
   1.135                  case 0x26: case 0x126: case 0x226: case 0x326: /*ES:*/
   1.136 -                oldds=ds;
   1.137 -                ds=es;
   1.138 -                rds=ES;
   1.139 -                changeds=1;
   1.140 +                ea_seg = &_es;
   1.141                  goto startrep;
   1.142                  break;
   1.143                  case 0x2E: case 0x12E: case 0x22E: case 0x32E: /*CS:*/
   1.144 -                oldds=ds;
   1.145 -                ds=cs;
   1.146 -                rds=CS;
   1.147 -                changeds=1;
   1.148 +                ea_seg = &_cs;
   1.149                  goto startrep;
   1.150 -                break;
   1.151                  case 0x36: case 0x136: case 0x236: case 0x336: /*SS:*/
   1.152 -                oldds=ds;
   1.153 -                ds=ss;
   1.154 -                rds=SS;
   1.155 -                changeds=1;
   1.156 +                ea_seg = &_ss;
   1.157                  goto startrep;
   1.158 -                break;
   1.159                  case 0x3E: case 0x13E: case 0x23E: case 0x33E: /*DS:*/
   1.160 -                oldds=ds;
   1.161 -                ds=ds;
   1.162 -                changeds=1;
   1.163 +                ea_seg = &_ds;
   1.164                  goto startrep;
   1.165 -                break;
   1.166                  case 0x64: case 0x164: case 0x264: case 0x364: /*FS:*/
   1.167 -                oldds=ds;
   1.168 -                ds=fs;
   1.169 -                rds=FS;
   1.170 -                changeds=1;
   1.171 +                ea_seg = &_fs;
   1.172                  goto startrep;
   1.173                  case 0x65: case 0x165: case 0x265: case 0x365: /*GS:*/
   1.174 -                oldds=ds;
   1.175 -                ds=gs;
   1.176 -                rds=GS;
   1.177 -                changeds=1;
   1.178 +                ea_seg = &_gs;
   1.179                  goto startrep;
   1.180                  case 0x66: case 0x166: case 0x266: case 0x366: /*Data size prefix*/
   1.181                  rep32^=0x100;
   1.182 @@ -502,7 +508,7 @@
   1.183                          c--;
   1.184                          cycles-=15;
   1.185                  }
   1.186 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.187 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.188                  else firstrepcycle=1;
   1.189                  break;
   1.190                  case 0x26C: case 0x36C: /*REP INSB*/
   1.191 @@ -517,7 +523,7 @@
   1.192                          c--;
   1.193                          cycles-=15;
   1.194                  }
   1.195 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.196 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.197                  else firstrepcycle=1;
   1.198                  break;
   1.199                  case 0x6D: /*REP INSW*/
   1.200 @@ -531,7 +537,7 @@
   1.201                          c--;
   1.202                          cycles-=15;
   1.203                  }
   1.204 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.205 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.206                  else firstrepcycle=1;
   1.207                  break;
   1.208                  case 0x16D: /*REP INSL*/
   1.209 @@ -545,7 +551,7 @@
   1.210                          c--;
   1.211                          cycles-=15;
   1.212                  }
   1.213 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.214 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.215                  else firstrepcycle=1;
   1.216                  break;
   1.217                  case 0x26D: /*REP INSW*/
   1.218 @@ -559,7 +565,7 @@
   1.219                          c--;
   1.220                          cycles-=15;
   1.221                  }
   1.222 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.223 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.224                  else firstrepcycle=1;
   1.225                  break;
   1.226                  case 0x36D: /*REP INSL*/
   1.227 @@ -573,13 +579,13 @@
   1.228                          c--;
   1.229                          cycles-=15;
   1.230                  }
   1.231 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.232 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.233                  else firstrepcycle=1;
   1.234                  break;
   1.235                  case 0x6E: case 0x16E: /*REP OUTSB*/
   1.236                  if (c>0)
   1.237                  {
   1.238 -                        temp2=readmemb(ds,SI);
   1.239 +                        temp2 = readmemb(ea_seg->base, SI);
   1.240                          if (abrt) break;
   1.241                          checkio_perm(DX);
   1.242                          outb(DX,temp2);
   1.243 @@ -588,13 +594,13 @@
   1.244                          c--;
   1.245                          cycles-=14;
   1.246                  }
   1.247 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.248 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.249                  else firstrepcycle=1;
   1.250                  break;
   1.251                  case 0x26E: case 0x36E: /*REP OUTSB*/
   1.252                  if (c>0)
   1.253                  {
   1.254 -                        temp2=readmemb(ds,ESI);
   1.255 +                        temp2 = readmemb(ea_seg->base, ESI);
   1.256                          if (abrt) break;
   1.257                          checkio_perm(DX);
   1.258                          outb(DX,temp2);
   1.259 @@ -603,13 +609,13 @@
   1.260                          c--;
   1.261                          cycles-=14;
   1.262                  }
   1.263 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.264 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.265                  else firstrepcycle=1;
   1.266                  break;
   1.267                  case 0x6F: /*REP OUTSW*/
   1.268                  if (c>0)
   1.269                  {
   1.270 -                        tempw=readmemw(ds,SI);
   1.271 +                        tempw = readmemw(ea_seg->base, SI);
   1.272                          if (abrt) break;
   1.273  //                        pclog("OUTSW %04X -> %04X\n",SI,tempw);
   1.274                          outw(DX,tempw);
   1.275 @@ -618,13 +624,13 @@
   1.276                          c--;
   1.277                          cycles-=14;
   1.278                  }
   1.279 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.280 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.281                  else firstrepcycle=1;
   1.282                  break;
   1.283                  case 0x16F: /*REP OUTSL*/
   1.284                  if (c > 0)
   1.285                  {
   1.286 -                        templ = readmeml(ds, SI);
   1.287 +                        templ = readmeml(ea_seg->base, SI);
   1.288                          if (abrt) break;
   1.289                          outl(DX, templ);
   1.290                          if (flags & D_FLAG) SI -= 4;
   1.291 @@ -632,13 +638,13 @@
   1.292                          c--;
   1.293                          cycles -= 14;
   1.294                  }
   1.295 -                if (c > 0) { firstrepcycle = 0; pc = ipc; if (ssegs) ssegs++; }
   1.296 +                if (c > 0) { firstrepcycle = 0; pc = ipc; }
   1.297                  else firstrepcycle = 1;
   1.298                  break;
   1.299                  case 0x26F: /*REP OUTSW*/
   1.300                  if (c>0)
   1.301                  {
   1.302 -                        tempw=readmemw(ds,ESI);
   1.303 +                        tempw = readmemw(ea_seg->base, ESI);
   1.304                          if (abrt) break;
   1.305                          outw(DX,tempw);
   1.306                          if (flags&D_FLAG) ESI-=2;
   1.307 @@ -646,13 +652,13 @@
   1.308                          c--;
   1.309                          cycles-=14;
   1.310                  }
   1.311 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.312 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.313                  else firstrepcycle=1;
   1.314                  break;
   1.315                  case 0x36F: /*REP OUTSL*/
   1.316                  if (c > 0)
   1.317                  {
   1.318 -                        templ = readmeml(ds, ESI);
   1.319 +                        templ = readmeml(ea_seg->base, ESI);
   1.320                          if (abrt) break;
   1.321                          outl(DX, templ);
   1.322                          if (flags & D_FLAG) ESI -= 4;
   1.323 @@ -660,7 +666,7 @@
   1.324                          c--;
   1.325                          cycles -= 14;
   1.326                  }
   1.327 -                if (c > 0) { firstrepcycle = 0; pc = ipc; if (ssegs) ssegs++; }
   1.328 +                if (c > 0) { firstrepcycle = 0; pc = ipc; }
   1.329                  else firstrepcycle = 1;
   1.330                  break;
   1.331                  case 0x90: case 0x190: /*REP NOP*/
   1.332 @@ -669,7 +675,8 @@
   1.333                  case 0xA4: case 0x1A4: /*REP MOVSB*/
   1.334                  if (c>0)
   1.335                  {
   1.336 -                        temp2=readmemb(ds,SI);  if (abrt) break;
   1.337 +                        CHECK_WRITE_REP(&_es, DI, DI);
   1.338 +                        temp2 = readmemb(ea_seg->base, SI); if (abrt) break;
   1.339                          writememb(es,DI,temp2); if (abrt) break;
   1.340  //                        if (output==3) pclog("MOVSB %08X:%04X -> %08X:%04X %02X\n",ds,SI,es,DI,temp2);
   1.341                          if (flags&D_FLAG) { DI--; SI--; }
   1.342 @@ -677,39 +684,42 @@
   1.343                          c--;
   1.344                          cycles-=(is486)?3:4;
   1.345                  }
   1.346 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.347 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.348                  else firstrepcycle=1;
   1.349                  break;
   1.350                  case 0x2A4: case 0x3A4: /*REP MOVSB*/
   1.351                  if (c>0)
   1.352                  {
   1.353 -                        temp2=readmemb(ds,ESI);  if (abrt) break;
   1.354 +                        CHECK_WRITE_REP(&_es, EDI, EDI);
   1.355 +                        temp2 = readmemb(ea_seg->base, ESI); if (abrt) break;
   1.356                          writememb(es,EDI,temp2); if (abrt) break;
   1.357                          if (flags&D_FLAG) { EDI--; ESI--; }
   1.358                          else              { EDI++; ESI++; }
   1.359                          c--;
   1.360                          cycles-=(is486)?3:4;
   1.361                  }
   1.362 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.363 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.364                  else firstrepcycle=1;
   1.365                  break;
   1.366                  case 0xA5: /*REP MOVSW*/
   1.367                  if (c>0)
   1.368                  {
   1.369 -                        tempw=readmemw(ds,SI);  if (abrt) break;
   1.370 +                        CHECK_WRITE_REP(&_es, DI, DI+1);
   1.371 +                        tempw = readmemw(ea_seg->base, SI); if (abrt) break;
   1.372                          writememw(es,DI,tempw); if (abrt) break;
   1.373                          if (flags&D_FLAG) { DI-=2; SI-=2; }
   1.374                          else              { DI+=2; SI+=2; }
   1.375                          c--;
   1.376                          cycles-=(is486)?3:4;
   1.377                  }
   1.378 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.379 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.380                  else firstrepcycle=1;
   1.381                  break;
   1.382                  case 0x1A5: /*REP MOVSL*/
   1.383                  if (c>0)
   1.384                  {
   1.385 -                        templ=readmeml(ds,SI);  if (abrt) break;
   1.386 +                        CHECK_WRITE_REP(&_es, DI, DI+3);
   1.387 +                        templ = readmeml(ea_seg->base, SI); if (abrt) break;
   1.388  //                        pclog("MOVSD %08X from %08X to %08X (%04X:%08X)\n", templ, ds+SI, es+DI, CS, pc);
   1.389                          writememl(es,DI,templ); if (abrt) break;
   1.390                          if (flags&D_FLAG) { DI-=4; SI-=4; }
   1.391 @@ -717,13 +727,14 @@
   1.392                          c--;
   1.393                          cycles-=(is486)?3:4;
   1.394                  }
   1.395 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.396 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.397                  else firstrepcycle=1;
   1.398                  break;
   1.399                  case 0x2A5: /*REP MOVSW*/
   1.400                  if (c>0)
   1.401                  {
   1.402 -                        tempw=readmemw(ds,ESI);  if (abrt) break;
   1.403 +                        CHECK_WRITE_REP(&_es, EDI, EDI+1);
   1.404 +                        tempw = readmemw(ea_seg->base, ESI); if (abrt) break;
   1.405                          writememw(es,EDI,tempw); if (abrt) break;
   1.406  //                        if (output) pclog("Written %04X from %08X to %08X %i  %08X %04X %08X %04X\n",tempw,ds+ESI,es+EDI,c,ds,ES,es,ES);
   1.407                          if (flags&D_FLAG) { EDI-=2; ESI-=2; }
   1.408 @@ -731,13 +742,14 @@
   1.409                          c--;
   1.410                          cycles-=(is486)?3:4;
   1.411                  }
   1.412 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.413 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.414                  else firstrepcycle=1;
   1.415                  break;
   1.416                  case 0x3A5: /*REP MOVSL*/
   1.417                  if (c>0)
   1.418                  {
   1.419 -                        templ=readmeml(ds,ESI); if (abrt) break;
   1.420 +                        CHECK_WRITE_REP(&_es, EDI, EDI+3);
   1.421 +                        templ = readmeml(ea_seg->base, ESI); if (abrt) break;
   1.422  //                        if ((EDI&0xFFFF0000)==0xA0000) cycles-=12;
   1.423                          writememl(es,EDI,templ); if (abrt) break;
   1.424  //                        if (output) pclog("Load %08X from %08X to %08X  %04X %08X  %04X %08X\n",templ,ESI,EDI,DS,ds,ES,es);
   1.425 @@ -746,14 +758,14 @@
   1.426                          c--;
   1.427                          cycles-=(is486)?3:4;
   1.428                  }
   1.429 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.430 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.431                  else firstrepcycle=1;
   1.432                  break;
   1.433                  case 0xA6: case 0x1A6: /*REP CMPSB*/
   1.434                  tempz = (fv) ? 1 : 0;
   1.435                  if ((c>0) && (fv==tempz))
   1.436                  {
   1.437 -                        temp=readmemb(ds,SI);
   1.438 +                        temp = readmemb(ea_seg->base, SI);
   1.439                          temp2=readmemb(es,DI);
   1.440                          if (abrt) { flags=of; break; }
   1.441                          if (flags&D_FLAG) { DI--; SI--; }
   1.442 @@ -763,14 +775,14 @@
   1.443                          setsub8(temp,temp2);
   1.444                          tempz = (ZF_SET()) ? 1 : 0;
   1.445                  }
   1.446 -                if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.447 +                if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
   1.448                  else firstrepcycle=1;
   1.449                  break;
   1.450                  case 0x2A6: case 0x3A6: /*REP CMPSB*/
   1.451                  tempz = (fv) ? 1 : 0;
   1.452                  if ((c>0) && (fv==tempz))
   1.453                  {
   1.454 -                        temp=readmemb(ds,ESI);
   1.455 +                        temp = readmemb(ea_seg->base, ESI);
   1.456                          temp2=readmemb(es,EDI);
   1.457                          if (abrt) { flags=of; break; }
   1.458                          if (flags&D_FLAG) { EDI--; ESI--; }
   1.459 @@ -780,7 +792,7 @@
   1.460                          setsub8(temp,temp2);
   1.461                          tempz = (ZF_SET()) ? 1 : 0;
   1.462                  }
   1.463 -                if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.464 +                if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
   1.465                  else firstrepcycle=1;
   1.466                  break;
   1.467                  case 0xA7: /*REP CMPSW*/
   1.468 @@ -788,7 +800,7 @@
   1.469                  if ((c>0) && (fv==tempz))
   1.470                  {
   1.471  //                        pclog("CMPSW %05X %05X  %08X %08X   ", ds+SI, es+DI, readlookup2[(ds+SI)>>12], readlookup2[(es+DI)>>12]);
   1.472 -                        tempw=readmemw(ds,SI);
   1.473 +                        tempw = readmemw(ea_seg->base, SI);
   1.474                          tempw2=readmemw(es,DI);
   1.475  //                        pclog("%04X %04X %02X\n", tempw, tempw2, ram[8]);
   1.476  
   1.477 @@ -800,14 +812,14 @@
   1.478                          setsub16(tempw,tempw2);
   1.479                          tempz = (ZF_SET()) ? 1 : 0;
   1.480                  }
   1.481 -                if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.482 +                if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
   1.483                  else firstrepcycle=1;
   1.484                  break;
   1.485                  case 0x1A7: /*REP CMPSL*/
   1.486                  tempz = (fv) ? 1 : 0;
   1.487                  if ((c>0) && (fv==tempz))
   1.488                  {
   1.489 -                        templ=readmeml(ds,SI);
   1.490 +                        templ = readmeml(ea_seg->base, SI);
   1.491                          templ2=readmeml(es,DI);
   1.492                          if (abrt) { flags=of; break; }
   1.493                          if (flags&D_FLAG) { DI-=4; SI-=4; }
   1.494 @@ -817,14 +829,14 @@
   1.495                          setsub32(templ,templ2);
   1.496                          tempz = (ZF_SET()) ? 1 : 0;
   1.497                  }
   1.498 -                if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.499 +                if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
   1.500                  else firstrepcycle=1;
   1.501                  break;
   1.502                  case 0x2A7: /*REP CMPSW*/
   1.503                  tempz = (fv) ? 1 : 0;
   1.504                  if ((c>0) && (fv==tempz))
   1.505                  {
   1.506 -                        tempw=readmemw(ds,ESI);
   1.507 +                        tempw = readmemw(ea_seg->base, ESI);
   1.508                          tempw2=readmemw(es,EDI);
   1.509                          if (abrt) { flags=of; break; }
   1.510                          if (flags&D_FLAG) { EDI-=2; ESI-=2; }
   1.511 @@ -834,14 +846,14 @@
   1.512                          setsub16(tempw,tempw2);
   1.513                          tempz = (ZF_SET()) ? 1 : 0;
   1.514                  }
   1.515 -                if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.516 +                if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
   1.517                  else firstrepcycle=1;
   1.518                  break;
   1.519                  case 0x3A7: /*REP CMPSL*/
   1.520                  tempz = (fv) ? 1 : 0;
   1.521                  if ((c>0) && (fv==tempz))
   1.522                  {
   1.523 -                        templ=readmeml(ds,ESI);
   1.524 +                        templ = readmeml(ea_seg->base, ESI);
   1.525                          templ2=readmeml(es,EDI);
   1.526                          if (abrt) { flags=of; break; }
   1.527                          if (flags&D_FLAG) { EDI-=4; ESI-=4; }
   1.528 @@ -851,13 +863,14 @@
   1.529                          setsub32(templ,templ2);
   1.530                          tempz = (ZF_SET()) ? 1 : 0;
   1.531                  }
   1.532 -                if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.533 +                if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
   1.534                  else firstrepcycle=1;
   1.535                  break;
   1.536  
   1.537                  case 0xAA: case 0x1AA: /*REP STOSB*/
   1.538                  if (c>0)
   1.539                  {
   1.540 +                        CHECK_WRITE_REP(&_es, DI, DI);
   1.541                          writememb(es,DI,AL);
   1.542                          if (abrt) break;
   1.543                          if (flags&D_FLAG) DI--;
   1.544 @@ -865,12 +878,13 @@
   1.545                          c--;
   1.546                          cycles-=(is486)?4:5;
   1.547                  }
   1.548 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.549 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.550                  else firstrepcycle=1;
   1.551                  break;
   1.552                  case 0x2AA: case 0x3AA: /*REP STOSB*/
   1.553                  if (c>0)
   1.554                  {
   1.555 +                        CHECK_WRITE_REP(&_es, EDI, EDI);
   1.556                          writememb(es,EDI,AL);
   1.557                          if (abrt) break;
   1.558                          if (flags&D_FLAG) EDI--;
   1.559 @@ -878,12 +892,13 @@
   1.560                          c--;
   1.561                          cycles-=(is486)?4:5;
   1.562                  }
   1.563 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.564 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.565                  else firstrepcycle=1;
   1.566                  break;
   1.567                  case 0xAB: /*REP STOSW*/
   1.568                  if (c>0)
   1.569                  {
   1.570 +                        CHECK_WRITE_REP(&_es, DI, DI+1);
   1.571                          writememw(es,DI,AX);
   1.572                          if (abrt) break;
   1.573                          if (flags&D_FLAG) DI-=2;
   1.574 @@ -891,12 +906,13 @@
   1.575                          c--;
   1.576                          cycles-=(is486)?4:5;
   1.577                  }
   1.578 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.579 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.580                  else firstrepcycle=1;
   1.581                  break;
   1.582                  case 0x2AB: /*REP STOSW*/
   1.583                  if (c>0)
   1.584                  {
   1.585 +                        CHECK_WRITE_REP(&_es, EDI, EDI+1);
   1.586                          writememw(es,EDI,AX);
   1.587                          if (abrt) break;
   1.588                          if (flags&D_FLAG) EDI-=2;
   1.589 @@ -904,12 +920,13 @@
   1.590                          c--;
   1.591                          cycles-=(is486)?4:5;
   1.592                  }
   1.593 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.594 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.595                  else firstrepcycle=1;
   1.596                  break;
   1.597                  case 0x1AB: /*REP STOSL*/
   1.598                  if (c>0)
   1.599                  {
   1.600 +                        CHECK_WRITE_REP(&_es, DI, DI+3);
   1.601                          writememl(es,DI,EAX);
   1.602                          if (abrt) break;
   1.603                          if (flags&D_FLAG) DI-=4;
   1.604 @@ -917,12 +934,13 @@
   1.605                          c--;
   1.606                          cycles-=(is486)?4:5;
   1.607                  }
   1.608 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.609 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.610                  else firstrepcycle=1;
   1.611                  break;
   1.612                  case 0x3AB: /*REP STOSL*/
   1.613                  if (c>0)
   1.614                  {
   1.615 +                        CHECK_WRITE_REP(&_es, EDI, EDI+3);
   1.616                          writememl(es,EDI,EAX);
   1.617                          if (abrt) break;
   1.618                          if (flags&D_FLAG) EDI-=4;
   1.619 @@ -930,91 +948,91 @@
   1.620                          c--;
   1.621                          cycles-=(is486)?4:5;
   1.622                  }
   1.623 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.624 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.625                  else firstrepcycle=1;
   1.626                  break;
   1.627                  case 0xAC: case 0x1AC: /*REP LODSB*/
   1.628  //                if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc);
   1.629                  if (c>0)
   1.630                  {
   1.631 -                        AL=readmemb(ds,SI);
   1.632 +                        AL = readmemb(ea_seg->base, SI);
   1.633                          if (abrt) break;
   1.634                          if (flags&D_FLAG) SI--;
   1.635                          else              SI++;
   1.636                          c--;
   1.637                          cycles-=5;
   1.638                  }
   1.639 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.640 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.641                  else firstrepcycle=1;
   1.642                  break;
   1.643                  case 0x2AC: case 0x3AC: /*REP LODSB*/
   1.644  //                if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc);
   1.645                  if (c>0)
   1.646                  {
   1.647 -                        AL=readmemb(ds,ESI);
   1.648 +                        AL = readmemb(ea_seg->base, ESI);
   1.649                          if (abrt) break;
   1.650                          if (flags&D_FLAG) ESI--;
   1.651                          else              ESI++;
   1.652                          c--;
   1.653                          cycles-=5;
   1.654                  }
   1.655 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.656 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.657                  else firstrepcycle=1;
   1.658                  break;
   1.659                  case 0xAD: /*REP LODSW*/
   1.660  //                if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc);
   1.661                  if (c>0)
   1.662                  {
   1.663 -                        AX=readmemw(ds,SI);
   1.664 +                        AX = readmemw(ea_seg->base, SI);
   1.665                          if (abrt) break;
   1.666                          if (flags&D_FLAG) SI-=2;
   1.667                          else              SI+=2;
   1.668                          c--;
   1.669                          cycles-=5;
   1.670                  }
   1.671 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.672 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.673                  else firstrepcycle=1;
   1.674                  break;
   1.675                  case 0x1AD: /*REP LODSL*/
   1.676  //                if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc);
   1.677                  if (c>0)
   1.678                  {
   1.679 -                        EAX=readmeml(ds,SI);
   1.680 +                        EAX = readmeml(ea_seg->base, SI);
   1.681                          if (abrt) break;
   1.682                          if (flags&D_FLAG) SI-=4;
   1.683                          else              SI+=4;
   1.684                          c--;
   1.685                          cycles-=5;
   1.686                  }
   1.687 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.688 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.689                  else firstrepcycle=1;
   1.690                  break;
   1.691                  case 0x2AD: /*REP LODSW*/
   1.692  //                if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc);
   1.693                  if (c>0)
   1.694                  {
   1.695 -                        AX=readmemw(ds,ESI);
   1.696 +                        AX = readmemw(ea_seg->base, ESI);
   1.697                          if (abrt) break;
   1.698                          if (flags&D_FLAG) ESI-=2;
   1.699                          else              ESI+=2;
   1.700                          c--;
   1.701                          cycles-=5;
   1.702                  }
   1.703 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.704 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.705                  else firstrepcycle=1;
   1.706                  break;
   1.707                  case 0x3AD: /*REP LODSL*/
   1.708  //                if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc);
   1.709                  if (c>0)
   1.710                  {
   1.711 -                        EAX=readmeml(ds,ESI);
   1.712 +                        EAX = readmeml(ea_seg->base, ESI);
   1.713                          if (abrt) break;
   1.714                          if (flags&D_FLAG) ESI-=4;
   1.715                          else              ESI+=4;
   1.716                          c--;
   1.717                          cycles-=5;
   1.718                  }
   1.719 -                if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
   1.720 +                if (c>0) { firstrepcycle=0; pc=ipc; }
   1.721                  else firstrepcycle=1;
   1.722                  break;
   1.723                  case 0xAE: case 0x1AE: /*REP SCASB*/
   1.724 @@ -1032,7 +1050,7 @@
   1.725                          c--;
   1.726                          cycles-=(is486)?5:8;
   1.727                  }
   1.728 -                if ((c>0) && (fv==tempz))  { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.729 +                if ((c>0) && (fv==tempz))  { pc=ipc; firstrepcycle=0; }
   1.730                  else firstrepcycle=1;
   1.731                  break;
   1.732                  case 0x2AE: case 0x3AE: /*REP SCASB*/
   1.733 @@ -1051,7 +1069,7 @@
   1.734                          c--;
   1.735                          cycles-=(is486)?5:8;
   1.736                  }
   1.737 -                if ((c>0) && (fv==tempz))  { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.738 +                if ((c>0) && (fv==tempz))  { pc=ipc; firstrepcycle=0; }
   1.739                  else firstrepcycle=1;
   1.740                  break;
   1.741                  case 0xAF: /*REP SCASW*/
   1.742 @@ -1068,7 +1086,7 @@
   1.743                          c--;
   1.744                          cycles-=(is486)?5:8;
   1.745                  }
   1.746 -                if ((c>0) && (fv==tempz))  { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.747 +                if ((c>0) && (fv==tempz))  { pc=ipc; firstrepcycle=0; }
   1.748                  else firstrepcycle=1;
   1.749                  break;
   1.750                  case 0x1AF: /*REP SCASL*/
   1.751 @@ -1085,7 +1103,7 @@
   1.752                          c--;
   1.753                          cycles-=(is486)?5:8;
   1.754                  }
   1.755 -                if ((c>0) && (fv==tempz))  { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.756 +                if ((c>0) && (fv==tempz))  { pc=ipc; firstrepcycle=0; }
   1.757                  else firstrepcycle=1;
   1.758                  break;
   1.759                  case 0x2AF: /*REP SCASW*/
   1.760 @@ -1102,7 +1120,7 @@
   1.761                          c--;
   1.762                          cycles-=(is486)?5:8;
   1.763                  }
   1.764 -                if ((c>0) && (fv==tempz))  { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.765 +                if ((c>0) && (fv==tempz))  { pc=ipc; firstrepcycle=0; }
   1.766                  else firstrepcycle=1;
   1.767                  break;
   1.768                  case 0x3AF: /*REP SCASL*/
   1.769 @@ -1119,7 +1137,7 @@
   1.770                          c--;
   1.771                          cycles-=(is486)?5:8;
   1.772                  }
   1.773 -                if ((c>0) && (fv==tempz))  { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
   1.774 +                if ((c>0) && (fv==tempz))  { pc=ipc; firstrepcycle=0; }
   1.775                  else firstrepcycle=1;
   1.776                  break;
   1.777  
   1.778 @@ -1132,7 +1150,6 @@
   1.779          }
   1.780          if (rep32&0x200) ECX=c;
   1.781          else             CX=c;
   1.782 -        if (changeds) ds=oldds;
   1.783  //        if (output) pclog("%03X %03X\n",rep32,use32);
   1.784  }
   1.785  
   1.786 @@ -1268,8 +1285,12 @@
   1.787                  
   1.788  dontprint=0;
   1.789  
   1.790 +                ea_seg = &_ds;
   1.791 +                ssegs = 0;
   1.792 +                
   1.793  opcodestart:
   1.794                  fetchdat = fastreadl(cs + pc);
   1.795 +
   1.796                  if (!abrt)
   1.797                  {               
   1.798                          tempc = CF_SET();
   1.799 @@ -1287,20 +1308,7 @@
   1.800                  }
   1.801  
   1.802                  if (!use32) pc &= 0xffff;
   1.803 -/*                if (ins == 74400000)
   1.804 -                {
   1.805 -                        pclog("Output on\n");
   1.806 -                        output = 3;
   1.807 -                }*/
   1.808 -                if ((cs + pc) == 0xc)
   1.809 -                        fatal("Dead\n");
   1.810 -                if (ssegs)
   1.811 -                {
   1.812 -                        ds=oldds;
   1.813 -                        ss=oldss;
   1.814 -                        rds=DS;
   1.815 -                        ssegs=0;
   1.816 -                }
   1.817 +
   1.818                  if (abrt)
   1.819                  {
   1.820                          flags_rebuild();
   1.821 @@ -1397,23 +1405,15 @@
   1.822                          }
   1.823                  }
   1.824  
   1.825 -//                tempi = ZF_SET() ? Z_FLAG : 0;
   1.826 -//                if (tempi != (flags & Z_FLAG))
   1.827 -//                   fatal("Z flag mismatch %02X %08X\n", opcode, fetchdat);
   1.828                  ins++;
   1.829                  insc++;
   1.830 -/*output = 3;
   1.831 -                if (ins == 1372108)
   1.832 -                        fatal("here2\n");
   1.833 -                if (ins == 50966339)
   1.834 -                        fatal("here\n");*/
   1.835 +
   1.836                  if (timetolive)
   1.837                  {
   1.838                          timetolive--;
   1.839                          if (!timetolive)
   1.840                                  fatal("Life expired\n");
   1.841                  }
   1.842 -//                if (ins == 97300000) output = 3;
   1.843                  }
   1.844                  
   1.845                  tsc += cycdiff;
     2.1 --- a/src/808x.c	Sun Aug 03 20:38:04 2014 +0100
     2.2 +++ b/src/808x.c	Wed Aug 13 20:33:56 2014 +0100
     2.3 @@ -588,15 +588,15 @@
     2.4             printf("In %s mode\n",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real");
     2.5          else
     2.6             printf("In %s mode\n",(msw&1)?"protected":"real");
     2.7 -        printf("CS : base=%06X limit=%04X access=%02X\n",cs,_cs.limit,_cs.access);
     2.8 -        printf("DS : base=%06X limit=%04X access=%02X\n",ds,_ds.limit,_ds.access);
     2.9 -        printf("ES : base=%06X limit=%04X access=%02X\n",es,_es.limit,_es.access);
    2.10 +        printf("CS : base=%06X limit=%08X access=%02X  limit_low=%08X limit_high=%08X\n",cs,_cs.limit,_cs.access, _cs.limit_low, _cs.limit_high);
    2.11 +        printf("DS : base=%06X limit=%08X access=%02X  limit_low=%08X limit_high=%08X\n",ds,_ds.limit,_ds.access, _ds.limit_low, _ds.limit_high);
    2.12 +        printf("ES : base=%06X limit=%08X access=%02X  limit_low=%08X limit_high=%08X\n",es,_es.limit,_es.access, _es.limit_low, _es.limit_high);
    2.13          if (is386)
    2.14          {
    2.15 -                printf("FS : base=%06X limit=%04X access=%02X\n",fs,_fs.limit,_fs.access);
    2.16 -                printf("GS : base=%06X limit=%04X access=%02X\n",gs,_gs.limit,_gs.access);
    2.17 +                printf("FS : base=%06X limit=%08X access=%02X  limit_low=%08X limit_high=%08X\n",fs,_fs.limit,_fs.access, _fs.limit_low, _fs.limit_high);
    2.18 +                printf("GS : base=%06X limit=%08X access=%02X  limit_low=%08X limit_high=%08X\n",gs,_gs.limit,_gs.access, _gs.limit_low, _gs.limit_high);
    2.19          }
    2.20 -        printf("SS : base=%06X limit=%04X access=%02X\n",ss,_ss.limit,_ss.access);
    2.21 +        printf("SS : base=%06X limit=%08X access=%02X  limit_low=%08X limit_high=%08X\n",ss,_ss.limit,_ss.access, _ss.limit_low, _ss.limit_high);
    2.22          printf("GDT : base=%06X limit=%04X\n",gdt.base,gdt.limit);
    2.23          printf("LDT : base=%06X limit=%04X\n",ldt.base,ldt.limit);
    2.24          printf("IDT : base=%06X limit=%04X\n",idt.base,idt.limit);
    2.25 @@ -646,6 +646,7 @@
    2.26          ESP=0;
    2.27          mmu_perm=4;
    2.28          memset(inscounts, 0, sizeof(inscounts));
    2.29 +        x86seg_reset();
    2.30  }
    2.31  
    2.32  void softresetx86()
    2.33 @@ -665,6 +666,7 @@
    2.34          //rammask=0xFFFFFFFF;
    2.35          flags=2;
    2.36          idt.base = 0;
    2.37 +        x86seg_reset();
    2.38  }
    2.39  
    2.40  static void setznp8(uint8_t val)
     3.1 --- a/src/ibm.h	Sun Aug 03 20:38:04 2014 +0100
     3.2 +++ b/src/ibm.h	Wed Aug 13 20:33:56 2014 +0100
     3.3 @@ -108,15 +108,18 @@
     3.4  typedef struct
     3.5  {
     3.6          uint32_t base;
     3.7 -        uint32_t limit,limitw;
     3.8 +        uint32_t limit;
     3.9          uint8_t access;
    3.10          uint16_t seg;
    3.11 +        uint32_t limit_low, limit_high;
    3.12  } x86seg;
    3.13  
    3.14  x86seg gdt,ldt,idt,tr;
    3.15  x86seg _cs,_ds,_es,_ss,_fs,_gs;
    3.16  x86seg _oldds;
    3.17  
    3.18 +extern x86seg *ea_seg;
    3.19 +
    3.20  uint32_t pccache;
    3.21  uint8_t *pccache2;
    3.22  /*Segments -
     4.1 --- a/src/x86.h	Sun Aug 03 20:38:04 2014 +0100
     4.2 +++ b/src/x86.h	Wed Aug 13 20:33:56 2014 +0100
     4.3 @@ -58,7 +58,7 @@
     4.4  extern uint32_t *mod1seg[8];
     4.5  
     4.6  
     4.7 -#define IRQTEST ((flags&I_FLAG) && (pic.pend&~pic.mask) && !ssegs && !noint)
     4.8 +#define IRQTEST ((flags&I_FLAG) && (pic.pend&~pic.mask) && !noint)
     4.9  
    4.10  extern int cgate32;
    4.11  
    4.12 @@ -99,3 +99,5 @@
    4.13  extern int inscounts[256];
    4.14  
    4.15  void x86illegal();
    4.16 +
    4.17 +void x86seg_reset();
     5.1 --- a/src/x86_ops_call.h	Sun Aug 03 20:38:04 2014 +0100
     5.2 +++ b/src/x86_ops_call.h	Wed Aug 13 20:33:56 2014 +0100
     5.3 @@ -1,7 +1,6 @@
     5.4  #define CALL_FAR_w(new_seg, new_pc)                                             \
     5.5          old_cs = CS;                                                            \
     5.6          old_pc = pc;                                                            \
     5.7 -        if (ssegs) ss = oldss;                                                  \
     5.8          oxpc = pc;                                                              \
     5.9          pc = new_pc;                                                            \
    5.10          optype = CALL;                                                          \
    5.11 @@ -27,7 +26,6 @@
    5.12  #define CALL_FAR_l(new_seg, new_pc)                                             \
    5.13          old_cs = CS;                                                            \
    5.14          old_pc = pc;                                                            \
    5.15 -        if (ssegs) ss = oldss;                                                  \
    5.16          oxpc = pc;                                                              \
    5.17          pc = new_pc;                                                            \
    5.18          optype = CALL;                                                          \
    5.19 @@ -54,7 +52,6 @@
    5.20  #define CALL_FAR_nr(new_seg, new_pc)                                               \
    5.21          old_cs = CS;                                                            \
    5.22          old_pc = pc;                                                            \
    5.23 -        if (ssegs) ss = oldss;                                                  \
    5.24          oxpc = pc;                                                              \
    5.25          pc = new_pc;                                                            \
    5.26          optype = CALL;                                                          \
    5.27 @@ -130,7 +127,6 @@
    5.28                  break;
    5.29                  case 0x10: /*CALL*/
    5.30                  new_pc = geteaw();                      if (abrt) return 0;
    5.31 -                if (ssegs) ss = oldss;
    5.32                  PUSH_W(pc);
    5.33                  pc = new_pc;
    5.34                  if (is486) cycles -= 5;
    5.35 @@ -160,7 +156,6 @@
    5.36                  break;
    5.37                  case 0x30: /*PUSH w*/
    5.38                  temp = geteaw();                        if (abrt) return 0;
    5.39 -                if (ssegs) ss = oldss;
    5.40                  PUSH_W(temp);
    5.41                  cycles -= ((mod == 3) ? 2 : 5);
    5.42                  break;
    5.43 @@ -196,7 +191,6 @@
    5.44                  break;
    5.45                  case 0x10: /*CALL*/
    5.46                  new_pc = geteaw();                      if (abrt) return 0;
    5.47 -                if (ssegs) ss = oldss;
    5.48                  PUSH_W(pc);
    5.49                  pc = new_pc;
    5.50                  if (is486) cycles -= 5;
    5.51 @@ -226,7 +220,6 @@
    5.52                  break;
    5.53                  case 0x30: /*PUSH w*/
    5.54                  temp = geteaw();                        if (abrt) return 0;
    5.55 -                if (ssegs) ss = oldss;
    5.56                  PUSH_W(temp);
    5.57                  cycles -= ((mod == 3) ? 2 : 5);
    5.58                  break;
    5.59 @@ -263,7 +256,6 @@
    5.60                  break;
    5.61                  case 0x10: /*CALL*/
    5.62                  new_pc = geteal();                      if (abrt) return 0;
    5.63 -                if (ssegs) ss = oldss;
    5.64                  PUSH_L(pc);
    5.65                  pc = new_pc;
    5.66                  if (is486) cycles -= 5;
    5.67 @@ -293,7 +285,6 @@
    5.68                  break;
    5.69                  case 0x30: /*PUSH l*/
    5.70                  temp = geteal();                        if (abrt) return 0;
    5.71 -                if (ssegs) ss = oldss;
    5.72                  PUSH_L(temp);
    5.73                  cycles -= ((mod == 3) ? 2 : 5);
    5.74                  break;
    5.75 @@ -329,7 +320,6 @@
    5.76                  break;
    5.77                  case 0x10: /*CALL*/
    5.78                  new_pc = geteal();                      if (abrt) return 0;
    5.79 -                if (ssegs) ss = oldss;
    5.80                  PUSH_L(pc);                             if (abrt) return 0;
    5.81                  pc = new_pc;
    5.82                  if (is486) cycles -= 5;
    5.83 @@ -359,7 +349,6 @@
    5.84                  break;
    5.85                  case 0x30: /*PUSH l*/
    5.86                  temp = geteal();                        if (abrt) return 0;
    5.87 -                if (ssegs) ss = oldss;
    5.88                  PUSH_L(temp);
    5.89                  cycles -= ((mod == 3) ? 2 : 5);
    5.90                  break;
     6.1 --- a/src/x86_ops_flag.h	Sun Aug 03 20:38:04 2014 +0100
     6.2 +++ b/src/x86_ops_flag.h	Wed Aug 13 20:33:56 2014 +0100
     6.3 @@ -76,7 +76,6 @@
     6.4  
     6.5  static int opPUSHF(uint32_t fetchdat)
     6.6  {
     6.7 -        if (ssegs) ss = oldss;
     6.8          if ((eflags & VM_FLAG) && (IOPL < 3))
     6.9          {
    6.10                  x86gpf(NULL,0);
    6.11 @@ -90,7 +89,6 @@
    6.12  static int opPUSHFD(uint32_t fetchdat)
    6.13  {
    6.14          uint16_t tempw;
    6.15 -        if (ssegs) ss=oldss;
    6.16          if ((eflags & VM_FLAG) && (IOPL < 3))
    6.17          {
    6.18                  x86gpf(NULL, 0);
    6.19 @@ -107,7 +105,6 @@
    6.20  static int opPOPF_286(uint32_t fetchdat)
    6.21  {
    6.22          uint16_t tempw;
    6.23 -        if (ssegs) ss = oldss;
    6.24          
    6.25          if ((eflags & VM_FLAG) && (IOPL < 3))
    6.26          {
    6.27 @@ -129,7 +126,6 @@
    6.28  static int opPOPF(uint32_t fetchdat)
    6.29  {
    6.30          uint16_t tempw;
    6.31 -        if (ssegs) ss = oldss;
    6.32          
    6.33          if ((eflags & VM_FLAG) && (IOPL < 3))
    6.34          {
    6.35 @@ -150,7 +146,6 @@
    6.36  static int opPOPFD(uint32_t fetchdat)
    6.37  {
    6.38          uint32_t templ;
    6.39 -        if (ssegs) ss = oldss;
    6.40          
    6.41          if ((eflags & VM_FLAG) && (IOPL < 3))
    6.42          {
     7.1 --- a/src/x86_ops_jump.h	Sun Aug 03 20:38:04 2014 +0100
     7.2 +++ b/src/x86_ops_jump.h	Wed Aug 13 20:33:56 2014 +0100
     7.3 @@ -198,7 +198,6 @@
     7.4  int opCALL_r16(uint32_t fetchdat)
     7.5  {
     7.6          int16_t addr = (int16_t)getwordf();
     7.7 -        if (ssegs) ss=oldss;
     7.8          PUSH_W(pc);
     7.9          pc += addr;
    7.10          cycles -= (is486) ? 3 : 7;
    7.11 @@ -207,7 +206,6 @@
    7.12  int opCALL_r32(uint32_t fetchdat)
    7.13  {
    7.14          int32_t addr = getlong();                       if (abrt) return 0;       
    7.15 -        if (ssegs) ss=oldss;
    7.16          PUSH_L(pc);
    7.17          pc += addr;
    7.18          cycles -= (is486) ? 3 : 7;
    7.19 @@ -218,7 +216,6 @@
    7.20  {
    7.21          uint16_t ret;
    7.22          
    7.23 -        if (ssegs) ss=oldss;        
    7.24          ret = POP_W();                          if (abrt) return 0;
    7.25          pc = ret;
    7.26          
    7.27 @@ -229,7 +226,6 @@
    7.28  {
    7.29          uint32_t ret;
    7.30  
    7.31 -        if (ssegs) ss=oldss;        
    7.32          ret = POP_L();                          if (abrt) return 0;
    7.33          pc = ret;
    7.34          
    7.35 @@ -242,7 +238,6 @@
    7.36          uint16_t offset = getwordf();
    7.37          uint16_t ret;
    7.38  
    7.39 -        if (ssegs) ss=oldss;       
    7.40          ret = POP_W();                          if (abrt) return 0;
    7.41          if (stack32) ESP += offset;
    7.42          else          SP += offset;       
    7.43 @@ -256,7 +251,6 @@
    7.44          uint16_t offset = getwordf();
    7.45          uint32_t ret;
    7.46  
    7.47 -        if (ssegs) ss=oldss;        
    7.48          ret = POP_L();                          if (abrt) return 0;
    7.49          if (stack32) ESP += offset;
    7.50          else          SP += offset;       
     8.1 --- a/src/x86_ops_misc.h	Sun Aug 03 20:38:04 2014 +0100
     8.2 +++ b/src/x86_ops_misc.h	Wed Aug 13 20:33:56 2014 +0100
     8.3 @@ -515,7 +515,7 @@
     8.4                  x86gpf(NULL,0);
     8.5                  return 0;
     8.6          }
     8.7 -        if (!((flags&I_FLAG) && pic_intpending && !ssegs)) 
     8.8 +        if (!((flags&I_FLAG) && pic_intpending))
     8.9          {
    8.10                  cycles -= 100;
    8.11                  pc--;
     9.1 --- a/src/x86_ops_mmx_mov.h	Sun Aug 03 20:38:04 2014 +0100
     9.2 +++ b/src/x86_ops_mmx_mov.h	Wed Aug 13 20:33:56 2014 +0100
     9.3 @@ -57,6 +57,7 @@
     9.4          }
     9.5          else
     9.6          {
     9.7 +                CHECK_WRITE(ea_seg, eaaddr, eaaddr + 3);
     9.8                  writememl(easeg, eaaddr, MM[reg].l[0]); if (abrt) return 0;
     9.9                  cycles -= 2;
    9.10          }
    9.11 @@ -74,6 +75,7 @@
    9.12          }
    9.13          else
    9.14          {
    9.15 +                CHECK_WRITE(ea_seg, eaaddr, eaaddr + 3);
    9.16                  writememl(easeg, eaaddr, MM[reg].l[0]); if (abrt) return 0;
    9.17                  cycles -= 2;
    9.18          }
    9.19 @@ -137,6 +139,7 @@
    9.20          }
    9.21          else
    9.22          {
    9.23 +                CHECK_WRITE(ea_seg, eaaddr, eaaddr + 7);
    9.24                  writememl(easeg, eaaddr,     MM[reg].l[0]);
    9.25                  writememl(easeg, eaaddr + 4, MM[reg].l[1]); if (abrt) return 0;
    9.26                  cycles -= 2;
    9.27 @@ -155,6 +158,7 @@
    9.28          }
    9.29          else
    9.30          {
    9.31 +                CHECK_WRITE(ea_seg, eaaddr, eaaddr + 7);
    9.32                  writememl(easeg, eaaddr,     MM[reg].l[0]);
    9.33                  writememl(easeg, eaaddr + 4, MM[reg].l[1]); if (abrt) return 0;
    9.34                  cycles -= 2;
    10.1 --- a/src/x86_ops_mov.h	Sun Aug 03 20:38:04 2014 +0100
    10.2 +++ b/src/x86_ops_mov.h	Wed Aug 13 20:33:56 2014 +0100
    10.3 @@ -213,7 +213,7 @@
    10.4  static int opMOV_AL_a16(uint32_t fetchdat)
    10.5  {
    10.6          uint16_t addr = getwordf();
    10.7 -        uint8_t temp = readmemb(ds, addr);      if (abrt) return 0;
    10.8 +        uint8_t temp = readmemb(ea_seg->base, addr);      if (abrt) return 0;
    10.9          AL = temp;
   10.10          cycles -= (is486) ? 1 : 4;
   10.11          return 0;        
   10.12 @@ -221,7 +221,7 @@
   10.13  static int opMOV_AL_a32(uint32_t fetchdat)
   10.14  {
   10.15          uint32_t addr = getlong();
   10.16 -        uint8_t temp = readmemb(ds, addr);      if (abrt) return 0;
   10.17 +        uint8_t temp = readmemb(ea_seg->base, addr);      if (abrt) return 0;
   10.18          AL = temp;
   10.19          cycles -= (is486) ? 1 : 4;
   10.20          return 0;        
   10.21 @@ -229,7 +229,7 @@
   10.22  static int opMOV_AX_a16(uint32_t fetchdat)
   10.23  {
   10.24          uint16_t addr = getwordf();
   10.25 -        uint16_t temp = readmemw(ds, addr);     if (abrt) return 0;
   10.26 +        uint16_t temp = readmemw(ea_seg->base, addr);     if (abrt) return 0;
   10.27          AX = temp;
   10.28          cycles -= (is486) ? 1 : 4;
   10.29          return 0;        
   10.30 @@ -237,7 +237,7 @@
   10.31  static int opMOV_AX_a32(uint32_t fetchdat)
   10.32  {
   10.33          uint32_t addr = getlong();
   10.34 -        uint16_t temp = readmemw(ds, addr);     if (abrt) return 0;
   10.35 +        uint16_t temp = readmemw(ea_seg->base, addr);     if (abrt) return 0;
   10.36          AX = temp;
   10.37          cycles -= (is486) ? 1 : 4;
   10.38          return 0;        
   10.39 @@ -245,7 +245,7 @@
   10.40  static int opMOV_EAX_a16(uint32_t fetchdat)
   10.41  {
   10.42          uint16_t addr = getwordf();             if (abrt) return 0;
   10.43 -        uint32_t temp = readmeml(ds, addr);     if (abrt) return 0;
   10.44 +        uint32_t temp = readmeml(ea_seg->base, addr);     if (abrt) return 0;
   10.45          EAX = temp;
   10.46          cycles -= (is486) ? 1 : 4;
   10.47          return 0;        
   10.48 @@ -253,7 +253,7 @@
   10.49  static int opMOV_EAX_a32(uint32_t fetchdat)
   10.50  {
   10.51          uint32_t addr = getlong();              if (abrt) return 0;
   10.52 -        uint32_t temp = readmeml(ds, addr);     if (abrt) return 0;
   10.53 +        uint32_t temp = readmeml(ea_seg->base, addr);     if (abrt) return 0;
   10.54          EAX = temp;
   10.55          cycles -= (is486) ? 1 : 4;
   10.56          return 0;        
   10.57 @@ -262,42 +262,42 @@
   10.58  static int opMOV_a16_AL(uint32_t fetchdat)
   10.59  {
   10.60          uint16_t addr = getwordf();
   10.61 -        writememb(ds, addr, AL);
   10.62 +        writememb(ea_seg->base, addr, AL);
   10.63          cycles -= (is486) ? 1 : 2;
   10.64          return 0;
   10.65  }
   10.66  static int opMOV_a32_AL(uint32_t fetchdat)
   10.67  {
   10.68          uint32_t addr = getlong();
   10.69 -        writememb(ds, addr, AL);
   10.70 +        writememb(ea_seg->base, addr, AL);
   10.71          cycles -= (is486) ? 1 : 2;
   10.72          return 0;
   10.73  }
   10.74  static int opMOV_a16_AX(uint32_t fetchdat)
   10.75  {
   10.76          uint16_t addr = getwordf();
   10.77 -        writememw(ds, addr, AX);
   10.78 +        writememw(ea_seg->base, addr, AX);
   10.79          cycles -= (is486) ? 1 : 2;
   10.80          return 0;
   10.81  }
   10.82  static int opMOV_a32_AX(uint32_t fetchdat)
   10.83  {
   10.84          uint32_t addr = getlong();
   10.85 -        writememw(ds, addr, AX);
   10.86 +        writememw(ea_seg->base, addr, AX);
   10.87          cycles -= (is486) ? 1 : 2;
   10.88          return 0;
   10.89  }
   10.90  static int opMOV_a16_EAX(uint32_t fetchdat)
   10.91  {
   10.92          uint16_t addr = getwordf();
   10.93 -        writememl(ds, addr, EAX);
   10.94 +        writememl(ea_seg->base, addr, EAX);
   10.95          cycles -= (is486) ? 1 : 2;
   10.96          return 0;
   10.97  }
   10.98  static int opMOV_a32_EAX(uint32_t fetchdat)
   10.99  {
  10.100          uint32_t addr = getlong();
  10.101 -        writememl(ds, addr, EAX);
  10.102 +        writememl(ea_seg->base, addr, EAX);
  10.103          cycles -= (is486) ? 1 : 2;
  10.104          return 0;
  10.105  }
  10.106 @@ -342,7 +342,7 @@
  10.107  int opXLAT_a16(uint32_t fetchdat)
  10.108  {
  10.109          uint32_t addr = (BX + AL)&0xFFFF;
  10.110 -        uint8_t temp = readmemb(ds, addr);      if (abrt) return 0;
  10.111 +        uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 0;
  10.112          AL = temp;
  10.113          cycles -= 5;
  10.114          return 0;
  10.115 @@ -350,7 +350,7 @@
  10.116  int opXLAT_a32(uint32_t fetchdat)
  10.117  {
  10.118          uint32_t addr = EBX + AL;
  10.119 -        uint8_t temp = readmemb(ds, addr);      if (abrt) return 0;
  10.120 +        uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 0;
  10.121          AL = temp;
  10.122          cycles -= 5;
  10.123          return 0;
  10.124 @@ -367,6 +367,7 @@
  10.125          else
  10.126          {
  10.127                  fetch_ea_16(fetchdat);
  10.128 +                CHECK_WRITE(ea_seg, eaaddr, eaaddr);
  10.129                  seteab(getr8(reg));
  10.130                  cycles -= is486 ? 1 : 2;
  10.131          }
  10.132 @@ -383,6 +384,7 @@
  10.133          else
  10.134          {
  10.135                  fetch_ea_32(fetchdat);
  10.136 +                CHECK_WRITE(ea_seg, eaaddr, eaaddr);
  10.137                  seteab(getr8(reg));
  10.138                  cycles -= is486 ? 1 : 2;
  10.139          }
  10.140 @@ -399,6 +401,7 @@
  10.141          else
  10.142          { 
  10.143                  fetch_ea_16(fetchdat);
  10.144 +                CHECK_WRITE(ea_seg, eaaddr, eaaddr+1);
  10.145                  seteaw(regs[reg].w);
  10.146                  cycles -= is486 ? 1 : 2;
  10.147          }
  10.148 @@ -415,6 +418,7 @@
  10.149          else
  10.150          { 
  10.151                  fetch_ea_32(fetchdat);
  10.152 +                CHECK_WRITE(ea_seg, eaaddr, eaaddr+1);
  10.153                  seteaw(regs[reg].w);
  10.154                  cycles -= is486 ? 1 : 2;
  10.155          }
  10.156 @@ -431,6 +435,7 @@
  10.157          else
  10.158          {
  10.159                  fetch_ea_16(fetchdat);
  10.160 +                CHECK_WRITE(ea_seg, eaaddr, eaaddr+3);
  10.161                  seteal(regs[reg].l);
  10.162                  cycles -= is486 ? 1 : 2;
  10.163          }
  10.164 @@ -447,6 +452,7 @@
  10.165          else
  10.166          {
  10.167                  fetch_ea_32(fetchdat);
  10.168 +                CHECK_WRITE(ea_seg, eaaddr, eaaddr+3);
  10.169                  seteal(regs[reg].l);
  10.170                  cycles -= is486 ? 1 : 2;
  10.171          }
  10.172 @@ -465,6 +471,7 @@
  10.173          {
  10.174                  uint8_t temp;
  10.175                  fetch_ea_16(fetchdat);
  10.176 +                CHECK_READ(ea_seg, eaaddr, eaaddr);
  10.177                  temp = geteab();                if (abrt) return 0;
  10.178                  setr8(reg, temp);
  10.179                  cycles -= is486 ? 1 : 4;
  10.180 @@ -483,6 +490,7 @@
  10.181          {
  10.182                  uint8_t temp;
  10.183                  fetch_ea_32(fetchdat);
  10.184 +                CHECK_READ(ea_seg, eaaddr, eaaddr);
  10.185                  temp = geteab();                if (abrt) return 0;
  10.186                  setr8(reg, temp);
  10.187                  cycles -= is486 ? 1 : 4;
  10.188 @@ -501,6 +509,7 @@
  10.189          {
  10.190                  uint16_t temp;
  10.191                  fetch_ea_16(fetchdat);
  10.192 +                CHECK_READ(ea_seg, eaaddr, eaaddr+1);
  10.193                  temp = geteaw();                if (abrt) return 0;
  10.194                  regs[reg].w = temp;
  10.195                  cycles -= (is486) ? 1 : 4;
  10.196 @@ -519,6 +528,7 @@
  10.197          {
  10.198                  uint16_t temp;
  10.199                  fetch_ea_32(fetchdat);
  10.200 +                CHECK_READ(ea_seg, eaaddr, eaaddr+1);
  10.201                  temp = geteaw();                if (abrt) return 0;
  10.202                  regs[reg].w = temp;
  10.203                  cycles -= (is486) ? 1 : 4;
  10.204 @@ -537,6 +547,7 @@
  10.205          {
  10.206                  uint32_t temp;
  10.207                  fetch_ea_16(fetchdat);
  10.208 +                CHECK_READ(ea_seg, eaaddr, eaaddr+3);
  10.209                  temp = geteal();                if (abrt) return 0;
  10.210                  regs[reg].l = temp;
  10.211                  cycles -= is486 ? 1 : 4;
  10.212 @@ -555,6 +566,7 @@
  10.213          {
  10.214                  uint32_t temp;
  10.215                  fetch_ea_32(fetchdat);
  10.216 +                CHECK_READ(ea_seg, eaaddr, eaaddr+3);
  10.217                  temp = geteal();                if (abrt) return 0;
  10.218                  regs[reg].l = temp;
  10.219                  cycles -= is486 ? 1 : 4;
    11.1 --- a/src/x86_ops_mov_seg.h	Sun Aug 03 20:38:04 2014 +0100
    11.2 +++ b/src/x86_ops_mov_seg.h	Wed Aug 13 20:33:56 2014 +0100
    11.3 @@ -11,11 +11,9 @@
    11.4                  seteaw(CS);
    11.5                  break;
    11.6                  case 0x18: /*DS*/
    11.7 -                if (ssegs) ds = oldds;
    11.8                  seteaw(DS);
    11.9                  break;
   11.10                  case 0x10: /*SS*/
   11.11 -                if (ssegs) ss = oldss;
   11.12                  seteaw(SS);
   11.13                  break;
   11.14                  case 0x20: /*FS*/
   11.15 @@ -42,11 +40,9 @@
   11.16                  seteaw(CS);
   11.17                  break;
   11.18                  case 0x18: /*DS*/
   11.19 -                if (ssegs) ds = oldds;
   11.20                  seteaw(DS);
   11.21                  break;
   11.22                  case 0x10: /*SS*/
   11.23 -                if (ssegs) ss = oldss;
   11.24                  seteaw(SS);
   11.25                  break;
   11.26                  case 0x20: /*FS*/
   11.27 @@ -76,12 +72,10 @@
   11.28                  else          seteaw(CS);
   11.29                  break;
   11.30                  case 0x18: /*DS*/
   11.31 -                if (ssegs) ds = oldds;
   11.32                  if (mod == 3) regs[rm].l = DS;
   11.33                  else          seteaw(DS);
   11.34                  break;
   11.35                  case 0x10: /*SS*/
   11.36 -                if (ssegs) ss = oldss;
   11.37                  if (mod == 3) regs[rm].l = SS;
   11.38                  else          seteaw(SS);
   11.39                  break;
   11.40 @@ -113,12 +107,10 @@
   11.41                  else          seteaw(CS);
   11.42                  break;
   11.43                  case 0x18: /*DS*/
   11.44 -                if (ssegs) ds = oldds;
   11.45                  if (mod == 3) regs[rm].l = DS;
   11.46                  else          seteaw(DS);
   11.47                  break;
   11.48                  case 0x10: /*SS*/
   11.49 -                if (ssegs) ss = oldss;
   11.50                  if (mod == 3) regs[rm].l = SS;
   11.51                  else          seteaw(SS);
   11.52                  break;
   11.53 @@ -151,16 +143,9 @@
   11.54                  break;
   11.55                  case 0x18: /*DS*/
   11.56                  loadseg(new_seg, &_ds);
   11.57 -                if (ssegs) oldds = ds;
   11.58                  break;
   11.59                  case 0x10: /*SS*/
   11.60                  loadseg(new_seg, &_ss);
   11.61 -                if (ssegs)
   11.62 -                {
   11.63 -                        ds = oldds;
   11.64 -                        rds = DS;
   11.65 -                        ssegs = 0;
   11.66 -                }
   11.67                  op32 = use32;
   11.68                  return 1;
   11.69                  case 0x20: /*FS*/
   11.70 @@ -189,16 +174,9 @@
   11.71                  break;
   11.72                  case 0x18: /*DS*/
   11.73                  loadseg(new_seg, &_ds);
   11.74 -                if (ssegs) oldds = ds;
   11.75                  break;
   11.76                  case 0x10: /*SS*/
   11.77                  loadseg(new_seg, &_ss);
   11.78 -                if (ssegs)
   11.79 -                {
   11.80 -                        ds = oldds;
   11.81 -                        rds = DS;
   11.82 -                        ssegs = 0;
   11.83 -                }
   11.84                  op32 = use32;
   11.85                  return 1;
   11.86                  case 0x20: /*FS*/
   11.87 @@ -224,7 +202,6 @@
   11.88          seg = readmemw(easeg, eaaddr + 2);      if (abrt) return 0;
   11.89          loadseg(seg, &_ds);                     if (abrt) return 0;
   11.90          regs[reg].w = addr;
   11.91 -        if (ssegs) oldds = ds;
   11.92   
   11.93          cycles -= 7;       
   11.94          return 0;
   11.95 @@ -239,7 +216,6 @@
   11.96          seg = readmemw(easeg, eaaddr + 2);      if (abrt) return 0;
   11.97          loadseg(seg, &_ds);                     if (abrt) return 0;
   11.98          regs[reg].w = addr;
   11.99 -        if (ssegs) oldds = ds;
  11.100   
  11.101          cycles -= 7;       
  11.102          return 0;
  11.103 @@ -255,7 +231,6 @@
  11.104          seg = readmemw(easeg, eaaddr + 4);      if (abrt) return 0;
  11.105          loadseg(seg, &_ds);                     if (abrt) return 0;
  11.106          regs[reg].l = addr;
  11.107 -        if (ssegs) oldds = ds;
  11.108   
  11.109          cycles -= 7;       
  11.110          return 0;
  11.111 @@ -271,7 +246,6 @@
  11.112          seg = readmemw(easeg, eaaddr + 4);      if (abrt) return 0;
  11.113          loadseg(seg, &_ds);                     if (abrt) return 0;
  11.114          regs[reg].l = addr;
  11.115 -        if (ssegs) oldds = ds;
  11.116   
  11.117          cycles -= 7;       
  11.118          return 0;
    12.1 --- a/src/x86_ops_prefix.h	Sun Aug 03 20:38:04 2014 +0100
    12.2 +++ b/src/x86_ops_prefix.h	Wed Aug 13 20:33:56 2014 +0100
    12.3 @@ -1,59 +1,42 @@
    12.4  static int op_CS(uint32_t fetchdat)
    12.5  {
    12.6 -        oldss = ss;
    12.7 -        oldds = ds;
    12.8 -        ds = ss = cs;
    12.9 -        rds = CS;
   12.10 -        ssegs = 2;
   12.11 +        ea_seg = &_cs;
   12.12 +        ssegs = 1;
   12.13          cycles -= 4;
   12.14          return 1;
   12.15  }
   12.16  static int op_DS(uint32_t fetchdat)
   12.17  {
   12.18 -        oldss = ss;
   12.19 -        oldds = ds;
   12.20 -        ds = ss = ds;
   12.21 -        ssegs = 2;
   12.22 +        ea_seg = &_ds;
   12.23 +        ssegs = 1;
   12.24          cycles -= 4;
   12.25          return 1;
   12.26  }
   12.27  static int op_ES(uint32_t fetchdat)
   12.28  {
   12.29 -        oldss = ss;
   12.30 -        oldds = ds;
   12.31 -        ds = ss = es;
   12.32 -        rds = ES;
   12.33 -        ssegs = 2;
   12.34 +        ea_seg = &_es;
   12.35 +        ssegs = 1;
   12.36          cycles -= 4;
   12.37          return 1;
   12.38  }      
   12.39  static int op_FS(uint32_t fetchdat)
   12.40  {
   12.41 -        oldss = ss;
   12.42 -        oldds = ds;
   12.43 -        rds = FS;
   12.44 -        ds = ss = fs;
   12.45 -        ssegs = 2;
   12.46 +        ea_seg = &_fs;
   12.47 +        ssegs = 1;
   12.48          cycles -= 4;
   12.49          return 1;
   12.50  }
   12.51  static int op_GS(uint32_t fetchdat)
   12.52  {
   12.53 -        oldss = ss;
   12.54 -        oldds = ds;
   12.55 -        rds = GS;
   12.56 -        ds = ss = gs;
   12.57 -        ssegs = 2;
   12.58 +        ea_seg = &_gs;
   12.59 +        ssegs = 1;
   12.60          cycles -= 4;
   12.61          return 1;
   12.62  }
   12.63  static int op_SS(uint32_t fetchdat)
   12.64  {
   12.65 -        oldss = ss;
   12.66 -        oldds = ds;
   12.67 -        ds = ss = ss;
   12.68 -        rds = SS;
   12.69 -        ssegs = 2;
   12.70 +        ea_seg = &_ss;
   12.71 +        ssegs = 1;
   12.72          cycles -= 4;
   12.73          return 1;
   12.74  }
    13.1 --- a/src/x86_ops_ret.h	Sun Aug 03 20:38:04 2014 +0100
    13.2 +++ b/src/x86_ops_ret.h	Wed Aug 13 20:33:56 2014 +0100
    13.3 @@ -4,7 +4,6 @@
    13.4                          pmoderetf(0, stack_offset);             \
    13.5                          return 0;                               \
    13.6                  }                                               \
    13.7 -                if (ssegs) ss = oldss;                          \
    13.8                  oxpc = pc;                                      \
    13.9                  if (stack32)                                    \
   13.10                  {                                               \
   13.11 @@ -27,7 +26,6 @@
   13.12                          pmoderetf(1, stack_offset);             \
   13.13                          return 0;                               \
   13.14                  }                                               \
   13.15 -                if (ssegs) ss = oldss;                          \
   13.16                  oxpc = pc;                                      \
   13.17                  if (stack32)                                    \
   13.18                  {                                               \
   13.19 @@ -75,7 +73,6 @@
   13.20                  x86gpf(NULL,0);
   13.21                  return 0;
   13.22          }
   13.23 -        if (ssegs) ss = oldss;
   13.24          if (msw&1)
   13.25          {
   13.26                  optype = IRET;
   13.27 @@ -115,7 +112,6 @@
   13.28                  x86gpf(NULL,0);
   13.29                  return 0;
   13.30          }
   13.31 -        if (ssegs) ss = oldss;
   13.32          if (msw&1)
   13.33          {
   13.34                  optype = IRET;
   13.35 @@ -155,7 +151,6 @@
   13.36                  x86gpf(NULL,0);
   13.37                  return 0;
   13.38          }
   13.39 -        if (ssegs) ss = oldss;
   13.40          if (msw & 1)
   13.41          {
   13.42                  optype = IRET;
    14.1 --- a/src/x86_ops_stack.h	Sun Aug 03 20:38:04 2014 +0100
    14.2 +++ b/src/x86_ops_stack.h	Wed Aug 13 20:33:56 2014 +0100
    14.3 @@ -1,7 +1,6 @@
    14.4  #define PUSH_W_OP(reg)                                                                          \
    14.5          static int opPUSH_ ## reg (uint32_t fetchdat)                                                  \
    14.6          {                                                                                       \
    14.7 -                if (ssegs) ss=oldss;                                                            \
    14.8                  PUSH_W(reg);                                                                    \
    14.9                  cycles -= (is486) ? 1 : 2;                                                      \
   14.10                  return 0;                                                                       \
   14.11 @@ -10,7 +9,6 @@
   14.12  #define PUSH_L_OP(reg)                                                                          \
   14.13          static int opPUSH_ ## reg (uint32_t fetchdat)                                                  \
   14.14          {                                                                                       \
   14.15 -                if (ssegs) ss=oldss;                                                            \
   14.16                  PUSH_L(reg);                                                                    \
   14.17                  cycles -= (is486) ? 1 : 2;                                                      \
   14.18                  return 0;                                                                       \
   14.19 @@ -19,7 +17,6 @@
   14.20  #define POP_W_OP(reg)                                                                           \
   14.21          static int opPOP_ ## reg (uint32_t fetchdat)                                                   \
   14.22          {                                                                                       \
   14.23 -                if (ssegs) ss=oldss;                                                            \
   14.24                  reg = POP_W();                                                                  \
   14.25                  cycles -= (is486) ? 1 : 4;                                                      \
   14.26                  return 0;                                                                       \
   14.27 @@ -28,7 +25,6 @@
   14.28  #define POP_L_OP(reg)                                                                           \
   14.29          static int opPOP_ ## reg (uint32_t fetchdat)                                                   \
   14.30          {                                                                                       \
   14.31 -                if (ssegs) ss=oldss;                                                            \
   14.32                  reg = POP_L();                                                                  \
   14.33                  cycles -= (is486) ? 1 : 4;                                                      \
   14.34                  return 0;                                                                       \
   14.35 @@ -188,7 +184,6 @@
   14.36  static int opPUSH_imm_w(uint32_t fetchdat)
   14.37  {
   14.38          uint16_t val = getwordf(); 
   14.39 -        if (ssegs) ss=oldss;
   14.40          PUSH_W(val);
   14.41          cycles -= 2;
   14.42          return 0;
   14.43 @@ -196,7 +191,6 @@
   14.44  static int opPUSH_imm_l(uint32_t fetchdat)
   14.45  {
   14.46          uint32_t val = getlong(); 
   14.47 -        if (ssegs) ss=oldss;
   14.48          PUSH_L(val);
   14.49          cycles -= 2;
   14.50          return 0;
   14.51 @@ -226,9 +220,8 @@
   14.52  static int opPOPW_a16(uint32_t fetchdat)
   14.53  {
   14.54          uint16_t temp;
   14.55 -        uint32_t tempseg = ssegs ? oldss : ss;
   14.56          
   14.57 -        temp = POP_W_seg(tempseg);                      if (abrt) return 0;
   14.58 +        temp = POP_W();                                 if (abrt) return 0;
   14.59  
   14.60          fetch_ea_16(fetchdat);
   14.61          seteaw(temp);
   14.62 @@ -245,9 +238,8 @@
   14.63  static int opPOPW_a32(uint32_t fetchdat)
   14.64  {
   14.65          uint16_t temp;
   14.66 -        uint32_t tempseg = ssegs ? oldss : ss;
   14.67                  
   14.68 -        temp = POP_W_seg(tempseg);                      if (abrt) return 0;
   14.69 +        temp = POP_W();                                 if (abrt) return 0;
   14.70          
   14.71          fetch_ea_32(fetchdat);
   14.72          seteaw(temp);
   14.73 @@ -265,9 +257,8 @@
   14.74  static int opPOPL_a16(uint32_t fetchdat)
   14.75  {
   14.76          uint32_t temp;
   14.77 -        uint32_t tempseg = ssegs ? oldss : ss;
   14.78  
   14.79 -        temp = POP_L_seg(tempseg);                      if (abrt) return 0;
   14.80 +        temp = POP_L();                                 if (abrt) return 0;
   14.81  
   14.82          fetch_ea_16(fetchdat);        
   14.83          seteal(temp);
   14.84 @@ -284,9 +275,8 @@
   14.85  static int opPOPL_a32(uint32_t fetchdat)
   14.86  {
   14.87          uint32_t temp;
   14.88 -        uint32_t tempseg = ssegs ? oldss : ss;
   14.89  
   14.90 -        temp = POP_L_seg(tempseg);                      if (abrt) return 0;
   14.91 +        temp = POP_L();                                 if (abrt) return 0;
   14.92  
   14.93          fetch_ea_32(fetchdat);
   14.94          seteal(temp);
   14.95 @@ -401,14 +391,12 @@
   14.96  #define PUSH_SEG_OPS(seg)                                                       \
   14.97          static int opPUSH_ ## seg ## _w(uint32_t fetchdat)                      \
   14.98          {                                                                       \
   14.99 -                if (ssegs) ss=oldss;                                            \
  14.100                  PUSH_W(seg);                                                    \
  14.101                  cycles -= 2;                                                    \
  14.102                  return 0;                                                       \
  14.103          }                                                                       \
  14.104          static int opPUSH_ ## seg ## _l(uint32_t fetchdat)                      \
  14.105          {                                                                       \
  14.106 -                if (ssegs) ss=oldss;                                            \
  14.107                  PUSH_L(seg);                                                    \
  14.108                  cycles -= 2;                                                    \
  14.109                  return 0;                                                       \
  14.110 @@ -419,7 +407,6 @@
  14.111          {                                                                       \
  14.112                  uint16_t temp_seg;                                              \
  14.113                  uint32_t temp_esp = ESP;                                        \
  14.114 -                if (ssegs) ss=oldss;                                            \
  14.115                  temp_seg = POP_W();                     if (abrt) return 0;     \
  14.116                  loadseg(temp_seg, realseg);             if (abrt) ESP = temp_esp; \
  14.117                  cycles -= is486 ? 3 : 7;                                        \
  14.118 @@ -429,7 +416,6 @@
  14.119          {                                                                       \
  14.120                  uint32_t temp_seg;                                              \
  14.121                  uint32_t temp_esp = ESP;                                        \
  14.122 -                if (ssegs) ss=oldss;                                            \
  14.123                  temp_seg = POP_L();                     if (abrt) return 0;     \
  14.124                  loadseg(temp_seg & 0xffff, realseg);    if (abrt) ESP = temp_esp; \
  14.125                  cycles -= is486 ? 3 : 7;                                        \
    15.1 --- a/src/x86_ops_string.h	Sun Aug 03 20:38:04 2014 +0100
    15.2 +++ b/src/x86_ops_string.h	Wed Aug 13 20:33:56 2014 +0100
    15.3 @@ -1,6 +1,6 @@
    15.4  static int opMOVSB_a16(uint32_t fetchdat)
    15.5  {
    15.6 -        uint8_t temp = readmemb(ds,SI);         if (abrt) return 0;
    15.7 +        uint8_t temp = readmemb(ea_seg->base, SI); if (abrt) return 0;
    15.8          writememb(es, DI, temp);                if (abrt) return 0;
    15.9          if (flags & D_FLAG) { DI--; SI--; }
   15.10          else                { DI++; SI++; }
   15.11 @@ -9,7 +9,7 @@
   15.12  }
   15.13  static int opMOVSB_a32(uint32_t fetchdat)
   15.14  {
   15.15 -        uint8_t temp = readmemb(ds,ESI);        if (abrt) return 0;
   15.16 +        uint8_t temp = readmemb(ea_seg->base, ESI); if (abrt) return 0;
   15.17          writememb(es, EDI, temp);               if (abrt) return 0;
   15.18          if (flags & D_FLAG) { EDI--; ESI--; }
   15.19          else                { EDI++; ESI++; }
   15.20 @@ -19,7 +19,7 @@
   15.21  
   15.22  static int opMOVSW_a16(uint32_t fetchdat)
   15.23  {
   15.24 -        uint16_t temp = readmemw(ds,SI);        if (abrt) return 0;
   15.25 +        uint16_t temp = readmemw(ea_seg->base, SI); if (abrt) return 0;
   15.26          writememw(es, DI, temp);                if (abrt) return 0;
   15.27          if (flags & D_FLAG) { DI -= 2; SI -= 2; }
   15.28          else                { DI += 2; SI += 2; }
   15.29 @@ -28,7 +28,7 @@
   15.30  }
   15.31  static int opMOVSW_a32(uint32_t fetchdat)
   15.32  {
   15.33 -        uint16_t temp = readmemw(ds,ESI);       if (abrt) return 0;
   15.34 +        uint16_t temp = readmemw(ea_seg->base, ESI); if (abrt) return 0;
   15.35          writememw(es, EDI, temp);               if (abrt) return 0;
   15.36          if (flags & D_FLAG) { EDI -= 2; ESI -= 2; }
   15.37          else                { EDI += 2; ESI += 2; }
   15.38 @@ -38,7 +38,7 @@
   15.39  
   15.40  static int opMOVSL_a16(uint32_t fetchdat)
   15.41  {
   15.42 -        uint32_t temp = readmeml(ds,SI);        if (abrt) return 0;
   15.43 +        uint32_t temp = readmeml(ea_seg->base, SI); if (abrt) return 0;
   15.44          writememl(es, DI, temp);                if (abrt) return 0;
   15.45          if (flags & D_FLAG) { DI -= 4; SI -= 4; }
   15.46          else                { DI += 4; SI += 4; }
   15.47 @@ -47,7 +47,7 @@
   15.48  }
   15.49  static int opMOVSL_a32(uint32_t fetchdat)
   15.50  {
   15.51 -        uint32_t temp = readmeml(ds,ESI);       if (abrt) return 0;
   15.52 +        uint32_t temp = readmeml(ea_seg->base, ESI); if (abrt) return 0;
   15.53          writememl(es, EDI, temp);               if (abrt) return 0;
   15.54          if (flags & D_FLAG) { EDI -= 4; ESI -= 4; }
   15.55          else                { EDI += 4; ESI += 4; }
   15.56 @@ -58,7 +58,7 @@
   15.57  
   15.58  static int opCMPSB_a16(uint32_t fetchdat)
   15.59  {
   15.60 -        uint8_t src = readmemb(ds, SI);
   15.61 +        uint8_t src = readmemb(ea_seg->base, SI);
   15.62          uint8_t dst = readmemb(es, DI);         if (abrt) return 0;
   15.63          setsub8(src, dst);
   15.64          if (flags & D_FLAG) { DI--; SI--; }
   15.65 @@ -68,7 +68,7 @@
   15.66  }
   15.67  static int opCMPSB_a32(uint32_t fetchdat)
   15.68  {
   15.69 -        uint8_t src = readmemb(ds, ESI);
   15.70 +        uint8_t src = readmemb(ea_seg->base, ESI);
   15.71          uint8_t dst = readmemb(es, EDI);        if (abrt) return 0;
   15.72          setsub8(src, dst);
   15.73          if (flags & D_FLAG) { EDI--; ESI--; }
   15.74 @@ -79,7 +79,7 @@
   15.75  
   15.76  static int opCMPSW_a16(uint32_t fetchdat)
   15.77  {
   15.78 -        uint16_t src = readmemw(ds, SI);
   15.79 +        uint16_t src = readmemw(ea_seg->base, SI);
   15.80          uint16_t dst = readmemw(es, DI);        if (abrt) return 0;
   15.81          setsub16(src, dst);
   15.82          if (flags & D_FLAG) { DI -= 2; SI -= 2; }
   15.83 @@ -89,7 +89,7 @@
   15.84  }
   15.85  static int opCMPSW_a32(uint32_t fetchdat)
   15.86  {
   15.87 -        uint16_t src = readmemw(ds, ESI);
   15.88 +        uint16_t src = readmemw(ea_seg->base, ESI);
   15.89          uint16_t dst = readmemw(es, EDI);        if (abrt) return 0;
   15.90          setsub16(src, dst);
   15.91          if (flags & D_FLAG) { EDI -= 2; ESI -= 2; }
   15.92 @@ -100,7 +100,7 @@
   15.93  
   15.94  static int opCMPSL_a16(uint32_t fetchdat)
   15.95  {
   15.96 -        uint32_t src = readmeml(ds, SI);
   15.97 +        uint32_t src = readmeml(ea_seg->base, SI);
   15.98          uint32_t dst = readmeml(es, DI);        if (abrt) return 0;
   15.99          setsub32(src, dst);
  15.100          if (flags & D_FLAG) { DI -= 4; SI -= 4; }
  15.101 @@ -110,7 +110,7 @@
  15.102  }
  15.103  static int opCMPSL_a32(uint32_t fetchdat)
  15.104  {
  15.105 -        uint32_t src = readmeml(ds, ESI);
  15.106 +        uint32_t src = readmeml(ea_seg->base, ESI);
  15.107          uint32_t dst = readmeml(es, EDI);        if (abrt) return 0;
  15.108          setsub32(src, dst);
  15.109          if (flags & D_FLAG) { EDI -= 4; ESI -= 4; }
  15.110 @@ -173,7 +173,7 @@
  15.111  
  15.112  static int opLODSB_a16(uint32_t fetchdat)
  15.113  {
  15.114 -        uint8_t temp = readmemb(ds, SI);        if (abrt) return 0;
  15.115 +        uint8_t temp = readmemb(ea_seg->base, SI); if (abrt) return 0;
  15.116          AL = temp;
  15.117          if (flags & D_FLAG) SI--;
  15.118          else                SI++;
  15.119 @@ -182,7 +182,7 @@
  15.120  }
  15.121  static int opLODSB_a32(uint32_t fetchdat)
  15.122  {
  15.123 -        uint8_t temp = readmemb(ds, ESI);       if (abrt) return 0;
  15.124 +        uint8_t temp = readmemb(ea_seg->base, ESI); if (abrt) return 0;
  15.125          AL = temp;
  15.126          if (flags & D_FLAG) ESI--;
  15.127          else                ESI++;
  15.128 @@ -192,7 +192,7 @@
  15.129  
  15.130  static int opLODSW_a16(uint32_t fetchdat)
  15.131  {
  15.132 -        uint16_t temp = readmemw(ds, SI);       if (abrt) return 0;
  15.133 +        uint16_t temp = readmemw(ea_seg->base, SI); if (abrt) return 0;
  15.134          AX = temp;
  15.135          if (flags & D_FLAG) SI -= 2;
  15.136          else                SI += 2;
  15.137 @@ -201,7 +201,7 @@
  15.138  }
  15.139  static int opLODSW_a32(uint32_t fetchdat)
  15.140  {
  15.141 -        uint16_t temp = readmemw(ds, ESI);      if (abrt) return 0;
  15.142 +        uint16_t temp = readmemw(ea_seg->base, ESI); if (abrt) return 0;
  15.143          AX = temp;
  15.144          if (flags & D_FLAG) ESI -= 2;
  15.145          else                ESI += 2;
  15.146 @@ -211,7 +211,7 @@
  15.147  
  15.148  static int opLODSL_a16(uint32_t fetchdat)
  15.149  {
  15.150 -        uint32_t temp = readmeml(ds, SI);       if (abrt) return 0;
  15.151 +        uint32_t temp = readmeml(ea_seg->base, SI); if (abrt) return 0;
  15.152          EAX = temp;
  15.153          if (flags & D_FLAG) SI -= 4;
  15.154          else                SI += 4;
  15.155 @@ -220,7 +220,7 @@
  15.156  }
  15.157  static int opLODSL_a32(uint32_t fetchdat)
  15.158  {
  15.159 -        uint32_t temp = readmeml(ds, ESI);      if (abrt) return 0;
  15.160 +        uint32_t temp = readmeml(ea_seg->base, ESI); if (abrt) return 0;
  15.161          EAX = temp;
  15.162          if (flags & D_FLAG) ESI -= 4;
  15.163          else                ESI += 4;
  15.164 @@ -365,7 +365,7 @@
  15.165  
  15.166  static int opOUTSB_a16(uint32_t fetchdat)
  15.167  {
  15.168 -        uint8_t temp = readmemb(ds, SI);        if (abrt) return 0;
  15.169 +        uint8_t temp = readmemb(ea_seg->base, SI); if (abrt) return 0;
  15.170          check_io_perm(DX);
  15.171          if (flags & D_FLAG) SI--;
  15.172          else                SI++;
  15.173 @@ -375,7 +375,7 @@
  15.174  }
  15.175  static int opOUTSB_a32(uint32_t fetchdat)
  15.176  {
  15.177 -        uint8_t temp = readmemb(ds, ESI);        if (abrt) return 0;
  15.178 +        uint8_t temp = readmemb(ea_seg->base, ESI); if (abrt) return 0;
  15.179          check_io_perm(DX);
  15.180          if (flags & D_FLAG) ESI--;
  15.181          else                ESI++;
  15.182 @@ -386,7 +386,7 @@
  15.183  
  15.184  static int opOUTSW_a16(uint32_t fetchdat)
  15.185  {
  15.186 -        uint16_t temp = readmemw(ds, SI);       if (abrt) return 0;
  15.187 +        uint16_t temp = readmemw(ea_seg->base, SI); if (abrt) return 0;
  15.188          check_io_perm(DX);
  15.189          check_io_perm(DX + 1);
  15.190          if (flags & D_FLAG) SI -= 2;
  15.191 @@ -397,7 +397,7 @@
  15.192  }
  15.193  static int opOUTSW_a32(uint32_t fetchdat)
  15.194  {
  15.195 -        uint16_t temp = readmemw(ds, ESI);      if (abrt) return 0;
  15.196 +        uint16_t temp = readmemw(ea_seg->base, ESI); if (abrt) return 0;
  15.197          check_io_perm(DX);
  15.198          check_io_perm(DX + 1);
  15.199          if (flags & D_FLAG) ESI -= 2;
  15.200 @@ -409,7 +409,7 @@
  15.201  
  15.202  static int opOUTSL_a16(uint32_t fetchdat)
  15.203  {
  15.204 -        uint32_t temp = readmeml(ds, SI);       if (abrt) return 0;
  15.205 +        uint32_t temp = readmeml(ea_seg->base, SI); if (abrt) return 0;
  15.206          check_io_perm(DX);
  15.207          check_io_perm(DX + 1);
  15.208          check_io_perm(DX + 2);
  15.209 @@ -422,7 +422,7 @@
  15.210  }
  15.211  static int opOUTSL_a32(uint32_t fetchdat)
  15.212  {
  15.213 -        uint32_t temp = readmeml(ds, ESI);      if (abrt) return 0;
  15.214 +        uint32_t temp = readmeml(ea_seg->base, ESI); if (abrt) return 0;
  15.215          check_io_perm(DX);
  15.216          check_io_perm(DX + 1);
  15.217          check_io_perm(DX + 2);
    16.1 --- a/src/x86seg.c	Sun Aug 03 20:38:04 2014 +0100
    16.2 +++ b/src/x86seg.c	Wed Aug 13 20:33:56 2014 +0100
    16.3 @@ -57,6 +57,24 @@
    16.4  
    16.5  uint8_t opcode2;
    16.6  
    16.7 +static void seg_reset(x86seg *s)
    16.8 +{
    16.9 +        s->access = 0 << 5;
   16.10 +        s->limit = 0xFFFF;
   16.11 +        s->limit_low = 0;
   16.12 +        s->limit_high = 0xffff;
   16.13 +}
   16.14 +
   16.15 +void x86seg_reset()
   16.16 +{
   16.17 +        seg_reset(&_cs);
   16.18 +        seg_reset(&_ds);
   16.19 +        seg_reset(&_es);
   16.20 +        seg_reset(&_fs);
   16.21 +        seg_reset(&_gs);
   16.22 +        seg_reset(&_ss);
   16.23 +}
   16.24 +
   16.25  void x86_doabrt(int x86_abrt)
   16.26  {
   16.27  //        ingpf = 1;
   16.28 @@ -73,7 +91,33 @@
   16.29          }*/
   16.30  //        pclog("GPF! - error %04X  %04X(%08X):%08X %02X %02X  %i  %04X %i %i\n",error,CS,cs,pc,opcode,opcode2,ins,flags&I_FLAG,IOPL, dtimes);
   16.31  
   16.32 -        pmodeint(x86_abrt, 0);
   16.33 +        if (msw & 1)
   16.34 +                pmodeint(x86_abrt, 0);
   16.35 +        else
   16.36 +        {
   16.37 +                uint32_t addr = (x86_abrt << 2) + idt.base;
   16.38 +                if (stack32)
   16.39 +                {
   16.40 +                        writememw(ss,ESP-2,flags);
   16.41 +                        writememw(ss,ESP-4,CS);
   16.42 +                        writememw(ss,ESP-6,pc);
   16.43 +                        ESP-=6;
   16.44 +                }
   16.45 +                else
   16.46 +                {
   16.47 +                        writememw(ss,((SP-2)&0xFFFF),flags);
   16.48 +                        writememw(ss,((SP-4)&0xFFFF),CS);
   16.49 +                        writememw(ss,((SP-6)&0xFFFF),pc);
   16.50 +                        SP-=6;
   16.51 +                }
   16.52 +
   16.53 +                flags&=~I_FLAG;
   16.54 +                flags&=~T_FLAG;
   16.55 +                oxpc=pc;
   16.56 +                pc=readmemw(0,addr);
   16.57 +                loadcs(readmemw(0,addr+2));
   16.58 +                return;
   16.59 +        }
   16.60          
   16.61          if (abrt) return;
   16.62          
   16.63 @@ -132,12 +176,90 @@
   16.64  }
   16.65  
   16.66  
   16.67 +static void do_seg_load(x86seg *s, uint16_t *segdat)
   16.68 +{
   16.69 +        s->limit = segdat[0] | ((segdat[3] & 0xF) << 16);
   16.70 +        if (segdat[3] & 0x80)
   16.71 +                s->limit = (s->limit << 12) | 0xFFF;
   16.72 +        s->base = segdat[1] | ((segdat[2] & 0xFF) << 16);
   16.73 +        if (is386)
   16.74 +                s->base |= ((segdat[3] >> 8) << 24);
   16.75 +        s->access = segdat[2] >> 8;
   16.76 +                        
   16.77 +        if ((segdat[2] & 0x1800) != 0x1000 || !(segdat[2] & (1 << 10))) /*expand-down*/
   16.78 +        {
   16.79 +                s->limit_high = s->limit;
   16.80 +                s->limit_low = 0;
   16.81 +        }
   16.82 +        else
   16.83 +        {
   16.84 +                s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff;
   16.85 +                s->limit_low = s->limit + 1;
   16.86 +        }
   16.87 +//        if (output) pclog("SEG : base=%08x limit=%08x low=%08x high=%08x\n", s->base, s->limit, s->limit_low, s->limit_high);
   16.88 +}
   16.89 +
   16.90 +static void do_seg_v86_init(x86seg *s)
   16.91 +{
   16.92 +        s->access = 3 << 5;
   16.93 +        s->limit = 0xffff;
   16.94 +        s->limit_low = 0;
   16.95 +        s->limit_high = 0xffff;
   16.96 +}
   16.97 +
   16.98 +static void check_seg_valid(x86seg *s)
   16.99 +{
  16.100 +        int dpl = (s->access >> 5) & 3;
  16.101 +        int valid = 1;
  16.102 +
  16.103 +        if (s->seg & 4)
  16.104 +        {
  16.105 +                if ((s->seg & ~7) >= ldt.limit)
  16.106 +                {
  16.107 +//                        pclog("Bigger than LDT limit %04X %04X %02X %02X %02X\n", s->seg, ldt.limit, opcode, opcode2, rmdat);
  16.108 +                        valid = 0;
  16.109 +                }
  16.110 +        }
  16.111 +        else
  16.112 +        {
  16.113 +                if ((s->seg & ~7) >= gdt.limit)
  16.114 +                {
  16.115 +//                        pclog("Bigger than GDT limit %04X %04X\n", s->seg, gdt.limit);
  16.116 +                        valid = 0;
  16.117 +                }
  16.118 +        }
  16.119 +
  16.120 +        switch (s->access & 0x1f)
  16.121 +        {
  16.122 +                case 0x10: case 0x11: case 0x12: case 0x13: /*Data segments*/
  16.123 +                case 0x14: case 0x15: case 0x16: case 0x17:
  16.124 +                case 0x1A: case 0x1B: /*Readable non-conforming code*/
  16.125 +                if ((s->seg & 3) > dpl || (CPL) > dpl)
  16.126 +                {
  16.127 +//                        pclog("Data seg fail - %04X:%08X %04X %i\n", CS, pc, s->seg, dpl);
  16.128 +                        valid = 0;
  16.129 +                        break;
  16.130 +                }
  16.131 +                break;
  16.132 +                
  16.133 +                case 0x1E: case 0x1F: /*Readable conforming code*/
  16.134 +                break;
  16.135 +                
  16.136 +                default:
  16.137 +                valid = 0;
  16.138 +                break;
  16.139 +        }
  16.140 +        
  16.141 +        if (!valid)
  16.142 +                loadseg(0, s);
  16.143 +}
  16.144 +
  16.145  void loadseg(uint16_t seg, x86seg *s)
  16.146  {
  16.147          uint16_t segdat[4];
  16.148          uint32_t addr;
  16.149          int dpl;
  16.150 -        if (output) pclog("Load seg %04X\n",seg);
  16.151 +
  16.152          if (msw&1 && !(eflags&VM_FLAG))
  16.153          {
  16.154  //                intcount++;
  16.155 @@ -153,6 +275,7 @@
  16.156                          }
  16.157  //                        if (s->base!=-1) pclog("NEW! ");
  16.158                          s->seg=0;
  16.159 +                        s->access = 0;
  16.160                          s->base=-1;
  16.161  //                        pclog("NULL selector %s%s%s%s %04X(%06X):%06X\n",(s==&_ds)?"DS":"",(s==&_es)?"ES":"",(s==&_fs)?"FS":"",(s==&_gs)?"GS":"",CS,cs,pc);
  16.162                          return;
  16.163 @@ -224,7 +347,7 @@
  16.164                          }
  16.165                          if (segdat[3]&0x40) stack32=1;
  16.166                          else                stack32=0;
  16.167 -//                        pclog("Load SS\n");
  16.168 +//                        pclog("Load SS  %04x %04x %04x %04x\n", segdat[0], segdat[1], segdat[2], segdat[3]);
  16.169                  }
  16.170                  else if (s!=&_cs)
  16.171                  {
  16.172 @@ -248,71 +371,38 @@
  16.173                                  break;
  16.174                                  default:
  16.175                                  pclog("Invalid segment type for %04X! %04X\n",seg&0xFFFC,segdat[2]);
  16.176 -//                                if ((seg & ~3) == 0x1508) btimes++;
  16.177 -//                                if (btimes == 2) output = 3;
  16.178 -//                                dumpregs();
  16.179 -//                                exit(-1);
  16.180                                  x86gpf(NULL,seg&~3);
  16.181 -//                                x86abort("Invalid segment type for %04X!\n",seg&0xFFFC);
  16.182                                  return;
  16.183                          }
  16.184                  }
  16.185 -//                #endif
  16.186 -//                }
  16.187 -//                if (!(segdat[2]&0x8000)) x86abort("Data segment not present!\n");
  16.188 -//                if (!(segdat[2]&0x800) || !(segdat[2]&0x400))
  16.189 -//                {
  16.190 -                        if (!(segdat[2]&0x8000))
  16.191 -                        {
  16.192 -                                x86np("Load data seg not present", seg & 0xfffc);
  16.193 -                                return;
  16.194 -                        }
  16.195 -                        s->seg=seg;
  16.196 -                        s->limit=segdat[0]|((segdat[3]&0xF)<<16);
  16.197 -                        if (segdat[3]&0x80) s->limit=(s->limit<<12)|0xFFF;
  16.198 -                        s->limitw=(segdat[2]&0x200)?1:0;
  16.199 -                        s->base=segdat[1];
  16.200 -                        s->base|=((segdat[2]&0xFF)<<16);
  16.201 -                        if (is386) s->base|=((segdat[3]>>8)<<24);
  16.202 -                        s->access=segdat[2]>>8;
  16.203 -                        
  16.204 -                        if ((segdat[2]>>8) & 4)
  16.205 -                           s->limit = 0xffffffff;
  16.206 -                           
  16.207 -//                        if (output) pclog("SS limit %08X\n", s->limit);
  16.208 -                        
  16.209 -//                        pclog("Seg Write %04X to %08X\n",segdat[2]|0x100,addr+4);
  16.210 +
  16.211 +                if (!(segdat[2] & 0x8000))
  16.212 +                {
  16.213 +                        x86np("Load data seg not present", seg & 0xfffc);
  16.214 +                        return;
  16.215 +                }
  16.216 +                s->seg = seg;
  16.217 +                do_seg_load(s, segdat);
  16.218 +
  16.219  #ifndef CS_ACCESSED
  16.220 -                        if (s != &_cs)
  16.221 -                        {
  16.222 +                if (s != &_cs)
  16.223 +                {
  16.224  #endif                   
  16.225  #ifdef SEL_ACCESSED         
  16.226 -                                cpl_override = 1;
  16.227 -                                writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/
  16.228 -                                cpl_override = 0;
  16.229 +                        cpl_override = 1;
  16.230 +                        writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/
  16.231 +                        cpl_override = 0;
  16.232  #endif
  16.233  #ifndef CS_ACCESSED
  16.234 -                        }
  16.235 +                }
  16.236  #endif
  16.237 -//                        pclog("Access=%02X Limit=%04X Limitw=%04X   %08X  %i %04X:%04X\n",s->access,s->limit,s->limitw, _ss.limit, ins, CS, pc);
  16.238 -//                        if (s==&_es && s->base>0x180000) s->base=0x180000;
  16.239 -//                }
  16.240 -//                pclog("base=%06X limit=%04X access=%02X  %06X  %04X %04X %04X  %04X\n",s->base,s->limit,s->access,addr,segdat[0],segdat[1],segdat[2],seg);
  16.241 -//                dumpregs();
  16.242 -//                exit(-1);
  16.243          }
  16.244          else
  16.245          {
  16.246 -                s->base=seg<<4;
  16.247 -                s->limit=0xFFFF;
  16.248 -                s->seg=seg;
  16.249 -                if (eflags&VM_FLAG) s->access=3<<5;
  16.250 -                else                s->access=0<<5;
  16.251 -                if (s==&_ss) stack32=0;
  16.252 -/*                if (s==&_ds)
  16.253 -                {
  16.254 -                        pclog("DS! %04X %06X %04X:%04X\n",DS,ds,CS,pc);
  16.255 -                }*/
  16.256 +                s->base = seg << 4;
  16.257 +                s->seg = seg;
  16.258 +                if (s == &_ss)
  16.259 +                        stack32 = 0;
  16.260          }
  16.261  }
  16.262  
  16.263 @@ -397,12 +487,7 @@
  16.264                          if (segdat[3]&0x40) use32=0x300;
  16.265                          else                use32=0;
  16.266                          CS=(seg&~3)|CPL;
  16.267 -                        _cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
  16.268 -                        if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
  16.269 -                        _cs.base=segdat[1];
  16.270 -                        _cs.base|=((segdat[2]&0xFF)<<16);
  16.271 -                        if (is386) _cs.base|=((segdat[3]>>8)<<24);
  16.272 -                        _cs.access=segdat[2]>>8;
  16.273 +                        do_seg_load(&_cs, segdat);
  16.274                          use32=(segdat[3]&0x40)?0x300:0;
  16.275                          if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
  16.276  
  16.277 @@ -437,6 +522,8 @@
  16.278          {
  16.279                  _cs.base=seg<<4;
  16.280                  _cs.limit=0xFFFF;
  16.281 +                _cs.limit_low = 0;
  16.282 +                _cs.limit_high = 0xffff;
  16.283                  CS=seg;
  16.284                  if (eflags&VM_FLAG) _cs.access=3<<5;
  16.285                  else                _cs.access=0<<5;
  16.286 @@ -526,13 +613,8 @@
  16.287                          
  16.288                          CS = (seg & ~3) | CPL;
  16.289                          segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8));
  16.290 -                        
  16.291 -                        _cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
  16.292 -                        if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
  16.293 -                        _cs.base=segdat[1];
  16.294 -                        _cs.base|=((segdat[2]&0xFF)<<16);
  16.295 -                        if (is386) _cs.base|=((segdat[3]>>8)<<24);
  16.296 -                        _cs.access=segdat[2]>>8;
  16.297 +
  16.298 +                        do_seg_load(&_cs, segdat);
  16.299                          if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
  16.300                          use32=(segdat[3]&0x40)?0x300:0;
  16.301                  }
  16.302 @@ -627,12 +709,7 @@
  16.303                                          }
  16.304                                          case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
  16.305                                          CS=seg2;
  16.306 -                                        _cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
  16.307 -                                        if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
  16.308 -                                        _cs.base=segdat[1];
  16.309 -                                        _cs.base|=((segdat[2]&0xFF)<<16);
  16.310 -                                        if (is386) _cs.base|=((segdat[3]>>8)<<24);
  16.311 -                                        _cs.access=segdat[2]>>8;
  16.312 +                                        do_seg_load(&_cs, segdat);
  16.313                                          if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
  16.314                                          use32=(segdat[3]&0x40)?0x300:0;
  16.315                                                  pc=newpc;
  16.316 @@ -679,6 +756,8 @@
  16.317          {
  16.318                  _cs.base=seg<<4;
  16.319                  _cs.limit=0xFFFF;
  16.320 +                _cs.limit_low = 0;
  16.321 +                _cs.limit_high = 0xffff;
  16.322                  CS=seg;
  16.323                  if (eflags&VM_FLAG) _cs.access=3<<5;
  16.324                  else                _cs.access=0<<5;
  16.325 @@ -858,12 +937,7 @@
  16.326                          else /*On non-conforming segments, set RPL = CPL*/
  16.327                                  seg = (seg & ~3) | CPL;
  16.328                          CS=seg;
  16.329 -                        _cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
  16.330 -                        if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
  16.331 -                        _cs.base=segdat[1];
  16.332 -                        _cs.base|=((segdat[2]&0xFF)<<16);
  16.333 -                        if (is386) _cs.base|=((segdat[3]>>8)<<24);
  16.334 -                        _cs.access=segdat[2]>>8;
  16.335 +                        do_seg_load(&_cs, segdat);
  16.336                          if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
  16.337                          use32=(segdat[3]&0x40)?0x300:0;
  16.338                          if (csout) pclog("Complete\n");
  16.339 @@ -1031,16 +1105,8 @@
  16.340                                                  stack32=segdat2[3]&0x40;
  16.341                                                  if (stack32) ESP=newsp;
  16.342                                                  else         SP=newsp;
  16.343 -                                                _ss.limit=segdat2[0]|((segdat2[3]&0xF)<<16);
  16.344 -                                                if (segdat2[3]&0x80) _ss.limit=(_ss.limit<<12)|0xFFF;
  16.345 -                                                if ((segdat2[2]>>8) & 4)
  16.346 -                                                   _ss.limit = 0xffffffff;
  16.347 -
  16.348 -                                                _ss.limitw=(segdat2[2]&0x200)?1:0;
  16.349 -                                                _ss.base=segdat2[1];
  16.350 -                                                _ss.base|=((segdat2[2]&0xFF)<<16);
  16.351 -                                                if (is386) _ss.base|=((segdat2[3]>>8)<<24);
  16.352 -                                                _ss.access=segdat2[2]>>8;
  16.353 +                                                
  16.354 +                                                do_seg_load(&_ss, segdat2);
  16.355  
  16.356                                                  if (output) pclog("Set access 1\n");
  16.357  
  16.358 @@ -1051,12 +1117,7 @@
  16.359  #endif
  16.360                                                  
  16.361                                                  CS=seg2;
  16.362 -                                                _cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
  16.363 -                                                if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
  16.364 -                                                _cs.base=segdat[1];
  16.365 -                                                _cs.base|=((segdat[2]&0xFF)<<16);
  16.366 -                                                if (is386) _cs.base|=((segdat[3]>>8)<<24);
  16.367 -                                                _cs.access=segdat[2]>>8;
  16.368 +                                                do_seg_load(&_cs, segdat);
  16.369                                                  if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
  16.370                                                  use32=(segdat[3]&0x40)?0x300:0;
  16.371                                                  pc=newpc;
  16.372 @@ -1159,12 +1220,7 @@
  16.373                                                  PUSHW(oldpc); if (abrt) return;
  16.374                                          }*/
  16.375                                          CS=seg2;
  16.376 -                                        _cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
  16.377 -                                        if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
  16.378 -                                        _cs.base=segdat[1];
  16.379 -                                        _cs.base|=((segdat[2]&0xFF)<<16);
  16.380 -                                        if (is386) _cs.base|=((segdat[3]>>8)<<24);
  16.381 -                                        _cs.access=segdat[2]>>8;
  16.382 +                                        do_seg_load(&_cs, segdat);
  16.383                                          if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
  16.384                                          use32=(segdat[3]&0x40)?0x300:0;
  16.385                                                  pc=newpc;
  16.386 @@ -1206,6 +1262,8 @@
  16.387          {
  16.388                  _cs.base=seg<<4;
  16.389                  _cs.limit=0xFFFF;
  16.390 +                _cs.limit_low = 0;
  16.391 +                _cs.limit_high = 0xffff;
  16.392                  CS=seg;
  16.393                  if (eflags&VM_FLAG) _cs.access=3<<5;
  16.394                  else                _cs.access=0<<5;
  16.395 @@ -1334,12 +1392,7 @@
  16.396                  if (segdat[2] & 0x400)
  16.397                     segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8));
  16.398                  CS = seg;
  16.399 -                _cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
  16.400 -                if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
  16.401 -                _cs.base=segdat[1];
  16.402 -                _cs.base|=((segdat[2]&0xFF)<<16);
  16.403 -                if (is386) _cs.base|=((segdat[3]>>8)<<24);
  16.404 -                _cs.access=segdat[2]>>8;
  16.405 +                do_seg_load(&_cs, segdat);
  16.406                  if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
  16.407                  use32=(segdat[3]&0x40)?0x300:0;
  16.408                  
  16.409 @@ -1472,15 +1525,7 @@
  16.410                  stack32=segdat2[3]&0x40;
  16.411                  if (stack32) ESP=newsp;
  16.412                  else         SP=newsp;
  16.413 -                _ss.limit=segdat2[0]|((segdat2[3]&0xF)<<16);
  16.414 -                if (segdat2[3]&0x80) _ss.limit=(_ss.limit<<12)|0xFFF;
  16.415 -                if ((segdat2[2]>>8) & 4)
  16.416 -                   _ss.limit = 0xffffffff;
  16.417 -                _ss.limitw=(segdat2[2]&0x200)?1:0;
  16.418 -                _ss.base=segdat2[1];
  16.419 -                _ss.base|=((segdat2[2]&0xFF)<<16);
  16.420 -                if (is386) _ss.base|=((segdat2[3]>>8)<<24);
  16.421 -                _ss.access=segdat2[2]>>8;
  16.422 +                do_seg_load(&_ss, segdat2);
  16.423  
  16.424  #ifdef SEL_ACCESSED
  16.425                  cpl_override = 1;
  16.426 @@ -1497,24 +1542,24 @@
  16.427  
  16.428                  pc=newpc;
  16.429                  CS=seg;
  16.430 -                _cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
  16.431 -                if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
  16.432 -                _cs.base=segdat[1];
  16.433 -                _cs.base|=((segdat[2]&0xFF)<<16);
  16.434 -                if (is386) _cs.base|=((segdat[3]>>8)<<24);
  16.435 -                _cs.access=segdat[2]>>8;
  16.436 +                do_seg_load(&_cs, segdat);
  16.437                  if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
  16.438                  use32=(segdat[3]&0x40)?0x300:0;
  16.439                  
  16.440                  if (stack32) ESP+=off;
  16.441                  else         SP+=off;
  16.442 +                
  16.443 +                check_seg_valid(&_ds);
  16.444 +                check_seg_valid(&_es);
  16.445 +                check_seg_valid(&_fs);
  16.446 +                check_seg_valid(&_gs);
  16.447  //                pclog("CPL<RPL return to %04X:%08X %04X:%08X\n",CS,pc,SS,ESP);
  16.448          }
  16.449  }
  16.450  
  16.451  void restore_stack()
  16.452  {
  16.453 -        ss=oldss; _ss.limit=oldsslimit; _ss.limitw=oldsslimitw;
  16.454 +        ss=oldss; _ss.limit=oldsslimit;
  16.455  }
  16.456  
  16.457  void pmodeint(int num, int soft)
  16.458 @@ -1527,6 +1572,7 @@
  16.459          uint32_t newsp;
  16.460          uint16_t seg;
  16.461          int stack_changed=0;
  16.462 +        
  16.463  //        if (!num) pclog("Pmode int 0 at %04X(%06X):%08X\n",CS,cs,pc);
  16.464  //        pclog("Pmode int %02X %i %04X:%08X %04X:%08X %i\n",num,soft,CS,pc, SS, ESP, abrt);
  16.465          if (eflags&VM_FLAG && IOPL!=3 && soft)
  16.466 @@ -1728,15 +1774,7 @@
  16.467                                          stack32=segdat3[3]&0x40;
  16.468                                          if (stack32) ESP=newsp;
  16.469                                          else         SP=newsp;
  16.470 -                                        _ss.limit=segdat3[0]|((segdat3[3]&0xF)<<16);
  16.471 -                                        if (segdat3[3]&0x80) _ss.limit=(_ss.limit<<12)|0xFFF;
  16.472 -                                        if ((segdat3[2]>>8) & 4)
  16.473 -                                           _ss.limit = 0xffffffff;
  16.474 -                                        _ss.limitw=(segdat3[2]&0x200)?1:0;
  16.475 -                                        _ss.base=segdat3[1];
  16.476 -                                        _ss.base|=((segdat3[2]&0xFF)<<16);
  16.477 -                                        if (is386) _ss.base|=((segdat3[3]>>8)<<24);
  16.478 -                                        _ss.access=segdat3[2]>>8;
  16.479 +                                        do_seg_load(&_ss, segdat3);
  16.480  
  16.481  #ifdef CS_ACCESSED                                        
  16.482                                          cpl_override = 1;
  16.483 @@ -1805,7 +1843,7 @@
  16.484                                          x86gpf(NULL,seg&~3);
  16.485                                          return;
  16.486                                  }
  16.487 -                                if (!stack_changed && ssegs) restore_stack();
  16.488 +//                                if (!stack_changed && ssegs) restore_stack();
  16.489                                  if (type>0x800)
  16.490                                  {
  16.491                                          PUSHL(flags|(eflags<<16));
  16.492 @@ -1830,12 +1868,7 @@
  16.493                          }
  16.494                  CS=(seg&~3)|CPL;
  16.495  //                pclog("New CS = %04X\n",CS);
  16.496 -                _cs.limit=segdat2[0]|((segdat2[3]&0xF)<<16);
  16.497 -                if (segdat2[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
  16.498 -                _cs.base=segdat2[1];
  16.499 -                _cs.base|=((segdat2[2]&0xFF)<<16);
  16.500 -                if (is386) _cs.base|=((segdat2[3]>>8)<<24);
  16.501 -                _cs.access=segdat2[2]>>8;
  16.502 +                do_seg_load(&_cs, segdat2);
  16.503                  if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
  16.504                  if (type>0x800) pc=segdat[0]|(segdat[3]<<16);
  16.505                  else            pc=segdat[0];
  16.506 @@ -1943,6 +1976,8 @@
  16.507                  pc=newpc;
  16.508                  _cs.base=seg<<4;
  16.509                  _cs.limit=0xFFFF;
  16.510 +                _cs.limit_low = 0;
  16.511 +                _cs.limit_high = 0xffff;
  16.512                  CS=seg;
  16.513                  flags=(flags&0x3000)|(tempflags&0xCFD5)|2;
  16.514                  return;
  16.515 @@ -2011,9 +2046,13 @@
  16.516  //                        pclog("Pop stack %04X:%04X\n",newss,newsp);
  16.517                          eflags=tempflags>>16;
  16.518                          loadseg(segs[0],&_es);
  16.519 +                        do_seg_v86_init(&_es);
  16.520                          loadseg(segs[1],&_ds);
  16.521 +                        do_seg_v86_init(&_ds);
  16.522                          loadseg(segs[2],&_fs);
  16.523 +                        do_seg_v86_init(&_fs);
  16.524                          loadseg(segs[3],&_gs);
  16.525 +                        do_seg_v86_init(&_gs);                        
  16.526                          
  16.527  //                        pclog("V86 IRET %04X:%08X\n",SS,ESP);
  16.528  //                        output=3;
  16.529 @@ -2021,12 +2060,15 @@
  16.530                          pc=newpc;
  16.531                          _cs.base=seg<<4;
  16.532                          _cs.limit=0xFFFF;
  16.533 +                        _cs.limit_low = 0;
  16.534 +                        _cs.limit_high = 0xffff;
  16.535                          CS=seg;
  16.536                          _cs.access=3<<5;
  16.537                          if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
  16.538  
  16.539                          ESP=newsp;
  16.540                          loadseg(newss,&_ss);
  16.541 +                        do_seg_v86_init(&_ss);
  16.542                          use32=0;
  16.543                          flags=(tempflags&0xFFD5)|2;
  16.544  
  16.545 @@ -2137,12 +2179,7 @@
  16.546          {
  16.547  //                pclog("Same level\n");
  16.548                  CS=seg;
  16.549 -                _cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
  16.550 -                if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
  16.551 -                _cs.base=segdat[1];
  16.552 -                _cs.base|=((segdat[2]&0xFF)<<16);
  16.553 -                if (is386) _cs.base|=((segdat[3]>>8)<<24);
  16.554 -                _cs.access=segdat[2]>>8;
  16.555 +                do_seg_load(&_cs, segdat);
  16.556                  if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
  16.557                  use32=(segdat[3]&0x40)?0x300:0;
  16.558  
  16.559 @@ -2240,15 +2277,7 @@
  16.560                  stack32=segdat2[3]&0x40;
  16.561                  if (stack32) ESP=newsp;
  16.562                  else         SP=newsp;
  16.563 -                _ss.limit=segdat2[0]|((segdat2[3]&0xF)<<16);
  16.564 -                if (segdat2[3]&0x80) _ss.limit=(_ss.limit<<12)|0xFFF;
  16.565 -                if ((segdat2[2]>>8) & 4)
  16.566 -                   _ss.limit = 0xffffffff;
  16.567 -                _ss.limitw=(segdat2[2]&0x200)?1:0;
  16.568 -                _ss.base=segdat2[1];
  16.569 -                _ss.base|=((segdat2[2]&0xFF)<<16);
  16.570 -                if (is386) _ss.base|=((segdat2[3]>>8)<<24);
  16.571 -                _ss.access=segdat2[2]>>8;
  16.572 +                do_seg_load(&_ss, segdat2);
  16.573  
  16.574  #ifdef SEL_ACCESSED
  16.575                  cpl_override = 1;
  16.576 @@ -2264,35 +2293,14 @@
  16.577                             segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8));
  16.578  
  16.579                  CS=seg;
  16.580 -                _cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
  16.581 -                if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
  16.582 -                _cs.base=segdat[1];
  16.583 -                _cs.base|=((segdat[2]&0xFF)<<16);
  16.584 -                if (is386) _cs.base|=((segdat[3]>>8)<<24);
  16.585 -                _cs.access=segdat[2]>>8;
  16.586 +                do_seg_load(&_cs, segdat);
  16.587                  if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
  16.588                  use32=(segdat[3]&0x40)?0x300:0;
  16.589                          
  16.590 -                if (CPL>((_ds.access>>5)&3))
  16.591 -                {
  16.592 -                        _ds.seg=0;
  16.593 -                        _ds.base=-1;
  16.594 -                }
  16.595 -                if (CPL>((_es.access>>5)&3))
  16.596 -                {
  16.597 -                        _es.seg=0;
  16.598 -                        _es.base=-1;
  16.599 -                }
  16.600 -                if (CPL>((_fs.access>>5)&3))
  16.601 -                {
  16.602 -                        _fs.seg=0;
  16.603 -                        _fs.base=-1;
  16.604 -                }
  16.605 -                if (CPL>((_gs.access>>5)&3))
  16.606 -                {
  16.607 -                        _gs.seg=0;
  16.608 -                        _gs.base=-1;
  16.609 -                }
  16.610 +                check_seg_valid(&_ds);
  16.611 +                check_seg_valid(&_es);
  16.612 +                check_seg_valid(&_fs);
  16.613 +                check_seg_valid(&_gs);
  16.614          }
  16.615          pc=newpc;
  16.616          flags=(flags&~flagmask)|(tempflags&flagmask&0xFFD5)|2;
  16.617 @@ -2501,12 +2509,7 @@
  16.618  
  16.619  //                if (output) pclog("new_cs %04X\n",new_cs);
  16.620                  CS=new_cs;
  16.621 -                _cs.limit=segdat2[0]|((segdat2[3]&0xF)<<16);
  16.622 -                if (segdat2[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
  16.623 -                _cs.base=segdat2[1];
  16.624 -                _cs.base|=((segdat2[2]&0xFF)<<16);
  16.625 -                if (is386) _cs.base|=((segdat2[3]>>8)<<24);
  16.626 -                _cs.access=segdat2[2]>>8;
  16.627 +                do_seg_load(&_cs, segdat2);
  16.628                  if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
  16.629                  use32=(segdat2[3]&0x40)?0x300:0;
  16.630