Fixes to task switching. Patch from Greatpsycho.
This commit is contained in:
parent
5d6c3fb9ea
commit
2ac22b03d5
1 changed files with 139 additions and 104 deletions
245
src/x86seg.c
245
src/x86seg.c
|
|
@ -1320,12 +1320,14 @@ void loadcscall(uint16_t seg)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case 0x900: /*386 Task gate*/
|
case 0x100: /*286 Task gate*/
|
||||||
// case 0xB00: /*386 Busy task gate*/
|
case 0x900: /*386 Task gate*/
|
||||||
// if (optype==JMP) pclog("Task switch!\n");
|
// pclog("Task gate\n");
|
||||||
// taskswitch386(seg,segdat);
|
cpu_state.pc=oxpc;
|
||||||
// return;
|
cpl_override=1;
|
||||||
|
taskswitch286(seg,segdat,segdat[2]&0x800);
|
||||||
|
cpl_override=0;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pclog("Bad CALL special descriptor %03X\n",segdat[2]&0xF00);
|
pclog("Bad CALL special descriptor %03X\n",segdat[2]&0xF00);
|
||||||
|
|
@ -1800,7 +1802,7 @@ void pmodeint(int num, int soft)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
addr = 2 + tr.base + (DPL2 * 8);
|
addr = 2 + tr.base + (DPL2 * 4);
|
||||||
newss=readmemw(0,addr+2);
|
newss=readmemw(0,addr+2);
|
||||||
newsp=readmemw(0,addr);
|
newsp=readmemw(0,addr);
|
||||||
}
|
}
|
||||||
|
|
@ -2421,6 +2423,11 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
//output=3;
|
//output=3;
|
||||||
base=segdat[1]|((segdat[2]&0xFF)<<16);
|
base=segdat[1]|((segdat[2]&0xFF)<<16);
|
||||||
limit=segdat[0];
|
limit=segdat[0];
|
||||||
|
if(is386)
|
||||||
|
{
|
||||||
|
base |= (segdat[3]>>8)<<24;
|
||||||
|
limit |= (segdat[3]&0xF)<<16;
|
||||||
|
}
|
||||||
// pclog("286 Task switch! %04X:%04X\n",CS,pc);
|
// pclog("286 Task switch! %04X:%04X\n",CS,pc);
|
||||||
/// pclog("TSS %04X base %08X limit %04X old TSS %04X %08X %i\n",seg,base,limit,tr.seg,tr.base,ins);
|
/// pclog("TSS %04X base %08X limit %04X old TSS %04X %08X %i\n",seg,base,limit,tr.seg,tr.base,ins);
|
||||||
// / pclog("%04X %04X %04X %04X\n",segdat[0],segdat[1],segdat[2],segdat[3]);
|
// / pclog("%04X %04X %04X %04X\n",segdat[0],segdat[1],segdat[2],segdat[3]);
|
||||||
|
|
@ -2428,41 +2435,11 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
if (is32)
|
if (is32)
|
||||||
{
|
{
|
||||||
// if (output) pclog("32-bit TSS\n");
|
// if (output) pclog("32-bit TSS\n");
|
||||||
|
if (limit < 103)
|
||||||
base |= (segdat[3]>>8)<<24;
|
|
||||||
limit |= (segdat[3]&0xF)<<16;
|
|
||||||
|
|
||||||
new_cr3=readmeml(base,0x1C);
|
|
||||||
new_pc=readmeml(base,0x20);
|
|
||||||
new_flags=readmeml(base,0x24);
|
|
||||||
|
|
||||||
new_eax=readmeml(base,0x28);
|
|
||||||
new_ecx=readmeml(base,0x2C);
|
|
||||||
new_edx=readmeml(base,0x30);
|
|
||||||
new_ebx=readmeml(base,0x34);
|
|
||||||
new_esp=readmeml(base,0x38);
|
|
||||||
new_ebp=readmeml(base,0x3C);
|
|
||||||
new_esi=readmeml(base,0x40);
|
|
||||||
new_edi=readmeml(base,0x44);
|
|
||||||
|
|
||||||
new_es=readmemw(base,0x48);
|
|
||||||
// if (output) pclog("Read CS from %08X\n",base+0x4C);
|
|
||||||
new_cs=readmemw(base,0x4C);
|
|
||||||
new_ss=readmemw(base,0x50);
|
|
||||||
new_ds=readmemw(base,0x54);
|
|
||||||
new_fs=readmemw(base,0x58);
|
|
||||||
new_gs=readmemw(base,0x5C);
|
|
||||||
new_ldt=readmemw(base,0x60);
|
|
||||||
|
|
||||||
if (cpu_state.abrt) return;
|
|
||||||
if (optype==JMP || optype==OPTYPE_INT)
|
|
||||||
{
|
{
|
||||||
if (tr.seg&4) tempw=readmemw(ldt.base,(tr.seg&~7)+4);
|
pclog("32-bit TSS %04X limit less than 103.\n", seg);
|
||||||
else tempw=readmemw(gdt.base,(tr.seg&~7)+4);
|
x86ts(NULL, seg);
|
||||||
if (cpu_state.abrt) return;
|
return;
|
||||||
tempw&=~0x200;
|
|
||||||
if (tr.seg&4) writememw(ldt.base,(tr.seg&~7)+4,tempw);
|
|
||||||
else writememw(gdt.base,(tr.seg&~7)+4,tempw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optype==IRET) flags&=~NT_FLAG;
|
if (optype==IRET) flags&=~NT_FLAG;
|
||||||
|
|
@ -2489,15 +2466,8 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
writememl(tr.base,0x54,DS);
|
writememl(tr.base,0x54,DS);
|
||||||
writememl(tr.base,0x58,FS);
|
writememl(tr.base,0x58,FS);
|
||||||
writememl(tr.base,0x5C,GS);
|
writememl(tr.base,0x5C,GS);
|
||||||
writememl(tr.base,0x60,ldt.seg);
|
|
||||||
|
|
||||||
if (optype==OPTYPE_INT)
|
if (optype==JMP || optype==CALL || optype==OPTYPE_INT)
|
||||||
{
|
|
||||||
writememl(base,0,tr.seg);
|
|
||||||
new_flags|=NT_FLAG;
|
|
||||||
}
|
|
||||||
if (cpu_state.abrt) return;
|
|
||||||
if (optype==JMP || optype==OPTYPE_INT)
|
|
||||||
{
|
{
|
||||||
if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4);
|
if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4);
|
||||||
else tempw=readmemw(gdt.base,(seg&~7)+4);
|
else tempw=readmemw(gdt.base,(seg&~7)+4);
|
||||||
|
|
@ -2506,7 +2476,49 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw);
|
if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw);
|
||||||
else writememw(gdt.base,(seg&~7)+4,tempw);
|
else writememw(gdt.base,(seg&~7)+4,tempw);
|
||||||
}
|
}
|
||||||
|
if (cpu_state.abrt) return;
|
||||||
|
|
||||||
|
new_cr3=readmeml(base,0x1C);
|
||||||
|
new_pc=readmeml(base,0x20);
|
||||||
|
new_flags=readmeml(base,0x24);
|
||||||
|
|
||||||
|
new_eax=readmeml(base,0x28);
|
||||||
|
new_ecx=readmeml(base,0x2C);
|
||||||
|
new_edx=readmeml(base,0x30);
|
||||||
|
new_ebx=readmeml(base,0x34);
|
||||||
|
new_esp=readmeml(base,0x38);
|
||||||
|
new_ebp=readmeml(base,0x3C);
|
||||||
|
new_esi=readmeml(base,0x40);
|
||||||
|
new_edi=readmeml(base,0x44);
|
||||||
|
|
||||||
|
new_es=readmemw(base,0x48);
|
||||||
|
// if (output) pclog("Read CS from %08X\n",base+0x4C);
|
||||||
|
new_cs=readmemw(base,0x4C);
|
||||||
|
new_ss=readmemw(base,0x50);
|
||||||
|
new_ds=readmemw(base,0x54);
|
||||||
|
new_fs=readmemw(base,0x58);
|
||||||
|
new_gs=readmemw(base,0x5C);
|
||||||
|
new_ldt=readmemw(base,0x60);
|
||||||
|
|
||||||
|
if (optype==JMP || optype==CALL || optype==OPTYPE_INT)
|
||||||
|
{
|
||||||
|
if (tr.seg&4) tempw=readmemw(ldt.base,(tr.seg&~7)+4);
|
||||||
|
else tempw=readmemw(gdt.base,(tr.seg&~7)+4);
|
||||||
|
if (cpu_state.abrt) return;
|
||||||
|
tempw&=~0x200;
|
||||||
|
if (tr.seg&4) writememw(ldt.base,(tr.seg&~7)+4,tempw);
|
||||||
|
else writememw(gdt.base,(tr.seg&~7)+4,tempw);
|
||||||
|
}
|
||||||
|
if (cpu_state.abrt) return;
|
||||||
|
|
||||||
|
if (optype==OPTYPE_INT || optype==CALL)
|
||||||
|
{
|
||||||
|
writememl(base,0,tr.seg);
|
||||||
|
new_flags|=NT_FLAG;
|
||||||
|
}
|
||||||
|
if (cpu_state.abrt) return;
|
||||||
|
|
||||||
|
cr0 |= 8;
|
||||||
|
|
||||||
|
|
||||||
cr3=new_cr3;
|
cr3=new_cr3;
|
||||||
|
|
@ -2545,7 +2557,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
if (!(new_cs&~3))
|
if (!(new_cs&~3))
|
||||||
{
|
{
|
||||||
pclog("TS loading null CS\n");
|
pclog("TS loading null CS\n");
|
||||||
x86gpf(NULL,0);
|
x86ts(NULL,0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addr=new_cs&~7;
|
addr=new_cs&~7;
|
||||||
|
|
@ -2554,7 +2566,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X %04X TS\n",new_cs,ldt.limit,addr);
|
pclog("Bigger than LDT limit %04X %04X %04X TS\n",new_cs,ldt.limit,addr);
|
||||||
x86gpf(NULL,0);
|
x86ts(NULL,new_cs&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addr+=ldt.base;
|
addr+=ldt.base;
|
||||||
|
|
@ -2564,7 +2576,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit);
|
pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit);
|
||||||
x86gpf(NULL,0);
|
x86ts(NULL,new_cs&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addr+=gdt.base;
|
addr+=gdt.base;
|
||||||
|
|
@ -2585,7 +2597,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
if ((new_cs&3) != DPL2)
|
if ((new_cs&3) != DPL2)
|
||||||
{
|
{
|
||||||
pclog("TS load CS non-conforming RPL != DPL");
|
pclog("TS load CS non-conforming RPL != DPL");
|
||||||
x86gpf(NULL,new_cs&~3);
|
x86ts(NULL,new_cs&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -2593,13 +2605,13 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
if ((new_cs&3) < DPL2)
|
if ((new_cs&3) < DPL2)
|
||||||
{
|
{
|
||||||
pclog("TS load CS non-conforming RPL < DPL");
|
pclog("TS load CS non-conforming RPL < DPL");
|
||||||
x86gpf(NULL,new_cs&~3);
|
x86ts(NULL,new_cs&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pclog("TS load CS not code segment\n");
|
pclog("TS load CS not code segment\n");
|
||||||
x86gpf(NULL,new_cs&~3);
|
x86ts(NULL,new_cs&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2635,35 +2647,11 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
{
|
{
|
||||||
// pclog("16-bit TSS\n");
|
// pclog("16-bit TSS\n");
|
||||||
// resetx86();
|
// resetx86();
|
||||||
|
if (limit < 43)
|
||||||
new_pc=readmemw(base,0x0E);
|
|
||||||
new_flags=readmemw(base,0x10);
|
|
||||||
|
|
||||||
new_eax=readmemw(base,0x12);
|
|
||||||
new_ecx=readmemw(base,0x14);
|
|
||||||
new_edx=readmemw(base,0x16);
|
|
||||||
new_ebx=readmemw(base,0x18);
|
|
||||||
new_esp=readmemw(base,0x1A);
|
|
||||||
new_ebp=readmemw(base,0x1C);
|
|
||||||
new_esi=readmemw(base,0x1E);
|
|
||||||
new_edi=readmemw(base,0x20);
|
|
||||||
|
|
||||||
new_es=readmemw(base,0x22);
|
|
||||||
// if (output) pclog("Read CS from %08X\n",base+0x4C);
|
|
||||||
new_cs=readmemw(base,0x24);
|
|
||||||
new_ss=readmemw(base,0x26);
|
|
||||||
new_ds=readmemw(base,0x28);
|
|
||||||
new_ldt=readmemw(base,0x2A);
|
|
||||||
|
|
||||||
if (cpu_state.abrt) return;
|
|
||||||
if (optype==JMP || optype==OPTYPE_INT)
|
|
||||||
{
|
{
|
||||||
if (tr.seg&4) tempw=readmemw(ldt.base,(tr.seg&~7)+4);
|
pclog("16-bit TSS %04X limit less than 43.\n", seg);
|
||||||
else tempw=readmemw(gdt.base,(tr.seg&~7)+4);
|
x86ts(NULL, seg);
|
||||||
if (cpu_state.abrt) return;
|
return;
|
||||||
tempw&=~0x200;
|
|
||||||
if (tr.seg&4) writememw(ldt.base,(tr.seg&~7)+4,tempw);
|
|
||||||
else writememw(gdt.base,(tr.seg&~7)+4,tempw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optype==IRET) flags&=~NT_FLAG;
|
if (optype==IRET) flags&=~NT_FLAG;
|
||||||
|
|
@ -2687,15 +2675,8 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
writememw(tr.base,0x24,CS);
|
writememw(tr.base,0x24,CS);
|
||||||
writememw(tr.base,0x26,SS);
|
writememw(tr.base,0x26,SS);
|
||||||
writememw(tr.base,0x28,DS);
|
writememw(tr.base,0x28,DS);
|
||||||
writememw(tr.base,0x2A,ldt.seg);
|
|
||||||
|
|
||||||
if (optype==OPTYPE_INT)
|
if (optype==JMP || optype==CALL || optype==OPTYPE_INT)
|
||||||
{
|
|
||||||
writememw(base,0,tr.seg);
|
|
||||||
new_flags|=NT_FLAG;
|
|
||||||
}
|
|
||||||
if (cpu_state.abrt) return;
|
|
||||||
if (optype==JMP || optype==OPTYPE_INT)
|
|
||||||
{
|
{
|
||||||
if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4);
|
if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4);
|
||||||
else tempw=readmemw(gdt.base,(seg&~7)+4);
|
else tempw=readmemw(gdt.base,(seg&~7)+4);
|
||||||
|
|
@ -2704,6 +2685,46 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw);
|
if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw);
|
||||||
else writememw(gdt.base,(seg&~7)+4,tempw);
|
else writememw(gdt.base,(seg&~7)+4,tempw);
|
||||||
}
|
}
|
||||||
|
if (cpu_state.abrt) return;
|
||||||
|
|
||||||
|
new_pc=readmemw(base,0x0E);
|
||||||
|
new_flags=readmemw(base,0x10);
|
||||||
|
|
||||||
|
new_eax=readmemw(base,0x12);
|
||||||
|
new_ecx=readmemw(base,0x14);
|
||||||
|
new_edx=readmemw(base,0x16);
|
||||||
|
new_ebx=readmemw(base,0x18);
|
||||||
|
new_esp=readmemw(base,0x1A);
|
||||||
|
new_ebp=readmemw(base,0x1C);
|
||||||
|
new_esi=readmemw(base,0x1E);
|
||||||
|
new_edi=readmemw(base,0x20);
|
||||||
|
|
||||||
|
new_es=readmemw(base,0x22);
|
||||||
|
// if (output) pclog("Read CS from %08X\n",base+0x4C);
|
||||||
|
new_cs=readmemw(base,0x24);
|
||||||
|
new_ss=readmemw(base,0x26);
|
||||||
|
new_ds=readmemw(base,0x28);
|
||||||
|
new_ldt=readmemw(base,0x2A);
|
||||||
|
|
||||||
|
if (optype==JMP || optype==CALL || optype==OPTYPE_INT)
|
||||||
|
{
|
||||||
|
if (tr.seg&4) tempw=readmemw(ldt.base,(tr.seg&~7)+4);
|
||||||
|
else tempw=readmemw(gdt.base,(tr.seg&~7)+4);
|
||||||
|
if (cpu_state.abrt) return;
|
||||||
|
tempw&=~0x200;
|
||||||
|
if (tr.seg&4) writememw(ldt.base,(tr.seg&~7)+4,tempw);
|
||||||
|
else writememw(gdt.base,(tr.seg&~7)+4,tempw);
|
||||||
|
}
|
||||||
|
if (cpu_state.abrt) return;
|
||||||
|
|
||||||
|
if (optype==OPTYPE_INT || optype==CALL)
|
||||||
|
{
|
||||||
|
writememw(base,0,tr.seg);
|
||||||
|
new_flags|=NT_FLAG;
|
||||||
|
}
|
||||||
|
if (cpu_state.abrt) return;
|
||||||
|
|
||||||
|
msw |= 8;
|
||||||
|
|
||||||
cpu_state.pc=new_pc;
|
cpu_state.pc=new_pc;
|
||||||
// if (output) pclog("New pc %08X\n",new_pc);
|
// if (output) pclog("New pc %08X\n",new_pc);
|
||||||
|
|
@ -2716,13 +2737,22 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
// if (output) pclog("Load from %08X %08X\n",templ,gdt.base);
|
// if (output) pclog("Load from %08X %08X\n",templ,gdt.base);
|
||||||
ldt.limit=readmemw(0,templ);
|
ldt.limit=readmemw(0,templ);
|
||||||
ldt.base=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16);
|
ldt.base=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16);
|
||||||
|
if (is386)
|
||||||
|
{
|
||||||
|
if (readmemb(0,templ+6)&0x80)
|
||||||
|
{
|
||||||
|
ldt.limit<<=12;
|
||||||
|
ldt.limit|=0xFFF;
|
||||||
|
}
|
||||||
|
ldt.base|=(readmemb(0,templ+7)<<24);
|
||||||
|
}
|
||||||
// if (output) pclog("Limit %04X Base %08X\n",ldt.limit,ldt.base);
|
// if (output) pclog("Limit %04X Base %08X\n",ldt.limit,ldt.base);
|
||||||
|
|
||||||
|
|
||||||
if (!(new_cs&~3))
|
if (!(new_cs&~3))
|
||||||
{
|
{
|
||||||
pclog("TS loading null CS\n");
|
pclog("TS loading null CS\n");
|
||||||
x86gpf(NULL,0);
|
x86ts(NULL,0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addr=new_cs&~7;
|
addr=new_cs&~7;
|
||||||
|
|
@ -2731,7 +2761,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X %04X TS\n",new_cs,ldt.limit,addr);
|
pclog("Bigger than LDT limit %04X %04X %04X TS\n",new_cs,ldt.limit,addr);
|
||||||
x86gpf(NULL,0);
|
x86ts(NULL,new_cs&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addr+=ldt.base;
|
addr+=ldt.base;
|
||||||
|
|
@ -2741,7 +2771,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit);
|
pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit);
|
||||||
x86gpf(NULL,0);
|
x86ts(NULL,new_cs&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addr+=gdt.base;
|
addr+=gdt.base;
|
||||||
|
|
@ -2762,7 +2792,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
if ((new_cs&3) != DPL2)
|
if ((new_cs&3) != DPL2)
|
||||||
{
|
{
|
||||||
pclog("TS load CS non-conforming RPL != DPL");
|
pclog("TS load CS non-conforming RPL != DPL");
|
||||||
x86gpf(NULL,new_cs&~3);
|
x86ts(NULL,new_cs&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -2770,13 +2800,13 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
if ((new_cs&3) < DPL2)
|
if ((new_cs&3) < DPL2)
|
||||||
{
|
{
|
||||||
pclog("TS load CS non-conforming RPL < DPL");
|
pclog("TS load CS non-conforming RPL < DPL");
|
||||||
x86gpf(NULL,new_cs&~3);
|
x86ts(NULL,new_cs&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pclog("TS load CS not code segment\n");
|
pclog("TS load CS not code segment\n");
|
||||||
x86gpf(NULL,new_cs&~3);
|
x86ts(NULL,new_cs&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2786,14 +2816,14 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||||
set_use32(0);
|
set_use32(0);
|
||||||
|
|
||||||
AX=new_eax;
|
EAX=new_eax | 0xFFFF0000;
|
||||||
CX=new_ecx;
|
ECX=new_ecx | 0xFFFF0000;
|
||||||
DX=new_edx;
|
EDX=new_edx | 0xFFFF0000;
|
||||||
BX=new_ebx;
|
EBX=new_ebx | 0xFFFF0000;
|
||||||
SP=new_esp;
|
ESP=new_esp | 0xFFFF0000;
|
||||||
BP=new_ebp;
|
EBP=new_ebp | 0xFFFF0000;
|
||||||
SI=new_esi;
|
ESI=new_esi | 0xFFFF0000;
|
||||||
DI=new_edi;
|
EDI=new_edi | 0xFFFF0000;
|
||||||
|
|
||||||
if (output) pclog("Load ES %04X\n",new_es);
|
if (output) pclog("Load ES %04X\n",new_es);
|
||||||
loadseg(new_es,&_es);
|
loadseg(new_es,&_es);
|
||||||
|
|
@ -2801,6 +2831,11 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||||
loadseg(new_ss,&_ss);
|
loadseg(new_ss,&_ss);
|
||||||
if (output) pclog("Load DS %04X\n",new_ds);
|
if (output) pclog("Load DS %04X\n",new_ds);
|
||||||
loadseg(new_ds,&_ds);
|
loadseg(new_ds,&_ds);
|
||||||
|
if (is386)
|
||||||
|
{
|
||||||
|
loadseg(0,&_fs);
|
||||||
|
loadseg(0,&_gs);
|
||||||
|
}
|
||||||
|
|
||||||
if (output) pclog("Resuming at %04X:%08X\n",CS,cpu_state.pc);
|
if (output) pclog("Resuming at %04X:%08X\n",CS,cpu_state.pc);
|
||||||
//exit(-1);
|
//exit(-1);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue