diff --git a/Components/6526/6526.hpp b/Components/6526/6526.hpp index aeb73659c..9687d56ea 100644 --- a/Components/6526/6526.hpp +++ b/Components/6526/6526.hpp @@ -20,18 +20,27 @@ class PortHandler { enum class Personality { // The 6526, used in machines such as the C64, has a BCD time-of-day clock. - Model6526, + P6526, // The 8250, used in the Amiga, provides a binary time-of-day clock. - Model8250, + P8250, }; -template class MOS6526 { +template class MOS6526 { public: + MOS6526(PortHandlerT &port_handler) noexcept : port_handler_(port_handler) {} + MOS6526(const MOS6526 &) = delete; + /// Writes @c value to the register at @c address. Only the low two bits of the address are decoded. void write(int address, uint8_t value); /// Fetches the value of the register @c address. Only the low two bits of the address are decoded. uint8_t read(int address); + + /// Runs for a specified number of half cycles. + void run_for(const HalfCycles half_cycles); + + private: + PortHandlerT &port_handler_; }; } diff --git a/Components/6526/Implementation/6526Implementation.hpp b/Components/6526/Implementation/6526Implementation.hpp index 91c44592e..0a01f0a8e 100644 --- a/Components/6526/Implementation/6526Implementation.hpp +++ b/Components/6526/Implementation/6526Implementation.hpp @@ -14,13 +14,21 @@ namespace MOS6526 { template void MOS6526::write(int address, uint8_t value) { + (void)address; + (void)value; } template uint8_t MOS6526::read(int address) { + (void)address; return 0xff; } +template +void MOS6526::run_for(const HalfCycles half_cycles) { + (void)half_cycles; +} + } } diff --git a/Machines/Amiga/Amiga.cpp b/Machines/Amiga/Amiga.cpp index 34f27198a..8ccacb7ba 100644 --- a/Machines/Amiga/Amiga.cpp +++ b/Machines/Amiga/Amiga.cpp @@ -12,6 +12,8 @@ #include "../../Processors/68000/68000.hpp" +#include "../../Components/6526/6526.hpp" + #include "../../Analyser/Static/Amiga/Target.hpp" #include "../Utility/MemoryPacker.hpp" @@ -26,7 +28,9 @@ class ConcreteMachine: public Machine { public: ConcreteMachine(const Analyser::Static::Amiga::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) : - mc68000_(*this) + mc68000_(*this), + cia1_(cia1_handler_), + cia2_(cia2_handler_) { (void)target; @@ -65,16 +69,20 @@ class ConcreteMachine: // MARK: - MC68000::BusHandler. using Microcycle = CPU::MC68000::Microcycle; HalfCycles perform_bus_operation(const CPU::MC68000::Microcycle &cycle, int) { - // Do nothing if no address is exposed. - if(!(cycle.operation & (Microcycle::NewAddress | Microcycle::SameAddress))) return HalfCycles(0); - - // Otherwise, intended 1-2 step here is: + // Intended 1-2 step here is: // // (1) determine when this CPU access will be scheduled; // (2) do all the other actions prior to this CPU access being scheduled. // // (or at least enqueue them, JIT-wise). + // Advance time. + cia1_.run_for(cycle.length); + cia2_.run_for(cycle.length); + + // Do nothing if no address is exposed. + if(!(cycle.operation & (Microcycle::NewAddress | Microcycle::SameAddress))) return HalfCycles(0); + // TODO: interrupt acknowledgement. // Grab the target address to pick a memory source. @@ -130,6 +138,17 @@ class ConcreteMachine: } } + // MARK: - CIAs. + + struct CIA1Handler: public MOS::MOS6526::PortHandler { + } cia1_handler_; + + struct CIA2Handler: public MOS::MOS6526::PortHandler { + } cia2_handler_; + + MOS::MOS6526::MOS6526 cia1_; + MOS::MOS6526::MOS6526 cia2_; + // MARK: - MachineTypes::ScanProducer. void set_scan_target(Outputs::Display::ScanTarget *scan_target) final {