libElysianVMU 1.6.0
Full-featured, accurate, cross-platform library emulating the Dreamcast's Visual Memory Unit
Loading...
Searching...
No Matches
evmu_wave.h
Go to the documentation of this file.
1/*! \file
2 * \brief EvmuWave and waveform API
3 *
4 * \author 2023 Falco Girgis
5 * \copyright MIT License
6 */
7#ifndef EVMU_WAVE_H
8#define EVMU_WAVE_H
9
10#include "../types/evmu_typedefs.h"
11
12#define EVMU_LOGIC_HIGH 1
13#define EVMU_LOGIC_LOW 0
14
15#define EVMU_WAVE_LOGIC_BITS 2
16#define EVMU_WAVE_LOGIC_CURRENT_MASK (0x3)
17#define EVMU_WAVE_LOGIC_PREVIOUS_MASK (0x70)
18
19#define GBL_SELF_TYPE GblEnum
20
21GBL_DECLS_BEGIN
22
23// Lowest-level boolean logic values
24GBL_DECLARE_ENUM(EVMU_LOGIC) {
25 EVMU_LOGIC_0 = EVMU_LOGIC_LOW,
26 EVMU_LOGIC_1 = EVMU_LOGIC_HIGH,
27 EVMU_LOGIC_Z = 0x2,
28 EVMU_LOGIC_X = 0x3,
29 GY_LOGIC_COUNT = EVMU_LOGIC_Z + 1
30};
31
32#define EVMU_DECLARE_SUBWAVE_ENUMS_(L)
33 EVMU_WAVE_##L##_0,
34 EVMU_WAVE_##L##_1,
35 EVMU_WAVE_##L##_Z,
36 EVMU_WAVE_##L##_X
37
38GBL_DECLARE_ENUM(EvmuWave) {
43 EVMU_WAVE_COUNT
44};
45
46EVMU_INLINE void EvmuWave_reset (GBL_SELF) GBL_NOEXCEPT;
47EVMU_INLINE void EvmuWave_fill (GBL_SELF, EVMU_LOGIC values) GBL_NOEXCEPT;
48EVMU_INLINE void EvmuWave_set (GBL_SELF, EVMU_LOGIC prevValue, EVMU_LOGIC curValue) GBL_NOEXCEPT;
49EVMU_INLINE void EvmuWave_update (GBL_SELF, EVMU_LOGIC value) GBL_NOEXCEPT;
50
51EVMU_INLINE EVMU_LOGIC EvmuWave_logicCurrent (GBL_CSELF) GBL_NOEXCEPT;
52EVMU_INLINE GblBool EvmuWave_isLogic (GBL_CSELF, EVMU_LOGIC value) GBL_NOEXCEPT;
53EVMU_INLINE GblBool EvmuWave_isLogicHigh (GBL_CSELF) GBL_NOEXCEPT;
54EVMU_INLINE GblBool EvmuWave_isLogicLow (GBL_CSELF) GBL_NOEXCEPT;
55EVMU_INLINE GblBool EvmuWave_isLogicInactive (GBL_CSELF) GBL_NOEXCEPT;
56EVMU_INLINE GblBool EvmuWave_isLogicUnknown (GBL_CSELF) GBL_NOEXCEPT;
57EVMU_INLINE GblBool EvmuWave_isLogicActive (GBL_CSELF) GBL_NOEXCEPT;
58EVMU_INLINE GblBool EvmuWave_isLogicKnown (GBL_CSELF) GBL_NOEXCEPT;
59EVMU_INLINE GblBool EvmuWave_isLogicValid (GBL_CSELF) GBL_NOEXCEPT;
60EVMU_INLINE GblBool EvmuWave_isLogicInvalid (GBL_CSELF) GBL_NOEXCEPT;
61
62EVMU_INLINE EVMU_LOGIC EvmuWave_logicPrevious (GBL_CSELF) GBL_NOEXCEPT;
63EVMU_INLINE GblBool EvmuWave_wasLogic (GBL_CSELF, EVMU_LOGIC value) GBL_NOEXCEPT;
64EVMU_INLINE GblBool EvmuWave_wasLogicHigh (GBL_CSELF) GBL_NOEXCEPT;
65EVMU_INLINE GblBool EvmuWave_wasLogicLow (GBL_CSELF) GBL_NOEXCEPT;
66EVMU_INLINE GblBool EvmuWave_wasLogicInactive (GBL_CSELF) GBL_NOEXCEPT;
67EVMU_INLINE GblBool EvmuWave_wasLogicUnknown (GBL_CSELF) GBL_NOEXCEPT;
68EVMU_INLINE GblBool EvmuWave_wasLogicActive (GBL_CSELF) GBL_NOEXCEPT;
69EVMU_INLINE GblBool EvmuWave_wasLogicKnown (GBL_CSELF) GBL_NOEXCEPT;
70EVMU_INLINE GblBool EvmuWave_wasLogicValid (GBL_CSELF) GBL_NOEXCEPT;
71EVMU_INLINE GblBool EvmuWave_wasLogicInvalid (GBL_CSELF) GBL_NOEXCEPT;
72
73EVMU_INLINE GblBool EvmuWave_hasStayed (GBL_CSELF) GBL_NOEXCEPT;
74EVMU_INLINE GblBool EvmuWave_hasStayedLogic (GBL_CSELF, EVMU_LOGIC value) GBL_NOEXCEPT;
75EVMU_INLINE GblBool EvmuWave_hasStayedLow (GBL_CSELF) GBL_NOEXCEPT;
76EVMU_INLINE GblBool EvmuWave_hasStayedHigh (GBL_CSELF) GBL_NOEXCEPT;
77EVMU_INLINE GblBool EvmuWave_hasStayedInactive (GBL_CSELF) GBL_NOEXCEPT;
78EVMU_INLINE GblBool EvmuWave_hasStayedUnknown (GBL_CSELF) GBL_NOEXCEPT;
79EVMU_INLINE GblBool EvmuWave_hasStayedActive (GBL_CSELF) GBL_NOEXCEPT;
80EVMU_INLINE GblBool EvmuWave_hasStayedKnown (GBL_CSELF) GBL_NOEXCEPT;
81EVMU_INLINE GblBool EvmuWave_hasStayedValid (GBL_CSELF) GBL_NOEXCEPT;
82EVMU_INLINE GblBool EvmuWave_hasStayedInvalid (GBL_CSELF) GBL_NOEXCEPT;
83
84EVMU_INLINE GblBool EvmuWave_hasChanged (GBL_CSELF) GBL_NOEXCEPT;
85EVMU_INLINE GblBool EvmuWave_hasChangedLogic (GBL_CSELF, EVMU_LOGIC value) GBL_NOEXCEPT;
86EVMU_INLINE GblBool EvmuWave_hasChangedEdge (GBL_CSELF) GBL_NOEXCEPT;
87EVMU_INLINE GblBool EvmuWave_hasChangedEdgeRising (GBL_CSELF) GBL_NOEXCEPT;
88EVMU_INLINE GblBool EvmuWave_hasChangedEdgeFalling (GBL_CSELF) GBL_NOEXCEPT;
89EVMU_INLINE GblBool EvmuWave_hasChangedActive (GBL_CSELF) GBL_NOEXCEPT;
90EVMU_INLINE GblBool EvmuWave_hasChangedInactive (GBL_CSELF) GBL_NOEXCEPT;
91EVMU_INLINE GblBool EvmuWave_hasChangedKnown (GBL_CSELF) GBL_NOEXCEPT;
92EVMU_INLINE GblBool EvmuWave_hasChangedUnknown (GBL_CSELF) GBL_NOEXCEPT;
93EVMU_INLINE GblBool EvmuWave_hasChangedValid (GBL_CSELF) GBL_NOEXCEPT;
94EVMU_INLINE GblBool EvmuWave_hasChangedInvalid (GBL_CSELF) GBL_NOEXCEPT;
95
96// ========== INLINE IMPLEMENTATION =======
97
98#define EVMU_WAVE_LOGIC_MASK_ (EVMU_WAVE_LOGIC_CURRENT_MASK | EVMU_WAVE_LOGIC_PREVIOUS_MASK)
99
100
101EVMU_INLINE void EvmuWave_logicPreviousSet_(GBL_SELF, EVMU_LOGIC value) GBL_NOEXCEPT {
103 *pSelf |= (value << EVMU_WAVE_LOGIC_BITS);
104}
105EVMU_INLINE void EvmuWave_logicCurrentSet_(GBL_SELF, EVMU_LOGIC value) GBL_NOEXCEPT {
107 *pSelf |= (value);
108}
109EVMU_INLINE void EvmuWave_reset(GBL_SELF) GBL_NOEXCEPT {
110 *pSelf = EVMU_WAVE_X_X;
111}
112EVMU_INLINE void EvmuWave_fill(GBL_SELF, EVMU_LOGIC values) GBL_NOEXCEPT {
113 EvmuWave_set(pSelf, values, values);
114}
115EVMU_INLINE void EvmuWave_set(GBL_SELF, EVMU_LOGIC prevValue, EVMU_LOGIC curValue) GBL_NOEXCEPT {
116 EvmuWave_logicPreviousSet_(pSelf, prevValue);
117 EvmuWave_logicCurrentSet_(pSelf, curValue);
118}
119EVMU_INLINE EVMU_LOGIC EvmuWave_logicCurrent(GBL_CSELF) GBL_NOEXCEPT {
120 return (EVMU_LOGIC)(*pSelf & EVMU_WAVE_LOGIC_CURRENT_MASK);
121}
122EVMU_INLINE EVMU_LOGIC EvmuWave_logicPrevious(GBL_CSELF) GBL_NOEXCEPT {
123 return (EVMU_LOGIC)(*pSelf & EVMU_WAVE_LOGIC_PREVIOUS_MASK);
124}
125EVMU_INLINE void EvmuWave_update(GBL_SELF, EVMU_LOGIC value) GBL_NOEXCEPT {
126 *pSelf <<= EVMU_WAVE_LOGIC_BITS;
127 *pSelf &= (value & EVMU_WAVE_LOGIC_MASK_);
128}
129EVMU_INLINE GblBool EvmuWave_hasStayed(GBL_CSELF) GBL_NOEXCEPT {
130 return EvmuWave_logicCurrent(pSelf) == EvmuWave_logicPrevious(pSelf);
131}
132EVMU_INLINE GblBool EvmuWave_hasStayedLogic(GBL_CSELF, EVMU_LOGIC value) GBL_NOEXCEPT {
133 return EvmuWave_isLogic(pSelf, value) && EvmuWave_wasLogic(pSelf, value);
134}
135EVMU_INLINE GblBool EvmuWave_hasStayedLow(GBL_CSELF) GBL_NOEXCEPT {
136 return EvmuWave_hasStayedLogic(pSelf, EVMU_LOGIC_0);
137}
138EVMU_INLINE GblBool EvmuWave_hasStayedHigh(GBL_CSELF) GBL_NOEXCEPT {
139 return EvmuWave_hasStayedLogic(pSelf, EVMU_LOGIC_1);
140}
141EVMU_INLINE GblBool EvmuWave_hasStayedInactive(GBL_CSELF) GBL_NOEXCEPT {
142 return EvmuWave_hasStayedLogic(pSelf, EVMU_LOGIC_Z);
143}
144EVMU_INLINE GblBool EvmuWave_hasStayedUnknown(GBL_CSELF) GBL_NOEXCEPT {
145 return EvmuWave_hasStayedLogic(pSelf, EVMU_LOGIC_X);
146}
147EVMU_INLINE GblBool EvmuWave_hasStayedActive(GBL_CSELF) GBL_NOEXCEPT {
148 return EvmuWave_wasLogicActive(pSelf) && EvmuWave_isLogicActive(pSelf);
149}
150EVMU_INLINE GblBool EvmuWave_hasStayedKnown(GBL_CSELF) GBL_NOEXCEPT {
151 return EvmuWave_wasLogicKnown(pSelf) && EvmuWave_isLogicKnown(pSelf);
152}
153EVMU_INLINE GblBool EvmuWave_hasStayedValid(GBL_CSELF) GBL_NOEXCEPT {
154 return EvmuWave_wasLogicValid(pSelf) && EvmuWave_isLogicValid(pSelf);
155}
156EVMU_INLINE GblBool EvmuWave_hasStayedInvalid(GBL_CSELF) GBL_NOEXCEPT {
157 return EvmuWave_wasLogicInvalid(pSelf) && EvmuWave_isLogicInvalid(pSelf);
158}
159EVMU_INLINE GblBool EvmuWave_hasChanged(GBL_CSELF) GBL_NOEXCEPT {
160 return !EvmuWave_hasStayed(pSelf);
161}
162EVMU_INLINE GblBool EvmuWave_hasChangedLogic(GBL_CSELF, EVMU_LOGIC value) GBL_NOEXCEPT {
163 return !EvmuWave_wasLogic(pSelf, value) && EvmuWave_isLogic(pSelf, value);
164}
165EVMU_INLINE GblBool EvmuWave_hasChangedEdge(GBL_CSELF) GBL_NOEXCEPT {
166 return EvmuWave_hasChangedEdgeRising(pSelf) || EvmuWave_hasChangedEdgeFalling(pSelf);
167}
168EVMU_INLINE GblBool EvmuWave_hasChangedEdgeRising(GBL_CSELF) GBL_NOEXCEPT {
169 return EvmuWave_wasLogicLow(pSelf) && EvmuWave_isLogicHigh(pSelf);
170}
171EVMU_INLINE GblBool EvmuWave_hasChangedEdgeFalling(GBL_CSELF) GBL_NOEXCEPT {
172 return EvmuWave_wasLogicHigh(pSelf) && EvmuWave_isLogicLow(pSelf);
173}
174EVMU_INLINE GblBool EvmuWave_hasChangedActive(GBL_CSELF) GBL_NOEXCEPT {
175 return EvmuWave_wasLogicInactive(pSelf) && EvmuWave_isLogicActive(pSelf);
176}
177EVMU_INLINE GblBool EvmuWave_hasChangedInactive(GBL_CSELF) GBL_NOEXCEPT {
178 return EvmuWave_wasLogicActive(pSelf) && EvmuWave_isLogicInactive(pSelf);
179}
180EVMU_INLINE GblBool EvmuWave_hasChangedKnown(GBL_CSELF) GBL_NOEXCEPT {
181 return EvmuWave_wasLogicUnknown(pSelf) && EvmuWave_isLogicKnown(pSelf);
182}
183EVMU_INLINE GblBool EvmuWave_hasChangedUnknown(GBL_CSELF) GBL_NOEXCEPT {
184 return EvmuWave_wasLogicKnown(pSelf) && EvmuWave_isLogicUnknown(pSelf);
185}
186EVMU_INLINE GblBool EvmuWave_hasChangedValid(GBL_CSELF) GBL_NOEXCEPT {
187 return EvmuWave_wasLogicInvalid(pSelf) && EvmuWave_isLogicValid(pSelf);
188}
189EVMU_INLINE GblBool EvmuWave_hasChangedInvalid(GBL_CSELF) GBL_NOEXCEPT {
190 return EvmuWave_wasLogicValid(pSelf) && EvmuWave_isLogicInvalid(pSelf);
191}
192EVMU_INLINE GblBool EvmuWave_isLogic(GBL_CSELF, EVMU_LOGIC value) GBL_NOEXCEPT {
193 return EvmuWave_logicCurrent(pSelf) == value;
194}
195EVMU_INLINE GblBool EvmuWave_isLogicHigh(GBL_CSELF) GBL_NOEXCEPT {
196 return EvmuWave_isLogic(pSelf, EVMU_LOGIC_1);
197}
198EVMU_INLINE GblBool EvmuWave_isLogicLow(GBL_CSELF) GBL_NOEXCEPT {
199 return EvmuWave_isLogic(pSelf, EVMU_LOGIC_0);
200}
201EVMU_INLINE GblBool EvmuWave_isLogicInactive(GBL_CSELF) GBL_NOEXCEPT {
202 return EvmuWave_isLogic(pSelf, EVMU_LOGIC_Z);
203}
204EVMU_INLINE GblBool EvmuWave_isLogicUnknown(GBL_CSELF) GBL_NOEXCEPT {
205 return EvmuWave_isLogic(pSelf, EVMU_LOGIC_X);
206}
207EVMU_INLINE GblBool EvmuWave_isLogicActive(GBL_CSELF) GBL_NOEXCEPT {
208 return !EvmuWave_isLogicInactive(pSelf);
209}
210EVMU_INLINE GblBool EvmuWave_isLogicKnown(GBL_CSELF) GBL_NOEXCEPT {
211 return !EvmuWave_isLogicUnknown(pSelf);
212}
213EVMU_INLINE GblBool EvmuWave_isLogicValid(GBL_CSELF) GBL_NOEXCEPT {
214 return EvmuWave_isLogicActive(pSelf) && EvmuWave_isLogicKnown(pSelf);
215}
216EVMU_INLINE GblBool EvmuWave_isLogicInvalid(GBL_CSELF) GBL_NOEXCEPT {
217 return EvmuWave_isLogicInactive(pSelf) || EvmuWave_isLogicUnknown(pSelf);
218}
219EVMU_INLINE GblBool EvmuWave_wasLogic(GBL_CSELF, EVMU_LOGIC value) GBL_NOEXCEPT {
220 return EvmuWave_logicPrevious(pSelf) == value;
221}
222EVMU_INLINE GblBool EvmuWave_wasLogicHigh(GBL_CSELF) GBL_NOEXCEPT {
223 return EvmuWave_wasLogic(pSelf, EVMU_LOGIC_1);
224}
225EVMU_INLINE GblBool EvmuWave_wasLogicLow(GBL_CSELF) GBL_NOEXCEPT {
226 return EvmuWave_wasLogic(pSelf, EVMU_LOGIC_0);
227}
228EVMU_INLINE GblBool EvmuWave_wasLogicInactive(GBL_CSELF) GBL_NOEXCEPT {
229 return EvmuWave_wasLogic(pSelf, EVMU_LOGIC_Z);
230}
231EVMU_INLINE GblBool EvmuWave_wasLogicUnknown(GBL_CSELF) GBL_NOEXCEPT {
232 return EvmuWave_wasLogic(pSelf, EVMU_LOGIC_X);
233}
234EVMU_INLINE GblBool EvmuWave_wasLogicActive(GBL_CSELF) GBL_NOEXCEPT {
235 return !EvmuWave_wasLogicInactive(pSelf);
236}
237EVMU_INLINE GblBool EvmuWave_wasLogicKnown(GBL_CSELF) GBL_NOEXCEPT {
238 return !EvmuWave_wasLogicUnknown(pSelf);
239}
240EVMU_INLINE GblBool EvmuWave_wasLogicValid(GBL_CSELF) GBL_NOEXCEPT {
241 return EvmuWave_wasLogicActive(pSelf) && EvmuWave_wasLogicKnown(pSelf);
242}
243EVMU_INLINE GblBool EvmuWave_wasLogicInvalid(GBL_CSELF) GBL_NOEXCEPT {
244 return EvmuWave_wasLogicInactive(pSelf) || EvmuWave_wasLogicUnknown(pSelf);
245}
246
247#undef EVMU_WAVE_LOGIC_MASK_
248
249GBL_DECLS_END
250
251#undef GBL_SELF_TYPE
252
253#endif // EVMU_WAVE_H
#define EVMU_INLINE
Define used for inlining a funcion within a C header file.
Definition evmu_api.h:20
#define EVMU_WAVE_LOGIC_PREVIOUS_MASK
Definition evmu_wave.h:17
#define EVMU_WAVE_LOGIC_MASK_
Definition evmu_wave.h:98
#define EVMU_DECLARE_SUBWAVE_ENUMS_(L)
Definition evmu_wave.h:32
#define EVMU_LOGIC_LOW
Definition evmu_wave.h:13
#define EVMU_WAVE_LOGIC_BITS
Definition evmu_wave.h:15
#define EVMU_WAVE_LOGIC_CURRENT_MASK
Definition evmu_wave.h:16
#define EVMU_LOGIC_HIGH
Definition evmu_wave.h:12
uint8_t GblBool