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:
@@ -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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 {
|
||||||
|
Reference in New Issue
Block a user