From 4f45d7de35400f29e46f1a176955b08c4c51d7fc Mon Sep 17 00:00:00 2001 From: joevt Date: Mon, 8 Apr 2024 21:18:45 -0700 Subject: [PATCH] cpu: Add cpu options to ppc_cpu_init. The first option is a flag that enables MPC601 (POWER) instructions for CPUs that are not MPC601. This can be useful for the following reasons: 1) To produce results similar to classic Mac OS which emulates MPC601 instructions on CPUs that don't implement MPC601 instructions. This option is used to compare the risu traces produced in Mac OS 9 on a G3 or G4 with DPPC. 2) May increase performance in apps that use POWER instructions on emulated machines with CPUs that are not MPC601. It is not known if any such apps exist but there could be since Apple included MPC601 emulation in classic Mac OS. --- cpu/ppc/ppcemu.h | 4 ++-- cpu/ppc/ppcexec.cpp | 12 ++++++------ cpu/ppc/test/ppctests.cpp | 2 +- machines/machinecatalyst.cpp | 4 ++-- machines/machinegazelle.cpp | 2 +- machines/machinegossamer.cpp | 2 +- machines/machinepdm.cpp | 2 +- machines/machinepippin.cpp | 2 +- machines/machinetnt.cpp | 6 +++--- machines/machineyosemite.cpp | 2 +- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index aeb76c0..539a898 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -398,7 +398,7 @@ typedef enum { } field_601; // Function prototypes -extern void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t cpu_version, uint64_t tb_freq); +extern void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t cpu_version, bool include_601, uint64_t tb_freq); extern void ppc_mmu_init(); void ppc_illegalop(); @@ -414,7 +414,7 @@ void ppc_opcode31(); void ppc_opcode59(); void ppc_opcode63(); -void initialize_ppc_opcode_tables(); +void initialize_ppc_opcode_tables(bool include_601); 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 ebacdd8..f8a26a4 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -586,13 +586,13 @@ do { \ #define OP63d(subopcode, fn) OPXd(SubOpcode63, subopcode, fn) #define OP63dc(subopcode, fn, carry) OPXdc(SubOpcode63, subopcode, fn, carry) -void initialize_ppc_opcode_tables() { +void initialize_ppc_opcode_tables(bool include_601) { 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. OP(7, ppc_mulli); OP(8, ppc_subfic); - if (is_601) OP(9, power_dozi); + if (is_601 || include_601) OP(9, power_dozi); OP(10, ppc_cmpli); OP(11, ppc_cmpi); OP(12, ppc_addic); @@ -605,7 +605,7 @@ void initialize_ppc_opcode_tables() { if (is_601) OP(19, ppc_opcode19); else OP(19, ppc_opcode19); OP(20, ppc_rlwimi); OP(21, ppc_rlwinm); - if (is_601) OP(22, power_rlmi); + if (is_601 || include_601) OP(22, power_rlmi); OP(23, ppc_rlwnm); OP(24, ppc_ori); OP(25, ppc_ori); @@ -741,7 +741,7 @@ void initialize_ppc_opcode_tables() { OP31(470, ppc_dcbi); OP31(1014, ppc_dcbz); - if (is_601) { + if (is_601 || include_601) { OP31d(29, power_maskg); OP31od(107, power_mul); OP31d(152, power_slq); @@ -822,7 +822,7 @@ void initialize_ppc_opcode_tables() { } } -void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t cpu_version, uint64_t tb_freq) +void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t cpu_version, bool include_601, uint64_t tb_freq) { int i; @@ -834,7 +834,7 @@ void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t cpu_version, uint64_t tb_freq) ppc_state.spr[SPR::PVR] = cpu_version; is_601 = (cpu_version >> 16) == 1; - initialize_ppc_opcode_tables(); + initialize_ppc_opcode_tables(include_601); // initialize emulator timers TimerManager::get_instance()->set_time_now_cb(&get_virt_time_ns); diff --git a/cpu/ppc/test/ppctests.cpp b/cpu/ppc/test/ppctests.cpp index b22067a..2a9a790 100644 --- a/cpu/ppc/test/ppctests.cpp +++ b/cpu/ppc/test/ppctests.cpp @@ -315,7 +315,7 @@ static void read_test_float_data() { } int main() { - initialize_ppc_opcode_tables(); //kludge + initialize_ppc_opcode_tables(true); //kludge cout << "Running DingusPPC emulator tests..." << endl << endl; diff --git a/machines/machinecatalyst.cpp b/machines/machinecatalyst.cpp index 99ae9c3..b00a598 100644 --- a/machines/machinecatalyst.cpp +++ b/machines/machinecatalyst.cpp @@ -79,7 +79,7 @@ int initialize_catalyst(std::string& id) std::string cpu = GET_STR_PROP("cpu"); if (cpu == "601") { // init virtual CPU and request MPC601 - ppc_cpu_init(platinum_obj, PPC_VER::MPC601, 7833600ULL); + ppc_cpu_init(platinum_obj, PPC_VER::MPC601, true, 7833600ULL); } else if (cpu == "750") { // configure CPU clocks @@ -87,7 +87,7 @@ int initialize_catalyst(std::string& id) uint64_t timebase_freq = bus_freq / 4; // initialize virtual CPU and request MPC750 CPU aka G3 - ppc_cpu_init(platinum_obj, PPC_VER::MPC750, timebase_freq); + ppc_cpu_init(platinum_obj, PPC_VER::MPC750, false, timebase_freq); // set CPU PLL ratio to 3.5 ppc_state.spr[SPR::HID1] = 0xE << 28; diff --git a/machines/machinegazelle.cpp b/machines/machinegazelle.cpp index d81f8c6..eccf962 100644 --- a/machines/machinegazelle.cpp +++ b/machines/machinegazelle.cpp @@ -77,7 +77,7 @@ int initialize_gazelle(std::string& id) uint64_t timebase_freq = bus_freq / 4; // init virtual CPU and request MPC603ev - ppc_cpu_init(psx_obj, PPC_VER::MPC603EV, timebase_freq); + ppc_cpu_init(psx_obj, PPC_VER::MPC603EV, false, timebase_freq); // CPU frequency is hardcoded to 225 MHz for now ppc_state.spr[SPR::HID1] = get_cpu_pll_value(225000000) << 28; diff --git a/machines/machinegossamer.cpp b/machines/machinegossamer.cpp index e47529c..b659f7a 100644 --- a/machines/machinegossamer.cpp +++ b/machines/machinegossamer.cpp @@ -146,7 +146,7 @@ int initialize_gossamer(std::string& id) uint64_t timebase_freq = bus_freq / 4; // initialize virtual CPU and request MPC750 CPU aka G3 - ppc_cpu_init(grackle_obj, PPC_VER::MPC750, timebase_freq); + ppc_cpu_init(grackle_obj, PPC_VER::MPC750, false, timebase_freq); // set CPU PLL ratio to 3.5 ppc_state.spr[SPR::HID1] = 0xE << 28; diff --git a/machines/machinepdm.cpp b/machines/machinepdm.cpp index e846f0f..82de2d9 100644 --- a/machines/machinepdm.cpp +++ b/machines/machinepdm.cpp @@ -90,7 +90,7 @@ int initialize_pdm(std::string& id) } // Init virtual CPU and request MPC601 - ppc_cpu_init(hmc_obj, PPC_VER::MPC601, 7812500ULL); + ppc_cpu_init(hmc_obj, PPC_VER::MPC601, true, 7812500ULL); return 0; } diff --git a/machines/machinepippin.cpp b/machines/machinepippin.cpp index 68a24f2..ed03f59 100644 --- a/machines/machinepippin.cpp +++ b/machines/machinepippin.cpp @@ -58,7 +58,7 @@ int initialize_pippin(std::string& id) { aspen_obj->insert_ram_dimm(3, GET_INT_PROP("rambank4_size")); // RAM expansion slot // init virtual CPU - ppc_cpu_init(aspen_obj, PPC_VER::MPC603, 16500000ULL); + ppc_cpu_init(aspen_obj, PPC_VER::MPC603, false, 16500000ULL); return 0; } diff --git a/machines/machinetnt.cpp b/machines/machinetnt.cpp index 4e78ae1..287d57e 100644 --- a/machines/machinetnt.cpp +++ b/machines/machinetnt.cpp @@ -101,16 +101,16 @@ int initialize_tnt(std::string& id) // init virtual CPU std::string cpu = GET_STR_PROP("cpu"); if (cpu == "604e") - ppc_cpu_init(memctrl_obj, PPC_VER::MPC604E, 12500000ULL); + ppc_cpu_init(memctrl_obj, PPC_VER::MPC604E, false, 12500000ULL); else if (cpu == "601") - ppc_cpu_init(memctrl_obj, PPC_VER::MPC601, 7833600ULL); + ppc_cpu_init(memctrl_obj, PPC_VER::MPC601, true, 7833600ULL); else if (cpu == "750") { // configure CPU clocks uint64_t bus_freq = 50000000ULL; uint64_t timebase_freq = bus_freq / 4; // initialize virtual CPU and request MPC750 CPU aka G3 - ppc_cpu_init(memctrl_obj, PPC_VER::MPC750, timebase_freq); + ppc_cpu_init(memctrl_obj, PPC_VER::MPC750, false, timebase_freq); // set CPU PLL ratio to 3.5 ppc_state.spr[SPR::HID1] = 0xE << 28; diff --git a/machines/machineyosemite.cpp b/machines/machineyosemite.cpp index 7daa011..b4e2128 100644 --- a/machines/machineyosemite.cpp +++ b/machines/machineyosemite.cpp @@ -76,7 +76,7 @@ int initialize_yosemite(std::string& id) uint64_t timebase_freq = bus_freq / 4; // initialize virtual CPU and request MPC750 CPU aka G3 - ppc_cpu_init(grackle_obj, PPC_VER::MPC750, timebase_freq); + ppc_cpu_init(grackle_obj, PPC_VER::MPC750, false, timebase_freq); // set CPU PLL ratio to 3.5 ppc_state.spr[SPR::HID1] = 0xE << 28;