openMSX
VDPIODelay.cc
Go to the documentation of this file.
1 #include "VDPIODelay.hh"
2 #include "MSXCPU.hh"
3 #include "MSXCPUInterface.hh"
4 #include "DummyDevice.hh"
5 #include "serialize.hh"
6 #include "xrange.hh"
7 #include <cassert>
8 
9 namespace openmsx {
10 
12  : MSXDevice(config)
13  , cpu(getCPU()) // used frequently, so cache it
14  , lastTime(EmuTime::zero())
15 {
16  for (auto port : xrange(0x98, 0x9c)) {
17  getInDevicePtr (port) = &cpuInterface.getDummyDevice();
18  getOutDevicePtr(port) = &cpuInterface.getDummyDevice();
19  }
20 }
21 
22 const MSXDevice& VDPIODelay::getInDevice(byte port) const
23 {
24  assert((0x98 <= port) && (port <= 0x9B));
25  return *inDevices[port - 0x98];
26 }
27 
29 {
30  assert((0x98 <= port) && (port <= 0x9B));
31  return inDevices[port - 0x98];
32 }
33 
35 {
36  assert((0x98 <= port) && (port <= 0x9B));
37  return outDevices[port - 0x98];
38 }
39 
40 byte VDPIODelay::readIO(word port, EmuTime::param time)
41 {
42  delay(time);
43  return getInDevicePtr(byte(port))->readIO(byte(port), lastTime.getTime());
44 }
45 
46 byte VDPIODelay::peekIO(word port, EmuTime::param time) const
47 {
48  return getInDevice(byte(port)).peekIO(byte(port), time);
49 }
50 
51 void VDPIODelay::writeIO(word port, byte value, EmuTime::param time)
52 {
53  delay(time);
54  getOutDevicePtr(byte(port))->writeIO(byte(port), value, lastTime.getTime());
55 }
56 
57 void VDPIODelay::delay(EmuTime::param time)
58 {
59  if (cpu.isR800Active()) {
60  // Number of cycles based on measurements on real HW.
61  // See doc/turbor-vdp-io-timing.ods for details.
62  lastTime += 62; // 8us
63  if (time < lastTime.getTime()) {
64  cpu.wait(lastTime.getTime());
65  return;
66  }
67  }
68  lastTime.advance(time);
69 }
70 
71 template<typename Archive>
72 void VDPIODelay::serialize(Archive& ar, unsigned /*version*/)
73 {
74  ar.serialize("lastTime", lastTime);
75 }
77 
78 } // namespace openmsx
constexpr EmuTime::param getTime() const
Gets the time at which the last clock tick occurred.
Definition: Clock.hh:46
constexpr void advance(EmuTime::param e)
Advance this clock in time until the last tick which is not past the given time.
Definition: Clock.hh:110
DummyDevice & getDummyDevice()
bool isR800Active() const
Is the R800 currently active?
Definition: MSXCPU.hh:124
void wait(EmuTime::param time)
Definition: MSXCPU.cc:320
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition: MSXDevice.hh:32
virtual void writeIO(word port, byte value, EmuTime::param time)
Write a byte to a given IO port at a certain time to this device.
Definition: MSXDevice.cc:415
virtual byte peekIO(word port, EmuTime::param time) const
Read a byte from a given IO port.
Definition: MSXDevice.cc:420
virtual byte readIO(word port, EmuTime::param time)
Read a byte from an IO port at a certain time from this device.
Definition: MSXDevice.cc:409
void serialize(Archive &ar, unsigned version)
Definition: VDPIODelay.cc:72
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
Definition: VDPIODelay.cc:40
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
Definition: VDPIODelay.cc:46
void writeIO(word port, byte value, EmuTime::param time) override
Write a byte to a given IO port at a certain time to this device.
Definition: VDPIODelay.cc:51
const MSXDevice & getInDevice(byte port) const
Definition: VDPIODelay.cc:22
MSXDevice *& getOutDevicePtr(byte port)
Definition: VDPIODelay.cc:34
MSXDevice *& getInDevicePtr(byte port)
Definition: VDPIODelay.cc:28
VDPIODelay(const DeviceConfig &config, MSXCPUInterface &cpuInterface)
Definition: VDPIODelay.cc:11
This file implemented 3 utility functions:
Definition: Autofire.cc:5
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:983
constexpr auto xrange(T e)
Definition: xrange.hh:155