--- SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp 2004/05/20 11:47:27 1.40 +++ SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp 2005/03/05 18:33:30 1.59 @@ -1,7 +1,7 @@ /* * sheepshaver_glue.cpp - Glue Kheperix CPU to SheepShaver CPU engine interface * - * SheepShaver (C) 1997-2004 Christian Bauer and Marc Hellwig + * SheepShaver (C) 1997-2005 Christian Bauer and Marc Hellwig * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,6 +42,13 @@ #include #include +#ifdef HAVE_MALLOC_H +#include +#endif + +#ifdef USE_SDL_VIDEO +#include +#endif #if ENABLE_MON #include "mon.h" @@ -52,11 +59,13 @@ #include "debug.h" // Emulation time statistics -#define EMUL_TIME_STATS 1 +#ifndef EMUL_TIME_STATS +#define EMUL_TIME_STATS 0 +#endif #if EMUL_TIME_STATS static clock_t emul_start_time; -static uint32 interrupt_count = 0; +static uint32 interrupt_count = 0, ppc_interrupt_count = 0; static clock_t interrupt_time = 0; static uint32 exec68k_count = 0; static clock_t exec68k_time = 0; @@ -84,12 +93,6 @@ extern "C" void check_load_invoc(uint32 // PowerPC EmulOp to exit from emulation looop const uint32 POWERPC_EXEC_RETURN = POWERPC_EMUL_OP | 1; -// Enable multicore (main/interrupts) cpu emulation? -#define MULTICORE_CPU (ASYNC_IRQ ? 1 : 0) - -// Enable interrupt routine safety checks? -#define SAFE_INTERRUPT_PPC 1 - // Enable Execute68k() safety checks? #define SAFE_EXEC_68K 1 @@ -102,14 +105,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 @@ -139,29 +139,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]; - uint32 pc; - uint32 lr; - uint32 ctr; - uint32 cr; - uint32 xer; - sheepshaver_cpu *cpu; - const char *where; - public: - interrupt_context(sheepshaver_cpu *_cpu, const char *_where); - ~interrupt_context(); - }; - public: // Constructor @@ -188,22 +165,26 @@ 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); // Handle MacOS interrupt void interrupt(uint32 entry); - void handle_interrupt(); // Make sure the SIGSEGV handler can access CPU registers friend sigsegv_return_t sigsegv_handler(sigsegv_address_t, sigsegv_address_t); + + // Memory allocator returning areas aligned on 16-byte boundaries + void *operator new(size_t size); + void operator delete(void *p); }; // Memory allocator returning areas aligned on 16-byte boundaries -void *operator new(size_t size) +void *sheepshaver_cpu::operator new(size_t size) { void *p; @@ -222,7 +203,7 @@ void *operator new(size_t size) return p; } -void operator delete(void *p) +void sheepshaver_cpu::operator delete(void *p) { #if defined(HAVE_MEMALIGN) || defined(HAVE_VALLOC) #if defined(__GLIBC__) @@ -271,57 +252,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); @@ -374,9 +307,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; @@ -447,14 +380,6 @@ int sheepshaver_cpu::compile1(codegen_co status = COMPILE_CODE_OK; break; #endif - case NATIVE_DISABLE_INTERRUPT: - dg.gen_invoke(DisableInterrupt); - status = COMPILE_CODE_OK; - break; - case NATIVE_ENABLE_INTERRUPT: - dg.gen_invoke(EnableInterrupt); - status = COMPILE_CODE_OK; - break; case NATIVE_BITBLT: dg.gen_load_T0_GPR(3); dg.gen_invoke_T0((void (*)(uint32))NQD_bitblt); @@ -472,21 +397,24 @@ int sheepshaver_cpu::compile1(codegen_co break; } // Could we fully translate this NativeOp? - if (FN_field::test(opcode)) { - if (status != COMPILE_FAILURE) { + if (status == COMPILE_CODE_OK) { + if (!FN_field::test(opcode)) + cg_context.done_compile = false; + else { dg.gen_load_A0_LR(); dg.gen_set_PC_A0(); + cg_context.done_compile = true; } - cg_context.done_compile = true; - break; - } - else if (status != COMPILE_FAILURE) { - cg_context.done_compile = false; break; } #if PPC_REENTRANT_JIT // Try to execute NativeOp trampoline - dg.gen_set_PC_im(cg_context.pc + 4); + if (!FN_field::test(opcode)) + dg.gen_set_PC_im(cg_context.pc + 4); + else { + dg.gen_load_A0_LR(); + dg.gen_set_PC_A0(); + } dg.gen_mov_32_T0_im(selector); dg.gen_jmp(native_op_trampoline); cg_context.done_compile = true; @@ -494,37 +422,20 @@ int sheepshaver_cpu::compile1(codegen_co break; #endif // Invoke NativeOp handler - typedef void (*func_t)(dyngen_cpu_base, uint32); - func_t func = (func_t)nv_mem_fun(&sheepshaver_cpu::execute_native_op).ptr(); - dg.gen_invoke_CPU_im(func, selector); - cg_context.done_compile = false; - status = COMPILE_CODE_OK; + if (!FN_field::test(opcode)) { + typedef void (*func_t)(dyngen_cpu_base, uint32); + func_t func = (func_t)nv_mem_fun(&sheepshaver_cpu::execute_native_op).ptr(); + dg.gen_invoke_CPU_im(func, selector); + cg_context.done_compile = false; + status = COMPILE_CODE_OK; + } + // Otherwise, let it generate a call to execute_sheep() which + // will cause necessary updates to the program counter break; } 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); @@ -544,72 +455,22 @@ int sheepshaver_cpu::compile1(codegen_co } } return status; -#endif - return COMPILE_FAILURE; -} - -// CPU context to preserve on interrupt -sheepshaver_cpu::interrupt_context::interrupt_context(sheepshaver_cpu *_cpu, const char *_where) -{ -#if SAFE_INTERRUPT_PPC >= 2 - cpu = _cpu; - where = _where; - - // Save interrupt context - memcpy(&gpr[0], &cpu->gpr(0), sizeof(gpr)); - pc = cpu->pc(); - lr = cpu->lr(); - ctr = cpu->ctr(); - cr = cpu->get_cr(); - xer = cpu->get_xer(); -#endif } - -sheepshaver_cpu::interrupt_context::~interrupt_context() -{ -#if SAFE_INTERRUPT_PPC >= 2 - // Check whether CPU context was preserved by interrupt - if (memcmp(&gpr[0], &cpu->gpr(0), sizeof(gpr)) != 0) { - printf("FATAL: %s: interrupt clobbers registers\n", where); - for (int i = 0; i < 32; i++) - if (gpr[i] != cpu->gpr(i)) - printf(" r%d: %08x -> %08x\n", i, gpr[i], cpu->gpr(i)); - } - if (pc != cpu->pc()) - printf("FATAL: %s: interrupt clobbers PC\n", where); - if (lr != cpu->lr()) - printf("FATAL: %s: interrupt clobbers LR\n", where); - if (ctr != cpu->ctr()) - printf("FATAL: %s: interrupt clobbers CTR\n", where); - if (cr != cpu->get_cr()) - printf("FATAL: %s: interrupt clobbers CR\n", where); - if (xer != cpu->get_xer()) - printf("FATAL: %s: interrupt clobbers XER\n", where); #endif -} // Handle MacOS interrupt void sheepshaver_cpu::interrupt(uint32 entry) { #if EMUL_TIME_STATS - interrupt_count++; + ppc_interrupt_count++; const clock_t interrupt_start = clock(); #endif -#if SAFE_INTERRUPT_PPC - static int depth = 0; - if (depth != 0) - printf("FATAL: sheepshaver_cpu::interrupt() called more than once: %d\n", depth); - depth++; -#endif - -#if !MULTICORE_CPU // Save program counters and branch registers uint32 saved_pc = pc(); uint32 saved_lr = lr(); uint32 saved_ctr= ctr(); uint32 saved_sp = gpr(1); -#endif // Initialize stack pointer to SheepShaver alternate stack base gpr(1) = SignalStackBase() - 64; @@ -649,21 +510,15 @@ void sheepshaver_cpu::interrupt(uint32 e // Enter nanokernel execute(entry); -#if !MULTICORE_CPU // Restore program counters and branch registers pc() = saved_pc; lr() = saved_lr; ctr()= saved_ctr; gpr(1) = saved_sp; -#endif #if EMUL_TIME_STATS interrupt_time += (clock() - interrupt_start); #endif - -#if SAFE_INTERRUPT_PPC - depth--; -#endif } // Execute 68k routine @@ -857,50 +712,32 @@ inline void sheepshaver_cpu::get_resourc * SheepShaver CPU engine interface **/ -static sheepshaver_cpu *main_cpu = NULL; // CPU emulator to handle usual control flow -static sheepshaver_cpu *interrupt_cpu = NULL; // CPU emulator to handle interrupts -static sheepshaver_cpu *current_cpu = NULL; // Current CPU emulator context +// PowerPC CPU emulator +static sheepshaver_cpu *ppc_cpu = NULL; void FlushCodeCache(uintptr start, uintptr end) { D(bug("FlushCodeCache(%08x, %08x)\n", start, end)); - main_cpu->invalidate_cache_range(start, end); -#if MULTICORE_CPU - interrupt_cpu->invalidate_cache_range(start, end); -#endif -} - -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 + ppc_cpu->invalidate_cache_range(start, end); } // Dump PPC registers static void dump_registers(void) { - current_cpu->dump_registers(); + ppc_cpu->dump_registers(); } // Dump log static void dump_log(void) { - current_cpu->dump_log(); + ppc_cpu->dump_log(); } /* * 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 @@ -912,15 +749,15 @@ 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 - sheepshaver_cpu * const cpu = current_cpu; + sheepshaver_cpu * const cpu = ppc_cpu; const uint32 pc = cpu->pc(); // Fault in Mac ROM or RAM? - bool mac_fault = (pc >= ROM_BASE) && (pc < (ROM_BASE + ROM_AREA_SIZE)) || (pc >= RAMBase) && (pc < (RAMBase + RAMSize)); + bool mac_fault = (pc >= ROM_BASE) && (pc < (ROM_BASE + ROM_AREA_SIZE)) || (pc >= RAMBase) && (pc < (RAMBase + RAMSize)) || (pc >= DR_CACHE_BASE && pc < (DR_CACHE_BASE + DR_CACHE_SIZE)); if (mac_fault) { // "VM settings" during MacOS 8 installation @@ -940,6 +777,12 @@ static sigsegv_return_t sigsegv_handler( return SIGSEGV_RETURN_SKIP_INSTRUCTION; else if (pc == ROM_BASE + 0x4a10a0 && (cpu->gpr(20) == 0xf3012002 || cpu->gpr(20) == 0xf3012000)) return SIGSEGV_RETURN_SKIP_INSTRUCTION; + + // MacOS 8.6 serial drivers on startup (with DR Cache and OldWorld ROM) + else if ((pc - DR_CACHE_BASE) < DR_CACHE_SIZE && (cpu->gpr(16) == 0xf3012002 || cpu->gpr(16) == 0xf3012000)) + return SIGSEGV_RETURN_SKIP_INSTRUCTION; + else if ((pc - DR_CACHE_BASE) < DR_CACHE_SIZE && (cpu->gpr(20) == 0xf3012002 || cpu->gpr(20) == 0xf3012000)) + return SIGSEGV_RETURN_SKIP_INSTRUCTION; // Ignore writes to the zero page else if ((uint32)(addr - SheepMem::ZeroPage()) < (uint32)SheepMem::PageSize()) @@ -956,9 +799,8 @@ static sigsegv_return_t sigsegv_handler( printf("SIGSEGV\n"); printf(" pc %p\n", fault_instruction); printf(" ea %p\n", fault_address); - printf(" cpu %s\n", current_cpu == main_cpu ? "main" : "interrupts"); dump_registers(); - current_cpu->dump_log(); + ppc_cpu->dump_log(); enter_mon(); QuitEmulator(); @@ -967,20 +809,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 - main_cpu = new sheepshaver_cpu(); - main_cpu->set_register(powerpc_registers::GPR(3), any_register((uint32)ROM_BASE + 0x30d000)); - main_cpu->set_register(powerpc_registers::GPR(4), any_register(KernelDataAddr + 0x1000)); + 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); -#if MULTICORE_CPU - // Initialize alternate CPU emulator to handle interrupts - interrupt_cpu = new sheepshaver_cpu(); -#endif - - // 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"); @@ -1006,6 +843,8 @@ void exit_emul_ppc(void) printf("Total emulation time : %.1f sec\n", double(emul_time) / double(CLOCKS_PER_SEC)); printf("Total interrupt count: %d (%2.1f Hz)\n", interrupt_count, (double(interrupt_count) * CLOCKS_PER_SEC) / double(emul_time)); + printf("Total ppc interrupt count: %d (%2.1f %%)\n", ppc_interrupt_count, + (double(ppc_interrupt_count) * 100.0) / double(interrupt_count)); #define PRINT_STATS(LABEL, VAR_PREFIX) do { \ printf("Total " LABEL " count : %d\n", VAR_PREFIX##_count); \ @@ -1022,10 +861,7 @@ void exit_emul_ppc(void) printf("\n"); #endif - delete main_cpu; -#if MULTICORE_CPU - delete interrupt_cpu; -#endif + delete ppc_cpu; } #if PPC_ENABLE_JIT && PPC_REENTRANT_JIT @@ -1060,68 +896,62 @@ void init_emul_op_trampolines(basic_dyng void emul_ppc(uint32 entry) { - current_cpu = main_cpu; #if 0 - current_cpu->start_log(); + ppc_cpu->start_log(); #endif // start emulation loop and enable code translation or caching - current_cpu->execute(entry); + ppc_cpu->execute(entry); } /* * Handle PowerPC interrupt */ -#if ASYNC_IRQ -void HandleInterrupt(void) -{ - main_cpu->handle_interrupt(); -} -#else void TriggerInterrupt(void) { #if 0 WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1); #else // Trigger interrupt to main cpu only - if (main_cpu) - main_cpu->trigger_interrupt(); + if (ppc_cpu) + ppc_cpu->trigger_interrupt(); #endif } -#endif -void sheepshaver_cpu::handle_interrupt(void) +void HandleInterrupt(powerpc_registers *r) { +#ifdef USE_SDL_VIDEO + // We must fill in the events queue in the same thread that did call SDL_SetVideoMode() + SDL_PumpEvents(); +#endif + // Do nothing if interrupts are disabled - if (*(int32 *)XLM_IRQ_NEST > 0) + if (int32(ReadMacInt32(XLM_IRQ_NEST)) > 0) return; - // Do nothing if there is no interrupt pending + // Do nothing if there is no pending interrupt if (InterruptFlags == 0) return; // Current interrupt nest level static int interrupt_depth = 0; ++interrupt_depth; - - // Disable MacOS stack sniffer - WriteMacInt32(0x110, 0); +#if EMUL_TIME_STATS + interrupt_count++; +#endif // Interrupt action depends on current run mode switch (ReadMacInt32(XLM_RUN_MODE)) { case MODE_68K: // 68k emulator active, trigger 68k interrupt level 1 - assert(current_cpu == main_cpu); WriteMacInt16(tswap32(kernel_data->v[0x67c >> 2]), 1); - set_cr(get_cr() | tswap32(kernel_data->v[0x674 >> 2])); + r->cr.set(r->cr.get() | tswap32(kernel_data->v[0x674 >> 2])); break; #if INTERRUPTS_IN_NATIVE_MODE case MODE_NATIVE: // 68k emulator inactive, in nanokernel? - assert(current_cpu == main_cpu); - if (gpr(1) != KernelDataAddr && interrupt_depth == 1) { - interrupt_context ctx(this, "PowerPC mode"); + if (r->gpr[1] != KernelDataAddr && interrupt_depth == 1) { // Prepare for 68k interrupt level 1 WriteMacInt16(tswap32(kernel_data->v[0x67c >> 2]), 1); @@ -1131,12 +961,10 @@ void sheepshaver_cpu::handle_interrupt(v // Execute nanokernel interrupt routine (this will activate the 68k emulator) DisableInterrupt(); - cpu_push(interrupt_cpu); if (ROMType == ROMTYPE_NEWWORLD) - current_cpu->interrupt(ROM_BASE + 0x312b1c); + ppc_cpu->interrupt(ROM_BASE + 0x312b1c); else - current_cpu->interrupt(ROM_BASE + 0x312a3c); - cpu_pop(); + ppc_cpu->interrupt(ROM_BASE + 0x312a3c); } break; #endif @@ -1145,13 +973,15 @@ void sheepshaver_cpu::handle_interrupt(v case MODE_EMUL_OP: // 68k emulator active, within EMUL_OP routine, execute 68k interrupt routine directly when interrupt level is 0 if ((ReadMacInt32(XLM_68K_R25) & 7) == 0) { - interrupt_context ctx(this, "68k mode"); +#if EMUL_TIME_STATS + const clock_t interrupt_start = clock(); +#endif #if 1 // Execute full 68k interrupt routine 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) @@ -1159,7 +989,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 @@ -1171,6 +1002,9 @@ void sheepshaver_cpu::handle_interrupt(v } } #endif +#if EMUL_TIME_STATS + interrupt_time += (clock() - interrupt_start); +#endif } break; #endif @@ -1205,10 +1039,8 @@ 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: EtherIRQ(); break; @@ -1230,12 +1062,6 @@ void sheepshaver_cpu::execute_native_op( case NATIVE_ETHER_RSRV: gpr(3) = ether_rsrv((queue_t *)gpr(3)); break; -#else - case NATIVE_ETHER_INIT: - // FIXME: needs more complicated thunks - gpr(3) = false; - break; -#endif case NATIVE_SYNC_HOOK: gpr(3) = NQD_sync_hook(gpr(3)); break; @@ -1290,14 +1116,8 @@ void sheepshaver_cpu::execute_native_op( get_resource_callbacks[selector - NATIVE_GET_RESOURCE](); break; } - case NATIVE_DISABLE_INTERRUPT: - DisableInterrupt(); - break; - case NATIVE_ENABLE_INTERRUPT: - EnableInterrupt(); - 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)); @@ -1321,7 +1141,7 @@ void sheepshaver_cpu::execute_native_op( void Execute68k(uint32 pc, M68kRegisters *r) { - current_cpu->execute_68k(pc, r); + ppc_cpu->execute_68k(pc, r); } /* @@ -1344,49 +1164,49 @@ void Execute68kTrap(uint16 trap, M68kReg uint32 call_macos(uint32 tvect) { - return current_cpu->execute_macos_code(tvect, 0, NULL); + return ppc_cpu->execute_macos_code(tvect, 0, NULL); } uint32 call_macos1(uint32 tvect, uint32 arg1) { const uint32 args[] = { arg1 }; - return current_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args); + return ppc_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args); } uint32 call_macos2(uint32 tvect, uint32 arg1, uint32 arg2) { const uint32 args[] = { arg1, arg2 }; - return current_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args); + return ppc_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args); } uint32 call_macos3(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3) { const uint32 args[] = { arg1, arg2, arg3 }; - return current_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args); + return ppc_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args); } uint32 call_macos4(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3, uint32 arg4) { const uint32 args[] = { arg1, arg2, arg3, arg4 }; - return current_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args); + return ppc_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args); } uint32 call_macos5(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3, uint32 arg4, uint32 arg5) { const uint32 args[] = { arg1, arg2, arg3, arg4, arg5 }; - return current_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args); + return ppc_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args); } uint32 call_macos6(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3, uint32 arg4, uint32 arg5, uint32 arg6) { const uint32 args[] = { arg1, arg2, arg3, arg4, arg5, arg6 }; - return current_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args); + return ppc_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args); } uint32 call_macos7(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3, uint32 arg4, uint32 arg5, uint32 arg6, uint32 arg7) { const uint32 args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7 }; - return current_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args); + return ppc_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args); } /* @@ -1395,25 +1215,25 @@ uint32 call_macos7(uint32 tvect, uint32 void get_resource(void) { - current_cpu->get_resource(ReadMacInt32(XLM_GET_RESOURCE)); + ppc_cpu->get_resource(ReadMacInt32(XLM_GET_RESOURCE)); } void get_1_resource(void) { - current_cpu->get_resource(ReadMacInt32(XLM_GET_1_RESOURCE)); + ppc_cpu->get_resource(ReadMacInt32(XLM_GET_1_RESOURCE)); } void get_ind_resource(void) { - current_cpu->get_resource(ReadMacInt32(XLM_GET_IND_RESOURCE)); + ppc_cpu->get_resource(ReadMacInt32(XLM_GET_IND_RESOURCE)); } void get_1_ind_resource(void) { - current_cpu->get_resource(ReadMacInt32(XLM_GET_1_IND_RESOURCE)); + ppc_cpu->get_resource(ReadMacInt32(XLM_GET_1_IND_RESOURCE)); } void r_get_resource(void) { - current_cpu->get_resource(ReadMacInt32(XLM_R_GET_RESOURCE)); + ppc_cpu->get_resource(ReadMacInt32(XLM_R_GET_RESOURCE)); }