OXYGENHUB
◆ main openmsx / src / cassette / CassettePort.cc
3.3 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#include "CassettePort.hh"
2
3
#include "CassetteDevice.hh"
4
#include "CassettePlayer.hh"
5
#include "DummyCassetteDevice.hh"
6
7
#include "HardwareConfig.hh"
8
#include "MSXMotherBoard.hh"
9
#include "PluggingController.hh"
10
#include "serialize.hh"
11
12
#include "checked_cast.hh"
13
14
#include "components.hh"
15
#if COMPONENT_LASERDISC
16
#include "LaserdiscPlayer.hh"
17
#endif
18
19
#include <memory>
20
21
namespace openmsx {
22
23
// DummyCassettePort
24
25
DummyCassettePort::DummyCassettePort(MSXMotherBoard& motherBoard)
26
	: cassettePlayerCommand(
27
		nullptr,
28
		motherBoard.getCommandController(),
29
		motherBoard.getStateChangeDistributor(),
30
		motherBoard.getScheduler())
31
{
32
}
33
34
void DummyCassettePort::setMotor(bool /*status*/, EmuTime /*time*/)
35
{
36
	// do nothing
37
}
38
void DummyCassettePort::cassetteOut(bool /*output*/, EmuTime /*time*/)
39
{
40
	// do nothing
41
}
42
bool DummyCassettePort::cassetteIn(EmuTime /*time*/)
43
{
44
	return false;
45
}
46
bool DummyCassettePort::lastOut() const
47
{
48
	return false; // not relevant
49
}
50
#if COMPONENT_LASERDISC
51
void DummyCassettePort::setLaserdiscPlayer(LaserdiscPlayer* /* laserdisc */)
52
{
53
	// do nothing
54
}
55
#endif
56
57
58
// CassettePort
59
60
CassettePort::CassettePort(HardwareConfig& hwConf)
61
	: Connector(hwConf.getMotherBoard().getPluggingController(), "cassetteport",
62
	            std::make_unique<DummyCassetteDevice>())
63
	, motherBoard(hwConf.getMotherBoard())
64
{
65
	auto player = std::make_unique<CassettePlayer>(hwConf);
66
	cassettePlayer = player.get();
67
	getPluggingController().registerPluggable(std::move(player));
68
}
69
70
CassettePort::~CassettePort()
71
{
72
	unplug(motherBoard.getCurrentTime());
73
}
74
75
76
void CassettePort::setMotor(bool status, EmuTime time)
77
{
78
	// TODO make 'click' sound
79
	motorControl = status;
80
	getPluggedCasDev().setMotor(status, time);
81
}
82
83
void CassettePort::cassetteOut(bool output, EmuTime time)
84
{
85
	lastOutput = output;
86
	// leave everything to the pluggable
87
	getPluggedCasDev().setSignal(output, time);
88
}
89
90
bool CassettePort::lastOut() const
91
{
92
	return lastOutput;
93
}
94
95
bool CassettePort::cassetteIn(EmuTime time)
96
{
97
	// All analog filtering is ignored for now
98
	//   only important component is DC-removal
99
	//   we just assume sample has no DC component
100
	int16_t sample = [&]{
101
	#if COMPONENT_LASERDISC
102
		if (!motorControl && laserdiscPlayer) {
103
			return laserdiscPlayer->readSample(time);
104
		}
105
	#endif
106
		return getPluggedCasDev().readSample(time); // read 1 sample
107
	}();
108
	return sample >= 0; // comparator
109
}
110
111
#if COMPONENT_LASERDISC
112
void CassettePort::setLaserdiscPlayer(LaserdiscPlayer *laserdiscPlayer_)
113
{
114
	laserdiscPlayer = laserdiscPlayer_;
115
}
116
#endif
117
118
zstring_view CassettePort::getDescription() const
119
{
120
	return "MSX Cassette port";
121
}
122
123
zstring_view CassettePort::getClass() const
124
{
125
	return "Cassette Port";
126
}
127
128
CassetteDevice& CassettePort::getPluggedCasDev() const
129
{
130
	return *checked_cast<CassetteDevice*>(&getPlugged());
131
}
132
133
template<typename Archive>
134
void CassettePort::serialize(Archive& ar, unsigned version)
135
{
136
	ar.template serializeBase<Connector>(*this);
137
	// don't serialize 'lastOutput', done via MSXPPI
138
139
	// Must come after serialization of the connector because that one
140
	// potentially serializes the CassettePlayer.
141
	if (ar.versionAtLeast(version, 2)) {
142
		// always serialize CassettePlayer, even if it's not plugged in.
143
		ar.serializeOnlyOnce("cassettePlayer", *cassettePlayer);
144
	}
145
}
146
INSTANTIATE_SERIALIZE_METHODS(CassettePort);
147
148
} // namespace openmsx