Move all PPC code execution to ppcexec.cpp.

This commit is contained in:
Maxim Poliakovski
2019-12-28 02:49:58 +01:00
parent 2d8150a201
commit 01dffb84f3
4 changed files with 120 additions and 124 deletions

View File

@@ -164,6 +164,8 @@ extern bool grab_branch;
extern bool grab_exception; extern bool grab_exception;
extern bool grab_return; extern bool grab_return;
extern bool power_on;
extern bool is_nubus; //For early Power Mac Emulation extern bool is_nubus; //For early Power Mac Emulation
extern bool is_601; //For PowerPC 601 Emulation extern bool is_601; //For PowerPC 601 Emulation
@@ -611,6 +613,9 @@ extern void ppc_psq_stu();
//G5+ instructions //G5+ instructions
extern void ppc_main_opcode(); extern void ppc_main_opcode(void);
extern void ppc_exec(void);
extern void ppc_exec_single(void);
extern void ppc_exec_until(uint32_t goal_addr);
#endif /* PPCEMU_H */ #endif /* PPCEMU_H */

View File

@@ -1,6 +1,12 @@
#include <unordered_map> #include <unordered_map>
#include <chrono>
#include "ppcemu.h" #include "ppcemu.h"
#include "ppcmmu.h"
bool power_on = 1;
clock_t clock_test_begin; //Used to make sure the TBR does not increment so quickly.
/** Opcode lookup tables. */ /** Opcode lookup tables. */
@@ -474,3 +480,106 @@ void ppc_main_opcode(){
uint8_t ppc_mainop = (ppc_cur_instruction >> 26) & 63; uint8_t ppc_mainop = (ppc_cur_instruction >> 26) & 63;
OpcodeGrabber[ppc_mainop](); OpcodeGrabber[ppc_mainop]();
} }
/** Old time base register (TBR) update code. */
void ppc_tbr_update()
{
clock_t clock_test_current = clock();
uint32_t test_clock = ((uint32_t) (clock_test_current - clock_test_begin)) / CLOCKS_PER_SEC;
if (test_clock){
if (ppc_state.ppc_tbr[0] != 0xFFFFFFFF){
ppc_state.ppc_tbr[0]++;
}
else{
ppc_state.ppc_tbr[0] = 0;
if (ppc_state.ppc_tbr[1] !=0xFFFFFFFF){
ppc_state.ppc_tbr[1]++;
}
else{
ppc_state.ppc_tbr[1] = 0;
}
}
clock_test_begin = clock();
//Placeholder Decrementing Code
if(ppc_state.ppc_spr[22] > 0){
ppc_state.ppc_spr[22]--;
}
}
}
/** Execute PPC code as long as power is on. */
void ppc_exec()
{
while (power_on){
//printf("PowerPC Address: %x \n", ppc_state.ppc_pc);
quickinstruction_translate(ppc_state.ppc_pc);
ppc_main_opcode();
if (grab_branch & !grab_exception){
ppc_state.ppc_pc = ppc_next_instruction_address;
grab_branch = 0;
ppc_tbr_update();
}
else if (grab_return | grab_exception){
ppc_state.ppc_pc = ppc_next_instruction_address;
grab_exception = 0;
grab_return = 0;
ppc_tbr_update();
}
else{
ppc_state.ppc_pc += 4;
ppc_tbr_update();
}
}
}
/** Execute one PPC instruction. */
void ppc_exec_single()
{
quickinstruction_translate(ppc_state.ppc_pc);
ppc_main_opcode();
if (grab_branch && !grab_exception) {
ppc_state.ppc_pc = ppc_next_instruction_address;
grab_branch = 0;
ppc_tbr_update();
}
else if (grab_return || grab_exception) {
ppc_state.ppc_pc = ppc_next_instruction_address;
grab_exception = 0;
grab_return = 0;
ppc_tbr_update();
}
else {
ppc_state.ppc_pc += 4;
ppc_tbr_update();
}
}
/** Execute PPC code until goal_addr is reached. */
void ppc_exec_until(uint32_t goal_addr)
{
while (ppc_state.ppc_pc != goal_addr) {
quickinstruction_translate(ppc_state.ppc_pc);
ppc_main_opcode();
if (grab_branch && !grab_exception) {
ppc_state.ppc_pc = ppc_next_instruction_address;
grab_branch = 0;
ppc_tbr_update();
}
else if (grab_return || grab_exception) {
ppc_state.ppc_pc = ppc_next_instruction_address;
grab_exception = 0;
grab_return = 0;
ppc_tbr_update();
}
else {
ppc_state.ppc_pc += 4;
ppc_tbr_update();
}
ppc_cur_instruction = 0;
}
}
void ppc_init()
{
clock_test_begin = clock();
}

View File

@@ -33,35 +33,6 @@ void dump_regs()
cout << "MSR: " << hex << ppc_state.ppc_msr << endl; cout << "MSR: " << hex << ppc_state.ppc_msr << endl;
} }
void execute_single_instr()
{
quickinstruction_translate(ppc_state.ppc_pc);
//cout << "Current instruction: " << hex << ppc_cur_instruction << endl;
ppc_main_opcode();
if (grab_branch && !grab_exception) {
//cout << "Grab branch, EA: " << hex << ppc_next_instruction_address << endl;
ppc_state.ppc_pc = ppc_next_instruction_address;
grab_branch = 0;
ppc_tbr_update();
}
else if (grab_return || grab_exception) {
ppc_state.ppc_pc = ppc_next_instruction_address;
grab_exception = 0;
grab_return = 0;
ppc_tbr_update();
}
else {
ppc_state.ppc_pc += 4;
ppc_tbr_update();
}
}
void execute_until(uint32_t goal_addr)
{
while(ppc_state.ppc_pc != goal_addr)
execute_single_instr();
}
void enter_debugger() void enter_debugger()
{ {
string inp, cmd, addr_str, last_cmd; string inp, cmd, addr_str, last_cmd;
@@ -94,11 +65,11 @@ void enter_debugger()
} else if (cmd == "regs") { } else if (cmd == "regs") {
dump_regs(); dump_regs();
} else if (cmd == "step") { } else if (cmd == "step") {
execute_single_instr(); ppc_exec_single();
} else if (cmd == "until") { } else if (cmd == "until") {
ss >> addr_str; ss >> addr_str;
addr = stol(addr_str, NULL, 16); addr = stol(addr_str, NULL, 16);
execute_until(addr); ppc_exec_until(addr);
} else if (cmd == "disas") { } else if (cmd == "disas") {
cout << "Disassembling not implemented yet. Sorry!" << endl; cout << "Disassembling not implemented yet. Sorry!" << endl;
} else { } else {

View File

@@ -16,8 +16,6 @@
#include <array> #include <array>
#include <stdio.h> #include <stdio.h>
#include <fstream> #include <fstream>
#include <chrono>
#include <ctime>
#include <stdexcept> #include <stdexcept>
#include "ppcemu.h" #include "ppcemu.h"
#include "ppcmmu.h" #include "ppcmmu.h"
@@ -66,7 +64,6 @@ static const map<string,string> PPCMac_ROMIdentity = { //Codename Abbreviation f
SetPRS ppc_state; SetPRS ppc_state;
bool power_on = 1;
bool is_nubus = 0; bool is_nubus = 0;
bool grab_branch; bool grab_branch;
@@ -121,8 +118,6 @@ uint32_t pci_io_end;
uint32_t rom_filesize; uint32_t rom_filesize;
clock_t clock_test_begin; //Used to make sure the TBR does not increment so quickly.
uint32_t write_opcode; uint32_t write_opcode;
uint8_t write_char; uint8_t write_char;
@@ -147,33 +142,6 @@ uint64_t rev_endian64(uint64_t insert_int){
return ENDIAN_REVERSE64(insert_int); return ENDIAN_REVERSE64(insert_int);
} }
//Time Base Register Update Code
//TODO - Make this a bit less hacky somehow.
void ppc_tbr_update()
{
clock_t clock_test_current = clock();
uint32_t test_clock = ((uint32_t) (clock_test_current - clock_test_begin)) / CLOCKS_PER_SEC;
if (test_clock){
if (ppc_state.ppc_tbr[0] != 0xFFFFFFFF){
ppc_state.ppc_tbr[0]++;
}
else{
ppc_state.ppc_tbr[0] = 0;
if (ppc_state.ppc_tbr[1] !=0xFFFFFFFF){
ppc_state.ppc_tbr[1]++;
}
else{
ppc_state.ppc_tbr[1] = 0;
}
}
clock_test_begin = clock();
//Placeholder Decrementing Code
if(ppc_state.ppc_spr[22] > 0){
ppc_state.ppc_spr[22]--;
}
}
}
void ppc_exception_handler(uint32_t exception_type, uint32_t handle_args){ void ppc_exception_handler(uint32_t exception_type, uint32_t handle_args){
ppc_next_instruction_address = 0x0; //used to construct a new address ppc_next_instruction_address = 0x0; //used to construct a new address
grab_exception = true; grab_exception = true;
@@ -365,61 +333,6 @@ uint32_t reg_write(){
return 0; return 0;
} }
void execute_interpreter(){
//Main execution loop for the interpreter.
while (power_on){
//printf("PowerPC Address: %x \n", ppc_state.ppc_pc);
quickinstruction_translate(ppc_state.ppc_pc);
ppc_main_opcode();
if (grab_branch & !grab_exception){
ppc_state.ppc_pc = ppc_next_instruction_address;
grab_branch = 0;
ppc_tbr_update();
}
else if (grab_return | grab_exception){
ppc_state.ppc_pc = ppc_next_instruction_address;
grab_exception = 0;
grab_return = 0;
ppc_tbr_update();
}
else{
ppc_state.ppc_pc += 4;
ppc_tbr_update();
}
}
}
void execute_interpreter_bp (uint32_t ppc_break_addr){
//Main loop like the above, with the only big difference
//being that this stops on reaching the desired address.
//It then prints the regs at the time it stopped.
while (ppc_state.ppc_pc != ppc_break_addr){
quickinstruction_translate(ppc_state.ppc_pc);
ppc_main_opcode();
if (grab_branch & !grab_exception){
ppc_state.ppc_pc = ppc_next_instruction_address;
grab_branch = 0;
ppc_tbr_update();
}
else if (grab_return | grab_exception){
ppc_state.ppc_pc = ppc_next_instruction_address;
grab_exception = 0;
grab_return = 0;
ppc_tbr_update();
}
else{
ppc_state.ppc_pc += 4;
ppc_tbr_update();
}
ppc_cur_instruction = 0;
}
reg_print();
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
ram_size_set = 0x4000000; //64 MB of RAM for the Mac ram_size_set = 0x4000000; //64 MB of RAM for the Mac
@@ -577,8 +490,6 @@ int main(int argc, char **argv)
mem_ctrl_instance->set_data(0xFFC00000, machine_sysrom_mem, rom_filesize); mem_ctrl_instance->set_data(0xFFC00000, machine_sysrom_mem, rom_filesize);
romFile.close(); romFile.close();
clock_test_begin = clock();
if (argc > 1){ if (argc > 1){
string checker = argv[1]; string checker = argv[1];
cout << checker << endl; cout << checker << endl;
@@ -593,7 +504,7 @@ int main(int argc, char **argv)
} }
} }
else if ((checker=="1")|(checker=="realtime")|(checker=="/realtime")|(checker=="-realtime")){ else if ((checker=="1")|(checker=="realtime")|(checker=="/realtime")|(checker=="-realtime")){
execute_interpreter(); ppc_exec();
} }
else if ((checker=="e")|(checker=="loadelf")|(checker=="/loadelf")|(checker=="-loadelf")){ else if ((checker=="e")|(checker=="loadelf")|(checker=="/loadelf")|(checker=="-loadelf")){
ifstream elfFile; ifstream elfFile;
@@ -656,7 +567,7 @@ int main(int argc, char **argv)
ppc_state.ppc_pc = atoi(elf_memoffset); ppc_state.ppc_pc = atoi(elf_memoffset);
execute_interpreter(); ppc_exec();
} }
else if ((checker=="until")|(checker=="/until")|(checker=="-until")){ else if ((checker=="until")|(checker=="/until")|(checker=="-until")){
uint32_t grab_bp = 0x0; uint32_t grab_bp = 0x0;
@@ -664,7 +575,7 @@ int main(int argc, char **argv)
std::cout << hex << "Enter the address in hex for where to stop execution." << endl; std::cout << hex << "Enter the address in hex for where to stop execution." << endl;
cin >> hex >> grab_bp; cin >> hex >> grab_bp;
execute_interpreter_bp(grab_bp); ppc_exec_until(grab_bp);
} }
else if (checker=="disas"){ else if (checker=="disas"){
if (argc > 2){ if (argc > 2){