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 <cassert>
7 
8 namespace openmsx {
9 
11  : MSXDevice(config)
12  , cpu(getCPU()) // used frequently, so cache it
13  , lastTime(EmuTime::zero())
14 {
15  for (int port = 0x098; port <= 0x9B; ++port) {
16  getInDevicePtr (port) = &cpuInterface.getDummyDevice();
17  getOutDevicePtr(port) = &cpuInterface.getDummyDevice();
18  }
19 }
20 
21 const MSXDevice& VDPIODelay::getInDevice(byte port) const
22 {
23  assert((0x98 <= port) && (port <= 0x9B));
24  return *inDevices[port - 0x98];
25 }
26 
28 {
29  assert((0x98 <= port) && (port <= 0x9B));
30  return inDevices[port - 0x98];
31 }
32 
34 {
35  assert((0x98 <= port) && (port <= 0x9B));
36  return outDevices[port - 0x98];
37 }
38 
39 byte VDPIODelay::readIO(word port, EmuTime::param time)
40 {
41  delay(time);
42  return getInDevicePtr(byte(port))->readIO(byte(port), lastTime.getTime());
43 }
44 
45 byte VDPIODelay::peekIO(word port, EmuTime::param time) const
46 {
47  return getInDevice(byte(port)).peekIO(byte(port), time);
48 }
49 
50 void VDPIODelay::writeIO(word port, byte value, EmuTime::param time)
51 {
52  delay(time);
53  getOutDevicePtr(byte(port))->writeIO(byte(port), value, lastTime.getTime());
54 }
55 
56 void VDPIODelay::delay(EmuTime::param time)
57 {
58  if (cpu.isR800Active()) {
59  // Number of cycles based on measurements on real HW.
60  // See doc/turbor-vdp-io-timing.ods for details.
61  lastTime += 62; // 8us
62  if (time < lastTime.getTime()) {
63  cpu.wait(lastTime.getTime());
64  return;
65  }
66  }
67  lastTime.advance(time);
68 }
69 
70 template<typename Archive>
71 void VDPIODelay::serialize(Archive& ar, unsigned /*version*/)
72 {
73  ar.serialize("lastTime", lastTime);
74 }
76 
77 } // namespace openmsx
openmsx::MSXDevice
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition: MSXDevice.hh:31
openmsx::Clock::getTime
constexpr EmuTime::param getTime() const
Gets the time at which the last clock tick occurred.
Definition: Clock.hh:46
openmsx::VDPIODelay::getOutDevicePtr
MSXDevice *& getOutDevicePtr(byte port)
Definition: VDPIODelay.cc:33
openmsx::MSXDevice::writeIO
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:412
serialize.hh
DummyDevice.hh
VDPIODelay.hh
openmsx::VDPIODelay::getInDevice
const MSXDevice & getInDevice(byte port) const
Definition: VDPIODelay.cc:21
openmsx::DeviceConfig
Definition: DeviceConfig.hh:19
MSXCPU.hh
openmsx::VDPIODelay::writeIO
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:50
openmsx::MSXCPU::wait
void wait(EmuTime::param time)
Definition: MSXCPU.cc:307
openmsx::VDPIODelay::VDPIODelay
VDPIODelay(const DeviceConfig &config, MSXCPUInterface &cpuInterface)
Definition: VDPIODelay.cc:10
openmsx::VDPIODelay::peekIO
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
Definition: VDPIODelay.cc:45
openmsx::MSXCPUInterface
Definition: MSXCPUInterface.hh:63
openmsx::VDPIODelay::getInDevicePtr
MSXDevice *& getInDevicePtr(byte port)
Definition: VDPIODelay.cc:27
INSTANTIATE_SERIALIZE_METHODS
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:981
openmsx::VDPIODelay::readIO
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:39
openmsx::VDPIODelay
Definition: VDPIODelay.hh:12
openmsx::MSXCPUInterface::getDummyDevice
DummyDevice & getDummyDevice()
Definition: MSXCPUInterface.hh:251
openmsx::MSXDevice::readIO
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:406
openmsx::Clock::advance
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
openmsx::word
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
MSXCPUInterface.hh
openmsx::MSXCPU::isR800Active
bool isR800Active() const
Is the R800 currently active?
Definition: MSXCPU.hh:124
openmsx::VDPIODelay::serialize
void serialize(Archive &ar, unsigned version)
Definition: VDPIODelay.cc:71
openmsx::MSXDevice::peekIO
virtual byte peekIO(word port, EmuTime::param time) const
Read a byte from a given IO port.
Definition: MSXDevice.cc:417
openmsx
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5