mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-28 21:49:27 +00:00
Add an incorrect execution loop.
This commit is contained in:
parent
341b705bef
commit
b7a1363add
@ -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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user