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.31 by cebix, 2001-03-28T16:53:39Z

# Line 1 | Line 1
1   /*
2   *  main_unix.cpp - Startup code for Unix
3   *
4 < *  Basilisk II (C) 1997-2000 Christian Bauer
4 > *  Basilisk II (C) 1997-2001 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 30 | Line 30
30   # include <pthread.h>
31   #endif
32  
33 < #if defined(USE_MAPPED_MEMORY) || REAL_ADDRESSING
33 > #if REAL_ADDRESSING || DIRECT_ADDRESSING
34   # include <sys/mman.h>
35   #endif
36  
# Line 50 | Line 50 | struct sigstate {
50  
51   #ifdef ENABLE_GTK
52   # include <gtk/gtk.h>
53 + # include <gdk/gdk.h>
54   #endif
55  
56   #ifdef ENABLE_XF86_DGA
# Line 108 | Line 109 | char *x_display_name = NULL;                                           // X11
109   Display *x_display = NULL;                                                      // X11 display handle
110  
111   static int zero_fd = -1;                                                        // FD of /dev/zero
111 static bool lm_area_mapped = false;                                     // Flag: Low Memory area mmap()ped
112   static uint8 last_xpram[256];                                           // Buffer for monitoring XPRAM changes
113  
114   #ifdef HAVE_PTHREADS
# Line 134 | Line 134 | static struct sigaction sigirq_sa;     // Vi
134   static struct sigaction sigill_sa;      // Illegal instruction
135   static void *sig_stack = NULL;          // Stack for signal handlers
136   uint16 EmulatedSR;                                      // Emulated bits of SR (supervisor bit and interrupt mask)
137 < uint32 ScratchMem = NULL;                       // Scratch memory for Mac ROM writes
137 > #endif
138 >
139 > #if USE_SCRATCHMEM_SUBTERFUGE
140 > uint8 *ScratchMem = NULL;                       // 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 < #ifdef USE_MAPPED_MEMORY
156 < extern char *address_space, *good_address_map;
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 > #if REAL_ADDRESSING || DIRECT_ADDRESSING
161 > static uint32 mapped_ram_rom_size;              // Total size of mmap()ed RAM/ROM area
162   #endif
163  
164  
# Line 201 | Line 209 | int main(int argc, char **argv)
209          printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR);
210          printf(" %s\n", GetString(STR_ABOUT_TEXT2));
211  
212 <        // Parse arguments
212 > #ifdef ENABLE_GTK
213 >        // Init GTK
214 >        gtk_set_locale();
215 >        gtk_init(&argc, &argv);
216 >        x_display_name = gdk_get_display(); // gtk_init() handles and removes the "--display" argument
217 > #endif
218 >
219 >        // Parse and remove arguments
220          for (int i=1; i<argc; i++) {
221 <                if (strcmp(argv[i], "-display") == 0 && ++i < argc)
222 <                        x_display_name = argv[i];
223 <                else if (strcmp(argv[i], "-break") == 0 && ++i < argc)
224 <                        ROMBreakpoint = strtol(argv[i], NULL, 0);
225 <                else if (strcmp(argv[i], "-rominfo") == 0)
221 >                if (strcmp(argv[i], "--display") == 0) {
222 >                        argv[i] = NULL;
223 >                        if ((i + 1) < argc && argv[i + 1]) {
224 >                                argv[i++] = NULL;
225 >                                x_display_name = strdup(argv[i]);
226 >                        }
227 >                } else if (strcmp(argv[i], "--break") == 0) {
228 >                        argv[i] = NULL;
229 >                        if ((i + 1) < argc && argv[i + 1]) {
230 >                                argv[i++] = NULL;
231 >                                ROMBreakpoint = strtol(argv[i], NULL, 0);
232 >                        }
233 >                } else if (strcmp(argv[i], "--rominfo") == 0) {
234 >                        argv[i] = NULL;
235                          PrintROMInfo = true;
236 +                }
237 +        }
238 +        for (int i=1; i<argc; i++) {
239 +                int k;
240 +                for (k=i; k<argc; k++)
241 +                        if (argv[k] != NULL)
242 +                                break;
243 +                if (k > i) {
244 +                        k -= i;
245 +                        for (int j=i+k; j<argc; j++)
246 +                                argv[j-k] = argv[j];
247 +                        argc -= k;
248 +                }
249          }
250  
251          // Open display
# Line 225 | Line 262 | int main(int argc, char **argv)
262          XF86DGAForkApp(DefaultScreen(x_display));
263   #endif
264  
228 #ifdef ENABLE_GTK
229        // Init GTK
230        gtk_set_locale();
231        gtk_init(&argc, &argv);
232 #endif
233
265          // Read preferences
266 <        PrefsInit();
266 >        PrefsInit(argc, argv);
267  
268          // Init system routines
269          SysInit();
# Line 257 | Line 288 | int main(int argc, char **argv)
288                  RAMSize = 1024*1024;
289          }
290  
291 + #if REAL_ADDRESSING || DIRECT_ADDRESSING
292 +        const uint32 page_size = getpagesize();
293 +        const uint32 page_mask = page_size - 1;
294 +        const uint32 aligned_ram_size = (RAMSize + page_mask) & ~page_mask;
295 +        mapped_ram_rom_size = aligned_ram_size + 0x100000;
296 + #endif
297 +
298   #if REAL_ADDRESSING
299 +        // Try to allocate the complete address space from zero
300 +        // gb-- the Solaris manpage about mmap(2) states that using MAP_FIXED
301 +        // implies undefined behaviour for further use of sbrk(), malloc(), etc.
302 +        // cebix-- on NetBSD/m68k, this causes a segfault
303 + #if defined(OS_solaris) || defined(OS_netbsd)
304 +        // Anyway, it doesn't work...
305 +        if (0) {
306 + #else
307 +        if (mmap((caddr_t)0x0000, mapped_ram_rom_size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, zero_fd, 0) != MAP_FAILED) {
308 + #endif
309 +                D(bug("Could allocate RAM and ROM from 0x0000\n"));
310 +                memory_mapped_from_zero = true;
311 +        }
312          // Create Low Memory area (0x0000..0x2000)
313 <        if (mmap((char *)0x0000, 0x2000, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, zero_fd, 0) == (void *)-1) {
313 >        else if (mmap((char *)0x0000, 0x2000, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, zero_fd, 0) != MAP_FAILED) {
314 >                D(bug("Could allocate the Low Memory globals\n"));
315 >                lm_area_mapped = true;
316 >        }
317 >        // Exit on error
318 >        else {
319                  sprintf(str, GetString(STR_LOW_MEM_MMAP_ERR), strerror(errno));
320                  ErrorAlert(str);
321                  QuitEmulator();
322          }
267        lm_area_mapped = true;
323   #endif
324  
325 < #if !EMULATED_68K
325 > #if USE_SCRATCHMEM_SUBTERFUGE
326          // Allocate scratch memory
327 <        ScratchMem = (uint32)malloc(SCRATCH_MEM_SIZE);
327 >        ScratchMem = (uint8 *)malloc(SCRATCH_MEM_SIZE);
328          if (ScratchMem == NULL) {
329                  ErrorAlert(GetString(STR_NO_MEM_ERR));
330                  QuitEmulator();
# Line 278 | Line 333 | int main(int argc, char **argv)
333   #endif
334  
335          // Create areas for Mac RAM and ROM
336 < #if defined(USE_MAPPED_MEMORY)
337 <    good_address_map = (char *)mmap(NULL, 1<<24, PROT_READ, MAP_PRIVATE, zero_fd, 0);
338 <    address_space = (char *)mmap(NULL, 1<<24, PROT_READ | PROT_WRITE, MAP_PRIVATE, zero_fd, 0);
339 <    if ((int)address_space < 0 || (int)good_address_map < 0) {
340 <                ErrorAlert(GetString(STR_NOT_ENOUGH_MEMORY_ERR));
341 <                QuitEmulator();
342 <    }
343 <    RAMBaseHost = (uint8 *)mmap(address_space, RAMSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, zero_fd, 0);
344 <    ROMBaseHost = (uint8 *)mmap(address_space + 0x00400000, 0x80000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, zero_fd, 0);
345 <        char *nam = tmpnam(NULL);
346 <    int good_address_fd = open(nam, O_CREAT | O_RDWR, 0600);
347 <        char buffer[4096];
348 <    memset(buffer, 1, sizeof(buffer));
349 <    write(good_address_fd, buffer, sizeof(buffer));
350 <    unlink(nam);
351 <    for (int i=0; i<RAMSize; i+=4096)
352 <        mmap(good_address_map + i, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE, good_address_fd, 0);
353 <    for (int i=0; i<0x80000; i+=4096)
299 <        mmap(good_address_map + i + 0x00400000, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE, good_address_fd, 0);
336 > #if REAL_ADDRESSING || DIRECT_ADDRESSING
337 >        // gb-- Overkill, needs to be cleaned up. Probably explode it for either
338 >        // real or direct addressing mode.
339 > #if REAL_ADDRESSING
340 >        if (memory_mapped_from_zero) {
341 >                RAMBaseHost = (uint8 *)0;
342 >                ROMBaseHost = RAMBaseHost + aligned_ram_size;
343 >        }
344 >        else
345 > #endif
346 >        {
347 >                RAMBaseHost = (uint8 *)mmap(0, mapped_ram_rom_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, zero_fd, 0);
348 >                if (RAMBaseHost == (uint8 *)MAP_FAILED) {
349 >                        ErrorAlert(GetString(STR_NO_MEM_ERR));
350 >                        QuitEmulator();
351 >                }
352 >                ROMBaseHost = RAMBaseHost + aligned_ram_size;
353 >        }
354   #else
355 <        RAMBaseHost = new uint8[RAMSize];
356 <        ROMBaseHost = new uint8[0x100000];
355 >        RAMBaseHost = (uint8 *)malloc(RAMSize);
356 >        ROMBaseHost = (uint8 *)malloc(0x100000);
357 >        if (RAMBaseHost == NULL || ROMBaseHost == NULL) {
358 >                ErrorAlert(GetString(STR_NO_MEM_ERR));
359 >                QuitEmulator();
360 >        }
361   #endif
362 < #if REAL_ADDRESSING && !EMULATED_68K
362 >
363 > #if DIRECT_ADDRESSING
364 >        // Initialize MEMBaseDiff now so that Host2MacAddr in the Video module
365 >        // will return correct results
366 >        RAMBaseMac = 0;
367 >        ROMBaseMac = RAMBaseMac + aligned_ram_size;
368 >        InitMEMBaseDiff(RAMBaseHost, RAMBaseMac);
369 > #endif
370 > #if REAL_ADDRESSING // && !EMULATED_68K
371          RAMBaseMac = (uint32)RAMBaseHost;
372          ROMBaseMac = (uint32)ROMBaseHost;
373   #endif
374          D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac));
375          D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac));
376 <
376 >        
377          // Get rom file path from preferences
378          const char *rom_path = PrefsFindString("rom");
379  
# Line 356 | Line 422 | int main(int argc, char **argv)
422                  printf("WARNING: Cannot detect CPU type, assuming 68020\n");
423                  CPUType = 2;
424          }
425 <        FPUType = 0;    //!!
425 >        FPUType = 1;    // NetBSD has an FPU emulation, so the FPU ought to be available at all times
426          TwentyFourBitAddressing = false;
427   #endif
428  
# Line 419 | Line 485 | int main(int argc, char **argv)
485   #ifdef ENABLE_MON
486          // Setup SIGINT handler to enter mon
487          sigemptyset(&sigint_sa.sa_mask);
488 <        sigint_sa.sa_handler = sigint_handler;
488 >        sigint_sa.sa_handler = (void (*)(int))sigint_handler;
489          sigint_sa.sa_flags = 0;
490          sigaction(SIGINT, &sigint_sa, NULL);
491   #endif
# Line 428 | Line 494 | int main(int argc, char **argv)
494  
495          // POSIX.4 timers and real-time signals available, start 60Hz timer
496          sigemptyset(&timer_sa.sa_mask);
497 <        timer_sa.sa_sigaction = one_tick;
497 >        timer_sa.sa_sigaction = (void (*)(int, siginfo_t *, void *))one_tick;
498          timer_sa.sa_flags = SA_SIGINFO | SA_RESTART;
499          if (sigaction(SIG_TIMER, &timer_sa, NULL) < 0) {
500                  sprintf(str, GetString(STR_SIG_INSTALL_ERR), "SIG_TIMER", strerror(errno));
# Line 557 | Line 623 | void QuitEmulator(void)
623          // Deinitialize everything
624          ExitAll();
625  
626 <        // Delete ROM area
627 <        delete[] ROMBaseHost;
628 <
629 <        // Delete RAM area
630 <        delete[] RAMBaseHost;
626 >        // Free ROM/RAM areas
627 > #if REAL_ADDRESSING
628 >        if (memory_mapped_from_zero)
629 >                munmap((caddr_t)0x0000, mapped_ram_rom_size);
630 >        else
631 > #endif
632 > #if REAL_ADDRESSING || DIRECT_ADDRESSING
633 >        if (RAMBaseHost != (uint8 *)MAP_FAILED) {
634 >                munmap((caddr_t)RAMBaseHost, mapped_ram_rom_size);
635 >                RAMBaseHost = NULL;
636 >        }
637 > #else
638 >        if (ROMBaseHost) {
639 >                free(ROMBaseHost);
640 >                ROMBaseHost = NULL;
641 >        }
642 >        if (RAMBaseHost) {
643 >                free(RAMBaseHost);
644 >                RAMBaseHost = NULL;
645 >        }
646 > #endif
647  
648 < #if !EMULATED_68K
648 > #if USE_SCRATCHMEM_SUBTERFUGE
649          // Delete scratch memory area
650 <        if (ScratchMem)
650 >        if (ScratchMem) {
651                  free((void *)(ScratchMem - SCRATCH_MEM_SIZE/2));
652 +                ScratchMem = NULL;
653 +        }
654   #endif
655  
656   #if REAL_ADDRESSING
# Line 618 | Line 702 | static void sigint_handler(...)
702          extern void m68k_dumpstate(uaecptr *nextpc);
703          m68k_dumpstate(&nextpc);
704   #else
705 <        char *arg[2] = {"rmon", NULL};
706 <        mon(1, arg);
705 >        char *arg[4] = {"mon", "-m", "-r", NULL};
706 >        mon(3, arg);
707          QuitEmulator();
708   #endif
709   }
# Line 665 | Line 749 | void TriggerInterrupt(void)
749          raise(SIG_IRQ);
750   #endif
751   }
752 +
753 + void TriggerNMI(void)
754 + {
755 +        // not yet supported
756 + }
757   #endif
758  
759  
# Line 684 | Line 773 | static void xpram_watchdog(void)
773   static void *xpram_func(void *arg)
774   {
775          while (!xpram_thread_cancel) {
776 <                for (int i=0; i<60 && !xpram_thread_cancel; i++) {
777 < #ifdef HAVE_NANOSLEEP
689 <                        struct timespec req = {1, 0};
690 <                        nanosleep(&req, NULL);
691 < #else
692 <                        usleep(1000000);
693 < #endif
694 <                }
776 >                for (int i=0; i<60 && !xpram_thread_cancel; i++)
777 >                        Delay_usec(999999);             // Only wait 1 second so we quit promptly when xpram_thread_cancel becomes true
778                  xpram_watchdog();
779          }
780          return NULL;
# Line 708 | Line 791 | static void one_second(void)
791          // Pseudo Mac 1Hz interrupt, update local time
792          WriteMacInt32(0x20c, TimerDateTime());
793  
794 <        SetInterruptFlag(INTFLAG_60HZ);
794 >        SetInterruptFlag(INTFLAG_1HZ);
795          TriggerInterrupt();
796  
797   #ifndef HAVE_PTHREADS
# Line 743 | Line 826 | static void one_tick(...)
826   #ifdef HAVE_PTHREADS
827   static void *tick_func(void *arg)
828   {
829 +        uint64 next = GetTicks_usec();
830          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
831                  one_tick();
832 +                next += 16625;
833 +                int64 delay = next - GetTicks_usec();
834 +                if (delay > 0)
835 +                        Delay_usec(delay);
836 +                else if (delay < -16625)
837 +                        next = GetTicks_usec();
838          }
839          return NULL;
840   }
841   #endif
842  
843  
844 + /*
845 + *  Get current value of microsecond timer
846 + */
847 +
848 + uint64 GetTicks_usec(void)
849 + {
850 + #ifdef HAVE_CLOCK_GETTIME
851 +        struct timespec t;
852 +        clock_gettime(CLOCK_REALTIME, &t);
853 +        return (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000;
854 + #else
855 +        struct timeval t;
856 +        gettimeofday(&t, NULL);
857 +        return (uint64)t.tv_sec * 1000000 + t.tv_usec;
858 + #endif
859 + }
860 +
861 +
862 + /*
863 + *  Delay by specified number of microseconds (<1 second)
864 + *  (adapted from SDL_Delay() source; this function is designed to provide
865 + *  the highest accuracy possible)
866 + */
867 +
868 + #if defined(linux)
869 + // Linux select() changes its timeout parameter upon return to contain
870 + // the remaining time. Most other unixen leave it unchanged or undefined.
871 + #define SELECT_SETS_REMAINING
872 + #elif defined(__FreeBSD__) || defined(__sun__)
873 + #define USE_NANOSLEEP
874 + #elif defined(HAVE_PTHREADS) && defined(sgi)
875 + // SGI pthreads has a bug when using pthreads+signals+nanosleep,
876 + // so instead of using nanosleep, wait on a CV which is never signalled.
877 + #define USE_COND_TIMEDWAIT
878 + #endif
879 +
880 + void Delay_usec(uint32 usec)
881 + {
882 +        int was_error;
883 +
884 + #if defined(USE_NANOSLEEP)
885 +        struct timespec elapsed, tv;
886 + #elif defined(USE_COND_TIMEDWAIT)
887 +        // Use a local mutex and cv, so threads remain independent
888 +        pthread_cond_t delay_cond = PTHREAD_COND_INITIALIZER;
889 +        pthread_mutex_t delay_mutex = PTHREAD_MUTEX_INITIALIZER;
890 +        struct timespec elapsed;
891 +        uint64 future;
892 + #else
893 +        struct timeval tv;
894 + #ifndef SELECT_SETS_REMAINING
895 +        uint64 then, now, elapsed;
896 + #endif
897 + #endif
898 +
899 +        // Set the timeout interval - Linux only needs to do this once
900 + #if defined(SELECT_SETS_REMAINING)
901 +    tv.tv_sec = 0;
902 +    tv.tv_usec = usec;
903 + #elif defined(USE_NANOSLEEP)
904 +    elapsed.tv_sec = 0;
905 +    elapsed.tv_nsec = usec * 1000;
906 + #elif defined(USE_COND_TIMEDWAIT)
907 +        future = GetTicks_usec() + usec;
908 +        elapsed.tv_sec = future / 1000000;
909 +        elapsed.tv_nsec = (future % 1000000) * 1000;
910 + #else
911 +    then = GetTicks_usec();
912 + #endif
913 +
914 +        do {
915 +                errno = 0;
916 + #if defined(USE_NANOSLEEP)
917 +                tv.tv_sec = elapsed.tv_sec;
918 +                tv.tv_nsec = elapsed.tv_nsec;
919 +                was_error = nanosleep(&tv, &elapsed);
920 + #elif defined(USE_COND_TIMEDWAIT)
921 +                was_error = pthread_mutex_lock(&delay_mutex);
922 +                was_error = pthread_cond_timedwait(&delay_cond, &delay_mutex, &elapsed);
923 +                was_error = pthread_mutex_unlock(&delay_mutex);
924 + #else
925 + #ifndef SELECT_SETS_REMAINING
926 +                // Calculate the time interval left (in case of interrupt)
927 +                now = GetTicks_usec();
928 +                elapsed = now - then;
929 +                then = now;
930 +                if (elapsed >= usec)
931 +                        break;
932 +                usec -= elapsed;
933 +                tv.tv_sec = 0;
934 +                tv.tv_usec = usec;
935 + #endif
936 +                was_error = select(0, NULL, NULL, NULL, &tv);
937 + #endif
938 +        } while (was_error && (errno == EINTR));
939 + }
940 +
941 +
942   #if !EMULATED_68K
943   /*
944   *  Virtual 68k interrupt handler
# Line 811 | Line 989 | static void sigill_handler(int sig, int
989  
990   #define STORE_SR(v) \
991          scp->sc_ps = (v) & 0xff; \
992 <        EmulatedSR = (v) & 0x2700; \
992 >        EmulatedSR = (v) & 0xe700; \
993          if (((v) & 0x0700) == 0 && InterruptFlags) \
994                  TriggerInterrupt();
995  
# Line 874 | Line 1052 | static void sigill_handler(int sig, int
1052                  case 0x007c: {  // ori #xxxx,sr
1053                          uint16 sr = GET_SR | pc[1];
1054                          scp->sc_ps = sr & 0xff;         // oring bits into the sr can't enable interrupts, so we don't need to call STORE_SR
1055 <                        EmulatedSR = sr & 0x2700;
1055 >                        EmulatedSR = sr & 0xe700;
1056                          INC_PC(4);
1057                          break;
1058                  }
# Line 951 | Line 1129 | static void sigill_handler(int sig, int
1129                  }
1130  
1131                  case 0xf327:    // fsave -(sp)
1132 <                        goto ill;       //!!
1132 >                        if (CPUIs68060) {
1133 >                                regs->a[7] -= 4;
1134 >                                WriteMacInt32(regs->a[7], 0x60000000);  // Idle frame
1135 >                                regs->a[7] -= 4;
1136 >                                WriteMacInt32(regs->a[7], 0);
1137 >                                regs->a[7] -= 4;
1138 >                                WriteMacInt32(regs->a[7], 0);
1139 >                        } else {
1140 >                                regs->a[7] -= 4;
1141 >                                WriteMacInt32(regs->a[7], 0x41000000);  // Idle frame
1142 >                        }
1143 >                        scp->sc_sp = regs->a[7];
1144 >                        INC_PC(2);
1145 >                        break;
1146  
1147                  case 0xf35f:    // frestore (sp)+
1148 <                        goto ill;       //!!
1148 >                        if (CPUIs68060)
1149 >                                regs->a[7] += 12;
1150 >                        else
1151 >                                regs->a[7] += 4;
1152 >                        scp->sc_sp = regs->a[7];
1153 >                        INC_PC(2);
1154 >                        break;
1155  
1156 <                case 0x4e73: {  // rte (only handles format 0)
1156 >                case 0x4e73: {  // rte
1157                          uint32 a7 = regs->a[7];
1158                          uint16 sr = ReadMacInt16(a7);
1159                          a7 += 2;
1160                          scp->sc_ps = sr & 0xff;
1161 <                        EmulatedSR = sr & 0x2700;
1161 >                        EmulatedSR = sr & 0xe700;
1162                          scp->sc_pc = ReadMacInt32(a7);
1163 <                        a7 += 6;
1164 <                        scp->sc_sp = regs->a[7] = a7;
1163 >                        a7 += 4;
1164 >                        uint16 format = ReadMacInt16(a7) >> 12;
1165 >                        a7 += 2;
1166 >                        static const int frame_adj[16] = {
1167 >                                0, 0, 4, 4, 8, 0, 0, 52, 50, 12, 24, 84, 16, 0, 0, 0
1168 >                        };
1169 >                        scp->sc_sp = regs->a[7] = a7 + frame_adj[format];
1170                          break;
1171                  }
1172  
1173                  case 0x4e7a:    // movec cr,x
1174                          switch (pc[1]) {
973                                case 0x8801:    // movec vbr,a0
974                                        regs->a[0] = 0;
975                                        break;
976                                case 0x9801:    // movec vbr,a1
977                                        regs->a[1] = 0;
978                                        break;
1175                                  case 0x0002:    // movec cacr,d0
1176                                          regs->d[0] = 0x3111;
1177                                          break;
# Line 983 | Line 1179 | static void sigill_handler(int sig, int
1179                                          regs->d[1] = 0x3111;
1180                                          break;
1181                                  case 0x0003:    // movec tc,d0
1182 +                                case 0x0004:    // movec itt0,d0
1183 +                                case 0x0005:    // movec itt1,d0
1184 +                                case 0x0006:    // movec dtt0,d0
1185 +                                case 0x0007:    // movec dtt1,d0
1186 +                                case 0x0806:    // movec urp,d0
1187 +                                case 0x0807:    // movec srp,d0
1188                                          regs->d[0] = 0;
1189                                          break;
1190 +                                case 0x1000:    // movec sfc,d1
1191 +                                case 0x1001:    // movec dfc,d1
1192                                  case 0x1003:    // movec tc,d1
1193 +                                case 0x1801:    // movec vbr,d1
1194                                          regs->d[1] = 0;
1195                                          break;
1196 +                                case 0x8801:    // movec vbr,a0
1197 +                                        regs->a[0] = 0;
1198 +                                        break;
1199 +                                case 0x9801:    // movec vbr,a1
1200 +                                        regs->a[1] = 0;
1201 +                                        break;
1202                                  default:
1203                                          goto ill;
1204                          }
# Line 996 | Line 1207 | static void sigill_handler(int sig, int
1207  
1208                  case 0x4e7b:    // movec x,cr
1209                          switch (pc[1]) {
1210 +                                case 0x1000:    // movec d1,sfc
1211 +                                case 0x1001:    // movec d1,dfc
1212                                  case 0x0801:    // movec d0,vbr
1213 +                                case 0x1801:    // movec d1,vbr
1214                                          break;
1215                                  case 0x0002:    // movec d0,cacr
1216                                  case 0x1002:    // movec d1,cacr
# Line 1031 | Line 1245 | ill:           printf("SIGILL num %d, code %d\n",
1245                                  printf("  a%d %08x\n", i, state->ss_frame.f_regs[i+8]);
1246  
1247   #ifdef ENABLE_MON
1248 <                        char *arg[2] = {"rmon", NULL};
1249 <                        mon(1, arg);
1248 >                        char *arg[4] = {"mon", "-m", "-r", NULL};
1249 >                        mon(3, arg);
1250   #endif
1251                          QuitEmulator();
1252                          break;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines