mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-06-11 04:29:37 +00:00
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()
|
||||||
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}/cpu/ppc/")
|
||||||
add_subdirectory("${PROJECT_SOURCE_DIR}/debugger/")
|
add_subdirectory("${PROJECT_SOURCE_DIR}/debugger/")
|
||||||
add_subdirectory("${PROJECT_SOURCE_DIR}/devices/")
|
add_subdirectory("${PROJECT_SOURCE_DIR}/devices/")
|
||||||
|
@ -64,7 +69,7 @@ target_link_libraries(dingusppc "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/S
|
||||||
cubeb)
|
cubeb)
|
||||||
else()
|
else()
|
||||||
#target_link_libraries(dingusppc libsoundio_static ${LIBSOUNDIO_LIBS} ${SDL2_LIBRARIES})
|
#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()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,7 +85,7 @@ target_link_libraries(testppc "${PROJECT_SOURCE_DIR}/thirdparty/SDL2/lib/x64/SDL
|
||||||
cubeb)
|
cubeb)
|
||||||
else()
|
else()
|
||||||
#target_link_libraries(testppc libsoundio_static ${LIBSOUNDIO_LIBS} ${SDL2_LIBRARIES})
|
#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()
|
endif()
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
|
|
|
@ -481,7 +481,7 @@ extern void ppc_b();
|
||||||
extern void ppc_ba();
|
extern void ppc_ba();
|
||||||
extern void ppc_bl();
|
extern void ppc_bl();
|
||||||
extern void ppc_bla();
|
extern void ppc_bla();
|
||||||
extern void ppc_bc();
|
extern void ppc_bc1();
|
||||||
extern void ppc_bca();
|
extern void ppc_bca();
|
||||||
extern void ppc_bcl();
|
extern void ppc_bcl();
|
||||||
extern void ppc_bcla();
|
extern void ppc_bcla();
|
||||||
|
|
|
@ -82,7 +82,7 @@ static PPCOpcode OpcodeGrabber[] = {
|
||||||
ppc_psq_st, ppc_psq_stu, ppc_illegalop, ppc_opcode63};
|
ppc_psq_st, ppc_psq_stu, ppc_illegalop, ppc_opcode63};
|
||||||
|
|
||||||
/** Lookup tables for branch instructions. */
|
/** 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};
|
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;
|
bb_kind = BB_end_kind::BB_BRANCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ppc_bc() {
|
void ppc_bc1() {
|
||||||
uint32_t ctr_ok;
|
uint32_t ctr_ok;
|
||||||
uint32_t cnd_ok;
|
uint32_t cnd_ok;
|
||||||
uint32_t br_bo = (ppc_cur_instruction >> 21) & 31;
|
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/>.
|
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 <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -30,6 +27,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thirdparty/loguru/loguru.hpp>
|
#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;
|
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) {
|
static void dump_mem(string& params) {
|
||||||
int cell_size, chars_per_line;
|
int cell_size, chars_per_line;
|
||||||
bool is_char;
|
bool is_char;
|
||||||
|
@ -181,13 +218,42 @@ static void dump_mem(string& params) {
|
||||||
cout << endl << endl;
|
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() {
|
void enter_debugger() {
|
||||||
string inp, cmd, addr_str, expr_str, reg_expr, last_cmd, reg_value_str, inst_string, inst_num_str;
|
string inp, cmd, addr_str, expr_str, reg_expr, last_cmd, reg_value_str, inst_string, inst_num_str;
|
||||||
uint32_t addr, inst_grab;
|
uint32_t addr, inst_grab;
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
int log_level;
|
int log_level, context;
|
||||||
size_t separator_pos;
|
size_t separator_pos;
|
||||||
|
|
||||||
|
context = 1; /* start with the PowerPC context */
|
||||||
|
|
||||||
cout << "Welcome to the DingusPPC command line debugger." << endl;
|
cout << "Welcome to the DingusPPC command line debugger." << endl;
|
||||||
cout << "Please enter a command or 'help'." << endl << endl;
|
cout << "Please enter a command or 'help'." << endl << endl;
|
||||||
|
|
||||||
|
@ -220,7 +286,11 @@ void enter_debugger() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (cmd == "regs") {
|
else if (cmd == "regs") {
|
||||||
print_gprs();
|
if (context == 2) {
|
||||||
|
print_68k_regs();
|
||||||
|
} else {
|
||||||
|
print_gprs();
|
||||||
|
}
|
||||||
} else if (cmd == "set") {
|
} else if (cmd == "set") {
|
||||||
ss >> expr_str;
|
ss >> expr_str;
|
||||||
|
|
||||||
|
@ -278,27 +348,52 @@ void enter_debugger() {
|
||||||
} catch (invalid_argument& exc) {
|
} catch (invalid_argument& exc) {
|
||||||
try {
|
try {
|
||||||
/* number conversion failed, trying reg name */
|
/* 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) {
|
} catch (invalid_argument& exc) {
|
||||||
cout << exc.what() << endl;
|
cout << exc.what() << endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
disasm(inst_grab, addr);
|
if (context == 2) {
|
||||||
|
disasm_68k(inst_grab, addr);
|
||||||
|
} else {
|
||||||
|
disasm(inst_grab, addr);
|
||||||
|
}
|
||||||
} catch (invalid_argument& exc) {
|
} catch (invalid_argument& exc) {
|
||||||
cout << exc.what() << endl;
|
cout << exc.what() << endl;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* disas without arguments defaults to disas 1,pc */
|
/* disas without arguments defaults to disas 1,pc */
|
||||||
addr_str = "PC";
|
if (context == 2) {
|
||||||
addr = get_reg(addr_str);
|
addr_str = "R24";
|
||||||
disasm(1, addr);
|
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") {
|
} else if (cmd == "dump") {
|
||||||
expr_str = "";
|
expr_str = "";
|
||||||
ss >> expr_str;
|
ss >> expr_str;
|
||||||
dump_mem(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 {
|
} else {
|
||||||
cout << "Unknown command: " << cmd << endl;
|
cout << "Unknown command: " << cmd << endl;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -170,6 +170,8 @@ uint32_t ATIRage::read_reg(uint32_t offset, uint32_t size) {
|
||||||
uint32_t res;
|
uint32_t res;
|
||||||
|
|
||||||
switch (offset & ~3) {
|
switch (offset & ~3) {
|
||||||
|
case ATI_GP_IO:
|
||||||
|
break;
|
||||||
case ATI_DAC_REGS:
|
case ATI_DAC_REGS:
|
||||||
if (offset == ATI_DAC_DATA) {
|
if (offset == ATI_DAC_DATA) {
|
||||||
this->block_io_regs[ATI_DAC_DATA] =
|
this->block_io_regs[ATI_DAC_DATA] =
|
||||||
|
|
Loading…
Reference in New Issue
Block a user