diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index 8b64c50..5001d60 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -164,6 +164,8 @@ extern bool grab_branch; extern bool grab_exception; extern bool grab_return; +extern bool power_on; + extern bool is_nubus; //For early Power Mac Emulation extern bool is_601; //For PowerPC 601 Emulation @@ -611,6 +613,9 @@ extern void ppc_psq_stu(); //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 */ diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index abfcc77..2aecdf7 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -1,6 +1,12 @@ #include +#include #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. */ @@ -474,3 +480,106 @@ void ppc_main_opcode(){ uint8_t ppc_mainop = (ppc_cur_instruction >> 26) & 63; 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(); +} diff --git a/debugger/debugger.cpp b/debugger/debugger.cpp index d3aa651..c797f97 100644 --- a/debugger/debugger.cpp +++ b/debugger/debugger.cpp @@ -33,35 +33,6 @@ void dump_regs() 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() { string inp, cmd, addr_str, last_cmd; @@ -94,11 +65,11 @@ void enter_debugger() } else if (cmd == "regs") { dump_regs(); } else if (cmd == "step") { - execute_single_instr(); + ppc_exec_single(); } else if (cmd == "until") { ss >> addr_str; addr = stol(addr_str, NULL, 16); - execute_until(addr); + ppc_exec_until(addr); } else if (cmd == "disas") { cout << "Disassembling not implemented yet. Sorry!" << endl; } else { diff --git a/main.cpp b/main.cpp index f6f0569..49c0f34 100644 --- a/main.cpp +++ b/main.cpp @@ -16,8 +16,6 @@ #include #include #include -#include -#include #include #include "ppcemu.h" #include "ppcmmu.h" @@ -66,7 +64,6 @@ static const map PPCMac_ROMIdentity = { //Codename Abbreviation f SetPRS ppc_state; -bool power_on = 1; bool is_nubus = 0; bool grab_branch; @@ -121,8 +118,6 @@ uint32_t pci_io_end; uint32_t rom_filesize; -clock_t clock_test_begin; //Used to make sure the TBR does not increment so quickly. - uint32_t write_opcode; uint8_t write_char; @@ -147,33 +142,6 @@ uint64_t rev_endian64(uint64_t 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){ ppc_next_instruction_address = 0x0; //used to construct a new address grab_exception = true; @@ -365,61 +333,6 @@ uint32_t reg_write(){ 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) { 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); romFile.close(); - clock_test_begin = clock(); - if (argc > 1){ string checker = argv[1]; cout << checker << endl; @@ -593,7 +504,7 @@ int main(int argc, char **argv) } } else if ((checker=="1")|(checker=="realtime")|(checker=="/realtime")|(checker=="-realtime")){ - execute_interpreter(); + ppc_exec(); } else if ((checker=="e")|(checker=="loadelf")|(checker=="/loadelf")|(checker=="-loadelf")){ ifstream elfFile; @@ -656,7 +567,7 @@ int main(int argc, char **argv) ppc_state.ppc_pc = atoi(elf_memoffset); - execute_interpreter(); + ppc_exec(); } else if ((checker=="until")|(checker=="/until")|(checker=="-until")){ 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; cin >> hex >> grab_bp; - execute_interpreter_bp(grab_bp); + ppc_exec_until(grab_bp); } else if (checker=="disas"){ if (argc > 2){