openMSX
V9990CmdEngine.hh
Go to the documentation of this file.
1#ifndef V9990CMDENGINE_HH
2#define V9990CMDENGINE_HH
3
4#include "Observer.hh"
5#include "EmuTime.hh"
6#include "serialize_meta.hh"
7#include "openmsx.hh"
8
9namespace openmsx {
10
11class V9990;
12class V9990VRAM;
13class Setting;
14class RenderSettings;
15class BooleanSetting;
16
19class V9990CmdEngine final : private Observer<Setting>
20{
21public:
22 // status bits
23 static constexpr byte TR = 0x80;
24 static constexpr byte BD = 0x10;
25 static constexpr byte CE = 0x01;
26
27 V9990CmdEngine(V9990& vdp, EmuTime::param time,
28 RenderSettings& settings);
30
34 void reset(EmuTime::param time);
35
39 void sync(EmuTime::param time) {
40 if (CMD >> 4) sync2(time);
41 }
42 void sync2(EmuTime::param time);
43
46 void setCmdReg(byte reg, byte val, EmuTime::param time);
47
50 void setCmdData(byte value, EmuTime::param time);
51
54 [[nodiscard]] byte getCmdData(EmuTime::param time);
55
58 [[nodiscard]] byte peekCmdData(EmuTime::param time) const;
59
65 [[nodiscard]] byte getStatus(EmuTime::param time) const {
66 // note: used for both normal and debug read
67 const_cast<V9990CmdEngine*>(this)->sync(time);
68 return status;
69 }
70
71 [[nodiscard]] word getBorderX(EmuTime::param time) const {
72 // note: used for both normal and debug read
73 const_cast<V9990CmdEngine*>(this)->sync(time);
74 return borderX;
75 }
76
88 [[nodiscard]] EmuTime estimateCmdEnd() const;
89
90 [[nodiscard]] const V9990& getVDP() const { return vdp; }
91 [[nodiscard]] bool getBrokenTiming() const { return brokenTiming; }
92
93 template<typename Archive>
94 void serialize(Archive& ar, unsigned version);
95
96private:
97 class V9990P1 {
98 public:
99 using Type = byte;
100 static constexpr word BITS_PER_PIXEL = 4;
101 static constexpr word PIXELS_PER_BYTE = 2;
102 static unsigned getPitch(unsigned width);
103 static unsigned addressOf(unsigned x, unsigned y, unsigned pitch);
104 static byte point(const V9990VRAM& vram,
105 unsigned x, unsigned y, unsigned pitch);
106 static byte shift(byte value, unsigned fromX, unsigned toX);
107 static byte shiftMask(unsigned x);
108 static std::span<const byte, 256 * 256> getLogOpLUT(byte op);
109 static byte logOp(std::span<const byte, 256 * 256> lut, byte src, byte dst);
110 static void pset(
111 V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
112 byte srcColor, word mask, std::span<const byte, 256 * 256> lut, byte op);
113 static void psetColor(
114 V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
115 word color, word mask, std::span<const byte, 256 * 256> lut, byte op);
116 };
117
118 class V9990P2 {
119 public:
120 using Type = byte;
121 static constexpr word BITS_PER_PIXEL = 4;
122 static constexpr word PIXELS_PER_BYTE = 2;
123 static unsigned getPitch(unsigned width);
124 static unsigned addressOf(unsigned x, unsigned y, unsigned pitch);
125 static byte point(const V9990VRAM& vram,
126 unsigned x, unsigned y, unsigned pitch);
127 static byte shift(byte value, unsigned fromX, unsigned toX);
128 static byte shiftMask(unsigned x);
129 static std::span<const byte, 256 * 256> getLogOpLUT(byte op);
130 static byte logOp(std::span<const byte, 256 * 256> lut, byte src, byte dst);
131 static void pset(
132 V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
133 byte srcColor, word mask, std::span<const byte, 256 * 256> lut, byte op);
134 static void psetColor(
135 V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
136 word color, word mask, std::span<const byte, 256 * 256> lut, byte op);
137 };
138
139 class V9990Bpp2 {
140 public:
141 using Type = byte;
142 static constexpr word BITS_PER_PIXEL = 2;
143 static constexpr word PIXELS_PER_BYTE = 4;
144 static unsigned getPitch(unsigned width);
145 static unsigned addressOf(unsigned x, unsigned y, unsigned pitch);
146 static byte point(const V9990VRAM& vram,
147 unsigned x, unsigned y, unsigned pitch);
148 static byte shift(byte value, unsigned fromX, unsigned toX);
149 static byte shiftMask(unsigned x);
150 static std::span<const byte, 256 * 256> getLogOpLUT(byte op);
151 static byte logOp(std::span<const byte, 256 * 256> lut, byte src, byte dst);
152 static void pset(
153 V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
154 byte srcColor, word mask, std::span<const byte, 256 * 256> lut, byte op);
155 static void psetColor(
156 V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
157 word color, word mask, std::span<const byte, 256 * 256> lut, byte op);
158 };
159
160 class V9990Bpp4 {
161 public:
162 using Type = byte;
163 static constexpr word BITS_PER_PIXEL = 4;
164 static constexpr word PIXELS_PER_BYTE = 2;
165 static unsigned getPitch(unsigned width);
166 static unsigned addressOf(unsigned x, unsigned y, unsigned pitch);
167 static byte point(const V9990VRAM& vram,
168 unsigned x, unsigned y, unsigned pitch);
169 static byte shift(byte value, unsigned fromX, unsigned toX);
170 static byte shiftMask(unsigned x);
171 static std::span<const byte, 256 * 256> getLogOpLUT(byte op);
172 static byte logOp(std::span<const byte, 256 * 256> lut, byte src, byte dst);
173 static void pset(
174 V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
175 byte srcColor, word mask, std::span<const byte, 256 * 256> lut, byte op);
176 static void psetColor(
177 V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
178 word color, word mask, std::span<const byte, 256 * 256> lut, byte op);
179 };
180
181 class V9990Bpp8 {
182 public:
183 using Type = byte;
184 static constexpr word BITS_PER_PIXEL = 8;
185 static constexpr word PIXELS_PER_BYTE = 1;
186 static unsigned getPitch(unsigned width);
187 static unsigned addressOf(unsigned x, unsigned y, unsigned pitch);
188 static byte point(const V9990VRAM& vram,
189 unsigned x, unsigned y, unsigned pitch);
190 static byte shift(byte value, unsigned fromX, unsigned toX);
191 static byte shiftMask(unsigned x);
192 static std::span<const byte, 256 * 256> getLogOpLUT(byte op);
193 static byte logOp(std::span<const byte, 256 * 256> lut, byte src, byte dst);
194 static void pset(
195 V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
196 byte srcColor, word mask, std::span<const byte, 256 * 256> lut, byte op);
197 static void psetColor(
198 V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
199 word color, word mask, std::span<const byte, 256 * 256> lut, byte op);
200 };
201
202 class V9990Bpp16 {
203 public:
204 using Type = word;
205 static constexpr word BITS_PER_PIXEL = 16;
206 static constexpr word PIXELS_PER_BYTE = 0;
207 static unsigned getPitch(unsigned width);
208 static unsigned addressOf(unsigned x, unsigned y, unsigned pitch);
209 static word point(const V9990VRAM& vram,
210 unsigned x, unsigned y, unsigned pitch);
211 static word shift(word value, unsigned fromX, unsigned toX);
212 static word shiftMask(unsigned x);
213 static std::span<const byte, 256 * 256> getLogOpLUT(byte op);
214 static word logOp(std::span<const byte, 256 * 256> lut, word src, word dst, bool transp);
215 static void pset(
216 V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
217 word srcColor, word mask, std::span<const byte, 256 * 256> lut, byte op);
218 static void psetColor(
219 V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
220 word color, word mask, std::span<const byte, 256 * 256> lut, byte op);
221 };
222
223 void startSTOP (EmuTime::param time);
224 void startLMMC (EmuTime::param time);
225 void startLMMC16(EmuTime::param time);
226 void startLMMV (EmuTime::param time);
227 void startLMCM (EmuTime::param time);
228 void startLMCM16(EmuTime::param time);
229 void startLMMM (EmuTime::param time);
230 void startCMMC (EmuTime::param time);
231 void startCMMK (EmuTime::param time);
232 void startCMMM (EmuTime::param time);
233 void startBMXL (EmuTime::param time);
234 void startBMLX (EmuTime::param time);
235 void startBMLL (EmuTime::param time);
236 void startBMLL16(EmuTime::param time);
237 void startLINE (EmuTime::param time);
238 void startSRCH (EmuTime::param time);
239 template<typename Mode> void startPOINT(EmuTime::param time);
240 template<typename Mode> void startPSET (EmuTime::param time);
241 void startADVN (EmuTime::param time);
242
243 void executeSTOP (EmuTime::param limit);
244 template<typename Mode> void executeLMMC (EmuTime::param limit);
245 template<typename Mode> void executeLMMV (EmuTime::param limit);
246 template<typename Mode> void executeLMCM (EmuTime::param limit);
247 template<typename Mode> void executeLMMM (EmuTime::param limit);
248 template<typename Mode> void executeCMMC (EmuTime::param limit);
249 void executeCMMK (EmuTime::param limit);
250 template<typename Mode> void executeCMMM (EmuTime::param limit);
251 template<typename Mode> void executeBMXL (EmuTime::param limit);
252 template<typename Mode> void executeBMLX (EmuTime::param limit);
253 template<typename Mode> void executeBMLL (EmuTime::param limit);
254 template<typename Mode> void executeLINE (EmuTime::param limit);
255 template<typename Mode> void executeSRCH (EmuTime::param limit);
256 template<typename Mode> void executePOINT(EmuTime::param limit);
257 void executePSET (EmuTime::param limit);
258 void executeADVN (EmuTime::param limit);
259
260 RenderSettings& settings;
261
264 std::shared_ptr<BooleanSetting> cmdTraceSetting;
265
268 V9990& vdp;
269 V9990VRAM& vram;
270
271 EmuTime engineTime;
272
275 unsigned srcAddress;
276 unsigned dstAddress;
277 unsigned nbBytes;
278
281 word borderX;
282
285 word ASX, ADX, ANX, ANY;
286
289 word SX, SY, DX, DY, NX, NY;
290 word WM, fgCol, bgCol;
291 byte ARG, LOG, CMD;
292
293 unsigned cmdMode; // TODO keep this up-to-date (now it's calculated at the start of a command)
294
297 byte status;
298
301 byte data;
302
305 byte bitsLeft;
306
309 byte partial;
310
313 bool endAfterRead;
314
317 bool brokenTiming;
318
321 void cmdReady(EmuTime::param time);
322
325 void reportV9990Command() const;
326
327 // Observer<Setting>
328 void update(const Setting& setting) noexcept override;
329
330 void setCommandMode();
331
332 [[nodiscard]] word getWrappedNX() const {
333 return NX ? NX : 2048;
334 }
335 [[nodiscard]] word getWrappedNY() const {
336 return NY ? NY : 4096;
337 }
338};
340
341} // namespace openmsx
342
343#endif
BaseSetting * setting
Generic Gang-of-Four Observer class, templatized edition.
Definition Observer.hh:10
Class containing all settings for renderers.
void sync(EmuTime::param time)
Synchronizes the command engine with the V9990.
void serialize(Archive &ar, unsigned version)
const V9990 & getVDP() const
byte peekCmdData(EmuTime::param time) const
read the command data byte (without side-effects)
void reset(EmuTime::param time)
Re-initialise the command engine's state.
static constexpr byte CE
void setCmdData(byte value, EmuTime::param time)
set the data byte
void setCmdReg(byte reg, byte val, EmuTime::param time)
Set a value to one of the command registers.
static constexpr byte BD
byte getStatus(EmuTime::param time) const
Get command engine related status bits.
byte getCmdData(EmuTime::param time)
read the command data byte
word getBorderX(EmuTime::param time) const
EmuTime estimateCmdEnd() const
Calculate an (under-)estimation for when the command will finish.
static constexpr byte TR
void sync2(EmuTime::param time)
Video RAM for the V9990.
Definition V9990VRAM.hh:17
Implementation of the Yamaha V9990 VDP as used in the GFX9000 cartridge by Sunrise.
Definition V9990.hh:35
This file implemented 3 utility functions:
Definition Autofire.cc:11
uint8_t byte
8 bit unsigned integer
Definition openmsx.hh:26
uint16_t word
16 bit unsigned integer
Definition openmsx.hh:29
#define SERIALIZE_CLASS_VERSION(CLASS, VERSION)