From 9685be31547411791b52027fefc4f81c9dae5873 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Wed, 17 Jul 2019 17:38:22 +0200 Subject: [PATCH 1/7] ppcopcodes: fix mask generation for rotation instructions. --- ppcopcodes.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ppcopcodes.cpp b/ppcopcodes.cpp index f8eed30..a5068e2 100644 --- a/ppcopcodes.cpp +++ b/ppcopcodes.cpp @@ -1272,7 +1272,7 @@ void ppc_rlwimi(){ rot_sh = (ppc_cur_instruction >> 11) & 31; rot_mb = (ppc_cur_instruction >> 6) & 31; rot_me = (ppc_cur_instruction >> 1) & 31; - uint32_t step1 = (0xFFFFFFFF >> (rot_me + 1)) ^ (0xFFFFFFFF >> rot_mb); + uint32_t step1 = (0xFFFFFFFFUL << (rot_me + 1)) ^ (0xFFFFFFFFUL >> rot_mb); uint32_t step2 = (rot_me < rot_mb)? ~step1 : step1; uint32_t step3 = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32-rot_sh))); ppc_result_a = (ppc_result_a & ~step2) | (step3 & step2); @@ -1287,7 +1287,7 @@ void ppc_rlwinm(){ rot_sh = (ppc_cur_instruction >> 11) & 31; rot_mb = (ppc_cur_instruction >> 6) & 31; rot_me = (ppc_cur_instruction >> 1) & 31; - uint32_t step1 = (0xFFFFFFFF >> (rot_me + 1)) ^ (0xFFFFFFFF >> rot_mb); + uint32_t step1 = (0xFFFFFFFFUL << (rot_me + 1)) ^ (0xFFFFFFFFUL >> rot_mb); uint32_t step2 = (rot_me < rot_mb)? ~step1 : step1; uint32_t step3 = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32-rot_sh))); ppc_result_a = step2 & step3; @@ -1301,7 +1301,7 @@ void ppc_rlwnm(){ ppc_grab_regssab(); rot_mb = (ppc_cur_instruction >> 6) & 31; rot_me = (ppc_cur_instruction >> 1) & 31; - uint32_t step1 = (0xFFFFFFFF >> (rot_me + 1)) ^ (0xFFFFFFFF >> rot_mb); + uint32_t step1 = (0xFFFFFFFFUL << (rot_me + 1)) ^ (0xFFFFFFFFUL >> rot_mb); uint32_t step2 = (rot_me < rot_mb)? ~step1 : step1; uint32_t step3 = ((ppc_result_d << ppc_result_b) | (ppc_result_d >> (32-ppc_result_b))); ppc_result_a = step2 & step3; From fc26660f1176411541c4123457077ce558692ffc Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Wed, 17 Jul 2019 17:40:19 +0200 Subject: [PATCH 2/7] ppcopcodes: partial fix for XER[CA] updates. --- ppcopcodes.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ppcopcodes.cpp b/ppcopcodes.cpp index a5068e2..38e8b29 100644 --- a/ppcopcodes.cpp +++ b/ppcopcodes.cpp @@ -168,7 +168,7 @@ void ppc_changecrf0(uint32_t set_result){ //Affects the XER register's Carry Bit void ppc_carry(uint32_t a, uint32_t b){ - if (b > ~a){ + if (b < a){ // TODO: ensure it works everywhere ppc_state.ppc_spr[1] |= 0x20000000; } else{ @@ -384,9 +384,9 @@ void ppc_addcodot(){ void ppc_adde(){ ppc_grab_regsdab(); - uint32_t grab_xer = ppc_state.ppc_spr[1] & 0x20000000; - ppc_result_d = ppc_result_a + ppc_result_b + grab_xer; - if (((grab_xer != 0) && (grab_xer > (~(ppc_result_b + ppc_result_a)))) || (ppc_result_d > ~ppc_result_a)){ + uint32_t xer_ca = !!(ppc_state.ppc_spr[1] & 0x20000000); + ppc_result_d = ppc_result_a + ppc_result_b + xer_ca; + if ((ppc_result_d < ppc_result_a) || (xer_ca && (ppc_result_d == ppc_result_a))){ ppc_state.ppc_spr[1] |= 0x20000000; } else{ @@ -646,7 +646,7 @@ void ppc_subfic(){ ppc_grab_regsdasimm(); not_this = ~ppc_result_a; ppc_result_d = not_this + simm + 1; - if (ppc_result_d < (not_this + 1)){ + if (ppc_result_d <= not_this) { ppc_state.ppc_spr[1] |= 0x20000000; } else{ From 051be54633a9f1850ed0a1c9e77d71800f2df0bd Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Wed, 17 Jul 2019 17:55:27 +0200 Subject: [PATCH 3/7] main: fix access to wrong/uninitialized variables. --- main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.cpp b/main.cpp index c04afbf..8abe295 100644 --- a/main.cpp +++ b/main.cpp @@ -729,7 +729,7 @@ int main(int argc, char **argv) uint32_t grab_bp = 0x0; std::cout << hex << "Enter the address in hex for where to stop execution." << endl; - cin >> hex >> opcode_entered; + cin >> hex >> grab_bp; execute_interpreter_bp(grab_bp); } @@ -757,7 +757,7 @@ int main(int argc, char **argv) quickinstruction_translate(ppc_state.ppc_pc); ppc_main_opcode(); if (grab_branch & !grab_exception){ - ppc_state.ppc_pc = ppc_effective_address; + ppc_state.ppc_pc = ppc_next_instruction_address; grab_branch = 0; ppc_tbr_update(); } From 4ffaf2cef3b9ecb9ad2c050ddc84d106ea20d848 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Wed, 17 Jul 2019 15:24:34 +0200 Subject: [PATCH 4/7] Add simple command-line debugger. --- CMakeLists.txt | 4 +- debugger.cpp | 111 +++++++++++++++++++++++++++++++++++++++++++++++++ debugger.h | 6 +++ main.cpp | 3 ++ makefile | 11 +++-- 5 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 debugger.cpp create mode 100644 debugger.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a31f0e5..aad0f61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ set(SOURCE_FILES viacuda.cpp main.cpp davbus.cpp + debugger.cpp ) set(HEADER_FILES @@ -33,7 +34,8 @@ set(HEADER_FILES ppcmemory.h viacuda.h davbus.h + debugger.h ) add_executable(dingusppc ${SOURCE_FILES} ${HEADER_FILES}) -install (TARGETS dingusppc DESTINATION bin) \ No newline at end of file +install (TARGETS dingusppc DESTINATION bin) diff --git a/debugger.cpp b/debugger.cpp new file mode 100644 index 0000000..3010aeb --- /dev/null +++ b/debugger.cpp @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include "ppcemumain.h" +#include "ppcmemory.h" + + +using namespace std; + +void show_help() +{ + cout << "Debugger commands:" << endl; + cout << " step -- execute single instruction" << endl; + cout << " until X -- execute until address X is reached" << endl; + cout << " regs -- dump content of the GRPs" << endl; + cout << " disas X,n -- disassemble N instructions starting at address X" << endl; + cout << " quit -- quit the debugger" << endl << endl; + cout << "Pressing ENTER will repeat last command." << endl; +} + +void dump_regs() +{ + for (uint32_t i = 0; i < 32; i++) + cout << "GPR " << dec << i << " : " << hex << ppc_state.ppc_gpr[i] << endl; + + cout << "PC: " << hex << ppc_state.ppc_pc << endl; + cout << "LR: " << hex << ppc_state.ppc_spr[8] << endl; + cout << "CR: " << hex << ppc_state.ppc_cr << endl; + cout << "CTR: " << hex << ppc_state.ppc_spr[9] << endl; + cout << "XER: " << hex << ppc_state.ppc_spr[1] << 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(); + } + ppc_cur_instruction = 0; +} + +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; + uint32_t addr; + std::stringstream ss; + + cout << "Welcome to the PowerPC debugger." << endl; + cout << "Please enter a command or 'help'." << endl << endl; + + while (1) { + cout << "ppcdbg> "; + + /* reset string stream */ + ss.str(""); + ss.clear(); + + cmd = ""; + getline(cin, inp, '\n'); + ss.str(inp); + ss >> cmd; + + if (cmd.empty() && !last_cmd.empty()) { + cmd = last_cmd; + cout << cmd << endl; + } + if (cmd == "help") { + show_help(); + } else if (cmd == "quit") { + break; + } else if (cmd == "regs") { + dump_regs(); + } else if (cmd == "step") { + execute_single_instr(); + } else if (cmd == "until") { + ss >> addr_str; + addr = stol(addr_str, NULL, 16); + execute_until(addr); + } else if (cmd == "disas") { + cout << "Disassembling not implemented yet. Sorry!" << endl; + } else { + cout << "Unknown command: " << cmd << endl; + continue; + } + last_cmd = cmd; + } +} diff --git a/debugger.h b/debugger.h new file mode 100644 index 0000000..b278ea9 --- /dev/null +++ b/debugger.h @@ -0,0 +1,6 @@ +#ifndef DEBUGGER_H_ +#define DEBUGGER_H_ + +void enter_debugger(void); + +#endif // DEBUGGER_H_ diff --git a/main.cpp b/main.cpp index 8abe295..17641e5 100644 --- a/main.cpp +++ b/main.cpp @@ -25,6 +25,7 @@ #include "viacuda.h" #include "mpc106.h" #include "openpic.h" +#include "debugger.h" //#include #define max_16b_int 65535 @@ -846,6 +847,8 @@ int main(int argc, char **argv) ppc_cur_instruction = 0; } } + } else if (checker == "debugger") { + enter_debugger(); } } else{ diff --git a/makefile b/makefile index a20d720..cc2c726 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,6 @@ -OBJS = main.o macioserial.o macscsi.o macswim3.o mpc106.o openpic.o poweropcodes.o ppcfpopcodes.o ppcgekkoopcodes.o ppcmemory.o ppcopcodes.o viacuda.o davbus.o -SOURCE = main.cpp macioserial.cpp macscsi.cpp macswim3.cpp mpc106.cpp openpic.cpp poweropcodes.cpp ppcfpopcodes.cpp ppcgekkoopcodes.cpp ppcmemory.cpp ppcopcodes.cpp viacuda.cpp davbus.cpp -HEADER = macioserial.h macscsi.h macswim3.h mpc106.h openpic.h ppcemumain.h ppcmemory.h viacuda.h +OBJS = main.o macioserial.o macscsi.o macswim3.o mpc106.o openpic.o poweropcodes.o ppcfpopcodes.o ppcgekkoopcodes.o ppcmemory.o ppcopcodes.o viacuda.o davbus.o debugger.o +SOURCE = main.cpp macioserial.cpp macscsi.cpp macswim3.cpp mpc106.cpp openpic.cpp poweropcodes.cpp ppcfpopcodes.cpp ppcgekkoopcodes.cpp ppcmemory.cpp ppcopcodes.cpp viacuda.cpp davbus.cpp debugger.cpp +HEADER = macioserial.h macscsi.h macswim3.h mpc106.h openpic.h ppcemumain.h ppcmemory.h viacuda.h debugger.h OUT = dingusppc CC = g++ FLAGS = -g -c -Wall -std=c++11 @@ -46,7 +46,10 @@ viacuda.o: viacuda.cpp $(CC) $(FLAGS) viacuda.cpp davbus.o: davbus.cpp - $(CC) $(FLAGS) davbus.cpp + $(CC) $(FLAGS) davbus.cpp + +debugger.o: debugger.cpp + $(CC) $(FLAGS) debugger.cpp clean: rm -f $(OBJS) $(OUT) From c253c48d89039563f61fb92e90863aa6440cfc7b Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Wed, 17 Jul 2019 19:04:31 +0200 Subject: [PATCH 5/7] ppcopcodes: fix mfmsr emulation. --- ppcopcodes.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/ppcopcodes.cpp b/ppcopcodes.cpp index 38e8b29..c501e52 100644 --- a/ppcopcodes.cpp +++ b/ppcopcodes.cpp @@ -1355,7 +1355,6 @@ void ppc_mfmsr(){ if ((ppc_state.ppc_msr & 0x4000) == 0){ reg_d = (ppc_cur_instruction >> 21) & 31; ppc_state.ppc_gpr[reg_d] = ppc_state.ppc_msr; - ppc_store_result_regd(); } } From 521d6e49606a5105baf7e4bed0964cebd21fa578 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Wed, 17 Jul 2019 19:37:07 +0200 Subject: [PATCH 6/7] ppcopcodes: fix (again) mask calculation for rotations. --- ppcopcodes.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ppcopcodes.cpp b/ppcopcodes.cpp index c501e52..5182861 100644 --- a/ppcopcodes.cpp +++ b/ppcopcodes.cpp @@ -1272,7 +1272,7 @@ void ppc_rlwimi(){ rot_sh = (ppc_cur_instruction >> 11) & 31; rot_mb = (ppc_cur_instruction >> 6) & 31; rot_me = (ppc_cur_instruction >> 1) & 31; - uint32_t step1 = (0xFFFFFFFFUL << (rot_me + 1)) ^ (0xFFFFFFFFUL >> rot_mb); + uint32_t step1 = (0xFFFFFFFFUL << (31 - rot_me)) & (0xFFFFFFFFUL >> rot_mb); uint32_t step2 = (rot_me < rot_mb)? ~step1 : step1; uint32_t step3 = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32-rot_sh))); ppc_result_a = (ppc_result_a & ~step2) | (step3 & step2); @@ -1287,7 +1287,7 @@ void ppc_rlwinm(){ rot_sh = (ppc_cur_instruction >> 11) & 31; rot_mb = (ppc_cur_instruction >> 6) & 31; rot_me = (ppc_cur_instruction >> 1) & 31; - uint32_t step1 = (0xFFFFFFFFUL << (rot_me + 1)) ^ (0xFFFFFFFFUL >> rot_mb); + uint32_t step1 = (0xFFFFFFFFUL << (31 - rot_me)) & (0xFFFFFFFFUL >> rot_mb); uint32_t step2 = (rot_me < rot_mb)? ~step1 : step1; uint32_t step3 = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32-rot_sh))); ppc_result_a = step2 & step3; @@ -1301,7 +1301,7 @@ void ppc_rlwnm(){ ppc_grab_regssab(); rot_mb = (ppc_cur_instruction >> 6) & 31; rot_me = (ppc_cur_instruction >> 1) & 31; - uint32_t step1 = (0xFFFFFFFFUL << (rot_me + 1)) ^ (0xFFFFFFFFUL >> rot_mb); + uint32_t step1 = (0xFFFFFFFFUL << (31 - rot_me)) & (0xFFFFFFFFUL >> rot_mb); uint32_t step2 = (rot_me < rot_mb)? ~step1 : step1; uint32_t step3 = ((ppc_result_d << ppc_result_b) | (ppc_result_d >> (32-ppc_result_b))); ppc_result_a = step2 & step3; From fece6e40424b900b321837c0008b3715e239bb90 Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Wed, 17 Jul 2019 19:55:46 +0200 Subject: [PATCH 7/7] ppcmemory: add missing newlines to printf messages. --- ppcmemory.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ppcmemory.cpp b/ppcmemory.cpp index 3be30fa..dc595af 100644 --- a/ppcmemory.cpp +++ b/ppcmemory.cpp @@ -163,7 +163,7 @@ void get_pointer_pteg1(uint32_t address_grab){ grab_pteg1_ptr = machine_sysconfig_mem; } else{ - printf("Uncharted territory: %x", address_grab); + printf("Uncharted territory: %x \n", address_grab); } } else if (address_grab < 0x80800000){ @@ -240,7 +240,7 @@ void get_pointer_pteg2(uint32_t address_grab){ grab_pteg2_ptr = machine_sysconfig_mem; } else{ - printf("Uncharted territory: %x", address_grab); + printf("Uncharted territory: %x \n", address_grab); } } else if (address_grab < 0x80800000){ @@ -959,7 +959,7 @@ void quickinstruction_translate(uint32_t address_grab){ else{ storage_area = address_grab % 0x04000000; grab_macmem_ptr = machine_sysram_mem; - printf("Uncharted territory: %x", address_grab); + printf("Uncharted territory: %x \n", address_grab); } } else if (address_grab < 0x80800000){