From 9f200fe2e83c99c0e4b8076afe451bf0c3da8f98 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Mar 2025 21:20:15 +0100 Subject: [PATCH 1/3] 386 Interpreter: Check for debug breakpoint before segment limit and presence checking. --- src/cpu/386.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index caa5f84a2..c9a62fa6e 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -264,11 +264,7 @@ exec386_2386(int32_t cycs) ol = opcode_length[fetchdat & 0xff]; if ((ol == 3) && opcode_has_modrm[fetchdat & 0xff] && (((fetchdat >> 14) & 0x03) == 0x03)) ol = 2; - if (cpu_16bitbus) { - CHECK_READ_CS(MIN(ol, 2)); - } else { - CHECK_READ_CS(MIN(ol, 4)); - } + if (is386) ins_fetch_fault = cpu_386_check_instruction_fault(); @@ -276,6 +272,10 @@ exec386_2386(int32_t cycs) if (ins_fetch_fault) { ins_fetch_fault = 0; cpu_state.abrt = 1; + } else if (cpu_16bitbus) { + CHECK_READ_CS(MIN(ol, 2)); + } else { + CHECK_READ_CS(MIN(ol, 4)); } if (!cpu_state.abrt) { From 52a16529dcfd554c6e7e7a2c5c921388ee9bb9a4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Mar 2025 23:54:55 +0100 Subject: [PATCH 2/3] 386 Interpreter: Fix execute breakpoints. --- src/cpu/386.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index c9a62fa6e..6abb7da18 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -269,9 +269,11 @@ exec386_2386(int32_t cycs) ins_fetch_fault = cpu_386_check_instruction_fault(); /* Breakpoint fault has priority over other faults. */ - if (ins_fetch_fault) { + if ((cpu_state.abrt == 0) & ins_fetch_fault) { + x86gen(); ins_fetch_fault = 0; - cpu_state.abrt = 1; + /* No instructions executed at this point. */ + goto block_ended; } else if (cpu_16bitbus) { CHECK_READ_CS(MIN(ol, 2)); } else { @@ -288,7 +290,6 @@ exec386_2386(int32_t cycs) trap |= !!(cpu_state.flags & T_FLAG); cpu_state.pc++; - cpu_state.eflags &= ~(RF_FLAG); if (opcode == 0xf0) in_lock = 1; x86_2386_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); @@ -316,6 +317,7 @@ exec386_2386(int32_t cycs) if (cpu_end_block_after_ins) cpu_end_block_after_ins--; +block_ended: if (cpu_state.abrt) { flags_rebuild(); tempi = cpu_state.abrt & ABRT_MASK; @@ -338,6 +340,9 @@ exec386_2386(int32_t cycs) #endif } } + + if (!x86_was_reset && ins_fetch_fault) + x86gen(); } else if (new_ne) { flags_rebuild(); new_ne = 0; From dd4e493f646e316162c732b70ad86a3b81cc3b0f Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 17 Mar 2025 00:07:41 +0100 Subject: [PATCH 3/3] Applied the fix to the optional 486 implementation as well. --- src/cpu/386.c | 2 +- src/cpu/386_dynarec.c | 45 ++++++++++++++++++------------------------- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index 6abb7da18..ed4b40ab2 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -341,7 +341,7 @@ block_ended: } } - if (!x86_was_reset && ins_fetch_fault) + if (is386 && !x86_was_reset && ins_fetch_fault) x86gen(); } else if (new_ne) { flags_rebuild(); diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index 5f41c416a..fd6285057 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -276,11 +276,7 @@ exec386_dynarec_int(void) cpu_block_end = 0; x86_was_reset = 0; -# ifdef USE_DEBUG_REGS_486 - if (trap & 2) { -# else if (trap == 2) { -# endif /* Handle the T bit in the new TSS first. */ CPU_BLOCK_END(); goto block_ended; @@ -297,13 +293,6 @@ exec386_dynarec_int(void) cpu_state.ea_seg = &cpu_state.seg_ds; cpu_state.ssegs = 0; -# ifdef USE_DEBUG_REGS_486 - if (UNLIKELY(cpu_386_check_instruction_fault())) { - x86gen(); - goto block_ended; - } -# endif - fetchdat = fastreadl_fetch(cs + cpu_state.pc); # ifdef ENABLE_386_DYNAREC_LOG if (in_smm) @@ -370,13 +359,7 @@ exec386_dynarec_int(void) block_ended: if (!cpu_state.abrt && !new_ne && trap) { -# ifdef USE_DEBUG_REGS_486 - //pclog("Debug trap 0x%X\n", trap); - if (trap & 2) dr[6] |= 0x8000; - if (trap & 1) dr[6] |= 0x4000; -# else dr[6] |= (trap == 2) ? 0x8000 : 0x4000; -# endif trap = 0; # ifndef USE_NEW_DYNAREC @@ -902,6 +885,9 @@ exec386(int32_t cycs) cycdiff = 0; oldcyc = cycles; while (cycdiff < cycle_period) { +#ifdef USE_DEBUG_REGS_486 + int ins_fetch_fault = 0; +#endif ins_cycles = cycles; #ifndef USE_NEW_DYNAREC @@ -919,8 +905,14 @@ exec386(int32_t cycs) cpu_state.ssegs = 0; #ifdef USE_DEBUG_REGS_486 - if (UNLIKELY(cpu_386_check_instruction_fault())) { + if (is386) + ins_fetch_fault = cpu_386_check_instruction_fault(); + + /* Breakpoint fault has priority over other faults. */ + if ((cpu_state.abrt == 0) & ins_fetch_fault) { x86gen(); + ins_fetch_fault = 0; + /* No instructions executed at this point. */ goto block_ended; } #endif @@ -972,11 +964,13 @@ exec386(int32_t cycs) block_ended: #endif if (cpu_state.abrt) { + uint8_t oop = opcode; flags_rebuild(); tempi = cpu_state.abrt & ABRT_MASK; cpu_state.abrt = 0; x86_doabrt(tempi); if (cpu_state.abrt) { + pclog("Double fault - %02X\n", oop); cpu_state.abrt = 0; #ifndef USE_NEW_DYNAREC CS = oldcs; @@ -993,6 +987,11 @@ block_ended: #endif } } + +#ifdef USE_DEBUG_REGS_486 + if (is386 && !x86_was_reset && ins_fetch_fault) + x86gen(); +#endif } else if (new_ne) { flags_rebuild(); @@ -1005,20 +1004,14 @@ block_ended: } else if (trap) { flags_rebuild(); #ifdef USE_DEBUG_REGS_486 - if (trap & 1) - dr[6] |= 0x4000; - if (trap & 2) - dr[6] |= 0x8000; + if (trap & 2) dr[6] |= 0x8000; + if (trap & 1) dr[6] |= 0x4000; #endif - trap = 0; #ifndef USE_NEW_DYNAREC oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; -#ifndef USE_DEBUG_REGS_486 - dr[6] |= 0x4000; -#endif x86_int(1); }