--- SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp 2004/06/24 15:37:26 1.47 +++ SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp 2004/11/22 22:04:38 1.53 @@ -42,6 +42,9 @@ #include #include +#ifdef HAVE_MALLOC_H +#include +#endif #ifdef USE_SDL_VIDEO #include @@ -105,14 +108,11 @@ const uint32 POWERPC_EXEC_RETURN = POWER // Interrupts in native mode? #define INTERRUPTS_IN_NATIVE_MODE 1 -// Enable native EMUL_OPs to be run without a mode switch -#define ENABLE_NATIVE_EMUL_OP 1 - // Pointer to Kernel Data -static KernelData * const kernel_data = (KernelData *)KERNEL_DATA_BASE; +static KernelData * kernel_data; // SIGSEGV handler -static sigsegv_return_t sigsegv_handler(sigsegv_address_t, sigsegv_address_t); +sigsegv_return_t sigsegv_handler(sigsegv_address_t, sigsegv_address_t); #if PPC_ENABLE_JIT && PPC_REENTRANT_JIT // Special trampolines for EmulOp and NativeOp @@ -142,14 +142,6 @@ class sheepshaver_cpu void init_decoder(); void execute_sheep(uint32 opcode); - // Filter out EMUL_OP routines that only call native code - bool filter_execute_emul_op(uint32 emul_op); - - // "Native" EMUL_OP routines - void execute_emul_op_microseconds(); - void execute_emul_op_idle_time_1(); - void execute_emul_op_idle_time_2(); - // CPU context to preserve on interrupt class interrupt_context { uint32 gpr[32]; @@ -191,9 +183,10 @@ public: // Execute MacOS/PPC code uint32 execute_macos_code(uint32 tvect, int nargs, uint32 const *args); +#if PPC_ENABLE_JIT // Compile one instruction virtual int compile1(codegen_context_t & cg_context); - +#endif // Resource manager thunk void get_resource(uint32 old_get_resource); @@ -274,57 +267,9 @@ typedef bit_field< 19, 19 > FN_field; typedef bit_field< 20, 25 > NATIVE_OP_field; typedef bit_field< 26, 31 > EMUL_OP_field; -// "Native" EMUL_OP routines -#define GPR_A(REG) gpr(16 + (REG)) -#define GPR_D(REG) gpr( 8 + (REG)) - -void sheepshaver_cpu::execute_emul_op_microseconds() -{ - Microseconds(GPR_A(0), GPR_D(0)); -} - -void sheepshaver_cpu::execute_emul_op_idle_time_1() -{ - // Sleep if no events pending - if (ReadMacInt32(0x14c) == 0) - Delay_usec(16667); - GPR_A(0) = ReadMacInt32(0x2b6); -} - -void sheepshaver_cpu::execute_emul_op_idle_time_2() -{ - // Sleep if no events pending - if (ReadMacInt32(0x14c) == 0) - Delay_usec(16667); - GPR_D(0) = (uint32)-2; -} - -// Filter out EMUL_OP routines that only call native code -bool sheepshaver_cpu::filter_execute_emul_op(uint32 emul_op) -{ - switch (emul_op) { - case OP_MICROSECONDS: - execute_emul_op_microseconds(); - return true; - case OP_IDLE_TIME: - execute_emul_op_idle_time_1(); - return true; - case OP_IDLE_TIME_2: - execute_emul_op_idle_time_2(); - return true; - } - return false; -} - // Execute EMUL_OP routine void sheepshaver_cpu::execute_emul_op(uint32 emul_op) { -#if ENABLE_NATIVE_EMUL_OP - // First, filter out EMUL_OPs that can be executed without a mode switch - if (filter_execute_emul_op(emul_op)) - return; -#endif - M68kRegisters r68; WriteMacInt32(XLM_68K_R25, gpr(25)); WriteMacInt32(XLM_RUN_MODE, MODE_EMUL_OP); @@ -377,9 +322,9 @@ void sheepshaver_cpu::execute_sheep(uint } // Compile one instruction +#if PPC_ENABLE_JIT int sheepshaver_cpu::compile1(codegen_context_t & cg_context) { -#if PPC_ENABLE_JIT const instr_info_t *ii = cg_context.instr_info; if (ii->mnemo != PPC_I(SHEEP)) return COMPILE_FAILURE; @@ -506,27 +451,6 @@ int sheepshaver_cpu::compile1(codegen_co default: { // EMUL_OP uint32 emul_op = EMUL_OP_field::extract(opcode) - 3; -#if ENABLE_NATIVE_EMUL_OP - typedef void (*emul_op_func_t)(dyngen_cpu_base); - emul_op_func_t emul_op_func = 0; - switch (emul_op) { - case OP_MICROSECONDS: - emul_op_func = (emul_op_func_t)nv_mem_fun(&sheepshaver_cpu::execute_emul_op_microseconds).ptr(); - break; - case OP_IDLE_TIME: - emul_op_func = (emul_op_func_t)nv_mem_fun(&sheepshaver_cpu::execute_emul_op_idle_time_1).ptr(); - break; - case OP_IDLE_TIME_2: - emul_op_func = (emul_op_func_t)nv_mem_fun(&sheepshaver_cpu::execute_emul_op_idle_time_2).ptr(); - break; - } - if (emul_op_func) { - dg.gen_invoke_CPU(emul_op_func); - cg_context.done_compile = false; - status = COMPILE_CODE_OK; - break; - } -#endif #if PPC_REENTRANT_JIT // Try to execute EmulOp trampoline dg.gen_set_PC_im(cg_context.pc + 4); @@ -546,9 +470,8 @@ int sheepshaver_cpu::compile1(codegen_co } } return status; -#endif - return COMPILE_FAILURE; } +#endif // CPU context to preserve on interrupt sheepshaver_cpu::interrupt_context::interrupt_context(sheepshaver_cpu *_cpu, const char *_where) @@ -880,7 +803,7 @@ static void dump_log(void) * Initialize CPU emulation */ -static sigsegv_return_t sigsegv_handler(sigsegv_address_t fault_address, sigsegv_address_t fault_instruction) +sigsegv_return_t sigsegv_handler(sigsegv_address_t fault_address, sigsegv_address_t fault_instruction) { #if ENABLE_VOSF // Handle screen fault @@ -892,7 +815,7 @@ static sigsegv_return_t sigsegv_handler( const uintptr addr = (uintptr)fault_address; #if HAVE_SIGSEGV_SKIP_INSTRUCTION // Ignore writes to ROM - if ((addr - ROM_BASE) < ROM_SIZE) + if ((addr - (uintptr)ROMBaseHost) < ROM_SIZE) return SIGSEGV_RETURN_SKIP_INSTRUCTION; // Get program counter of target CPU @@ -952,15 +875,15 @@ static sigsegv_return_t sigsegv_handler( void init_emul_ppc(void) { + // Get pointer to KernelData in host address space + kernel_data = (KernelData *)Mac2HostAddr(KERNEL_DATA_BASE); + // Initialize main CPU emulator ppc_cpu = new sheepshaver_cpu(); ppc_cpu->set_register(powerpc_registers::GPR(3), any_register((uint32)ROM_BASE + 0x30d000)); ppc_cpu->set_register(powerpc_registers::GPR(4), any_register(KernelDataAddr + 0x1000)); WriteMacInt32(XLM_RUN_MODE, MODE_68K); - // Install the handler for SIGSEGV - sigsegv_install_handler(sigsegv_handler); - #if ENABLE_MON // Install "regs" command in cxmon mon_add_command("regs", dump_registers, "regs Dump PowerPC registers\n"); @@ -1125,7 +1048,7 @@ void sheepshaver_cpu::handle_interrupt(v M68kRegisters r; uint32 old_r25 = ReadMacInt32(XLM_68K_R25); // Save interrupt level WriteMacInt32(XLM_68K_R25, 0x21); // Execute with interrupt level 1 - static const uint8 proc[] = { + static const uint8 proc_template[] = { 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) @@ -1133,7 +1056,8 @@ void sheepshaver_cpu::handle_interrupt(v 0x4e, 0xd0, // jmp (a0) M68K_RTS >> 8, M68K_RTS & 0xff // @1 }; - Execute68k((uint32)proc, &r); + BUILD_SHEEPSHAVER_PROCEDURE(proc); + Execute68k(proc, &r); WriteMacInt32(XLM_68K_R25, old_r25); // Restore interrupt level #else // Only update cursor @@ -1182,8 +1106,7 @@ void sheepshaver_cpu::execute_native_op( VideoVBL(); break; case NATIVE_VIDEO_DO_DRIVER_IO: - gpr(3) = (int32)(int16)VideoDoDriverIO((void *)gpr(3), (void *)gpr(4), - (void *)gpr(5), gpr(6), gpr(7)); + gpr(3) = (int32)(int16)VideoDoDriverIO(gpr(3), gpr(4), gpr(5), gpr(6), gpr(7)); break; #ifdef WORDS_BIGENDIAN case NATIVE_ETHER_IRQ: @@ -1268,7 +1191,7 @@ void sheepshaver_cpu::execute_native_op( break; } case NATIVE_MAKE_EXECUTABLE: - MakeExecutable(0, (void *)gpr(4), gpr(5)); + MakeExecutable(0, gpr(4), gpr(5)); break; case NATIVE_CHECK_LOAD_INVOC: check_load_invoc(gpr(3), gpr(4), gpr(5));