openMSX
VDPCmdEngine.hh
Go to the documentation of this file.
1 #ifndef VDPCMDENGINE_HH
2 #define VDPCMDENGINE_HH
3 
4 #include "VDP.hh"
5 #include "VDPAccessSlots.hh"
6 #include "BooleanSetting.hh"
7 #include "TclCallback.hh"
8 #include "serialize_meta.hh"
9 #include "openmsx.hh"
10 
11 namespace openmsx {
12 
13 class VDPVRAM;
14 class DisplayMode;
15 class CommandController;
16 
17 
22 {
23 public:
24  VDPCmdEngine(VDP& vdp, CommandController& commandController);
25 
29  void reset(EmuTime::param time);
30 
36  inline void sync(EmuTime::param time) {
37  if (CMD) sync2(time);
38  }
39  void sync2(EmuTime::param time);
40 
45  void stealAccessSlot(EmuTime::param time) {
46  if (!CMD) return;
47  engineTime = time;
48  nextAccessSlot(VDPAccessSlots::DELTA_1); // skip one slot
49  assert(engineTime > time);
50  }
51 
58  inline byte getStatus(EmuTime::param time) {
59  if (time >= statusChangeTime) {
60  sync(time);
61  }
62  return status;
63  }
64 
70  inline byte readColor(EmuTime::param time) {
71  sync(time);
72  return COL;
73  }
74  inline void resetColor() {
75  // Note: Real VDP always resets TR, but for such a short time
76  // that the MSX won't notice it.
77  // TODO: What happens on non-transfer commands?
78  if (!CMD) status &= 0x7F;
79  transfer = true;
80  }
81 
89  inline unsigned getBorderX(EmuTime::param time) {
90  sync(time);
91  return ASX;
92  }
93 
99  void setCmdReg(byte index, byte value, EmuTime::param time);
100 
107  byte peekCmdReg(byte index);
108 
114  void updateDisplayMode(DisplayMode mode, bool cmdBit, EmuTime::param time);
115 
118  template<typename Archive>
119  void serialize(Archive& ar, unsigned version);
120 
121 private:
122  void executeCommand(EmuTime::param time);
123 
124  void calcFinishTime(unsigned NX, unsigned NY, unsigned ticksPerPixel);
125 
126  void startAbrt(EmuTime::param time);
127  void startPoint(EmuTime::param time);
128  void startPset(EmuTime::param time);
129  void startSrch(EmuTime::param time);
130  void startLine(EmuTime::param time);
131  template<typename Mode> void startLmmv(EmuTime::param time);
132  template<typename Mode> void startLmmm(EmuTime::param time);
133  template<typename Mode> void startLmcm(EmuTime::param time);
134  template<typename Mode> void startLmmc(EmuTime::param time);
135  template<typename Mode> void startHmmv(EmuTime::param time);
136  template<typename Mode> void startHmmm(EmuTime::param time);
137  template<typename Mode> void startYmmm(EmuTime::param time);
138  template<typename Mode> void startHmmc(EmuTime::param time);
139 
140  template<typename Mode> void executePoint(EmuTime::param limit);
141  template<typename Mode, typename LogOp> void executePset(EmuTime::param limit);
142  template<typename Mode> void executeSrch(EmuTime::param limit);
143  template<typename Mode, typename LogOp> void executeLine(EmuTime::param limit);
144  template<typename Mode, typename LogOp> void executeLmmv(EmuTime::param limit);
145  template<typename Mode, typename LogOp> void executeLmmm(EmuTime::param limit);
146  template<typename Mode> void executeLmcm(EmuTime::param limit);
147  template<typename Mode, typename LogOp> void executeLmmc(EmuTime::param limit);
148  template<typename Mode> void executeHmmv(EmuTime::param limit);
149  template<typename Mode> void executeHmmm(EmuTime::param limit);
150  template<typename Mode> void executeYmmm(EmuTime::param limit);
151  template<typename Mode> void executeHmmc(EmuTime::param limit);
152 
153  // Advance to the next access slot at or past the given time.
154  inline void nextAccessSlot(EmuTime::param time) {
155  engineTime = vdp.getAccessSlot(time, VDPAccessSlots::DELTA_0);
156  }
157  // Advance to the next access slot that is at least 'delta' cycles past
158  // the current one.
159  inline void nextAccessSlot(VDPAccessSlots::Delta delta) {
160  engineTime = vdp.getAccessSlot(engineTime, delta);
161  }
162  inline VDPAccessSlots::Calculator getSlotCalculator(
163  EmuTime::param limit) const {
164  return vdp.getAccessSlotCalculator(engineTime, limit);
165  }
166 
169  void commandDone(EmuTime::param time);
170 
173  void reportVdpCommand();
174 
175 
178  VDP& vdp;
179  VDPVRAM& vram;
180 
183  BooleanSetting cmdTraceSetting;
184  TclCallback cmdInProgressCallback;
185 
189  EmuTime engineTime;
190 
196  EmuTime statusChangeTime;
197 
201  int phase;
202 
208  int scrMode;
209 
212  unsigned SX, SY, DX, DY, NX, NY; // registers that can be set by CPU
213  unsigned ASX, ADX, ANX; // Temporary registers used in the VDP commands
214  // Register ASX can be read (via status register 8/9)
215  byte COL, ARG, CMD;
216 
219  byte tmpSrc;
220  byte tmpDst;
221 
228  byte status;
229 
233  bool transfer;
234 
237  const bool hasExtendedVRAM;
238 };
240 
241 } // namespace openmsx
242 
243 #endif
void sync2(EmuTime::param time)
void stealAccessSlot(EmuTime::param time)
Steal a VRAM access slot from the CmdEngine.
Definition: VDPCmdEngine.hh:45
VDP command engine by Alex Wulms.
Definition: VDPCmdEngine.hh:21
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
Represents a VDP display mode.
Definition: DisplayMode.hh:14
VDPAccessSlots::Calculator getAccessSlotCalculator(EmuTime::param time, EmuTime::param limit) const
Same as getAccessSlot(), but it can be much faster for repeated calls, e.g.
Definition: VDP.cc:846
void serialize(Archive &ar, unsigned version)
Interface for logical operations.
EmuTime getAccessSlot(EmuTime::param time, VDPAccessSlots::Delta delta) const
Get the earliest access slot that is at least &#39;delta&#39; cycles in the future.
Definition: VDP.cc:840
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
byte getStatus(EmuTime::param time)
Gets the command engine status (part of S#2).
Definition: VDPCmdEngine.hh:58
VDPCmdEngine(VDP &vdp, CommandController &commandController)
void sync(EmuTime::param time)
Synchronises the command engine with the VDP.
Definition: VDPCmdEngine.hh:36
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
byte peekCmdReg(byte index)
Read the content of a command register.
void reset(EmuTime::param time)
Reinitialise Renderer state.
byte readColor(EmuTime::param time)
Use this method to transfer pixel(s) from VDP to CPU.
Definition: VDPCmdEngine.hh:70
VDP-VRAM access slot calculator, meant to be used in the inner loops of the VDPCmdEngine commands...
Unified implementation of MSX Video Display Processors (VDPs).
Definition: VDP.hh:61
void updateDisplayMode(DisplayMode mode, bool cmdBit, EmuTime::param time)
Informs the command engine of a VDP display mode change.
void setCmdReg(byte index, byte value, EmuTime::param time)
Writes to a command register.
Manages VRAM contents and synchronises the various users of the VRAM.
Definition: VDPVRAM.hh:384
unsigned getBorderX(EmuTime::param time)
Gets the X coordinate of a border detected by SRCH (intended behaviour, as documented in the V9938 te...
Definition: VDPCmdEngine.hh:89