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