WIP: basic 68k debugging environment.
This commit is contained in:
parent
8094fb30f6
commit
6b74e358dc
|
@ -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(
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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] =
|
||||
|
|
Loading…
Reference in New Issue