mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-04-15 15:40:17 +00:00
Merge pull request #2 from maximumspatium/master
Various CPU emulation fixes + new command-line debugger.
This commit is contained in:
commit
e909d48ee6
@ -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)
|
||||
install (TARGETS dingusppc DESTINATION bin)
|
||||
|
111
debugger.cpp
Normal file
111
debugger.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#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;
|
||||
}
|
||||
}
|
6
debugger.h
Normal file
6
debugger.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef DEBUGGER_H_
|
||||
#define DEBUGGER_H_
|
||||
|
||||
void enter_debugger(void);
|
||||
|
||||
#endif // DEBUGGER_H_
|
7
main.cpp
7
main.cpp
@ -25,6 +25,7 @@
|
||||
#include "viacuda.h"
|
||||
#include "mpc106.h"
|
||||
#include "openpic.h"
|
||||
#include "debugger.h"
|
||||
//#include <vector>
|
||||
|
||||
#define max_16b_int 65535
|
||||
@ -729,7 +730,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 +758,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();
|
||||
}
|
||||
@ -846,6 +847,8 @@ int main(int argc, char **argv)
|
||||
ppc_cur_instruction = 0;
|
||||
}
|
||||
}
|
||||
} else if (checker == "debugger") {
|
||||
enter_debugger();
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
11
makefile
11
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)
|
||||
|
@ -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){
|
||||
|
@ -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{
|
||||
@ -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 << (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 = (0xFFFFFFFF >> (rot_me + 1)) ^ (0xFFFFFFFF >> 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 = (0xFFFFFFFF >> (rot_me + 1)) ^ (0xFFFFFFFF >> 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;
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user