#ifdef USE_JIT_FPU
cfgfile_write_bool (f, _T("compfpu"), p->compfpu);
#endif
+ cfgfile_write_bool(f, _T("comp_catchdetect"), p->comp_catchfault);
cfgfile_write (f, _T("cachesize"), _T("%d"), p->cachesize);
for (i = 0; i < MAX_JPORTS; i++) {
|| cfgfile_yesno (option, value, _T("fpu_strict"), &p->fpu_strict)
|| cfgfile_yesno (option, value, _T("comp_nf"), &p->compnf)
|| cfgfile_yesno (option, value, _T("comp_constjump"), &p->comp_constjump)
+ || cfgfile_yesno(option, value, _T("comp_catchfault"), &p->comp_catchfault)
#ifdef USE_JIT_FPU
|| cfgfile_yesno (option, value, _T("compfpu"), &p->compfpu)
#endif
#else
p->compfpu = 0;
#endif
+ p->comp_catchfault = true;
p->cachesize = 0;
p->gfx_framerate = 1;
extern void exception3i (uae_u32 opcode, uaecptr addr);
extern void exception3b (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc);
extern void exception2 (uaecptr addr, bool read, int size, uae_u32 fc);
+extern void exception2_setup(uaecptr addr, bool read, int size, uae_u32 fc);
extern void m68k_reset (void);
extern void cpureset (void);
extern void cpu_halt (int id);
bool compfpu;
bool comp_hardflush;
bool comp_constjump;
+ bool comp_catchfault;
int cachesize;
bool fpu_strict;
int fpu_mode;
if (handle_access(address, info)) {
return EXCEPTION_CONTINUE_EXECUTION;
}
+ if (currprefs.comp_catchfault) {
+ // setup fake exception
+ exception2_setup(uae_p32(address) - uae_p32(NATMEM_OFFSET), info->ExceptionRecord->ExceptionInformation[0] == 0, 1, regs.s ? 4 : 0);
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
return EXCEPTION_CONTINUE_SEARCH;
}
// address = format $2 stack frame address field
static void ExceptionX (int nr, uaecptr address)
{
+ uaecptr pc = m68k_getpc();
regs.exception = nr;
if (cpu_tracer) {
cputrace.state = nr;
}
if (!regs.s) {
- regs.instruction_pc_user_exception = m68k_getpc();
+ regs.instruction_pc_user_exception = pc;
}
#ifdef JIT
if (currprefs.cachesize)
- regs.instruction_pc = address == -1 ? m68k_getpc () : address;
+ regs.instruction_pc = address == -1 ? pc : address;
#endif
+
+ if (debug_illegal && !in_rom(pc)) {
+ if (nr <= 63 && (debug_illegal_mask & ((uae_u64)1 << nr))) {
+ write_log(_T("Exception %d breakpoint\n"), nr);
+ activate_debugger();
+ }
+ }
+
#ifdef CPUEMU_13
if (currprefs.cpu_cycle_exact && currprefs.cpu_model <= 68010)
Exception_ce000 (nr);
Exception_normal (nr);
}
- if (debug_illegal && !in_rom (M68K_GETPC)) {
- if (nr <= 63 && (debug_illegal_mask & ((uae_u64)1 << nr))) {
- write_log (_T("Exception %d breakpoint\n"), nr);
- activate_debugger ();
- }
- }
regs.exception = 0;
if (cpu_tracer) {
cputrace.state = 0;
#endif
for (;;) {
- ((compiled_handler*)(pushall_call_handler))();
- /* Whenever we return from that, we should check spcflags */
- check_uae_int_request();
- if (regs.spcflags) {
- if (do_specialties (0)) {
- return;
+#ifdef USE_STRUCTURED_EXCEPTION_HANDLING
+ __try {
+#endif
+ for (;;) {
+ ((compiled_handler*)(pushall_call_handler))();
+ /* Whenever we return from that, we should check spcflags */
+ check_uae_int_request();
+ if (regs.spcflags) {
+ if (do_specialties(0)) {
+ return;
+ }
+ }
}
+
+#ifdef USE_STRUCTURED_EXCEPTION_HANDLING
+ } __except (EvalException(GetExceptionInformation())) {
+ // Something very bad happened, generate fake bus error exception
+ // Either emulation continues normally or crashes.
+ // Without this it would have crashed in any case..
+ uaecptr pc = M68K_GETPC;
+ write_log(_T("Unhandled JIT exception! PC=%08x\n"), pc);
+ if (pc & 1)
+ Exception(3);
+ else
+ Exception(2);
}
+#endif
}
+
}
#endif /* JIT */
exception3f (opcode, addr, w, i, false, pc, true);
}
+void exception2_setup(uaecptr addr, bool read, int size, uae_u32 fc)
+{
+ last_addr_for_exception_3 = m68k_getpc() + bus_error_offset;
+ last_fault_for_exception_3 = addr;
+ last_writeaccess_for_exception_3 = read == 0;
+ last_instructionaccess_for_exception_3 = (fc & 1) == 0;
+ last_op_for_exception_3 = regs.opcode;
+ last_notinstruction_for_exception_3 = exception_in_exception != 0;
+}
+
void exception2 (uaecptr addr, bool read, int size, uae_u32 fc)
{
if (currprefs.mmu_model) {
mmu_bus_error (addr, 0, fc, read == false, size, 0, true);
}
} else {
- last_addr_for_exception_3 = m68k_getpc() + bus_error_offset;
- last_fault_for_exception_3 = addr;
- last_writeaccess_for_exception_3 = read == 0;
- last_instructionaccess_for_exception_3 = (fc & 1) == 0;
- last_op_for_exception_3 = regs.opcode;
- last_notinstruction_for_exception_3 = exception_in_exception != 0;
+ exception2_setup(addr, read, size, fc);
THROW(2);
}
}
#define IDC_SOUNDDRIVEVOLUME2 1581
#define IDC_CS_CACHE_TEXT 1582
#define IDC_SOUNDVOLUMEEXT2 1582
+#define IDC_JITCRASH 1582
#define IDC_CS_CACHE_TEXT2 1583
#define IDC_SOUNDDRIVEVOLUMEX 1583
#define IDC_COLLISIONS 1584
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,145,161,236,10
RTEXT "Stopped M68K CPU idle mode",IDC_STATIC,180,183,121,9
CONTROL "",IDC_PPC_CPUIDLE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,308,177,69,21
- GROUPBOX "x86 Bridgeboard CPU options",IDC_STATIC,136,202,258,42
+ GROUPBOX "x86 Bridgeboard CPU options",IDC_STATIC,136,202,258,38
RTEXT "CPU Speed",IDC_STATIC,147,221,55,9,SS_CENTERIMAGE
EDITTEXT IDC_CPUTEXT_x86,224,220,39,12,ES_CENTER | ES_READONLY
CONTROL "",IDC_SPEED_x86,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,278,215,108,20
- GROUPBOX "Advanced JIT Settings",IDC_STATIC,136,245,258,70
- RTEXT "Cache size:",IDC_STATIC,143,261,66,10,SS_CENTERIMAGE
- CONTROL "Slider1",IDC_CACHE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,212,255,115,20
- EDITTEXT IDC_CACHETEXT,331,260,30,12,ES_CENTER | ES_READONLY
- CONTROL "FPU support",IDC_JITFPU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,143,281,71,11
- CONTROL "Constant jump",IDC_CONSTJUMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,281,71,11
- CONTROL "Hard flush",IDC_HARDFLUSH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,299,281,84,11
- CONTROL "Direct",IDC_TRUST0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,143,299,72,10
- CONTROL "Indirect",IDC_TRUST1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,221,299,72,10
- CONTROL "No flags",IDC_NOFLAGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,299,299,68,11
+ GROUPBOX "Advanced JIT Settings",IDC_STATIC,136,241,258,74
+ RTEXT "Cache size:",IDC_STATIC,143,260,66,10,SS_CENTERIMAGE
+ CONTROL "Slider1",IDC_CACHE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,212,250,115,20
+ EDITTEXT IDC_CACHETEXT,331,255,30,12,ES_CENTER | ES_READONLY
+ CONTROL "FPU support",IDC_JITFPU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,143,273,71,11
+ CONTROL "Constant jump",IDC_CONSTJUMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,273,71,11
+ CONTROL "Hard flush",IDC_HARDFLUSH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,299,273,84,11
+ CONTROL "Direct",IDC_TRUST0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,143,288,72,10
+ CONTROL "Indirect",IDC_TRUST1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,221,288,72,10
+ CONTROL "No flags",IDC_NOFLAGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,299,288,68,11
GROUPBOX "MMU",IDC_STATIC,2,168,129,42,BS_LEFT
CONTROL "Data cache emulation [] 68030, 040 and 060 optional data cache emulation. Requires More compatible option.",IDC_CPUDATACACHE,
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,8,123,119,12
COMBOBOX IDC_FPU_MODE,7,299,112,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Catch unexpected exceptions",IDC_JITCRASH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,143,300,115,11
END
IDD_FLOPPY DIALOGEX 0, 0, 396, 261
ew(hDlg, IDC_HARDFLUSH, enable);
ew(hDlg, IDC_CONSTJUMP, enable);
ew(hDlg, IDC_JITFPU, enable);
+ ew(hDlg, IDC_JITCRASH, enable);
ew(hDlg, IDC_NOFLAGS, enable);
ew(hDlg, IDC_CS_CACHE_TEXT, enable);
ew(hDlg, IDC_CACHE, enable);
_stprintf (buffer, _T("%d MB"), workprefs.cachesize / 1024 );
SetDlgItemText (hDlg, IDC_CACHETEXT, buffer);
- CheckDlgButton (hDlg, IDC_NOFLAGS, workprefs.compnf);
- CheckDlgButton (hDlg, IDC_JITFPU, workprefs.compfpu);
- CheckDlgButton (hDlg, IDC_HARDFLUSH, workprefs.comp_hardflush);
- CheckDlgButton (hDlg, IDC_CONSTJUMP, workprefs.comp_constjump);
- CheckDlgButton (hDlg, IDC_JITENABLE, workprefs.cachesize > 0);
+ CheckDlgButton(hDlg, IDC_JITCRASH, workprefs.comp_catchfault);
+ CheckDlgButton(hDlg, IDC_NOFLAGS, workprefs.compnf);
+ CheckDlgButton(hDlg, IDC_JITFPU, workprefs.compfpu);
+ CheckDlgButton(hDlg, IDC_HARDFLUSH, workprefs.comp_hardflush);
+ CheckDlgButton(hDlg, IDC_CONSTJUMP, workprefs.comp_constjump);
+ CheckDlgButton(hDlg, IDC_JITENABLE, workprefs.cachesize > 0);
bool mmu = ((workprefs.cpu_model == 68060 && workprefs.mmu_model == 68060) ||
(workprefs.cpu_model == 68040 && workprefs.mmu_model == 68040) ||
(workprefs.cpu_model == 68030 && workprefs.mmu_model == 68030)) &&
workprefs.comptrustlong = newtrust;
workprefs.comptrustnaddr= newtrust;
- workprefs.compnf = ischecked (hDlg, IDC_NOFLAGS);
- workprefs.compfpu = ischecked (hDlg, IDC_JITFPU);
- workprefs.comp_hardflush = ischecked (hDlg, IDC_HARDFLUSH);
- workprefs.comp_constjump = ischecked (hDlg, IDC_CONSTJUMP);
+ workprefs.comp_catchfault = ischecked(hDlg, IDC_JITCRASH);
+ workprefs.compnf = ischecked(hDlg, IDC_NOFLAGS);
+ workprefs.compfpu = ischecked(hDlg, IDC_JITFPU);
+ workprefs.comp_hardflush = ischecked(hDlg, IDC_HARDFLUSH);
+ workprefs.comp_constjump = ischecked(hDlg, IDC_CONSTJUMP);
#ifdef JIT
oldcache = workprefs.cachesize;