MSXPrinterPort.cc 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include "MSXPrinterPort.hh"
  2. #include "DummyPrinterPortDevice.hh"
  3. #include "checked_cast.hh"
  4. #include "outer.hh"
  5. #include "serialize.hh"
  6. #include "unreachable.hh"
  7. #include <memory>
  8. using std::string;
  9. namespace openmsx {
  10. MSXPrinterPort::MSXPrinterPort(const DeviceConfig& config)
  11. : MSXDevice(config)
  12. , Connector(MSXDevice::getPluggingController(), "printerport",
  13. std::make_unique<DummyPrinterPortDevice>())
  14. , debuggable(getMotherBoard(), MSXDevice::getName())
  15. {
  16. data = 255; // != 0;
  17. strobe = false; // != true;
  18. reset(getCurrentTime());
  19. }
  20. void MSXPrinterPort::reset(EmuTime::param time)
  21. {
  22. writeData(0, time); // TODO check this
  23. setStrobe(true, time); // TODO check this
  24. }
  25. byte MSXPrinterPort::readIO(word port, EmuTime::param time)
  26. {
  27. return peekIO(port, time);
  28. }
  29. byte MSXPrinterPort::peekIO(word /*port*/, EmuTime::param time) const
  30. {
  31. // bit 1 = status / other bits always 1
  32. return getPluggedPrintDev().getStatus(time)
  33. ? 0xFF : 0xFD;
  34. }
  35. void MSXPrinterPort::writeIO(word port, byte value, EmuTime::param time)
  36. {
  37. switch (port & 0x01) {
  38. case 0:
  39. setStrobe(value & 1, time); // bit 0 = strobe
  40. break;
  41. case 1:
  42. writeData(value, time);
  43. break;
  44. default:
  45. UNREACHABLE;
  46. }
  47. }
  48. void MSXPrinterPort::setStrobe(bool newStrobe, EmuTime::param time)
  49. {
  50. if (newStrobe != strobe) {
  51. strobe = newStrobe;
  52. getPluggedPrintDev().setStrobe(strobe, time);
  53. }
  54. }
  55. void MSXPrinterPort::writeData(byte newData, EmuTime::param time)
  56. {
  57. if (newData != data) {
  58. data = newData;
  59. getPluggedPrintDev().writeData(data, time);
  60. }
  61. }
  62. const string MSXPrinterPort::getDescription() const
  63. {
  64. return "MSX Printer port";
  65. }
  66. string_view MSXPrinterPort::getClass() const
  67. {
  68. return "Printer Port";
  69. }
  70. void MSXPrinterPort::plug(Pluggable& dev, EmuTime::param time)
  71. {
  72. Connector::plug(dev, time);
  73. getPluggedPrintDev().writeData(data, time);
  74. getPluggedPrintDev().setStrobe(strobe, time);
  75. }
  76. PrinterPortDevice& MSXPrinterPort::getPluggedPrintDev() const
  77. {
  78. return *checked_cast<PrinterPortDevice*>(&getPlugged());
  79. }
  80. MSXPrinterPort::Debuggable::Debuggable(MSXMotherBoard& motherBoard_, const std::string& name_)
  81. : SimpleDebuggable(motherBoard_, name_, "Printer Port", 2)
  82. {
  83. }
  84. byte MSXPrinterPort::Debuggable::read(unsigned address)
  85. {
  86. auto& pport = OUTER(MSXPrinterPort, debuggable);
  87. return (address == 0) ? pport.strobe : pport.data;
  88. }
  89. void MSXPrinterPort::Debuggable::write(unsigned address, byte value)
  90. {
  91. auto& pport = OUTER(MSXPrinterPort, debuggable);
  92. pport.writeIO(address, value, pport.getCurrentTime());
  93. }
  94. template<typename Archive>
  95. void MSXPrinterPort::serialize(Archive& ar, unsigned /*version*/)
  96. {
  97. ar.template serializeBase<MSXDevice>(*this);
  98. ar.template serializeBase<Connector>(*this);
  99. ar.serialize("strobe", strobe);
  100. ar.serialize("data", data);
  101. // TODO force writing data to port??
  102. }
  103. INSTANTIATE_SERIALIZE_METHODS(MSXPrinterPort);
  104. REGISTER_MSXDEVICE(MSXPrinterPort, "PrinterPort");
  105. } // namespace openmsx