1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-21 21:33:54 +00:00

Fix IRQ/FIQ return addresses.

This commit is contained in:
Thomas Harte 2024-03-22 21:42:34 -04:00
parent fb5fdc9f10
commit 9ea3e547ee
4 changed files with 22 additions and 12 deletions

View File

@ -402,7 +402,7 @@ struct Executor {
// Check whether access is forced ot the user bank; if so then switch
// to it now. Also keep track of the original mode to switch back at
// the end.
const Mode original_mode = registers_.mode();
Mode original_mode = registers_.mode();
const bool adopt_user_mode =
flags.load_psr() && (
flags.operation() == BlockDataTransferFlags::Operation::STM ||
@ -519,6 +519,8 @@ struct Executor {
registers_.set_pc(value);
if constexpr (flags.load_psr()) {
registers_.set_status(value);
original_mode = registers_.mode(); // Avoid switching back to the wrong mode
// in case user registers were exposed.
}
}
}

View File

@ -148,17 +148,17 @@ struct Registers {
//
// * exceptions occuring during execution of an instruction are taken
// to occur after R15 has already been incremented by 4; but
// * exceptions occurring instead of execution of an isntruction are
// * exceptions occurring instead of execution of an instruction are
// taken to occur with R15 pointing to an instruction that hasn't begun.
//
// i.e. in net R15 always refers to the next instruction
// that has not yet started.
switch(exception) {
// "To return normally from FIQ use SUBS PC, R14_fiq, #4".
case Exception::FIQ: return 0;
case Exception::FIQ: return 4;
// "To return normally from IRQ use SUBS PC, R14_fiq, #4".
case Exception::IRQ: return 0;
// "To return normally from IRQ use SUBS PC, R14_irq, #4".
case Exception::IRQ: return 4;
// "If a return is required from [address exception traps], use
// SUBS PC, R14_svc, #4. This will return to the instruction after

View File

@ -117,6 +117,12 @@ class ConcreteMachine:
return;
}
if(requests & InterruptRequests::IRQ) {
// logger.info().append("[%d] IRQ at %08x prior:[r13:%08x r14:%08x]",
// instr_count,
// executor_.pc(),
// executor_.registers()[13],
// executor_.registers()[14]);
executor_.registers().interrupt<Exception::IRQ>();
}
}
@ -134,7 +140,7 @@ class ConcreteMachine:
return executor_.bus.video().crt().get_scaled_scan_status();
}
std::array<uint32_t, 10> pc_history;
std::array<uint32_t, 750> pc_history;
std::size_t pc_history_ptr = 0;
uint32_t instr_count = 0;
@ -158,6 +164,10 @@ class ConcreteMachine:
static uint32_t last_pc = 0;
static bool log = false;
// if(executor_.pc() == 0x03803400) {
// printf("At %08x; after last PC %08x and %zu ago was %08x\n", executor_.pc(), pc_history[(pc_history_ptr - 2 + pc_history.size()) % pc_history.size()], pc_history.size(), pc_history[pc_history_ptr]);
// }
uint32_t instruction;
pc_history[pc_history_ptr] = executor_.pc();
pc_history_ptr = (pc_history_ptr + 1) % pc_history.size();
@ -172,11 +182,9 @@ class ConcreteMachine:
}
// TODO: pipeline prefetch?
if(executor_.pc() == 0x03810bd8) {
printf("At %08x; after last PC %08x and %zu ago was %08x\n", executor_.pc(), pc_history[(pc_history_ptr - 2 + pc_history.size()) % pc_history.size()], pc_history.size(), pc_history[pc_history_ptr]);
}
log = executor_.pc() == 0x03808de0;
// log |= executor_.pc() == 0x3961244;
// log |= instr_count == 72766815;
// log &= executor_.pc() != 0x000000a0;
if(log) {
InstructionSet::ARM::Disassembler<arm_model> disassembler;

View File

@ -62,7 +62,7 @@
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
enableASanStackUseAfterReturn = "YES"