From b7a1363add980c93f08c6f230eba6166a035d8b9 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 4 Mar 2024 21:09:24 -0500 Subject: [PATCH] Add an incorrect execution loop. --- Machines/Acorn/Archimedes/Archimedes.cpp | 57 ++++++++++++++++++++---- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/Machines/Acorn/Archimedes/Archimedes.cpp b/Machines/Acorn/Archimedes/Archimedes.cpp index f75ff0e50..a4c8fd0e8 100644 --- a/Machines/Acorn/Archimedes/Archimedes.cpp +++ b/Machines/Acorn/Archimedes/Archimedes.cpp @@ -16,10 +16,19 @@ #include "../../../InstructionSets/ARM/Executor.hpp" +#include +#include +#include + namespace Archimedes { struct Memory { - std::vector rom; + void set_rom(const std::vector &rom) { + std::copy( + rom.begin(), + rom.begin() + static_cast(std::min(rom.size(), rom_.size())), + rom_.begin()); + } template bool write(uint32_t address, IntT source, InstructionSet::ARM::Mode mode, bool trans) { @@ -42,15 +51,14 @@ struct Memory { if(address >= 0x3800000) { has_moved_rom_ = true; - source = *reinterpret_cast(&rom[address - 0x3800000]); + source = *reinterpret_cast(&rom_[address - 0x3800000]); } else if(!has_moved_rom_) { // TODO: this is true only very transiently. - source = *reinterpret_cast(&rom[address]); + 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)); } return true; @@ -59,10 +67,12 @@ struct Memory { private: bool has_moved_rom_ = false; std::array ram_{}; + std::array rom_; }; class ConcreteMachine: public Machine, + public MachineTypes::MediaTarget, public MachineTypes::TimedMachine, public MachineTypes::ScanProducer { @@ -71,8 +81,19 @@ class ConcreteMachine: const Analyser::Static::Target &target, const ROMMachine::ROMFetcher &rom_fetcher ) { - (void)target; - (void)rom_fetcher; + constexpr ROM::Name risc_os = ROM::Name::AcornRISCOS319; + ROM::Request request(risc_os); + auto roms = rom_fetcher(request); + if(!request.validate(roms)) { + throw ROMMachine::Error::MissingROMs; + } + + executor_.bus.set_rom(roms.find(risc_os)->second); + + // TODO: pick a sensible clock rate; this is just code for '20 MIPS, please'. + set_clock_rate(20'000'000); + + insert_media(target.media); } private: @@ -87,11 +108,31 @@ class ConcreteMachine: // MARK: - TimedMachine. void run_for(Cycles cycles) override { - (void)cycles; + auto instructions = cycles.as(); + while(instructions--) { + uint32_t instruction; + executor_.bus.read(executor_.pc(), instruction, executor_.registers().mode(), false); + // TODO: what if abort? How about pipeline prefetch? + + InstructionSet::ARM::execute(instruction, executor_); + } + } + + // MARK: - MediaTarget + bool insert_media(const Analyser::Static::Media &) override { +// int c = 0; +// for(auto &disk : media.disks) { +// fdc_.set_disk(disk, c); +// c++; +// if(c == 4) break; +// } +// return true; + return false; } // MARK: - ARM execution - InstructionSet::ARM::Executor executor_; + static constexpr auto arm_model = InstructionSet::ARM::Model::ARMv2; + InstructionSet::ARM::Executor executor_; }; }