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.
This commit is contained in:
joevt 2024-04-08 21:18:45 -07:00 committed by dingusdev
parent a6ba9a0554
commit 4f45d7de35
10 changed files with 19 additions and 19 deletions

View File

@ -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);

View File

@ -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<RC0>);
@ -605,7 +605,7 @@ void initialize_ppc_opcode_tables() {
if (is_601) OP(19, ppc_opcode19<IS601>); else OP(19, ppc_opcode19<NOT601>);
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<SHFT0>);
OP(25, ppc_ori<SHFT1>);
@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;