Move all PPC code execution to ppcexec.cpp.

This commit is contained in:
Maxim Poliakovski 2019-12-28 02:49:58 +01:00
parent 2d8150a201
commit 01dffb84f3
4 changed files with 120 additions and 124 deletions

View File

@ -164,6 +164,8 @@ extern bool grab_branch;
extern bool grab_exception;
extern bool grab_return;
extern bool power_on;
extern bool is_nubus; //For early Power Mac Emulation
extern bool is_601; //For PowerPC 601 Emulation
@ -611,6 +613,9 @@ extern void ppc_psq_stu();
//G5+ instructions
extern void ppc_main_opcode();
extern void ppc_main_opcode(void);
extern void ppc_exec(void);
extern void ppc_exec_single(void);
extern void ppc_exec_until(uint32_t goal_addr);
#endif /* PPCEMU_H */

View File

@ -1,6 +1,12 @@
#include <unordered_map>
#include <chrono>
#include "ppcemu.h"
#include "ppcmmu.h"
bool power_on = 1;
clock_t clock_test_begin; //Used to make sure the TBR does not increment so quickly.
/** Opcode lookup tables. */
@ -474,3 +480,106 @@ void ppc_main_opcode(){
uint8_t ppc_mainop = (ppc_cur_instruction >> 26) & 63;
OpcodeGrabber[ppc_mainop]();
}
/** Old time base register (TBR) update code. */
void ppc_tbr_update()
{
clock_t clock_test_current = clock();
uint32_t test_clock = ((uint32_t) (clock_test_current - clock_test_begin)) / CLOCKS_PER_SEC;
if (test_clock){
if (ppc_state.ppc_tbr[0] != 0xFFFFFFFF){
ppc_state.ppc_tbr[0]++;
}
else{
ppc_state.ppc_tbr[0] = 0;
if (ppc_state.ppc_tbr[1] !=0xFFFFFFFF){
ppc_state.ppc_tbr[1]++;
}
else{
ppc_state.ppc_tbr[1] = 0;
}
}
clock_test_begin = clock();
//Placeholder Decrementing Code
if(ppc_state.ppc_spr[22] > 0){
ppc_state.ppc_spr[22]--;
}
}
}
/** Execute PPC code as long as power is on. */
void ppc_exec()
{
while (power_on){
//printf("PowerPC Address: %x \n", ppc_state.ppc_pc);
quickinstruction_translate(ppc_state.ppc_pc);
ppc_main_opcode();
if (grab_branch & !grab_exception){
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();
}
}
}
/** Execute one PPC instruction. */
void ppc_exec_single()
{
quickinstruction_translate(ppc_state.ppc_pc);
ppc_main_opcode();
if (grab_branch && !grab_exception) {
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();
}
}
/** Execute PPC code until goal_addr is reached. */
void ppc_exec_until(uint32_t goal_addr)
{
while (ppc_state.ppc_pc != goal_addr) {
quickinstruction_translate(ppc_state.ppc_pc);
ppc_main_opcode();
if (grab_branch && !grab_exception) {
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 ppc_init()
{
clock_test_begin = clock();
}

View File

@ -33,35 +33,6 @@ void dump_regs()
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();
}
}
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;
@ -94,11 +65,11 @@ void enter_debugger()
} else if (cmd == "regs") {
dump_regs();
} else if (cmd == "step") {
execute_single_instr();
ppc_exec_single();
} else if (cmd == "until") {
ss >> addr_str;
addr = stol(addr_str, NULL, 16);
execute_until(addr);
ppc_exec_until(addr);
} else if (cmd == "disas") {
cout << "Disassembling not implemented yet. Sorry!" << endl;
} else {

View File

@ -16,8 +16,6 @@
#include <array>
#include <stdio.h>
#include <fstream>
#include <chrono>
#include <ctime>
#include <stdexcept>
#include "ppcemu.h"
#include "ppcmmu.h"
@ -66,7 +64,6 @@ static const map<string,string> PPCMac_ROMIdentity = { //Codename Abbreviation f
SetPRS ppc_state;
bool power_on = 1;
bool is_nubus = 0;
bool grab_branch;
@ -121,8 +118,6 @@ uint32_t pci_io_end;
uint32_t rom_filesize;
clock_t clock_test_begin; //Used to make sure the TBR does not increment so quickly.
uint32_t write_opcode;
uint8_t write_char;
@ -147,33 +142,6 @@ uint64_t rev_endian64(uint64_t insert_int){
return ENDIAN_REVERSE64(insert_int);
}
//Time Base Register Update Code
//TODO - Make this a bit less hacky somehow.
void ppc_tbr_update()
{
clock_t clock_test_current = clock();
uint32_t test_clock = ((uint32_t) (clock_test_current - clock_test_begin)) / CLOCKS_PER_SEC;
if (test_clock){
if (ppc_state.ppc_tbr[0] != 0xFFFFFFFF){
ppc_state.ppc_tbr[0]++;
}
else{
ppc_state.ppc_tbr[0] = 0;
if (ppc_state.ppc_tbr[1] !=0xFFFFFFFF){
ppc_state.ppc_tbr[1]++;
}
else{
ppc_state.ppc_tbr[1] = 0;
}
}
clock_test_begin = clock();
//Placeholder Decrementing Code
if(ppc_state.ppc_spr[22] > 0){
ppc_state.ppc_spr[22]--;
}
}
}
void ppc_exception_handler(uint32_t exception_type, uint32_t handle_args){
ppc_next_instruction_address = 0x0; //used to construct a new address
grab_exception = true;
@ -365,61 +333,6 @@ uint32_t reg_write(){
return 0;
}
void execute_interpreter(){
//Main execution loop for the interpreter.
while (power_on){
//printf("PowerPC Address: %x \n", ppc_state.ppc_pc);
quickinstruction_translate(ppc_state.ppc_pc);
ppc_main_opcode();
if (grab_branch & !grab_exception){
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();
}
}
}
void execute_interpreter_bp (uint32_t ppc_break_addr){
//Main loop like the above, with the only big difference
//being that this stops on reaching the desired address.
//It then prints the regs at the time it stopped.
while (ppc_state.ppc_pc != ppc_break_addr){
quickinstruction_translate(ppc_state.ppc_pc);
ppc_main_opcode();
if (grab_branch & !grab_exception){
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;
}
reg_print();
}
int main(int argc, char **argv)
{
ram_size_set = 0x4000000; //64 MB of RAM for the Mac
@ -577,8 +490,6 @@ int main(int argc, char **argv)
mem_ctrl_instance->set_data(0xFFC00000, machine_sysrom_mem, rom_filesize);
romFile.close();
clock_test_begin = clock();
if (argc > 1){
string checker = argv[1];
cout << checker << endl;
@ -593,7 +504,7 @@ int main(int argc, char **argv)
}
}
else if ((checker=="1")|(checker=="realtime")|(checker=="/realtime")|(checker=="-realtime")){
execute_interpreter();
ppc_exec();
}
else if ((checker=="e")|(checker=="loadelf")|(checker=="/loadelf")|(checker=="-loadelf")){
ifstream elfFile;
@ -656,7 +567,7 @@ int main(int argc, char **argv)
ppc_state.ppc_pc = atoi(elf_memoffset);
execute_interpreter();
ppc_exec();
}
else if ((checker=="until")|(checker=="/until")|(checker=="-until")){
uint32_t grab_bp = 0x0;
@ -664,7 +575,7 @@ int main(int argc, char **argv)
std::cout << hex << "Enter the address in hex for where to stop execution." << endl;
cin >> hex >> grab_bp;
execute_interpreter_bp(grab_bp);
ppc_exec_until(grab_bp);
}
else if (checker=="disas"){
if (argc > 2){