diff --git a/Machines/Enterprise/Dave.cpp b/Machines/Enterprise/Dave.cpp index 38a151d87..995ce29a5 100644 --- a/Machines/Enterprise/Dave.cpp +++ b/Machines/Enterprise/Dave.cpp @@ -235,22 +235,17 @@ void TimedInterruptSource::update_channel(int c, bool is_linked, int decrement) if(channels_[c].sync) { channels_[c].value = channels_[c].reload; } else { - // TODO: the while loop below is far from efficient. - - channels_[c].value -= decrement; - while(channels_[c].value < 0) { - channels_[c].value += channels_[c].reload + 1; - - if(is_linked) { - if(channels_[c].level) { - interrupts_ |= uint8_t(Interrupt::VariableFrequency); - } - programmable_level_ = channels_[c].level; + if(decrement <= channels_[c].value) { + channels_[c].value -= decrement; + } else { + const int num_flips = (decrement - (channels_[c].value + 1)) / (channels_[c].reload + 1); + if(is_linked && num_flips + channels_[c].level >= 2) { + interrupts_ |= uint8_t(Interrupt::VariableFrequency); } - channels_[c].level ^= true; + channels_[c].level ^= (num_flips & 1); + channels_[c].value = (decrement - (channels_[c].value + 1)) % (channels_[c].reload + 1); } } - } void TimedInterruptSource::run_for(Cycles cycles) { diff --git a/Machines/Enterprise/Dave.hpp b/Machines/Enterprise/Dave.hpp index beb1db4fd..a280665af 100644 --- a/Machines/Enterprise/Dave.hpp +++ b/Machines/Enterprise/Dave.hpp @@ -136,15 +136,14 @@ class TimedInterruptSource { Cycles one_hz_offset_ = clock_rate; - int programmable_offset_ = std::numeric_limits::max(); - bool programmable_level_ = false; - enum class InterruptRate { OnekHz, FiftyHz, ToneGenerator0, ToneGenerator1, } rate_ = InterruptRate::OnekHz; + int programmable_offset_ = programmble_reload(InterruptRate::OnekHz); + bool programmable_level_ = false; struct Channel { int value = 100, reload = 100;