OXYGENHUB
◆ main openmsx / src / cpu / VDPIODelay.cc
1.9 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#include "VDPIODelay.hh"
2
3
#include "DummyDevice.hh"
4
#include "MSXCPU.hh"
5
#include "MSXCPUInterface.hh"
6
#include "serialize.hh"
7
8
#include "xrange.hh"
9
10
#include <cassert>
11
12
namespace openmsx {
13
14
VDPIODelay::VDPIODelay(const DeviceConfig& config, MSXCPUInterface& cpuInterface)
15
	: MSXDevice(config)
16
	, cpu(getCPU()) // used frequently, so cache it
17
{
18
	for (auto port : xrange(uint8_t(0x98), uint8_t(0x9c))) {
19
		getInDevicePtr (port) = &cpuInterface.getDummyDevice();
20
		getOutDevicePtr(port) = &cpuInterface.getDummyDevice();
21
	}
22
}
23
24
const MSXDevice& VDPIODelay::getInDevice(uint8_t port) const
25
{
26
	assert((0x98 <= port) && (port <= 0x9B));
27
	return *inDevices[port - 0x98];
28
}
29
30
MSXDevice*& VDPIODelay::getInDevicePtr(uint8_t port)
31
{
32
	assert((0x98 <= port) && (port <= 0x9B));
33
	return inDevices[port - 0x98];
34
}
35
36
MSXDevice*& VDPIODelay::getOutDevicePtr(uint8_t port)
37
{
38
	assert((0x98 <= port) && (port <= 0x9B));
39
	return outDevices[port - 0x98];
40
}
41
42
uint8_t VDPIODelay::readIO(uint16_t port, EmuTime time)
43
{
44
	delay(time);
45
	return getInDevicePtr(uint8_t(port))->readIO(uint8_t(port), lastTime.getTime());
46
}
47
48
uint8_t VDPIODelay::peekIO(uint16_t port, EmuTime time) const
49
{
50
	return getInDevice(uint8_t(port)).peekIO(uint8_t(port), time);
51
}
52
53
void VDPIODelay::writeIO(uint16_t port, uint8_t value, EmuTime time)
54
{
55
	delay(time);
56
	getOutDevicePtr(uint8_t(port))->writeIO(uint8_t(port), value, lastTime.getTime());
57
}
58
59
void VDPIODelay::delay(EmuTime time)
60
{
61
	if (cpu.isR800Active()) {
62
		// Number of cycles based on measurements on real HW.
63
		// See doc/turbor-vdp-io-timing.ods for details.
64
		lastTime += 62; // 8us
65
		if (time < lastTime.getTime()) {
66
			cpu.wait(lastTime.getTime());
67
			return;
68
		}
69
	}
70
	lastTime.advance(time);
71
}
72
73
template<typename Archive>
74
void VDPIODelay::serialize(Archive& ar, unsigned /*version*/)
75
{
76
	ar.serialize("lastTime", lastTime);
77
}
78
INSTANTIATE_SERIALIZE_METHODS(VDPIODelay);
79
80
} // namespace openmsx