1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-01 11:49:58 +00:00

Add an incorrect execution loop.

This commit is contained in:
Thomas Harte 2024-03-04 21:09:24 -05:00
parent 341b705bef
commit b7a1363add

View File

@ -16,10 +16,19 @@
#include "../../../InstructionSets/ARM/Executor.hpp" #include "../../../InstructionSets/ARM/Executor.hpp"
#include <algorithm>
#include <array>
#include <vector>
namespace Archimedes { namespace Archimedes {
struct Memory { struct Memory {
std::vector<uint8_t> rom; void set_rom(const std::vector<uint8_t> &rom) {
std::copy(
rom.begin(),
rom.begin() + static_cast<ptrdiff_t>(std::min(rom.size(), rom_.size())),
rom_.begin());
}
template <typename IntT> template <typename IntT>
bool write(uint32_t address, IntT source, InstructionSet::ARM::Mode mode, bool trans) { bool write(uint32_t address, IntT source, InstructionSet::ARM::Mode mode, bool trans) {
@ -42,15 +51,14 @@ struct Memory {
if(address >= 0x3800000) { if(address >= 0x3800000) {
has_moved_rom_ = true; has_moved_rom_ = true;
source = *reinterpret_cast<const IntT *>(&rom[address - 0x3800000]); source = *reinterpret_cast<const IntT *>(&rom_[address - 0x3800000]);
} else if(!has_moved_rom_) { } else if(!has_moved_rom_) {
// TODO: this is true only very transiently. // TODO: this is true only very transiently.
source = *reinterpret_cast<const IntT *>(&rom[address]); source = *reinterpret_cast<const IntT *>(&rom_[address]);
} else if(address < ram_.size()) { } else if(address < ram_.size()) {
source = *reinterpret_cast<const IntT *>(&ram_[address]); source = *reinterpret_cast<const IntT *>(&ram_[address]);
} else { } else {
source = 0; source = 0;
printf("Unknown read from %08x [%lu]\n", address, sizeof(IntT));
} }
return true; return true;
@ -59,10 +67,12 @@ struct Memory {
private: private:
bool has_moved_rom_ = false; bool has_moved_rom_ = false;
std::array<uint8_t, 4*1024*1024> ram_{}; std::array<uint8_t, 4*1024*1024> ram_{};
std::array<uint8_t, 2*1024*1024> rom_;
}; };
class ConcreteMachine: class ConcreteMachine:
public Machine, public Machine,
public MachineTypes::MediaTarget,
public MachineTypes::TimedMachine, public MachineTypes::TimedMachine,
public MachineTypes::ScanProducer public MachineTypes::ScanProducer
{ {
@ -71,8 +81,19 @@ class ConcreteMachine:
const Analyser::Static::Target &target, const Analyser::Static::Target &target,
const ROMMachine::ROMFetcher &rom_fetcher const ROMMachine::ROMFetcher &rom_fetcher
) { ) {
(void)target; constexpr ROM::Name risc_os = ROM::Name::AcornRISCOS319;
(void)rom_fetcher; 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: private:
@ -87,11 +108,31 @@ class ConcreteMachine:
// MARK: - TimedMachine. // MARK: - TimedMachine.
void run_for(Cycles cycles) override { void run_for(Cycles cycles) override {
(void)cycles; auto instructions = cycles.as<int>();
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<arm_model>(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 // MARK: - ARM execution
InstructionSet::ARM::Executor<InstructionSet::ARM::Model::ARMv2, Memory> executor_; static constexpr auto arm_model = InstructionSet::ARM::Model::ARMv2;
InstructionSet::ARM::Executor<arm_model, Memory> executor_;
}; };
} }