diff --git a/InstructionSets/ARM/Executor.hpp b/InstructionSets/ARM/Executor.hpp index afd97b748..9c20adb93 100644 --- a/InstructionSets/ARM/Executor.hpp +++ b/InstructionSets/ARM/Executor.hpp @@ -546,6 +546,10 @@ struct Executor { MemoryT bus; + const Registers ®isters() const { + return registers_; + } + /// Sets the expected address of the instruction after whichever is about to be executed. /// So it's PC+4 compared to most other systems. void set_pc(uint32_t pc) { @@ -559,11 +563,6 @@ struct Executor { return registers_.pc(0); } - /// @returns The current processor mode. - Mode mode() const { - return registers_.mode(); - } - private: Registers registers_; }; diff --git a/InstructionSets/ARM/Registers.hpp b/InstructionSets/ARM/Registers.hpp index 7b0fb4db5..91589a472 100644 --- a/InstructionSets/ARM/Registers.hpp +++ b/InstructionSets/ARM/Registers.hpp @@ -66,11 +66,9 @@ struct Registers { overflow_flag_ = value; } - /// @returns The full PC + status bits. - uint32_t pc_status(uint32_t offset) const { + uint32_t status() const { return uint32_t(mode_) | - ((active[15] + offset) & ConditionCode::Address) | (negative_flag_ & ConditionCode::Negative) | (zero_result_ ? 0 : ConditionCode::Zero) | (carry_flag_ ? ConditionCode::Carry : 0) | @@ -78,6 +76,13 @@ struct Registers { interrupt_flags_; } + /// @returns The full PC + status bits. + uint32_t pc_status(uint32_t offset) const { + return + ((active[15] + offset) & ConditionCode::Address) | + status(); + } + /// Sets status bits only, subject to mode. void set_status(uint32_t status) { // ... in user mode the other flags (I, F, M1, M0) are protected from direct change @@ -100,7 +105,6 @@ struct Registers { } /// Sets a new PC. - /// TODO: communicate this onward. void set_pc(uint32_t value) { active[15] = value & ConditionCode::Address; } @@ -204,7 +208,7 @@ struct Registers { } } - std::array active; + std::array active{}; void set_mode(Mode target_mode) { if(mode_ == target_mode) { @@ -257,17 +261,17 @@ struct Registers { private: Mode mode_ = Mode::Supervisor; - uint32_t zero_result_ = 0; + uint32_t zero_result_ = 1; uint32_t negative_flag_ = 0; - uint32_t interrupt_flags_ = 0; + uint32_t interrupt_flags_ = ConditionCode::IRQDisable | ConditionCode::FIQDisable; uint32_t carry_flag_ = 0; uint32_t overflow_flag_ = 0; // Various shadow registers. - std::array user_registers_; - std::array fiq_registers_; - std::array irq_registers_; - std::array supervisor_registers_; + std::array user_registers_{}; + std::array fiq_registers_{}; + std::array irq_registers_{}; + std::array supervisor_registers_{}; }; } diff --git a/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm b/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm index 9ce934b60..cb1d4030c 100644 --- a/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm +++ b/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm @@ -20,33 +20,42 @@ struct Memory { template bool write(uint32_t address, IntT source, Mode mode, bool trans) { - (void)address; - (void)source; (void)mode; (void)trans; + printf("W of %08x to %08x [%lu]\n", source, address, sizeof(IntT)); + + if(has_moved_rom_ && address < ram_.size()) { + *reinterpret_cast(&ram_[address]) = source; + } + return true; } template bool read(uint32_t address, IntT &source, Mode mode, bool trans) { + (void)mode; + (void)trans; + if(address >= 0x3800000) { has_moved_rom_ = true; source = *reinterpret_cast(&rom[address - 0x3800000]); } else if(!has_moved_rom_) { // TODO: this is true only very transiently. source = *reinterpret_cast(&rom[address]); + } else if(address < ram_.size()) { + source = *reinterpret_cast(&ram_[address]); } else { + source = 0; printf("Unknown read from %08x [%lu]\n", address, sizeof(IntT)); } - (void)mode; - (void)trans; return true; } private: bool has_moved_rom_ = false; + std::array ram_{}; }; } @@ -207,15 +216,19 @@ struct Memory { ROM::Request request(rom_name); const auto roms = CSROMFetcher()(request); - Executor executor; - executor.bus.rom = roms.find(rom_name)->second; + auto executor = std::make_unique>(); + executor->bus.rom = roms.find(rom_name)->second; for(int c = 0; c < 1000; c++) { uint32_t instruction; - executor.bus.read(executor.pc(), instruction, executor.mode(), false); + executor->bus.read(executor->pc(), instruction, executor->registers().mode(), false); - printf("%08x: %08x\n", executor.pc(), instruction); - execute(instruction, executor); + printf("%08x: %08x [", executor->pc(), instruction); + for(int c = 0; c < 15; c++) { + printf("r%d:%08x ", c, executor->registers().active[c]); + } + printf("psr:%08x]\n", executor->registers().status()); + execute(instruction, *executor); } }