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.20 by gbeauche, 2000-09-22T17:14:28Z

# 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 > uint8 *ScratchMem = NULL;                       // Scratch memory for Mac ROM writes
137 > #endif
138 >
139 > #if USE_SCRATCHMEM_SUBTERFUGE
140 > uint8 *ScratchMem = 0;                          // Scratch memory for Mac ROM writes
141   #endif
142  
143   static struct sigaction timer_sa;       // sigaction used for timer
# Line 149 | Line 152 | static struct sigaction sigint_sa;     // si
152   static void sigint_handler(...);
153   #endif
154  
155 + #if REAL_ADDRESSING
156 + static bool lm_area_mapped = false;     // Flag: Low Memory area mmap()ped
157 + static bool memory_mapped_from_zero = false; // Flag: Could allocate RAM area from 0
158 + #endif
159 +
160   #ifdef USE_MAPPED_MEMORY
161   extern char *address_space, *good_address_map;
162   #endif
# Line 257 | Line 265 | int main(int argc, char **argv)
265                  RAMSize = 1024*1024;
266          }
267  
268 + #if REAL_ADDRESSING || DIRECT_ADDRESSING
269 +        const uint32 page_size = getpagesize();
270 +        const uint32 page_mask = page_size - 1;
271 +        const uint32 aligned_ram_size = (RAMSize + page_mask) & ~page_mask;
272 +        const uint32 ram_rom_size = aligned_ram_size + 0x100000;
273 + #endif
274 +
275   #if REAL_ADDRESSING
276 +        // Try to allocate the complete address space from zero
277 +        // gb-- the Solaris manpage about mmap(2) states that using MAP_FIXED
278 +        // implies undefined behaviour for further use of sbrk(), malloc(), etc.
279 + #if defined(OS_solaris)
280 +        // Anyway, it doesn't work...
281 +        if (0) {
282 + #else
283 +        if (mmap((caddr_t)0x0000, ram_rom_size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, zero_fd, 0) != MAP_FAILED) {
284 + #endif
285 +                D(bug("Could allocate RAM and ROM from 0x0000\n"));
286 +                memory_mapped_from_zero = true;
287 +        }
288          // Create Low Memory area (0x0000..0x2000)
289 <        if (mmap((char *)0x0000, 0x2000, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, zero_fd, 0) == (void *)-1) {
289 >        else if (mmap((char *)0x0000, 0x2000, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, zero_fd, 0) != MAP_FAILED) {
290 >                D(bug("Could allocate the Low Memory globals\n"));
291 >                lm_area_mapped = true;
292 >        }
293 >        // Exit on error
294 >        else {
295                  sprintf(str, GetString(STR_LOW_MEM_MMAP_ERR), strerror(errno));
296                  ErrorAlert(str);
297                  QuitEmulator();
298          }
267        lm_area_mapped = true;
299   #endif
300  
301 < #if !EMULATED_68K
301 > #if !EMULATED_68K || USE_SCRATCHMEM_SUBTERFUGE
302          // Allocate scratch memory
303 <        ScratchMem = (uint32)malloc(SCRATCH_MEM_SIZE);
303 >        ScratchMem = (uint8 *)malloc(SCRATCH_MEM_SIZE);
304          if (ScratchMem == NULL) {
305                  ErrorAlert(GetString(STR_NO_MEM_ERR));
306                  QuitEmulator();
# Line 297 | Line 328 | int main(int argc, char **argv)
328          mmap(good_address_map + i, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE, good_address_fd, 0);
329      for (int i=0; i<0x80000; i+=4096)
330          mmap(good_address_map + i + 0x00400000, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE, good_address_fd, 0);
331 + #elif REAL_ADDRESSING || DIRECT_ADDRESSING
332 +        // gb-- Overkill, needs to be cleaned up. Probably explode it for either
333 +        // real or direct addressing mode.
334 + #if REAL_ADDRESSING
335 +        if (memory_mapped_from_zero) {
336 +                RAMBaseHost = (uint8 *)0;
337 +                ROMBaseHost = RAMBaseHost + aligned_ram_size;
338 +        }
339 +        else
340 + #endif
341 +        {
342 +                RAMBaseHost = (uint8 *)mmap(0, ram_rom_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, zero_fd, 0);
343 +                if (RAMBaseHost == (uint8 *)MAP_FAILED) {
344 +                        ErrorAlert(GetString(STR_NO_MEM_ERR));
345 +                        QuitEmulator();
346 +                }
347 +                ROMBaseHost = RAMBaseHost + aligned_ram_size;
348 +        }
349   #else
350 <        RAMBaseHost = new uint8[RAMSize];
351 <        ROMBaseHost = new uint8[0x100000];
350 >        RAMBaseHost = (uint8 *)malloc(RAMSize);
351 >        ROMBaseHost = (uint8 *)malloc(0x100000);
352 >        if (RAMBaseHost == NULL || ROMBaseHost == NULL) {
353 >                ErrorAlert(GetString(STR_NO_MEM_ERR));
354 >                QuitEmulator();
355 >        }
356 > #endif
357 > #if DIRECT_ADDRESSING
358 >        // Initialize MEMBaseDiff now so that Host2MacAddr in the Video module
359 >        // will return correct results
360 >        RAMBaseMac = 0;
361 >        ROMBaseMac = RAMBaseMac + aligned_ram_size;
362 >        InitMEMBaseDiff(RAMBaseHost, RAMBaseMac);
363   #endif
364 < #if REAL_ADDRESSING && !EMULATED_68K
364 > #if REAL_ADDRESSING // && !EMULATED_68K
365          RAMBaseMac = (uint32)RAMBaseHost;
366          ROMBaseMac = (uint32)ROMBaseHost;
367   #endif
368          D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac));
369          D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac));
370 <
370 >        
371          // Get rom file path from preferences
372          const char *rom_path = PrefsFindString("rom");
373  
# Line 428 | Line 488 | int main(int argc, char **argv)
488  
489          // POSIX.4 timers and real-time signals available, start 60Hz timer
490          sigemptyset(&timer_sa.sa_mask);
491 <        timer_sa.sa_sigaction = one_tick;
491 >        timer_sa.sa_sigaction = (void (*)(int, siginfo_t *, void *))one_tick;
492          timer_sa.sa_flags = SA_SIGINFO | SA_RESTART;
493          if (sigaction(SIG_TIMER, &timer_sa, NULL) < 0) {
494                  sprintf(str, GetString(STR_SIG_INSTALL_ERR), "SIG_TIMER", strerror(errno));
# Line 557 | Line 617 | void QuitEmulator(void)
617          // Deinitialize everything
618          ExitAll();
619  
620 + #if REAL_ADDRESSING || DIRECT_ADDRESSING
621 +        // Unmap ROM area
622 +        if (ROMBaseHost != (uint8 *)MAP_FAILED) {
623 +                munmap((caddr_t)ROMBaseHost, 0x100000);
624 +                ROMBaseHost = 0;
625 +        }
626 +        
627 +        //Unmap RAM area
628 +        if (RAMBaseHost != (uint8 *)MAP_FAILED) {
629 +                const uint32 page_size = getpagesize();
630 +                const uint32 page_mask = page_size - 1;
631 +                munmap((caddr_t)RAMBaseHost, ((RAMSize + page_mask) & ~page_mask));
632 +        }
633 + #else
634          // Delete ROM area
635 <        delete[] ROMBaseHost;
635 >        if (ROMBaseHost) {
636 >                free(ROMBaseHost);
637 >                ROMBaseHost = NULL;
638 >        }
639  
640          // Delete RAM area
641 <        delete[] RAMBaseHost;
641 >        if (RAMBaseHost) {
642 >                free(RAMBaseHost);
643 >                RAMBaseHost = NULL;
644 >        }
645 > #endif
646  
647 < #if !EMULATED_68K
647 > #if !EMULATED_68K || USE_SCRATMEM_SUBTERFUGE
648          // Delete scratch memory area
649 <        if (ScratchMem)
649 >        if (ScratchMem) {
650                  free((void *)(ScratchMem - SCRATCH_MEM_SIZE/2));
651 +                ScratchMem = NULL;
652 +        }
653   #endif
654  
655   #if REAL_ADDRESSING
# Line 684 | Line 767 | static void xpram_watchdog(void)
767   static void *xpram_func(void *arg)
768   {
769          while (!xpram_thread_cancel) {
770 <                for (int i=0; i<60 && !xpram_thread_cancel; i++) {
771 < #ifdef HAVE_NANOSLEEP
689 <                        struct timespec req = {1, 0};
690 <                        nanosleep(&req, NULL);
691 < #else
692 <                        usleep(1000000);
693 < #endif
694 <                }
770 >                for (int i=0; i<60 && !xpram_thread_cancel; i++)
771 >                        Delay_usec(1000000);
772                  xpram_watchdog();
773          }
774          return NULL;
# Line 708 | Line 785 | static void one_second(void)
785          // Pseudo Mac 1Hz interrupt, update local time
786          WriteMacInt32(0x20c, TimerDateTime());
787  
788 <        SetInterruptFlag(INTFLAG_60HZ);
788 >        SetInterruptFlag(INTFLAG_1HZ);
789          TriggerInterrupt();
790  
791   #ifndef HAVE_PTHREADS
# Line 743 | Line 820 | static void one_tick(...)
820   #ifdef HAVE_PTHREADS
821   static void *tick_func(void *arg)
822   {
823 +        uint64 next = GetTicks_usec();
824          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
825                  one_tick();
826 +                next += 16625;
827 +                int64 delay = next - GetTicks_usec();
828 +                if (delay > 0)
829 +                        Delay_usec(delay);
830 +                else if (delay < -16625)
831 +                        next = GetTicks_usec();
832          }
833          return NULL;
834   }
835   #endif
836  
837  
838 + /*
839 + *  Get current value of microsecond timer
840 + */
841 +
842 + uint64 GetTicks_usec(void)
843 + {
844 + #ifdef HAVE_CLOCK_GETTIME
845 +        struct timespec t;
846 +        clock_gettime(CLOCK_REALTIME, &t);
847 +        return (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000;
848 + #else
849 +        struct timeval t;
850 +        gettimeofday(&t, NULL);
851 +        return (uint64)t.tv_sec * 1000000 + t.tv_usec;
852 + #endif
853 + }
854 +
855 +
856 + /*
857 + *  Delay by specified number of microseconds (<1 second)
858 + *  (adapted from SDL_Delay() source)
859 + */
860 +
861 + void Delay_usec(uint32 usec)
862 + {
863 +        int was_error;
864 + #ifndef __linux__       // Non-Linux implementations need to calculate time left
865 +        uint64 then, now, elapsed;
866 + #endif
867 +        struct timeval tv;
868 +
869 +        // Set the timeout interval - Linux only needs to do this once
870 + #ifdef __linux__
871 +        tv.tv_sec = 0;
872 +        tv.tv_usec = usec;
873 + #else
874 +        then = GetTicks_usec();
875 + #endif
876 +        do {
877 +                errno = 0;
878 + #ifndef __linux__
879 +                /* Calculate the time interval left (in case of interrupt) */
880 +                now = GetTicks_usec();
881 +                elapsed = now - then;
882 +                then = now;
883 +                if (elapsed >= usec)
884 +                        break;
885 +                usec -= elapsed;
886 +                tv.tv_sec = 0;
887 +                tv.tv_usec = usec;
888 + #endif
889 +                was_error = select(0, NULL, NULL, NULL, &tv);
890 +        } while (was_error && (errno == EINTR));
891 + }
892 +
893 +
894   #if !EMULATED_68K
895   /*
896   *  Virtual 68k interrupt handler

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines