Implemented selector limits on some instructions - fixes LBA2.
GPFs in real mode now work. Selectors correctly zeroed on far return to lower privilege.
This commit is contained in:
parent
624ef9ba3c
commit
cd2c3b47ed
16 changed files with 404 additions and 462 deletions
256
src/386.c
256
src/386.c
|
|
@ -10,6 +10,9 @@
|
|||
#include "timer.h"
|
||||
#include "video.h"
|
||||
|
||||
|
||||
x86seg *ea_seg;
|
||||
|
||||
int nmi_enable = 1;
|
||||
|
||||
int inscounts[256];
|
||||
|
|
@ -39,6 +42,27 @@ int trap;
|
|||
} \
|
||||
}
|
||||
|
||||
#define CHECK_READ(seg, low, high) \
|
||||
if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) \
|
||||
{ \
|
||||
x86gpf("Limit check", 0); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define CHECK_WRITE(seg, low, high) \
|
||||
if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) \
|
||||
{ \
|
||||
x86gpf("Limit check", 0); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define CHECK_WRITE_REP(seg, low, high) \
|
||||
if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) \
|
||||
{ \
|
||||
x86gpf("Limit check", 0); \
|
||||
break; \
|
||||
}
|
||||
|
||||
|
||||
int cpl_override=0;
|
||||
|
||||
|
|
@ -206,8 +230,8 @@ uint32_t *mod1seg[8];
|
|||
static inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = ds;
|
||||
ea_rseg = DS;
|
||||
easeg = ea_seg->base;
|
||||
ea_rseg = ea_seg->seg;
|
||||
if (rm == 4)
|
||||
{
|
||||
uint8_t sib = rmdat >> 8;
|
||||
|
|
@ -231,10 +255,11 @@ static inline void fetch_ea_32_long(uint32_t rmdat)
|
|||
/*SIB byte present*/
|
||||
if ((sib & 7) == 5 && !mod)
|
||||
eaaddr = getlong();
|
||||
else if ((sib & 6) == 4)
|
||||
else if ((sib & 6) == 4 && !ssegs)
|
||||
{
|
||||
easeg = ss;
|
||||
ea_rseg = SS;
|
||||
ea_seg = &_ss;
|
||||
}
|
||||
if (((sib >> 3) & 7) != 4)
|
||||
eaaddr += regs[(sib >> 3) & 7].l << (sib >> 6);
|
||||
|
|
@ -244,10 +269,11 @@ static inline void fetch_ea_32_long(uint32_t rmdat)
|
|||
eaaddr = regs[rm].l;
|
||||
if (mod)
|
||||
{
|
||||
if (rm == 5)
|
||||
if (rm == 5 && !ssegs)
|
||||
{
|
||||
easeg = ss;
|
||||
ea_rseg = SS;
|
||||
ea_seg = &_ss;
|
||||
}
|
||||
if (mod == 1)
|
||||
{
|
||||
|
|
@ -276,11 +302,11 @@ static inline void fetch_ea_32_long(uint32_t rmdat)
|
|||
static inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = ea_seg->base;
|
||||
ea_rseg = ea_seg->seg;
|
||||
if (!mod && rm == 6)
|
||||
{
|
||||
eaaddr = getword();
|
||||
easeg = ds;
|
||||
ea_rseg = DS;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -297,9 +323,12 @@ static inline void fetch_ea_16_long(uint32_t rmdat)
|
|||
break;
|
||||
}
|
||||
eaaddr += (*mod1add[0][rm]) + (*mod1add[1][rm]);
|
||||
easeg = *mod1seg[rm];
|
||||
if (mod1seg[rm] == &ss) ea_rseg = SS;
|
||||
else ea_rseg = DS;
|
||||
if (mod1seg[rm] == &ss && !ssegs)
|
||||
{
|
||||
easeg = ss;
|
||||
ea_rseg = SS;
|
||||
ea_seg = &_ss;
|
||||
}
|
||||
eaaddr &= 0xFFFF;
|
||||
}
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC)
|
||||
|
|
@ -328,7 +357,6 @@ void x86_int(int num)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (ssegs) ss=oldss;
|
||||
if (stack32)
|
||||
{
|
||||
writememw(ss,ESP-2,flags);
|
||||
|
|
@ -365,7 +393,6 @@ void x86_int_sw(int num)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (ssegs) ss=oldss;
|
||||
if (stack32)
|
||||
{
|
||||
writememw(ss,ESP-2,flags);
|
||||
|
|
@ -418,7 +445,6 @@ void rep386(int fv)
|
|||
uint8_t temp2;
|
||||
uint16_t tempw,tempw2,of;
|
||||
uint32_t ipc=oldpc;//pc-1;
|
||||
int changeds=0;
|
||||
uint32_t oldds;
|
||||
uint32_t rep32=op32;
|
||||
uint32_t templ,templ2;
|
||||
|
|
@ -446,43 +472,23 @@ void rep386(int fv)
|
|||
pc=ipc+1;
|
||||
break;
|
||||
case 0x26: case 0x126: case 0x226: case 0x326: /*ES:*/
|
||||
oldds=ds;
|
||||
ds=es;
|
||||
rds=ES;
|
||||
changeds=1;
|
||||
ea_seg = &_es;
|
||||
goto startrep;
|
||||
break;
|
||||
case 0x2E: case 0x12E: case 0x22E: case 0x32E: /*CS:*/
|
||||
oldds=ds;
|
||||
ds=cs;
|
||||
rds=CS;
|
||||
changeds=1;
|
||||
ea_seg = &_cs;
|
||||
goto startrep;
|
||||
break;
|
||||
case 0x36: case 0x136: case 0x236: case 0x336: /*SS:*/
|
||||
oldds=ds;
|
||||
ds=ss;
|
||||
rds=SS;
|
||||
changeds=1;
|
||||
ea_seg = &_ss;
|
||||
goto startrep;
|
||||
break;
|
||||
case 0x3E: case 0x13E: case 0x23E: case 0x33E: /*DS:*/
|
||||
oldds=ds;
|
||||
ds=ds;
|
||||
changeds=1;
|
||||
ea_seg = &_ds;
|
||||
goto startrep;
|
||||
break;
|
||||
case 0x64: case 0x164: case 0x264: case 0x364: /*FS:*/
|
||||
oldds=ds;
|
||||
ds=fs;
|
||||
rds=FS;
|
||||
changeds=1;
|
||||
ea_seg = &_fs;
|
||||
goto startrep;
|
||||
case 0x65: case 0x165: case 0x265: case 0x365: /*GS:*/
|
||||
oldds=ds;
|
||||
ds=gs;
|
||||
rds=GS;
|
||||
changeds=1;
|
||||
ea_seg = &_gs;
|
||||
goto startrep;
|
||||
case 0x66: case 0x166: case 0x266: case 0x366: /*Data size prefix*/
|
||||
rep32^=0x100;
|
||||
|
|
@ -502,7 +508,7 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x26C: case 0x36C: /*REP INSB*/
|
||||
|
|
@ -517,7 +523,7 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x6D: /*REP INSW*/
|
||||
|
|
@ -531,7 +537,7 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x16D: /*REP INSL*/
|
||||
|
|
@ -545,7 +551,7 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x26D: /*REP INSW*/
|
||||
|
|
@ -559,7 +565,7 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x36D: /*REP INSL*/
|
||||
|
|
@ -573,13 +579,13 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x6E: case 0x16E: /*REP OUTSB*/
|
||||
if (c>0)
|
||||
{
|
||||
temp2=readmemb(ds,SI);
|
||||
temp2 = readmemb(ea_seg->base, SI);
|
||||
if (abrt) break;
|
||||
checkio_perm(DX);
|
||||
outb(DX,temp2);
|
||||
|
|
@ -588,13 +594,13 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=14;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x26E: case 0x36E: /*REP OUTSB*/
|
||||
if (c>0)
|
||||
{
|
||||
temp2=readmemb(ds,ESI);
|
||||
temp2 = readmemb(ea_seg->base, ESI);
|
||||
if (abrt) break;
|
||||
checkio_perm(DX);
|
||||
outb(DX,temp2);
|
||||
|
|
@ -603,13 +609,13 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=14;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x6F: /*REP OUTSW*/
|
||||
if (c>0)
|
||||
{
|
||||
tempw=readmemw(ds,SI);
|
||||
tempw = readmemw(ea_seg->base, SI);
|
||||
if (abrt) break;
|
||||
// pclog("OUTSW %04X -> %04X\n",SI,tempw);
|
||||
outw(DX,tempw);
|
||||
|
|
@ -618,13 +624,13 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=14;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x16F: /*REP OUTSL*/
|
||||
if (c > 0)
|
||||
{
|
||||
templ = readmeml(ds, SI);
|
||||
templ = readmeml(ea_seg->base, SI);
|
||||
if (abrt) break;
|
||||
outl(DX, templ);
|
||||
if (flags & D_FLAG) SI -= 4;
|
||||
|
|
@ -632,13 +638,13 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles -= 14;
|
||||
}
|
||||
if (c > 0) { firstrepcycle = 0; pc = ipc; if (ssegs) ssegs++; }
|
||||
if (c > 0) { firstrepcycle = 0; pc = ipc; }
|
||||
else firstrepcycle = 1;
|
||||
break;
|
||||
case 0x26F: /*REP OUTSW*/
|
||||
if (c>0)
|
||||
{
|
||||
tempw=readmemw(ds,ESI);
|
||||
tempw = readmemw(ea_seg->base, ESI);
|
||||
if (abrt) break;
|
||||
outw(DX,tempw);
|
||||
if (flags&D_FLAG) ESI-=2;
|
||||
|
|
@ -646,13 +652,13 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=14;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x36F: /*REP OUTSL*/
|
||||
if (c > 0)
|
||||
{
|
||||
templ = readmeml(ds, ESI);
|
||||
templ = readmeml(ea_seg->base, ESI);
|
||||
if (abrt) break;
|
||||
outl(DX, templ);
|
||||
if (flags & D_FLAG) ESI -= 4;
|
||||
|
|
@ -660,7 +666,7 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles -= 14;
|
||||
}
|
||||
if (c > 0) { firstrepcycle = 0; pc = ipc; if (ssegs) ssegs++; }
|
||||
if (c > 0) { firstrepcycle = 0; pc = ipc; }
|
||||
else firstrepcycle = 1;
|
||||
break;
|
||||
case 0x90: case 0x190: /*REP NOP*/
|
||||
|
|
@ -669,7 +675,8 @@ void rep386(int fv)
|
|||
case 0xA4: case 0x1A4: /*REP MOVSB*/
|
||||
if (c>0)
|
||||
{
|
||||
temp2=readmemb(ds,SI); if (abrt) break;
|
||||
CHECK_WRITE_REP(&_es, DI, DI);
|
||||
temp2 = readmemb(ea_seg->base, SI); if (abrt) break;
|
||||
writememb(es,DI,temp2); if (abrt) break;
|
||||
// if (output==3) pclog("MOVSB %08X:%04X -> %08X:%04X %02X\n",ds,SI,es,DI,temp2);
|
||||
if (flags&D_FLAG) { DI--; SI--; }
|
||||
|
|
@ -677,39 +684,42 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2A4: case 0x3A4: /*REP MOVSB*/
|
||||
if (c>0)
|
||||
{
|
||||
temp2=readmemb(ds,ESI); if (abrt) break;
|
||||
CHECK_WRITE_REP(&_es, EDI, EDI);
|
||||
temp2 = readmemb(ea_seg->base, ESI); if (abrt) break;
|
||||
writememb(es,EDI,temp2); if (abrt) break;
|
||||
if (flags&D_FLAG) { EDI--; ESI--; }
|
||||
else { EDI++; ESI++; }
|
||||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xA5: /*REP MOVSW*/
|
||||
if (c>0)
|
||||
{
|
||||
tempw=readmemw(ds,SI); if (abrt) break;
|
||||
CHECK_WRITE_REP(&_es, DI, DI+1);
|
||||
tempw = readmemw(ea_seg->base, SI); if (abrt) break;
|
||||
writememw(es,DI,tempw); if (abrt) break;
|
||||
if (flags&D_FLAG) { DI-=2; SI-=2; }
|
||||
else { DI+=2; SI+=2; }
|
||||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x1A5: /*REP MOVSL*/
|
||||
if (c>0)
|
||||
{
|
||||
templ=readmeml(ds,SI); if (abrt) break;
|
||||
CHECK_WRITE_REP(&_es, DI, DI+3);
|
||||
templ = readmeml(ea_seg->base, SI); if (abrt) break;
|
||||
// pclog("MOVSD %08X from %08X to %08X (%04X:%08X)\n", templ, ds+SI, es+DI, CS, pc);
|
||||
writememl(es,DI,templ); if (abrt) break;
|
||||
if (flags&D_FLAG) { DI-=4; SI-=4; }
|
||||
|
|
@ -717,13 +727,14 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2A5: /*REP MOVSW*/
|
||||
if (c>0)
|
||||
{
|
||||
tempw=readmemw(ds,ESI); if (abrt) break;
|
||||
CHECK_WRITE_REP(&_es, EDI, EDI+1);
|
||||
tempw = readmemw(ea_seg->base, ESI); if (abrt) break;
|
||||
writememw(es,EDI,tempw); if (abrt) break;
|
||||
// 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);
|
||||
if (flags&D_FLAG) { EDI-=2; ESI-=2; }
|
||||
|
|
@ -731,13 +742,14 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x3A5: /*REP MOVSL*/
|
||||
if (c>0)
|
||||
{
|
||||
templ=readmeml(ds,ESI); if (abrt) break;
|
||||
CHECK_WRITE_REP(&_es, EDI, EDI+3);
|
||||
templ = readmeml(ea_seg->base, ESI); if (abrt) break;
|
||||
// if ((EDI&0xFFFF0000)==0xA0000) cycles-=12;
|
||||
writememl(es,EDI,templ); if (abrt) break;
|
||||
// if (output) pclog("Load %08X from %08X to %08X %04X %08X %04X %08X\n",templ,ESI,EDI,DS,ds,ES,es);
|
||||
|
|
@ -746,14 +758,14 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xA6: case 0x1A6: /*REP CMPSB*/
|
||||
tempz = (fv) ? 1 : 0;
|
||||
if ((c>0) && (fv==tempz))
|
||||
{
|
||||
temp=readmemb(ds,SI);
|
||||
temp = readmemb(ea_seg->base, SI);
|
||||
temp2=readmemb(es,DI);
|
||||
if (abrt) { flags=of; break; }
|
||||
if (flags&D_FLAG) { DI--; SI--; }
|
||||
|
|
@ -763,14 +775,14 @@ void rep386(int fv)
|
|||
setsub8(temp,temp2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2A6: case 0x3A6: /*REP CMPSB*/
|
||||
tempz = (fv) ? 1 : 0;
|
||||
if ((c>0) && (fv==tempz))
|
||||
{
|
||||
temp=readmemb(ds,ESI);
|
||||
temp = readmemb(ea_seg->base, ESI);
|
||||
temp2=readmemb(es,EDI);
|
||||
if (abrt) { flags=of; break; }
|
||||
if (flags&D_FLAG) { EDI--; ESI--; }
|
||||
|
|
@ -780,7 +792,7 @@ void rep386(int fv)
|
|||
setsub8(temp,temp2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xA7: /*REP CMPSW*/
|
||||
|
|
@ -788,7 +800,7 @@ void rep386(int fv)
|
|||
if ((c>0) && (fv==tempz))
|
||||
{
|
||||
// pclog("CMPSW %05X %05X %08X %08X ", ds+SI, es+DI, readlookup2[(ds+SI)>>12], readlookup2[(es+DI)>>12]);
|
||||
tempw=readmemw(ds,SI);
|
||||
tempw = readmemw(ea_seg->base, SI);
|
||||
tempw2=readmemw(es,DI);
|
||||
// pclog("%04X %04X %02X\n", tempw, tempw2, ram[8]);
|
||||
|
||||
|
|
@ -800,14 +812,14 @@ void rep386(int fv)
|
|||
setsub16(tempw,tempw2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x1A7: /*REP CMPSL*/
|
||||
tempz = (fv) ? 1 : 0;
|
||||
if ((c>0) && (fv==tempz))
|
||||
{
|
||||
templ=readmeml(ds,SI);
|
||||
templ = readmeml(ea_seg->base, SI);
|
||||
templ2=readmeml(es,DI);
|
||||
if (abrt) { flags=of; break; }
|
||||
if (flags&D_FLAG) { DI-=4; SI-=4; }
|
||||
|
|
@ -817,14 +829,14 @@ void rep386(int fv)
|
|||
setsub32(templ,templ2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2A7: /*REP CMPSW*/
|
||||
tempz = (fv) ? 1 : 0;
|
||||
if ((c>0) && (fv==tempz))
|
||||
{
|
||||
tempw=readmemw(ds,ESI);
|
||||
tempw = readmemw(ea_seg->base, ESI);
|
||||
tempw2=readmemw(es,EDI);
|
||||
if (abrt) { flags=of; break; }
|
||||
if (flags&D_FLAG) { EDI-=2; ESI-=2; }
|
||||
|
|
@ -834,14 +846,14 @@ void rep386(int fv)
|
|||
setsub16(tempw,tempw2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x3A7: /*REP CMPSL*/
|
||||
tempz = (fv) ? 1 : 0;
|
||||
if ((c>0) && (fv==tempz))
|
||||
{
|
||||
templ=readmeml(ds,ESI);
|
||||
templ = readmeml(ea_seg->base, ESI);
|
||||
templ2=readmeml(es,EDI);
|
||||
if (abrt) { flags=of; break; }
|
||||
if (flags&D_FLAG) { EDI-=4; ESI-=4; }
|
||||
|
|
@ -851,13 +863,14 @@ void rep386(int fv)
|
|||
setsub32(templ,templ2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
|
||||
case 0xAA: case 0x1AA: /*REP STOSB*/
|
||||
if (c>0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, DI, DI);
|
||||
writememb(es,DI,AL);
|
||||
if (abrt) break;
|
||||
if (flags&D_FLAG) DI--;
|
||||
|
|
@ -865,12 +878,13 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2AA: case 0x3AA: /*REP STOSB*/
|
||||
if (c>0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, EDI, EDI);
|
||||
writememb(es,EDI,AL);
|
||||
if (abrt) break;
|
||||
if (flags&D_FLAG) EDI--;
|
||||
|
|
@ -878,12 +892,13 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xAB: /*REP STOSW*/
|
||||
if (c>0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, DI, DI+1);
|
||||
writememw(es,DI,AX);
|
||||
if (abrt) break;
|
||||
if (flags&D_FLAG) DI-=2;
|
||||
|
|
@ -891,12 +906,13 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2AB: /*REP STOSW*/
|
||||
if (c>0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, EDI, EDI+1);
|
||||
writememw(es,EDI,AX);
|
||||
if (abrt) break;
|
||||
if (flags&D_FLAG) EDI-=2;
|
||||
|
|
@ -904,12 +920,13 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x1AB: /*REP STOSL*/
|
||||
if (c>0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, DI, DI+3);
|
||||
writememl(es,DI,EAX);
|
||||
if (abrt) break;
|
||||
if (flags&D_FLAG) DI-=4;
|
||||
|
|
@ -917,12 +934,13 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x3AB: /*REP STOSL*/
|
||||
if (c>0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, EDI, EDI+3);
|
||||
writememl(es,EDI,EAX);
|
||||
if (abrt) break;
|
||||
if (flags&D_FLAG) EDI-=4;
|
||||
|
|
@ -930,91 +948,91 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xAC: case 0x1AC: /*REP LODSB*/
|
||||
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc);
|
||||
if (c>0)
|
||||
{
|
||||
AL=readmemb(ds,SI);
|
||||
AL = readmemb(ea_seg->base, SI);
|
||||
if (abrt) break;
|
||||
if (flags&D_FLAG) SI--;
|
||||
else SI++;
|
||||
c--;
|
||||
cycles-=5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2AC: case 0x3AC: /*REP LODSB*/
|
||||
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc);
|
||||
if (c>0)
|
||||
{
|
||||
AL=readmemb(ds,ESI);
|
||||
AL = readmemb(ea_seg->base, ESI);
|
||||
if (abrt) break;
|
||||
if (flags&D_FLAG) ESI--;
|
||||
else ESI++;
|
||||
c--;
|
||||
cycles-=5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xAD: /*REP LODSW*/
|
||||
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc);
|
||||
if (c>0)
|
||||
{
|
||||
AX=readmemw(ds,SI);
|
||||
AX = readmemw(ea_seg->base, SI);
|
||||
if (abrt) break;
|
||||
if (flags&D_FLAG) SI-=2;
|
||||
else SI+=2;
|
||||
c--;
|
||||
cycles-=5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x1AD: /*REP LODSL*/
|
||||
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc);
|
||||
if (c>0)
|
||||
{
|
||||
EAX=readmeml(ds,SI);
|
||||
EAX = readmeml(ea_seg->base, SI);
|
||||
if (abrt) break;
|
||||
if (flags&D_FLAG) SI-=4;
|
||||
else SI+=4;
|
||||
c--;
|
||||
cycles-=5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2AD: /*REP LODSW*/
|
||||
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc);
|
||||
if (c>0)
|
||||
{
|
||||
AX=readmemw(ds,ESI);
|
||||
AX = readmemw(ea_seg->base, ESI);
|
||||
if (abrt) break;
|
||||
if (flags&D_FLAG) ESI-=2;
|
||||
else ESI+=2;
|
||||
c--;
|
||||
cycles-=5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x3AD: /*REP LODSL*/
|
||||
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc);
|
||||
if (c>0)
|
||||
{
|
||||
EAX=readmeml(ds,ESI);
|
||||
EAX = readmeml(ea_seg->base, ESI);
|
||||
if (abrt) break;
|
||||
if (flags&D_FLAG) ESI-=4;
|
||||
else ESI+=4;
|
||||
c--;
|
||||
cycles-=5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; }
|
||||
if (c>0) { firstrepcycle=0; pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xAE: case 0x1AE: /*REP SCASB*/
|
||||
|
|
@ -1032,7 +1050,7 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2AE: case 0x3AE: /*REP SCASB*/
|
||||
|
|
@ -1051,7 +1069,7 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xAF: /*REP SCASW*/
|
||||
|
|
@ -1068,7 +1086,7 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x1AF: /*REP SCASL*/
|
||||
|
|
@ -1085,7 +1103,7 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2AF: /*REP SCASW*/
|
||||
|
|
@ -1102,7 +1120,7 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x3AF: /*REP SCASL*/
|
||||
|
|
@ -1119,7 +1137,7 @@ void rep386(int fv)
|
|||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; }
|
||||
if ((c>0) && (fv==tempz)) { pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
|
||||
|
|
@ -1132,7 +1150,6 @@ void rep386(int fv)
|
|||
}
|
||||
if (rep32&0x200) ECX=c;
|
||||
else CX=c;
|
||||
if (changeds) ds=oldds;
|
||||
// if (output) pclog("%03X %03X\n",rep32,use32);
|
||||
}
|
||||
|
||||
|
|
@ -1268,8 +1285,12 @@ opcode_realstart:
|
|||
|
||||
dontprint=0;
|
||||
|
||||
ea_seg = &_ds;
|
||||
ssegs = 0;
|
||||
|
||||
opcodestart:
|
||||
fetchdat = fastreadl(cs + pc);
|
||||
|
||||
if (!abrt)
|
||||
{
|
||||
tempc = CF_SET();
|
||||
|
|
@ -1287,20 +1308,7 @@ opcodestart:
|
|||
}
|
||||
|
||||
if (!use32) pc &= 0xffff;
|
||||
/* if (ins == 74400000)
|
||||
{
|
||||
pclog("Output on\n");
|
||||
output = 3;
|
||||
}*/
|
||||
if ((cs + pc) == 0xc)
|
||||
fatal("Dead\n");
|
||||
if (ssegs)
|
||||
{
|
||||
ds=oldds;
|
||||
ss=oldss;
|
||||
rds=DS;
|
||||
ssegs=0;
|
||||
}
|
||||
|
||||
if (abrt)
|
||||
{
|
||||
flags_rebuild();
|
||||
|
|
@ -1397,23 +1405,15 @@ opcodestart:
|
|||
}
|
||||
}
|
||||
|
||||
// tempi = ZF_SET() ? Z_FLAG : 0;
|
||||
// if (tempi != (flags & Z_FLAG))
|
||||
// fatal("Z flag mismatch %02X %08X\n", opcode, fetchdat);
|
||||
ins++;
|
||||
insc++;
|
||||
/*output = 3;
|
||||
if (ins == 1372108)
|
||||
fatal("here2\n");
|
||||
if (ins == 50966339)
|
||||
fatal("here\n");*/
|
||||
|
||||
if (timetolive)
|
||||
{
|
||||
timetolive--;
|
||||
if (!timetolive)
|
||||
fatal("Life expired\n");
|
||||
}
|
||||
// if (ins == 97300000) output = 3;
|
||||
}
|
||||
|
||||
tsc += cycdiff;
|
||||
|
|
|
|||
14
src/808x.c
14
src/808x.c
|
|
@ -588,15 +588,15 @@ chdir(pcempath);
|
|||
printf("In %s mode\n",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real");
|
||||
else
|
||||
printf("In %s mode\n",(msw&1)?"protected":"real");
|
||||
printf("CS : base=%06X limit=%04X access=%02X\n",cs,_cs.limit,_cs.access);
|
||||
printf("DS : base=%06X limit=%04X access=%02X\n",ds,_ds.limit,_ds.access);
|
||||
printf("ES : base=%06X limit=%04X access=%02X\n",es,_es.limit,_es.access);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
if (is386)
|
||||
{
|
||||
printf("FS : base=%06X limit=%04X access=%02X\n",fs,_fs.limit,_fs.access);
|
||||
printf("GS : base=%06X limit=%04X access=%02X\n",gs,_gs.limit,_gs.access);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
printf("SS : base=%06X limit=%04X access=%02X\n",ss,_ss.limit,_ss.access);
|
||||
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);
|
||||
printf("GDT : base=%06X limit=%04X\n",gdt.base,gdt.limit);
|
||||
printf("LDT : base=%06X limit=%04X\n",ldt.base,ldt.limit);
|
||||
printf("IDT : base=%06X limit=%04X\n",idt.base,idt.limit);
|
||||
|
|
@ -646,6 +646,7 @@ void resetx86()
|
|||
ESP=0;
|
||||
mmu_perm=4;
|
||||
memset(inscounts, 0, sizeof(inscounts));
|
||||
x86seg_reset();
|
||||
}
|
||||
|
||||
void softresetx86()
|
||||
|
|
@ -665,6 +666,7 @@ void softresetx86()
|
|||
//rammask=0xFFFFFFFF;
|
||||
flags=2;
|
||||
idt.base = 0;
|
||||
x86seg_reset();
|
||||
}
|
||||
|
||||
static void setznp8(uint8_t val)
|
||||
|
|
|
|||
|
|
@ -108,15 +108,18 @@ extern int cycdiff;
|
|||
typedef struct
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t limit,limitw;
|
||||
uint32_t limit;
|
||||
uint8_t access;
|
||||
uint16_t seg;
|
||||
uint32_t limit_low, limit_high;
|
||||
} x86seg;
|
||||
|
||||
x86seg gdt,ldt,idt,tr;
|
||||
x86seg _cs,_ds,_es,_ss,_fs,_gs;
|
||||
x86seg _oldds;
|
||||
|
||||
extern x86seg *ea_seg;
|
||||
|
||||
uint32_t pccache;
|
||||
uint8_t *pccache2;
|
||||
/*Segments -
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ extern uint16_t *mod1add[2][8];
|
|||
extern uint32_t *mod1seg[8];
|
||||
|
||||
|
||||
#define IRQTEST ((flags&I_FLAG) && (pic.pend&~pic.mask) && !ssegs && !noint)
|
||||
#define IRQTEST ((flags&I_FLAG) && (pic.pend&~pic.mask) && !noint)
|
||||
|
||||
extern int cgate32;
|
||||
|
||||
|
|
@ -99,3 +99,5 @@ extern uint32_t rmdat32;
|
|||
extern int inscounts[256];
|
||||
|
||||
void x86illegal();
|
||||
|
||||
void x86seg_reset();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#define CALL_FAR_w(new_seg, new_pc) \
|
||||
old_cs = CS; \
|
||||
old_pc = pc; \
|
||||
if (ssegs) ss = oldss; \
|
||||
oxpc = pc; \
|
||||
pc = new_pc; \
|
||||
optype = CALL; \
|
||||
|
|
@ -27,7 +26,6 @@
|
|||
#define CALL_FAR_l(new_seg, new_pc) \
|
||||
old_cs = CS; \
|
||||
old_pc = pc; \
|
||||
if (ssegs) ss = oldss; \
|
||||
oxpc = pc; \
|
||||
pc = new_pc; \
|
||||
optype = CALL; \
|
||||
|
|
@ -54,7 +52,6 @@
|
|||
#define CALL_FAR_nr(new_seg, new_pc) \
|
||||
old_cs = CS; \
|
||||
old_pc = pc; \
|
||||
if (ssegs) ss = oldss; \
|
||||
oxpc = pc; \
|
||||
pc = new_pc; \
|
||||
optype = CALL; \
|
||||
|
|
@ -130,7 +127,6 @@ static int opFF_w_a16(uint32_t fetchdat)
|
|||
break;
|
||||
case 0x10: /*CALL*/
|
||||
new_pc = geteaw(); if (abrt) return 0;
|
||||
if (ssegs) ss = oldss;
|
||||
PUSH_W(pc);
|
||||
pc = new_pc;
|
||||
if (is486) cycles -= 5;
|
||||
|
|
@ -160,7 +156,6 @@ static int opFF_w_a16(uint32_t fetchdat)
|
|||
break;
|
||||
case 0x30: /*PUSH w*/
|
||||
temp = geteaw(); if (abrt) return 0;
|
||||
if (ssegs) ss = oldss;
|
||||
PUSH_W(temp);
|
||||
cycles -= ((mod == 3) ? 2 : 5);
|
||||
break;
|
||||
|
|
@ -196,7 +191,6 @@ static int opFF_w_a32(uint32_t fetchdat)
|
|||
break;
|
||||
case 0x10: /*CALL*/
|
||||
new_pc = geteaw(); if (abrt) return 0;
|
||||
if (ssegs) ss = oldss;
|
||||
PUSH_W(pc);
|
||||
pc = new_pc;
|
||||
if (is486) cycles -= 5;
|
||||
|
|
@ -226,7 +220,6 @@ static int opFF_w_a32(uint32_t fetchdat)
|
|||
break;
|
||||
case 0x30: /*PUSH w*/
|
||||
temp = geteaw(); if (abrt) return 0;
|
||||
if (ssegs) ss = oldss;
|
||||
PUSH_W(temp);
|
||||
cycles -= ((mod == 3) ? 2 : 5);
|
||||
break;
|
||||
|
|
@ -263,7 +256,6 @@ static int opFF_l_a16(uint32_t fetchdat)
|
|||
break;
|
||||
case 0x10: /*CALL*/
|
||||
new_pc = geteal(); if (abrt) return 0;
|
||||
if (ssegs) ss = oldss;
|
||||
PUSH_L(pc);
|
||||
pc = new_pc;
|
||||
if (is486) cycles -= 5;
|
||||
|
|
@ -293,7 +285,6 @@ static int opFF_l_a16(uint32_t fetchdat)
|
|||
break;
|
||||
case 0x30: /*PUSH l*/
|
||||
temp = geteal(); if (abrt) return 0;
|
||||
if (ssegs) ss = oldss;
|
||||
PUSH_L(temp);
|
||||
cycles -= ((mod == 3) ? 2 : 5);
|
||||
break;
|
||||
|
|
@ -329,7 +320,6 @@ static int opFF_l_a32(uint32_t fetchdat)
|
|||
break;
|
||||
case 0x10: /*CALL*/
|
||||
new_pc = geteal(); if (abrt) return 0;
|
||||
if (ssegs) ss = oldss;
|
||||
PUSH_L(pc); if (abrt) return 0;
|
||||
pc = new_pc;
|
||||
if (is486) cycles -= 5;
|
||||
|
|
@ -359,7 +349,6 @@ static int opFF_l_a32(uint32_t fetchdat)
|
|||
break;
|
||||
case 0x30: /*PUSH l*/
|
||||
temp = geteal(); if (abrt) return 0;
|
||||
if (ssegs) ss = oldss;
|
||||
PUSH_L(temp);
|
||||
cycles -= ((mod == 3) ? 2 : 5);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@ static int opLAHF(uint32_t fetchdat)
|
|||
|
||||
static int opPUSHF(uint32_t fetchdat)
|
||||
{
|
||||
if (ssegs) ss = oldss;
|
||||
if ((eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
|
|
@ -90,7 +89,6 @@ static int opPUSHF(uint32_t fetchdat)
|
|||
static int opPUSHFD(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
if (ssegs) ss=oldss;
|
||||
if ((eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
|
|
@ -107,7 +105,6 @@ static int opPUSHFD(uint32_t fetchdat)
|
|||
static int opPOPF_286(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
if (ssegs) ss = oldss;
|
||||
|
||||
if ((eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
|
|
@ -129,7 +126,6 @@ static int opPOPF_286(uint32_t fetchdat)
|
|||
static int opPOPF(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
if (ssegs) ss = oldss;
|
||||
|
||||
if ((eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
|
|
@ -150,7 +146,6 @@ static int opPOPF(uint32_t fetchdat)
|
|||
static int opPOPFD(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t templ;
|
||||
if (ssegs) ss = oldss;
|
||||
|
||||
if ((eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -198,7 +198,6 @@ static int opJMP_far_a32(uint32_t fetchdat)
|
|||
int opCALL_r16(uint32_t fetchdat)
|
||||
{
|
||||
int16_t addr = (int16_t)getwordf();
|
||||
if (ssegs) ss=oldss;
|
||||
PUSH_W(pc);
|
||||
pc += addr;
|
||||
cycles -= (is486) ? 3 : 7;
|
||||
|
|
@ -207,7 +206,6 @@ int opCALL_r16(uint32_t fetchdat)
|
|||
int opCALL_r32(uint32_t fetchdat)
|
||||
{
|
||||
int32_t addr = getlong(); if (abrt) return 0;
|
||||
if (ssegs) ss=oldss;
|
||||
PUSH_L(pc);
|
||||
pc += addr;
|
||||
cycles -= (is486) ? 3 : 7;
|
||||
|
|
@ -218,7 +216,6 @@ int opRET_w(uint32_t fetchdat)
|
|||
{
|
||||
uint16_t ret;
|
||||
|
||||
if (ssegs) ss=oldss;
|
||||
ret = POP_W(); if (abrt) return 0;
|
||||
pc = ret;
|
||||
|
||||
|
|
@ -229,7 +226,6 @@ int opRET_l(uint32_t fetchdat)
|
|||
{
|
||||
uint32_t ret;
|
||||
|
||||
if (ssegs) ss=oldss;
|
||||
ret = POP_L(); if (abrt) return 0;
|
||||
pc = ret;
|
||||
|
||||
|
|
@ -242,7 +238,6 @@ int opRET_w_imm(uint32_t fetchdat)
|
|||
uint16_t offset = getwordf();
|
||||
uint16_t ret;
|
||||
|
||||
if (ssegs) ss=oldss;
|
||||
ret = POP_W(); if (abrt) return 0;
|
||||
if (stack32) ESP += offset;
|
||||
else SP += offset;
|
||||
|
|
@ -256,7 +251,6 @@ int opRET_l_imm(uint32_t fetchdat)
|
|||
uint16_t offset = getwordf();
|
||||
uint32_t ret;
|
||||
|
||||
if (ssegs) ss=oldss;
|
||||
ret = POP_L(); if (abrt) return 0;
|
||||
if (stack32) ESP += offset;
|
||||
else SP += offset;
|
||||
|
|
|
|||
|
|
@ -515,7 +515,7 @@ static int opHLT(uint32_t fetchdat)
|
|||
x86gpf(NULL,0);
|
||||
return 0;
|
||||
}
|
||||
if (!((flags&I_FLAG) && pic_intpending && !ssegs))
|
||||
if (!((flags&I_FLAG) && pic_intpending))
|
||||
{
|
||||
cycles -= 100;
|
||||
pc--;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ int opMOVD_mm_l_a16(uint32_t fetchdat)
|
|||
}
|
||||
else
|
||||
{
|
||||
CHECK_WRITE(ea_seg, eaaddr, eaaddr + 3);
|
||||
writememl(easeg, eaaddr, MM[reg].l[0]); if (abrt) return 0;
|
||||
cycles -= 2;
|
||||
}
|
||||
|
|
@ -74,6 +75,7 @@ int opMOVD_mm_l_a32(uint32_t fetchdat)
|
|||
}
|
||||
else
|
||||
{
|
||||
CHECK_WRITE(ea_seg, eaaddr, eaaddr + 3);
|
||||
writememl(easeg, eaaddr, MM[reg].l[0]); if (abrt) return 0;
|
||||
cycles -= 2;
|
||||
}
|
||||
|
|
@ -137,6 +139,7 @@ int opMOVQ_mm_q_a16(uint32_t fetchdat)
|
|||
}
|
||||
else
|
||||
{
|
||||
CHECK_WRITE(ea_seg, eaaddr, eaaddr + 7);
|
||||
writememl(easeg, eaaddr, MM[reg].l[0]);
|
||||
writememl(easeg, eaaddr + 4, MM[reg].l[1]); if (abrt) return 0;
|
||||
cycles -= 2;
|
||||
|
|
@ -155,6 +158,7 @@ int opMOVQ_mm_q_a32(uint32_t fetchdat)
|
|||
}
|
||||
else
|
||||
{
|
||||
CHECK_WRITE(ea_seg, eaaddr, eaaddr + 7);
|
||||
writememl(easeg, eaaddr, MM[reg].l[0]);
|
||||
writememl(easeg, eaaddr + 4, MM[reg].l[1]); if (abrt) return 0;
|
||||
cycles -= 2;
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ static int opMOV_l_imm_a32(uint32_t fetchdat)
|
|||
static int opMOV_AL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr = getwordf();
|
||||
uint8_t temp = readmemb(ds, addr); if (abrt) return 0;
|
||||
uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 0;
|
||||
AL = temp;
|
||||
cycles -= (is486) ? 1 : 4;
|
||||
return 0;
|
||||
|
|
@ -221,7 +221,7 @@ static int opMOV_AL_a16(uint32_t fetchdat)
|
|||
static int opMOV_AL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr = getlong();
|
||||
uint8_t temp = readmemb(ds, addr); if (abrt) return 0;
|
||||
uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 0;
|
||||
AL = temp;
|
||||
cycles -= (is486) ? 1 : 4;
|
||||
return 0;
|
||||
|
|
@ -229,7 +229,7 @@ static int opMOV_AL_a32(uint32_t fetchdat)
|
|||
static int opMOV_AX_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr = getwordf();
|
||||
uint16_t temp = readmemw(ds, addr); if (abrt) return 0;
|
||||
uint16_t temp = readmemw(ea_seg->base, addr); if (abrt) return 0;
|
||||
AX = temp;
|
||||
cycles -= (is486) ? 1 : 4;
|
||||
return 0;
|
||||
|
|
@ -237,7 +237,7 @@ static int opMOV_AX_a16(uint32_t fetchdat)
|
|||
static int opMOV_AX_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr = getlong();
|
||||
uint16_t temp = readmemw(ds, addr); if (abrt) return 0;
|
||||
uint16_t temp = readmemw(ea_seg->base, addr); if (abrt) return 0;
|
||||
AX = temp;
|
||||
cycles -= (is486) ? 1 : 4;
|
||||
return 0;
|
||||
|
|
@ -245,7 +245,7 @@ static int opMOV_AX_a32(uint32_t fetchdat)
|
|||
static int opMOV_EAX_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr = getwordf(); if (abrt) return 0;
|
||||
uint32_t temp = readmeml(ds, addr); if (abrt) return 0;
|
||||
uint32_t temp = readmeml(ea_seg->base, addr); if (abrt) return 0;
|
||||
EAX = temp;
|
||||
cycles -= (is486) ? 1 : 4;
|
||||
return 0;
|
||||
|
|
@ -253,7 +253,7 @@ static int opMOV_EAX_a16(uint32_t fetchdat)
|
|||
static int opMOV_EAX_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr = getlong(); if (abrt) return 0;
|
||||
uint32_t temp = readmeml(ds, addr); if (abrt) return 0;
|
||||
uint32_t temp = readmeml(ea_seg->base, addr); if (abrt) return 0;
|
||||
EAX = temp;
|
||||
cycles -= (is486) ? 1 : 4;
|
||||
return 0;
|
||||
|
|
@ -262,42 +262,42 @@ static int opMOV_EAX_a32(uint32_t fetchdat)
|
|||
static int opMOV_a16_AL(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr = getwordf();
|
||||
writememb(ds, addr, AL);
|
||||
writememb(ea_seg->base, addr, AL);
|
||||
cycles -= (is486) ? 1 : 2;
|
||||
return 0;
|
||||
}
|
||||
static int opMOV_a32_AL(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr = getlong();
|
||||
writememb(ds, addr, AL);
|
||||
writememb(ea_seg->base, addr, AL);
|
||||
cycles -= (is486) ? 1 : 2;
|
||||
return 0;
|
||||
}
|
||||
static int opMOV_a16_AX(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr = getwordf();
|
||||
writememw(ds, addr, AX);
|
||||
writememw(ea_seg->base, addr, AX);
|
||||
cycles -= (is486) ? 1 : 2;
|
||||
return 0;
|
||||
}
|
||||
static int opMOV_a32_AX(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr = getlong();
|
||||
writememw(ds, addr, AX);
|
||||
writememw(ea_seg->base, addr, AX);
|
||||
cycles -= (is486) ? 1 : 2;
|
||||
return 0;
|
||||
}
|
||||
static int opMOV_a16_EAX(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr = getwordf();
|
||||
writememl(ds, addr, EAX);
|
||||
writememl(ea_seg->base, addr, EAX);
|
||||
cycles -= (is486) ? 1 : 2;
|
||||
return 0;
|
||||
}
|
||||
static int opMOV_a32_EAX(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr = getlong();
|
||||
writememl(ds, addr, EAX);
|
||||
writememl(ea_seg->base, addr, EAX);
|
||||
cycles -= (is486) ? 1 : 2;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -342,7 +342,7 @@ static int opLEA_l_a32(uint32_t fetchdat)
|
|||
int opXLAT_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr = (BX + AL)&0xFFFF;
|
||||
uint8_t temp = readmemb(ds, addr); if (abrt) return 0;
|
||||
uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 0;
|
||||
AL = temp;
|
||||
cycles -= 5;
|
||||
return 0;
|
||||
|
|
@ -350,7 +350,7 @@ int opXLAT_a16(uint32_t fetchdat)
|
|||
int opXLAT_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr = EBX + AL;
|
||||
uint8_t temp = readmemb(ds, addr); if (abrt) return 0;
|
||||
uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 0;
|
||||
AL = temp;
|
||||
cycles -= 5;
|
||||
return 0;
|
||||
|
|
@ -367,6 +367,7 @@ static int opMOV_b_r_a16(uint32_t fetchdat)
|
|||
else
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
CHECK_WRITE(ea_seg, eaaddr, eaaddr);
|
||||
seteab(getr8(reg));
|
||||
cycles -= is486 ? 1 : 2;
|
||||
}
|
||||
|
|
@ -383,6 +384,7 @@ static int opMOV_b_r_a32(uint32_t fetchdat)
|
|||
else
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
CHECK_WRITE(ea_seg, eaaddr, eaaddr);
|
||||
seteab(getr8(reg));
|
||||
cycles -= is486 ? 1 : 2;
|
||||
}
|
||||
|
|
@ -399,6 +401,7 @@ static int opMOV_w_r_a16(uint32_t fetchdat)
|
|||
else
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
CHECK_WRITE(ea_seg, eaaddr, eaaddr+1);
|
||||
seteaw(regs[reg].w);
|
||||
cycles -= is486 ? 1 : 2;
|
||||
}
|
||||
|
|
@ -415,6 +418,7 @@ static int opMOV_w_r_a32(uint32_t fetchdat)
|
|||
else
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
CHECK_WRITE(ea_seg, eaaddr, eaaddr+1);
|
||||
seteaw(regs[reg].w);
|
||||
cycles -= is486 ? 1 : 2;
|
||||
}
|
||||
|
|
@ -431,6 +435,7 @@ static int opMOV_l_r_a16(uint32_t fetchdat)
|
|||
else
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
CHECK_WRITE(ea_seg, eaaddr, eaaddr+3);
|
||||
seteal(regs[reg].l);
|
||||
cycles -= is486 ? 1 : 2;
|
||||
}
|
||||
|
|
@ -447,6 +452,7 @@ static int opMOV_l_r_a32(uint32_t fetchdat)
|
|||
else
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
CHECK_WRITE(ea_seg, eaaddr, eaaddr+3);
|
||||
seteal(regs[reg].l);
|
||||
cycles -= is486 ? 1 : 2;
|
||||
}
|
||||
|
|
@ -465,6 +471,7 @@ static int opMOV_r_b_a16(uint32_t fetchdat)
|
|||
{
|
||||
uint8_t temp;
|
||||
fetch_ea_16(fetchdat);
|
||||
CHECK_READ(ea_seg, eaaddr, eaaddr);
|
||||
temp = geteab(); if (abrt) return 0;
|
||||
setr8(reg, temp);
|
||||
cycles -= is486 ? 1 : 4;
|
||||
|
|
@ -483,6 +490,7 @@ static int opMOV_r_b_a32(uint32_t fetchdat)
|
|||
{
|
||||
uint8_t temp;
|
||||
fetch_ea_32(fetchdat);
|
||||
CHECK_READ(ea_seg, eaaddr, eaaddr);
|
||||
temp = geteab(); if (abrt) return 0;
|
||||
setr8(reg, temp);
|
||||
cycles -= is486 ? 1 : 4;
|
||||
|
|
@ -501,6 +509,7 @@ static int opMOV_r_w_a16(uint32_t fetchdat)
|
|||
{
|
||||
uint16_t temp;
|
||||
fetch_ea_16(fetchdat);
|
||||
CHECK_READ(ea_seg, eaaddr, eaaddr+1);
|
||||
temp = geteaw(); if (abrt) return 0;
|
||||
regs[reg].w = temp;
|
||||
cycles -= (is486) ? 1 : 4;
|
||||
|
|
@ -519,6 +528,7 @@ static int opMOV_r_w_a32(uint32_t fetchdat)
|
|||
{
|
||||
uint16_t temp;
|
||||
fetch_ea_32(fetchdat);
|
||||
CHECK_READ(ea_seg, eaaddr, eaaddr+1);
|
||||
temp = geteaw(); if (abrt) return 0;
|
||||
regs[reg].w = temp;
|
||||
cycles -= (is486) ? 1 : 4;
|
||||
|
|
@ -537,6 +547,7 @@ static int opMOV_r_l_a16(uint32_t fetchdat)
|
|||
{
|
||||
uint32_t temp;
|
||||
fetch_ea_16(fetchdat);
|
||||
CHECK_READ(ea_seg, eaaddr, eaaddr+3);
|
||||
temp = geteal(); if (abrt) return 0;
|
||||
regs[reg].l = temp;
|
||||
cycles -= is486 ? 1 : 4;
|
||||
|
|
@ -555,6 +566,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat)
|
|||
{
|
||||
uint32_t temp;
|
||||
fetch_ea_32(fetchdat);
|
||||
CHECK_READ(ea_seg, eaaddr, eaaddr+3);
|
||||
temp = geteal(); if (abrt) return 0;
|
||||
regs[reg].l = temp;
|
||||
cycles -= is486 ? 1 : 4;
|
||||
|
|
|
|||
|
|
@ -11,11 +11,9 @@ static int opMOV_w_seg_a16(uint32_t fetchdat)
|
|||
seteaw(CS);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
if (ssegs) ds = oldds;
|
||||
seteaw(DS);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
if (ssegs) ss = oldss;
|
||||
seteaw(SS);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
|
|
@ -42,11 +40,9 @@ static int opMOV_w_seg_a32(uint32_t fetchdat)
|
|||
seteaw(CS);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
if (ssegs) ds = oldds;
|
||||
seteaw(DS);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
if (ssegs) ss = oldss;
|
||||
seteaw(SS);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
|
|
@ -76,12 +72,10 @@ static int opMOV_l_seg_a16(uint32_t fetchdat)
|
|||
else seteaw(CS);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
if (ssegs) ds = oldds;
|
||||
if (mod == 3) regs[rm].l = DS;
|
||||
else seteaw(DS);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
if (ssegs) ss = oldss;
|
||||
if (mod == 3) regs[rm].l = SS;
|
||||
else seteaw(SS);
|
||||
break;
|
||||
|
|
@ -113,12 +107,10 @@ static int opMOV_l_seg_a32(uint32_t fetchdat)
|
|||
else seteaw(CS);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
if (ssegs) ds = oldds;
|
||||
if (mod == 3) regs[rm].l = DS;
|
||||
else seteaw(DS);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
if (ssegs) ss = oldss;
|
||||
if (mod == 3) regs[rm].l = SS;
|
||||
else seteaw(SS);
|
||||
break;
|
||||
|
|
@ -151,16 +143,9 @@ static int opMOV_seg_w_a16(uint32_t fetchdat)
|
|||
break;
|
||||
case 0x18: /*DS*/
|
||||
loadseg(new_seg, &_ds);
|
||||
if (ssegs) oldds = ds;
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
loadseg(new_seg, &_ss);
|
||||
if (ssegs)
|
||||
{
|
||||
ds = oldds;
|
||||
rds = DS;
|
||||
ssegs = 0;
|
||||
}
|
||||
op32 = use32;
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
|
|
@ -189,16 +174,9 @@ static int opMOV_seg_w_a32(uint32_t fetchdat)
|
|||
break;
|
||||
case 0x18: /*DS*/
|
||||
loadseg(new_seg, &_ds);
|
||||
if (ssegs) oldds = ds;
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
loadseg(new_seg, &_ss);
|
||||
if (ssegs)
|
||||
{
|
||||
ds = oldds;
|
||||
rds = DS;
|
||||
ssegs = 0;
|
||||
}
|
||||
op32 = use32;
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
|
|
@ -224,7 +202,6 @@ static int opLDS_w_a16(uint32_t fetchdat)
|
|||
seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0;
|
||||
loadseg(seg, &_ds); if (abrt) return 0;
|
||||
regs[reg].w = addr;
|
||||
if (ssegs) oldds = ds;
|
||||
|
||||
cycles -= 7;
|
||||
return 0;
|
||||
|
|
@ -239,7 +216,6 @@ static int opLDS_w_a32(uint32_t fetchdat)
|
|||
seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0;
|
||||
loadseg(seg, &_ds); if (abrt) return 0;
|
||||
regs[reg].w = addr;
|
||||
if (ssegs) oldds = ds;
|
||||
|
||||
cycles -= 7;
|
||||
return 0;
|
||||
|
|
@ -255,7 +231,6 @@ static int opLDS_l_a16(uint32_t fetchdat)
|
|||
seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0;
|
||||
loadseg(seg, &_ds); if (abrt) return 0;
|
||||
regs[reg].l = addr;
|
||||
if (ssegs) oldds = ds;
|
||||
|
||||
cycles -= 7;
|
||||
return 0;
|
||||
|
|
@ -271,7 +246,6 @@ static int opLDS_l_a32(uint32_t fetchdat)
|
|||
seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0;
|
||||
loadseg(seg, &_ds); if (abrt) return 0;
|
||||
regs[reg].l = addr;
|
||||
if (ssegs) oldds = ds;
|
||||
|
||||
cycles -= 7;
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,59 +1,42 @@
|
|||
static int op_CS(uint32_t fetchdat)
|
||||
{
|
||||
oldss = ss;
|
||||
oldds = ds;
|
||||
ds = ss = cs;
|
||||
rds = CS;
|
||||
ssegs = 2;
|
||||
ea_seg = &_cs;
|
||||
ssegs = 1;
|
||||
cycles -= 4;
|
||||
return 1;
|
||||
}
|
||||
static int op_DS(uint32_t fetchdat)
|
||||
{
|
||||
oldss = ss;
|
||||
oldds = ds;
|
||||
ds = ss = ds;
|
||||
ssegs = 2;
|
||||
ea_seg = &_ds;
|
||||
ssegs = 1;
|
||||
cycles -= 4;
|
||||
return 1;
|
||||
}
|
||||
static int op_ES(uint32_t fetchdat)
|
||||
{
|
||||
oldss = ss;
|
||||
oldds = ds;
|
||||
ds = ss = es;
|
||||
rds = ES;
|
||||
ssegs = 2;
|
||||
ea_seg = &_es;
|
||||
ssegs = 1;
|
||||
cycles -= 4;
|
||||
return 1;
|
||||
}
|
||||
static int op_FS(uint32_t fetchdat)
|
||||
{
|
||||
oldss = ss;
|
||||
oldds = ds;
|
||||
rds = FS;
|
||||
ds = ss = fs;
|
||||
ssegs = 2;
|
||||
ea_seg = &_fs;
|
||||
ssegs = 1;
|
||||
cycles -= 4;
|
||||
return 1;
|
||||
}
|
||||
static int op_GS(uint32_t fetchdat)
|
||||
{
|
||||
oldss = ss;
|
||||
oldds = ds;
|
||||
rds = GS;
|
||||
ds = ss = gs;
|
||||
ssegs = 2;
|
||||
ea_seg = &_gs;
|
||||
ssegs = 1;
|
||||
cycles -= 4;
|
||||
return 1;
|
||||
}
|
||||
static int op_SS(uint32_t fetchdat)
|
||||
{
|
||||
oldss = ss;
|
||||
oldds = ds;
|
||||
ds = ss = ss;
|
||||
rds = SS;
|
||||
ssegs = 2;
|
||||
ea_seg = &_ss;
|
||||
ssegs = 1;
|
||||
cycles -= 4;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
pmoderetf(0, stack_offset); \
|
||||
return 0; \
|
||||
} \
|
||||
if (ssegs) ss = oldss; \
|
||||
oxpc = pc; \
|
||||
if (stack32) \
|
||||
{ \
|
||||
|
|
@ -27,7 +26,6 @@
|
|||
pmoderetf(1, stack_offset); \
|
||||
return 0; \
|
||||
} \
|
||||
if (ssegs) ss = oldss; \
|
||||
oxpc = pc; \
|
||||
if (stack32) \
|
||||
{ \
|
||||
|
|
@ -75,7 +73,6 @@ static int opIRET_286(uint32_t fetchdat)
|
|||
x86gpf(NULL,0);
|
||||
return 0;
|
||||
}
|
||||
if (ssegs) ss = oldss;
|
||||
if (msw&1)
|
||||
{
|
||||
optype = IRET;
|
||||
|
|
@ -115,7 +112,6 @@ static int opIRET(uint32_t fetchdat)
|
|||
x86gpf(NULL,0);
|
||||
return 0;
|
||||
}
|
||||
if (ssegs) ss = oldss;
|
||||
if (msw&1)
|
||||
{
|
||||
optype = IRET;
|
||||
|
|
@ -155,7 +151,6 @@ static int opIRETD(uint32_t fetchdat)
|
|||
x86gpf(NULL,0);
|
||||
return 0;
|
||||
}
|
||||
if (ssegs) ss = oldss;
|
||||
if (msw & 1)
|
||||
{
|
||||
optype = IRET;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#define PUSH_W_OP(reg) \
|
||||
static int opPUSH_ ## reg (uint32_t fetchdat) \
|
||||
{ \
|
||||
if (ssegs) ss=oldss; \
|
||||
PUSH_W(reg); \
|
||||
cycles -= (is486) ? 1 : 2; \
|
||||
return 0; \
|
||||
|
|
@ -10,7 +9,6 @@
|
|||
#define PUSH_L_OP(reg) \
|
||||
static int opPUSH_ ## reg (uint32_t fetchdat) \
|
||||
{ \
|
||||
if (ssegs) ss=oldss; \
|
||||
PUSH_L(reg); \
|
||||
cycles -= (is486) ? 1 : 2; \
|
||||
return 0; \
|
||||
|
|
@ -19,7 +17,6 @@
|
|||
#define POP_W_OP(reg) \
|
||||
static int opPOP_ ## reg (uint32_t fetchdat) \
|
||||
{ \
|
||||
if (ssegs) ss=oldss; \
|
||||
reg = POP_W(); \
|
||||
cycles -= (is486) ? 1 : 4; \
|
||||
return 0; \
|
||||
|
|
@ -28,7 +25,6 @@
|
|||
#define POP_L_OP(reg) \
|
||||
static int opPOP_ ## reg (uint32_t fetchdat) \
|
||||
{ \
|
||||
if (ssegs) ss=oldss; \
|
||||
reg = POP_L(); \
|
||||
cycles -= (is486) ? 1 : 4; \
|
||||
return 0; \
|
||||
|
|
@ -188,7 +184,6 @@ static int opPOPA_l(uint32_t fetchdat)
|
|||
static int opPUSH_imm_w(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t val = getwordf();
|
||||
if (ssegs) ss=oldss;
|
||||
PUSH_W(val);
|
||||
cycles -= 2;
|
||||
return 0;
|
||||
|
|
@ -196,7 +191,6 @@ static int opPUSH_imm_w(uint32_t fetchdat)
|
|||
static int opPUSH_imm_l(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t val = getlong();
|
||||
if (ssegs) ss=oldss;
|
||||
PUSH_L(val);
|
||||
cycles -= 2;
|
||||
return 0;
|
||||
|
|
@ -226,9 +220,8 @@ static int opPUSH_imm_bl(uint32_t fetchdat)
|
|||
static int opPOPW_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint32_t tempseg = ssegs ? oldss : ss;
|
||||
|
||||
temp = POP_W_seg(tempseg); if (abrt) return 0;
|
||||
temp = POP_W(); if (abrt) return 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
seteaw(temp);
|
||||
|
|
@ -245,9 +238,8 @@ static int opPOPW_a16(uint32_t fetchdat)
|
|||
static int opPOPW_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint32_t tempseg = ssegs ? oldss : ss;
|
||||
|
||||
temp = POP_W_seg(tempseg); if (abrt) return 0;
|
||||
temp = POP_W(); if (abrt) return 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
seteaw(temp);
|
||||
|
|
@ -265,9 +257,8 @@ static int opPOPW_a32(uint32_t fetchdat)
|
|||
static int opPOPL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t tempseg = ssegs ? oldss : ss;
|
||||
|
||||
temp = POP_L_seg(tempseg); if (abrt) return 0;
|
||||
temp = POP_L(); if (abrt) return 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
seteal(temp);
|
||||
|
|
@ -284,9 +275,8 @@ static int opPOPL_a16(uint32_t fetchdat)
|
|||
static int opPOPL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t tempseg = ssegs ? oldss : ss;
|
||||
|
||||
temp = POP_L_seg(tempseg); if (abrt) return 0;
|
||||
temp = POP_L(); if (abrt) return 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
seteal(temp);
|
||||
|
|
@ -401,14 +391,12 @@ static int opLEAVE_l(uint32_t fetchdat)
|
|||
#define PUSH_SEG_OPS(seg) \
|
||||
static int opPUSH_ ## seg ## _w(uint32_t fetchdat) \
|
||||
{ \
|
||||
if (ssegs) ss=oldss; \
|
||||
PUSH_W(seg); \
|
||||
cycles -= 2; \
|
||||
return 0; \
|
||||
} \
|
||||
static int opPUSH_ ## seg ## _l(uint32_t fetchdat) \
|
||||
{ \
|
||||
if (ssegs) ss=oldss; \
|
||||
PUSH_L(seg); \
|
||||
cycles -= 2; \
|
||||
return 0; \
|
||||
|
|
@ -419,7 +407,6 @@ static int opLEAVE_l(uint32_t fetchdat)
|
|||
{ \
|
||||
uint16_t temp_seg; \
|
||||
uint32_t temp_esp = ESP; \
|
||||
if (ssegs) ss=oldss; \
|
||||
temp_seg = POP_W(); if (abrt) return 0; \
|
||||
loadseg(temp_seg, realseg); if (abrt) ESP = temp_esp; \
|
||||
cycles -= is486 ? 3 : 7; \
|
||||
|
|
@ -429,7 +416,6 @@ static int opLEAVE_l(uint32_t fetchdat)
|
|||
{ \
|
||||
uint32_t temp_seg; \
|
||||
uint32_t temp_esp = ESP; \
|
||||
if (ssegs) ss=oldss; \
|
||||
temp_seg = POP_L(); if (abrt) return 0; \
|
||||
loadseg(temp_seg & 0xffff, realseg); if (abrt) ESP = temp_esp; \
|
||||
cycles -= is486 ? 3 : 7; \
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
static int opMOVSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp = readmemb(ds,SI); if (abrt) return 0;
|
||||
uint8_t temp = readmemb(ea_seg->base, SI); if (abrt) return 0;
|
||||
writememb(es, DI, temp); if (abrt) return 0;
|
||||
if (flags & D_FLAG) { DI--; SI--; }
|
||||
else { DI++; SI++; }
|
||||
|
|
@ -9,7 +9,7 @@ static int opMOVSB_a16(uint32_t fetchdat)
|
|||
}
|
||||
static int opMOVSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp = readmemb(ds,ESI); if (abrt) return 0;
|
||||
uint8_t temp = readmemb(ea_seg->base, ESI); if (abrt) return 0;
|
||||
writememb(es, EDI, temp); if (abrt) return 0;
|
||||
if (flags & D_FLAG) { EDI--; ESI--; }
|
||||
else { EDI++; ESI++; }
|
||||
|
|
@ -19,7 +19,7 @@ static int opMOVSB_a32(uint32_t fetchdat)
|
|||
|
||||
static int opMOVSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = readmemw(ds,SI); if (abrt) return 0;
|
||||
uint16_t temp = readmemw(ea_seg->base, SI); if (abrt) return 0;
|
||||
writememw(es, DI, temp); if (abrt) return 0;
|
||||
if (flags & D_FLAG) { DI -= 2; SI -= 2; }
|
||||
else { DI += 2; SI += 2; }
|
||||
|
|
@ -28,7 +28,7 @@ static int opMOVSW_a16(uint32_t fetchdat)
|
|||
}
|
||||
static int opMOVSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = readmemw(ds,ESI); if (abrt) return 0;
|
||||
uint16_t temp = readmemw(ea_seg->base, ESI); if (abrt) return 0;
|
||||
writememw(es, EDI, temp); if (abrt) return 0;
|
||||
if (flags & D_FLAG) { EDI -= 2; ESI -= 2; }
|
||||
else { EDI += 2; ESI += 2; }
|
||||
|
|
@ -38,7 +38,7 @@ static int opMOVSW_a32(uint32_t fetchdat)
|
|||
|
||||
static int opMOVSL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = readmeml(ds,SI); if (abrt) return 0;
|
||||
uint32_t temp = readmeml(ea_seg->base, SI); if (abrt) return 0;
|
||||
writememl(es, DI, temp); if (abrt) return 0;
|
||||
if (flags & D_FLAG) { DI -= 4; SI -= 4; }
|
||||
else { DI += 4; SI += 4; }
|
||||
|
|
@ -47,7 +47,7 @@ static int opMOVSL_a16(uint32_t fetchdat)
|
|||
}
|
||||
static int opMOVSL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = readmeml(ds,ESI); if (abrt) return 0;
|
||||
uint32_t temp = readmeml(ea_seg->base, ESI); if (abrt) return 0;
|
||||
writememl(es, EDI, temp); if (abrt) return 0;
|
||||
if (flags & D_FLAG) { EDI -= 4; ESI -= 4; }
|
||||
else { EDI += 4; ESI += 4; }
|
||||
|
|
@ -58,7 +58,7 @@ static int opMOVSL_a32(uint32_t fetchdat)
|
|||
|
||||
static int opCMPSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src = readmemb(ds, SI);
|
||||
uint8_t src = readmemb(ea_seg->base, SI);
|
||||
uint8_t dst = readmemb(es, DI); if (abrt) return 0;
|
||||
setsub8(src, dst);
|
||||
if (flags & D_FLAG) { DI--; SI--; }
|
||||
|
|
@ -68,7 +68,7 @@ static int opCMPSB_a16(uint32_t fetchdat)
|
|||
}
|
||||
static int opCMPSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src = readmemb(ds, ESI);
|
||||
uint8_t src = readmemb(ea_seg->base, ESI);
|
||||
uint8_t dst = readmemb(es, EDI); if (abrt) return 0;
|
||||
setsub8(src, dst);
|
||||
if (flags & D_FLAG) { EDI--; ESI--; }
|
||||
|
|
@ -79,7 +79,7 @@ static int opCMPSB_a32(uint32_t fetchdat)
|
|||
|
||||
static int opCMPSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src = readmemw(ds, SI);
|
||||
uint16_t src = readmemw(ea_seg->base, SI);
|
||||
uint16_t dst = readmemw(es, DI); if (abrt) return 0;
|
||||
setsub16(src, dst);
|
||||
if (flags & D_FLAG) { DI -= 2; SI -= 2; }
|
||||
|
|
@ -89,7 +89,7 @@ static int opCMPSW_a16(uint32_t fetchdat)
|
|||
}
|
||||
static int opCMPSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src = readmemw(ds, ESI);
|
||||
uint16_t src = readmemw(ea_seg->base, ESI);
|
||||
uint16_t dst = readmemw(es, EDI); if (abrt) return 0;
|
||||
setsub16(src, dst);
|
||||
if (flags & D_FLAG) { EDI -= 2; ESI -= 2; }
|
||||
|
|
@ -100,7 +100,7 @@ static int opCMPSW_a32(uint32_t fetchdat)
|
|||
|
||||
static int opCMPSL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src = readmeml(ds, SI);
|
||||
uint32_t src = readmeml(ea_seg->base, SI);
|
||||
uint32_t dst = readmeml(es, DI); if (abrt) return 0;
|
||||
setsub32(src, dst);
|
||||
if (flags & D_FLAG) { DI -= 4; SI -= 4; }
|
||||
|
|
@ -110,7 +110,7 @@ static int opCMPSL_a16(uint32_t fetchdat)
|
|||
}
|
||||
static int opCMPSL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src = readmeml(ds, ESI);
|
||||
uint32_t src = readmeml(ea_seg->base, ESI);
|
||||
uint32_t dst = readmeml(es, EDI); if (abrt) return 0;
|
||||
setsub32(src, dst);
|
||||
if (flags & D_FLAG) { EDI -= 4; ESI -= 4; }
|
||||
|
|
@ -173,7 +173,7 @@ static int opSTOSL_a32(uint32_t fetchdat)
|
|||
|
||||
static int opLODSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp = readmemb(ds, SI); if (abrt) return 0;
|
||||
uint8_t temp = readmemb(ea_seg->base, SI); if (abrt) return 0;
|
||||
AL = temp;
|
||||
if (flags & D_FLAG) SI--;
|
||||
else SI++;
|
||||
|
|
@ -182,7 +182,7 @@ static int opLODSB_a16(uint32_t fetchdat)
|
|||
}
|
||||
static int opLODSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp = readmemb(ds, ESI); if (abrt) return 0;
|
||||
uint8_t temp = readmemb(ea_seg->base, ESI); if (abrt) return 0;
|
||||
AL = temp;
|
||||
if (flags & D_FLAG) ESI--;
|
||||
else ESI++;
|
||||
|
|
@ -192,7 +192,7 @@ static int opLODSB_a32(uint32_t fetchdat)
|
|||
|
||||
static int opLODSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = readmemw(ds, SI); if (abrt) return 0;
|
||||
uint16_t temp = readmemw(ea_seg->base, SI); if (abrt) return 0;
|
||||
AX = temp;
|
||||
if (flags & D_FLAG) SI -= 2;
|
||||
else SI += 2;
|
||||
|
|
@ -201,7 +201,7 @@ static int opLODSW_a16(uint32_t fetchdat)
|
|||
}
|
||||
static int opLODSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = readmemw(ds, ESI); if (abrt) return 0;
|
||||
uint16_t temp = readmemw(ea_seg->base, ESI); if (abrt) return 0;
|
||||
AX = temp;
|
||||
if (flags & D_FLAG) ESI -= 2;
|
||||
else ESI += 2;
|
||||
|
|
@ -211,7 +211,7 @@ static int opLODSW_a32(uint32_t fetchdat)
|
|||
|
||||
static int opLODSL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = readmeml(ds, SI); if (abrt) return 0;
|
||||
uint32_t temp = readmeml(ea_seg->base, SI); if (abrt) return 0;
|
||||
EAX = temp;
|
||||
if (flags & D_FLAG) SI -= 4;
|
||||
else SI += 4;
|
||||
|
|
@ -220,7 +220,7 @@ static int opLODSL_a16(uint32_t fetchdat)
|
|||
}
|
||||
static int opLODSL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = readmeml(ds, ESI); if (abrt) return 0;
|
||||
uint32_t temp = readmeml(ea_seg->base, ESI); if (abrt) return 0;
|
||||
EAX = temp;
|
||||
if (flags & D_FLAG) ESI -= 4;
|
||||
else ESI += 4;
|
||||
|
|
@ -365,7 +365,7 @@ static int opINSL_a32(uint32_t fetchdat)
|
|||
|
||||
static int opOUTSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp = readmemb(ds, SI); if (abrt) return 0;
|
||||
uint8_t temp = readmemb(ea_seg->base, SI); if (abrt) return 0;
|
||||
check_io_perm(DX);
|
||||
if (flags & D_FLAG) SI--;
|
||||
else SI++;
|
||||
|
|
@ -375,7 +375,7 @@ static int opOUTSB_a16(uint32_t fetchdat)
|
|||
}
|
||||
static int opOUTSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp = readmemb(ds, ESI); if (abrt) return 0;
|
||||
uint8_t temp = readmemb(ea_seg->base, ESI); if (abrt) return 0;
|
||||
check_io_perm(DX);
|
||||
if (flags & D_FLAG) ESI--;
|
||||
else ESI++;
|
||||
|
|
@ -386,7 +386,7 @@ static int opOUTSB_a32(uint32_t fetchdat)
|
|||
|
||||
static int opOUTSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = readmemw(ds, SI); if (abrt) return 0;
|
||||
uint16_t temp = readmemw(ea_seg->base, SI); if (abrt) return 0;
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
if (flags & D_FLAG) SI -= 2;
|
||||
|
|
@ -397,7 +397,7 @@ static int opOUTSW_a16(uint32_t fetchdat)
|
|||
}
|
||||
static int opOUTSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = readmemw(ds, ESI); if (abrt) return 0;
|
||||
uint16_t temp = readmemw(ea_seg->base, ESI); if (abrt) return 0;
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
if (flags & D_FLAG) ESI -= 2;
|
||||
|
|
@ -409,7 +409,7 @@ static int opOUTSW_a32(uint32_t fetchdat)
|
|||
|
||||
static int opOUTSL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = readmeml(ds, SI); if (abrt) return 0;
|
||||
uint32_t temp = readmeml(ea_seg->base, SI); if (abrt) return 0;
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
|
|
@ -422,7 +422,7 @@ static int opOUTSL_a16(uint32_t fetchdat)
|
|||
}
|
||||
static int opOUTSL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = readmeml(ds, ESI); if (abrt) return 0;
|
||||
uint32_t temp = readmeml(ea_seg->base, ESI); if (abrt) return 0;
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
|
|
|
|||
377
src/x86seg.c
377
src/x86seg.c
|
|
@ -57,6 +57,24 @@ void x86abort(const char *format, ...)
|
|||
|
||||
uint8_t opcode2;
|
||||
|
||||
static void seg_reset(x86seg *s)
|
||||
{
|
||||
s->access = 0 << 5;
|
||||
s->limit = 0xFFFF;
|
||||
s->limit_low = 0;
|
||||
s->limit_high = 0xffff;
|
||||
}
|
||||
|
||||
void x86seg_reset()
|
||||
{
|
||||
seg_reset(&_cs);
|
||||
seg_reset(&_ds);
|
||||
seg_reset(&_es);
|
||||
seg_reset(&_fs);
|
||||
seg_reset(&_gs);
|
||||
seg_reset(&_ss);
|
||||
}
|
||||
|
||||
void x86_doabrt(int x86_abrt)
|
||||
{
|
||||
// ingpf = 1;
|
||||
|
|
@ -73,7 +91,33 @@ void x86_doabrt(int x86_abrt)
|
|||
}*/
|
||||
// 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);
|
||||
|
||||
pmodeint(x86_abrt, 0);
|
||||
if (msw & 1)
|
||||
pmodeint(x86_abrt, 0);
|
||||
else
|
||||
{
|
||||
uint32_t addr = (x86_abrt << 2) + idt.base;
|
||||
if (stack32)
|
||||
{
|
||||
writememw(ss,ESP-2,flags);
|
||||
writememw(ss,ESP-4,CS);
|
||||
writememw(ss,ESP-6,pc);
|
||||
ESP-=6;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss,((SP-2)&0xFFFF),flags);
|
||||
writememw(ss,((SP-4)&0xFFFF),CS);
|
||||
writememw(ss,((SP-6)&0xFFFF),pc);
|
||||
SP-=6;
|
||||
}
|
||||
|
||||
flags&=~I_FLAG;
|
||||
flags&=~T_FLAG;
|
||||
oxpc=pc;
|
||||
pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
return;
|
||||
}
|
||||
|
||||
if (abrt) return;
|
||||
|
||||
|
|
@ -132,12 +176,90 @@ void x86np(char *s, uint16_t error)
|
|||
}
|
||||
|
||||
|
||||
static void do_seg_load(x86seg *s, uint16_t *segdat)
|
||||
{
|
||||
s->limit = segdat[0] | ((segdat[3] & 0xF) << 16);
|
||||
if (segdat[3] & 0x80)
|
||||
s->limit = (s->limit << 12) | 0xFFF;
|
||||
s->base = segdat[1] | ((segdat[2] & 0xFF) << 16);
|
||||
if (is386)
|
||||
s->base |= ((segdat[3] >> 8) << 24);
|
||||
s->access = segdat[2] >> 8;
|
||||
|
||||
if ((segdat[2] & 0x1800) != 0x1000 || !(segdat[2] & (1 << 10))) /*expand-down*/
|
||||
{
|
||||
s->limit_high = s->limit;
|
||||
s->limit_low = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff;
|
||||
s->limit_low = s->limit + 1;
|
||||
}
|
||||
// if (output) pclog("SEG : base=%08x limit=%08x low=%08x high=%08x\n", s->base, s->limit, s->limit_low, s->limit_high);
|
||||
}
|
||||
|
||||
static void do_seg_v86_init(x86seg *s)
|
||||
{
|
||||
s->access = 3 << 5;
|
||||
s->limit = 0xffff;
|
||||
s->limit_low = 0;
|
||||
s->limit_high = 0xffff;
|
||||
}
|
||||
|
||||
static void check_seg_valid(x86seg *s)
|
||||
{
|
||||
int dpl = (s->access >> 5) & 3;
|
||||
int valid = 1;
|
||||
|
||||
if (s->seg & 4)
|
||||
{
|
||||
if ((s->seg & ~7) >= ldt.limit)
|
||||
{
|
||||
// pclog("Bigger than LDT limit %04X %04X %02X %02X %02X\n", s->seg, ldt.limit, opcode, opcode2, rmdat);
|
||||
valid = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((s->seg & ~7) >= gdt.limit)
|
||||
{
|
||||
// pclog("Bigger than GDT limit %04X %04X\n", s->seg, gdt.limit);
|
||||
valid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (s->access & 0x1f)
|
||||
{
|
||||
case 0x10: case 0x11: case 0x12: case 0x13: /*Data segments*/
|
||||
case 0x14: case 0x15: case 0x16: case 0x17:
|
||||
case 0x1A: case 0x1B: /*Readable non-conforming code*/
|
||||
if ((s->seg & 3) > dpl || (CPL) > dpl)
|
||||
{
|
||||
// pclog("Data seg fail - %04X:%08X %04X %i\n", CS, pc, s->seg, dpl);
|
||||
valid = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1E: case 0x1F: /*Readable conforming code*/
|
||||
break;
|
||||
|
||||
default:
|
||||
valid = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!valid)
|
||||
loadseg(0, s);
|
||||
}
|
||||
|
||||
void loadseg(uint16_t seg, x86seg *s)
|
||||
{
|
||||
uint16_t segdat[4];
|
||||
uint32_t addr;
|
||||
int dpl;
|
||||
if (output) pclog("Load seg %04X\n",seg);
|
||||
|
||||
if (msw&1 && !(eflags&VM_FLAG))
|
||||
{
|
||||
// intcount++;
|
||||
|
|
@ -153,6 +275,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||
}
|
||||
// if (s->base!=-1) pclog("NEW! ");
|
||||
s->seg=0;
|
||||
s->access = 0;
|
||||
s->base=-1;
|
||||
// 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);
|
||||
return;
|
||||
|
|
@ -224,7 +347,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||
}
|
||||
if (segdat[3]&0x40) stack32=1;
|
||||
else stack32=0;
|
||||
// pclog("Load SS\n");
|
||||
// pclog("Load SS %04x %04x %04x %04x\n", segdat[0], segdat[1], segdat[2], segdat[3]);
|
||||
}
|
||||
else if (s!=&_cs)
|
||||
{
|
||||
|
|
@ -248,71 +371,38 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||
break;
|
||||
default:
|
||||
pclog("Invalid segment type for %04X! %04X\n",seg&0xFFFC,segdat[2]);
|
||||
// if ((seg & ~3) == 0x1508) btimes++;
|
||||
// if (btimes == 2) output = 3;
|
||||
// dumpregs();
|
||||
// exit(-1);
|
||||
x86gpf(NULL,seg&~3);
|
||||
// x86abort("Invalid segment type for %04X!\n",seg&0xFFFC);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
// }
|
||||
// if (!(segdat[2]&0x8000)) x86abort("Data segment not present!\n");
|
||||
// if (!(segdat[2]&0x800) || !(segdat[2]&0x400))
|
||||
// {
|
||||
if (!(segdat[2]&0x8000))
|
||||
{
|
||||
x86np("Load data seg not present", seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
s->seg=seg;
|
||||
s->limit=segdat[0]|((segdat[3]&0xF)<<16);
|
||||
if (segdat[3]&0x80) s->limit=(s->limit<<12)|0xFFF;
|
||||
s->limitw=(segdat[2]&0x200)?1:0;
|
||||
s->base=segdat[1];
|
||||
s->base|=((segdat[2]&0xFF)<<16);
|
||||
if (is386) s->base|=((segdat[3]>>8)<<24);
|
||||
s->access=segdat[2]>>8;
|
||||
|
||||
if ((segdat[2]>>8) & 4)
|
||||
s->limit = 0xffffffff;
|
||||
|
||||
// if (output) pclog("SS limit %08X\n", s->limit);
|
||||
|
||||
// pclog("Seg Write %04X to %08X\n",segdat[2]|0x100,addr+4);
|
||||
|
||||
if (!(segdat[2] & 0x8000))
|
||||
{
|
||||
x86np("Load data seg not present", seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
s->seg = seg;
|
||||
do_seg_load(s, segdat);
|
||||
|
||||
#ifndef CS_ACCESSED
|
||||
if (s != &_cs)
|
||||
{
|
||||
if (s != &_cs)
|
||||
{
|
||||
#endif
|
||||
#ifdef SEL_ACCESSED
|
||||
cpl_override = 1;
|
||||
writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/
|
||||
cpl_override = 0;
|
||||
cpl_override = 1;
|
||||
writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/
|
||||
cpl_override = 0;
|
||||
#endif
|
||||
#ifndef CS_ACCESSED
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// pclog("Access=%02X Limit=%04X Limitw=%04X %08X %i %04X:%04X\n",s->access,s->limit,s->limitw, _ss.limit, ins, CS, pc);
|
||||
// if (s==&_es && s->base>0x180000) s->base=0x180000;
|
||||
// }
|
||||
// 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);
|
||||
// dumpregs();
|
||||
// exit(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
s->base=seg<<4;
|
||||
s->limit=0xFFFF;
|
||||
s->seg=seg;
|
||||
if (eflags&VM_FLAG) s->access=3<<5;
|
||||
else s->access=0<<5;
|
||||
if (s==&_ss) stack32=0;
|
||||
/* if (s==&_ds)
|
||||
{
|
||||
pclog("DS! %04X %06X %04X:%04X\n",DS,ds,CS,pc);
|
||||
}*/
|
||||
s->base = seg << 4;
|
||||
s->seg = seg;
|
||||
if (s == &_ss)
|
||||
stack32 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -397,12 +487,7 @@ void loadcs(uint16_t seg)
|
|||
if (segdat[3]&0x40) use32=0x300;
|
||||
else use32=0;
|
||||
CS=(seg&~3)|CPL;
|
||||
_cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
|
||||
if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
|
||||
_cs.base=segdat[1];
|
||||
_cs.base|=((segdat[2]&0xFF)<<16);
|
||||
if (is386) _cs.base|=((segdat[3]>>8)<<24);
|
||||
_cs.access=segdat[2]>>8;
|
||||
do_seg_load(&_cs, segdat);
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
|
|
@ -437,6 +522,8 @@ void loadcs(uint16_t seg)
|
|||
{
|
||||
_cs.base=seg<<4;
|
||||
_cs.limit=0xFFFF;
|
||||
_cs.limit_low = 0;
|
||||
_cs.limit_high = 0xffff;
|
||||
CS=seg;
|
||||
if (eflags&VM_FLAG) _cs.access=3<<5;
|
||||
else _cs.access=0<<5;
|
||||
|
|
@ -526,13 +613,8 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||
|
||||
CS = (seg & ~3) | CPL;
|
||||
segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8));
|
||||
|
||||
_cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
|
||||
if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
|
||||
_cs.base=segdat[1];
|
||||
_cs.base|=((segdat[2]&0xFF)<<16);
|
||||
if (is386) _cs.base|=((segdat[3]>>8)<<24);
|
||||
_cs.access=segdat[2]>>8;
|
||||
|
||||
do_seg_load(&_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
}
|
||||
|
|
@ -627,12 +709,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||
}
|
||||
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
|
||||
CS=seg2;
|
||||
_cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
|
||||
if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
|
||||
_cs.base=segdat[1];
|
||||
_cs.base|=((segdat[2]&0xFF)<<16);
|
||||
if (is386) _cs.base|=((segdat[3]>>8)<<24);
|
||||
_cs.access=segdat[2]>>8;
|
||||
do_seg_load(&_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
pc=newpc;
|
||||
|
|
@ -679,6 +756,8 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||
{
|
||||
_cs.base=seg<<4;
|
||||
_cs.limit=0xFFFF;
|
||||
_cs.limit_low = 0;
|
||||
_cs.limit_high = 0xffff;
|
||||
CS=seg;
|
||||
if (eflags&VM_FLAG) _cs.access=3<<5;
|
||||
else _cs.access=0<<5;
|
||||
|
|
@ -858,12 +937,7 @@ void loadcscall(uint16_t seg)
|
|||
else /*On non-conforming segments, set RPL = CPL*/
|
||||
seg = (seg & ~3) | CPL;
|
||||
CS=seg;
|
||||
_cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
|
||||
if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
|
||||
_cs.base=segdat[1];
|
||||
_cs.base|=((segdat[2]&0xFF)<<16);
|
||||
if (is386) _cs.base|=((segdat[3]>>8)<<24);
|
||||
_cs.access=segdat[2]>>8;
|
||||
do_seg_load(&_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
if (csout) pclog("Complete\n");
|
||||
|
|
@ -1031,16 +1105,8 @@ void loadcscall(uint16_t seg)
|
|||
stack32=segdat2[3]&0x40;
|
||||
if (stack32) ESP=newsp;
|
||||
else SP=newsp;
|
||||
_ss.limit=segdat2[0]|((segdat2[3]&0xF)<<16);
|
||||
if (segdat2[3]&0x80) _ss.limit=(_ss.limit<<12)|0xFFF;
|
||||
if ((segdat2[2]>>8) & 4)
|
||||
_ss.limit = 0xffffffff;
|
||||
|
||||
_ss.limitw=(segdat2[2]&0x200)?1:0;
|
||||
_ss.base=segdat2[1];
|
||||
_ss.base|=((segdat2[2]&0xFF)<<16);
|
||||
if (is386) _ss.base|=((segdat2[3]>>8)<<24);
|
||||
_ss.access=segdat2[2]>>8;
|
||||
|
||||
do_seg_load(&_ss, segdat2);
|
||||
|
||||
if (output) pclog("Set access 1\n");
|
||||
|
||||
|
|
@ -1051,12 +1117,7 @@ void loadcscall(uint16_t seg)
|
|||
#endif
|
||||
|
||||
CS=seg2;
|
||||
_cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
|
||||
if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
|
||||
_cs.base=segdat[1];
|
||||
_cs.base|=((segdat[2]&0xFF)<<16);
|
||||
if (is386) _cs.base|=((segdat[3]>>8)<<24);
|
||||
_cs.access=segdat[2]>>8;
|
||||
do_seg_load(&_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
pc=newpc;
|
||||
|
|
@ -1159,12 +1220,7 @@ void loadcscall(uint16_t seg)
|
|||
PUSHW(oldpc); if (abrt) return;
|
||||
}*/
|
||||
CS=seg2;
|
||||
_cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
|
||||
if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
|
||||
_cs.base=segdat[1];
|
||||
_cs.base|=((segdat[2]&0xFF)<<16);
|
||||
if (is386) _cs.base|=((segdat[3]>>8)<<24);
|
||||
_cs.access=segdat[2]>>8;
|
||||
do_seg_load(&_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
pc=newpc;
|
||||
|
|
@ -1206,6 +1262,8 @@ void loadcscall(uint16_t seg)
|
|||
{
|
||||
_cs.base=seg<<4;
|
||||
_cs.limit=0xFFFF;
|
||||
_cs.limit_low = 0;
|
||||
_cs.limit_high = 0xffff;
|
||||
CS=seg;
|
||||
if (eflags&VM_FLAG) _cs.access=3<<5;
|
||||
else _cs.access=0<<5;
|
||||
|
|
@ -1334,12 +1392,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||
if (segdat[2] & 0x400)
|
||||
segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8));
|
||||
CS = seg;
|
||||
_cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
|
||||
if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
|
||||
_cs.base=segdat[1];
|
||||
_cs.base|=((segdat[2]&0xFF)<<16);
|
||||
if (is386) _cs.base|=((segdat[3]>>8)<<24);
|
||||
_cs.access=segdat[2]>>8;
|
||||
do_seg_load(&_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
|
||||
|
|
@ -1472,15 +1525,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||
stack32=segdat2[3]&0x40;
|
||||
if (stack32) ESP=newsp;
|
||||
else SP=newsp;
|
||||
_ss.limit=segdat2[0]|((segdat2[3]&0xF)<<16);
|
||||
if (segdat2[3]&0x80) _ss.limit=(_ss.limit<<12)|0xFFF;
|
||||
if ((segdat2[2]>>8) & 4)
|
||||
_ss.limit = 0xffffffff;
|
||||
_ss.limitw=(segdat2[2]&0x200)?1:0;
|
||||
_ss.base=segdat2[1];
|
||||
_ss.base|=((segdat2[2]&0xFF)<<16);
|
||||
if (is386) _ss.base|=((segdat2[3]>>8)<<24);
|
||||
_ss.access=segdat2[2]>>8;
|
||||
do_seg_load(&_ss, segdat2);
|
||||
|
||||
#ifdef SEL_ACCESSED
|
||||
cpl_override = 1;
|
||||
|
|
@ -1497,24 +1542,24 @@ void pmoderetf(int is32, uint16_t off)
|
|||
|
||||
pc=newpc;
|
||||
CS=seg;
|
||||
_cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
|
||||
if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
|
||||
_cs.base=segdat[1];
|
||||
_cs.base|=((segdat[2]&0xFF)<<16);
|
||||
if (is386) _cs.base|=((segdat[3]>>8)<<24);
|
||||
_cs.access=segdat[2]>>8;
|
||||
do_seg_load(&_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
|
||||
if (stack32) ESP+=off;
|
||||
else SP+=off;
|
||||
|
||||
check_seg_valid(&_ds);
|
||||
check_seg_valid(&_es);
|
||||
check_seg_valid(&_fs);
|
||||
check_seg_valid(&_gs);
|
||||
// pclog("CPL<RPL return to %04X:%08X %04X:%08X\n",CS,pc,SS,ESP);
|
||||
}
|
||||
}
|
||||
|
||||
void restore_stack()
|
||||
{
|
||||
ss=oldss; _ss.limit=oldsslimit; _ss.limitw=oldsslimitw;
|
||||
ss=oldss; _ss.limit=oldsslimit;
|
||||
}
|
||||
|
||||
void pmodeint(int num, int soft)
|
||||
|
|
@ -1527,6 +1572,7 @@ void pmodeint(int num, int soft)
|
|||
uint32_t newsp;
|
||||
uint16_t seg;
|
||||
int stack_changed=0;
|
||||
|
||||
// if (!num) pclog("Pmode int 0 at %04X(%06X):%08X\n",CS,cs,pc);
|
||||
// pclog("Pmode int %02X %i %04X:%08X %04X:%08X %i\n",num,soft,CS,pc, SS, ESP, abrt);
|
||||
if (eflags&VM_FLAG && IOPL!=3 && soft)
|
||||
|
|
@ -1728,15 +1774,7 @@ void pmodeint(int num, int soft)
|
|||
stack32=segdat3[3]&0x40;
|
||||
if (stack32) ESP=newsp;
|
||||
else SP=newsp;
|
||||
_ss.limit=segdat3[0]|((segdat3[3]&0xF)<<16);
|
||||
if (segdat3[3]&0x80) _ss.limit=(_ss.limit<<12)|0xFFF;
|
||||
if ((segdat3[2]>>8) & 4)
|
||||
_ss.limit = 0xffffffff;
|
||||
_ss.limitw=(segdat3[2]&0x200)?1:0;
|
||||
_ss.base=segdat3[1];
|
||||
_ss.base|=((segdat3[2]&0xFF)<<16);
|
||||
if (is386) _ss.base|=((segdat3[3]>>8)<<24);
|
||||
_ss.access=segdat3[2]>>8;
|
||||
do_seg_load(&_ss, segdat3);
|
||||
|
||||
#ifdef CS_ACCESSED
|
||||
cpl_override = 1;
|
||||
|
|
@ -1805,7 +1843,7 @@ void pmodeint(int num, int soft)
|
|||
x86gpf(NULL,seg&~3);
|
||||
return;
|
||||
}
|
||||
if (!stack_changed && ssegs) restore_stack();
|
||||
// if (!stack_changed && ssegs) restore_stack();
|
||||
if (type>0x800)
|
||||
{
|
||||
PUSHL(flags|(eflags<<16));
|
||||
|
|
@ -1830,12 +1868,7 @@ void pmodeint(int num, int soft)
|
|||
}
|
||||
CS=(seg&~3)|CPL;
|
||||
// pclog("New CS = %04X\n",CS);
|
||||
_cs.limit=segdat2[0]|((segdat2[3]&0xF)<<16);
|
||||
if (segdat2[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
|
||||
_cs.base=segdat2[1];
|
||||
_cs.base|=((segdat2[2]&0xFF)<<16);
|
||||
if (is386) _cs.base|=((segdat2[3]>>8)<<24);
|
||||
_cs.access=segdat2[2]>>8;
|
||||
do_seg_load(&_cs, segdat2);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
if (type>0x800) pc=segdat[0]|(segdat[3]<<16);
|
||||
else pc=segdat[0];
|
||||
|
|
@ -1943,6 +1976,8 @@ void pmodeiret(int is32)
|
|||
pc=newpc;
|
||||
_cs.base=seg<<4;
|
||||
_cs.limit=0xFFFF;
|
||||
_cs.limit_low = 0;
|
||||
_cs.limit_high = 0xffff;
|
||||
CS=seg;
|
||||
flags=(flags&0x3000)|(tempflags&0xCFD5)|2;
|
||||
return;
|
||||
|
|
@ -2011,9 +2046,13 @@ void pmodeiret(int is32)
|
|||
// pclog("Pop stack %04X:%04X\n",newss,newsp);
|
||||
eflags=tempflags>>16;
|
||||
loadseg(segs[0],&_es);
|
||||
do_seg_v86_init(&_es);
|
||||
loadseg(segs[1],&_ds);
|
||||
do_seg_v86_init(&_ds);
|
||||
loadseg(segs[2],&_fs);
|
||||
do_seg_v86_init(&_fs);
|
||||
loadseg(segs[3],&_gs);
|
||||
do_seg_v86_init(&_gs);
|
||||
|
||||
// pclog("V86 IRET %04X:%08X\n",SS,ESP);
|
||||
// output=3;
|
||||
|
|
@ -2021,12 +2060,15 @@ void pmodeiret(int is32)
|
|||
pc=newpc;
|
||||
_cs.base=seg<<4;
|
||||
_cs.limit=0xFFFF;
|
||||
_cs.limit_low = 0;
|
||||
_cs.limit_high = 0xffff;
|
||||
CS=seg;
|
||||
_cs.access=3<<5;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
ESP=newsp;
|
||||
loadseg(newss,&_ss);
|
||||
do_seg_v86_init(&_ss);
|
||||
use32=0;
|
||||
flags=(tempflags&0xFFD5)|2;
|
||||
|
||||
|
|
@ -2137,12 +2179,7 @@ void pmodeiret(int is32)
|
|||
{
|
||||
// pclog("Same level\n");
|
||||
CS=seg;
|
||||
_cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
|
||||
if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
|
||||
_cs.base=segdat[1];
|
||||
_cs.base|=((segdat[2]&0xFF)<<16);
|
||||
if (is386) _cs.base|=((segdat[3]>>8)<<24);
|
||||
_cs.access=segdat[2]>>8;
|
||||
do_seg_load(&_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
|
||||
|
|
@ -2240,15 +2277,7 @@ void pmodeiret(int is32)
|
|||
stack32=segdat2[3]&0x40;
|
||||
if (stack32) ESP=newsp;
|
||||
else SP=newsp;
|
||||
_ss.limit=segdat2[0]|((segdat2[3]&0xF)<<16);
|
||||
if (segdat2[3]&0x80) _ss.limit=(_ss.limit<<12)|0xFFF;
|
||||
if ((segdat2[2]>>8) & 4)
|
||||
_ss.limit = 0xffffffff;
|
||||
_ss.limitw=(segdat2[2]&0x200)?1:0;
|
||||
_ss.base=segdat2[1];
|
||||
_ss.base|=((segdat2[2]&0xFF)<<16);
|
||||
if (is386) _ss.base|=((segdat2[3]>>8)<<24);
|
||||
_ss.access=segdat2[2]>>8;
|
||||
do_seg_load(&_ss, segdat2);
|
||||
|
||||
#ifdef SEL_ACCESSED
|
||||
cpl_override = 1;
|
||||
|
|
@ -2264,35 +2293,14 @@ void pmodeiret(int is32)
|
|||
segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8));
|
||||
|
||||
CS=seg;
|
||||
_cs.limit=segdat[0]|((segdat[3]&0xF)<<16);
|
||||
if (segdat[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
|
||||
_cs.base=segdat[1];
|
||||
_cs.base|=((segdat[2]&0xFF)<<16);
|
||||
if (is386) _cs.base|=((segdat[3]>>8)<<24);
|
||||
_cs.access=segdat[2]>>8;
|
||||
do_seg_load(&_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
|
||||
if (CPL>((_ds.access>>5)&3))
|
||||
{
|
||||
_ds.seg=0;
|
||||
_ds.base=-1;
|
||||
}
|
||||
if (CPL>((_es.access>>5)&3))
|
||||
{
|
||||
_es.seg=0;
|
||||
_es.base=-1;
|
||||
}
|
||||
if (CPL>((_fs.access>>5)&3))
|
||||
{
|
||||
_fs.seg=0;
|
||||
_fs.base=-1;
|
||||
}
|
||||
if (CPL>((_gs.access>>5)&3))
|
||||
{
|
||||
_gs.seg=0;
|
||||
_gs.base=-1;
|
||||
}
|
||||
check_seg_valid(&_ds);
|
||||
check_seg_valid(&_es);
|
||||
check_seg_valid(&_fs);
|
||||
check_seg_valid(&_gs);
|
||||
}
|
||||
pc=newpc;
|
||||
flags=(flags&~flagmask)|(tempflags&flagmask&0xFFD5)|2;
|
||||
|
|
@ -2501,12 +2509,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
|||
|
||||
// if (output) pclog("new_cs %04X\n",new_cs);
|
||||
CS=new_cs;
|
||||
_cs.limit=segdat2[0]|((segdat2[3]&0xF)<<16);
|
||||
if (segdat2[3]&0x80) _cs.limit=(_cs.limit<<12)|0xFFF;
|
||||
_cs.base=segdat2[1];
|
||||
_cs.base|=((segdat2[2]&0xFF)<<16);
|
||||
if (is386) _cs.base|=((segdat2[3]>>8)<<24);
|
||||
_cs.access=segdat2[2]>>8;
|
||||
do_seg_load(&_cs, segdat2);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
use32=(segdat2[3]&0x40)?0x300:0;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue