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

Comparing SheepShaver/src/Unix/main_unix.cpp (file contents):
Revision 1.4 by gbeauche, 2003-05-13T16:59:57Z vs.
Revision 1.18 by gbeauche, 2003-12-05T12:36:10Z

# Line 108 | Line 108
108   #include "rom_patches.h"
109   #include "user_strings.h"
110   #include "vm_alloc.h"
111 + #include "sigsegv.h"
112 + #include "thunks.h"
113  
114   #define DEBUG 0
115   #include "debug.h"
# Line 144 | Line 146
146   const char ROM_FILE_NAME[] = "ROM";
147   const char ROM_FILE_NAME2[] = "Mac OS ROM";
148  
149 < const uint32 ROM_AREA_SIZE = 0x500000;          // Size of ROM area
148 < const uint32 ROM_END = ROM_BASE + ROM_SIZE;     // End of ROM
149 <
150 < const uint32 KERNEL_DATA_BASE = 0x68ffe000;     // Address of Kernel Data
151 < const uint32 KERNEL_DATA2_BASE = 0x5fffe000;    // Alternate address of Kernel Data
152 < const uint32 KERNEL_AREA_SIZE = 0x2000;         // Size of Kernel Data area
153 <
149 > const uintptr RAM_BASE = 0x20000000;            // Base address of RAM
150   const uint32 SIG_STACK_SIZE = 0x10000;          // Size of signal stack
151  
152  
157 // 68k Emulator Data
158 struct EmulatorData {
159        uint32  v[0x400];      
160 };
161
162
163 // Kernel Data
164 struct KernelData {
165        uint32  v[0x400];
166        EmulatorData ed;
167 };
168
169
153   #if !EMULATED_PPC
154   // Structure in which registers are saved in a signal handler;
155   // sigcontext->regs points to it
# Line 198 | Line 181 | int64 BusClockSpeed;   // Bus clock speed
181  
182  
183   // Global variables
184 < static char *x_display_name = NULL;                     // X11 display name
184 > char *x_display_name = NULL;                            // X11 display name
185   Display *x_display = NULL;                                      // X11 display handle
186  
187   static int zero_fd = 0;                                         // FD of /dev/zero
# Line 206 | Line 189 | static bool lm_area_mapped = false;                    //
189   static int kernel_area = -1;                            // SHM ID of Kernel Data area
190   static bool rom_area_mapped = false;            // Flag: Mac ROM mmap()ped
191   static bool ram_area_mapped = false;            // Flag: Mac RAM mmap()ped
209 static void *mmap_RAMBase = NULL;                       // Base address of mmap()ed RAM area
192   static KernelData *kernel_data;                         // Pointer to Kernel Data
193   static EmulatorData *emulator_data;
194  
# Line 221 | Line 203 | static pthread_t emul_thread;                          // MacO
203   static bool ready_for_signals = false;          // Handler installed, signals can be sent
204   static int64 num_segv = 0;                                      // Number of handled SEGV signals
205  
224 #if !EMULATED_PPC
206   static struct sigaction sigusr2_action;         // Interrupt signal (of emulator thread)
207 + #if !EMULATED_PPC
208   static struct sigaction sigsegv_action;         // Data access exception signal (of emulator thread)
209   static struct sigaction sigill_action;          // Illegal instruction signal (of emulator thread)
210   static void *sig_stack = NULL;                          // Stack for signal handlers
# Line 231 | Line 213 | static bool emul_thread_fatal = false;
213   static sigregs sigsegv_regs;                            // Register dump when crashed
214   #endif
215  
216 + uintptr SheepMem::zero_page = 0;                        // Address of ro page filled in with zeros
217 + uintptr SheepMem::base = 0x60000000;            // Address of SheepShaver data
218 + uintptr SheepMem::top = 0;                                      // Top of SheepShaver data (stack like storage)
219 +
220  
221   // Prototypes
222   static void Quit(void);
223   static void *emul_func(void *arg);
224   static void *nvram_func(void *arg);
225   static void *tick_func(void *arg);
226 < #if !EMULATED_PPC
226 > #if EMULATED_PPC
227 > static void sigusr2_handler(int sig);
228 > extern void emul_ppc(uint32 start);
229 > extern void init_emul_ppc(void);
230 > extern void exit_emul_ppc(void);
231 > #else
232   static void sigusr2_handler(int sig, sigcontext_struct *sc);
233   static void sigsegv_handler(int sig, sigcontext_struct *sc);
234   static void sigill_handler(int sig, sigcontext_struct *sc);
# Line 245 | Line 236 | static void sigill_handler(int sig, sigc
236  
237  
238   // From asm_linux.S
239 < #if EMULATED_PPC
249 < extern int atomic_add(int *var, int v);
250 < extern int atomic_and(int *var, int v);
251 < extern int atomic_or(int *var, int v);
252 < #else
239 > #if !EMULATED_PPC
240   extern "C" void *get_toc(void);
241   extern "C" void *get_sp(void);
242   extern "C" void flush_icache_range(void *start, void *end);
# Line 264 | Line 251 | extern void paranoia_check(void);
251   #endif
252  
253  
254 + #if EMULATED_PPC
255 + /*
256 + *  Atomic operations
257 + */
258 +
259 + #if HAVE_SPINLOCKS
260 + static spinlock_t atomic_ops_lock = SPIN_LOCK_UNLOCKED;
261 + #else
262 + #define spin_lock(LOCK)
263 + #define spin_unlock(LOCK)
264 + #endif
265 +
266 + int atomic_add(int *var, int v)
267 + {
268 +        spin_lock(&atomic_ops_lock);
269 +        int ret = *var;
270 +        *var += v;
271 +        spin_unlock(&atomic_ops_lock);
272 +        return ret;
273 + }
274 +
275 + int atomic_and(int *var, int v)
276 + {
277 +        spin_lock(&atomic_ops_lock);
278 +        int ret = *var;
279 +        *var &= v;
280 +        spin_unlock(&atomic_ops_lock);
281 +        return ret;
282 + }
283 +
284 + int atomic_or(int *var, int v)
285 + {
286 +        spin_lock(&atomic_ops_lock);
287 +        int ret = *var;
288 +        *var |= v;
289 +        spin_unlock(&atomic_ops_lock);
290 +        return ret;
291 + }
292 + #endif
293 +
294 +
295   /*
296   *  Main program
297   */
# Line 282 | Line 310 | int main(int argc, char **argv)
310          char str[256];
311          uint32 *boot_globs;
312          int16 i16;
285        int drive, driver;
313          int rom_fd;
314          FILE *proc_file;
315          const char *rom_path;
# Line 292 | Line 319 | int main(int argc, char **argv)
319  
320          // Initialize variables
321          RAMBase = 0;
295        mmap_RAMBase = NULL;
322          tzset();
323  
324          // Print some info
# Line 445 | Line 471 | int main(int argc, char **argv)
471                  ErrorAlert(str);
472                  goto quit;
473          }
474 <        kernel_data = (KernelData *)0x68ffe000;
474 >        kernel_data = (KernelData *)KERNEL_DATA_BASE;
475          emulator_data = &kernel_data->ed;
476 <        KernelDataAddr = (uint32)kernel_data;
476 >        KernelDataAddr = KERNEL_DATA_BASE;
477          D(bug("Kernel Data at %p, Emulator Data at %p\n", kernel_data, emulator_data));
478  
479 +        // Create area for SheepShaver data
480 +        if (!SheepMem::Init()) {
481 +                sprintf(str, GetString(STR_SHEEP_MEM_MMAP_ERR), strerror(errno));
482 +                ErrorAlert(str);
483 +                goto quit;
484 +        }
485 +
486          // Create area for Mac ROM
487          if (vm_acquire_fixed((char *)ROM_BASE, ROM_AREA_SIZE) < 0) {
488                  sprintf(str, GetString(STR_ROM_MMAP_ERR), strerror(errno));
489                  ErrorAlert(str);
490                  goto quit;
491          }
492 < #if !EMULATED_PPC
492 > #if !EMULATED_PPC || defined(__powerpc__)
493          if (vm_protect((char *)ROM_BASE, ROM_AREA_SIZE, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE) < 0) {
494                  sprintf(str, GetString(STR_ROM_MMAP_ERR), strerror(errno));
495                  ErrorAlert(str);
# Line 473 | Line 506 | int main(int argc, char **argv)
506                  RAMSize = 8*1024*1024;
507          }
508  
509 <        mmap_RAMBase = (void *)0x20000000;
477 <        if (vm_acquire_fixed(mmap_RAMBase, RAMSize) < 0) {
509 >        if (vm_acquire_fixed((char *)RAM_BASE, RAMSize) < 0) {
510                  sprintf(str, GetString(STR_RAM_MMAP_ERR), strerror(errno));
511                  ErrorAlert(str);
512                  goto quit;
513          }
514   #if !EMULATED_PPC
515 <        if (vm_protect(mmap_RAMBase, RAMSize, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE) < 0) {
515 >        if (vm_protect((char *)RAM_BASE, RAMSize, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE) < 0) {
516                  sprintf(str, GetString(STR_RAM_MMAP_ERR), strerror(errno));
517                  ErrorAlert(str);
518                  goto quit;
519          }
520   #endif
521 <        RAMBase = (uint32)mmap_RAMBase;
521 >        RAMBase = RAM_BASE;
522          ram_area_mapped = true;
523          D(bug("RAM area at %08x\n", RAMBase));
524  
# Line 528 | Line 560 | int main(int argc, char **argv)
560          XPRAMInit();
561  
562          // Set boot volume
563 <        drive = PrefsFindInt32("bootdrive");
563 >        i16 = PrefsFindInt32("bootdrive");
564          XPRAM[0x1378] = i16 >> 8;
565          XPRAM[0x1379] = i16 & 0xff;
566 <        driver = PrefsFindInt32("bootdriver");
566 >        i16 = PrefsFindInt32("bootdriver");
567          XPRAM[0x137a] = i16 >> 8;
568          XPRAM[0x137b] = i16 & 0xff;
569  
# Line 544 | Line 576 | int main(int argc, char **argv)
576          boot_globs[1] = htonl(RAMSize);
577          boot_globs[2] = htonl((uint32)-1);                      // End of bank table
578  
579 +        // Init thunks
580 +        if (!ThunksInit())
581 +                goto quit;
582 +
583          // Init drivers
584          SonyInit();
585          DiskInit();
# Line 587 | Line 623 | int main(int argc, char **argv)
623          // Initialize Kernel Data
624          memset(kernel_data, 0, sizeof(KernelData));
625          if (ROMType == ROMTYPE_NEWWORLD) {
626 <                static uint32 of_dev_tree[4] = {0, 0, 0, 0};
627 <                static uint8 vector_lookup_tbl[128];
628 <                static uint8 vector_mask_tbl[64];
626 >                uintptr of_dev_tree = SheepMem::Reserve(4 * sizeof(uint32));
627 >                memset((void *)of_dev_tree, 0, 4 * sizeof(uint32));
628 >                uintptr vector_lookup_tbl = SheepMem::Reserve(128);
629 >                uintptr vector_mask_tbl = SheepMem::Reserve(64);
630                  memset((uint8 *)kernel_data + 0xb80, 0x3d, 0x80);
631 <                memset(vector_lookup_tbl, 0, 128);
632 <                memset(vector_mask_tbl, 0, 64);
631 >                memset((void *)vector_lookup_tbl, 0, 128);
632 >                memset((void *)vector_mask_tbl, 0, 64);
633                  kernel_data->v[0xb80 >> 2] = htonl(ROM_BASE);
634 <                kernel_data->v[0xb84 >> 2] = htonl((uint32)of_dev_tree);        // OF device tree base
635 <                kernel_data->v[0xb90 >> 2] = htonl((uint32)vector_lookup_tbl);
636 <                kernel_data->v[0xb94 >> 2] = htonl((uint32)vector_mask_tbl);
634 >                kernel_data->v[0xb84 >> 2] = htonl(of_dev_tree);                        // OF device tree base
635 >                kernel_data->v[0xb90 >> 2] = htonl(vector_lookup_tbl);
636 >                kernel_data->v[0xb94 >> 2] = htonl(vector_mask_tbl);
637                  kernel_data->v[0xb98 >> 2] = htonl(ROM_BASE);                           // OpenPIC base
638                  kernel_data->v[0xbb0 >> 2] = htonl(0);                                          // ADB base
639                  kernel_data->v[0xc20 >> 2] = htonl(RAMSize);
# Line 632 | Line 669 | int main(int argc, char **argv)
669          D(bug("Initializing Low Memory...\n"));
670          memset(NULL, 0, 0x3000);
671          WriteMacInt32(XLM_SIGNATURE, FOURCC('B','a','a','h'));                  // Signature to detect SheepShaver
672 <        WriteMacInt32(XLM_KERNEL_DATA, (uint32)kernel_data);                    // For trap replacement routines
672 >        WriteMacInt32(XLM_KERNEL_DATA, KernelDataAddr);                                 // For trap replacement routines
673          WriteMacInt32(XLM_PVR, PVR);                                                                    // Theoretical PVR
674          WriteMacInt32(XLM_BUS_CLOCK, BusClockSpeed);                                    // For DriverServicesLib patch
675          WriteMacInt16(XLM_EXEC_RETURN_OPCODE, M68K_EXEC_RETURN);                // For Execute68k() (RTS from the executed 68k code will jump here and end 68k mode)
676 +        WriteMacInt32(XLM_ZERO_PAGE, SheepMem::ZeroPage());                             // Pointer to read-only page with all bits set to 0
677   #if !EMULATED_PPC
678 <        WriteMacInt32(XLM_TOC, (uint32)TOC);                                                    // TOC pointer of emulator
641 <        WriteMacInt32(XLM_ETHER_INIT, (uint32)InitStreamModule);                // DLPI ethernet driver functions
642 <        WriteMacInt32(XLM_ETHER_TERM, (uint32)TerminateStreamModule);
643 <        WriteMacInt32(XLM_ETHER_OPEN, (uint32)ether_open);
644 <        WriteMacInt32(XLM_ETHER_CLOSE, (uint32)ether_close);
645 <        WriteMacInt32(XLM_ETHER_WPUT, (uint32)ether_wput);
646 <        WriteMacInt32(XLM_ETHER_RSRV, (uint32)ether_rsrv);
647 <        WriteMacInt32(XLM_VIDEO_DOIO, (uint32)VideoDoDriverIO);
678 >        WriteMacInt32(XLM_TOC, (uint32)TOC);                                                            // TOC pointer of emulator
679   #endif
680 +        WriteMacInt32(XLM_ETHER_INIT, NativeFunction(NATIVE_ETHER_INIT));       // DLPI ethernet driver functions
681 +        WriteMacInt32(XLM_ETHER_TERM, NativeFunction(NATIVE_ETHER_TERM));
682 +        WriteMacInt32(XLM_ETHER_OPEN, NativeFunction(NATIVE_ETHER_OPEN));
683 +        WriteMacInt32(XLM_ETHER_CLOSE, NativeFunction(NATIVE_ETHER_CLOSE));
684 +        WriteMacInt32(XLM_ETHER_WPUT, NativeFunction(NATIVE_ETHER_WPUT));
685 +        WriteMacInt32(XLM_ETHER_RSRV, NativeFunction(NATIVE_ETHER_RSRV));
686 +        WriteMacInt32(XLM_VIDEO_DOIO, NativeFunction(NATIVE_VIDEO_DO_DRIVER_IO));
687          D(bug("Low Memory initialized\n"));
688  
689          // Start 60Hz thread
# Line 706 | Line 744 | int main(int argc, char **argv)
744                  ErrorAlert(str);
745                  goto quit;
746          }
747 + #endif
748  
749          // Install interrupt signal handler
750          sigemptyset(&sigusr2_action.sa_mask);
751          sigusr2_action.sa_handler = (__sighandler_t)sigusr2_handler;
752 +        sigusr2_action.sa_flags = 0;
753 + #if !EMULATED_PPC
754          sigusr2_action.sa_flags = SA_ONSTACK | SA_RESTART;
755 + #endif
756          sigusr2_action.sa_restorer = NULL;
757          if (sigaction(SIGUSR2, &sigusr2_action, NULL) < 0) {
758                  sprintf(str, GetString(STR_SIGUSR2_INSTALL_ERR), strerror(errno));
759                  ErrorAlert(str);
760                  goto quit;
761          }
720 #endif
762  
763          // Get my thread ID and execute MacOS thread function
764          emul_thread = pthread_self();
# Line 736 | Line 777 | quit:
777  
778   static void Quit(void)
779   {
780 + #if EMULATED_PPC
781 +        // Exit PowerPC emulation
782 +        exit_emul_ppc();
783 + #endif
784 +
785          // Stop 60Hz thread
786          if (tick_thread_active) {
787                  pthread_cancel(tick_thread);
# Line 792 | Line 838 | static void Quit(void)
838          DiskExit();
839          SonyExit();
840  
841 +        // Delete SheepShaver globals
842 +        SheepMem::Exit();
843 +
844          // Delete RAM area
845          if (ram_area_mapped)
846 <                vm_release(mmap_RAMBase, RAMSize);
846 >                vm_release((char *)RAM_BASE, RAMSize);
847  
848          // Delete ROM area
849          if (rom_area_mapped)
# Line 839 | Line 888 | static void Quit(void)
888   */
889  
890   #if EMULATED_PPC
842 extern void emul_ppc(uint32 start);
843 extern void init_emul_ppc(void);
891   void jump_to_rom(uint32 entry)
892   {
893          init_emul_ppc();
# Line 909 | Line 956 | void Execute68kTrap(uint16 trap, M68kReg
956  
957  
958   /*
912 *  Execute PPC code from EMUL_OP routine (real mode switch)
913 */
914
915 void ExecutePPC(void (*func)())
916 {
917        uint32 tvect[2] = {(uint32)func, 0};    // Fake TVECT
918        RoutineDescriptor desc = BUILD_PPC_ROUTINE_DESCRIPTOR(0, tvect);
919        M68kRegisters r;
920        Execute68k((uint32)&desc, &r);
921 }
922
923
924 /*
959   *  Quit emulator (cause return from jump_to_rom)
960   */
961  
# Line 980 | Line 1014 | void Dump68kRegs(M68kRegisters *r)
1014  
1015   void MakeExecutable(int dummy, void *start, uint32 length)
1016   {
1017 < #if !EMULATED_PPC
984 <        if (((uint32)start >= ROM_BASE) && ((uint32)start < (ROM_BASE + ROM_SIZE)))
1017 >        if (((uintptr)start >= ROM_BASE) && ((uintptr)start < (ROM_BASE + ROM_SIZE)))
1018                  return;
1019 <        flush_icache_range(start, (void *)((uint32)start + length));
1019 > #if EMULATED_PPC
1020 >        FlushCodeCache((uintptr)start, (uintptr)start + length);
1021 > #else
1022 >        flush_icache_range(start, (void *)((uintptr)start + length));
1023   #endif
1024   }
1025  
# Line 994 | Line 1030 | void MakeExecutable(int dummy, void *sta
1030  
1031   void PatchAfterStartup(void)
1032   {
1033 <        ExecutePPC(VideoInstallAccel);
1033 >        ExecuteNative(NATIVE_VIDEO_INSTALL_ACCEL);
1034          InstallExtFS();
1035   }
1036  
# Line 1097 | Line 1133 | static void *tick_func(void *arg)
1133  
1134   void Set_pthread_attr(pthread_attr_t *attr, int priority)
1135   {
1136 <        // nothing to do
1136 > #ifdef HAVE_PTHREADS
1137 >        pthread_attr_init(attr);
1138 > #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
1139 >        // Some of these only work for superuser
1140 >        if (geteuid() == 0) {
1141 >                pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
1142 >                pthread_attr_setschedpolicy(attr, SCHED_FIFO);
1143 >                struct sched_param fifo_param;
1144 >                fifo_param.sched_priority = ((sched_get_priority_min(SCHED_FIFO) +
1145 >                                              sched_get_priority_max(SCHED_FIFO)) / 2 +
1146 >                                             priority);
1147 >                pthread_attr_setschedparam(attr, &fifo_param);
1148 >        }
1149 >        if (pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM) != 0) {
1150 > #ifdef PTHREAD_SCOPE_BOUND_NP
1151 >            // If system scope is not available (eg. we're not running
1152 >            // with CAP_SCHED_MGT capability on an SGI box), try bound
1153 >            // scope.  It exposes pthread scheduling to the kernel,
1154 >            // without setting realtime priority.
1155 >            pthread_attr_setscope(attr, PTHREAD_SCOPE_BOUND_NP);
1156 > #endif
1157 >        }
1158 > #endif
1159 > #endif
1160   }
1161  
1162  
# Line 1105 | Line 1164 | void Set_pthread_attr(pthread_attr_t *at
1164   *  Mutexes
1165   */
1166  
1167 + #ifdef HAVE_PTHREADS
1168 +
1169 + struct B2_mutex {
1170 +        B2_mutex() {
1171 +            pthread_mutexattr_t attr;
1172 +            pthread_mutexattr_init(&attr);
1173 +            // Initialize the mutex for priority inheritance --
1174 +            // required for accurate timing.
1175 + #ifdef HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL
1176 +            pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
1177 + #endif
1178 + #if defined(HAVE_PTHREAD_MUTEXATTR_SETTYPE) && defined(PTHREAD_MUTEX_NORMAL)
1179 +            pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
1180 + #endif
1181 + #ifdef HAVE_PTHREAD_MUTEXATTR_SETPSHARED
1182 +            pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
1183 + #endif
1184 +            pthread_mutex_init(&m, &attr);
1185 +            pthread_mutexattr_destroy(&attr);
1186 +        }
1187 +        ~B2_mutex() {
1188 +            pthread_mutex_trylock(&m); // Make sure it's locked before
1189 +            pthread_mutex_unlock(&m);  // unlocking it.
1190 +            pthread_mutex_destroy(&m);
1191 +        }
1192 +        pthread_mutex_t m;
1193 + };
1194 +
1195 + B2_mutex *B2_create_mutex(void)
1196 + {
1197 +        return new B2_mutex;
1198 + }
1199 +
1200 + void B2_lock_mutex(B2_mutex *mutex)
1201 + {
1202 +        pthread_mutex_lock(&mutex->m);
1203 + }
1204 +
1205 + void B2_unlock_mutex(B2_mutex *mutex)
1206 + {
1207 +        pthread_mutex_unlock(&mutex->m);
1208 + }
1209 +
1210 + void B2_delete_mutex(B2_mutex *mutex)
1211 + {
1212 +        delete mutex;
1213 + }
1214 +
1215 + #else
1216 +
1217   struct B2_mutex {
1218          int dummy;
1219   };
# Line 1127 | Line 1236 | void B2_delete_mutex(B2_mutex *mutex)
1236          delete mutex;
1237   }
1238  
1239 + #endif
1240 +
1241  
1242   /*
1243   *  Trigger signal USR2 from another thread
1244   */
1245  
1246 + #if !EMULATED_PPC || ASYNC_IRQ
1247   void TriggerInterrupt(void)
1248   {
1137 #if EMULATED_PPC
1138        WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1);
1139 #else
1140 #if 0
1141        WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1);
1142 #else
1249          if (ready_for_signals)
1250                  pthread_kill(emul_thread, SIGUSR2);
1145 #endif
1146 #endif
1251   }
1252 + #endif
1253  
1254  
1255   /*
# Line 1184 | Line 1289 | void EnableInterrupt(void)
1289   }
1290  
1291  
1187 #if !EMULATED_PPC
1292   /*
1293   *  USR2 handler
1294   */
1295  
1296 + #if EMULATED_PPC
1297 + static void sigusr2_handler(int sig)
1298 + {
1299 + #if ASYNC_IRQ
1300 +        extern void HandleInterrupt(void);
1301 +        HandleInterrupt();
1302 + #endif
1303 + }
1304 + #else
1305   static void sigusr2_handler(int sig, sigcontext_struct *sc)
1306   {
1307          pt_regs *r = sc->regs;
# Line 1258 | Line 1371 | static void sigusr2_handler(int sig, sig
1371                                          if (InterruptFlags & INTFLAG_VIA) {
1372                                                  ClearInterruptFlag(INTFLAG_VIA);
1373                                                  ADBInterrupt();
1374 <                                                ExecutePPC(VideoVBL);
1374 >                                                ExecuteNative(NATIVE_VIDEO_VBL);
1375                                          }
1376                                  }
1377   #endif
# Line 1270 | Line 1383 | static void sigusr2_handler(int sig, sig
1383                          }
1384                          break;
1385   #endif
1273
1386          }
1387   }
1388 + #endif
1389  
1390  
1391   /*
1392   *  SIGSEGV handler
1393   */
1394  
1395 + #if !EMULATED_PPC
1396   static void sigsegv_handler(int sig, sigcontext_struct *sc)
1397   {
1398          pt_regs *r = sc->regs;
1399 +
1400 +        // Get effective address
1401 +        uint32 addr = r->dar;
1402 +        
1403 + #if ENABLE_VOSF
1404 +        // Handle screen fault.
1405 +        extern bool Screen_fault_handler(sigsegv_address_t fault_address, sigsegv_address_t fault_instruction);
1406 +        if (Screen_fault_handler((sigsegv_address_t)addr, (sigsegv_address_t)r->nip))
1407 +                return;
1408 + #endif
1409 +
1410          num_segv++;
1411  
1412          // Fault in Mac ROM or RAM?
1413          bool mac_fault = (r->nip >= ROM_BASE) && (r->nip < (ROM_BASE + ROM_AREA_SIZE)) || (r->nip >= RAMBase) && (r->nip < (RAMBase + RAMSize));
1414          if (mac_fault) {
1415  
1291                // Get opcode and divide into fields
1292                uint32 opcode = *((uint32 *)r->nip);
1293                uint32 primop = opcode >> 26;
1294                uint32 exop = (opcode >> 1) & 0x3ff;
1295                uint32 ra = (opcode >> 16) & 0x1f;
1296                uint32 rb = (opcode >> 11) & 0x1f;
1297                uint32 rd = (opcode >> 21) & 0x1f;
1298                int32 imm = (int16)(opcode & 0xffff);
1299
1416                  // "VM settings" during MacOS 8 installation
1417                  if (r->nip == ROM_BASE + 0x488160 && r->gpr[20] == 0xf8000000) {
1418                          r->nip += 4;
# Line 1324 | Line 1440 | static void sigsegv_handler(int sig, sig
1440                          return;
1441                  }
1442  
1443 +                // Get opcode and divide into fields
1444 +                uint32 opcode = *((uint32 *)r->nip);
1445 +                uint32 primop = opcode >> 26;
1446 +                uint32 exop = (opcode >> 1) & 0x3ff;
1447 +                uint32 ra = (opcode >> 16) & 0x1f;
1448 +                uint32 rb = (opcode >> 11) & 0x1f;
1449 +                uint32 rd = (opcode >> 21) & 0x1f;
1450 +                int32 imm = (int16)(opcode & 0xffff);
1451 +
1452                  // Analyze opcode
1453                  enum {
1454                          TYPE_UNKNOWN,
# Line 1407 | Line 1532 | static void sigsegv_handler(int sig, sig
1532                                  transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break;
1533                  }
1534          
1410                // Calculate effective address
1411                uint32 addr = 0;
1412                switch (addr_mode) {
1413                        case MODE_X:
1414                        case MODE_UX:
1415                                if (ra == 0)
1416                                        addr = r->gpr[rb];
1417                                else
1418                                        addr = r->gpr[ra] + r->gpr[rb];
1419                                break;
1420                        case MODE_NORM:
1421                        case MODE_U:
1422                                if (ra == 0)
1423                                        addr = (int32)(int16)imm;
1424                                else
1425                                        addr = r->gpr[ra] + (int32)(int16)imm;
1426                                break;
1427                        default:
1428                                break;
1429                }
1430
1535                  // Ignore ROM writes
1536                  if (transfer_type == TYPE_STORE && addr >= ROM_BASE && addr < ROM_BASE + ROM_SIZE) {
1537   //                      D(bug("WARNING: %s write access to ROM at %08lx, pc %08lx\n", transfer_size == SIZE_BYTE ? "Byte" : transfer_size == SIZE_HALFWORD ? "Halfword" : "Word", addr, r->nip));
# Line 1664 | Line 1768 | rti:;
1768  
1769  
1770   /*
1771 + *  Helpers to share 32-bit addressable data with MacOS
1772 + */
1773 +
1774 + bool SheepMem::Init(void)
1775 + {
1776 +        if (vm_acquire_fixed((char *)base, size) < 0)
1777 +                return false;
1778 +
1779 +        zero_page = base + size;
1780 +
1781 +        int page_size = getpagesize();
1782 +        if (vm_acquire_fixed((char *)zero_page, page_size) < 0)
1783 +                return false;
1784 +        if (vm_protect((char *)zero_page, page_size, VM_PAGE_READ) < 0)
1785 +                return false;
1786 +
1787 +        top = base + size;
1788 +        return true;
1789 + }
1790 +
1791 + void SheepMem::Exit(void)
1792 + {
1793 +        if (top) {
1794 +                // The zero page is next to SheepShaver globals
1795 +                vm_release((void *)base, size + getpagesize());
1796 +        }
1797 + }
1798 +
1799 +
1800 + /*
1801   *  Display alert
1802   */
1803  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines