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 
9 namespace openmsx {
10 
11 class V9990;
12 class V9990VRAM;
13 class Setting;
14 class RenderSettings;
15 class BooleanSetting;
16 
19 class V9990CmdEngine final : private Observer<Setting>
20 {
21 public:
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  inline 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 
96 private:
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 inline unsigned getPitch(unsigned width);
103  static inline unsigned addressOf(unsigned x, unsigned y, unsigned pitch);
104  static inline byte point(V9990VRAM& vram,
105  unsigned x, unsigned y, unsigned pitch);
106  static inline byte shift(byte value, unsigned fromX, unsigned toX);
107  static inline byte shiftMask(unsigned x);
108  static inline const byte* getLogOpLUT(byte op);
109  static inline byte logOp(const byte* lut, byte src, byte dst);
110  static inline void pset(
111  V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
112  byte srcColor, word mask, const byte* lut, byte op);
113  static inline void psetColor(
114  V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
115  word color, word mask, const byte* 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 inline unsigned getPitch(unsigned width);
124  static inline unsigned addressOf(unsigned x, unsigned y, unsigned pitch);
125  static inline byte point(V9990VRAM& vram,
126  unsigned x, unsigned y, unsigned pitch);
127  static inline byte shift(byte value, unsigned fromX, unsigned toX);
128  static inline byte shiftMask(unsigned x);
129  static inline const byte* getLogOpLUT(byte op);
130  static inline byte logOp(const byte* lut, byte src, byte dst);
131  static inline void pset(
132  V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
133  byte srcColor, word mask, const byte* lut, byte op);
134  static inline void psetColor(
135  V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
136  word color, word mask, const byte* 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 inline unsigned getPitch(unsigned width);
145  static inline unsigned addressOf(unsigned x, unsigned y, unsigned pitch);
146  static inline byte point(V9990VRAM& vram,
147  unsigned x, unsigned y, unsigned pitch);
148  static inline byte shift(byte value, unsigned fromX, unsigned toX);
149  static inline byte shiftMask(unsigned x);
150  static inline const byte* getLogOpLUT(byte op);
151  static inline byte logOp(const byte* lut, byte src, byte dst);
152  static inline void pset(
153  V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
154  byte srcColor, word mask, const byte* lut, byte op);
155  static inline void psetColor(
156  V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
157  word color, word mask, const byte* 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 inline unsigned getPitch(unsigned width);
166  static inline unsigned addressOf(unsigned x, unsigned y, unsigned pitch);
167  static inline byte point(V9990VRAM& vram,
168  unsigned x, unsigned y, unsigned pitch);
169  static inline byte shift(byte value, unsigned fromX, unsigned toX);
170  static inline byte shiftMask(unsigned x);
171  static inline const byte* getLogOpLUT(byte op);
172  static inline byte logOp(const byte* lut, byte src, byte dst);
173  static inline void pset(
174  V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
175  byte srcColor, word mask, const byte* lut, byte op);
176  static inline void psetColor(
177  V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
178  word color, word mask, const byte* 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 inline unsigned getPitch(unsigned width);
187  static inline unsigned addressOf(unsigned x, unsigned y, unsigned pitch);
188  static inline byte point(V9990VRAM& vram,
189  unsigned x, unsigned y, unsigned pitch);
190  static inline byte shift(byte value, unsigned fromX, unsigned toX);
191  static inline byte shiftMask(unsigned x);
192  static inline const byte* getLogOpLUT(byte op);
193  static inline byte logOp(const byte* lut, byte src, byte dst);
194  static inline void pset(
195  V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
196  byte srcColor, word mask, const byte* lut, byte op);
197  static inline void psetColor(
198  V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
199  word color, word mask, const byte* 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 inline unsigned getPitch(unsigned width);
208  static inline unsigned addressOf(unsigned x, unsigned y, unsigned pitch);
209  static inline word point(V9990VRAM& vram,
210  unsigned x, unsigned y, unsigned pitch);
211  static inline word shift(word value, unsigned fromX, unsigned toX);
212  static inline word shiftMask(unsigned x);
213  static inline const byte* getLogOpLUT(byte op);
214  static inline word logOp(const byte* lut, word src, word dst, bool transp);
215  static inline void pset(
216  V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
217  word srcColor, word mask, const byte* lut, byte op);
218  static inline void psetColor(
219  V9990VRAM& vram, unsigned x, unsigned y, unsigned pitch,
220  word color, word mask, const byte* 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]] inline unsigned getWrappedNX() const {
333  return NX ? NX : 2048;
334  }
335  [[nodiscard]] inline unsigned getWrappedNY() const {
336  return NY ? NY : 4096;
337  }
338 };
340 
341 } // namespace openmsx
342 
343 #endif
BaseSetting * setting
Definition: Interpreter.cc:27
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)
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.
bool getBrokenTiming() const
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
const V9990 & getVDP() const
word getBorderX(EmuTime::param time) const
V9990CmdEngine(V9990 &vdp, EmuTime::param time, RenderSettings &settings)
Constructor.
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:16
Implementation of the Yamaha V9990 VDP as used in the GFX9000 cartridge by Sunrise.
Definition: V9990.hh:32
This file implemented 3 utility functions:
Definition: Autofire.cc:9
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:118
constexpr nibble mask[4][13]
Definition: RP5C01.cc:34