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:
parent
a6ba9a0554
commit
4f45d7de35
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue