From 95f62b6e8c058a965f1cfefb2520cad64f902ab3 Mon Sep 17 00:00:00 2001 From: Jonathan Campbell Date: Fri, 20 Dec 2024 18:19:07 -0800 Subject: [PATCH] Dynamic x86 core: Reflect STI to normal core so 1-instruction delay is correctly emulated, which makes dynamic core, Windows XP, and SYSENTER/SYSEXIT possible --- CHANGELOG | 4 ++++ src/cpu/core_dyn_x86.cpp | 6 ++++++ src/cpu/core_dyn_x86/decoder.h | 15 ++++++++------- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 484e55c0a..65aed1a17 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,8 @@ Next + - Dynamic x86 core: Reflect STI instruction to normal core so that + the 1-instruction delay is correctly emulated. This makes it + possible to run Windows XP or Server 2003 with dynamic core and + SYSENTER/SYSEXIT emulation without random BSODs (joncampbell123). - Fix default code page. Instead of assuming 437 at all times, use 437 for all IBM PC compatible modes and 932 for PC-98 emulation. (joncampbell123). diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 2c63b5d93..66c119364 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -103,6 +103,7 @@ enum BlockReturnDynX86 { BR_Cycles, BR_Link1,BR_Link2, BR_Opcode, + BR_Opcode2, BR_Iret, BR_CallBack, BR_SMCBlock, @@ -484,6 +485,11 @@ run_block: CPU_Cycles=1; if (!use_dynamic_core_with_paging) dosbox_allow_nonrecursive_page_fault = true; return Safe_CPU_Core_Normal_Run(); + case BR_Opcode2: + CPU_CycleLeft+=CPU_Cycles; + CPU_Cycles=2; + if (!use_dynamic_core_with_paging) dosbox_allow_nonrecursive_page_fault = true; + return Safe_CPU_Core_Normal_Run(); case BR_Link1: case BR_Link2: { diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index d6edaf909..438ac5011 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -3152,13 +3152,7 @@ restart_prefix: gen_releasereg(DREG(TMPB)); break; case 0xfb: //STI - gen_releasereg(DREG(FLAGS)); - gen_call_function((void *)&CPU_STI,"%Rd",DREG(TMPB)); - dyn_check_bool_exception(DREG(TMPB)); - gen_releasereg(DREG(TMPB)); - dyn_check_irqrequest(); - if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode - break; + goto illegalopcode2; // signal "illegal" opcode so the core reflects to normal core which can then properly do the STI delay case 0xfc: //CLD gen_protectflags(); gen_dop_word_imm(DOP_AND,true,DREG(FLAGS),~FLAG_DF); @@ -3283,6 +3277,13 @@ illegalopcode: gen_return(BR_Opcode); dyn_closeblock(); goto finish_block; +illegalopcode2: + dyn_set_eip_last(); + dyn_reduce_cycles(); + dyn_save_critical_regs(); + gen_return(BR_Opcode2); + dyn_closeblock(); + goto finish_block; finish_block: /* Setup the correct end-address */ decode.active_block->page.end=(uint16_t)--decode.page.index;