Merged the two copies of x86seg.c, finishing the mergers started in February.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -108,9 +108,7 @@ static void seg_reset(x86seg *s)
|
||||
s->limit_high = 0xffff;
|
||||
if (s == &cpu_state.seg_cs)
|
||||
{
|
||||
// TODO - When the PC is reset, initialization of the CS descriptor must be like the annotated line below.
|
||||
s->base = AT ? (cpu_16bitbus ? 0xFF0000 : 0xFFFF0000) : 0xFFFF0;
|
||||
// s->base = AT ? 0xF0000 : 0xFFFF0;
|
||||
s->seg = AT ? 0xF000 : 0xFFFF;
|
||||
}
|
||||
else
|
||||
@@ -118,7 +116,6 @@ static void seg_reset(x86seg *s)
|
||||
s->base = 0;
|
||||
s->seg = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void x86seg_reset()
|
||||
@@ -133,7 +130,9 @@ void x86seg_reset()
|
||||
|
||||
void x86_doabrt(int x86_abrt)
|
||||
{
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
CS = oldcs;
|
||||
#endif
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
cpu_state.seg_cs.access = (oldcpl << 5) | 0x80;
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
@@ -160,7 +159,9 @@ void x86_doabrt(int x86_abrt)
|
||||
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oxpc=cpu_state.pc;
|
||||
#endif
|
||||
cpu_state.pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
return;
|
||||
@@ -331,7 +332,11 @@ static void check_seg_valid(x86seg *s)
|
||||
loadseg(0, s);
|
||||
}
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
int loadseg(uint16_t seg, x86seg *s)
|
||||
#else
|
||||
void loadseg(uint16_t seg, x86seg *s)
|
||||
#endif
|
||||
{
|
||||
uint16_t segdat[4];
|
||||
uint32_t addr;
|
||||
@@ -344,7 +349,11 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
if (s==&cpu_state.seg_ss)
|
||||
{
|
||||
x86ss(NULL,0);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
s->seg = 0;
|
||||
s->access = 0x80;
|
||||
@@ -352,32 +361,36 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
s->base=-1;
|
||||
if (s == &cpu_state.seg_ds)
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 0;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
addr=seg&~7;
|
||||
if (seg&4)
|
||||
{
|
||||
#if 0
|
||||
if (addr>=ldt.limit)
|
||||
#else
|
||||
if ((addr+7)>ldt.limit)
|
||||
#endif
|
||||
{
|
||||
x86gpf("loadseg(): Bigger than LDT limit",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
addr+=ldt.base;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
if (addr>=gdt.limit)
|
||||
#else
|
||||
if ((addr+7)>gdt.limit)
|
||||
#endif
|
||||
{
|
||||
x86gpf("loadseg(): Bigger than GDT limit",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
addr+=gdt.base;
|
||||
}
|
||||
@@ -385,24 +398,40 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
segdat[0]=readmemw(0,addr);
|
||||
segdat[1]=readmemw(0,addr+2);
|
||||
segdat[2]=readmemw(0,addr+4);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return 1;
|
||||
#else
|
||||
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return;
|
||||
#endif
|
||||
dpl=(segdat[2]>>13)&3;
|
||||
if (s==&cpu_state.seg_ss)
|
||||
{
|
||||
if (!(seg&~3))
|
||||
{
|
||||
x86gpf("loadseg(): Stack segment is zero",seg&~3);
|
||||
x86gpf("loadseg(): Zero stack segment",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
if ((seg&3)!=CPL)
|
||||
{
|
||||
x86gpf("loadseg(): Stack segment RPL != CPL",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
if (dpl!=CPL)
|
||||
{
|
||||
x86gpf("loadseg(): Stack segment DPL != CPL",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
switch ((segdat[2]>>8)&0x1F)
|
||||
{
|
||||
@@ -410,12 +439,20 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
break;
|
||||
default:
|
||||
x86gpf("loadseg(): Unknown stack segment type",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
if (!(segdat[2]&0x8000))
|
||||
{
|
||||
x86ss(NULL,seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
set_stack32((segdat[3] & 0x40) ? 1 : 0);
|
||||
}
|
||||
@@ -430,33 +467,49 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
case 0x1A: case 0x1B: /*Readable non-conforming code*/
|
||||
if ((seg&3)>dpl)
|
||||
{
|
||||
x86gpf("loadseg(): Normal segment is zero",seg&~3);
|
||||
x86gpf("loadseg(): Normal segment RPL > DPL",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
if ((CPL)>dpl)
|
||||
{
|
||||
x86gpf("loadseg(): Normal segment DPL < CPL",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 0x1E: case 0x1F: /*Readable conforming code*/
|
||||
break;
|
||||
default:
|
||||
x86gpf("loadseg(): Unknown normal segment type",seg&~3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!(segdat[2] & 0x8000))
|
||||
{
|
||||
x86np("Load data seg not present", seg & 0xfffc);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 1;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
s->seg = seg;
|
||||
do_seg_load(s, segdat);
|
||||
|
||||
#ifndef CS_ACCESSED
|
||||
if (s != &cpu_state.seg_cs)
|
||||
if (s != &_cs)
|
||||
{
|
||||
#endif
|
||||
#ifdef SEL_ACCESSED
|
||||
@@ -506,6 +559,10 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
else
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
|
||||
}
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return cpu_state.abrt;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define DPL ((segdat[2]>>13)&3)
|
||||
@@ -521,7 +578,7 @@ void loadcs(uint16_t seg)
|
||||
{
|
||||
if (!(seg&~3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
x86gpf("loadcs(): Protected mode selector is zero",0);
|
||||
return;
|
||||
}
|
||||
addr=seg&~7;
|
||||
@@ -578,6 +635,9 @@ void loadcs(uint16_t seg)
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
|
||||
#ifdef CS_ACCESSED
|
||||
cpl_override = 1;
|
||||
@@ -589,7 +649,7 @@ void loadcs(uint16_t seg)
|
||||
{
|
||||
if (!(segdat[2]&0x8000))
|
||||
{
|
||||
x86np("Load CS system seg not present", seg & 0xfffc);
|
||||
x86np("Load CS system seg not present\n", seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
switch (segdat[2]&0xF00)
|
||||
@@ -611,6 +671,9 @@ void loadcs(uint16_t seg)
|
||||
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -690,6 +753,9 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
cycles -= timing_jmp_pm;
|
||||
}
|
||||
else /*System segment*/
|
||||
@@ -708,7 +774,9 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
case 0xC00:
|
||||
cgate32=(type&0x800);
|
||||
cgate16=!cgate32;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oldcs=CS;
|
||||
#endif
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
if (DPL < CPL)
|
||||
{
|
||||
@@ -720,16 +788,6 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
x86gpf("loadcsjmp(): Call gate DPL< RPL",seg&~3);
|
||||
return;
|
||||
}
|
||||
if (DPL < CPL)
|
||||
{
|
||||
x86gpf("loadcsjmp(): ex DPL < CPL",seg&~3);
|
||||
return;
|
||||
}
|
||||
if ((DPL < (seg&3)))
|
||||
{
|
||||
x86gpf("loadcsjmp(): ex (DPL < (seg&3))",seg&~3);
|
||||
return;
|
||||
}
|
||||
if (!(segdat[2]&0x8000))
|
||||
{
|
||||
x86np("Load CS JMP call gate not present\n", seg & 0xfffc);
|
||||
@@ -792,7 +850,9 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
CS=seg2;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat[3]&0x40);
|
||||
cpu_state.pc=newpc;
|
||||
|
||||
@@ -838,6 +898,9 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
cycles -= timing_jmp_rm;
|
||||
}
|
||||
}
|
||||
@@ -907,7 +970,11 @@ uint32_t POPL()
|
||||
return templ;
|
||||
}
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
void loadcscall(uint16_t seg, uint32_t old_pc)
|
||||
#else
|
||||
void loadcscall(uint16_t seg)
|
||||
#endif
|
||||
{
|
||||
uint16_t seg2;
|
||||
uint16_t segdat[4],segdat2[4],newss;
|
||||
@@ -999,7 +1066,9 @@ void loadcscall(uint16_t seg)
|
||||
CS=seg;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
#ifdef ENABLE_X86SEG_LOG
|
||||
x86seg_log("Complete\n");
|
||||
#endif
|
||||
@@ -1016,7 +1085,9 @@ void loadcscall(uint16_t seg)
|
||||
x86seg_log("Callgate %08X\n", cpu_state.pc);
|
||||
cgate32=(type&0x800);
|
||||
cgate16=!cgate32;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oldcs=CS;
|
||||
#endif
|
||||
count=segdat[2]&31;
|
||||
if (DPL < CPL)
|
||||
{
|
||||
@@ -1030,7 +1101,6 @@ void loadcscall(uint16_t seg)
|
||||
}
|
||||
if (!(segdat[2]&0x8000))
|
||||
{
|
||||
x86seg_log("Call gate not present %04X\n",seg);
|
||||
x86np("Call gate not present\n", seg & 0xfffc);
|
||||
return;
|
||||
}
|
||||
@@ -1082,12 +1152,14 @@ void loadcscall(uint16_t seg)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch (segdat[2]&0x1F00)
|
||||
{
|
||||
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/
|
||||
if (DPL < CPL)
|
||||
{
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
uint16_t oldcs = CS;
|
||||
#endif
|
||||
oaddr = addr;
|
||||
/*Load new stack*/
|
||||
oldss=SS;
|
||||
@@ -1116,11 +1188,7 @@ void loadcscall(uint16_t seg)
|
||||
addr=newss&~7;
|
||||
if (newss&4)
|
||||
{
|
||||
#if 0
|
||||
if (addr>=ldt.limit)
|
||||
#else
|
||||
if ((addr+7)>ldt.limit)
|
||||
#endif
|
||||
{
|
||||
x86abort("Bigger than LDT limit %04X %08X %04X CSC SS\n",newss,addr,ldt.limit);
|
||||
x86ts(NULL,newss&~3);
|
||||
@@ -1130,11 +1198,7 @@ void loadcscall(uint16_t seg)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
if (addr>=gdt.limit)
|
||||
#else
|
||||
if ((addr+7)>gdt.limit)
|
||||
#endif
|
||||
{
|
||||
x86abort("Bigger than GDT limit %04X %04X CSC\n",newss,gdt.limit);
|
||||
x86ts(NULL,newss&~3);
|
||||
@@ -1183,7 +1247,9 @@ void loadcscall(uint16_t seg)
|
||||
CS=seg2;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat[3]&0x40);
|
||||
cpu_state.pc=newpc;
|
||||
|
||||
@@ -1204,6 +1270,9 @@ void loadcscall(uint16_t seg)
|
||||
{
|
||||
SS = oldss;
|
||||
ESP = oldsp2;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
CS = oldcs;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (count)
|
||||
@@ -1216,6 +1285,9 @@ void loadcscall(uint16_t seg)
|
||||
{
|
||||
SS = oldss;
|
||||
ESP = oldsp2;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
CS = oldcs;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1231,6 +1303,9 @@ void loadcscall(uint16_t seg)
|
||||
{
|
||||
SS = oldss;
|
||||
ESP = oldsp2;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
CS = oldcs;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
x86seg_log("Write SP to %04X:%04X\n",SS,SP);
|
||||
@@ -1246,6 +1321,9 @@ void loadcscall(uint16_t seg)
|
||||
{
|
||||
SS = oldss;
|
||||
ESP = oldsp2;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
CS = oldcs;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1264,6 +1342,9 @@ void loadcscall(uint16_t seg)
|
||||
CS=seg2;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat[3]&0x40);
|
||||
cpu_state.pc=newpc;
|
||||
|
||||
@@ -1283,7 +1364,11 @@ void loadcscall(uint16_t seg)
|
||||
|
||||
case 0x100: /*286 Task gate*/
|
||||
case 0x900: /*386 Task gate*/
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.pc = old_pc;
|
||||
#else
|
||||
cpu_state.pc = oxpc;
|
||||
#endif
|
||||
cpl_override=1;
|
||||
taskswitch286(seg,segdat,segdat[2]&0x800);
|
||||
cpl_override=0;
|
||||
@@ -1306,6 +1391,9 @@ void loadcscall(uint16_t seg)
|
||||
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1417,6 +1505,9 @@ void pmoderetf(int is32, uint16_t off)
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat[3] & 0x40);
|
||||
|
||||
cycles -= timing_retf_pm;
|
||||
@@ -1547,6 +1638,9 @@ void pmoderetf(int is32, uint16_t off)
|
||||
CS=seg;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat[3] & 0x40);
|
||||
|
||||
if (stack32) ESP+=off;
|
||||
@@ -1560,11 +1654,6 @@ void pmoderetf(int is32, uint16_t off)
|
||||
}
|
||||
}
|
||||
|
||||
void restore_stack()
|
||||
{
|
||||
ss=oldss; cpu_state.seg_ss.limit=oldsslimit;
|
||||
}
|
||||
|
||||
void pmodeint(int num, int soft)
|
||||
{
|
||||
uint16_t segdat[4],segdat2[4],segdat3[4];
|
||||
@@ -1607,7 +1696,11 @@ void pmodeint(int num, int soft)
|
||||
segdat[0]=readmemw(0,addr);
|
||||
segdat[1]=readmemw(2,addr);
|
||||
segdat[2]=readmemw(4,addr);
|
||||
segdat[3]=readmemw(6,addr); cpl_override=0; if (cpu_state.abrt) { /* x86seg_log("Abrt reading from %08X\n",addr); */ return; }
|
||||
segdat[3]=readmemw(6,addr); cpl_override=0;
|
||||
if (cpu_state.abrt) {
|
||||
x86seg_log("Abrt reading from %08X\n",addr);
|
||||
return;
|
||||
}
|
||||
oaddr = addr;
|
||||
|
||||
x86seg_log("Addr %08X seg %04X %04X %04X %04X\n",addr,segdat[0],segdat[1],segdat[2],segdat[3]);
|
||||
@@ -1826,6 +1919,9 @@ void pmodeint(int num, int soft)
|
||||
CS = (seg & ~3) | new_cpl;
|
||||
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | (new_cpl << 5);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
if (type>0x800) cpu_state.pc=segdat[0]|(segdat[3]<<16);
|
||||
else cpu_state.pc=segdat[0];
|
||||
set_use32(segdat2[3]&0x40);
|
||||
@@ -1839,9 +1935,7 @@ void pmodeint(int num, int soft)
|
||||
cpu_state.eflags &= ~VM_FLAG;
|
||||
cpu_cur_status &= ~CPU_STATUS_V86;
|
||||
if (!(type&0x100))
|
||||
{
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
}
|
||||
cpu_state.flags &= ~(T_FLAG|NT_FLAG);
|
||||
cycles -= timing_int_pm;
|
||||
break;
|
||||
@@ -1898,7 +1992,7 @@ void pmodeiret(int is32)
|
||||
uint32_t newpc;
|
||||
uint16_t segdat[4],segdat2[4];
|
||||
uint16_t segs[4];
|
||||
uint16_t seg;
|
||||
uint16_t seg = 0;
|
||||
uint32_t addr, oaddr;
|
||||
uint32_t oldsp=ESP;
|
||||
if (is386 && (cpu_state.eflags & VM_FLAG))
|
||||
@@ -1908,7 +2002,9 @@ void pmodeiret(int is32)
|
||||
x86gpf(NULL,0);
|
||||
return;
|
||||
}
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oxpc=cpu_state.pc;
|
||||
#endif
|
||||
if (is32)
|
||||
{
|
||||
newpc=POPL();
|
||||
@@ -1962,7 +2058,9 @@ void pmodeiret(int is32)
|
||||
cpl_override=0;
|
||||
return;
|
||||
}
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oxpc=cpu_state.pc;
|
||||
#endif
|
||||
flagmask=0xFFFF;
|
||||
if (CPL) flagmask&=~0x3000;
|
||||
if (IOPL<CPL) flagmask&=~0x200;
|
||||
@@ -1991,7 +2089,7 @@ void pmodeiret(int is32)
|
||||
loadseg(segs[3],&cpu_state.seg_gs);
|
||||
do_seg_v86_init(&cpu_state.seg_gs);
|
||||
|
||||
cpu_state.pc=newpc;
|
||||
cpu_state.pc = newpc & 0xffff;
|
||||
cpu_state.seg_cs.base=seg<<4;
|
||||
cpu_state.seg_cs.limit=0xFFFF;
|
||||
cpu_state.seg_cs.limit_low = 0;
|
||||
@@ -2000,6 +2098,9 @@ void pmodeiret(int is32)
|
||||
cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
|
||||
ESP=newsp;
|
||||
loadseg(newss,&cpu_state.seg_ss);
|
||||
@@ -2093,6 +2194,9 @@ void pmodeiret(int is32)
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat[3]&0x40);
|
||||
|
||||
#ifdef CS_ACCESSED
|
||||
@@ -2198,6 +2302,9 @@ void pmodeiret(int is32)
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat[3] & 0x40);
|
||||
|
||||
check_seg_valid(&cpu_state.seg_ds);
|
||||
@@ -2405,6 +2512,9 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
CS=new_cs;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat2);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(segdat2[3] & 0x40);
|
||||
cpu_cur_status &= ~CPU_STATUS_V86;
|
||||
}
|
||||
@@ -2443,7 +2553,8 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
}
|
||||
if (cpu_state.abrt) return;
|
||||
|
||||
if (optype==IRET) cpu_state.flags&=~NT_FLAG;
|
||||
if (optype == IRET)
|
||||
cpu_state.flags &= ~NT_FLAG;
|
||||
|
||||
cpu_386_flags_rebuild();
|
||||
writememw(tr.base,0x0E,cpu_state.pc);
|
||||
@@ -2578,6 +2689,9 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
CS=new_cs;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat2);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
oldcpl = CPL;
|
||||
#endif
|
||||
set_use32(0);
|
||||
|
||||
EAX=new_eax | 0xFFFF0000;
|
||||
Reference in New Issue
Block a user