mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-12-23 19:29:18 +00:00
- Integrate new NativeOp instructions to be used as trampolines to call
native functions from ppc code. - Little endian fixes in emul_op.cpp - Add new 'gpch' 750 patch to workaround crash with MacOS 8.6 - Don't crash in Process Manager on reset/shutdown with MacOS 8.6 - We also have an experimental interrupt thread in emulation mode
This commit is contained in:
parent
15a1208483
commit
cb1dd6dac5
@ -32,6 +32,9 @@
|
||||
/* Define if using XFree86 VidMode extension. */
|
||||
#undef ENABLE_XF86_VIDMODE
|
||||
|
||||
/* Define is using PowerPC emulator. */
|
||||
#undef EMULATED_PPC
|
||||
|
||||
|
||||
/* Leave that blank line there!! Autoheader needs it.
|
||||
If you're adding to this file, keep in mind:
|
||||
|
@ -222,8 +222,8 @@ static pthread_t emul_thread; // MacOS thread
|
||||
static bool ready_for_signals = false; // Handler installed, signals can be sent
|
||||
static int64 num_segv = 0; // Number of handled SEGV signals
|
||||
|
||||
#if !EMULATED_PPC
|
||||
static struct sigaction sigusr2_action; // Interrupt signal (of emulator thread)
|
||||
#if !EMULATED_PPC
|
||||
static struct sigaction sigsegv_action; // Data access exception signal (of emulator thread)
|
||||
static struct sigaction sigill_action; // Illegal instruction signal (of emulator thread)
|
||||
static void *sig_stack = NULL; // Stack for signal handlers
|
||||
@ -238,8 +238,8 @@ static void Quit(void);
|
||||
static void *emul_func(void *arg);
|
||||
static void *nvram_func(void *arg);
|
||||
static void *tick_func(void *arg);
|
||||
#if !EMULATED_PPC
|
||||
static void sigusr2_handler(int sig, sigcontext_struct *sc);
|
||||
#if !EMULATED_PPC
|
||||
static void sigsegv_handler(int sig, sigcontext_struct *sc);
|
||||
static void sigill_handler(int sig, sigcontext_struct *sc);
|
||||
#endif
|
||||
@ -457,7 +457,7 @@ int main(int argc, char **argv)
|
||||
ErrorAlert(str);
|
||||
goto quit;
|
||||
}
|
||||
#if !EMULATED_PPC
|
||||
#if !EMULATED_PPC || defined(__powerpc__)
|
||||
if (vm_protect((char *)ROM_BASE, ROM_AREA_SIZE, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE) < 0) {
|
||||
sprintf(str, GetString(STR_ROM_MMAP_ERR), strerror(errno));
|
||||
ErrorAlert(str);
|
||||
@ -637,7 +637,15 @@ int main(int argc, char **argv)
|
||||
WriteMacInt32(XLM_PVR, PVR); // Theoretical PVR
|
||||
WriteMacInt32(XLM_BUS_CLOCK, BusClockSpeed); // For DriverServicesLib patch
|
||||
WriteMacInt16(XLM_EXEC_RETURN_OPCODE, M68K_EXEC_RETURN); // For Execute68k() (RTS from the executed 68k code will jump here and end 68k mode)
|
||||
#if !EMULATED_PPC
|
||||
#if EMULATED_PPC
|
||||
WriteMacInt32(XLM_ETHER_INIT, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_INIT));
|
||||
WriteMacInt32(XLM_ETHER_TERM, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_TERM));
|
||||
WriteMacInt32(XLM_ETHER_OPEN, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_OPEN));
|
||||
WriteMacInt32(XLM_ETHER_CLOSE, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_CLOSE));
|
||||
WriteMacInt32(XLM_ETHER_WPUT, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_WPUT));
|
||||
WriteMacInt32(XLM_ETHER_RSRV, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_RSRV));
|
||||
WriteMacInt32(XLM_VIDEO_DOIO, POWERPC_NATIVE_OP_FUNC(NATIVE_VIDEO_DO_DRIVER_IO));
|
||||
#else
|
||||
WriteMacInt32(XLM_TOC, (uint32)TOC); // TOC pointer of emulator
|
||||
WriteMacInt32(XLM_ETHER_INIT, (uint32)InitStreamModule); // DLPI ethernet driver functions
|
||||
WriteMacInt32(XLM_ETHER_TERM, (uint32)TerminateStreamModule);
|
||||
@ -707,18 +715,21 @@ int main(int argc, char **argv)
|
||||
ErrorAlert(str);
|
||||
goto quit;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Install interrupt signal handler
|
||||
sigemptyset(&sigusr2_action.sa_mask);
|
||||
sigusr2_action.sa_handler = (__sighandler_t)sigusr2_handler;
|
||||
sigusr2_action.sa_flags = 0;
|
||||
#if !EMULATED_PPC
|
||||
sigusr2_action.sa_flags = SA_ONSTACK | SA_RESTART;
|
||||
#endif
|
||||
sigusr2_action.sa_restorer = NULL;
|
||||
if (sigaction(SIGUSR2, &sigusr2_action, NULL) < 0) {
|
||||
sprintf(str, GetString(STR_SIGUSR2_INSTALL_ERR), strerror(errno));
|
||||
ErrorAlert(str);
|
||||
goto quit;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get my thread ID and execute MacOS thread function
|
||||
emul_thread = pthread_self();
|
||||
@ -995,7 +1006,11 @@ void MakeExecutable(int dummy, void *start, uint32 length)
|
||||
|
||||
void PatchAfterStartup(void)
|
||||
{
|
||||
#if EMULATED_PPC
|
||||
ExecuteNative(NATIVE_VIDEO_INSTALL_ACCEL);
|
||||
#else
|
||||
ExecutePPC(VideoInstallAccel);
|
||||
#endif
|
||||
InstallExtFS();
|
||||
}
|
||||
|
||||
@ -1135,16 +1150,8 @@ void B2_delete_mutex(B2_mutex *mutex)
|
||||
|
||||
void TriggerInterrupt(void)
|
||||
{
|
||||
#if EMULATED_PPC
|
||||
WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1);
|
||||
#else
|
||||
#if 0
|
||||
WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1);
|
||||
#else
|
||||
if (ready_for_signals)
|
||||
pthread_kill(emul_thread, SIGUSR2);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -1171,7 +1178,7 @@ void ClearInterruptFlag(uint32 flag)
|
||||
|
||||
void DisableInterrupt(void)
|
||||
{
|
||||
atomic_add((int *)XLM_IRQ_NEST, 1);
|
||||
atomic_add((int *)XLM_IRQ_NEST, tswap32(1));
|
||||
}
|
||||
|
||||
|
||||
@ -1181,17 +1188,19 @@ void DisableInterrupt(void)
|
||||
|
||||
void EnableInterrupt(void)
|
||||
{
|
||||
atomic_add((int *)XLM_IRQ_NEST, -1);
|
||||
atomic_add((int *)XLM_IRQ_NEST, tswap32((uint32)-1));
|
||||
}
|
||||
|
||||
|
||||
#if !EMULATED_PPC
|
||||
/*
|
||||
* USR2 handler
|
||||
*/
|
||||
|
||||
static void sigusr2_handler(int sig, sigcontext_struct *sc)
|
||||
{
|
||||
#if EMULATED_PPC
|
||||
HandleInterrupt();
|
||||
#else
|
||||
pt_regs *r = sc->regs;
|
||||
|
||||
// Do nothing if interrupts are disabled
|
||||
@ -1273,9 +1282,11 @@ static void sigusr2_handler(int sig, sigcontext_struct *sc)
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if !EMULATED_PPC
|
||||
/*
|
||||
* SIGSEGV handler
|
||||
*/
|
||||
|
@ -67,7 +67,6 @@ static uint32 *MakeExecutableTvec;
|
||||
|
||||
void EmulOp(M68kRegisters *r, uint32 pc, int selector)
|
||||
{
|
||||
|
||||
D(bug("EmulOp %04x at %08x\n", selector, pc));
|
||||
switch (selector) {
|
||||
case OP_BREAK: // Breakpoint
|
||||
@ -271,10 +270,10 @@ void EmulOp(M68kRegisters *r, uint32 pc, int selector)
|
||||
#endif
|
||||
|
||||
// Patch DebugStr()
|
||||
static const uint16 proc[] = {
|
||||
M68K_EMUL_OP_DEBUG_STR,
|
||||
0x4e74, // rtd #4
|
||||
0x0004
|
||||
static const uint8 proc[] = {
|
||||
M68K_EMUL_OP_DEBUG_STR >> 8, M68K_EMUL_OP_DEBUG_STR & 0xff,
|
||||
0x4e, 0x74, // rtd #4
|
||||
0x00, 0x04
|
||||
};
|
||||
WriteMacInt32(0x1dfc, (uint32)proc);
|
||||
break;
|
||||
@ -311,7 +310,11 @@ void EmulOp(M68kRegisters *r, uint32 pc, int selector)
|
||||
#if !PRECISE_TIMING
|
||||
TimerInterrupt();
|
||||
#endif
|
||||
#if EMULATED_PPC
|
||||
ExecuteNative(NATIVE_VIDEO_VBL);
|
||||
#else
|
||||
ExecutePPC(VideoVBL);
|
||||
#endif
|
||||
|
||||
static int tick_counter = 0;
|
||||
if (++tick_counter >= 60) {
|
||||
@ -329,7 +332,11 @@ void EmulOp(M68kRegisters *r, uint32 pc, int selector)
|
||||
}
|
||||
if (InterruptFlags & INTFLAG_ETHER) {
|
||||
ClearInterruptFlag(INTFLAG_ETHER);
|
||||
#if EMULATED_PPC
|
||||
ExecuteNative(NATIVE_ETHER_IRQ);
|
||||
#else
|
||||
ExecutePPC(EtherIRQ);
|
||||
#endif
|
||||
}
|
||||
if (InterruptFlags & INTFLAG_TIMER) {
|
||||
ClearInterruptFlag(INTFLAG_TIMER);
|
||||
|
@ -68,6 +68,11 @@ static inline void *Mac2Mac_memcpy(uint32 dest, uint32 src, size_t n) {return me
|
||||
struct M68kRegisters;
|
||||
extern void Execute68k(uint32, M68kRegisters *r); // Execute 68k subroutine from EMUL_OP routine, must be ended with RTS
|
||||
extern void Execute68kTrap(uint16 trap, M68kRegisters *r); // Execute 68k A-Trap from EMUL_OP routine
|
||||
extern void ExecutePPC(void (*func)()); // Execute PPC code from EMUL_OP routine (real mode switch)
|
||||
#if EMULATED_PPC
|
||||
extern void HandleInterrupt(void);
|
||||
extern void ExecuteNative(int selector); // Execute native code from EMUL_OP routine (real mode switch)
|
||||
#else
|
||||
extern void ExecutePPC(void (*func)(void)); // Execute PPC code from EMUL_OP routine (real mode switch)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -28,6 +28,35 @@ const uint32 POWERPC_BLR = 0x4e800020;
|
||||
const uint32 POWERPC_BCTR = 0x4e800420;
|
||||
const uint32 POWERPC_EMUL_OP = 0x18000000; // Base opcode for EMUL_OP opcodes (only used with PPC emulation)
|
||||
|
||||
enum { // Selectors for NATIVE_EXEC callbacks (only used with PPC emulation)
|
||||
NATIVE_PATCH_NAME_REGISTRY,
|
||||
NATIVE_VIDEO_INSTALL_ACCEL,
|
||||
NATIVE_VIDEO_VBL,
|
||||
NATIVE_VIDEO_DO_DRIVER_IO,
|
||||
NATIVE_ETHER_IRQ,
|
||||
NATIVE_ETHER_INIT,
|
||||
NATIVE_ETHER_TERM,
|
||||
NATIVE_ETHER_OPEN,
|
||||
NATIVE_ETHER_CLOSE,
|
||||
NATIVE_ETHER_WPUT,
|
||||
NATIVE_ETHER_RSRV,
|
||||
NATIVE_SERIAL_NOTHING,
|
||||
NATIVE_SERIAL_OPEN,
|
||||
NATIVE_SERIAL_PRIME_IN,
|
||||
NATIVE_SERIAL_PRIME_OUT,
|
||||
NATIVE_SERIAL_CONTROL,
|
||||
NATIVE_SERIAL_STATUS,
|
||||
NATIVE_SERIAL_CLOSE,
|
||||
NATIVE_GET_RESOURCE,
|
||||
NATIVE_GET_1_RESOURCE,
|
||||
NATIVE_GET_IND_RESOURCE,
|
||||
NATIVE_GET_1_IND_RESOURCE,
|
||||
NATIVE_R_GET_RESOURCE,
|
||||
NATIVE_OP_MAX
|
||||
};
|
||||
#define POWERPC_NATIVE_OP_FUNC(SELECTOR) ((uint32)(uintptr)&NativeOpTable[SELECTOR])
|
||||
extern const uint32 NativeOpTable[NATIVE_OP_MAX];
|
||||
|
||||
// 68k opcodes
|
||||
const uint16 M68K_ILLEGAL = 0x4afc;
|
||||
const uint16 M68K_NOP = 0x4e71;
|
||||
@ -53,7 +82,8 @@ enum { // Selectors for EMUL_OP opcodes
|
||||
};
|
||||
const uint16 M68K_EMUL_RETURN = 0xfe40; // Extended opcodes
|
||||
const uint16 M68K_EXEC_RETURN = 0xfe41;
|
||||
const uint16 M68K_EMUL_BREAK = 0xfe42;
|
||||
const uint16 M68K_EXEC_NATIVE = 0xfe42;
|
||||
const uint16 M68K_EMUL_BREAK = 0xfe43;
|
||||
const uint16 M68K_EMUL_OP_XPRAM1 = M68K_EMUL_BREAK + OP_XPRAM1;
|
||||
const uint16 M68K_EMUL_OP_XPRAM2 = M68K_EMUL_BREAK + OP_XPRAM2;
|
||||
const uint16 M68K_EMUL_OP_XPRAM3 = M68K_EMUL_BREAK + OP_XPRAM3;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#ifndef NAME_REGISTRY_H
|
||||
#define NAME_REGISTRY_H
|
||||
|
||||
extern void DoPatchNameRegistry(void);
|
||||
extern void PatchNameRegistry(void);
|
||||
|
||||
#endif
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "main.h"
|
||||
#include "macos_util.h"
|
||||
#include "user_strings.h"
|
||||
#include "emul_op.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
@ -60,7 +61,7 @@ static const uint8 ethernet_driver[] = {
|
||||
* Patch Name Registry during startup
|
||||
*/
|
||||
|
||||
static void patch_name_registry(void)
|
||||
void DoPatchNameRegistry(void)
|
||||
{
|
||||
uint32 u32;
|
||||
D(bug("Patching Name Registry..."));
|
||||
@ -286,5 +287,9 @@ void PatchNameRegistry(void)
|
||||
}
|
||||
|
||||
// Main routine must be executed in PPC mode
|
||||
ExecutePPC(patch_name_registry);
|
||||
#if EMULATED_PPC
|
||||
ExecuteNative(NATIVE_PATCH_NAME_REGISTRY);
|
||||
#else
|
||||
ExecutePPC(DoPatchNameRegistry);
|
||||
#endif
|
||||
}
|
||||
|
@ -447,7 +447,17 @@ static const uint8 cdrom_driver[] = { // CD-ROM driver
|
||||
0x4e, 0x75 // rts
|
||||
};
|
||||
|
||||
#ifdef __linux__
|
||||
#if EMULATED_PPC
|
||||
#define SERIAL_TRAMPOLINES 1
|
||||
static uint32 serial_nothing_tvect[2] = {POWERPC_NATIVE_OP_FUNC(NATIVE_SERIAL_NOTHING), 0};
|
||||
static uint32 serial_open_tvect[2] = {POWERPC_NATIVE_OP_FUNC(NATIVE_SERIAL_OPEN), 0};
|
||||
static uint32 serial_prime_in_tvect[2] = {POWERPC_NATIVE_OP_FUNC(NATIVE_SERIAL_PRIME_IN), 0};
|
||||
static uint32 serial_prime_out_tvect[2] = {POWERPC_NATIVE_OP_FUNC(NATIVE_SERIAL_PRIME_OUT), 0};
|
||||
static uint32 serial_control_tvect[2] = {POWERPC_NATIVE_OP_FUNC(NATIVE_SERIAL_CONTROL), 0};
|
||||
static uint32 serial_status_tvect[2] = {POWERPC_NATIVE_OP_FUNC(NATIVE_SERIAL_STATUS), 0};
|
||||
static uint32 serial_close_tvect[2] = {POWERPC_NATIVE_OP_FUNC(NATIVE_SERIAL_CLOSE), 0};
|
||||
#elif defined(__linux__)
|
||||
#define SERIAL_TRAMPOLINES 1
|
||||
static uint32 serial_nothing_tvect[2] = {(uint32)SerialNothing, 0};
|
||||
static uint32 serial_open_tvect[2] = {(uint32)SerialOpen, 0};
|
||||
static uint32 serial_prime_in_tvect[2] = {(uint32)SerialPrimeIn, 0};
|
||||
@ -464,7 +474,7 @@ static const uint32 ain_driver[] = { // .AIn driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_nothing_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialNothing,
|
||||
@ -472,7 +482,7 @@ static const uint32 ain_driver[] = { // .AIn driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_prime_in_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialPrimeIn,
|
||||
@ -480,7 +490,7 @@ static const uint32 ain_driver[] = { // .AIn driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_control_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialControl,
|
||||
@ -488,7 +498,7 @@ static const uint32 ain_driver[] = { // .AIn driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_status_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialStatus,
|
||||
@ -496,7 +506,7 @@ static const uint32 ain_driver[] = { // .AIn driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_nothing_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialNothing,
|
||||
@ -511,7 +521,7 @@ static const uint32 aout_driver[] = { // .AOut driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_open_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialOpen,
|
||||
@ -519,7 +529,7 @@ static const uint32 aout_driver[] = { // .AOut driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_prime_out_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialPrimeOut,
|
||||
@ -527,7 +537,7 @@ static const uint32 aout_driver[] = { // .AOut driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_control_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialControl,
|
||||
@ -535,7 +545,7 @@ static const uint32 aout_driver[] = { // .AOut driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_status_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialStatus,
|
||||
@ -543,7 +553,7 @@ static const uint32 aout_driver[] = { // .AOut driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_close_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialClose,
|
||||
@ -558,7 +568,7 @@ static const uint32 bin_driver[] = { // .BIn driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_nothing_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialNothing,
|
||||
@ -566,7 +576,7 @@ static const uint32 bin_driver[] = { // .BIn driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_prime_in_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialPrimeIn,
|
||||
@ -574,7 +584,7 @@ static const uint32 bin_driver[] = { // .BIn driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_control_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialControl,
|
||||
@ -582,7 +592,7 @@ static const uint32 bin_driver[] = { // .BIn driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_status_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialStatus,
|
||||
@ -590,7 +600,7 @@ static const uint32 bin_driver[] = { // .BIn driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_nothing_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialNothing,
|
||||
@ -605,7 +615,7 @@ static const uint32 bout_driver[] = { // .BOut driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_open_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialOpen,
|
||||
@ -613,7 +623,7 @@ static const uint32 bout_driver[] = { // .BOut driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_prime_out_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialPrimeOut,
|
||||
@ -621,7 +631,7 @@ static const uint32 bout_driver[] = { // .BOut driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_control_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialControl,
|
||||
@ -629,7 +639,7 @@ static const uint32 bout_driver[] = { // .BOut driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_status_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialStatus,
|
||||
@ -637,7 +647,7 @@ static const uint32 bout_driver[] = { // .BOut driver header
|
||||
0x00000000, 0x00000000,
|
||||
0xaafe0700, 0x00000000,
|
||||
0x00000000, 0x00179822,
|
||||
#ifdef __linux__
|
||||
#ifdef SERIAL_TRAMPOLINES
|
||||
0x00010004, (uint32)serial_close_tvect,
|
||||
#else
|
||||
0x00010004, (uint32)SerialClose,
|
||||
@ -1030,15 +1040,17 @@ static bool patch_68k_emul(void)
|
||||
*lp = htonl(POWERPC_ILLEGAL);
|
||||
|
||||
#if EMULATED_PPC
|
||||
// Install EMUL_RETURN, EXEC_RETURN and EMUL_OP opcodes
|
||||
// Install EMUL_RETURN, EXEC_RETURN, EXEC_NATIVE and EMUL_OP opcodes
|
||||
lp = (uint32 *)(ROM_BASE + 0x380000 + (M68K_EMUL_RETURN << 3));
|
||||
*lp++ = htonl(POWERPC_EMUL_OP);
|
||||
*lp++ = htonl(0x4bf66e80); // b 0x366084
|
||||
*lp++ = htonl(POWERPC_EMUL_OP | 1);
|
||||
*lp++ = htonl(0x4bf66e78); // b 0x366084
|
||||
*lp++ = htonl(POWERPC_EMUL_OP | 2);
|
||||
*lp++ = htonl(0x4bf66e70); // b 0x366084
|
||||
for (int i=0; i<OP_MAX; i++) {
|
||||
*lp++ = htonl(POWERPC_EMUL_OP | (i + 2));
|
||||
*lp++ = htonl(0x4bf66e70 - i*8); // b 0x366084
|
||||
*lp++ = htonl(POWERPC_EMUL_OP | (i + 3));
|
||||
*lp++ = htonl(0x4bf66e68 - i*8); // b 0x366084
|
||||
}
|
||||
#else
|
||||
// Install EMUL_RETURN, EXEC_RETURN and EMUL_OP opcodes
|
||||
@ -1047,9 +1059,11 @@ static bool patch_68k_emul(void)
|
||||
*lp++ = htonl(0x4bf705fc); // b 0x36f800
|
||||
*lp++ = htonl(0x80000000 + XLM_EXEC_RETURN_PROC); // lwz r0,XLM_EXEC_RETURN_PROC
|
||||
*lp++ = htonl(0x4bf705f4); // b 0x36f800
|
||||
*lp++ = htonl(0x00dead00); // Let SheepShaver crash, since
|
||||
*lp++ = htonl(0x00beef00); // no native opcode is available
|
||||
for (int i=0; i<OP_MAX; i++) {
|
||||
*lp++ = htonl(0x38a00000 + i); // li r5,OP_*
|
||||
*lp++ = htonl(0x4bf705f4 - i*8); // b 0x36f808
|
||||
*lp++ = htonl(0x4bf705ec - i*8); // b 0x36f808
|
||||
}
|
||||
|
||||
// Extra routines for EMUL_RETURN/EXEC_RETURN/EMUL_OP
|
||||
@ -2137,6 +2151,12 @@ void InstallDrivers(void)
|
||||
M68kRegisters r;
|
||||
uint8 pb[SIZEOF_IOParam];
|
||||
|
||||
#if DISABLE_SCSI && 0
|
||||
// Fake SCSIGlobals
|
||||
static const uint8 fake_scsi_globals[32] = {0,};
|
||||
WriteMacInt32(0xc0c, (uint32)fake_scsi_globals);
|
||||
#endif
|
||||
|
||||
// Install floppy driver
|
||||
if (ROMType == ROMTYPE_NEWWORLD) {
|
||||
|
||||
|
@ -319,6 +319,14 @@ void CheckLoad(uint32 type, int16 id, uint16 *p, uint32 size)
|
||||
// Don't call FE0A opcode (7.6, 7.6.1, 8.0, 8.1, 8.5, 8.6)
|
||||
p[1] = 0x7000;
|
||||
D(bug(" patch 3 applied\n"));
|
||||
} else if (p[0] == 0x6c00 && p[1] == 0x016a && p[2] == 0x2278 && p[3] == 0x0134) {
|
||||
// We don't have SonyVars (8.6)
|
||||
p[-4] = 0x21fc; // move.l $40810000,($0000)
|
||||
p[-3] = 0x4081;
|
||||
p[-2] = 0x0000;
|
||||
p[-1] = 0x0000;
|
||||
p[0] = 0x6000;
|
||||
D(bug(" patch 4 applied\n"));
|
||||
}
|
||||
p++;
|
||||
}
|
||||
@ -480,6 +488,19 @@ void CheckLoad(uint32 type, int16 id, uint16 *p, uint32 size)
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
} else if (type == FOURCC('s','c','o','d') && id == -16465) {
|
||||
D(bug("scod -16465 found\n"));
|
||||
|
||||
// Don't crash in Process Manager on reset/shutdown (8.6)
|
||||
static const uint8 dat[] = {0x4e, 0x56, 0x00, 0x00, 0x48, 0xe7, 0x03, 0x18, 0x2c, 0x2e, 0x00, 0x10};
|
||||
base = find_rsrc_data((uint8 *)p, size, dat, sizeof(dat));
|
||||
if (base) {
|
||||
p16 = (uint16 *)((uint32)p + base);
|
||||
p16[0] = 0x7000; // moveq #0,d0
|
||||
p16[1] = M68K_RTS;
|
||||
D(bug(" patch 1 applied\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -684,19 +705,23 @@ void PatchNativeResourceManager(void)
|
||||
D(bug("PatchNativeResourceManager\n"));
|
||||
|
||||
// Patch native GetResource()
|
||||
uint32 **upp = *(uint32 ***)0x1480;
|
||||
uint32 **upp = (uint32 **)(uintptr)ReadMacInt32(0x1480);
|
||||
if (((uint32)upp & 0xffc00000) == ROM_BASE)
|
||||
return;
|
||||
uint32 *tvec = upp[5];
|
||||
D(bug(" GetResource() entry %08x, TOC %08x\n", tvec[0], tvec[1]));
|
||||
*(uint32 *)XLM_RES_LIB_TOC = tvec[1];
|
||||
*(uint32 *)XLM_GET_RESOURCE = tvec[0];
|
||||
#if EMULATED_PPC
|
||||
tvec[0] = POWERPC_NATIVE_OP_FUNC(NATIVE_GET_RESOURCE);
|
||||
#else
|
||||
#ifdef __BEOS__
|
||||
uint32 *tvec2 = (uint32 *)get_resource;
|
||||
tvec[0] = tvec2[0];
|
||||
tvec[1] = tvec2[1];
|
||||
#else
|
||||
tvec[0] = (uint32)get_resource;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Patch native Get1Resource()
|
||||
@ -704,12 +729,16 @@ void PatchNativeResourceManager(void)
|
||||
tvec = upp[5];
|
||||
D(bug(" Get1Resource() entry %08x, TOC %08x\n", tvec[0], tvec[1]));
|
||||
*(uint32 *)XLM_GET_1_RESOURCE = tvec[0];
|
||||
#if EMULATED_PPC
|
||||
tvec[0] = POWERPC_NATIVE_OP_FUNC(NATIVE_GET_1_RESOURCE);
|
||||
#else
|
||||
#ifdef __BEOS__
|
||||
tvec2 = (uint32 *)get_1_resource;
|
||||
tvec[0] = tvec2[0];
|
||||
tvec[1] = tvec2[1];
|
||||
#else
|
||||
tvec[0] = (uint32)get_1_resource;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Patch native GetIndResource()
|
||||
@ -717,12 +746,16 @@ void PatchNativeResourceManager(void)
|
||||
tvec = upp[5];
|
||||
D(bug(" GetIndResource() entry %08x, TOC %08x\n", tvec[0], tvec[1]));
|
||||
*(uint32 *)XLM_GET_IND_RESOURCE = tvec[0];
|
||||
#if EMULATED_PPC
|
||||
tvec[0] = POWERPC_NATIVE_OP_FUNC(NATIVE_GET_IND_RESOURCE);
|
||||
#else
|
||||
#ifdef __BEOS__
|
||||
tvec2 = (uint32 *)get_ind_resource;
|
||||
tvec[0] = tvec2[0];
|
||||
tvec[1] = tvec2[1];
|
||||
#else
|
||||
tvec[0] = (uint32)get_ind_resource;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Patch native Get1IndResource()
|
||||
@ -730,12 +763,16 @@ void PatchNativeResourceManager(void)
|
||||
tvec = upp[5];
|
||||
D(bug(" Get1IndResource() entry %08x, TOC %08x\n", tvec[0], tvec[1]));
|
||||
*(uint32 *)XLM_GET_1_IND_RESOURCE = tvec[0];
|
||||
#if EMULATED_PPC
|
||||
tvec[0] = POWERPC_NATIVE_OP_FUNC(NATIVE_GET_1_IND_RESOURCE);
|
||||
#else
|
||||
#ifdef __BEOS__
|
||||
tvec2 = (uint32 *)get_1_ind_resource;
|
||||
tvec[0] = tvec2[0];
|
||||
tvec[1] = tvec2[1];
|
||||
#else
|
||||
tvec[0] = (uint32)get_1_ind_resource;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Patch native RGetResource()
|
||||
@ -743,6 +780,9 @@ void PatchNativeResourceManager(void)
|
||||
tvec = upp[5];
|
||||
D(bug(" RGetResource() entry %08x, TOC %08x\n", tvec[0], tvec[1]));
|
||||
*(uint32 *)XLM_R_GET_RESOURCE = tvec[0];
|
||||
#if EMULATED_PPC
|
||||
tvec[0] = POWERPC_NATIVE_OP_FUNC(NATIVE_R_GET_RESOURCE);
|
||||
#else
|
||||
#ifdef __BEOS__
|
||||
tvec2 = (uint32 *)r_get_resource;
|
||||
tvec[0] = tvec2[0];
|
||||
@ -750,4 +790,5 @@ void PatchNativeResourceManager(void)
|
||||
#else
|
||||
tvec[0] = (uint32)r_get_resource;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user