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
9namespace openmsx {
10
12 : MSXDevice(config)
13 , cpu(getCPU()) // used frequently, so cache it
14 , lastTime(EmuTime::zero())
15{
16 for (auto port : xrange(byte(0x98), byte(0x9c))) {
17 getInDevicePtr (port) = &cpuInterface.getDummyDevice();
18 getOutDevicePtr(port) = &cpuInterface.getDummyDevice();
19 }
20}
21
22const 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
40byte VDPIODelay::readIO(word port, EmuTime::param time)
41{
42 delay(time);
43 return getInDevicePtr(byte(port))->readIO(byte(port), lastTime.getTime());
44}
45
46byte VDPIODelay::peekIO(word port, EmuTime::param time) const
47{
48 return getInDevice(byte(port)).peekIO(byte(port), time);
49}
50
51void 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
57void 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
71template<typename Archive>
72void 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
bool isR800Active() const
Is the R800 currently active?
Definition MSXCPU.hh:131
void wait(EmuTime::param time)
Definition MSXCPU.cc:321
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition MSXDevice.hh:36
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:408
virtual byte peekIO(word port, EmuTime::param time) const
Read a byte from a given IO port.
Definition MSXDevice.cc:413
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:402
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:11
uint16_t word
16 bit unsigned integer
Definition openmsx.hh:29
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
constexpr auto xrange(T e)
Definition xrange.hh:132