Implemented IDT limit checking on real mode interrupts. Patch from Greatpsycho.

This commit is contained in:
SarahW 2018-01-08 20:54:19 +00:00
commit f336dd9589

View file

@ -198,27 +198,43 @@ void x86_int(int num)
} }
else else
{ {
if (stack32) addr = (num << 2) + idt.base;
if ((num << 2) + 3 > idt.limit)
{ {
writememw(ss,ESP-2,flags); if (idt.limit < 35)
writememw(ss,ESP-4,CS); {
writememw(ss,ESP-6,cpu_state.pc); cpu_state.abrt = 0;
ESP-=6; softresetx86();
cpu_set_edx();
pclog("Triple fault in real mode - reset\n");
}
else
x86_int(8);
} }
else else
{ {
writememw(ss,((SP-2)&0xFFFF),flags); if (stack32)
writememw(ss,((SP-4)&0xFFFF),CS); {
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); writememw(ss,ESP-2,flags);
SP-=6; writememw(ss,ESP-4,CS);
} writememw(ss,ESP-6,cpu_state.pc);
addr = (num << 2) + idt.base; ESP-=6;
}
else
{
writememw(ss,((SP-2)&0xFFFF),flags);
writememw(ss,((SP-4)&0xFFFF),CS);
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc);
SP-=6;
}
flags&=~I_FLAG; flags&=~I_FLAG;
flags&=~T_FLAG; flags&=~T_FLAG;
oxpc=cpu_state.pc; oxpc=cpu_state.pc;
cpu_state.pc=readmemw(0,addr); cpu_state.pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2)); loadcs(readmemw(0,addr+2));
}
} }
cycles-=70; cycles-=70;
CPU_BLOCK_END(); CPU_BLOCK_END();
@ -237,28 +253,36 @@ void x86_int_sw(int num)
} }
else else
{ {
if (stack32) addr = (num << 2) + idt.base;
if ((num << 2) + 3 > idt.limit)
{ {
writememw(ss,ESP-2,flags); x86_int(13);
writememw(ss,ESP-4,CS);
writememw(ss,ESP-6,cpu_state.pc);
ESP-=6;
} }
else else
{ {
writememw(ss,((SP-2)&0xFFFF),flags); if (stack32)
writememw(ss,((SP-4)&0xFFFF),CS); {
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); writememw(ss,ESP-2,flags);
SP-=6; writememw(ss,ESP-4,CS);
} writememw(ss,ESP-6,cpu_state.pc);
addr = (num << 2) + idt.base; ESP-=6;
}
else
{
writememw(ss,((SP-2)&0xFFFF),flags);
writememw(ss,((SP-4)&0xFFFF),CS);
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc);
SP-=6;
}
flags&=~I_FLAG; flags&=~I_FLAG;
flags&=~T_FLAG; flags&=~T_FLAG;
oxpc=cpu_state.pc; oxpc=cpu_state.pc;
cpu_state.pc=readmemw(0,addr); cpu_state.pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2)); loadcs(readmemw(0,addr+2));
cycles -= timing_int_rm; cycles -= timing_int_rm;
}
} }
trap = 0; trap = 0;
CPU_BLOCK_END(); CPU_BLOCK_END();