From 40339a12e189bd432577827b1141a1352ac83818 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 25 Jul 2017 07:15:31 -0400 Subject: [PATCH] Formalised the use of a cycles count with a divider, bringing a few additional plain-int users into the fold. --- Components/6560/6560.hpp | 10 ++++------ Components/ClockReceiver.hpp | 5 +++++ Machines/Atari2600/Bus.hpp | 6 ++---- Machines/Atari2600/Cartridges/Cartridge.hpp | 14 +++++++------- Machines/Electron/Electron.cpp | 8 +++----- Machines/Electron/Electron.hpp | 2 +- 6 files changed, 22 insertions(+), 23 deletions(-) diff --git a/Components/6560/6560.hpp b/Components/6560/6560.hpp index 4b31c5ebe..e0e8c02e4 100644 --- a/Components/6560/6560.hpp +++ b/Components/6560/6560.hpp @@ -151,11 +151,10 @@ template class MOS6560: public ClockReceiver> { Runs for cycles. Derr. */ inline void run_for(const Cycles &cycles) { - int number_of_cycles = cycles.as_int(); - // keep track of the amount of time since the speaker was updated; lazy updates are applied - cycles_since_speaker_update_ += (unsigned int)number_of_cycles; + cycles_since_speaker_update_ += cycles; + int number_of_cycles = cycles.as_int(); while(number_of_cycles--) { // keep an old copy of the vertical count because that test is a cycle later than the actual changes int previous_vertical_counter = vertical_counter_; @@ -409,10 +408,9 @@ template class MOS6560: public ClockReceiver> { std::shared_ptr crt_; std::shared_ptr speaker_; - unsigned int cycles_since_speaker_update_; + Cycles cycles_since_speaker_update_; void update_audio() { - speaker_->run_for(Cycles((int)cycles_since_speaker_update_ >> 2)); - cycles_since_speaker_update_ &= 3; + speaker_->run_for(Cycles(cycles_since_speaker_update_.divide(Cycles(4)))); } // register state diff --git a/Components/ClockReceiver.hpp b/Components/ClockReceiver.hpp index ae03b9688..88f9bdb53 100644 --- a/Components/ClockReceiver.hpp +++ b/Components/ClockReceiver.hpp @@ -68,6 +68,11 @@ template class WrappedInt { inline operator bool() const { return !!length_; } inline int as_int() const { return length_; } + inline T divide(const T &divisor) { + T result(length_ / divisor); + length_ %= divisor; + return result; + } // operator int() is deliberately not provided, to avoid accidental subtitution of // classes that use this template. diff --git a/Machines/Atari2600/Bus.hpp b/Machines/Atari2600/Bus.hpp index e5a4f1738..023483604 100644 --- a/Machines/Atari2600/Bus.hpp +++ b/Machines/Atari2600/Bus.hpp @@ -36,11 +36,9 @@ class Bus { protected: // speaker backlog accumlation counter - unsigned int cycles_since_speaker_update_; + Cycles cycles_since_speaker_update_; inline void update_audio() { - unsigned int audio_cycles = cycles_since_speaker_update_ / (CPUTicksPerAudioTick * 3); - cycles_since_speaker_update_ %= (CPUTicksPerAudioTick * 3); - speaker_->run_for(Cycles((int)audio_cycles)); + speaker_->run_for(cycles_since_speaker_update_.divide(Cycles(CPUTicksPerAudioTick * 3))); } // video backlog accumulation counter diff --git a/Machines/Atari2600/Cartridges/Cartridge.hpp b/Machines/Atari2600/Cartridges/Cartridge.hpp index aab7c29d4..2c0acde4f 100644 --- a/Machines/Atari2600/Cartridges/Cartridge.hpp +++ b/Machines/Atari2600/Cartridges/Cartridge.hpp @@ -29,19 +29,19 @@ template class Cartridge: // to satisfy CPU::MOS6502::Processor unsigned int perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) { uint8_t returnValue = 0xff; - unsigned int cycles_run_for = 3; + int cycles_run_for = 3; // this occurs as a feedback loop — the 2600 requests ready, then performs the cycles_run_for // leap to the end of ready only once ready is signalled — because on a 6502 ready doesn't take // effect until the next read; therefore it isn't safe to assume that signalling ready immediately // skips to the end of the line. if(operation == CPU::MOS6502::BusOperation::Ready) - cycles_run_for = (unsigned int)tia_->get_cycles_until_horizontal_blank(cycles_since_video_update_); + cycles_run_for = tia_->get_cycles_until_horizontal_blank(cycles_since_video_update_); - cycles_since_speaker_update_ += cycles_run_for; - cycles_since_video_update_ += (int)cycles_run_for; - cycles_since_6532_update_ += (int)(cycles_run_for / 3); - static_cast(this)->advance_cycles(cycles_run_for / 3); + cycles_since_speaker_update_ += Cycles(cycles_run_for); + cycles_since_video_update_ += Cycles(cycles_run_for); + cycles_since_6532_update_ += Cycles(cycles_run_for / 3); + static_cast(this)->advance_cycles((unsigned int)cycles_run_for / 3); if(operation != CPU::MOS6502::BusOperation::Ready) { // give the cartridge a chance to respond to the bus access @@ -158,7 +158,7 @@ template class Cartridge: if(!tia_->get_cycles_until_horizontal_blank(cycles_since_video_update_)) CPU::MOS6502::Processor>::set_ready_line(false); - return cycles_run_for / 3; + return (unsigned int)(cycles_run_for / 3); } void flush() { diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index 7b7e8a128..40764fe8c 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -316,8 +316,8 @@ unsigned int Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation } cycles_since_display_update_ += Cycles((int)cycles); - cycles_since_audio_update_ += cycles; - if(cycles_since_audio_update_ > 16384) update_audio(); + cycles_since_audio_update_ += Cycles((int)cycles); + if(cycles_since_audio_update_ > Cycles(16384)) update_audio(); tape_.run_for(Cycles((int)cycles)); cycles_until_display_interrupt_ -= cycles; @@ -365,9 +365,7 @@ inline void Machine::queue_next_display_interrupt() { inline void Machine::update_audio() { if(cycles_since_audio_update_) { - unsigned int difference = cycles_since_audio_update_ / Speaker::clock_rate_divider; - cycles_since_audio_update_ %= Speaker::clock_rate_divider; - speaker_->run_for(Cycles((int)difference)); + speaker_->run_for(cycles_since_audio_update_.divide(Cycles(Speaker::clock_rate_divider))); } } diff --git a/Machines/Electron/Electron.hpp b/Machines/Electron/Electron.hpp index 7788be9c7..0a2094761 100644 --- a/Machines/Electron/Electron.hpp +++ b/Machines/Electron/Electron.hpp @@ -129,7 +129,7 @@ class Machine: // Counters related to simultaneous subsystems Cycles cycles_since_display_update_; - unsigned int cycles_since_audio_update_; + Cycles cycles_since_audio_update_; int cycles_until_display_interrupt_; Interrupt next_display_interrupt_; VideoOutput::Range video_access_range_;