mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-16 18:30:32 +00:00
Fix IRQ/FIQ return addresses.
This commit is contained in:
parent
fb5fdc9f10
commit
9ea3e547ee
@ -402,7 +402,7 @@ struct Executor {
|
|||||||
// Check whether access is forced ot the user bank; if so then switch
|
// 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
|
// to it now. Also keep track of the original mode to switch back at
|
||||||
// the end.
|
// the end.
|
||||||
const Mode original_mode = registers_.mode();
|
Mode original_mode = registers_.mode();
|
||||||
const bool adopt_user_mode =
|
const bool adopt_user_mode =
|
||||||
flags.load_psr() && (
|
flags.load_psr() && (
|
||||||
flags.operation() == BlockDataTransferFlags::Operation::STM ||
|
flags.operation() == BlockDataTransferFlags::Operation::STM ||
|
||||||
@ -519,6 +519,8 @@ struct Executor {
|
|||||||
registers_.set_pc(value);
|
registers_.set_pc(value);
|
||||||
if constexpr (flags.load_psr()) {
|
if constexpr (flags.load_psr()) {
|
||||||
registers_.set_status(value);
|
registers_.set_status(value);
|
||||||
|
original_mode = registers_.mode(); // Avoid switching back to the wrong mode
|
||||||
|
// in case user registers were exposed.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,17 +148,17 @@ struct Registers {
|
|||||||
//
|
//
|
||||||
// * exceptions occuring during execution of an instruction are taken
|
// * exceptions occuring during execution of an instruction are taken
|
||||||
// to occur after R15 has already been incremented by 4; but
|
// 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.
|
// taken to occur with R15 pointing to an instruction that hasn't begun.
|
||||||
//
|
//
|
||||||
// i.e. in net R15 always refers to the next instruction
|
// i.e. in net R15 always refers to the next instruction
|
||||||
// that has not yet started.
|
// that has not yet started.
|
||||||
switch(exception) {
|
switch(exception) {
|
||||||
// "To return normally from FIQ use SUBS PC, R14_fiq, #4".
|
// "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".
|
// "To return normally from IRQ use SUBS PC, R14_irq, #4".
|
||||||
case Exception::IRQ: return 0;
|
case Exception::IRQ: return 4;
|
||||||
|
|
||||||
// "If a return is required from [address exception traps], use
|
// "If a return is required from [address exception traps], use
|
||||||
// SUBS PC, R14_svc, #4. This will return to the instruction after
|
// SUBS PC, R14_svc, #4. This will return to the instruction after
|
||||||
|
@ -117,6 +117,12 @@ class ConcreteMachine:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(requests & InterruptRequests::IRQ) {
|
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>();
|
executor_.registers().interrupt<Exception::IRQ>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,7 +140,7 @@ class ConcreteMachine:
|
|||||||
return executor_.bus.video().crt().get_scaled_scan_status();
|
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;
|
std::size_t pc_history_ptr = 0;
|
||||||
uint32_t instr_count = 0;
|
uint32_t instr_count = 0;
|
||||||
|
|
||||||
@ -158,6 +164,10 @@ class ConcreteMachine:
|
|||||||
static uint32_t last_pc = 0;
|
static uint32_t last_pc = 0;
|
||||||
static bool log = false;
|
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;
|
uint32_t instruction;
|
||||||
pc_history[pc_history_ptr] = executor_.pc();
|
pc_history[pc_history_ptr] = executor_.pc();
|
||||||
pc_history_ptr = (pc_history_ptr + 1) % pc_history.size();
|
pc_history_ptr = (pc_history_ptr + 1) % pc_history.size();
|
||||||
@ -172,11 +182,9 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
// TODO: pipeline prefetch?
|
// TODO: pipeline prefetch?
|
||||||
|
|
||||||
if(executor_.pc() == 0x03810bd8) {
|
// log |= executor_.pc() == 0x3961244;
|
||||||
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 |= instr_count == 72766815;
|
||||||
}
|
// log &= executor_.pc() != 0x000000a0;
|
||||||
|
|
||||||
log = executor_.pc() == 0x03808de0;
|
|
||||||
|
|
||||||
if(log) {
|
if(log) {
|
||||||
InstructionSet::ARM::Disassembler<arm_model> disassembler;
|
InstructionSet::ARM::Disassembler<arm_model> disassembler;
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
</Testables>
|
</Testables>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Debug"
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
enableASanStackUseAfterReturn = "YES"
|
enableASanStackUseAfterReturn = "YES"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user