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.17 by cebix, 2000-07-24T15:17:07Z vs.
Revision 1.25 by cebix, 2000-11-02T14:45: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 133 | 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 150 | Line 153 | static void sigint_handler(...);
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
# Line 260 | 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          }
270        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 300 | 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 = (uint8 *)malloc(RAMSize);
355          ROMBaseHost = (uint8 *)malloc(0x100000);
306 #endif
356          if (RAMBaseHost == NULL || ROMBaseHost == NULL) {
357                  ErrorAlert(GetString(STR_NO_MEM_ERR));
358                  QuitEmulator();
359          }
360 < #if REAL_ADDRESSING && !EMULATED_68K
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
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 363 | Line 421 | int main(int argc, char **argv)
421                  printf("WARNING: Cannot detect CPU type, assuming 68020\n");
422                  CPUType = 2;
423          }
424 <        FPUType = 0;    //!!
424 >        FPUType = 1;    // NetBSD has an FPU emulation, so the FPU ought to be available at all times
425          TwentyFourBitAddressing = false;
426   #endif
427  
# Line 426 | 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 435 | 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 564 | Line 622 | void QuitEmulator(void)
622          // Deinitialize everything
623          ExitAll();
624  
625 <        // Delete ROM area
625 >        // Free ROM/RAM areas
626 > #if REAL_ADDRESSING
627 >        if (memory_mapped_from_zero)
628 >                munmap((caddr_t)0x0000, mapped_ram_rom_size);
629 >        else
630 > #endif
631 > #if REAL_ADDRESSING || DIRECT_ADDRESSING
632 >        if (RAMBaseHost != (uint8 *)MAP_FAILED) {
633 >                munmap((caddr_t)RAMBaseHost, mapped_ram_rom_size);
634 >                RAMBaseHost = NULL;
635 >        }
636 > #else
637          if (ROMBaseHost) {
638                  free(ROMBaseHost);
639                  ROMBaseHost = NULL;
640          }
572
573        // Delete RAM area
641          if (RAMBaseHost) {
642                  free(RAMBaseHost);
643                  RAMBaseHost = NULL;
644          }
645 + #endif
646  
647 < #if !EMULATED_68K
647 > #if USE_SCRATCHMEM_SUBTERFUGE
648          // Delete scratch memory area
649          if (ScratchMem) {
650                  free((void *)(ScratchMem - SCRATCH_MEM_SIZE/2));
# Line 633 | Line 701 | static void sigint_handler(...)
701          extern void m68k_dumpstate(uaecptr *nextpc);
702          m68k_dumpstate(&nextpc);
703   #else
704 <        char *arg[2] = {"rmon", NULL};
705 <        mon(1, arg);
704 >        char *arg[4] = {"mon", "-m", "-r", NULL};
705 >        mon(3, arg);
706          QuitEmulator();
707   #endif
708   }
# Line 680 | Line 748 | void TriggerInterrupt(void)
748          raise(SIG_IRQ);
749   #endif
750   }
751 +
752 + void TriggerNMI(void)
753 + {
754 +        // not yet supported
755 + }
756   #endif
757  
758  
# Line 717 | Line 790 | static void one_second(void)
790          // Pseudo Mac 1Hz interrupt, update local time
791          WriteMacInt32(0x20c, TimerDateTime());
792  
793 <        SetInterruptFlag(INTFLAG_60HZ);
793 >        SetInterruptFlag(INTFLAG_1HZ);
794          TriggerInterrupt();
795  
796   #ifndef HAVE_PTHREADS
# Line 787 | Line 860 | uint64 GetTicks_usec(void)
860  
861   /*
862   *  Delay by specified number of microseconds (<1 second)
863 < *  (adapted from SDL_Delay() source)
863 > *  (adapted from SDL_Delay() source; this function is designed to provide
864 > *  the highest accuracy possible)
865   */
866  
867   void Delay_usec(uint32 usec)
868   {
869          int was_error;
870 < #ifndef __linux__       // Non-Linux implementations need to calculate time left
870 >
871 > #if defined(linux)
872 >        struct timeval tv;
873 > #elif defined(__FreeBSD__) || defined(sgi)
874 >        struct timespec elapsed, tv;
875 > #else   // Non-Linux implementations need to calculate time left
876          uint64 then, now, elapsed;
877   #endif
799        struct timeval tv;
878  
879          // Set the timeout interval - Linux only needs to do this once
880 < #ifdef __linux__
880 > #if defined(linux)
881          tv.tv_sec = 0;
882          tv.tv_usec = usec;
883 + #elif defined(__FreeBSD__)
884 +        elapsed.tv_sec = 0;
885 +        elapsed.tv_nsec = usec * 1000;
886   #else
887          then = GetTicks_usec();
888   #endif
889          do {
890                  errno = 0;
891 < #ifndef __linux__
891 > #if !defined(linux) && !defined(__FreeBSD__) && !defined(sgi)
892                  /* Calculate the time interval left (in case of interrupt) */
893                  now = GetTicks_usec();
894                  elapsed = now - then;
# Line 818 | Line 899 | void Delay_usec(uint32 usec)
899                  tv.tv_sec = 0;
900                  tv.tv_usec = usec;
901   #endif
902 + #if defined(__FreeBSD__) || defined(sgi)
903 +                tv.tv_sec = elapsed.tv_sec;
904 +                tv.tv_nsec = elapsed.tv_nsec;
905 +                was_error = nanosleep(&tv, &elapsed);
906 + #else
907                  was_error = select(0, NULL, NULL, NULL, &tv);
908 + #endif
909          } while (was_error && (errno == EINTR));
910   }
911  
# Line 873 | Line 960 | static void sigill_handler(int sig, int
960  
961   #define STORE_SR(v) \
962          scp->sc_ps = (v) & 0xff; \
963 <        EmulatedSR = (v) & 0x2700; \
963 >        EmulatedSR = (v) & 0xe700; \
964          if (((v) & 0x0700) == 0 && InterruptFlags) \
965                  TriggerInterrupt();
966  
# Line 936 | Line 1023 | static void sigill_handler(int sig, int
1023                  case 0x007c: {  // ori #xxxx,sr
1024                          uint16 sr = GET_SR | pc[1];
1025                          scp->sc_ps = sr & 0xff;         // oring bits into the sr can't enable interrupts, so we don't need to call STORE_SR
1026 <                        EmulatedSR = sr & 0x2700;
1026 >                        EmulatedSR = sr & 0xe700;
1027                          INC_PC(4);
1028                          break;
1029                  }
# Line 1013 | Line 1100 | static void sigill_handler(int sig, int
1100                  }
1101  
1102                  case 0xf327:    // fsave -(sp)
1103 <                        goto ill;       //!!
1103 >                        if (CPUIs68060) {
1104 >                                regs->a[7] -= 4;
1105 >                                WriteMacInt32(regs->a[7], 0x60000000);  // Idle frame
1106 >                                regs->a[7] -= 4;
1107 >                                WriteMacInt32(regs->a[7], 0);
1108 >                                regs->a[7] -= 4;
1109 >                                WriteMacInt32(regs->a[7], 0);
1110 >                        } else {
1111 >                                regs->a[7] -= 4;
1112 >                                WriteMacInt32(regs->a[7], 0x41000000);  // Idle frame
1113 >                        }
1114 >                        scp->sc_sp = regs->a[7];
1115 >                        INC_PC(2);
1116 >                        break;
1117  
1118                  case 0xf35f:    // frestore (sp)+
1119 <                        goto ill;       //!!
1119 >                        if (CPUIs68060)
1120 >                                regs->a[7] += 12;
1121 >                        else
1122 >                                regs->a[7] += 4;
1123 >                        scp->sc_sp = regs->a[7];
1124 >                        INC_PC(2);
1125 >                        break;
1126  
1127 <                case 0x4e73: {  // rte (only handles format 0)
1127 >                case 0x4e73: {  // rte
1128                          uint32 a7 = regs->a[7];
1129                          uint16 sr = ReadMacInt16(a7);
1130                          a7 += 2;
1131                          scp->sc_ps = sr & 0xff;
1132 <                        EmulatedSR = sr & 0x2700;
1132 >                        EmulatedSR = sr & 0xe700;
1133                          scp->sc_pc = ReadMacInt32(a7);
1134 <                        a7 += 6;
1135 <                        scp->sc_sp = regs->a[7] = a7;
1134 >                        a7 += 4;
1135 >                        uint16 format = ReadMacInt16(a7) >> 12;
1136 >                        a7 += 2;
1137 >                        static const int frame_adj[16] = {
1138 >                                0, 0, 4, 4, 8, 0, 0, 52, 50, 12, 24, 84, 16, 0, 0, 0
1139 >                        };
1140 >                        scp->sc_sp = regs->a[7] = a7 + frame_adj[format];
1141                          break;
1142                  }
1143  
1144                  case 0x4e7a:    // movec cr,x
1145                          switch (pc[1]) {
1035                                case 0x8801:    // movec vbr,a0
1036                                        regs->a[0] = 0;
1037                                        break;
1038                                case 0x9801:    // movec vbr,a1
1039                                        regs->a[1] = 0;
1040                                        break;
1146                                  case 0x0002:    // movec cacr,d0
1147                                          regs->d[0] = 0x3111;
1148                                          break;
# Line 1045 | Line 1150 | static void sigill_handler(int sig, int
1150                                          regs->d[1] = 0x3111;
1151                                          break;
1152                                  case 0x0003:    // movec tc,d0
1153 +                                case 0x0004:    // movec itt0,d0
1154 +                                case 0x0005:    // movec itt1,d0
1155 +                                case 0x0006:    // movec dtt0,d0
1156 +                                case 0x0007:    // movec dtt1,d0
1157 +                                case 0x0806:    // movec urp,d0
1158 +                                case 0x0807:    // movec srp,d0
1159                                          regs->d[0] = 0;
1160                                          break;
1161 +                                case 0x1000:    // movec sfc,d1
1162 +                                case 0x1001:    // movec dfc,d1
1163                                  case 0x1003:    // movec tc,d1
1164 +                                case 0x1801:    // movec vbr,d1
1165                                          regs->d[1] = 0;
1166                                          break;
1167 +                                case 0x8801:    // movec vbr,a0
1168 +                                        regs->a[0] = 0;
1169 +                                        break;
1170 +                                case 0x9801:    // movec vbr,a1
1171 +                                        regs->a[1] = 0;
1172 +                                        break;
1173                                  default:
1174                                          goto ill;
1175                          }
# Line 1058 | Line 1178 | static void sigill_handler(int sig, int
1178  
1179                  case 0x4e7b:    // movec x,cr
1180                          switch (pc[1]) {
1181 +                                case 0x1000:    // movec d1,sfc
1182 +                                case 0x1001:    // movec d1,dfc
1183                                  case 0x0801:    // movec d0,vbr
1184 +                                case 0x1801:    // movec d1,vbr
1185                                          break;
1186                                  case 0x0002:    // movec d0,cacr
1187                                  case 0x1002:    // movec d1,cacr
# Line 1093 | Line 1216 | ill:           printf("SIGILL num %d, code %d\n",
1216                                  printf("  a%d %08x\n", i, state->ss_frame.f_regs[i+8]);
1217  
1218   #ifdef ENABLE_MON
1219 <                        char *arg[2] = {"rmon", NULL};
1220 <                        mon(1, arg);
1219 >                        char *arg[4] = {"mon", "-m", "-r", NULL};
1220 >                        mon(3, arg);
1221   #endif
1222                          QuitEmulator();
1223                          break;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines