From e9a0dc19d87ea7a7ffc3ab59f4810d23b1a672ef Mon Sep 17 00:00:00 2001 From: Aaron Giles Date: Thu, 20 Aug 2020 18:06:29 -0700 Subject: pit8253: Fix cycles computation error due to using floating-point. --- src/devices/machine/pit8253.cpp | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/devices/machine/pit8253.cpp b/src/devices/machine/pit8253.cpp index 2e73aecbcb9..f0f4450e90d 100644 --- a/src/devices/machine/pit8253.cpp +++ b/src/devices/machine/pit8253.cpp @@ -714,7 +714,44 @@ void pit_counter_device::update() if (now > m_last_updated) { attotime elapsed_time = now - m_last_updated; - elapsed_cycles = elapsed_time.as_double() * m_clockin; + + // in the case of sub-Hz frequencies, just loop; there's not going to be many + if (m_clock_period.m_seconds != 0) + { + while (elapsed_time >= m_clock_period) + { + elapsed_cycles++; + elapsed_time -= m_clock_period; + } + } + + // otherwise, compute it a straightforward way + else + { + elapsed_cycles = elapsed_time.m_attoseconds / m_clock_period.m_attoseconds; + + // not expecting to see many cases of this, but just in case, let's do it right + if (elapsed_time.m_seconds != 0) + { + // first account for the elapsed_cycles counted above (guaranteed to be <= elapsed_time.m_attoseconds) + elapsed_time.m_attoseconds -= elapsed_cycles * m_clock_period.m_attoseconds; + + // now compute the integral cycles per second based on the clock period + int64_t cycles_per_second = ATTOSECONDS_PER_SECOND / m_clock_period.m_attoseconds; + + // add that many times the number of elapsed seconds + elapsed_cycles += cycles_per_second * elapsed_time.m_seconds; + + // now compute how many attoseconds we missed for each full second (will be 0 for integral values) + int64_t remainder_per_second = ATTOSECONDS_PER_SECOND - cycles_per_second * m_clock_period.m_attoseconds; + + // add those to the elapsed attoseconds + elapsed_time.m_attoseconds += elapsed_time.m_seconds * remainder_per_second; + + // finally, see if that adds up to any additional cycles + elapsed_cycles += elapsed_time.m_attoseconds / m_clock_period.m_attoseconds; + } + } LOG2("update(): %d elapsed_cycles\n", elapsed_cycles); -- cgit v1.2.3