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

This commit is contained in:
Jonathan Campbell 2024-12-20 18:19:07 -08:00
parent 8b9fcc04e3
commit 95f62b6e8c
3 changed files with 18 additions and 7 deletions

View File

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

View File

@ -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:
{

View File

@ -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;