openMSX
ClockPin.cc
Go to the documentation of this file.
1#include "ClockPin.hh"
2#include "serialize.hh"
3#include <cassert>
4
5namespace openmsx {
6
8 : Schedulable(scheduler_), listener(listener_)
9 , referenceTime(EmuTime::zero())
10 , periodic(false) , status(false), signalEdge(false)
11{
12}
13
14void 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
56bool 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
77int 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
95void 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
115void ClockPin::unschedule()
116{
118}
119
120void ClockPin::schedule(EmuTime::param time)
121{
122 assert(signalEdge && periodic && listener);
123 setSyncPoint(time);
124}
125
126void 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
136template<typename Archive>
137void 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:106
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:1009
constexpr auto begin(const zstring_view &x)
constexpr auto end(const zstring_view &x)