2024-03-04 17:06:43 +00:00
|
|
|
//
|
|
|
|
// Archimedes.cpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 04/03/2024.
|
|
|
|
// Copyright © 2024 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "Archimedes.hpp"
|
|
|
|
|
|
|
|
#include "../../AudioProducer.hpp"
|
|
|
|
#include "../../KeyboardMachine.hpp"
|
|
|
|
#include "../../MediaTarget.hpp"
|
|
|
|
#include "../../ScanProducer.hpp"
|
|
|
|
#include "../../TimedMachine.hpp"
|
|
|
|
|
2024-03-04 17:08:46 +00:00
|
|
|
#include "../../../InstructionSets/ARM/Executor.hpp"
|
|
|
|
|
2024-03-04 17:06:43 +00:00
|
|
|
namespace Archimedes {
|
|
|
|
|
2024-03-04 17:08:46 +00:00
|
|
|
struct Memory {
|
|
|
|
std::vector<uint8_t> rom;
|
|
|
|
|
|
|
|
template <typename IntT>
|
|
|
|
bool write(uint32_t address, IntT source, InstructionSet::ARM::Mode mode, bool trans) {
|
|
|
|
(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<IntT *>(&ram_[address]) = source;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename IntT>
|
|
|
|
bool read(uint32_t address, IntT &source, InstructionSet::ARM::Mode mode, bool trans) {
|
|
|
|
(void)mode;
|
|
|
|
(void)trans;
|
|
|
|
|
|
|
|
if(address >= 0x3800000) {
|
|
|
|
has_moved_rom_ = true;
|
|
|
|
source = *reinterpret_cast<const IntT *>(&rom[address - 0x3800000]);
|
|
|
|
} else if(!has_moved_rom_) {
|
|
|
|
// TODO: this is true only very transiently.
|
|
|
|
source = *reinterpret_cast<const IntT *>(&rom[address]);
|
|
|
|
} else if(address < ram_.size()) {
|
|
|
|
source = *reinterpret_cast<const IntT *>(&ram_[address]);
|
|
|
|
} else {
|
|
|
|
source = 0;
|
|
|
|
printf("Unknown read from %08x [%lu]\n", address, sizeof(IntT));
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool has_moved_rom_ = false;
|
|
|
|
std::array<uint8_t, 4*1024*1024> ram_{};
|
|
|
|
};
|
|
|
|
|
2024-03-04 17:06:43 +00:00
|
|
|
class ConcreteMachine:
|
|
|
|
public Machine,
|
|
|
|
public MachineTypes::TimedMachine,
|
|
|
|
public MachineTypes::ScanProducer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ConcreteMachine(
|
|
|
|
const Analyser::Static::Target &target,
|
|
|
|
const ROMMachine::ROMFetcher &rom_fetcher
|
|
|
|
) {
|
|
|
|
(void)target;
|
|
|
|
(void)rom_fetcher;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
// MARK: - ScanProducer.
|
|
|
|
void set_scan_target(Outputs::Display::ScanTarget *scan_target) override {
|
|
|
|
(void)scan_target;
|
|
|
|
}
|
|
|
|
Outputs::Display::ScanStatus get_scaled_scan_status() const override {
|
|
|
|
return Outputs::Display::ScanStatus();
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: - TimedMachine.
|
|
|
|
void run_for(Cycles cycles) override {
|
|
|
|
(void)cycles;
|
|
|
|
}
|
2024-03-04 17:08:46 +00:00
|
|
|
|
|
|
|
// MARK: - ARM execution
|
|
|
|
InstructionSet::ARM::Executor<InstructionSet::ARM::Model::ARMv2, Memory> executor_;
|
2024-03-04 17:06:43 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
using namespace Archimedes;
|
|
|
|
|
|
|
|
std::unique_ptr<Machine> Machine::Archimedes(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher) {
|
|
|
|
return std::make_unique<ConcreteMachine>(*target, rom_fetcher);
|
|
|
|
}
|