summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2021-04-01 01:11:04 -0700
committer Aaron Giles <aaron@aarongiles.com>2021-04-01 01:11:04 -0700
commitc51f3c05b08f9911fe0657a730d7c5b114ca7ecf (patch)
treede29c6c253bf4ab0b09006ae9aabedfa99cb4f48
parent3ba36e65d39553535503ce67e7e9c1bae8f6bd51 (diff)
Create subseconds class to wrap sub-second times. Currently just maps to attoseconds but in the future may represent some other form of data.time-experiments
-rw-r--r--src/emu/attotime.h137
1 files changed, 133 insertions, 4 deletions
diff --git a/src/emu/attotime.h b/src/emu/attotime.h
index ba801392b75..a67e4092b97 100644
--- a/src/emu/attotime.h
+++ b/src/emu/attotime.h
@@ -47,8 +47,8 @@
//**************************************************************************
// core components of the attotime structure
-typedef s64 attoseconds_t;
-typedef s32 seconds_t;
+using attoseconds_t = s64;
+using seconds_t = s32;
// core definitions
constexpr attoseconds_t ATTOSECONDS_PER_SECOND_SQRT = 1'000'000'000;
@@ -86,6 +86,123 @@ template <typename T> inline constexpr attoseconds_t ATTOSECONDS_IN_NSEC(T &&x)
// TYPE DEFINITIONS
//***************************************************************************/
+class subseconds
+{
+ // save_manager needs direct access for save/restore purposes
+ friend class save_manager;
+
+public:
+ static constexpr u64 MAX_RAW = ATTOSECONDS_PER_SECOND;
+// static constexpr subseconds MAX = subseconds(MAX_RAW);
+
+ constexpr subseconds() :
+ m_subseconds(0)
+ {
+ }
+
+ subseconds(subseconds const &src) :
+ m_subseconds(src.m_subseconds)
+ {
+ }
+
+ subseconds &operator=(subseconds const &src)
+ {
+ m_subseconds = src.m_subseconds;
+ return *this;
+ }
+
+ // math
+ subseconds &operator+=(subseconds const &right) noexcept
+ {
+ m_subseconds += right.m_subseconds;
+ return *this;
+ }
+
+ subseconds &operator-=(subseconds const &right) noexcept
+ {
+ m_subseconds -= right.m_subseconds;
+ return *this;
+ }
+
+ subseconds &operator*=(u32 factor) noexcept
+ {
+ m_subseconds *= factor;
+ return *this;
+ }
+
+ subseconds &operator/=(u32 factor)
+ {
+ m_subseconds /= factor;
+ return *this;
+ }
+
+ constexpr u64 raw() const { return m_subseconds; }
+
+ // constants
+ static const subseconds max;
+ static const subseconds zero;
+
+ // static creators
+ static constexpr subseconds from_raw(u64 raw) { return subseconds(raw); }
+ static constexpr subseconds from_msec(u64 msec) { return subseconds(msec * ATTOSECONDS_PER_MILLISECOND); }
+ static constexpr subseconds from_usec(u64 usec) { return subseconds(usec * ATTOSECONDS_PER_MICROSECOND); }
+ static constexpr subseconds from_nsec(u64 nsec) { return subseconds(nsec * ATTOSECONDS_PER_NANOSECOND); }
+ static constexpr subseconds from_hz(double hz)
+ {
+ u64 const hz_int = u64(hz);
+ if (hz == double(hz_int))
+ return subseconds(MAX_RAW / s64(hz));
+ return subseconds(u64(2e64 / hz));
+ }
+ static constexpr subseconds from_hz(u32 hz) { return subseconds((hz > 1) ? (MAX_RAW / hz) : MAX_RAW); }
+ static constexpr subseconds from_hz(int hz) { return subseconds((hz > 1) ? (MAX_RAW / hz) : MAX_RAW); }
+ static subseconds from_hz(XTAL const &xtal) { return from_hz(xtal.dvalue()); }
+
+ // friend functions
+ friend subseconds operator+(subseconds const &left, subseconds const &right) noexcept;
+ friend subseconds operator-(subseconds const &left, subseconds const &right) noexcept;
+ friend subseconds operator*(subseconds const &left, u32 factor) noexcept;
+ friend subseconds operator*(u32 factor, subseconds const &right) noexcept;
+ friend u64 operator/(subseconds const &left, subseconds const &right);
+ friend subseconds operator/(subseconds const &left, u32 factor);
+ friend constexpr bool operator==(subseconds const &left, subseconds const &right) noexcept;
+ friend constexpr bool operator!=(subseconds const &left, subseconds const &right) noexcept;
+ friend constexpr bool operator<(subseconds const &left, subseconds const &right) noexcept;
+ friend constexpr bool operator<=(subseconds const &left, subseconds const &right) noexcept;
+ friend constexpr bool operator>(subseconds const &left, subseconds const &right) noexcept;
+ friend constexpr bool operator>=(subseconds const &left, subseconds const &right) noexcept;
+
+private:
+ constexpr subseconds(u64 raw) : m_subseconds(raw) { }
+
+ u64 m_subseconds;
+};
+
+inline subseconds operator+(subseconds const &left, subseconds const &right) noexcept
+{ return subseconds(left.m_subseconds + right.m_subseconds); }
+inline subseconds operator-(subseconds const &left, subseconds const &right) noexcept
+{ return subseconds(left.m_subseconds - right.m_subseconds); }
+inline subseconds operator*(subseconds const &left, u32 factor) noexcept
+{ return subseconds(left.m_subseconds * factor); }
+inline subseconds operator*(u32 factor, subseconds const &right) noexcept
+{ return subseconds(factor * right.m_subseconds); }
+inline u64 operator/(subseconds const &left, subseconds const &right)
+{ return left.m_subseconds / right.m_subseconds; }
+inline subseconds operator/(subseconds const &left, u32 factor)
+{ return subseconds(left.m_subseconds / factor); }
+inline constexpr bool operator==(subseconds const &left, subseconds const &right) noexcept
+{ return left.m_subseconds == right.m_subseconds; }
+inline constexpr bool operator!=(subseconds const &left, subseconds const &right) noexcept
+{ return left.m_subseconds != right.m_subseconds; }
+inline constexpr bool operator<(subseconds const &left, subseconds const &right) noexcept
+{ return left.m_subseconds < right.m_subseconds; }
+inline constexpr bool operator<=(subseconds const &left, subseconds const &right) noexcept
+{ return left.m_subseconds <= right.m_subseconds; }
+inline constexpr bool operator>(subseconds const &left, subseconds const &right) noexcept
+{ return left.m_subseconds > right.m_subseconds; }
+inline constexpr bool operator>=(subseconds const &left, subseconds const &right) noexcept
+{ return left.m_subseconds >= right.m_subseconds; }
+
// the attotime structure itself
class attotime
{
@@ -98,6 +215,8 @@ public:
/** Constructs with @p secs seconds and @p attos attoseconds. */
constexpr attotime(seconds_t secs, attoseconds_t attos) noexcept : m_attoseconds(attos), m_seconds(secs) { }
+ constexpr attotime(seconds_t secs, subseconds subs) noexcept : m_attoseconds(subs.raw()), m_seconds(secs) { }
+ constexpr attotime(subseconds subs) noexcept : m_attoseconds(subs.raw()), m_seconds(0) { }
constexpr attotime(const attotime& that) noexcept : m_attoseconds(that.m_attoseconds), m_seconds(that.m_seconds) { }
@@ -117,6 +236,7 @@ public:
// conversion to other forms
constexpr double as_double() const noexcept { return double(m_seconds) + ATTOSECONDS_TO_DOUBLE(m_attoseconds); }
constexpr attoseconds_t as_attoseconds() const noexcept;
+ constexpr subseconds as_subseconds() const noexcept;
double as_hz() const noexcept { assert(!is_zero()); return m_seconds == 0 ? ATTOSECONDS_TO_HZ(m_attoseconds) : is_never() ? 0.0 : 1.0 / as_double(); }
double as_khz() const noexcept { assert(!is_zero()); return m_seconds == 0 ? double(ATTOSECONDS_PER_MILLISECOND) / double(m_attoseconds) : is_never() ? 0.0 : 1e-3 / as_double(); }
double as_mhz() const noexcept { assert(!is_zero()); return m_seconds == 0 ? double(ATTOSECONDS_PER_MICROSECOND) / double(m_attoseconds) : is_never() ? 0.0 : 1e-6 / as_double(); }
@@ -148,8 +268,8 @@ public:
/** Create an attotime from a integer count of nanoseconds @nsec */
static constexpr attotime from_nsec(s64 nsec) { return attotime(nsec / 1000000000, (nsec % 1000000000) * (ATTOSECONDS_PER_SECOND / 1000000000)); }
/** Create an attotime from at the given frequency @frequency */
- static attotime from_hz(u32 frequency) { return (frequency > 1) ? attotime(0, HZ_TO_ATTOSECONDS(frequency)) : (frequency == 1) ? attotime(1, 0) : attotime::never; }
- static attotime from_hz(int frequency) { return (frequency > 0) ? from_hz(u32(frequency)) : attotime::never; }
+ static constexpr attotime from_hz(u32 frequency) { return (frequency > 1) ? attotime(0, HZ_TO_ATTOSECONDS(frequency)) : (frequency == 1) ? attotime(1, 0) : attotime::never; }
+ static constexpr attotime from_hz(int frequency) { return (frequency > 0) ? from_hz(u32(frequency)) : attotime::never; }
static attotime from_hz(const XTAL &xtal) { return (xtal.dvalue() > 1.0) ? attotime(0, HZ_TO_ATTOSECONDS(xtal)) : from_hz(xtal.dvalue()); }
static attotime from_hz(double frequency)
{
@@ -412,6 +532,15 @@ inline constexpr attoseconds_t attotime::as_attoseconds() const noexcept
-ATTOSECONDS_PER_SECOND; // out-of-range negative values
}
+/** Convert to an subseconds value, clamping to 0-1 second */
+inline constexpr subseconds attotime::as_subseconds() const noexcept
+{
+ return subseconds::from_raw(
+ (m_seconds == 0) ? m_attoseconds : // positive values between 0 and 1 second
+ (m_seconds < 0) ? 0 : // negative values between -1 and 0 seconds
+ subseconds::MAX_RAW); // out-of-range negative values
+}
+
/** as_ticks - convert to ticks at @p frequency */
inline u64 attotime::as_ticks(u32 frequency) const