From efdac2ce8c860651269d0641af99e8eaa5d2a2df Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 24 Jul 2017 22:29:09 -0400 Subject: [PATCH] The 6522 is now a `ClockReceiver`. --- Components/6522/6522.hpp | 38 ++++++++++------------------- Machines/Commodore/1540/C1540.cpp | 4 +-- Machines/Commodore/Vic-20/Vic20.cpp | 4 +-- Machines/Oric/Oric.cpp | 12 ++++----- Machines/Oric/Oric.hpp | 4 +-- 5 files changed, 25 insertions(+), 37 deletions(-) diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index 472a6ac78..5c5753b30 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -13,6 +13,8 @@ #include #include +#include "../ClockReceiver.hpp" + namespace MOS { /*! @@ -26,7 +28,7 @@ namespace MOS { Consumers should derive their own curiously-recurring-template-pattern subclass, implementing bus communications as required. */ -template class MOS6522 { +template class MOS6522: public ClockReceiver> { private: enum InterruptFlag: uint8_t { CA2ActiveEdge = 1 << 0, @@ -250,32 +252,22 @@ template class MOS6522 { timer_is_running_[0] = false;\ } - /*! - Runs for a specified number of half cycles. + /*! Runs for a specified number of half cycles. */ + inline void run_for(const HalfCycles &half_cycles) { + int number_of_half_cycles = half_cycles.as_int(); - Although the original chip accepts only a phase-2 input, timer reloads are specified as occuring - 1.5 cycles after the timer hits zero. It therefore may be necessary to emulate at half-cycle precision. - - The first emulated half-cycle will be the period between the trailing edge of a phase-2 input and the - next rising edge. So it should align with a full system's phase-1. The next emulated half-cycle will be - that which occurs during phase-2. - - Callers should decide whether they are going to use @c run_for_half_cycles or @c run_for_cycles, and not - intermingle usage. - */ - inline void run_for_half_cycles(unsigned int number_of_cycles) { if(is_phase2_) { phase2(); - number_of_cycles--; + number_of_half_cycles--; } - while(number_of_cycles >= 2) { + while(number_of_half_cycles >= 2) { phase1(); phase2(); - number_of_cycles -= 2; + number_of_half_cycles -= 2; } - if(number_of_cycles) { + if(number_of_half_cycles) { phase1(); is_phase2_ = true; } else { @@ -283,13 +275,9 @@ template class MOS6522 { } } - /*! - Runs for a specified number of cycles. - - Callers should decide whether they are going to use @c run_for_half_cycles or @c run_for_cycles, and not - intermingle usage. - */ - inline void run_for_cycles(unsigned int number_of_cycles) { + /*! Runs for a specified number of cycles. */ + inline void run_for(const Cycles &cycles) { + int number_of_cycles = cycles.as_int(); while(number_of_cycles--) { phase1(); phase2(); diff --git a/Machines/Commodore/1540/C1540.cpp b/Machines/Commodore/1540/C1540.cpp index 8e379ee37..da8a16955 100644 --- a/Machines/Commodore/1540/C1540.cpp +++ b/Machines/Commodore/1540/C1540.cpp @@ -63,8 +63,8 @@ unsigned int Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation drive_VIA_.set_register(address, *value); } - serial_port_VIA_->run_for_cycles(1); - drive_VIA_.run_for_cycles(1); + serial_port_VIA_->run_for(Cycles(1)); + drive_VIA_.run_for(Cycles(1)); return 1; } diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index dc85fbc32..691c36a79 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -179,8 +179,8 @@ unsigned int Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation } } - user_port_via_->run_for_cycles(1); - keyboard_via_->run_for_cycles(1); + user_port_via_->run_for(Cycles(1)); + keyboard_via_->run_for(Cycles(1)); if(typer_ && operation == CPU::MOS6502::BusOperation::ReadOpcode && address == 0xEB1E) { if(!typer_->type_next_character()) { clear_all_keys(); diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index 1f06466e7..fb89a83b6 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -130,7 +130,7 @@ unsigned int Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation } } - via_.run_for_cycles(1); + via_.run_for(Cycles(1)); if(microdisc_is_enabled_) microdisc_.run_for(Cycles(8)); cycles_since_video_update_++; return 1; @@ -235,15 +235,15 @@ uint8_t Machine::VIA::get_port_input(Port port) { } void Machine::VIA::flush() { - ay8910->run_for(Cycles((int)cycles_since_ay_update_)); + ay8910->run_for(Cycles(cycles_since_ay_update_)); ay8910->flush(); cycles_since_ay_update_ = 0; } -void Machine::VIA::run_for_cycles(unsigned int number_of_cycles) { - cycles_since_ay_update_ += number_of_cycles; - MOS::MOS6522::run_for_cycles(number_of_cycles); - tape->run_for(Cycles((int)number_of_cycles)); +void Machine::VIA::run_for(const Cycles &cycles) { + cycles_since_ay_update_ += cycles.as_int(); + MOS::MOS6522::run_for(cycles); + tape->run_for(cycles); } void Machine::VIA::update_ay() { diff --git a/Machines/Oric/Oric.hpp b/Machines/Oric/Oric.hpp index be1df2c78..cf534bb68 100644 --- a/Machines/Oric/Oric.hpp +++ b/Machines/Oric/Oric.hpp @@ -143,7 +143,7 @@ class Machine: void set_control_line_output(Port port, Line line, bool value); void set_port_output(Port port, uint8_t value, uint8_t direction_mask); uint8_t get_port_input(Port port); - inline void run_for_cycles(unsigned int number_of_cycles); + inline void run_for(const Cycles &cycles); std::shared_ptr ay8910; std::unique_ptr tape; @@ -154,7 +154,7 @@ class Machine: private: void update_ay(); bool ay_bdir_, ay_bc1_; - unsigned int cycles_since_ay_update_; + int cycles_since_ay_update_; }; VIA via_; std::shared_ptr keyboard_;