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.13 by gbeauche, 2005-01-30T21:42:13Z vs.
Revision 1.18 by gbeauche, 2007-12-30T08:47:34Z

# 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 +
25 + #import <AppKit/AppKit.h>
26 + #undef check
27 +
28   #define PTHREADS        // Why is this here?
29   #include "sysdeps.h"
30  
# Line 50 | Line 54 | using std::string;
54   #include "xpram.h"
55  
56   #if USE_JIT
57 < extern void flush_icache_range(uint32 start, uint32 size);  // from compemu_support.cpp
57 > extern void flush_icache_range(uint8 *start, uint32 size);  // from compemu_support.cpp
58   #endif
59  
60   #ifdef ENABLE_MON
# Line 61 | Line 65 | extern void flush_icache_range(uint32 st
65   #include "debug.h"
66  
67  
64 #import <AppKit/AppKit.h>
65
68   #include "main_macosx.h"                // To bridge between main() and misc. classes
69  
70  
# Line 108 | Line 110 | static bool lm_area_mapped = false;    // F
110  
111  
112   /*
113 + *  Helpers to map memory that can be accessed from the Mac side
114 + */
115 +
116 + // NOTE: VM_MAP_32BIT is only used when compiling a 64-bit JIT on specific platforms
117 + void *vm_acquire_mac(size_t size)
118 + {
119 +        return vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT);
120 + }
121 +
122 + static int vm_acquire_mac_fixed(void *addr, size_t size)
123 + {
124 +        return vm_acquire_fixed(addr, size, VM_MAP_DEFAULT | VM_MAP_32BIT);
125 + }
126 +
127 +
128 + /*
129   *  SIGSEGV handler
130   */
131  
132 < static sigsegv_return_t sigsegv_handler(sigsegv_address_t fault_address,
115 <                                                                                sigsegv_address_t fault_instruction)
132 > static sigsegv_return_t sigsegv_handler(sigsegv_info_t *sip)
133   {
134 +        const uintptr fault_address = (uintptr)sigsegv_get_fault_address(sip);
135   #if ENABLE_VOSF
136          // Handle screen fault
137 <        extern bool Screen_fault_handler(sigsegv_address_t, sigsegv_address_t);
138 <        if (Screen_fault_handler(fault_address, fault_instruction))
137 >        extern bool Screen_fault_handler(sigsegv_info_t *sip);
138 >        if (Screen_fault_handler(sip))
139                  return SIGSEGV_RETURN_SUCCESS;
140   #endif
141  
# Line 139 | Line 157 | static sigsegv_return_t sigsegv_handler(
157   *  Dump state when everything went wrong after a SEGV
158   */
159  
160 < static void sigsegv_dump_state(sigsegv_address_t fault_address, sigsegv_address_t fault_instruction)
160 > static void sigsegv_dump_state(sigsegv_info_t *sip)
161   {
162 +        const sigsegv_address_t fault_address = sigsegv_get_fault_address(sip);
163 +        const sigsegv_address_t fault_instruction = sigsegv_get_fault_instruction_address(sip);
164          fprintf(stderr, "Caught SIGSEGV at address %p", fault_address);
165 <        if (fault_instruction != SIGSEGV_INVALID_PC)
165 >        if (fault_instruction != SIGSEGV_INVALID_ADDRESS)
166                  fprintf(stderr, " [IP=%p]", fault_instruction);
167          fprintf(stderr, "\n");
168          uaecptr nextpc;
# Line 156 | Line 176 | static void sigsegv_dump_state(sigsegv_a
176   #ifdef ENABLE_MON
177          char *arg[4] = {"mon", "-m", "-r", NULL};
178          mon(3, arg);
159        QuitEmulator();
179   #endif
180 +        QuitEmulator();
181   }
182  
183  
# Line 258 | Line 278 | bool InitEmulator (void)
278                  WarningAlert(GetString(STR_SMALL_RAM_WARN));
279                  RAMSize = 1024*1024;
280          }
281 +        if (RAMSize > 1023*1024*1024)                                           // Cap to 1023MB (APD crashes at 1GB)
282 +                RAMSize = 1023*1024*1024;
283  
284   #if REAL_ADDRESSING || DIRECT_ADDRESSING
285          RAMSize = RAMSize & -getpagesize();                                     // Round down to page boundary
# Line 269 | Line 291 | bool InitEmulator (void)
291   #if REAL_ADDRESSING
292          // Flag: RAM and ROM are contigously allocated from address 0
293          bool memory_mapped_from_zero = false;
294 <        
295 <        // Under Solaris/SPARC and NetBSD/m68k, Basilisk II is known to crash
296 <        // when trying to map a too big chunk of memory starting at address 0
297 < #if defined(OS_solaris) || defined(OS_netbsd) || defined(PAGEZERO_HACK)
298 <        const bool can_map_all_memory = false;
277 < #else
294 >
295 >        // Make sure to map RAM & ROM at address 0 only on platforms that
296 >        // supports linker scripts to relocate the Basilisk II executable
297 >        // above 0x70000000
298 > #if HAVE_LINKER_SCRIPT
299          const bool can_map_all_memory = true;
300 + #else
301 +        const bool can_map_all_memory = false;
302   #endif
303          
304          // Try to allocate all memory from 0x0000, if it is not known to crash
305 <        if (can_map_all_memory && (vm_acquire_fixed(0, RAMSize + 0x100000) == 0)) {
305 >        if (can_map_all_memory && (vm_acquire_mac_fixed(0, RAMSize + 0x100000) == 0)) {
306                  D(bug("Could allocate RAM and ROM from 0x0000\n"));
307                  memory_mapped_from_zero = true;
308          }
309 <
309 >        
310   #ifndef PAGEZERO_HACK
311          // Otherwise, just create the Low Memory area (0x0000..0x2000)
312 <        else if (vm_acquire_fixed(0, 0x2000) == 0) {
312 >        else if (vm_acquire_mac_fixed(0, 0x2000) == 0) {
313                  D(bug("Could allocate the Low Memory globals\n"));
314                  lm_area_mapped = true;
315          }
# Line 311 | Line 334 | bool InitEmulator (void)
334          else
335   #endif
336          {
337 <                RAMBaseHost = (uint8 *)vm_acquire(RAMSize);
338 <                ROMBaseHost = (uint8 *)vm_acquire(0x100000);
316 <                if (RAMBaseHost == VM_MAP_FAILED || ROMBaseHost == VM_MAP_FAILED) {
337 >                uint8 *ram_rom_area = (uint8 *)vm_acquire_mac(RAMSize + 0x100000);
338 >                if (ram_rom_area == VM_MAP_FAILED) {
339                          ErrorAlert(STR_NO_MEM_ERR);
340                          QuitEmulator();
341                  }
342 +                RAMBaseHost = ram_rom_area;
343 +                ROMBaseHost = RAMBaseHost + RAMSize;
344          }
345  
346   #if USE_SCRATCHMEM_SUBTERFUGE
347          // Allocate scratch memory
348 <        ScratchMem = (uint8 *)vm_acquire(SCRATCH_MEM_SIZE);
348 >        ScratchMem = (uint8 *)vm_acquire_mac(SCRATCH_MEM_SIZE);
349          if (ScratchMem == VM_MAP_FAILED) {
350                  ErrorAlert(STR_NO_MEM_ERR);
351                  QuitEmulator();
# Line 336 | Line 360 | bool InitEmulator (void)
360          ROMBaseMac = Host2MacAddr(ROMBaseHost);
361   #endif
362   #if REAL_ADDRESSING
363 <        RAMBaseMac = (uint32)RAMBaseHost;
364 <        ROMBaseMac = (uint32)ROMBaseHost;
363 >        RAMBaseMac = Host2MacAddr(RAMBaseHost);
364 >        ROMBaseMac = Host2MacAddr(ROMBaseHost);
365   #endif
366          D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac));
367          D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac));
# Line 405 | Line 429 | void QuitEmuNoExit()
429  
430          // Free ROM/RAM areas
431          if (RAMBaseHost != VM_MAP_FAILED) {
432 <                vm_release(RAMBaseHost, RAMSize);
432 >                vm_release(RAMBaseHost, RAMSize + 0x100000);
433                  RAMBaseHost = NULL;
410        }
411        if (ROMBaseHost != VM_MAP_FAILED) {
412                vm_release(ROMBaseHost, 0x100000);
434                  ROMBaseHost = NULL;
435          }
436  
# Line 439 | Line 460 | void QuitEmuNoExit()
460  
461   void QuitEmulator(void)
462   {
442        extern  NSApplication *NSApp;
443
444
463          QuitEmuNoExit();
464  
465          // Stop run loop?
# Line 460 | Line 478 | void FlushCodeCache(void *start, uint32
478   {
479   #if USE_JIT
480      if (UseJIT)
481 <                flush_icache_range((uintptr)start, size);
481 >                flush_icache_range((uint8 *)start, size);
482   #endif
483   }
484  
# Line 483 | Line 501 | static void sigint_handler(...)
501   #endif
502  
503  
504 + #ifdef HAVE_PTHREADS
505 + /*
506 + *  Pthread configuration
507 + */
508 +
509 + void Set_pthread_attr(pthread_attr_t *attr, int priority)
510 + {
511 +        pthread_attr_init(attr);
512 + #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
513 +        // Some of these only work for superuser
514 +        if (geteuid() == 0) {
515 +                pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
516 +                pthread_attr_setschedpolicy(attr, SCHED_FIFO);
517 +                struct sched_param fifo_param;
518 +                fifo_param.sched_priority = ((sched_get_priority_min(SCHED_FIFO)
519 +                                                                         + sched_get_priority_max(SCHED_FIFO))
520 +                                                                         / 2 + priority);
521 +                pthread_attr_setschedparam(attr, &fifo_param);
522 +        }
523 +        if (pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM) != 0) {
524 + #ifdef PTHREAD_SCOPE_BOUND_NP
525 +            // If system scope is not available (eg. we're not running
526 +            // with CAP_SCHED_MGT capability on an SGI box), try bound
527 +            // scope.  It exposes pthread scheduling to the kernel,
528 +            // without setting realtime priority.
529 +            pthread_attr_setscope(attr, PTHREAD_SCOPE_BOUND_NP);
530 + #endif
531 +        }
532 + #endif
533 + }
534 + #endif // HAVE_PTHREADS
535 +
536 +
537   /*
538   *  Mutexes
539   */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines