23 , i8254(getScheduler(), &cntr0, &cntr1, nullptr, getCurrentTime())
24 , i8251(getScheduler(), interface, getCurrentTime())
25 , rom(config.findChild(
"rom")
27 MSXDevice::getName() +
" ROM",
"rom", config)
29 , ram(config.getChildDataAsBool(
"ram", false)
34 , rxrdyIRQ(getMotherBoard(),
MSXDevice::getName() +
".IRQrxrdy")
35 , hasMemoryBasedIo(config.getChildDataAsBool(
"memorybasedio", false))
36 , hasRIPin(config.getChildDataAsBool(
"has_ri_pin", true))
37 , inputsPullup(config.getChildDataAsBool(
"rs232_pullup",false))
38 , ioAccessEnabled(!hasMemoryBasedIo)
39 , switchSetting(config.getChildDataAsBool(
"toshiba_rs232c_switch",
41 "toshiba_rs232c_switch",
"status of the RS-232C enable switch",
44 if (rom && (rom->size() !=
one_of(0x2000u, 0x4000u))) {
45 throw MSXException(
"RS232C only supports 8kB or 16kB ROMs.");
62 if (ram) ram->clear();
68 rxrdyIRQlatch =
false;
69 rxrdyIRQenabled =
false;
72 ioAccessEnabled = !hasMemoryBasedIo;
74 if (ram) ram->clear();
79 if (hasMemoryBasedIo && (0xBFF8 <= address) && (address <= 0xBFFF)) {
80 return readIOImpl(address & 0x07, time);
82 word addr = address & 0x3FFF;
85 }
else if (rom && (0x4000 <= address) && (address < 0x8000)) {
86 return (*rom)[addr & (rom->size() - 1)];
97 word addr = start & 0x3FFF;
100 }
else if (rom && (0x4000 <= start) && (start < 0x8000)) {
101 return &(*rom)[addr & (rom->size() - 1)];
110 if (hasMemoryBasedIo && (0xBFF8 <= address) && (address <= 0xBFFF)) {
116 if (address == 0xBFFA) {
117 ioAccessEnabled = (value & (1 << 4))!=0;
119 return writeIOImpl(address & 0x07, value, time);
121 word addr = address & 0x3FFF;
132 word addr = start & 0x3FFF;
148 if (ioAccessEnabled) {
149 return readIOImpl(port & 0x07, time);
154byte MSXRS232::readIOImpl(
word port, EmuTime::param time)
159 return i8251.
readIO(port, time);
161 return readStatus(time);
168 return i8254.
readIO(port - 4, time);
176 if (hasMemoryBasedIo && !ioAccessEnabled)
return 0xFF;
181 return i8251.
peekIO(port, time);
190 return i8254.
peekIO(port - 4, time);
198 if (ioAccessEnabled) writeIOImpl(port & 0x07, value, time);
201void MSXRS232::writeIOImpl(
word port,
byte value, EmuTime::param time)
206 i8251.
writeIO(port, value, time);
217 i8254.
writeIO(port - 4, value, time);
222byte MSXRS232::readStatus(EmuTime::param time)
246 if (dev.getDCD(time).value_or(inputsPullup)) result &= ~0x01;
248 if (hasRIPin && (dev.getRI(time).value_or(inputsPullup))) result &= ~0x02;
250 if (rxrdyIRQenabled && switchSetting && switchSetting->getBoolean()) result &= ~0x08;
254 if (interface.getCTS(time)) result &= ~0x80;
259void MSXRS232::setIRQMask(
byte value)
261 enableRxRDYIRQ(!(value & 1));
264void MSXRS232::setRxRDYIRQ(
bool status)
266 if (rxrdyIRQlatch != status) {
267 rxrdyIRQlatch = status;
268 if (rxrdyIRQenabled) {
278void MSXRS232::enableRxRDYIRQ(
bool enabled)
280 if (rxrdyIRQenabled != enabled) {
281 rxrdyIRQenabled = enabled;
282 if (!rxrdyIRQenabled && rxrdyIRQlatch) {
291void MSXRS232::Interface::setRxRDY(
bool status, EmuTime::param )
293 auto& rs232 =
OUTER(MSXRS232, interface);
294 rs232.setRxRDYIRQ(status);
297void MSXRS232::Interface::setDTR(
bool status, EmuTime::param time)
299 auto& rs232 =
OUTER(MSXRS232, interface);
300 rs232.getPluggedRS232Dev().setDTR(status, time);
303void MSXRS232::Interface::setRTS(
bool status, EmuTime::param time)
305 auto& rs232 =
OUTER(MSXRS232, interface);
306 rs232.getPluggedRS232Dev().setRTS(status, time);
309bool MSXRS232::Interface::getDSR(EmuTime::param time)
311 auto& rs232 =
OUTER(MSXRS232, interface);
312 return rs232.getPluggedRS232Dev().getDSR(time).value_or(rs232.inputsPullup);
315bool MSXRS232::Interface::getCTS(EmuTime::param time)
317 auto& rs232 =
OUTER(MSXRS232, interface);
318 return rs232.getPluggedRS232Dev().getCTS(time).value_or(rs232.inputsPullup);
321void MSXRS232::Interface::setDataBits(DataBits bits)
323 auto& rs232 =
OUTER(MSXRS232, interface);
324 rs232.getPluggedRS232Dev().setDataBits(bits);
327void MSXRS232::Interface::setStopBits(StopBits bits)
329 auto& rs232 =
OUTER(MSXRS232, interface);
330 rs232.getPluggedRS232Dev().setStopBits(bits);
333void MSXRS232::Interface::setParityBit(
bool enable, ParityBit parity)
335 auto& rs232 =
OUTER(MSXRS232, interface);
336 rs232.getPluggedRS232Dev().setParityBit(enable, parity);
339void MSXRS232::Interface::recvByte(
byte value, EmuTime::param time)
341 auto& rs232 =
OUTER(MSXRS232, interface);
342 rs232.getPluggedRS232Dev().recvByte(value, time);
345void MSXRS232::Interface::signal(EmuTime::param time)
347 auto& rs232 =
OUTER(MSXRS232, interface);
348 rs232.getPluggedRS232Dev().signal(time);
354void MSXRS232::Counter0::signal(ClockPin& pin, EmuTime::param time)
356 auto& rs232 =
OUTER(MSXRS232, cntr0);
357 ClockPin& clk = rs232.i8251.getClockPin();
358 if (pin.isPeriodic()) {
359 clk.setPeriodicState(pin.getTotalDuration(),
360 pin.getHighDuration(), time);
362 clk.setState(pin.getState(time), time);
366void MSXRS232::Counter0::signalPosEdge(ClockPin& , EmuTime::param )
374void MSXRS232::Counter1::signal(ClockPin& pin, EmuTime::param time)
376 auto& rs232 =
OUTER(MSXRS232, cntr1);
377 ClockPin& clk = rs232.i8251.getClockPin();
378 if (pin.isPeriodic()) {
379 clk.setPeriodicState(pin.getTotalDuration(),
380 pin.getHighDuration(), time);
382 clk.setState(pin.getState(time), time);
386void MSXRS232::Counter1::signalPosEdge(ClockPin& , EmuTime::param )
427template<
typename Archive>
430 ar.template serializeBase<MSXDevice>(*
this);
431 ar.template serializeBase<RS232Connector>(*
this);
433 ar.serialize(
"I8254", i8254,
435 if (ram) ar.serialize(
"ram", *ram);
436 ar.serialize(
"rxrdyIRQ", rxrdyIRQ,
437 "rxrdyIRQlatch", rxrdyIRQlatch,
438 "rxrdyIRQenabled", rxrdyIRQenabled);
439 if (ar.versionAtLeast(version, 2)) {
440 ar.serialize(
"ioAccessEnabled", ioAccessEnabled);
442 assert(Archive::IS_LOADER);
443 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 setParityBit(bool enable, ParityBit parity) override
void writeIO(word port, byte value, EmuTime::param time)
void setDataBits(DataBits bits) override
byte readIO(word port, EmuTime::param time)
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 * getWriteCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
void setParityBit(bool enable, ParityBit parity) 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.
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 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)