mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-16 18:30:32 +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.
|
/// The FIQ went low at least one cycle ago and ConditionCode::FIQDisable was not set.
|
||||||
FIQ = 0x1c,
|
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.
|
/// Updates the program counter, interupt flags and link register if applicable to begin @c exception.
|
||||||
template <Exception type>
|
template <Exception type>
|
||||||
void exception() {
|
void exception() {
|
||||||
const auto r14 = pc_status(4);
|
const auto r14 = pc_status(pc_offset_during(type));
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case Exception::IRQ: set_mode(Mode::IRQ); break;
|
case Exception::IRQ: set_mode(Mode::IRQ); break;
|
||||||
case Exception::FIQ: set_mode(Mode::FIQ); break;
|
case Exception::FIQ: set_mode(Mode::FIQ); break;
|
||||||
|
@ -1051,7 +1051,7 @@ class ConcreteMachine:
|
|||||||
// MARK: - TimedMachine.
|
// MARK: - TimedMachine.
|
||||||
void run_for(Cycles cycles) override {
|
void run_for(Cycles cycles) override {
|
||||||
static uint32_t last_pc = 0;
|
static uint32_t last_pc = 0;
|
||||||
static bool log = true;
|
static bool log = false;
|
||||||
|
|
||||||
auto instructions = cycles.as<int>();
|
auto instructions = cycles.as<int>();
|
||||||
|
|
||||||
@ -1086,7 +1086,7 @@ class ConcreteMachine:
|
|||||||
// log = executor_.pc() == 0x0381202c;
|
// log = executor_.pc() == 0x0381202c;
|
||||||
// log |= (executor_.pc() > 0x03801000);
|
// log |= (executor_.pc() > 0x03801000);
|
||||||
// log &= executor_.pc() != 0x03801a0c;
|
// log &= executor_.pc() != 0x03801a0c;
|
||||||
// log |= instr_count == 71259670 - 50;
|
// log |= instr_count == 71259625;
|
||||||
|
|
||||||
// if(executor_.pc() == 0x02000078) {
|
// if(executor_.pc() == 0x02000078) {
|
||||||
// if(!all.empty()) {
|
// if(!all.empty()) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user