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

@@ -304,6 +304,14 @@ exec386_2386(int32_t cycs)
cpu_state.pc &= 0xffff;
#endif
if (cpu_flush_pending == 1)
cpu_flush_pending++;
else if (cpu_flush_pending == 2) {
cpu_flush_pending = 0;
cr0 ^= 0x80000000;
flushmmucache();
}
if (cpu_end_block_after_ins)
cpu_end_block_after_ins--;

View File

@@ -933,6 +933,14 @@ exec386(int32_t cycs)
x386_dynarec_log("[%04X:%08X] ABRT\n", CS, cpu_state.pc);
#endif
if (cpu_flush_pending == 1)
cpu_flush_pending++;
else if (cpu_flush_pending == 2) {
cpu_flush_pending = 0;
cr0 ^= 0x80000000;
flushmmucache();
}
#ifndef USE_NEW_DYNAREC
if (!use32)
cpu_state.pc &= 0xffff;

View File

@@ -182,6 +182,7 @@ int cpu_rom_prefetch_cycles;
int cpu_waitstates;
int cpu_cache_int_enabled;
int cpu_cache_ext_enabled;
int cpu_flush_pending;
int cpu_isa_speed;
int cpu_pci_speed;
int cpu_isa_pci_div;

View File

@@ -616,6 +616,7 @@ extern int cpu_prefetch_width;
extern int cpu_mem_prefetch_cycles;
extern int cpu_rom_prefetch_cycles;
extern int cpu_waitstates;
extern int cpu_flush_pending;
extern int cpu_cache_int_enabled;
extern int cpu_cache_ext_enabled;
extern int cpu_isa_speed;

View File

@@ -277,7 +277,7 @@ reset_common(int hard)
cr0 = 0;
if (is386 && !is486 && (fpu_type == FPU_387))
cr0 |= 0x10;
cpu_cache_int_enabled = 0;
cpu_cache_int_enabled = 0;
cpu_update_waitstates();
cr4 = 0;
cpu_state.eflags = 0;
@@ -325,6 +325,7 @@ reset_common(int hard)
if (hard)
codegen_reset();
#endif
cpu_flush_pending = 0;
if (!hard)
flushmmucache();
x86_was_reset = 1;

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))

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 {
@@ -176,12 +180,17 @@ 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)
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 ((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))
@@ -233,12 +242,17 @@ 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)
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 ((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))

View File

@@ -431,12 +431,21 @@ op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
if (is386 && is32 && (cpu_mod == 3)) {
if (is486 || isibm486)
seteaw(cr0);
else if (is386 && !cpu_16bitbus)
seteaw(cr0 | /* 0x7FFFFF00 */ 0x7FFFFFE0);
else
seteaw(cr0 | 0x7FFFFFF0);
if (cpu_flush_pending) {
if (is486 || isibm486)
seteaw(cr0 ^ 0x80000000);
else if (is386 && !cpu_16bitbus)
seteaw((cr0 ^ 0x80000000) | /* 0x7FFFFF00 */ 0x7FFFFFE0);
else
seteaw((cr0 ^ 0x80000000) | 0x7FFFFFF0);
} else {
if (is486 || isibm486)
seteaw(cr0);
else if (is386 && !cpu_16bitbus)
seteaw(cr0 | /* 0x7FFFFF00 */ 0x7FFFFFE0);
else
seteaw(cr0 | 0x7FFFFFF0);
}
} else {
if (is486 || isibm486)
seteaw(msw);