openMSX
MSXPrinterPort.cc
Go to the documentation of this file.
1#include "MSXPrinterPort.hh"
3#include "checked_cast.hh"
4#include "narrow.hh"
5#include "outer.hh"
6#include "serialize.hh"
7#include "unreachable.hh"
8#include <cstdint>
9#include <memory>
10
11namespace openmsx {
12
14 : MSXDevice(config)
15 , Connector(MSXDevice::getPluggingController(), "printerport",
16 std::make_unique<DummyPrinterPortDevice>())
17 , debuggable(getMotherBoard(), MSXDevice::getName())
18 , writePortMask(config.getChildDataAsBool("bidirectional", false) ? 0x03 : 0x01)
19 , readPortMask(config.getChildDataAsBool("status_readable_on_all_ports", false) ? 0 : writePortMask)
20 , unusedBits(uint8_t(config.getChildDataAsInt("unused_bits", 0xFF))) // TODO: some machines use the port number as unused bits (e.g. lintweaker's Sanyo PHC-23)
21{
23}
24
25void MSXPrinterPort::reset(EmuTime::param time)
26{
27 writeData(0, time); // TODO check this
28 setStrobe(true, time); // TODO check this
29}
30
31uint8_t MSXPrinterPort::readIO(uint16_t port, EmuTime::param time)
32{
33 return peekIO(port, time);
34}
35
36uint8_t MSXPrinterPort::peekIO(uint16_t port, EmuTime::param time) const
37{
38 bool showStatus = (port & readPortMask) == 0;
39 if (!showStatus) return 0xFF;
40 // bit 1 = status / other bits depend on something unknown, specified
41 // in the XML file
42 return getPluggedPrintDev().getStatus(time)
43 ? (unusedBits | 0b10) : (unusedBits & ~0b10);
44}
45
46void MSXPrinterPort::writeIO(uint16_t port, uint8_t value, EmuTime::param time)
47{
48 switch (port & writePortMask) {
49 case 0:
50 setStrobe(value & 1, time); // bit 0 = strobe
51 break;
52 case 1:
53 writeData(value, time);
54 break;
55 case 2: // nothing here
56 break;
57 case 3: // 0x93 PDIR (BiDi) is not implemented.
58 break;
59 default:
61 }
62}
63
64void MSXPrinterPort::setStrobe(bool newStrobe, EmuTime::param time)
65{
66 if (newStrobe != strobe) {
67 strobe = newStrobe;
68 getPluggedPrintDev().setStrobe(strobe, time);
69 }
70}
71void MSXPrinterPort::writeData(uint8_t newData, EmuTime::param time)
72{
73 if (newData != data) {
74 data = newData;
75 getPluggedPrintDev().writeData(data, time);
76 }
77}
78
79std::string_view MSXPrinterPort::getDescription() const
80{
81 return "MSX Printer port";
82}
83
84std::string_view MSXPrinterPort::getClass() const
85{
86 return "Printer Port";
87}
88
89void MSXPrinterPort::plug(Pluggable& dev, EmuTime::param time)
90{
91 Connector::plug(dev, time);
92 getPluggedPrintDev().writeData(data, time);
93 getPluggedPrintDev().setStrobe(strobe, time);
94}
95
96PrinterPortDevice& MSXPrinterPort::getPluggedPrintDev() const
97{
98 return *checked_cast<PrinterPortDevice*>(&getPlugged());
99}
100
101
102MSXPrinterPort::Debuggable::Debuggable(MSXMotherBoard& motherBoard_, const std::string& name_)
103 : SimpleDebuggable(motherBoard_, name_, "Printer Port", 2)
104{
105}
106
107uint8_t MSXPrinterPort::Debuggable::read(unsigned address)
108{
109 auto& pPort = OUTER(MSXPrinterPort, debuggable);
110 return (address == 0) ? pPort.strobe : pPort.data;
111}
112
113void MSXPrinterPort::Debuggable::write(unsigned address, uint8_t value)
114{
115 auto& pPort = OUTER(MSXPrinterPort, debuggable);
116 pPort.writeIO(narrow<uint16_t>(address), value, pPort.getCurrentTime());
117}
118
119
120template<typename Archive>
121void MSXPrinterPort::serialize(Archive& ar, unsigned /*version*/)
122{
123 ar.template serializeBase<MSXDevice>(*this);
124 ar.template serializeBase<Connector>(*this);
125 ar.serialize("strobe", strobe,
126 "data", data);
127 // TODO force writing data to port??
128}
131
132} // namespace openmsx
#define REGISTER_MSXDEVICE(CLASS, NAME)
Definition MSXDevice.hh:354
Represents something you can plug devices into.
Definition Connector.hh:21
Pluggable & getPlugged() const
Returns the Pluggable currently plugged in.
Definition Connector.hh:59
virtual void plug(Pluggable &device, EmuTime::param time)
This plugs a Pluggable in this Connector.
Definition Connector.cc:25
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition MSXDevice.hh:36
EmuTime::param getCurrentTime() const
Definition MSXDevice.cc:125
void serialize(Archive &ar, unsigned version)
std::string_view getDescription() const override
Get a description for this connector.
uint8_t readIO(uint16_t port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
MSXPrinterPort(const DeviceConfig &config)
void reset(EmuTime::param time) override
This method is called on reset.
uint8_t peekIO(uint16_t port, EmuTime::param time) const override
Read a byte from a given IO port.
void writeIO(uint16_t port, uint8_t value, EmuTime::param time) override
Write a byte to a given IO port at a certain time to this device.
std::string_view getClass() const override
A Connector belong to a certain class.
void plug(Pluggable &dev, EmuTime::param time) override
This plugs a Pluggable in this Connector.
virtual bool getStatus(EmuTime::param time)=0
Returns the STATUS signal: false = low = ready, true = high = not ready.
virtual void writeData(uint8_t data, EmuTime::param time)=0
Sets the data signals.
virtual void setStrobe(bool strobe, EmuTime::param time)=0
Sets the strobe signal: false = low, true = high.
This file implemented 3 utility functions:
Definition Autofire.cc:9
STL namespace.
#define OUTER(type, member)
Definition outer.hh:41
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
#define UNREACHABLE