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.14 by cebix, 2000-07-14T21:29:13Z vs.
Revision 1.22 by cebix, 2000-10-09T17:05:16Z

# Line 30 | Line 30
30   # include <pthread.h>
31   #endif
32  
33 < #if defined(USE_MAPPED_MEMORY) || REAL_ADDRESSING
33 > #if defined(USE_MAPPED_MEMORY) || REAL_ADDRESSING || DIRECT_ADDRESSING
34   # include <sys/mman.h>
35   #endif
36  
# Line 108 | Line 108 | char *x_display_name = NULL;                                           // X11
108   Display *x_display = NULL;                                                      // X11 display handle
109  
110   static int zero_fd = -1;                                                        // FD of /dev/zero
111 static bool lm_area_mapped = false;                                     // Flag: Low Memory area mmap()ped
111   static uint8 last_xpram[256];                                           // Buffer for monitoring XPRAM changes
112  
113   #ifdef HAVE_PTHREADS
# Line 134 | Line 133 | static struct sigaction sigirq_sa;     // Vi
133   static struct sigaction sigill_sa;      // Illegal instruction
134   static void *sig_stack = NULL;          // Stack for signal handlers
135   uint16 EmulatedSR;                                      // Emulated bits of SR (supervisor bit and interrupt mask)
136 < uint32 ScratchMem = NULL;                       // Scratch memory for Mac ROM writes
136 > #endif
137 >
138 > #if USE_SCRATCHMEM_SUBTERFUGE
139 > uint8 *ScratchMem = NULL;                       // Scratch memory for Mac ROM writes
140   #endif
141  
142   static struct sigaction timer_sa;       // sigaction used for timer
# Line 149 | Line 151 | static struct sigaction sigint_sa;     // si
151   static void sigint_handler(...);
152   #endif
153  
154 + #if REAL_ADDRESSING
155 + static bool lm_area_mapped = false;     // Flag: Low Memory area mmap()ped
156 + static bool memory_mapped_from_zero = false; // Flag: Could allocate RAM area from 0
157 + #endif
158 +
159 + #if REAL_ADDRESSING || DIRECT_ADDRESSING
160 + static uint32 mapped_ram_rom_size;              // Total size of mmap()ed RAM/ROM area
161 + #endif
162 +
163   #ifdef USE_MAPPED_MEMORY
164   extern char *address_space, *good_address_map;
165   #endif
# Line 257 | Line 268 | int main(int argc, char **argv)
268                  RAMSize = 1024*1024;
269          }
270  
271 + #if REAL_ADDRESSING || DIRECT_ADDRESSING
272 +        const uint32 page_size = getpagesize();
273 +        const uint32 page_mask = page_size - 1;
274 +        const uint32 aligned_ram_size = (RAMSize + page_mask) & ~page_mask;
275 +        mapped_ram_rom_size = aligned_ram_size + 0x100000;
276 + #endif
277 +
278   #if REAL_ADDRESSING
279 +        // Try to allocate the complete address space from zero
280 +        // gb-- the Solaris manpage about mmap(2) states that using MAP_FIXED
281 +        // implies undefined behaviour for further use of sbrk(), malloc(), etc.
282 +        // cebix-- on NetBSD/m68k, this causes a segfault
283 + #if defined(OS_solaris) || defined(OS_netbsd)
284 +        // Anyway, it doesn't work...
285 +        if (0) {
286 + #else
287 +        if (mmap((caddr_t)0x0000, mapped_ram_rom_size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, zero_fd, 0) != MAP_FAILED) {
288 + #endif
289 +                D(bug("Could allocate RAM and ROM from 0x0000\n"));
290 +                memory_mapped_from_zero = true;
291 +        }
292          // Create Low Memory area (0x0000..0x2000)
293 <        if (mmap((char *)0x0000, 0x2000, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, zero_fd, 0) == (void *)-1) {
293 >        else if (mmap((char *)0x0000, 0x2000, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, zero_fd, 0) != MAP_FAILED) {
294 >                D(bug("Could allocate the Low Memory globals\n"));
295 >                lm_area_mapped = true;
296 >        }
297 >        // Exit on error
298 >        else {
299                  sprintf(str, GetString(STR_LOW_MEM_MMAP_ERR), strerror(errno));
300                  ErrorAlert(str);
301                  QuitEmulator();
302          }
267        lm_area_mapped = true;
303   #endif
304  
305 < #if !EMULATED_68K
305 > #if USE_SCRATCHMEM_SUBTERFUGE
306          // Allocate scratch memory
307 <        ScratchMem = (uint32)malloc(SCRATCH_MEM_SIZE);
307 >        ScratchMem = (uint8 *)malloc(SCRATCH_MEM_SIZE);
308          if (ScratchMem == NULL) {
309                  ErrorAlert(GetString(STR_NO_MEM_ERR));
310                  QuitEmulator();
# Line 297 | Line 332 | int main(int argc, char **argv)
332          mmap(good_address_map + i, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE, good_address_fd, 0);
333      for (int i=0; i<0x80000; i+=4096)
334          mmap(good_address_map + i + 0x00400000, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE, good_address_fd, 0);
335 + #elif REAL_ADDRESSING || DIRECT_ADDRESSING
336 +        // gb-- Overkill, needs to be cleaned up. Probably explode it for either
337 +        // real or direct addressing mode.
338 + #if REAL_ADDRESSING
339 +        if (memory_mapped_from_zero) {
340 +                RAMBaseHost = (uint8 *)0;
341 +                ROMBaseHost = RAMBaseHost + aligned_ram_size;
342 +        }
343 +        else
344 + #endif
345 +        {
346 +                RAMBaseHost = (uint8 *)mmap(0, mapped_ram_rom_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, zero_fd, 0);
347 +                if (RAMBaseHost == (uint8 *)MAP_FAILED) {
348 +                        ErrorAlert(GetString(STR_NO_MEM_ERR));
349 +                        QuitEmulator();
350 +                }
351 +                ROMBaseHost = RAMBaseHost + aligned_ram_size;
352 +        }
353   #else
354 <        RAMBaseHost = new uint8[RAMSize];
355 <        ROMBaseHost = new uint8[0x100000];
354 >        RAMBaseHost = (uint8 *)malloc(RAMSize);
355 >        ROMBaseHost = (uint8 *)malloc(0x100000);
356 >        if (RAMBaseHost == NULL || ROMBaseHost == NULL) {
357 >                ErrorAlert(GetString(STR_NO_MEM_ERR));
358 >                QuitEmulator();
359 >        }
360 > #endif
361 >
362 > #if DIRECT_ADDRESSING
363 >        // Initialize MEMBaseDiff now so that Host2MacAddr in the Video module
364 >        // will return correct results
365 >        RAMBaseMac = 0;
366 >        ROMBaseMac = RAMBaseMac + aligned_ram_size;
367 >        InitMEMBaseDiff(RAMBaseHost, RAMBaseMac);
368   #endif
369 < #if REAL_ADDRESSING && !EMULATED_68K
369 > #if REAL_ADDRESSING // && !EMULATED_68K
370          RAMBaseMac = (uint32)RAMBaseHost;
371          ROMBaseMac = (uint32)ROMBaseHost;
372   #endif
373          D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac));
374          D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac));
375 <
375 >        
376          // Get rom file path from preferences
377          const char *rom_path = PrefsFindString("rom");
378  
# Line 419 | Line 484 | int main(int argc, char **argv)
484   #ifdef ENABLE_MON
485          // Setup SIGINT handler to enter mon
486          sigemptyset(&sigint_sa.sa_mask);
487 <        sigint_sa.sa_handler = sigint_handler;
487 >        sigint_sa.sa_handler = (void (*)(int))sigint_handler;
488          sigint_sa.sa_flags = 0;
489          sigaction(SIGINT, &sigint_sa, NULL);
490   #endif
# Line 428 | Line 493 | int main(int argc, char **argv)
493  
494          // POSIX.4 timers and real-time signals available, start 60Hz timer
495          sigemptyset(&timer_sa.sa_mask);
496 <        timer_sa.sa_sigaction = one_tick;
496 >        timer_sa.sa_sigaction = (void (*)(int, siginfo_t *, void *))one_tick;
497          timer_sa.sa_flags = SA_SIGINFO | SA_RESTART;
498          if (sigaction(SIG_TIMER, &timer_sa, NULL) < 0) {
499                  sprintf(str, GetString(STR_SIG_INSTALL_ERR), "SIG_TIMER", strerror(errno));
# Line 557 | Line 622 | void QuitEmulator(void)
622          // Deinitialize everything
623          ExitAll();
624  
625 <        // Delete ROM area
626 <        delete[] ROMBaseHost;
627 <
628 <        // Delete RAM area
629 <        delete[] RAMBaseHost;
625 >        // Free ROM/RAM areas
626 > #if REAL_ADDRESSING || DIRECT_ADDRESSING
627 >        if (memory_mapped_from_zero)
628 >                munmap((caddr_t)0x0000, mapped_ram_rom_size);
629 >        else if (RAMBaseHost != (uint8 *)MAP_FAILED) {
630 >                munmap((caddr_t)RAMBaseHost, mapped_ram_rom_size);
631 >                RAMBaseHost = NULL;
632 >        }
633 > #else
634 >        if (ROMBaseHost) {
635 >                free(ROMBaseHost);
636 >                ROMBaseHost = NULL;
637 >        }
638 >        if (RAMBaseHost) {
639 >                free(RAMBaseHost);
640 >                RAMBaseHost = NULL;
641 >        }
642 > #endif
643  
644 < #if !EMULATED_68K
644 > #if USE_SCRATCHMEM_SUBTERFUGE
645          // Delete scratch memory area
646 <        if (ScratchMem)
646 >        if (ScratchMem) {
647                  free((void *)(ScratchMem - SCRATCH_MEM_SIZE/2));
648 +                ScratchMem = NULL;
649 +        }
650   #endif
651  
652   #if REAL_ADDRESSING
# Line 618 | Line 698 | static void sigint_handler(...)
698          extern void m68k_dumpstate(uaecptr *nextpc);
699          m68k_dumpstate(&nextpc);
700   #else
701 <        char *arg[2] = {"rmon", NULL};
702 <        mon(1, arg);
701 >        char *arg[4] = {"mon", "-m", "-r", NULL};
702 >        mon(3, arg);
703          QuitEmulator();
704   #endif
705   }
# Line 665 | Line 745 | void TriggerInterrupt(void)
745          raise(SIG_IRQ);
746   #endif
747   }
748 +
749 + void TriggerNMI(void)
750 + {
751 +        // not yet supported
752 + }
753   #endif
754  
755  
# Line 684 | Line 769 | static void xpram_watchdog(void)
769   static void *xpram_func(void *arg)
770   {
771          while (!xpram_thread_cancel) {
772 <                for (int i=0; i<60 && !xpram_thread_cancel; i++) {
773 < #ifdef HAVE_NANOSLEEP
689 <                        struct timespec req = {1, 0};
690 <                        nanosleep(&req, NULL);
691 < #else
692 <                        usleep(1000000);
693 < #endif
694 <                }
772 >                for (int i=0; i<60 && !xpram_thread_cancel; i++)
773 >                        Delay_usec(1000000);
774                  xpram_watchdog();
775          }
776          return NULL;
# Line 708 | Line 787 | static void one_second(void)
787          // Pseudo Mac 1Hz interrupt, update local time
788          WriteMacInt32(0x20c, TimerDateTime());
789  
790 <        SetInterruptFlag(INTFLAG_60HZ);
790 >        SetInterruptFlag(INTFLAG_1HZ);
791          TriggerInterrupt();
792  
793   #ifndef HAVE_PTHREADS
# Line 743 | Line 822 | static void one_tick(...)
822   #ifdef HAVE_PTHREADS
823   static void *tick_func(void *arg)
824   {
825 +        uint64 next = GetTicks_usec();
826          while (!tick_thread_cancel) {
747
748                // Wait
749 #ifdef HAVE_NANOSLEEP
750                struct timespec req = {0, 16625000};
751                nanosleep(&req, NULL);
752 #else
753                usleep(16625);
754 #endif
755
756                // Action
827                  one_tick();
828 +                next += 16625;
829 +                int64 delay = next - GetTicks_usec();
830 +                if (delay > 0)
831 +                        Delay_usec(delay);
832 +                else if (delay < -16625)
833 +                        next = GetTicks_usec();
834          }
835          return NULL;
836   }
837   #endif
838  
839  
840 + /*
841 + *  Get current value of microsecond timer
842 + */
843 +
844 + uint64 GetTicks_usec(void)
845 + {
846 + #ifdef HAVE_CLOCK_GETTIME
847 +        struct timespec t;
848 +        clock_gettime(CLOCK_REALTIME, &t);
849 +        return (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000;
850 + #else
851 +        struct timeval t;
852 +        gettimeofday(&t, NULL);
853 +        return (uint64)t.tv_sec * 1000000 + t.tv_usec;
854 + #endif
855 + }
856 +
857 +
858 + /*
859 + *  Delay by specified number of microseconds (<1 second)
860 + *  (adapted from SDL_Delay() source)
861 + */
862 +
863 + void Delay_usec(uint32 usec)
864 + {
865 +        int was_error;
866 + #ifndef __linux__       // Non-Linux implementations need to calculate time left
867 +        uint64 then, now, elapsed;
868 + #endif
869 +        struct timeval tv;
870 +
871 +        // Set the timeout interval - Linux only needs to do this once
872 + #ifdef __linux__
873 +        tv.tv_sec = 0;
874 +        tv.tv_usec = usec;
875 + #else
876 +        then = GetTicks_usec();
877 + #endif
878 +        do {
879 +                errno = 0;
880 + #ifndef __linux__
881 +                /* Calculate the time interval left (in case of interrupt) */
882 +                now = GetTicks_usec();
883 +                elapsed = now - then;
884 +                then = now;
885 +                if (elapsed >= usec)
886 +                        break;
887 +                usec -= elapsed;
888 +                tv.tv_sec = 0;
889 +                tv.tv_usec = usec;
890 + #endif
891 +                was_error = select(0, NULL, NULL, NULL, &tv);
892 +        } while (was_error && (errno == EINTR));
893 + }
894 +
895 +
896   #if !EMULATED_68K
897   /*
898   *  Virtual 68k interrupt handler
# Line 1031 | Line 1163 | ill:           printf("SIGILL num %d, code %d\n",
1163                                  printf("  a%d %08x\n", i, state->ss_frame.f_regs[i+8]);
1164  
1165   #ifdef ENABLE_MON
1166 <                        char *arg[2] = {"rmon", NULL};
1167 <                        mon(1, arg);
1166 >                        char *arg[4] = {"mon", "-m", "-r", NULL};
1167 >                        mon(3, arg);
1168   #endif
1169                          QuitEmulator();
1170                          break;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines