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
