openMSX
EmuDuration.hh
Go to the documentation of this file.
1 #ifndef EMUDUARTION_HH
2 #define EMUDUARTION_HH
3 
4 #include <cassert>
5 #include <cstdint>
6 
7 namespace openmsx {
8 
9 // constants
10 static const uint64_t MAIN_FREQ = 3579545ULL * 960;
11 static const unsigned MAIN_FREQ32 = MAIN_FREQ;
12 static_assert(MAIN_FREQ < (1ull << 32), "must fit in 32 bit");
13 
14 
16 {
17 public:
18  // This is only a very small class (one 64-bit member). On 64-bit CPUs
19  // it's cheaper to pass this by value. On 32-bit CPUs pass-by-reference
20  // is cheaper.
21 #ifdef __x86_64
22  using param = const EmuDuration;
23 #else
24  using param = const EmuDuration&;
25 #endif
26 
27  // friends
28  friend class EmuTime;
29 
30  // constructors
31  EmuDuration() : time(0) {}
32  explicit EmuDuration(uint64_t n) : time(n) {}
33  explicit EmuDuration(double duration)
34  : time(uint64_t(duration * MAIN_FREQ)) {}
35 
36  static EmuDuration sec(unsigned x)
37  { return EmuDuration(x * MAIN_FREQ); }
38  static EmuDuration msec(unsigned x)
39  { return EmuDuration(x * MAIN_FREQ / 1000); }
40  static EmuDuration usec(unsigned x)
41  { return EmuDuration(x * MAIN_FREQ / 1000000); }
42  static EmuDuration hz(unsigned x)
43  { return EmuDuration(MAIN_FREQ / x); }
44 
45  // conversions
46  double toDouble() const { return double(time) / MAIN_FREQ32; }
47  uint64_t length() const { return time; }
48 
49  // assignment operator
51  { time = d.time; return *this; }
52 
53  // comparison operators
55  { return time == d.time; }
57  { return time != d.time; }
59  { return time < d.time; }
61  { return time <= d.time; }
63  { return time > d.time; }
65  { return time >= d.time; }
66 
67  // arithmetic operators
69  { return EmuDuration(time % d.time); }
71  { return EmuDuration(time + d.time); }
72  const EmuDuration operator*(unsigned fact) const
73  { return EmuDuration(time * fact); }
74  const EmuDuration operator/(unsigned fact) const
75  { return EmuDuration(time / fact); }
76  const EmuDuration divRoundUp(unsigned fact) const
77  { return EmuDuration((time + fact - 1) / fact); }
78  unsigned operator/(EmuDuration::param d) const
79  {
80  uint64_t result = time / d.time;
81 #ifdef DEBUG
82  // we don't even want this overhead in devel builds
83  assert(result == unsigned(result));
84 #endif
85  return unsigned(result);
86  }
87  unsigned divUp(EmuDuration::param d) const {
88  uint64_t result = (time + d.time - 1) / d.time;
89 #ifdef DEBUG
90  assert(result == unsigned(result));
91 #endif
92  return unsigned(result);
93  }
94  double div(EmuDuration::param d) const
95  { return double(time) / d.time; }
96 
97  EmuDuration& operator*=(unsigned fact)
98  { time *= fact; return *this; }
99  EmuDuration& operator*=(double fact)
100  { time = uint64_t(time * fact); return *this; }
101  EmuDuration& operator/=(double fact)
102  { time = uint64_t(time / fact); return *this; }
103 
104  // ticks
105  // TODO: Used in WavAudioInput. Keep or use DynamicClock instead?
106  unsigned getTicksAt(unsigned freq) const
107  {
108  uint64_t result = time / (MAIN_FREQ32 / freq);
109 #ifdef DEBUG
110  // we don't even want this overhead in devel builds
111  assert(result == unsigned(result));
112 #endif
113  return unsigned(result);
114  }
115 
116  template<typename Archive>
117  void serialize(Archive& ar, unsigned version);
118 
119  static const EmuDuration zero;
120  static const EmuDuration infinity;
121 
122 private:
123  uint64_t time;
124 };
125 
126 } // namespace openmsx
127 
128 #endif
unsigned divUp(EmuDuration::param d) const
Definition: EmuDuration.hh:87
static EmuDuration sec(unsigned x)
Definition: EmuDuration.hh:36
static EmuDuration hz(unsigned x)
Definition: EmuDuration.hh:42
static EmuDuration msec(unsigned x)
Definition: EmuDuration.hh:38
bool operator>=(EmuDuration::param d) const
Definition: EmuDuration.hh:64
bool operator>(EmuDuration::param d) const
Definition: EmuDuration.hh:62
const EmuDuration operator/(unsigned fact) const
Definition: EmuDuration.hh:74
bool operator!=(EmuDuration::param d) const
Definition: EmuDuration.hh:56
const EmuDuration operator+(EmuDuration::param d) const
Definition: EmuDuration.hh:70
EmuDuration & operator/=(double fact)
Definition: EmuDuration.hh:101
double toDouble() const
Definition: EmuDuration.hh:46
EmuDuration & operator*=(double fact)
Definition: EmuDuration.hh:99
EmuDuration & operator*=(unsigned fact)
Definition: EmuDuration.hh:97
EmuDuration(double duration)
Definition: EmuDuration.hh:33
static const EmuDuration zero
Definition: EmuDuration.hh:119
uint64_t length() const
Definition: EmuDuration.hh:47
bool operator<(EmuDuration::param d) const
Definition: EmuDuration.hh:58
static const EmuDuration infinity
Definition: EmuDuration.hh:120
double div(EmuDuration::param d) const
Definition: EmuDuration.hh:94
friend class EmuTime
Definition: EmuDuration.hh:28
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
static EmuDuration usec(unsigned x)
Definition: EmuDuration.hh:40
const EmuDuration operator*(unsigned fact) const
Definition: EmuDuration.hh:72
const EmuDuration operator%(EmuDuration::param d) const
Definition: EmuDuration.hh:68
EmuDuration & operator=(EmuDuration::param d)
Definition: EmuDuration.hh:50
unsigned getTicksAt(unsigned freq) const
Definition: EmuDuration.hh:106
unsigned operator/(EmuDuration::param d) const
Definition: EmuDuration.hh:78
bool operator<=(EmuDuration::param d) const
Definition: EmuDuration.hh:60
void serialize(Archive &ar, unsigned version)
Definition: EmuDuration.cc:11
EmuDuration(uint64_t n)
Definition: EmuDuration.hh:32
const EmuDuration divRoundUp(unsigned fact) const
Definition: EmuDuration.hh:76
bool operator==(EmuDuration::param d) const
Definition: EmuDuration.hh:54