Non-808x interpreters: fetch the next instruction after a CR0 paging bit toggle with the old CR0 paging bit value, fixes SCO Unix.

This commit is contained in:
OBattler
2024-08-27 02:34:59 +02:00
parent f9b80f1a10
commit 7c7cc921ee
8 changed files with 79 additions and 15 deletions

View File

@@ -9,6 +9,8 @@ opMOV_r_CRx_a16(uint32_t fetchdat)
switch (cpu_reg) {
case 0:
cpu_state.regs[cpu_rm].l = cr0;
if (cpu_flush_pending)
cpu_state.regs[cpu_rm].l ^= 0x80000000;
if (is486 || isibm486)
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
else {
@@ -49,6 +51,8 @@ opMOV_r_CRx_a32(uint32_t fetchdat)
switch (cpu_reg) {
case 0:
cpu_state.regs[cpu_rm].l = cr0;
if (cpu_flush_pending)
cpu_state.regs[cpu_rm].l ^= 0x80000000;
if (is486 || isibm486)
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
else {
@@ -180,12 +184,21 @@ opMOV_CRx_r_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
switch (cpu_reg) {
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x00000001)
flushmmucache();
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) {
if (is_p6 && !cpu_use_dynarec)
flushmmucache();
else
cpu_flush_pending = 1;
}
/* Make sure CPL = 0 when switching from real mode to protected mode. */
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
cpu_state.seg_cs.access &= 0x9f;
cr0 = cpu_state.regs[cpu_rm].l;
if (!is_p6 && !cpu_use_dynarec && ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000))
cr0 = (cr0 & 0x80000000) | (cpu_state.regs[cpu_rm].l & 0x7fffffff);
else
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))
@@ -237,12 +250,21 @@ opMOV_CRx_r_a32(uint32_t fetchdat)
fetch_ea_32(fetchdat);
switch (cpu_reg) {
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x00000001)
flushmmucache();
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) {
if (is_p6 && !cpu_use_dynarec)
flushmmucache();
else
cpu_flush_pending = 1;
}
/* Make sure CPL = 0 when switching from real mode to protected mode. */
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
cpu_state.seg_cs.access &= 0x9f;
cr0 = cpu_state.regs[cpu_rm].l;
if (!is_p6 && !cpu_use_dynarec && ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000))
cr0 = (cr0 & 0x80000000) | (cpu_state.regs[cpu_rm].l & 0x7fffffff);
else
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))