diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index bf8b31600..590d6f5c7 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -937,8 +937,7 @@ exec386(int32_t cycs) cpu_flush_pending++; else if (cpu_flush_pending == 2) { cpu_flush_pending = 0; - cr0 ^= 0x80000000; - flushmmucache(); + flushmmucache_pc(); } #ifndef USE_NEW_DYNAREC diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index c8ac9ab63..f4241feb1 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -189,16 +189,15 @@ opMOV_CRx_r_a16(uint32_t fetchdat) else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) { if (is_p6 || cpu_use_dynarec) flushmmucache(); - else + else { + flushmmucache_nopc(); 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; - 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; + cr0 = cpu_state.regs[cpu_rm].l; if (cpu_16bitbus) cr0 |= 0x10; if (!(cr0 & 0x80000000)) @@ -255,16 +254,15 @@ opMOV_CRx_r_a32(uint32_t fetchdat) else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) { if (is_p6 || cpu_use_dynarec) flushmmucache(); - else + else { + flushmmucache_nopc(); 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; - 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; + cr0 = cpu_state.regs[cpu_rm].l; if (cpu_16bitbus) cr0 |= 0x10; if (!(cr0 & 0x80000000)) diff --git a/src/cpu/x86_ops_mov_ctrl_2386.h b/src/cpu/x86_ops_mov_ctrl_2386.h index 6b6db8c94..03a18caa7 100644 --- a/src/cpu/x86_ops_mov_ctrl_2386.h +++ b/src/cpu/x86_ops_mov_ctrl_2386.h @@ -182,15 +182,14 @@ opMOV_CRx_r_a16(uint32_t fetchdat) case 0: if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x00000001) flushmmucache(); - else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) + else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) { + flushmmucache_nopc(); 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; - 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; + cr0 = cpu_state.regs[cpu_rm].l; if (cpu_16bitbus) cr0 |= 0x10; if (!(cr0 & 0x80000000)) @@ -244,15 +243,14 @@ opMOV_CRx_r_a32(uint32_t fetchdat) case 0: if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x00000001) flushmmucache(); - else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) + else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) { + flushmmucache_nopc(); 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; - 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; + cr0 = cpu_state.regs[cpu_rm].l; if (cpu_16bitbus) cr0 |= 0x10; if (!(cr0 & 0x80000000)) diff --git a/src/cpu/x86_ops_pmode.h b/src/cpu/x86_ops_pmode.h index b68aaffbd..4f32b0e37 100644 --- a/src/cpu/x86_ops_pmode.h +++ b/src/cpu/x86_ops_pmode.h @@ -431,21 +431,12 @@ 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 (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); - } + if (is486 || isibm486) + seteaw(cr0); + else if (is386 && !cpu_16bitbus) + seteaw(cr0 | /* 0x7FFFFF00 */ 0x7FFFFFE0); + else + seteaw(cr0 | 0x7FFFFFF0); } else { if (is486 || isibm486) seteaw(msw); diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 3c0e0aee0..ad89e4b4f 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -446,6 +446,7 @@ extern void mem_flush_write_page(uint32_t addr, uint32_t virt); extern void mem_reset_page_blocks(void); extern void flushmmucache(void); +extern void flushmmucache_pc(void); extern void flushmmucache_nopc(void); extern void mem_debug_check_addr(uint32_t addr, int write); diff --git a/src/mem/mem.c b/src/mem/mem.c index ae6e4ae00..0b038d640 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -225,6 +225,19 @@ flushmmucache(void) #endif } +void +flushmmucache_pc(void) +{ + mmuflush++; + + pccache = (uint32_t) 0xffffffff; + pccache2 = (uint8_t *) 0xffffffff; + +#ifdef USE_DYNAREC + codegen_flush(); +#endif +} + void flushmmucache_nopc(void) {