openMSX
ClockPin.cc
Go to the documentation of this file.
1 #include "ClockPin.hh"
2 #include "serialize.hh"
3 #include <cassert>
4 
5 namespace openmsx {
6 
8  : Schedulable(scheduler_), listener(listener_)
9  , referenceTime(EmuTime::zero())
10  , periodic(false) , status(false), signalEdge(false)
11 {
12 }
13 
14 void ClockPin::setState(bool newStatus, EmuTime::param time)
15 {
16  periodic = false;
17  if (signalEdge) {
18  unschedule();
19  }
20  if (signalEdge && !status && newStatus) {
21  // pos edge
22  status = newStatus;
23  if (listener) {
24  listener->signalPosEdge(*this, time);
25  }
26  } else {
27  status = newStatus;
28  }
29  if (listener) {
30  listener->signal(*this, time);
31  }
32 }
33 
35  EmuDuration::param hi, EmuTime::param time)
36 {
37  referenceTime = time;
38  totalDur = total;
39  hiDur = hi;
40 
41  if (listener) {
42  if (periodic) {
43  unschedule();
44  }
45  periodic = true;
46  if (signalEdge) {
47  executeUntil(time);
48  }
49  listener->signal(*this, time);
50  } else {
51  periodic = true;
52  }
53 }
54 
55 
56 bool ClockPin::getState(EmuTime::param time) const
57 {
58  if (!periodic) {
59  return status;
60  } else {
61  return ((time - referenceTime) % totalDur) < hiDur;
62  }
63 }
64 
66 {
67  assert(periodic);
68  return totalDur;
69 }
70 
72 {
73  assert(periodic);
74  return hiDur;
75 }
76 
77 int ClockPin::getTicksBetween(EmuTime::param begin, EmuTime::param end) const
78 {
79  assert(begin <= end);
80  if (!periodic) {
81  return 0;
82  }
83  if (totalDur > EmuDuration::zero()) {
84  int a = (begin < referenceTime) ?
85  0 :
86  (begin - referenceTime) / totalDur;
87  int b = (end - referenceTime) / totalDur;
88  return b - a;
89  } else {
90  return 0;
91  }
92 }
93 
94 
95 void ClockPin::generateEdgeSignals(bool wanted, EmuTime::param time)
96 {
97  if (signalEdge != wanted) {
98  signalEdge = wanted;
99  if (periodic) {
100  if (signalEdge) {
101  EmuTime tmp(referenceTime);
102  while (tmp < time) {
103  tmp += totalDur;
104  }
105  if (listener) {
106  schedule(tmp);
107  }
108  } else {
109  unschedule();
110  }
111  }
112  }
113 }
114 
115 void ClockPin::unschedule()
116 {
117  removeSyncPoint();
118 }
119 
120 void ClockPin::schedule(EmuTime::param time)
121 {
122  assert(signalEdge && periodic && listener);
123  setSyncPoint(time);
124 }
125 
126 void ClockPin::executeUntil(EmuTime::param time)
127 {
128  assert(signalEdge && periodic && listener);
129  listener->signalPosEdge(*this, time);
130  if (signalEdge && (totalDur > EmuDuration::zero())) {
131  schedule(time + totalDur);
132  }
133 }
134 
135 
136 template<typename Archive>
137 void ClockPin::serialize(Archive& ar, unsigned /*version*/)
138 {
139  ar.template serializeBase<Schedulable>(*this);
140  ar.serialize("totalDur", totalDur,
141  "hiDur", hiDur,
142  "referenceTime", referenceTime,
143  "periodic", periodic,
144  "status", status,
145  "signalEdge", signalEdge);
146 }
148 
149 } // namespace openmsx
virtual void signal(ClockPin &pin, EmuTime::param time)=0
virtual void signalPosEdge(ClockPin &pin, EmuTime::param time)=0
ClockPin(Scheduler &scheduler, ClockPinListener *listener=nullptr)
Definition: ClockPin.cc:7
void generateEdgeSignals(bool wanted, EmuTime::param time)
Definition: ClockPin.cc:95
void setState(bool status, EmuTime::param time)
Definition: ClockPin.cc:14
void serialize(Archive &ar, unsigned version)
Definition: ClockPin.cc:137
int getTicksBetween(EmuTime::param begin, EmuTime::param end) const
Definition: ClockPin.cc:77
bool getState(EmuTime::param time) const
Definition: ClockPin.cc:56
EmuDuration::param getHighDuration() const
Definition: ClockPin.cc:71
void setPeriodicState(EmuDuration::param total, EmuDuration::param hi, EmuTime::param time)
Definition: ClockPin.cc:34
EmuDuration::param getTotalDuration() const
Definition: ClockPin.cc:65
static constexpr EmuDuration zero()
Definition: EmuDuration.hh:115
Every class that wants to get scheduled at some point must inherit from this class.
Definition: Schedulable.hh:34
void setSyncPoint(EmuTime::param timestamp)
Definition: Schedulable.cc:23
This file implemented 3 utility functions:
Definition: Autofire.cc:9
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:998
constexpr auto begin(const zstring_view &x)
Definition: zstring_view.hh:83
constexpr auto end(const zstring_view &x)
Definition: zstring_view.hh:84