diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index 250913d..f98e77e 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -325,6 +325,7 @@ extern bool int_pin; extern bool dec_exception_pending; extern bool is_601; // For PowerPC 601 Emulation +extern bool include_601; // For non-PowerPC 601 emulation with 601 extras (matches Mac OS 9 environment which can emulate MPC 601 instructions) extern bool is_altivec; // For Altivec Emulation extern bool is_64bit; // For PowerPC G5 Emulation @@ -417,7 +418,7 @@ void ppc_opcode31(); void ppc_opcode59(); void ppc_opcode63(); -void initialize_ppc_opcode_tables(bool include_601); +void initialize_ppc_opcode_tables(); extern double fp_return_double(uint32_t reg); extern uint64_t fp_return_uint64(uint32_t reg); diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 8d8a3c8..84d6059 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -56,6 +56,7 @@ using namespace dppc_interpreter; MemCtrlBase* mem_ctrl_instance = 0; bool is_601 = false; +bool include_601 = false; bool is_deterministic = false; @@ -637,7 +638,7 @@ do { \ #define OP63d(subopcode, fn) OPXd(SubOpcode63, subopcode, fn) #define OP63dc(subopcode, fn, carry) OPXdc(SubOpcode63, subopcode, fn, carry) -void initialize_ppc_opcode_tables(bool include_601) { +void initialize_ppc_opcode_tables() { std::fill_n(OpcodeGrabber, 64, ppc_illegalop); OP(3, ppc_twi); //OP(4, ppc_opcode4); - Altivec instructions not emulated yet. Uncomment once they're implemented. @@ -873,7 +874,7 @@ void initialize_ppc_opcode_tables(bool include_601) { } } -void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t cpu_version, bool include_601, uint64_t tb_freq) +void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t cpu_version, bool do_include_601, uint64_t tb_freq) { mem_ctrl_instance = mem_ctrl; @@ -882,8 +883,9 @@ void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t cpu_version, bool include_601, ppc_state.spr[SPR::PVR] = cpu_version; is_601 = (cpu_version >> 16) == 1; + include_601 = !is_601 & do_include_601; - initialize_ppc_opcode_tables(include_601); + initialize_ppc_opcode_tables(); // initialize emulator timers TimerManager::get_instance()->set_time_now_cb(&get_virt_time_ns); diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index 8bfe4f9..0e28d51 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -903,7 +903,7 @@ void dppc_interpreter::ppc_mfspr() { switch (ref_spr) { case SPR::MQ: - if (!is_601) { + if (!(is_601 || include_601)) { ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); } ppc_state.gpr[reg_d] = ppc_state.spr[ref_spr]; @@ -957,10 +957,10 @@ void dppc_interpreter::ppc_mtspr() { switch (ref_spr) { case SPR::MQ: - if (!is_601) { + if (is_601 || include_601) + ppc_state.spr[ref_spr] = val; + else ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP); - } - ppc_state.spr[ref_spr] = val; break; case SPR::RTCL_U: case SPR::RTCU_U: diff --git a/cpu/ppc/test/ppctests.cpp b/cpu/ppc/test/ppctests.cpp index ae16b1b..5e014ea 100644 --- a/cpu/ppc/test/ppctests.cpp +++ b/cpu/ppc/test/ppctests.cpp @@ -321,7 +321,8 @@ static void read_test_float_data() { } int main() { - initialize_ppc_opcode_tables(true); //kludge + is_601 = true; + initialize_ppc_opcode_tables(); //kludge cout << "Running DingusPPC emulator tests..." << endl << endl;