The instruction following STI is always executed, even if an interrupt

is pending. Fixes Windows 9x boot broken by SYSENTER commit.
This commit is contained in:
SarahW 2020-07-01 21:50:11 +01:00
commit 4fe71bdbed
3 changed files with 32 additions and 4 deletions

View file

@ -238,6 +238,8 @@ static void prefetch_flush()
#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) #define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG))
//#define CACHE_ON() 0 //#define CACHE_ON() 0
int cpu_end_block_after_ins = 0;
static int cycles_main = 0; static int cycles_main = 0;
void exec386_dynarec(int cycs) void exec386_dynarec(int cycs)
{ {
@ -297,10 +299,17 @@ void exec386_dynarec(int cycs)
CPU_BLOCK_END(); CPU_BLOCK_END();
if (nmi && nmi_enable && nmi_mask) if (nmi && nmi_enable && nmi_mask)
CPU_BLOCK_END(); CPU_BLOCK_END();
if (cpu_end_block_after_ins)
{
cpu_end_block_after_ins--;
if (!cpu_end_block_after_ins)
CPU_BLOCK_END();
}
ins++; ins++;
insc++; insc++;
} }
cpu_end_block_after_ins = 0;
} }
else else
{ {
@ -458,6 +467,13 @@ void exec386_dynarec(int cycs)
if (nmi && nmi_enable && nmi_mask) if (nmi && nmi_enable && nmi_mask)
CPU_BLOCK_END(); CPU_BLOCK_END();
if (cpu_end_block_after_ins)
{
cpu_end_block_after_ins--;
if (!cpu_end_block_after_ins)
CPU_BLOCK_END();
}
if (cpu_state.abrt) if (cpu_state.abrt)
{ {
codegen_block_remove(); codegen_block_remove();
@ -467,6 +483,7 @@ void exec386_dynarec(int cycs)
ins++; ins++;
insc++; insc++;
} }
cpu_end_block_after_ins = 0;
if (!cpu_state.abrt && !x86_was_reset) if (!cpu_state.abrt && !x86_was_reset)
codegen_block_end_recompile(block); codegen_block_end_recompile(block);
@ -530,6 +547,13 @@ void exec386_dynarec(int cycs)
if (nmi && nmi_enable && nmi_mask) if (nmi && nmi_enable && nmi_mask)
CPU_BLOCK_END(); CPU_BLOCK_END();
if (cpu_end_block_after_ins)
{
cpu_end_block_after_ins--;
if (!cpu_end_block_after_ins)
CPU_BLOCK_END();
}
if (cpu_state.abrt) if (cpu_state.abrt)
{ {
codegen_block_remove(); codegen_block_remove();
@ -539,6 +563,7 @@ void exec386_dynarec(int cycs)
ins++; ins++;
insc++; insc++;
} }
cpu_end_block_after_ins = 0;
if (!cpu_state.abrt && !x86_was_reset) if (!cpu_state.abrt && !x86_was_reset)
codegen_block_end(); codegen_block_end();

View file

@ -303,4 +303,6 @@ void sysexit(void);
int divl(uint32_t val); int divl(uint32_t val);
int idivl(int32_t val); int idivl(int32_t val);
extern int cpu_end_block_after_ins;
#endif #endif

View file

@ -85,12 +85,13 @@ static int opSTI(uint32_t fetchdat)
else else
cpu_state.flags |= I_FLAG; cpu_state.flags |= I_FLAG;
/*TODO - should end block after 1 further instruction*/ /*First instruction after STI will always execute, regardless of whether
// CPU_BLOCK_END(); there is a pending interrupt*/
cpu_end_block_after_ins = 2;
CLOCK_CYCLES(2); CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
return 1; return 0;
} }
static int opSAHF(uint32_t fetchdat) static int opSAHF(uint32_t fetchdat)