Try to handle XLM_IRQ_NEST atomically in emulated PPC views. Fix placement

of fake SCSIGlobals (disabled for now). Switch back to mono core emulation
until things are debugged enough. Implement get_resource() et al.
This commit is contained in:
gbeauche 2003-09-28 21:27:34 +00:00
parent 2a86a4f62a
commit 3851071ecd
3 changed files with 304 additions and 65 deletions

View File

@ -27,6 +27,7 @@
#include "macos_util.h"
#include "block-alloc.hpp"
#include "sigsegv.h"
#include "spcflags.h"
#include "cpu/ppc/ppc-cpu.hpp"
#include "cpu/ppc/ppc-operations.hpp"
@ -54,6 +55,9 @@ static void enter_mon(void)
#endif
}
// Enable multicore (main/interrupts) cpu emulation?
#define MULTICORE_CPU 0
// Enable Execute68k() safety checks?
#define SAFE_EXEC_68K 1
@ -99,10 +103,6 @@ public:
: powerpc_cpu()
{ init_decoder(); }
// Stack pointer accessors
uint32 get_sp() const { return gpr(1); }
void set_sp(uint32 v) { gpr(1) = v; }
// Condition Register accessors
uint32 get_cr() const { return cr().get(); }
void set_cr(uint32 v) { cr().set(v); }
@ -113,6 +113,9 @@ public:
// Execute 68k routine
void execute_68k(uint32 entry, M68kRegisters *r);
// Execute ppc routine
void execute_ppc(uint32 entry);
// Execute MacOS/PPC code
uint32 execute_macos_code(uint32 tvect, int nargs, uint32 const *args);
@ -120,7 +123,10 @@ public:
void get_resource(uint32 old_get_resource);
// Handle MacOS interrupt
void interrupt(uint32 entry, uint32 sp);
void interrupt(uint32 entry, sheepshaver_cpu *cpu);
// spcflags for interrupts handling
static uint32 spcflags;
// Lazy memory allocator (one item at a time)
void *operator new(size_t size)
@ -132,6 +138,7 @@ public:
void operator delete[](void *p);
};
uint32 sheepshaver_cpu::spcflags = 0;
lazy_allocator< sheepshaver_cpu > allocator_helper< sheepshaver_cpu, lazy_allocator >::allocator;
void sheepshaver_cpu::init_decoder()
@ -163,6 +170,17 @@ void sheepshaver_cpu::init_decoder()
// Forward declaration for native opcode handler
static void NativeOp(int selector);
/* NativeOp instruction format:
+------------+--------------------------+--+----------+------------+
| 6 | |FN| OP | 2 |
+------------+--------------------------+--+----------+------------+
0 5 |6 19 20 21 25 26 31
*/
typedef bit_field< 20, 20 > FN_field;
typedef bit_field< 21, 25 > NATIVE_OP_field;
typedef bit_field< 26, 31 > EMUL_OP_field;
// Execute SheepShaver instruction
void sheepshaver_cpu::execute_sheep(uint32 opcode)
{
@ -179,8 +197,11 @@ void sheepshaver_cpu::execute_sheep(uint32 opcode)
break;
case 2: // EXEC_NATIVE
NativeOp((opcode >> 6) & 0x1f);
pc() = lr();
NativeOp(NATIVE_OP_field::extract(opcode));
if (FN_field::test(opcode))
pc() = lr();
else
pc() += 4;
break;
default: { // EMUL_OP
@ -192,7 +213,7 @@ void sheepshaver_cpu::execute_sheep(uint32 opcode)
for (int i = 0; i < 7; i++)
r68.a[i] = gpr(16 + i);
r68.a[7] = gpr(1);
EmulOp(&r68, gpr(24), (opcode & 0x3f) - 3);
EmulOp(&r68, gpr(24), EMUL_OP_field::extract(opcode) - 3);
for (int i = 0; i < 8; i++)
gpr(8 + i) = r68.d[i];
for (int i = 0; i < 7; i++)
@ -205,12 +226,38 @@ void sheepshaver_cpu::execute_sheep(uint32 opcode)
}
}
// Checks for pending interrupts
struct execute_nothing {
static inline void execute(powerpc_cpu *) { }
};
static void HandleInterrupt(void);
struct execute_spcflags_check {
static inline void execute(powerpc_cpu *cpu) {
if (SPCFLAGS_TEST(SPCFLAG_ALL_BUT_EXEC_RETURN)) {
if (SPCFLAGS_TEST( SPCFLAG_ENTER_MON )) {
SPCFLAGS_CLEAR( SPCFLAG_ENTER_MON );
enter_mon();
}
if (SPCFLAGS_TEST( SPCFLAG_DOINT )) {
SPCFLAGS_CLEAR( SPCFLAG_DOINT );
HandleInterrupt();
}
if (SPCFLAGS_TEST( SPCFLAG_INT )) {
SPCFLAGS_CLEAR( SPCFLAG_INT );
SPCFLAGS_SET( SPCFLAG_DOINT );
}
}
}
};
// Execution loop
void sheepshaver_cpu::execute(uint32 entry)
{
try {
pc() = entry;
powerpc_cpu::execute();
powerpc_cpu::do_execute<execute_nothing, execute_spcflags_check>();
}
catch (sheepshaver_exec_return const &) {
// Nothing, simply return
@ -222,10 +269,20 @@ void sheepshaver_cpu::execute(uint32 entry)
}
// Handle MacOS interrupt
void sheepshaver_cpu::interrupt(uint32 entry, uint32 sp)
void sheepshaver_cpu::interrupt(uint32 entry, sheepshaver_cpu *cpu)
{
#if MULTICORE_CPU
// Initialize stack pointer from previous CPU running
gpr(1) = cpu->gpr(1);
#else
// Save program counters and branch registers
uint32 saved_pc = pc();
uint32 saved_lr = lr();
uint32 saved_ctr= ctr();
#endif
// Create stack frame
gpr(1) = sp - 64;
gpr(1) -= 64;
// Build trampoline to return from interrupt
uint32 trampoline[] = { POWERPC_EMUL_OP | 1 };
@ -235,6 +292,7 @@ void sheepshaver_cpu::interrupt(uint32 entry, uint32 sp)
kernel_data->v[0x018 >> 2] = gpr(6);
gpr(6) = kernel_data->v[0x65c >> 2];
assert(gpr(6) != 0);
WriteMacInt32(gpr(6) + 0x13c, gpr(7));
WriteMacInt32(gpr(6) + 0x144, gpr(8));
WriteMacInt32(gpr(6) + 0x14c, gpr(9));
@ -263,6 +321,13 @@ void sheepshaver_cpu::interrupt(uint32 entry, uint32 sp)
// Cleanup stack
gpr(1) += 64;
#if !MULTICORE_CPU
// Restore program counters and branch registers
pc() = saved_pc;
lr() = saved_lr;
ctr()= saved_ctr;
#endif
}
// Execute 68k routine
@ -290,8 +355,7 @@ void sheepshaver_cpu::execute_68k(uint32 entry, M68kRegisters *r)
#endif
// Setup registers for 68k emulator
cr().set(0);
cr().set(2, 1); // Supervisor mode
cr().set(CR_SO_field<2>::mask()); // Supervisor mode
for (int i = 0; i < 8; i++) // d[0]..d[7]
gpr(8 + i) = r->d[i];
for (int i = 0; i < 7; i++) // a[0]..a[6]
@ -392,11 +456,45 @@ uint32 sheepshaver_cpu::execute_macos_code(uint32 tvect, int nargs, uint32 const
return retval;
}
// Execute ppc routine
inline void sheepshaver_cpu::execute_ppc(uint32 entry)
{
// Save branch registers
uint32 saved_lr = lr();
uint32 saved_ctr= ctr();
const uint32 trampoline[] = { POWERPC_EMUL_OP | 1 };
lr() = (uint32)trampoline;
ctr()= entry;
execute(entry);
// Restore branch registers
lr() = saved_lr;
ctr()= saved_ctr;
}
// Resource Manager thunk
extern "C" void check_load_invoc(uint32 type, int16 id, uint16 **h);
inline void sheepshaver_cpu::get_resource(uint32 old_get_resource)
{
printf("ERROR: get_resource() unimplemented\n");
QuitEmulator();
uint32 type = gpr(3);
int16 id = gpr(4);
// Create stack frame
gpr(1) -= 56;
// Call old routine
execute_ppc(old_get_resource);
uint16 **handle = (uint16 **)gpr(3);
// Call CheckLoad()
check_load_invoc(type, id, handle);
gpr(3) = (uint32)handle;
// Cleanup stack
gpr(1) += 56;
}
@ -408,6 +506,20 @@ static sheepshaver_cpu *main_cpu = NULL; // CPU emulator to handle usual contro
static sheepshaver_cpu *interrupt_cpu = NULL; // CPU emulator to handle interrupts
static sheepshaver_cpu *current_cpu = NULL; // Current CPU emulator context
static inline void cpu_push(sheepshaver_cpu *new_cpu)
{
#if MULTICORE_CPU
current_cpu = new_cpu;
#endif
}
static inline void cpu_pop()
{
#if MULTICORE_CPU
current_cpu = main_cpu;
#endif
}
// Dump PPC registers
static void dump_registers(void)
{
@ -463,7 +575,6 @@ static void sigsegv_handler(int sig, siginfo_t *sip, void *scp)
interrupt_cpu->dump_registers();
#endif
current_cpu->dump_log();
WriteMacInt32(XLM_IRQ_NEST, 1);
enter_mon();
QuitEmulator();
}
@ -475,8 +586,10 @@ void init_emul_ppc(void)
main_cpu->set_register(powerpc_registers::GPR(3), any_register((uint32)ROM_BASE + 0x30d000));
WriteMacInt32(XLM_RUN_MODE, MODE_68K);
#if MULTICORE_CPU
// Initialize alternate CPU emulator to handle interrupts
interrupt_cpu = new sheepshaver_cpu();
#endif
// Install SIGSEGV handler
sigemptyset(&sigsegv_action.sa_mask);
@ -512,14 +625,23 @@ extern int atomic_add(int *var, int v);
extern int atomic_and(int *var, int v);
extern int atomic_or(int *var, int v);
void HandleInterrupt(void)
void TriggerInterrupt(void)
{
#if 0
WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1);
#else
SPCFLAGS_SET( SPCFLAG_INT );
#endif
}
static void HandleInterrupt(void)
{
// Do nothing if interrupts are disabled
if (ReadMacInt32(XLM_IRQ_NEST) > 0 || InterruptFlags == 0)
if (int32(ReadMacInt32(XLM_IRQ_NEST)) > 0)
return;
// Do nothing if CPU objects are not initialized yet
if (current_cpu == NULL)
// Do nothing if there is no interrupt pending
if (InterruptFlags == 0)
return;
// Disable MacOS stack sniffer
@ -546,13 +668,13 @@ void HandleInterrupt(void)
| tswap32(kernel_data->v[0x674 >> 2]));
// Execute nanokernel interrupt routine (this will activate the 68k emulator)
atomic_add((int32 *)XLM_IRQ_NEST, htonl(1));
current_cpu = interrupt_cpu;
DisableInterrupt();
cpu_push(interrupt_cpu);
if (ROMType == ROMTYPE_NEWWORLD)
current_cpu->interrupt(ROM_BASE + 0x312b1c, main_cpu->get_sp());
current_cpu->interrupt(ROM_BASE + 0x312b1c, main_cpu);
else
current_cpu->interrupt(ROM_BASE + 0x312a3c, main_cpu->get_sp());
current_cpu = main_cpu;
current_cpu->interrupt(ROM_BASE + 0x312a3c, main_cpu);
cpu_pop();
}
break;
#endif
@ -566,13 +688,13 @@ void HandleInterrupt(void)
M68kRegisters r;
uint32 old_r25 = ReadMacInt32(XLM_68K_R25); // Save interrupt level
WriteMacInt32(XLM_68K_R25, 0x21); // Execute with interrupt level 1
static const uint16 proc[] = {
0x3f3c, 0x0000, // move.w #$0000,-(sp) (fake format word)
0x487a, 0x000a, // pea @1(pc) (return address)
0x40e7, // move sr,-(sp) (saved SR)
0x2078, 0x0064, // move.l $64,a0
0x4ed0, // jmp (a0)
M68K_RTS // @1
static const uint8 proc[] = {
0x3f, 0x3c, 0x00, 0x00, // move.w #$0000,-(sp) (fake format word)
0x48, 0x7a, 0x00, 0x0a, // pea @1(pc) (return address)
0x40, 0xe7, // move sr,-(sp) (saved SR)
0x20, 0x78, 0x00, 0x064, // move.l $64,a0
0x4e, 0xd0, // jmp (a0)
M68K_RTS >> 8, M68K_RTS & 0xff // @1
};
Execute68k((uint32)proc, &r);
WriteMacInt32(XLM_68K_R25, old_r25); // Restore interrupt level
@ -596,34 +718,36 @@ void HandleInterrupt(void)
* Execute NATIVE_OP opcode (called by PowerPC emulator)
*/
#define POWERPC_NATIVE_OP(selector) \
{ tswap32(POWERPC_EMUL_OP | 2 | (((uint32)selector) << 6)) }
#define POWERPC_NATIVE_OP_INIT(LR, OP) \
tswap32(POWERPC_EMUL_OP | ((LR) << 11) | (((uint32)OP) << 6) | 2)
// FIXME: Make sure 32-bit relocations are used
const uint32 NativeOpTable[NATIVE_OP_MAX] = {
POWERPC_NATIVE_OP(NATIVE_PATCH_NAME_REGISTRY),
POWERPC_NATIVE_OP(NATIVE_VIDEO_INSTALL_ACCEL),
POWERPC_NATIVE_OP(NATIVE_VIDEO_VBL),
POWERPC_NATIVE_OP(NATIVE_VIDEO_DO_DRIVER_IO),
POWERPC_NATIVE_OP(NATIVE_ETHER_IRQ),
POWERPC_NATIVE_OP(NATIVE_ETHER_INIT),
POWERPC_NATIVE_OP(NATIVE_ETHER_TERM),
POWERPC_NATIVE_OP(NATIVE_ETHER_OPEN),
POWERPC_NATIVE_OP(NATIVE_ETHER_CLOSE),
POWERPC_NATIVE_OP(NATIVE_ETHER_WPUT),
POWERPC_NATIVE_OP(NATIVE_ETHER_RSRV),
POWERPC_NATIVE_OP(NATIVE_SERIAL_NOTHING),
POWERPC_NATIVE_OP(NATIVE_SERIAL_OPEN),
POWERPC_NATIVE_OP(NATIVE_SERIAL_PRIME_IN),
POWERPC_NATIVE_OP(NATIVE_SERIAL_PRIME_OUT),
POWERPC_NATIVE_OP(NATIVE_SERIAL_CONTROL),
POWERPC_NATIVE_OP(NATIVE_SERIAL_STATUS),
POWERPC_NATIVE_OP(NATIVE_SERIAL_CLOSE),
POWERPC_NATIVE_OP(NATIVE_GET_RESOURCE),
POWERPC_NATIVE_OP(NATIVE_GET_1_RESOURCE),
POWERPC_NATIVE_OP(NATIVE_GET_IND_RESOURCE),
POWERPC_NATIVE_OP(NATIVE_GET_1_IND_RESOURCE),
POWERPC_NATIVE_OP(NATIVE_R_GET_RESOURCE),
POWERPC_NATIVE_OP_INIT(1, NATIVE_PATCH_NAME_REGISTRY),
POWERPC_NATIVE_OP_INIT(1, NATIVE_VIDEO_INSTALL_ACCEL),
POWERPC_NATIVE_OP_INIT(1, NATIVE_VIDEO_VBL),
POWERPC_NATIVE_OP_INIT(1, NATIVE_VIDEO_DO_DRIVER_IO),
POWERPC_NATIVE_OP_INIT(1, NATIVE_ETHER_IRQ),
POWERPC_NATIVE_OP_INIT(1, NATIVE_ETHER_INIT),
POWERPC_NATIVE_OP_INIT(1, NATIVE_ETHER_TERM),
POWERPC_NATIVE_OP_INIT(1, NATIVE_ETHER_OPEN),
POWERPC_NATIVE_OP_INIT(1, NATIVE_ETHER_CLOSE),
POWERPC_NATIVE_OP_INIT(1, NATIVE_ETHER_WPUT),
POWERPC_NATIVE_OP_INIT(1, NATIVE_ETHER_RSRV),
POWERPC_NATIVE_OP_INIT(1, NATIVE_SERIAL_NOTHING),
POWERPC_NATIVE_OP_INIT(1, NATIVE_SERIAL_OPEN),
POWERPC_NATIVE_OP_INIT(1, NATIVE_SERIAL_PRIME_IN),
POWERPC_NATIVE_OP_INIT(1, NATIVE_SERIAL_PRIME_OUT),
POWERPC_NATIVE_OP_INIT(1, NATIVE_SERIAL_CONTROL),
POWERPC_NATIVE_OP_INIT(1, NATIVE_SERIAL_STATUS),
POWERPC_NATIVE_OP_INIT(1, NATIVE_SERIAL_CLOSE),
POWERPC_NATIVE_OP_INIT(1, NATIVE_GET_RESOURCE),
POWERPC_NATIVE_OP_INIT(1, NATIVE_GET_1_RESOURCE),
POWERPC_NATIVE_OP_INIT(1, NATIVE_GET_IND_RESOURCE),
POWERPC_NATIVE_OP_INIT(1, NATIVE_GET_1_IND_RESOURCE),
POWERPC_NATIVE_OP_INIT(1, NATIVE_R_GET_RESOURCE),
POWERPC_NATIVE_OP_INIT(0, NATIVE_DISABLE_INTERRUPT),
POWERPC_NATIVE_OP_INIT(0, NATIVE_ENABLE_INTERRUPT),
};
static void get_resource(void);
@ -685,6 +809,12 @@ static void NativeOp(int selector)
GPR(3) = serial_callbacks[selector - NATIVE_SERIAL_NOTHING](GPR(3), GPR(4));
break;
}
case NATIVE_DISABLE_INTERRUPT:
DisableInterrupt();
break;
case NATIVE_ENABLE_INTERRUPT:
EnableInterrupt();
break;
default:
printf("FATAL: NATIVE_OP called with bogus selector %d\n", selector);
QuitEmulator();
@ -808,8 +938,6 @@ int atomic_or(int *var, int v)
* Resource Manager thunks
*/
extern "C" void check_load_invoc(uint32 type, int16 id, uint16 **h);
void get_resource(void)
{
current_cpu->get_resource(ReadMacInt32(XLM_GET_RESOURCE));

View File

@ -0,0 +1,89 @@
/*
* UAE - The Un*x Amiga Emulator
*
* MC68000 emulation
*
* Copyright 1995 Bernd Schmidt
*/
#ifndef SPCFLAGS_H
#define SPCFLAGS_H
typedef uint32 spcflags_t;
enum {
SPCFLAG_STOP = 0x01,
SPCFLAG_INT = 0x02,
SPCFLAG_DOINT = 0x04,
SPCFLAG_ENTER_MON = 0x08,
#if USE_JIT
SPCFLAG_JIT_END_COMPILE = 0x40,
SPCFLAG_JIT_EXEC_RETURN = 0x80,
#else
SPCFLAG_JIT_END_COMPILE = 0,
SPCFLAG_JIT_EXEC_RETURN = 0,
#endif
SPCFLAG_ALL = SPCFLAG_STOP
| SPCFLAG_INT
| SPCFLAG_DOINT
| SPCFLAG_ENTER_MON
| SPCFLAG_JIT_END_COMPILE
| SPCFLAG_JIT_EXEC_RETURN
,
SPCFLAG_ALL_BUT_EXEC_RETURN = SPCFLAG_ALL & ~SPCFLAG_JIT_EXEC_RETURN
};
#define SPCFLAGS_TEST(m) \
((sheepshaver_cpu::spcflags & (m)) != 0)
/* Macro only used in m68k_reset() */
#define SPCFLAGS_INIT(m) do { \
sheepshaver_cpu::spcflags = (m); \
} while (0)
#if !(ENABLE_EXCLUSIVE_SPCFLAGS)
#define SPCFLAGS_SET(m) do { \
sheepshaver_cpu::spcflags |= (m); \
} while (0)
#define SPCFLAGS_CLEAR(m) do { \
sheepshaver_cpu::spcflags &= ~(m); \
} while (0)
#elif defined(__i386__) && defined(X86_ASSEMBLY)
#define HAVE_HARDWARE_LOCKS
#define SPCFLAGS_SET(m) do { \
__asm__ __volatile__("lock\n\torl %1,%0" : "=m" (sheepshaver_cpu::spcflags) : "i" ((m))); \
} while (0)
#define SPCFLAGS_CLEAR(m) do { \
__asm__ __volatile__("lock\n\tandl %1,%0" : "=m" (sheepshaver_cpu::spcflags) : "i" (~(m))); \
} while (0)
#else
#undef HAVE_HARDWARE_LOCKS
#include "main.h"
extern B2_mutex *spcflags_lock;
#define SPCFLAGS_SET(m) do { \
B2_lock_mutex(spcflags_lock); \
sheepshaver_cpu::spcflags |= (m); \
B2_unlock_mutex(spcflags_lock); \
} while (0)
#define SPCFLAGS_CLEAR(m) do { \
B2_lock_mutex(spcflags_lock); \
sheepshaver_cpu::spcflags &= ~(m); \
B2_unlock_mutex(spcflags_lock); \
} while (0)
#endif
#endif /* SPCFLAGS_H */

View File

@ -1079,9 +1079,13 @@ static bool patch_68k_emul(void)
// Extra routine for 68k emulator start
lp = (uint32 *)(ROM_BASE + 0x36f900);
*lp++ = htonl(0x7c2903a6); // mtctr r1
#if EMULATED_PPC
*lp++ = POWERPC_NATIVE_OP(NATIVE_DISABLE_INTERRUPT);
#else
*lp++ = htonl(0x80200000 + XLM_IRQ_NEST); // lwz r1,XLM_IRQ_NEST
*lp++ = htonl(0x38210001); // addi r1,r1,1
*lp++ = htonl(0x90200000 + XLM_IRQ_NEST); // stw r1,XLM_IRQ_NEST
#endif
*lp++ = htonl(0x80200000 + XLM_KERNEL_DATA);// lwz r1,XLM_KERNEL_DATA
*lp++ = htonl(0x90c10018); // stw r6,0x18(r1)
*lp++ = htonl(0x7cc902a6); // mfctr r6
@ -1109,9 +1113,13 @@ static bool patch_68k_emul(void)
// Extra routine for Mixed Mode
lp = (uint32 *)(ROM_BASE + 0x36fa00);
*lp++ = htonl(0x7c2903a6); // mtctr r1
#if EMULATED_PPC
*lp++ = POWERPC_NATIVE_OP(NATIVE_DISABLE_INTERRUPT);
#else
*lp++ = htonl(0x80200000 + XLM_IRQ_NEST); // lwz r1,XLM_IRQ_NEST
*lp++ = htonl(0x38210001); // addi r1,r1,1
*lp++ = htonl(0x90200000 + XLM_IRQ_NEST); // stw r1,XLM_IRQ_NEST
#endif
*lp++ = htonl(0x80200000 + XLM_KERNEL_DATA);// lwz r1,XLM_KERNEL_DATA
*lp++ = htonl(0x90c10018); // stw r6,0x18(r1)
*lp++ = htonl(0x7cc902a6); // mfctr r6
@ -1139,9 +1147,13 @@ static bool patch_68k_emul(void)
// Extra routine for Reset/FC1E opcode
lp = (uint32 *)(ROM_BASE + 0x36fb00);
*lp++ = htonl(0x7c2903a6); // mtctr r1
#if EMULATED_PPC
*lp++ = POWERPC_NATIVE_OP(NATIVE_DISABLE_INTERRUPT);
#else
*lp++ = htonl(0x80200000 + XLM_IRQ_NEST); // lwz r1,XLM_IRQ_NEST
*lp++ = htonl(0x38210001); // addi r1,r1,1
*lp++ = htonl(0x90200000 + XLM_IRQ_NEST); // stw r1,XLM_IRQ_NEST
#endif
*lp++ = htonl(0x80200000 + XLM_KERNEL_DATA);// lwz r1,XLM_KERNEL_DATA
*lp++ = htonl(0x90c10018); // stw r6,0x18(r1)
*lp++ = htonl(0x7cc902a6); // mfctr r6
@ -1169,9 +1181,13 @@ static bool patch_68k_emul(void)
// Extra routine for FE0A opcode (QuickDraw 3D needs this)
lp = (uint32 *)(ROM_BASE + 0x36fc00);
*lp++ = htonl(0x7c2903a6); // mtctr r1
#if EMULATED_PPC
*lp++ = POWERPC_NATIVE_OP(NATIVE_DISABLE_INTERRUPT);
#else
*lp++ = htonl(0x80200000 + XLM_IRQ_NEST); // lwz r1,XLM_IRQ_NEST
*lp++ = htonl(0x38210001); // addi r1,r1,1
*lp++ = htonl(0x90200000 + XLM_IRQ_NEST); // stw r1,XLM_IRQ_NEST
#endif
*lp++ = htonl(0x80200000 + XLM_KERNEL_DATA);// lwz r1,XLM_KERNEL_DATA
*lp++ = htonl(0x90c10018); // stw r6,0x18(r1)
*lp++ = htonl(0x7cc902a6); // mfctr r6
@ -1306,10 +1322,16 @@ static bool patch_nanokernel(void)
*lp = htonl(POWERPC_BCTR);
lp = (uint32 *)(ROM_BASE + 0x318000);
#if EMULATED_PPC
*lp++ = POWERPC_NATIVE_OP(NATIVE_ENABLE_INTERRUPT);
*lp = htonl(0x48000000 + ((xlp - 0x8004) & 0x03fffffc)); // b ROM_BASE+0x312c2c
#else
*lp++ = htonl(0x81400000 + XLM_IRQ_NEST); // lwz r10,XLM_IRQ_NEST
*lp++ = htonl(0x394affff); // subi r10,r10,1
*lp++ = htonl(0x91400000 + XLM_IRQ_NEST); // stw r10,XLM_IRQ_NEST
*lp = htonl(0x48000000 + ((xlp - 0x800c) & 0x03fffffc)); // b ROM_BASE+0x312c2c
#endif
/*
// Disable FE0A/FE06 opcodes
lp = (uint32 *)(ROM_BASE + 0x3144ac);
@ -2151,12 +2173,6 @@ 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) {
@ -2171,6 +2187,12 @@ void InstallDrivers(void)
WriteMacInt16(dce + dCtlFlags, SonyDriverFlags);
}
#if DISABLE_SCSI && 0
// Fake SCSIGlobals
static const uint8 fake_scsi_globals[32] = {0,};
WriteMacInt32(0xc0c, (uint32)fake_scsi_globals);
#endif
// Open .Sony driver
WriteMacInt8((uint32)pb + ioPermssn, 0);
WriteMacInt32((uint32)pb + ioNamePtr, (uint32)"\005.Sony");