mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-04 18:32:19 +00:00
ppcexec: Make ppc_exec template functions.
This commit is contained in:
parent
98c7e224fe
commit
e4d9cb95b4
@ -254,9 +254,15 @@ static void force_cycle_counter_reload()
|
||||
exec_timer = true;
|
||||
}
|
||||
|
||||
/** Execute PPC code as long as power is on. */
|
||||
typedef enum {
|
||||
main,
|
||||
until,
|
||||
debug,
|
||||
} ppc_exec_type_t;
|
||||
|
||||
// inner interpreter loop
|
||||
static void ppc_exec_inner()
|
||||
template <ppc_exec_type_t exec_type>
|
||||
static void ppc_exec_inner(uint32_t start_addr, uint32_t size)
|
||||
{
|
||||
uint64_t max_cycles;
|
||||
uint32_t page_start, eb_start, eb_end;
|
||||
@ -266,6 +272,10 @@ static void ppc_exec_inner()
|
||||
max_cycles = 0;
|
||||
|
||||
while (power_on) {
|
||||
if (exec_type == debug)
|
||||
if (ppc_state.pc >= start_addr && ppc_state.pc < start_addr + size)
|
||||
break;
|
||||
|
||||
// define boundaries of the next execution block
|
||||
// max execution block length = one memory page
|
||||
eb_start = ppc_state.pc;
|
||||
@ -278,6 +288,10 @@ static void ppc_exec_inner()
|
||||
|
||||
// interpret execution block
|
||||
while (power_on && ppc_state.pc < eb_end) {
|
||||
if (exec_type == debug)
|
||||
if (ppc_state.pc >= start_addr && ppc_state.pc < start_addr + size)
|
||||
break;
|
||||
|
||||
ppc_main_opcode(opcode);
|
||||
if (g_icycles++ >= max_cycles || exec_timer) {
|
||||
max_cycles = process_events();
|
||||
@ -302,10 +316,23 @@ static void ppc_exec_inner()
|
||||
pc_real += 4;
|
||||
opcode = ppc_read_instruction(pc_real);
|
||||
}
|
||||
|
||||
if (exec_type == until)
|
||||
if (ppc_state.pc == start_addr)
|
||||
break;
|
||||
}
|
||||
|
||||
if (exec_type == until)
|
||||
if (ppc_state.pc == start_addr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Execute PPC code as long as power is on. */
|
||||
|
||||
// inner interpreter loop
|
||||
template void ppc_exec_inner<main>(uint32_t start_addr, uint32_t size);
|
||||
|
||||
// outer interpreter loop
|
||||
void ppc_exec()
|
||||
{
|
||||
@ -316,7 +343,7 @@ void ppc_exec()
|
||||
}
|
||||
|
||||
while (power_on) {
|
||||
ppc_exec_inner();
|
||||
ppc_exec_inner<main>(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,58 +375,7 @@ void ppc_exec_single()
|
||||
/** Execute PPC code until goal_addr is reached. */
|
||||
|
||||
// inner interpreter loop
|
||||
static void ppc_exec_until_inner(const uint32_t goal_addr)
|
||||
{
|
||||
uint64_t max_cycles;
|
||||
uint32_t page_start, eb_start, eb_end;
|
||||
uint8_t* pc_real;
|
||||
uint32_t opcode;
|
||||
|
||||
max_cycles = 0;
|
||||
|
||||
do {
|
||||
// define boundaries of the next execution block
|
||||
// max execution block length = one memory page
|
||||
eb_start = ppc_state.pc;
|
||||
page_start = eb_start & PPC_PAGE_MASK;
|
||||
eb_end = page_start + PPC_PAGE_SIZE - 1;
|
||||
exec_flags = 0;
|
||||
|
||||
pc_real = mmu_translate_imem(eb_start);
|
||||
opcode = ppc_read_instruction(pc_real);
|
||||
|
||||
// interpret execution block
|
||||
while (power_on && ppc_state.pc < eb_end) {
|
||||
ppc_main_opcode(opcode);
|
||||
if (g_icycles++ >= max_cycles || exec_timer) {
|
||||
max_cycles = process_events();
|
||||
}
|
||||
|
||||
if (exec_flags) {
|
||||
// define next execution block
|
||||
eb_start = ppc_next_instruction_address;
|
||||
if (!(exec_flags & EXEF_RFI) && (eb_start & PPC_PAGE_MASK) == page_start) {
|
||||
pc_real += (int)eb_start - (int)ppc_state.pc;
|
||||
opcode = ppc_read_instruction(pc_real);
|
||||
} else {
|
||||
page_start = eb_start & PPC_PAGE_MASK;
|
||||
eb_end = page_start + PPC_PAGE_SIZE - 1;
|
||||
pc_real = mmu_translate_imem(eb_start);
|
||||
opcode = ppc_read_instruction(pc_real);
|
||||
}
|
||||
ppc_state.pc = eb_start;
|
||||
exec_flags = 0;
|
||||
} else {
|
||||
ppc_state.pc += 4;
|
||||
pc_real += 4;
|
||||
opcode = ppc_read_instruction(pc_real);
|
||||
}
|
||||
|
||||
if (ppc_state.pc == goal_addr)
|
||||
break;
|
||||
}
|
||||
} while (power_on && ppc_state.pc != goal_addr);
|
||||
}
|
||||
template void ppc_exec_inner<until>(uint32_t start_addr, uint32_t size);
|
||||
|
||||
// outer interpreter loop
|
||||
void ppc_exec_until(volatile uint32_t goal_addr)
|
||||
@ -410,64 +386,17 @@ void ppc_exec_until(volatile uint32_t goal_addr)
|
||||
ppc_state.pc = ppc_next_instruction_address;
|
||||
}
|
||||
|
||||
do {
|
||||
ppc_exec_until_inner(goal_addr);
|
||||
} while (power_on && ppc_state.pc != goal_addr);
|
||||
while (power_on) {
|
||||
ppc_exec_inner<until>(goal_addr, 0);
|
||||
if (ppc_state.pc == goal_addr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Execute PPC code until control is reached the specified region. */
|
||||
|
||||
// inner interpreter loop
|
||||
static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size)
|
||||
{
|
||||
uint64_t max_cycles;
|
||||
uint32_t page_start, eb_start, eb_end;
|
||||
uint8_t* pc_real;
|
||||
uint32_t opcode;
|
||||
|
||||
max_cycles = 0;
|
||||
|
||||
while (power_on && (ppc_state.pc < start_addr || ppc_state.pc >= start_addr + size)) {
|
||||
// define boundaries of the next execution block
|
||||
// max execution block length = one memory page
|
||||
eb_start = ppc_state.pc;
|
||||
page_start = eb_start & PPC_PAGE_MASK;
|
||||
eb_end = page_start + PPC_PAGE_SIZE - 1;
|
||||
exec_flags = 0;
|
||||
|
||||
pc_real = mmu_translate_imem(eb_start);
|
||||
opcode = ppc_read_instruction(pc_real);
|
||||
|
||||
// interpret execution block
|
||||
while (power_on && (ppc_state.pc < start_addr || ppc_state.pc >= start_addr + size)
|
||||
&& (ppc_state.pc < eb_end)) {
|
||||
ppc_main_opcode(opcode);
|
||||
if (g_icycles++ >= max_cycles || exec_timer) {
|
||||
max_cycles = process_events();
|
||||
}
|
||||
|
||||
if (exec_flags) {
|
||||
// define next execution block
|
||||
eb_start = ppc_next_instruction_address;
|
||||
if (!(exec_flags & EXEF_RFI) && (eb_start & PPC_PAGE_MASK) == page_start) {
|
||||
pc_real += (int)eb_start - (int)ppc_state.pc;
|
||||
opcode = ppc_read_instruction(pc_real);
|
||||
} else {
|
||||
page_start = eb_start & PPC_PAGE_MASK;
|
||||
eb_end = page_start + PPC_PAGE_SIZE - 1;
|
||||
pc_real = mmu_translate_imem(eb_start);
|
||||
opcode = ppc_read_instruction(pc_real);
|
||||
}
|
||||
ppc_state.pc = eb_start;
|
||||
exec_flags = 0;
|
||||
} else {
|
||||
ppc_state.pc += 4;
|
||||
pc_real += 4;
|
||||
opcode = ppc_read_instruction(pc_real);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
template void ppc_exec_inner<debug>(uint32_t start_addr, uint32_t size);
|
||||
|
||||
// outer interpreter loop
|
||||
void ppc_exec_dbg(volatile uint32_t start_addr, volatile uint32_t size)
|
||||
@ -479,7 +408,7 @@ void ppc_exec_dbg(volatile uint32_t start_addr, volatile uint32_t size)
|
||||
}
|
||||
|
||||
while (power_on && (ppc_state.pc < start_addr || ppc_state.pc >= start_addr + size)) {
|
||||
ppc_exec_dbg_inner(start_addr, size);
|
||||
ppc_exec_inner<debug>(start_addr, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user