1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-08-09 05:25:01 +00:00

Adds concept of time, captured port handler.

This commit is contained in:
Thomas Harte
2021-07-18 11:49:10 -04:00
parent 377cc7bdcd
commit 48999c03a5
3 changed files with 44 additions and 8 deletions

View File

@@ -20,18 +20,27 @@ class PortHandler {
enum class Personality { enum class Personality {
// The 6526, used in machines such as the C64, has a BCD time-of-day clock. // 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. // The 8250, used in the Amiga, provides a binary time-of-day clock.
Model8250, P8250,
}; };
template <typename BusHandlerT, Personality personality> class MOS6526 { template <typename PortHandlerT, Personality personality> class MOS6526 {
public: 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. /// 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); 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. /// Fetches the value of the register @c address. Only the low two bits of the address are decoded.
uint8_t read(int address); uint8_t read(int address);
/// Runs for a specified number of half cycles.
void run_for(const HalfCycles half_cycles);
private:
PortHandlerT &port_handler_;
}; };
} }

View File

@@ -14,13 +14,21 @@ namespace MOS6526 {
template <typename BusHandlerT, Personality personality> template <typename BusHandlerT, Personality personality>
void MOS6526<BusHandlerT, personality>::write(int address, uint8_t value) { void MOS6526<BusHandlerT, personality>::write(int address, uint8_t value) {
(void)address;
(void)value;
} }
template <typename BusHandlerT, Personality personality> template <typename BusHandlerT, Personality personality>
uint8_t MOS6526<BusHandlerT, personality>::read(int address) { uint8_t MOS6526<BusHandlerT, personality>::read(int address) {
(void)address;
return 0xff; return 0xff;
} }
template <typename BusHandlerT, Personality personality>
void MOS6526<BusHandlerT, personality>::run_for(const HalfCycles half_cycles) {
(void)half_cycles;
}
} }
} }

View File

@@ -12,6 +12,8 @@
#include "../../Processors/68000/68000.hpp" #include "../../Processors/68000/68000.hpp"
#include "../../Components/6526/6526.hpp"
#include "../../Analyser/Static/Amiga/Target.hpp" #include "../../Analyser/Static/Amiga/Target.hpp"
#include "../Utility/MemoryPacker.hpp" #include "../Utility/MemoryPacker.hpp"
@@ -26,7 +28,9 @@ class ConcreteMachine:
public Machine { public Machine {
public: public:
ConcreteMachine(const Analyser::Static::Amiga::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) : ConcreteMachine(const Analyser::Static::Amiga::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) :
mc68000_(*this) mc68000_(*this),
cia1_(cia1_handler_),
cia2_(cia2_handler_)
{ {
(void)target; (void)target;
@@ -65,16 +69,20 @@ class ConcreteMachine:
// MARK: - MC68000::BusHandler. // MARK: - MC68000::BusHandler.
using Microcycle = CPU::MC68000::Microcycle; using Microcycle = CPU::MC68000::Microcycle;
HalfCycles perform_bus_operation(const CPU::MC68000::Microcycle &cycle, int) { HalfCycles perform_bus_operation(const CPU::MC68000::Microcycle &cycle, int) {
// Do nothing if no address is exposed. // Intended 1-2 step here is:
if(!(cycle.operation & (Microcycle::NewAddress | Microcycle::SameAddress))) return HalfCycles(0);
// Otherwise, intended 1-2 step here is:
// //
// (1) determine when this CPU access will be scheduled; // (1) determine when this CPU access will be scheduled;
// (2) do all the other actions prior to this CPU access being scheduled. // (2) do all the other actions prior to this CPU access being scheduled.
// //
// (or at least enqueue them, JIT-wise). // (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. // TODO: interrupt acknowledgement.
// Grab the target address to pick a memory source. // 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<CIA1Handler, MOS::MOS6526::Personality::P8250> cia1_;
MOS::MOS6526::MOS6526<CIA2Handler, MOS::MOS6526::Personality::P8250> cia2_;
// MARK: - MachineTypes::ScanProducer. // MARK: - MachineTypes::ScanProducer.
void set_scan_target(Outputs::Display::ScanTarget *scan_target) final { void set_scan_target(Outputs::Display::ScanTarget *scan_target) final {