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