From 6efc41ded79293657f65cf4cf717e2443768beb2 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 12 Mar 2024 10:42:09 -0400 Subject: [PATCH] Come to conclusion on R15; fix link values. --- InstructionSets/ARM/Executor.hpp | 10 ++++---- InstructionSets/ARM/Registers.hpp | 6 ++--- Machines/Acorn/Archimedes/Archimedes.cpp | 30 ++++++++++++------------ 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/InstructionSets/ARM/Executor.hpp b/InstructionSets/ARM/Executor.hpp index 6ebaa2de5..40dc6e1b3 100644 --- a/InstructionSets/ARM/Executor.hpp +++ b/InstructionSets/ARM/Executor.hpp @@ -182,9 +182,11 @@ struct Executor { registers_.set_pc(pc_proxy); } if constexpr (flags.set_condition_codes()) { - // TODO: different sources have me going back and forth on the second - // part of the conditional here. - if(fields.destination() == 15 && is_comparison(flags.operation())) { + // "When Rd is R15 and the S flag in the instruction is set, the PSR is overwritten by the + // corresponding bits in the ALU result... [even] if the instruction is of a type that does not + // normally produce a result (CMP, CMN, TST, TEQ) ... the result will be used to update those + // PSR flags which are not protected by virtue of the processor mode" + if(fields.destination() == 15) { registers_.set_status(conditions); } else { // Set N and Z in a unified way. @@ -229,7 +231,7 @@ struct Executor { constexpr BranchFlags flags(f); if constexpr (flags.operation() == BranchFlags::Operation::BL) { - registers_[14] = registers_.pc(0); + registers_[14] = registers_.pc_status(0); } registers_.set_pc(registers_.pc(4) + branch.offset()); } diff --git a/InstructionSets/ARM/Registers.hpp b/InstructionSets/ARM/Registers.hpp index fa3d05925..c84cdf489 100644 --- a/InstructionSets/ARM/Registers.hpp +++ b/InstructionSets/ARM/Registers.hpp @@ -155,15 +155,15 @@ struct Registers { switch(type) { case Exception::IRQ: set_mode(Mode::IRQ); - active_[14] = pc(8); + active_[14] = pc_status(8); break; case Exception::FIQ: set_mode(Mode::FIQ); - active_[14] = pc(8); + active_[14] = pc_status(8); break; default: set_mode(Mode::Supervisor); - active_[14] = pc(4); + active_[14] = pc_status(4); break; } diff --git a/Machines/Acorn/Archimedes/Archimedes.cpp b/Machines/Acorn/Archimedes/Archimedes.cpp index fbff0aafd..ab820010b 100644 --- a/Machines/Acorn/Archimedes/Archimedes.cpp +++ b/Machines/Acorn/Archimedes/Archimedes.cpp @@ -750,26 +750,26 @@ class ConcreteMachine: all.insert(instruction); - if(executor_.pc() == 0x03801a14) { + if(executor_.pc() == 0x03802b40) { printf(""); } // log |= (executor_.pc() > 0x02000000 && executor_.pc() < 0x02000078); - log |= executor_.pc() == 0x03801980; +// log |= executor_.pc() == 0x03801980; // log |= (executor_.pc() > 0x03801000); - log &= executor_.pc() != 0x03801a0c; +// log &= executor_.pc() != 0x03801a0c; - if(executor_.pc() == 0x02000078) { - if(!all.empty()) { - int c = 0; - for(auto instr: all) { - printf("0x%08x, ", instr); - ++c; - if(!(c&31)) printf("\n"); - } - all.clear(); - } - return; - } +// if(executor_.pc() == 0x02000078) { +// if(!all.empty()) { +// int c = 0; +// for(auto instr: all) { +// printf("0x%08x, ", instr); +// ++c; +// if(!(c&31)) printf("\n"); +// } +// all.clear(); +// } +// return; +// } if(log) { auto info = logger.info();