mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-25 16:31:42 +00:00
Get rigorous on exception addresses.
This commit is contained in:
parent
17dbdce230
commit
85a738acff
@ -143,11 +143,52 @@ struct Registers {
|
||||
/// The FIQ went low at least one cycle ago and ConditionCode::FIQDisable was not set.
|
||||
FIQ = 0x1c,
|
||||
};
|
||||
static constexpr uint32_t pc_offset_during(Exception exception) {
|
||||
// The below is somewhat convoluted by the assumed execution model:
|
||||
//
|
||||
// * 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
|
||||
// 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;
|
||||
|
||||
// "To return normally from IRQ use SUBS PC, R14_fiq, #4".
|
||||
case Exception::IRQ: return 0;
|
||||
|
||||
// "If a return is required from [address exception traps], use
|
||||
// SUBS PC, R14_svc, #4. This will return to the instruction after
|
||||
// the one causing the trap".
|
||||
case Exception::Address: return 4;
|
||||
|
||||
// "A Data Abort requires [work before a return], the return being
|
||||
// done by SUBS PC, R14_svc, #8".
|
||||
case Exception::DataAbort: return 8;
|
||||
|
||||
// "To continue after a Prefetch Abort use SUBS PC, R14_svc #4".
|
||||
case Exception::PrefetchAbort: return 4;
|
||||
|
||||
// "To return from a SWI, use MOVS PC, R14_svc. This returns to the instruction
|
||||
// following the SWI".
|
||||
case Exception::SoftwareInterrupt: return 0;
|
||||
|
||||
// "To return from [an undefined instruction trap] use MOVS PC, R14_svc.
|
||||
// This returns to the instruction following the undefined instruction".
|
||||
case Exception::UndefinedInstruction: return 0;
|
||||
|
||||
// Unspecified; a guess.
|
||||
case Exception::Reset: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates the program counter, interupt flags and link register if applicable to begin @c exception.
|
||||
template <Exception type>
|
||||
void exception() {
|
||||
const auto r14 = pc_status(4);
|
||||
const auto r14 = pc_status(pc_offset_during(type));
|
||||
switch(type) {
|
||||
case Exception::IRQ: set_mode(Mode::IRQ); break;
|
||||
case Exception::FIQ: set_mode(Mode::FIQ); break;
|
||||
|
@ -1051,7 +1051,7 @@ class ConcreteMachine:
|
||||
// MARK: - TimedMachine.
|
||||
void run_for(Cycles cycles) override {
|
||||
static uint32_t last_pc = 0;
|
||||
static bool log = true;
|
||||
static bool log = false;
|
||||
|
||||
auto instructions = cycles.as<int>();
|
||||
|
||||
@ -1086,7 +1086,7 @@ class ConcreteMachine:
|
||||
// log = executor_.pc() == 0x0381202c;
|
||||
// log |= (executor_.pc() > 0x03801000);
|
||||
// log &= executor_.pc() != 0x03801a0c;
|
||||
// log |= instr_count == 71259670 - 50;
|
||||
// log |= instr_count == 71259625;
|
||||
|
||||
// if(executor_.pc() == 0x02000078) {
|
||||
// if(!all.empty()) {
|
||||
|
Loading…
Reference in New Issue
Block a user