--- BasiliskII/src/MacOSX/main_macosx.mm 2002/05/25 23:58:51 1.2 +++ BasiliskII/src/MacOSX/main_macosx.mm 2005/01/30 21:42:13 1.13 @@ -1,11 +1,11 @@ /* - * $Id: main_macosx.mm,v 1.2 2002/05/25 23:58:51 nigel Exp $ + * $Id: main_macosx.mm,v 1.13 2005/01/30 21:42:13 gbeauche Exp $ * * main_macosx.mm - Startup code for MacOS X * Based (in a small way) on the default main.m, and on Basilisk's main_unix.cpp * - * Basilisk II (C) 1997-2002 Christian Bauer + * Basilisk II (C) 1997-2005 Christian Bauer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,7 +21,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define PTHREADS +#define PTHREADS // Why is this here? #include "sysdeps.h" #ifdef HAVE_PTHREADS @@ -32,20 +32,27 @@ # include #endif +#include +using std::string; + #include "cpu_emulation.h" #include "macos_util_macosx.h" #include "main.h" #include "prefs.h" #include "prefs_editor.h" #include "rom_patches.h" +#include "sigsegv.h" #include "sys.h" -#include "timer.h" #include "user_strings.h" #include "version.h" #include "video.h" #include "vm_alloc.h" #include "xpram.h" +#if USE_JIT +extern void flush_icache_range(uint32 start, uint32 size); // from compemu_support.cpp +#endif + #ifdef ENABLE_MON # include "mon.h" #endif @@ -61,7 +68,6 @@ // Constants const char ROM_FILE_NAME[] = "ROM"; -const int SIG_STACK_SIZE = SIGSTKSZ; // Size of signal stack const int SCRATCH_MEM_SIZE = 0x10000; // Size of scratch memory area @@ -91,21 +97,69 @@ static pthread_mutex_t intflag_lock = PT uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes #endif -#if defined(HAVE_TIMER_CREATE) && defined(_POSIX_REALTIME_SIGNALS) -#define SIG_TIMER SIGRTMIN -static timer_t timer; // 60Hz timer -#endif - -//#ifdef ENABLE_MON +#ifdef ENABLE_MON static struct sigaction sigint_sa; // sigaction for SIGINT handler static void sigint_handler(...); -//#endif +#endif #if REAL_ADDRESSING static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped #endif +/* + * SIGSEGV handler + */ + +static sigsegv_return_t sigsegv_handler(sigsegv_address_t fault_address, + sigsegv_address_t fault_instruction) +{ +#if ENABLE_VOSF + // Handle screen fault + extern bool Screen_fault_handler(sigsegv_address_t, sigsegv_address_t); + if (Screen_fault_handler(fault_address, fault_instruction)) + return SIGSEGV_RETURN_SUCCESS; +#endif + +#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION + // Ignore writes to ROM + if (((uintptr)fault_address - (uintptr)ROMBaseHost) < ROMSize) + return SIGSEGV_RETURN_SKIP_INSTRUCTION; + + // Ignore all other faults, if requested + if (PrefsFindBool("ignoresegv")) + return SIGSEGV_RETURN_SKIP_INSTRUCTION; +#endif + + return SIGSEGV_RETURN_FAILURE; +} + + +/* + * Dump state when everything went wrong after a SEGV + */ + +static void sigsegv_dump_state(sigsegv_address_t fault_address, sigsegv_address_t fault_instruction) +{ + fprintf(stderr, "Caught SIGSEGV at address %p", fault_address); + if (fault_instruction != SIGSEGV_INVALID_PC) + fprintf(stderr, " [IP=%p]", fault_instruction); + fprintf(stderr, "\n"); + uaecptr nextpc; + extern void m68k_dumpstate(uaecptr *nextpc); + m68k_dumpstate(&nextpc); +#if USE_JIT && JIT_DEBUG + extern void compiler_dumpstate(void); + compiler_dumpstate(); +#endif + VideoQuitFullScreen(); +#ifdef ENABLE_MON + char *arg[4] = {"mon", "-m", "-r", NULL}; + mon(3, arg); + QuitEmulator(); +#endif +} + /* * Main program @@ -116,8 +170,10 @@ static void usage(const char *prg_name) printf("Usage: %s [OPTION...]\n", prg_name); printf("\nUnix options:\n"); printf(" --help\n display this usage message\n"); + printf(" --config FILE\n read/write configuration from/to FILE\n"); printf(" --break ADDRESS\n set ROM breakpoint\n"); printf(" --rominfo\n dump ROM information\n"); + LoadPrefs(); // read the prefs file so PrefsPrintUsage() will print the correct default values PrefsPrintUsage(); exit(0); } @@ -134,9 +190,6 @@ int main(int argc, char **argv) printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); printf(" %s\n", GetString(STR_ABOUT_TEXT2)); - // Read preferences - PrefsInit(argc, argv); - // Parse command line arguments for (int i=1; i