26 , i8254(getScheduler(), &cntr0, &cntr1, nullptr, getCurrentTime())
27 , i8251(getScheduler(), interface, getCurrentTime())
28 , rom(config.findChild(
"rom")
30 MSXDevice::getName() +
" ROM",
"rom", config)
32 , ram(config.getChildDataAsBool(
"ram", false)
37 , rxrdyIRQ(getMotherBoard(),
MSXDevice::getName() +
".IRQrxrdy")
38 , hasMemoryBasedIo(config.getChildDataAsBool(
"memorybasedio", false))
39 , hasRIPin(config.getChildDataAsBool(
"has_ri_pin", true))
40 , inputsPullup(config.getChildDataAsBool(
"rs232_pullup",false))
41 , ioAccessEnabled(!hasMemoryBasedIo)
42 , switchSetting(config.getChildDataAsBool(
"toshiba_rs232c_switch",
44 "toshiba_rs232c_switch",
"status of the RS-232C enable switch",
47 if (rom && (rom->size() !=
one_of(0x2000u, 0x4000u))) {
48 throw MSXException(
"RS232C only supports 8kB or 16kB ROMs.");
65 if (ram) ram->clear();
71 rxrdyIRQlatch =
false;
72 rxrdyIRQenabled =
false;
75 ioAccessEnabled = !hasMemoryBasedIo;
77 if (ram) ram->clear();
82 if (hasMemoryBasedIo && (0xBFF8 <= address) && (address <= 0xBFFF)) {
83 return readIOImpl(address & 0x07, time);
85 word addr = address & 0x3FFF;
88 }
else if (rom && (0x4000 <= address) && (address < 0x8000)) {
89 return (*rom)[addr & (rom->size() - 1)];
100 word addr = start & 0x3FFF;
103 }
else if (rom && (0x4000 <= start) && (start < 0x8000)) {
104 return &(*rom)[addr & (rom->size() - 1)];
113 if (hasMemoryBasedIo && (0xBFF8 <= address) && (address <= 0xBFFF)) {
119 if (address == 0xBFFA) {
120 ioAccessEnabled = (value & (1 << 4))!=0;
122 return writeIOImpl(address & 0x07, value, time);
124 word addr = address & 0x3FFF;
135 word addr = start & 0x3FFF;
151 if (ioAccessEnabled) {
152 return readIOImpl(port & 0x07, time);
157byte MSXRS232::readIOImpl(
word port, EmuTime::param time)
162 return i8251.
readIO(port, time);
164 return readStatus(time);
171 return i8254.
readIO(port - 4, time);
179 if (hasMemoryBasedIo && !ioAccessEnabled)
return 0xFF;
184 return i8251.
peekIO(port, time);
193 return i8254.
peekIO(port - 4, time);
201 if (ioAccessEnabled) writeIOImpl(port & 0x07, value, time);
204void MSXRS232::writeIOImpl(
word port,
byte value, EmuTime::param time)
209 i8251.
writeIO(port, value, time);
220 i8254.
writeIO(port - 4, value, time);
225byte MSXRS232::readStatus(EmuTime::param time)
248 if (dev.getDCD(time).value_or(inputsPullup)) result &= ~0x01;
249 if (hasRIPin && (dev.getRI(time).value_or(inputsPullup))) result &= ~0x02;
250 if (rxrdyIRQenabled && switchSetting && switchSetting->getBoolean()) result &= ~0x08;
252 if (interface.getCTS(time)) result &= ~0x80;
257void MSXRS232::setIRQMask(
byte value)
259 enableRxRDYIRQ(!(value & 1));
262void MSXRS232::setRxRDYIRQ(
bool status)
264 if (rxrdyIRQlatch != status) {
265 rxrdyIRQlatch = status;
266 if (rxrdyIRQenabled) {
276void MSXRS232::enableRxRDYIRQ(
bool enabled)
278 if (rxrdyIRQenabled != enabled) {
279 rxrdyIRQenabled = enabled;
280 if (!rxrdyIRQenabled && rxrdyIRQlatch) {
289void MSXRS232::Interface::setRxRDY(
bool status, EmuTime::param )
291 auto& rs232 =
OUTER(MSXRS232, interface);
292 rs232.setRxRDYIRQ(status);
295void MSXRS232::Interface::setDTR(
bool status, EmuTime::param time)
297 const auto& rs232 =
OUTER(MSXRS232, interface);
298 rs232.getPluggedRS232Dev().setDTR(status, time);
301void MSXRS232::Interface::setRTS(
bool status, EmuTime::param time)
303 const auto& rs232 =
OUTER(MSXRS232, interface);
304 rs232.getPluggedRS232Dev().setRTS(status, time);
307bool MSXRS232::Interface::getDSR(EmuTime::param time)
309 const auto& rs232 =
OUTER(MSXRS232, interface);
310 return rs232.getPluggedRS232Dev().getDSR(time).value_or(rs232.inputsPullup);
313bool MSXRS232::Interface::getCTS(EmuTime::param time)
315 const auto& rs232 =
OUTER(MSXRS232, interface);
316 return rs232.getPluggedRS232Dev().getCTS(time).value_or(rs232.inputsPullup);
319void MSXRS232::Interface::setDataBits(DataBits bits)
321 const auto& rs232 =
OUTER(MSXRS232, interface);
322 rs232.getPluggedRS232Dev().setDataBits(bits);
325void MSXRS232::Interface::setStopBits(StopBits bits)
327 const auto& rs232 =
OUTER(MSXRS232, interface);
328 rs232.getPluggedRS232Dev().setStopBits(bits);
331void MSXRS232::Interface::setParityBit(
bool enable, Parity parity)
333 const auto& rs232 =
OUTER(MSXRS232, interface);
334 rs232.getPluggedRS232Dev().setParityBit(enable, parity);
337void MSXRS232::Interface::recvByte(
byte value, EmuTime::param time)
339 const auto& rs232 =
OUTER(MSXRS232, interface);
340 rs232.getPluggedRS232Dev().recvByte(value, time);
343void MSXRS232::Interface::signal(EmuTime::param time)
345 const auto& rs232 =
OUTER(MSXRS232, interface);
346 rs232.getPluggedRS232Dev().signal(time);
352void MSXRS232::Counter0::signal(ClockPin& pin, EmuTime::param time)
354 auto& rs232 =
OUTER(MSXRS232, cntr0);
355 ClockPin& clk = rs232.i8251.getClockPin();
356 if (pin.isPeriodic()) {
357 clk.setPeriodicState(pin.getTotalDuration(),
358 pin.getHighDuration(), time);
360 clk.setState(pin.getState(time), time);
364void MSXRS232::Counter0::signalPosEdge(ClockPin& , EmuTime::param )
372void MSXRS232::Counter1::signal(ClockPin& pin, EmuTime::param time)
374 auto& rs232 =
OUTER(MSXRS232, cntr1);
375 ClockPin& clk = rs232.i8251.getClockPin();
376 if (pin.isPeriodic()) {
377 clk.setPeriodicState(pin.getTotalDuration(),
378 pin.getHighDuration(), time);
380 clk.setState(pin.getState(time), time);
384void MSXRS232::Counter1::signalPosEdge(ClockPin& , EmuTime::param )
425template<
typename Archive>
428 ar.template serializeBase<MSXDevice>(*
this);
429 ar.template serializeBase<RS232Connector>(*
this);
431 ar.serialize(
"I8254", i8254,
433 if (ram) ar.serialize(
"ram", *ram);
434 ar.serialize(
"rxrdyIRQ", rxrdyIRQ,
435 "rxrdyIRQlatch", rxrdyIRQlatch,
436 "rxrdyIRQenabled", rxrdyIRQenabled);
437 if (ar.versionAtLeast(version, 2)) {
438 ar.serialize(
"ioAccessEnabled", ioAccessEnabled);
440 assert(Archive::IS_LOADER);
441 ioAccessEnabled = !hasMemoryBasedIo;
#define REGISTER_MSXDEVICE(CLASS, NAME)
bool getState(EmuTime::param time) const
void setPeriodicState(EmuDuration::param total, EmuDuration::param hi, EmuTime::param time)
byte peekIO(word port, EmuTime::param time) const
void setStopBits(StopBits bits) override
void recvByte(byte value, EmuTime::param time) override
void writeIO(word port, byte value, EmuTime::param time)
void setDataBits(DataBits bits) override
byte readIO(word port, EmuTime::param time)
void setParityBit(bool enable, Parity parity) override
bool isRecvEnabled() const
uint8_t peekIO(uint16_t port, EmuTime::param time) const
void writeIO(uint16_t port, uint8_t value, EmuTime::param time)
uint8_t readIO(uint16_t port, EmuTime::param time)
ClockPin & getClockPin(unsigned cntr)
ClockPin & getOutputPin(unsigned cntr)
void set()
Set the interrupt request on the bus.
void reset()
Reset the interrupt request on the bus.
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
static std::array< byte, 0x10000 > unmappedRead
static std::array< byte, 0x10000 > unmappedWrite
EmuTime::param getCurrentTime() const
void writeIO(word port, byte value, EmuTime::param time) override
Write a byte to a given IO port at a certain time to this device.
MSXRS232(const DeviceConfig &config)
void setDataBits(DataBits bits) override
void reset(EmuTime::param time) override
This method is called on reset.
bool acceptsData() override
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
void powerUp(EmuTime::param time) override
This method is called when MSX is powered up.
const byte * getReadCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
void writeMem(word address, byte value, EmuTime::param time) override
Write a given byte to a given location at a certain time to this device.
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
byte * getWriteCacheLine(word start) override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
void setStopBits(StopBits bits) override
bool allowUnaligned() const override
By default we don't allow unaligned <mem> specifications in the config file.
void serialize(Archive &ar, unsigned version)
void setParityBit(bool enable, Parity parity) override
void recvByte(byte value, EmuTime::param time) override
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
RS232Device & getPluggedRS232Dev() const
This file implemented 3 utility functions:
const unsigned RAM_OFFSET
uint16_t word
16 bit unsigned integer
#define OUTER(type, member)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)