ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/MacOSX/main_macosx.mm
(Generate patch)

Comparing BasiliskII/src/MacOSX/main_macosx.mm (file contents):
Revision 1.2 by nigel, 2002-05-25T23:58:51Z vs.
Revision 1.13 by gbeauche, 2005-01-30T21:42:13Z

# Line 5 | Line 5
5   *                                              Based (in a small way) on the default main.m,
6                                                  and on Basilisk's main_unix.cpp
7   *
8 < *  Basilisk II (C) 1997-2002 Christian Bauer
8 > *  Basilisk II (C) 1997-2005 Christian Bauer
9   *
10   *  This program is free software; you can redistribute it and/or modify
11   *  it under the terms of the GNU General Public License as published by
# Line 21 | Line 21
21   *  along with this program; if not, write to the Free Software
22   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23   */
24 < #define PTHREADS
24 > #define PTHREADS        // Why is this here?
25   #include "sysdeps.h"
26  
27   #ifdef HAVE_PTHREADS
# Line 32 | Line 32
32   # include <sys/mman.h>
33   #endif
34  
35 + #include <string>
36 + using std::string;
37 +
38   #include "cpu_emulation.h"
39   #include "macos_util_macosx.h"
40   #include "main.h"
41   #include "prefs.h"
42   #include "prefs_editor.h"
43   #include "rom_patches.h"
44 + #include "sigsegv.h"
45   #include "sys.h"
42 #include "timer.h"
46   #include "user_strings.h"
47   #include "version.h"
48   #include "video.h"
49   #include "vm_alloc.h"
50   #include "xpram.h"
51  
52 + #if USE_JIT
53 + extern void flush_icache_range(uint32 start, uint32 size);  // from compemu_support.cpp
54 + #endif
55 +
56   #ifdef ENABLE_MON
57   # include "mon.h"
58   #endif
# Line 61 | Line 68
68  
69   // Constants
70   const char ROM_FILE_NAME[] = "ROM";
64 const int SIG_STACK_SIZE = SIGSTKSZ;    // Size of signal stack
71   const int SCRATCH_MEM_SIZE = 0x10000;   // Size of scratch memory area
72  
73  
# Line 91 | Line 97 | static pthread_mutex_t intflag_lock = PT
97   uint8 *ScratchMem = NULL;                       // Scratch memory for Mac ROM writes
98   #endif
99  
100 < #if defined(HAVE_TIMER_CREATE) && defined(_POSIX_REALTIME_SIGNALS)
95 < #define SIG_TIMER SIGRTMIN
96 < static timer_t timer;                           // 60Hz timer
97 < #endif
98 <
99 < //#ifdef ENABLE_MON
100 > #ifdef ENABLE_MON
101   static struct sigaction sigint_sa;      // sigaction for SIGINT handler
102   static void sigint_handler(...);
103 < //#endif
103 > #endif
104  
105   #if REAL_ADDRESSING
106   static bool lm_area_mapped = false;     // Flag: Low Memory area mmap()ped
107   #endif
108  
109  
110 + /*
111 + *  SIGSEGV handler
112 + */
113 +
114 + static sigsegv_return_t sigsegv_handler(sigsegv_address_t fault_address,
115 +                                                                                sigsegv_address_t fault_instruction)
116 + {
117 + #if ENABLE_VOSF
118 +        // Handle screen fault
119 +        extern bool Screen_fault_handler(sigsegv_address_t, sigsegv_address_t);
120 +        if (Screen_fault_handler(fault_address, fault_instruction))
121 +                return SIGSEGV_RETURN_SUCCESS;
122 + #endif
123 +
124 + #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
125 +        // Ignore writes to ROM
126 +        if (((uintptr)fault_address - (uintptr)ROMBaseHost) < ROMSize)
127 +                return SIGSEGV_RETURN_SKIP_INSTRUCTION;
128 +
129 +        // Ignore all other faults, if requested
130 +        if (PrefsFindBool("ignoresegv"))
131 +                return SIGSEGV_RETURN_SKIP_INSTRUCTION;
132 + #endif
133 +
134 +        return SIGSEGV_RETURN_FAILURE;
135 + }
136 +
137 +
138 + /*
139 + *  Dump state when everything went wrong after a SEGV
140 + */
141 +
142 + static void sigsegv_dump_state(sigsegv_address_t fault_address, sigsegv_address_t fault_instruction)
143 + {
144 +        fprintf(stderr, "Caught SIGSEGV at address %p", fault_address);
145 +        if (fault_instruction != SIGSEGV_INVALID_PC)
146 +                fprintf(stderr, " [IP=%p]", fault_instruction);
147 +        fprintf(stderr, "\n");
148 +        uaecptr nextpc;
149 +        extern void m68k_dumpstate(uaecptr *nextpc);
150 +        m68k_dumpstate(&nextpc);
151 + #if USE_JIT && JIT_DEBUG
152 +        extern void compiler_dumpstate(void);
153 +        compiler_dumpstate();
154 + #endif
155 +        VideoQuitFullScreen();
156 + #ifdef ENABLE_MON
157 +        char *arg[4] = {"mon", "-m", "-r", NULL};
158 +        mon(3, arg);
159 +        QuitEmulator();
160 + #endif
161 + }
162 +
163  
164   /*
165   *  Main program
# Line 116 | Line 170 | static void usage(const char *prg_name)
170          printf("Usage: %s [OPTION...]\n", prg_name);
171          printf("\nUnix options:\n");
172          printf("  --help\n    display this usage message\n");
173 +        printf("  --config FILE\n    read/write configuration from/to FILE\n");
174          printf("  --break ADDRESS\n    set ROM breakpoint\n");
175          printf("  --rominfo\n    dump ROM information\n");
176 +        LoadPrefs(); // read the prefs file so PrefsPrintUsage() will print the correct default values
177          PrefsPrintUsage();
178          exit(0);
179   }
# Line 134 | Line 190 | int main(int argc, char **argv)
190          printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR);
191          printf(" %s\n", GetString(STR_ABOUT_TEXT2));
192  
137        // Read preferences
138        PrefsInit(argc, argv);
139
193          // Parse command line arguments
194          for (int i=1; i<argc; i++) {
195                  if (strcmp(argv[i], "--help") == 0) {
# Line 147 | Line 200 | int main(int argc, char **argv)
200                          i++;
201                          if (i < argc)
202                                  ROMBreakpoint = strtol(argv[i], NULL, 0);
203 +                } else if (strcmp(argv[i], "--config") == 0) {
204 +                        argv[i++] = NULL;
205 +                        if (i < argc) {
206 +                                extern string UserPrefsPath; // from prefs_unix.cpp
207 +                                UserPrefsPath = argv[i];
208 +                                argv[i] = NULL;
209 +                        }
210                  } else if (strcmp(argv[i], "--rominfo") == 0) {
211                          PrintROMInfo = true;
212                  } else if (argv[i][0] == '-') {
# Line 155 | Line 215 | int main(int argc, char **argv)
215                  }
216          }
217  
218 +        // Read preferences
219 +        PrefsInit(argc, argv);
220 +
221          // Init system routines
222          SysInit();
223  
# Line 172 | Line 235 | int main(int argc, char **argv)
235          return i;
236   }
237  
238 < #define QuitEmulator()  QuitEmuNoExit() ; return NO;
238 > #define QuitEmulator()  { QuitEmuNoExit() ; return NO; }
239  
240   bool InitEmulator (void)
241   {
242          char str[256];
243  
244  
245 +        // Install the handler for SIGSEGV
246 +        if (!sigsegv_install_handler(sigsegv_handler)) {
247 +                sprintf(str, GetString(STR_SIG_INSTALL_ERR), "SIGSEGV", strerror(errno));
248 +                ErrorAlert(str);
249 +                QuitEmulator();
250 +        }
251 +
252 +        // Register dump state function when we got mad after a segfault
253 +        sigsegv_set_dump_state(sigsegv_dump_state);
254 +
255          // Read RAM size
256          RAMSize = PrefsFindInt32("ramsize") & 0xfff00000;       // Round down to 1MB boundary
257          if (RAMSize < 1024*1024) {
# Line 199 | Line 272 | bool InitEmulator (void)
272          
273          // Under Solaris/SPARC and NetBSD/m68k, Basilisk II is known to crash
274          // when trying to map a too big chunk of memory starting at address 0
275 < #if defined(OS_solaris) || defined(OS_netbsd)
275 > #if defined(OS_solaris) || defined(OS_netbsd) || defined(PAGEZERO_HACK)
276          const bool can_map_all_memory = false;
277   #else
278          const bool can_map_all_memory = true;
# Line 210 | Line 283 | bool InitEmulator (void)
283                  D(bug("Could allocate RAM and ROM from 0x0000\n"));
284                  memory_mapped_from_zero = true;
285          }
286 <        
286 >
287 > #ifndef PAGEZERO_HACK
288          // Otherwise, just create the Low Memory area (0x0000..0x2000)
289          else if (vm_acquire_fixed(0, 0x2000) == 0) {
290                  D(bug("Could allocate the Low Memory globals\n"));
# Line 224 | Line 298 | bool InitEmulator (void)
298                  QuitEmulator();
299          }
300   #endif
301 + #else
302 +        *str = 0;               // Eliminate unused variable warning
303 + #endif /* REAL_ADDRESSING */
304  
305          // Create areas for Mac RAM and ROM
306   #if REAL_ADDRESSING
# Line 267 | Line 344 | bool InitEmulator (void)
344          
345          // Get rom file path from preferences
346          const char *rom_path = PrefsFindString("rom");
347 +        if ( ! rom_path )
348 +                WarningAlert("No rom pathname set. Trying ./ROM");
349  
350          // Load Mac ROM
351          int rom_fd = open(rom_path ? rom_path : ROM_FILE_NAME, O_RDONLY);
# Line 316 | Line 395 | bool InitEmulator (void)
395  
396   void QuitEmuNoExit()
397   {
319        extern  NSApplication *NSApp;
320
321
398          D(bug("QuitEmulator\n"));
399  
400          // Exit 680x0 emulation
# Line 359 | Line 435 | void QuitEmuNoExit()
435  
436          // Exit preferences
437          PrefsExit();
362
363        // Stop run loop
364        [NSApp terminate: nil];
438   }
439  
440   void QuitEmulator(void)
441   {
442 +        extern  NSApplication *NSApp;
443 +
444 +
445          QuitEmuNoExit();
446 +
447 +        // Stop run loop?
448 +        [NSApp terminate: nil];
449 +
450          exit(0);
451   }
452  
# Line 378 | Line 458 | void QuitEmulator(void)
458  
459   void FlushCodeCache(void *start, uint32 size)
460   {
461 + #if USE_JIT
462 +    if (UseJIT)
463 +                flush_icache_range((uintptr)start, size);
464 + #endif
465   }
466  
467  
# Line 406 | Line 490 | static void sigint_handler(...)
490   #ifdef HAVE_PTHREADS
491  
492   struct B2_mutex {
493 <        B2_mutex() { pthread_mutex_init(&m, NULL); }
494 <        ~B2_mutex() { pthread_mutex_unlock(&m); pthread_mutex_destroy(&m); }
493 >        B2_mutex() {
494 >                pthread_mutexattr_t attr;
495 >                pthread_mutexattr_init(&attr);
496 >                // Initialize the mutex for priority inheritance --
497 >                // required for accurate timing.
498 > #ifdef HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL
499 >                pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
500 > #endif
501 > #if defined(HAVE_PTHREAD_MUTEXATTR_SETTYPE) && defined(PTHREAD_MUTEX_NORMAL)
502 >                pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
503 > #endif
504 > #ifdef HAVE_PTHREAD_MUTEXATTR_SETPSHARED
505 >                pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
506 > #endif
507 >                pthread_mutex_init(&m, &attr);
508 >                pthread_mutexattr_destroy(&attr);
509 >        }
510 >        ~B2_mutex() {
511 >                pthread_mutex_trylock(&m);      // Make sure it's locked before
512 >                pthread_mutex_unlock(&m);       // unlocking it.
513 >                pthread_mutex_destroy(&m);
514 >        }
515          pthread_mutex_t m;
516   };
517  
# Line 490 | Line 594 | void ErrorAlert(const char *text)
594          NSString *error  = [NSString stringWithCString: text];
595          NSString *button = [NSString stringWithCString: GetString(STR_QUIT_BUTTON) ];
596  
493 //      If we have a full screen mode, quit it here?
494
597          NSLog(error);
598 +        if ( PrefsFindBool("nogui") )
599 +                return;
600 +        VideoQuitFullScreen();
601          NSRunCriticalAlertPanel(title, error, button, nil, nil);
602   }
603  
# Line 509 | Line 614 | void WarningAlert(const char *text)
614          NSString *button  = [NSString stringWithCString: GetString(STR_OK_BUTTON) ];
615  
616          NSLog(warning);
617 +        if ( PrefsFindBool("nogui") )
618 +                return;
619 +        VideoQuitFullScreen();
620          NSRunAlertPanel(title, warning, button, nil, nil);
621   }
622  
# Line 525 | Line 633 | bool ChoiceAlert(const char *text, const
633          NSString *yes     = [NSString stringWithCString: pos];
634          NSString *no      = [NSString stringWithCString: neg];
635  
528        NSLog(warning);
636          return NSRunInformationalAlertPanel(title, warning, yes, no, nil);
637   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines