WIP: basic 68k debugging environment.

This commit is contained in:
Maxim Poliakovski 2020-07-13 23:39:31 +02:00
parent 8094fb30f6
commit 6b74e358dc
6 changed files with 117 additions and 15 deletions

View File

@ -16,6 +16,11 @@ if (UNIX AND NOT APPLE)
endif()
endif()
find_package(PkgConfig REQUIRED)
pkg_check_modules(CAPSTONE REQUIRED capstone>=4.0.1)
include_directories(${CAPSTONE_INCLUDE_DIRS})
link_directories(${CAPSTONE_LIBRARY_DIRS})
add_subdirectory("${PROJECT_SOURCE_DIR}/cpu/ppc/")
add_subdirectory("${PROJECT_SOURCE_DIR}/debugger/")
add_subdirectory("${PROJECT_SOURCE_DIR}/devices/")
@ -64,7 +69,7 @@ target_link_libraries(dingusppc "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/S
cubeb)
else()
#target_link_libraries(dingusppc libsoundio_static ${LIBSOUNDIO_LIBS} ${SDL2_LIBRARIES})
target_link_libraries(dingusppc cubeb ${SDL2_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(dingusppc cubeb ${SDL2_LIBRARIES} ${CAPSTONE_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
endif()
@ -80,7 +85,7 @@ target_link_libraries(testppc "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/SDL
cubeb)
else()
#target_link_libraries(testppc libsoundio_static ${LIBSOUNDIO_LIBS} ${SDL2_LIBRARIES})
target_link_libraries(testppc cubeb ${SDL2_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(testppc cubeb ${SDL2_LIBRARIES} ${CAPSTONE_LIBRARIES} ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
endif()
add_custom_command(

View File

@ -481,7 +481,7 @@ extern void ppc_b();
extern void ppc_ba();
extern void ppc_bl();
extern void ppc_bla();
extern void ppc_bc();
extern void ppc_bc1();
extern void ppc_bca();
extern void ppc_bcl();
extern void ppc_bcla();

View File

@ -82,7 +82,7 @@ static PPCOpcode OpcodeGrabber[] = {
ppc_psq_st, ppc_psq_stu, ppc_illegalop, ppc_opcode63};
/** Lookup tables for branch instructions. */
static PPCOpcode SubOpcode16Grabber[] = {ppc_bc, ppc_bcl, ppc_bca, ppc_bcla};
static PPCOpcode SubOpcode16Grabber[] = {ppc_bc1, ppc_bcl, ppc_bca, ppc_bcla};
static PPCOpcode SubOpcode18Grabber[] = {ppc_b, ppc_bl, ppc_ba, ppc_bla};

View File

@ -1416,7 +1416,7 @@ void ppc_bla() {
bb_kind = BB_end_kind::BB_BRANCH;
}
void ppc_bc() {
void ppc_bc1() {
uint32_t ctr_ok;
uint32_t cnd_ok;
uint32_t br_bo = (ppc_cur_instruction >> 21) & 31;

View File

@ -19,9 +19,6 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "../cpu/ppc/ppcdisasm.h"
#include "../cpu/ppc/ppcemu.h"
#include "../cpu/ppc/ppcmmu.h"
#include <fstream>
#include <iomanip>
#include <iostream>
@ -30,6 +27,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <stdio.h>
#include <string>
#include <thirdparty/loguru/loguru.hpp>
#include <capstone/capstone.h>
#include "../cpu/ppc/ppcdisasm.h"
#include "../cpu/ppc/ppcemu.h"
#include "../cpu/ppc/ppcmmu.h"
using namespace std;
@ -88,6 +89,42 @@ static void disasm(uint32_t count, uint32_t address) {
}
}
static void disasm_68k(uint32_t count, uint32_t address) {
csh cs_handle;
uint8_t code[8];
size_t code_size;
uint64_t dis_addr;
if (cs_open(CS_ARCH_M68K, CS_MODE_M68K_040, &cs_handle) != CS_ERR_OK) {
cout << "Capstone initialization error" << endl;
return;
}
cs_insn* insn = cs_malloc(cs_handle);
for (; count > 0; count--) {
for (int i = 0; i < sizeof(code); i++) {
code[i] = mem_read_dbg(address + i, 1);
}
const uint8_t *code_ptr = code;
code_size = sizeof(code);
dis_addr = address;
if (cs_disasm_iter(cs_handle, &code_ptr, &code_size, &dis_addr, insn)) {
cout << uppercase << hex << insn->address;
cout << " " << insn->mnemonic << " " << insn->op_str << endl;
address = dis_addr;
} else {
cout << "DS.W " << hex << ((code[0] << 8) | code[1]) << endl;
address += 2;
}
}
cs_free(insn, 1);
cs_close(&cs_handle);
}
static void dump_mem(string& params) {
int cell_size, chars_per_line;
bool is_char;
@ -181,13 +218,42 @@ static void dump_mem(string& params) {
cout << endl << endl;
}
void print_68k_regs()
{
int i;
string reg;
for (i = 0; i < 8; i++) {
reg = "R" + to_string(i + 8);
cout << "D" << dec << i << " : " << uppercase << hex << get_reg(reg) << endl;
}
for (i = 0; i < 7; i++) {
reg = "R" + to_string(i + 16);
cout << "A" << dec << i << " : " << uppercase << hex << get_reg(reg) << endl;
}
reg = "R1";
cout << "A7 : " << uppercase << hex << get_reg(reg) << endl;
reg = "R24";
cout << "PC: " << uppercase << hex << get_reg(reg) - 2 << endl;
reg = "R25";
cout << "SR: " << uppercase << hex << ((get_reg(reg) & 0xFF) << 8) << endl;
reg = "R26";
cout << "CCR: " << uppercase << hex << get_reg(reg) << endl;
}
void enter_debugger() {
string inp, cmd, addr_str, expr_str, reg_expr, last_cmd, reg_value_str, inst_string, inst_num_str;
uint32_t addr, inst_grab;
std::stringstream ss;
int log_level;
int log_level, context;
size_t separator_pos;
context = 1; /* start with the PowerPC context */
cout << "Welcome to the DingusPPC command line debugger." << endl;
cout << "Please enter a command or 'help'." << endl << endl;
@ -220,7 +286,11 @@ void enter_debugger() {
}
#endif
else if (cmd == "regs") {
print_gprs();
if (context == 2) {
print_68k_regs();
} else {
print_gprs();
}
} else if (cmd == "set") {
ss >> expr_str;
@ -278,27 +348,52 @@ void enter_debugger() {
} catch (invalid_argument& exc) {
try {
/* number conversion failed, trying reg name */
addr = get_reg(addr_str);
if (context == 2 && (addr_str == "pc" || addr_str == "PC")) {
addr_str = "R24";
addr = get_reg(addr_str) - 2;
} else {
addr = get_reg(addr_str);
}
} catch (invalid_argument& exc) {
cout << exc.what() << endl;
continue;
}
}
try {
disasm(inst_grab, addr);
if (context == 2) {
disasm_68k(inst_grab, addr);
} else {
disasm(inst_grab, addr);
}
} catch (invalid_argument& exc) {
cout << exc.what() << endl;
}
} else {
/* disas without arguments defaults to disas 1,pc */
addr_str = "PC";
addr = get_reg(addr_str);
disasm(1, addr);
if (context == 2) {
addr_str = "R24";
addr = get_reg(addr_str);
disasm_68k(1, addr - 2);
} else {
addr_str = "PC";
addr = get_reg(addr_str);
disasm(1, addr);
}
}
} else if (cmd == "dump") {
expr_str = "";
ss >> expr_str;
dump_mem(expr_str);
} else if (cmd == "context") {
expr_str = "";
ss >> expr_str;
if (expr_str == "ppc" || expr_str == "PPC") {
context = 1;
} else if (expr_str == "68k" || expr_str == "68K") {
context = 2;
} else {
cout << "Unknown debugging context: " << expr_str << endl;
}
} else {
cout << "Unknown command: " << cmd << endl;
continue;

View File

@ -170,6 +170,8 @@ uint32_t ATIRage::read_reg(uint32_t offset, uint32_t size) {
uint32_t res;
switch (offset & ~3) {
case ATI_GP_IO:
break;
case ATI_DAC_REGS:
if (offset == ATI_DAC_DATA) {
this->block_io_regs[ATI_DAC_DATA] =