static void ppc_opc_invalid() { #if 0 if (gCPU.pc == gPromOSIEntry && gCPU.current_opc == PROM_MAGIC_OPCODE) { call_prom_osi(); return; } if (gCPU.current_opc == 0x00333301) { // memset(r3, r4, r5) uint32 dest = gCPU.gpr[3]; uint32 c = gCPU.gpr[4]; uint32 size = gCPU.gpr[5]; if (dest & 0xfff) { byte *dst; ppc_direct_effective_memory_handle(dest, dst); uint32 a = 4096 - (dest & 0xfff); memset(dst, c, a); size -= a; dest += a; } while (size >= 4096) { byte *dst; ppc_direct_effective_memory_handle(dest, dst); memset(dst, c, 4096); dest += 4096; size -= 4096; } if (size) { byte *dst; ppc_direct_effective_memory_handle(dest, dst); memset(dst, c, size); } gCPU.pc = gCPU.npc; return; } if (gCPU.current_opc == 0x00333302) { // memcpy uint32 dest = gCPU.gpr[3]; uint32 src = gCPU.gpr[4]; uint32 size = gCPU.gpr[5]; byte *d, *s; ppc_direct_effective_memory_handle(dest, d); ppc_direct_effective_memory_handle(src, s); while (size--) { if (!(dest & 0xfff)) ppc_direct_effective_memory_handle(dest, d); if (!(src & 0xfff)) ppc_direct_effective_memory_handle(src, s); *d = *s; src++; dest++; d++; s++; } gCPU.pc = gCPU.npc; return; } #endif ht_printf("[PPC/DEC] Bad opcode: %08x (%u:%u) PC=%08x\n", gCPU.current_opc, PPC_OPC_MAIN(gCPU.current_opc), PPC_OPC_EXT(gCPU.current_opc), gCPU.pc); SINGLESTEP("unknown instruction\n"); }
void ppc_cpu_run() { /*gDebugger = new Debugger(); gDebugger->mAlwaysShowRegs = true;*/ PPC_CPU_TRACE("execution started at %08x\n", current_core->pc); uint ops=0; current_core->effective_code_page = 0xffffffff; // ppc_fpu_test(); // return; while (true) { current_core->npc = current_core->pc+4; if ((current_core->pc & ~0xfff) == current_core->effective_code_page) { current_core->current_opc = ppc_word_from_BE(*((uint32*)(¤t_core->physical_code_page[current_core->pc & 0xfff]))); ppc_debug_hook(); } else { int ret; if ((ret = ppc_direct_effective_memory_handle_code(current_core->pc & ~0xfff, current_core->physical_code_page))) { if (ret == PPC_MMU_EXC) { current_core->pc = current_core->npc; continue; } else { PPC_CPU_ERR("?\n"); } } current_core->effective_code_page = current_core->pc & ~0xfff; continue; } ppc_exec_opc(); ops++; current_core->ptb++; if (current_core->pdec == 0) { current_core->exception_pending = true; current_core->dec_exception = true; current_core->pdec=0xffffffff*TB_TO_PTB_FACTOR; } else { current_core->pdec--; } if ((ops & 0x3ffff)==0) { /* if (pic_check_interrupt()) { current_core->exception_pending = true; current_core->ext_exception = true; }*/ if ((ops & 0x0fffff)==0) { // uint32 j=0; // ppc_read_effective_word(0xc046b2f8, j); ht_printf("@%08x (%u ops) pdec: %08x lr: %08x\r", current_core->pc, ops, current_core->pdec, current_core->lr); #if 0 extern uint32 PIC_enable_low; extern uint32 PIC_enable_high; ht_printf("enable "); int x = 1; for (int i=0; i<31; i++) { if (PIC_enable_low & x) { ht_printf("%d ", i); } x<<=1; } x=1; for (int i=0; i<31; i++) { if (PIC_enable_high & x) { ht_printf("%d ", 32+i); } x<<=1; } ht_printf("\n"); #endif } } current_core->pc = current_core->npc; if (current_core->exception_pending) { if (current_core->stop_exception) { current_core->stop_exception = false; if (!current_core->dec_exception && !current_core->ext_exception) current_core->exception_pending = false; break; } if (current_core->msr & MSR_EE) { /*sys_lock_mutex(exception_mutex);*/ if (current_core->ext_exception) { ppc_exception(current_core, PPC_EXC_EXT_INT,0,0); current_core->ext_exception = false; current_core->pc = current_core->npc; if (!current_core->dec_exception) current_core->exception_pending = false; /*sys_unlock_mutex(exception_mutex);*/ continue; } if (current_core->dec_exception) { ppc_exception(current_core, PPC_EXC_DEC,0,0); current_core->dec_exception = false; current_core->pc = current_core->npc; current_core->exception_pending = false; /*sys_unlock_mutex(exception_mutex);*/ continue; } /*sys_unlock_mutex(exception_mutex);*/ PPC_CPU_ERR("no interrupt, but signaled?!\n"); } } #ifdef PPC_CPU_ENABLE_SINGLESTEP if (current_core->msr & MSR_SE) { if (current_core->singlestep_ignore) { current_core->singlestep_ignore = false; } else { ppc_exception(current_core, PPC_EXC_TRACE2); current_core->pc = current_core->npc; continue; } } #endif } }