mirror of
https://github.com/86Box/86Box.git
synced 2025-01-22 09:11:50 -05:00
FPU: Properly implement INT 10h FPU exception, fixes #5162.
This commit is contained in:
parent
5e12d46f32
commit
40fd79aeb9
10 changed files with 55 additions and 15 deletions
|
@ -268,7 +268,8 @@ exec386_2386(int32_t cycs)
|
|||
} else {
|
||||
CHECK_READ_CS(MIN(ol, 4));
|
||||
}
|
||||
ins_fetch_fault = cpu_386_check_instruction_fault();
|
||||
if (is386)
|
||||
ins_fetch_fault = cpu_386_check_instruction_fault();
|
||||
|
||||
/* Breakpoint fault has priority over other faults. */
|
||||
if (ins_fetch_fault) {
|
||||
|
@ -336,6 +337,14 @@ exec386_2386(int32_t cycs)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
} else if (new_ne) {
|
||||
flags_rebuild();
|
||||
new_ne = 0;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oldcs = CS;
|
||||
#endif
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
x86_int(16);
|
||||
} else if (trap) {
|
||||
flags_rebuild();
|
||||
if (trap & 2) dr[6] |= 0x8000;
|
||||
|
|
|
@ -72,6 +72,7 @@ extern uint8_t *pccache2;
|
|||
extern int optype;
|
||||
extern uint32_t pccache;
|
||||
|
||||
int new_ne = 0;
|
||||
int in_sys = 0;
|
||||
int unmask_a20_in_smm = 0;
|
||||
uint32_t old_rammask = 0xffffffff;
|
||||
|
|
|
@ -357,6 +357,8 @@ exec386_dynarec_int(void)
|
|||
CPU_BLOCK_END();
|
||||
if (smi_line)
|
||||
CPU_BLOCK_END();
|
||||
else if (new_ne)
|
||||
CPU_BLOCK_END();
|
||||
else if (trap)
|
||||
CPU_BLOCK_END();
|
||||
else if (nmi && nmi_enable && nmi_mask)
|
||||
|
@ -366,7 +368,7 @@ exec386_dynarec_int(void)
|
|||
}
|
||||
|
||||
block_ended:
|
||||
if (!cpu_state.abrt && trap) {
|
||||
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;
|
||||
|
@ -602,6 +604,8 @@ exec386_dynarec_dyn(void)
|
|||
if (cpu_init)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (new_ne)
|
||||
CPU_BLOCK_END();
|
||||
if ((cpu_state.flags & T_FLAG) || (trap == 2))
|
||||
CPU_BLOCK_END();
|
||||
if (smi_line)
|
||||
|
@ -626,7 +630,7 @@ exec386_dynarec_dyn(void)
|
|||
|
||||
cpu_end_block_after_ins = 0;
|
||||
|
||||
if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset)
|
||||
if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !new_ne && !x86_was_reset)
|
||||
codegen_block_end_recompile(block);
|
||||
|
||||
if (x86_was_reset)
|
||||
|
@ -702,6 +706,8 @@ exec386_dynarec_dyn(void)
|
|||
if (cpu_init)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (new_ne)
|
||||
CPU_BLOCK_END();
|
||||
if (cpu_state.flags & T_FLAG)
|
||||
CPU_BLOCK_END();
|
||||
if (smi_line)
|
||||
|
@ -726,7 +732,7 @@ exec386_dynarec_dyn(void)
|
|||
|
||||
cpu_end_block_after_ins = 0;
|
||||
|
||||
if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset)
|
||||
if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !new_ne && !x86_was_reset)
|
||||
codegen_block_end();
|
||||
|
||||
if (x86_was_reset)
|
||||
|
@ -809,6 +815,15 @@ exec386_dynarec(int32_t cycs)
|
|||
}
|
||||
}
|
||||
|
||||
if (new_ne) {
|
||||
# ifndef USE_NEW_DYNAREC
|
||||
oldcs = CS;
|
||||
# endif
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
new_ne = 0;
|
||||
x86_int(16);
|
||||
}
|
||||
|
||||
if (smi_line)
|
||||
enter_smm_check(0);
|
||||
else if (nmi && nmi_enable && nmi_mask) {
|
||||
|
@ -977,6 +992,15 @@ block_ended:
|
|||
#endif
|
||||
}
|
||||
}
|
||||
} else if (new_ne) {
|
||||
flags_rebuild();
|
||||
|
||||
new_ne = 0;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oldcs = CS;
|
||||
#endif
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
x86_int(16);
|
||||
} else if (trap) {
|
||||
flags_rebuild();
|
||||
#ifdef USE_DEBUG_REGS_486
|
||||
|
|
|
@ -814,6 +814,8 @@ extern int lock_legal_80[8];
|
|||
extern int lock_legal_f6[8];
|
||||
extern int lock_legal_fe[8];
|
||||
|
||||
extern int new_ne;
|
||||
|
||||
extern int in_lock;
|
||||
extern int cpu_override_interpreter;
|
||||
|
||||
|
|
|
@ -271,6 +271,7 @@ reset_common(int hard)
|
|||
stack32 = 0;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
msw = 0;
|
||||
new_ne = 0;
|
||||
if (hascache)
|
||||
cr0 = 1 << 30;
|
||||
else
|
||||
|
|
|
@ -99,8 +99,8 @@ opWAIT(uint32_t fetchdat)
|
|||
|
||||
if (fpu_softfloat) {
|
||||
if (fpu_state.swd & FPU_SW_Summary) {
|
||||
if (is486 && (cr0 & 0x20))
|
||||
x86_int(16);
|
||||
if (cr0 & 0x20)
|
||||
new_ne = 1;
|
||||
else
|
||||
picint(1 << 13);
|
||||
return 1;
|
||||
|
|
|
@ -99,7 +99,10 @@ opWAIT(uint32_t fetchdat)
|
|||
|
||||
if (fpu_softfloat) {
|
||||
if (fpu_state.swd & FPU_SW_Summary) {
|
||||
picint(1 << 13);
|
||||
if (cr0 & 0x20)
|
||||
new_ne = 1;
|
||||
else
|
||||
picint(1 << 13);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -355,10 +355,10 @@ FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store)
|
|||
nmi = 1;
|
||||
}
|
||||
#else
|
||||
if (is486 && (cr0 & 0x20))
|
||||
x86_int(16);
|
||||
else
|
||||
picint(1 << 13);
|
||||
if (cr0 & 0x20)
|
||||
new_ne = 1;
|
||||
else
|
||||
picint(1 << 13);
|
||||
#endif // FPU_8087
|
||||
}
|
||||
return unmasked;
|
||||
|
|
|
@ -228,8 +228,8 @@ FPU_save_regi_tag(extFloat80_t reg, int tag, int stnr)
|
|||
#define FPU_check_pending_exceptions() \
|
||||
do { \
|
||||
if (fpu_state.swd & FPU_SW_Summary) { \
|
||||
if (is486 && (cr0 & 0x20)) \
|
||||
x86_int(16); \
|
||||
if (cr0 & 0x20) \
|
||||
new_ne = 1; \
|
||||
else \
|
||||
picint(1 << 13); \
|
||||
return 1; \
|
||||
|
|
|
@ -99,8 +99,8 @@ typedef union {
|
|||
dst = src1 / (double) src2; \
|
||||
else { \
|
||||
fpu_log("FPU : divide by zero\n"); \
|
||||
if (is486 && (cr0 & 0x20)) \
|
||||
x86_int(16); \
|
||||
if (cr0 & 0x20) \
|
||||
new_ne = 1; \
|
||||
else \
|
||||
picint(1 << 13); \
|
||||
return 1; \
|
||||
|
|
Loading…
Reference in a new issue