OXYGENHUB
◆ main openmsx / src / SVIPrinterPort.cc
2.4 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#include "SVIPrinterPort.hh"
2
3
#include "DummyPrinterPortDevice.hh"
4
#include "serialize.hh"
5
6
#include "checked_cast.hh"
7
8
#include "unreachable.hh"
9
10
#include <memory>
11
12
// Centronics interface
13
//
14
// DAT0-DAT7   Printer data write port, output (10H)
15
// /STB        Printer strobe port,     output (11H)
16
// BUSY        Printer status port,     input  (12H)
17
18
namespace openmsx {
19
20
SVIPrinterPort::SVIPrinterPort(const DeviceConfig& config)
21
	: MSXDevice(config)
22
	, Connector(MSXDevice::getPluggingController(), "printerport",
23
	            std::make_unique<DummyPrinterPortDevice>())
24
{
25
	reset(getCurrentTime());
26
}
27
28
void SVIPrinterPort::reset(EmuTime time)
29
{
30
	writeData(0, time);    // TODO check this
31
	setStrobe(true, time); // TODO check this
32
}
33
34
uint8_t SVIPrinterPort::readIO(uint16_t port, EmuTime time)
35
{
36
	return peekIO(port, time);
37
}
38
39
uint8_t SVIPrinterPort::peekIO(uint16_t /*port*/, EmuTime time) const
40
{
41
	// bit 1 = status / other bits always 1
42
	return getPluggedPrintDev().getStatus(time) ? 0xFF : 0xFE;
43
}
44
45
void SVIPrinterPort::writeIO(uint16_t port, uint8_t value, EmuTime time)
46
{
47
	switch (port & 0x01) {
48
	case 0:
49
		writeData(value, time);
50
		break;
51
	case 1:
52
		setStrobe(value & 1, time); // bit 0 = strobe
53
		break;
54
	default:
55
		UNREACHABLE;
56
	}
57
}
58
59
void SVIPrinterPort::setStrobe(bool newStrobe, EmuTime time)
60
{
61
	if (newStrobe != strobe) {
62
		strobe = newStrobe;
63
		getPluggedPrintDev().setStrobe(strobe, time);
64
	}
65
}
66
void SVIPrinterPort::writeData(uint8_t newData, EmuTime time)
67
{
68
	if (newData != data) {
69
		data = newData;
70
		getPluggedPrintDev().writeData(data, time);
71
	}
72
}
73
74
zstring_view SVIPrinterPort::getDescription() const
75
{
76
	return "Spectravideo SVI-328 Printer port";
77
}
78
79
zstring_view SVIPrinterPort::getClass() const
80
{
81
	return "Printer Port";
82
}
83
84
void SVIPrinterPort::plug(Pluggable& dev, EmuTime time)
85
{
86
	Connector::plug(dev, time);
87
	getPluggedPrintDev().writeData(data, time);
88
	getPluggedPrintDev().setStrobe(strobe, time);
89
}
90
91
PrinterPortDevice& SVIPrinterPort::getPluggedPrintDev() const
92
{
93
	return *checked_cast<PrinterPortDevice*>(&getPlugged());
94
}
95
96
template<typename Archive>
97
void SVIPrinterPort::serialize(Archive& ar, unsigned /*version*/)
98
{
99
	ar.template serializeBase<MSXDevice>(*this);
100
	ar.template serializeBase<Connector>(*this);
101
	ar.serialize("strobe", strobe,
102
	             "data",   data);
103
	// TODO force writing data to port??
104
}
105
INSTANTIATE_SERIALIZE_METHODS(SVIPrinterPort);
106
REGISTER_MSXDEVICE(SVIPrinterPort, "SVI-328 PrinterPort");
107
108
} // namespace openmsx