ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/main_unix.cpp
(Generate patch)

Comparing BasiliskII/src/Unix/main_unix.cpp (file contents):
Revision 1.58 by cebix, 2004-01-12T15:29:25Z vs.
Revision 1.72 by gbeauche, 2006-02-27T07:24:58Z

# Line 1 | Line 1
1   /*
2   *  main_unix.cpp - Startup code for Unix
3   *
4 < *  Basilisk II (C) 1997-2004 Christian Bauer
4 > *  Basilisk II (C) 1997-2005 Christian Bauer
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 24 | Line 24
24   #include <stdlib.h>
25   #include <signal.h>
26   #include <errno.h>
27 < #include <X11/Xlib.h>
27 >
28 > #ifdef USE_SDL
29 > # include <SDL.h>
30 > #endif
31 >
32 > #ifndef USE_SDL_VIDEO
33 > # include <X11/Xlib.h>
34 > #endif
35  
36   #ifdef HAVE_PTHREADS
37   # include <pthread.h>
# Line 116 | Line 123 | int CPUType;
123   bool CPUIs68060;
124   int FPUType;
125   bool TwentyFourBitAddressing;
126 + bool ThirtyThreeBitAddressing = false;
127  
128  
129   // Global variables
130 < char *x_display_name = NULL;                                            // X11 display name
131 < Display *x_display = NULL;                                                      // X11 display handle
130 > #ifndef USE_SDL_VIDEO
131 > extern char *x_display_name;                                            // X11 display name
132 > extern Display *x_display;                                                      // X11 display handle
133 > #ifdef X11_LOCK_TYPE
134 > X11_LOCK_TYPE x_display_lock = X11_LOCK_INIT;           // X11 display lock
135 > #endif
136 > #endif
137  
138   static uint8 last_xpram[XPRAM_SIZE];                            // Buffer for monitoring XPRAM changes
139  
# Line 210 | Line 223 | char *strdup(const char *s)
223  
224  
225   /*
226 + *  Helpers to map memory that can be accessed from the Mac side
227 + */
228 +
229 + // NOTE: VM_MAP_33BIT is only used when compiling a 64-bit JIT on specific platforms
230 + void *vm_acquire_mac(size_t size)
231 + {
232 +        void *m = vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_33BIT);
233 + #ifdef USE_33BIT_ADDRESSING
234 +        if (m == VM_MAP_FAILED) {
235 +                printf("WARNING: Cannot acquire memory in 33-bit address space (%s)\n", strerror(errno));
236 +                ThirtyThreeBitAddressing = false;
237 +                m = vm_acquire(size);
238 +        }
239 + #endif
240 +        return m;
241 + }
242 +
243 + static int vm_acquire_mac_fixed(void *addr, size_t size)
244 + {
245 +        int ret = vm_acquire_fixed(addr, size, VM_MAP_DEFAULT | VM_MAP_33BIT);
246 + #ifdef USE_33BIT_ADDRESSING
247 +        if (ret < 0) {
248 +                printf("WARNING: Cannot acquire fixed memory in 33-bit address space (%s)\n", strerror(errno));
249 +                ThirtyThreeBitAddressing = false;
250 +                ret = vm_acquire_fixed(addr, size);
251 +        }
252 + #endif
253 +        return ret;
254 + }
255 +
256 +
257 + /*
258   *  SIGSEGV handler
259   */
260  
# Line 258 | Line 303 | static void sigsegv_dump_state(sigsegv_a
303   #ifdef ENABLE_MON
304          char *arg[4] = {"mon", "-m", "-r", NULL};
305          mon(3, arg);
261        QuitEmulator();
306   #endif
307 +        QuitEmulator();
308 + }
309 +
310 +
311 + /*
312 + *  Update virtual clock and trigger interrupts if necessary
313 + */
314 +
315 + #ifdef USE_CPU_EMUL_SERVICES
316 + static uint64 n_check_ticks = 0;
317 + static uint64 emulated_ticks_start = 0;
318 + static uint64 emulated_ticks_count = 0;
319 + static int64 emulated_ticks_current = 0;
320 + static int32 emulated_ticks_quantum = 1000;
321 + int32 emulated_ticks = emulated_ticks_quantum;
322 +
323 + void cpu_do_check_ticks(void)
324 + {
325 + #if DEBUG
326 +        n_check_ticks++;
327 + #endif
328 +
329 +        uint64 now;
330 +        static uint64 next = 0;
331 +        if (next == 0)
332 +                next = emulated_ticks_start = GetTicks_usec();
333 +
334 +        // Update total instructions count
335 +        if (emulated_ticks <= 0) {
336 +                emulated_ticks_current += (emulated_ticks_quantum - emulated_ticks);
337 +                // XXX: can you really have a machine fast enough to overflow
338 +                // a 63-bit m68k instruction counter within 16 ms?
339 +                if (emulated_ticks_current < 0) {
340 +                        printf("WARNING: Overflowed 63-bit m68k instruction counter in less than 16 ms!\n");
341 +                        goto recalibrate_quantum;
342 +                }
343 +        }
344 +
345 +        // Check for interrupt opportunity
346 +        now = GetTicks_usec();
347 +        if (next < now) {
348 +                one_tick();
349 +                do {
350 +                        next += 16625;
351 +                } while (next < now);
352 +                emulated_ticks_count++;
353 +
354 +                // Recalibrate 1000 Hz quantum every 10 ticks
355 +                static uint64 last = 0;
356 +                if (last == 0)
357 +                        last = now;
358 +                else if (now - last > 166250) {
359 +                  recalibrate_quantum:
360 +                        emulated_ticks_quantum = ((uint64)emulated_ticks_current * 1000) / (now - last);
361 +                        emulated_ticks_current = 0;
362 +                        last = now;
363 +                }
364 +        }
365 +
366 +        // Update countdown
367 +        if (emulated_ticks <= 0)
368 +                emulated_ticks += emulated_ticks_quantum;
369   }
370 + #endif
371  
372  
373   /*
# Line 300 | Line 407 | int main(int argc, char **argv)
407          for (int i=1; i<argc; i++) {
408                  if (strcmp(argv[i], "--help") == 0) {
409                          usage(argv[0]);
410 + #ifndef USE_SDL_VIDEO
411                  } else if (strcmp(argv[i], "--display") == 0) {
412                          i++; // don't remove the argument, gtk_init() needs it too
413                          if (i < argc)
414                                  x_display_name = strdup(argv[i]);
415 + #endif
416                  } else if (strcmp(argv[i], "--break") == 0) {
417                          argv[i++] = NULL;
418                          if (i < argc) {
# Line 361 | Line 470 | int main(int argc, char **argv)
470                  }
471          }
472  
473 + #ifndef USE_SDL_VIDEO
474          // Open display
475          x_display = XOpenDisplay(x_display_name);
476          if (x_display == NULL) {
# Line 374 | Line 484 | int main(int argc, char **argv)
484          // Fork out, so we can return from fullscreen mode when things get ugly
485          XF86DGAForkApp(DefaultScreen(x_display));
486   #endif
487 + #endif
488 +
489 + #ifdef USE_SDL
490 +        // Initialize SDL system
491 +        int sdl_flags = 0;
492 + #ifdef USE_SDL_VIDEO
493 +        sdl_flags |= SDL_INIT_VIDEO;
494 + #endif
495 + #ifdef USE_SDL_AUDIO
496 +        sdl_flags |= SDL_INIT_AUDIO;
497 + #endif
498 +        assert(sdl_flags != 0);
499 +        if (SDL_Init(sdl_flags) == -1) {
500 +                char str[256];
501 +                sprintf(str, "Could not initialize SDL: %s.\n", SDL_GetError());
502 +                ErrorAlert(str);
503 +                QuitEmulator();
504 +        }
505 +        atexit(SDL_Quit);
506 + #endif
507  
508          // Init system routines
509          SysInit();
# Line 399 | Line 529 | int main(int argc, char **argv)
529                  WarningAlert(GetString(STR_SMALL_RAM_WARN));
530                  RAMSize = 1024*1024;
531          }
532 +        if (RAMSize > 1023*1024*1024)                                           // Cap to 1023MB (APD crashes at 1GB)
533 +                RAMSize = 1023*1024*1024;
534  
535   #if REAL_ADDRESSING || DIRECT_ADDRESSING
536          RAMSize = RAMSize & -getpagesize();                                     // Round down to page boundary
# Line 407 | Line 539 | int main(int argc, char **argv)
539          // Initialize VM system
540          vm_init();
541  
542 + #ifdef USE_33BIT_ADDRESSING
543 +        // Speculatively enables 33-bit addressing
544 +        ThirtyThreeBitAddressing = true;
545 + #endif
546 +
547   #if REAL_ADDRESSING
548          // Flag: RAM and ROM are contigously allocated from address 0
549          bool memory_mapped_from_zero = false;
550 <        
551 <        // Under Solaris/SPARC and NetBSD/m68k, Basilisk II is known to crash
552 <        // when trying to map a too big chunk of memory starting at address 0
553 < #if defined(OS_solaris) || defined(OS_netbsd) || defined(PAGEZERO_HACK)
554 <        const bool can_map_all_memory = false;
418 < #else
550 >
551 >        // Make sure to map RAM & ROM at address 0 only on platforms that
552 >        // supports linker scripts to relocate the Basilisk II executable
553 >        // above 0x70000000
554 > #if HAVE_LINKER_SCRIPT
555          const bool can_map_all_memory = true;
556 + #else
557 +        const bool can_map_all_memory = false;
558   #endif
559          
560          // Try to allocate all memory from 0x0000, if it is not known to crash
561 <        if (can_map_all_memory && (vm_acquire_fixed(0, RAMSize + 0x100000) == 0)) {
561 >        if (can_map_all_memory && (vm_acquire_mac_fixed(0, RAMSize + 0x100000) == 0)) {
562                  D(bug("Could allocate RAM and ROM from 0x0000\n"));
563                  memory_mapped_from_zero = true;
564          }
565          
566   #ifndef PAGEZERO_HACK
567          // Otherwise, just create the Low Memory area (0x0000..0x2000)
568 <        else if (vm_acquire_fixed(0, 0x2000) == 0) {
568 >        else if (vm_acquire_mac_fixed(0, 0x2000) == 0) {
569                  D(bug("Could allocate the Low Memory globals\n"));
570                  lm_area_mapped = true;
571          }
# Line 450 | Line 588 | int main(int argc, char **argv)
588          else
589   #endif
590          {
591 <                RAMBaseHost = (uint8 *)vm_acquire(RAMSize);
592 <                ROMBaseHost = (uint8 *)vm_acquire(0x100000);
455 <                if (RAMBaseHost == VM_MAP_FAILED || ROMBaseHost == VM_MAP_FAILED) {
591 >                uint8 *ram_rom_area = (uint8 *)vm_acquire_mac(RAMSize + 0x100000);
592 >                if (ram_rom_area == VM_MAP_FAILED) {    
593                          ErrorAlert(STR_NO_MEM_ERR);
594                          QuitEmulator();
595                  }
596 +                RAMBaseHost = ram_rom_area;
597 +                ROMBaseHost = RAMBaseHost + RAMSize;
598          }
599  
600   #if USE_SCRATCHMEM_SUBTERFUGE
601          // Allocate scratch memory
602 <        ScratchMem = (uint8 *)vm_acquire(SCRATCH_MEM_SIZE);
602 >        ScratchMem = (uint8 *)vm_acquire_mac(SCRATCH_MEM_SIZE);
603          if (ScratchMem == VM_MAP_FAILED) {
604                  ErrorAlert(STR_NO_MEM_ERR);
605                  QuitEmulator();
# Line 475 | Line 614 | int main(int argc, char **argv)
614          ROMBaseMac = Host2MacAddr(ROMBaseHost);
615   #endif
616   #if REAL_ADDRESSING
617 <        RAMBaseMac = (uint32)RAMBaseHost;
618 <        ROMBaseMac = (uint32)ROMBaseHost;
617 >        RAMBaseMac = Host2MacAddr(RAMBaseHost);
618 >        ROMBaseMac = Host2MacAddr(ROMBaseHost);
619   #endif
620          D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac));
621          D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac));
# Line 597 | Line 736 | int main(int argc, char **argv)
736          sigaction(SIGINT, &sigint_sa, NULL);
737   #endif
738  
739 + #ifndef USE_CPU_EMUL_SERVICES
740   #if defined(HAVE_PTHREADS)
741  
742          // POSIX threads available, start 60Hz thread
# Line 660 | Line 800 | int main(int argc, char **argv)
800          setitimer(ITIMER_REAL, &req, NULL);
801  
802   #endif
803 + #endif
804  
805 < #ifdef HAVE_PTHREADS
805 > #ifdef USE_PTHREADS_SERVICES
806          // Start XPRAM watchdog thread
807          memcpy(last_xpram, XPRAM, XPRAM_SIZE);
808          xpram_thread_active = (pthread_create(&xpram_thread, NULL, xpram_func, NULL) == 0);
# Line 690 | Line 831 | void QuitEmulator(void)
831          Exit680x0();
832   #endif
833  
834 < #if defined(HAVE_PTHREADS)
834 > #if defined(USE_CPU_EMUL_SERVICES)
835 >        // Show statistics
836 >        uint64 emulated_ticks_end = GetTicks_usec();
837 >        D(bug("%ld ticks in %ld usec = %f ticks/sec [%ld tick checks]\n",
838 >                  (long)emulated_ticks_count, (long)(emulated_ticks_end - emulated_ticks_start),
839 >                  emulated_ticks_count * 1000000.0 / (emulated_ticks_end - emulated_ticks_start), (long)n_check_ticks));
840 > #elif defined(USE_PTHREADS_SERVICES)
841          // Stop 60Hz thread
842          if (tick_thread_active) {
843                  tick_thread_cancel = true;
# Line 709 | Line 856 | void QuitEmulator(void)
856          setitimer(ITIMER_REAL, &req, NULL);
857   #endif
858  
859 < #ifdef HAVE_PTHREADS
859 > #ifdef USE_PTHREADS_SERVICES
860          // Stop XPRAM watchdog thread
861          if (xpram_thread_active) {
862                  xpram_thread_cancel = true;
# Line 725 | Line 872 | void QuitEmulator(void)
872  
873          // Free ROM/RAM areas
874          if (RAMBaseHost != VM_MAP_FAILED) {
875 <                vm_release(RAMBaseHost, RAMSize);
875 >                vm_release(RAMBaseHost, RAMSize + 0x100000);
876                  RAMBaseHost = NULL;
730        }
731        if (ROMBaseHost != VM_MAP_FAILED) {
732                vm_release(ROMBaseHost, 0x100000);
877                  ROMBaseHost = NULL;
878          }
879  
# Line 757 | Line 901 | void QuitEmulator(void)
901          PrefsExit();
902  
903          // Close X11 server connection
904 + #ifndef USE_SDL_VIDEO
905          if (x_display)
906                  XCloseDisplay(x_display);
907 + #endif
908  
909          exit(0);
910   }
# Line 846 | Line 992 | struct B2_mutex {
992              pthread_mutexattr_init(&attr);
993              // Initialize the mutex for priority inheritance --
994              // required for accurate timing.
995 < #ifdef HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL
995 > #if defined(HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL) && !defined(__CYGWIN__)
996              pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
997   #endif
998   #if defined(HAVE_PTHREAD_MUTEXATTR_SETTYPE) && defined(PTHREAD_MUTEX_NORMAL)
# Line 964 | Line 1110 | static void xpram_watchdog(void)
1110          }
1111   }
1112  
1113 < #ifdef HAVE_PTHREADS
1113 > #ifdef USE_PTHREADS_SERVICES
1114   static void *xpram_func(void *arg)
1115   {
1116          while (!xpram_thread_cancel) {
# Line 989 | Line 1135 | static void one_second(void)
1135          SetInterruptFlag(INTFLAG_1HZ);
1136          TriggerInterrupt();
1137  
1138 < #ifndef HAVE_PTHREADS
1138 > #ifndef USE_PTHREADS_SERVICES
1139          static int second_counter = 0;
1140          if (++second_counter > 60) {
1141                  second_counter = 0;
# Line 1006 | Line 1152 | static void one_tick(...)
1152                  one_second();
1153          }
1154  
1155 < #ifndef HAVE_PTHREADS
1156 <        // No threads available, perform video refresh and networking from here
1155 > #ifndef USE_PTHREADS_SERVICES
1156 >        // Threads not used to trigger interrupts, perform video refresh from here
1157          VideoRefresh();
1158 + #endif
1159 +
1160 + #ifndef HAVE_PTHREADS
1161 +        // No threads available, perform networking from here
1162          SetInterruptFlag(INTFLAG_ETHER);
1163   #endif
1164  
# Line 1019 | Line 1169 | static void one_tick(...)
1169          }
1170   }
1171  
1172 < #ifdef HAVE_PTHREADS
1172 > #ifdef USE_PTHREADS_SERVICES
1173   static void *tick_func(void *arg)
1174   {
1175          uint64 start = GetTicks_usec();
# Line 1036 | Line 1186 | static void *tick_func(void *arg)
1186                  ticks++;
1187          }
1188          uint64 end = GetTicks_usec();
1189 <        D(bug("%Ld ticks in %Ld usec = %f ticks/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start)));
1189 >        D(bug("%lld ticks in %lld usec = %f ticks/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start)));
1190          return NULL;
1191   }
1192   #endif
# Line 1396 | Line 1546 | void display_alert(int title_id, int pre
1546  
1547   void ErrorAlert(const char *text)
1548   {
1549 < #ifdef ENABLE_GTK
1549 > #if defined(ENABLE_GTK) && !defined(USE_SDL_VIDEO)
1550          if (PrefsFindBool("nogui") || x_display == NULL) {
1551                  printf(GetString(STR_SHELL_ERROR_PREFIX), text);
1552                  return;
# Line 1415 | Line 1565 | void ErrorAlert(const char *text)
1565  
1566   void WarningAlert(const char *text)
1567   {
1568 < #ifdef ENABLE_GTK
1568 > #if defined(ENABLE_GTK) && !defined(USE_SDL_VIDEO)
1569          if (PrefsFindBool("nogui") || x_display == NULL) {
1570                  printf(GetString(STR_SHELL_WARNING_PREFIX), text);
1571                  return;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines