23 , i8254(getScheduler(), &cntr0, &cntr1, nullptr, getCurrentTime())
24 , i8251(getScheduler(), interface, getCurrentTime())
25 , rom(config.findChild(
"rom")
29 , ram(config.getChildDataAsBool(
"ram", false)
35 , hasMemoryBasedIo(config.getChildDataAsBool(
"memorybasedio", false))
36 , ioAccessEnabled(!hasMemoryBasedIo)
37 , switchSetting(config.getChildDataAsBool(
"toshiba_rs232c_switch",
39 "toshiba_rs232c_switch",
"status of the RS-232C enable switch",
42 if (rom && (rom->size() !=
one_of(0x2000u, 0x4000u))) {
43 throw MSXException(
"RS232C only supports 8kB or 16kB ROMs.");
60 if (ram) ram->clear();
66 rxrdyIRQlatch =
false;
67 rxrdyIRQenabled =
false;
70 ioAccessEnabled = !hasMemoryBasedIo;
72 if (ram) ram->clear();
77 if (hasMemoryBasedIo && (0xBFF8 <= address) && (address <= 0xBFFF)) {
78 return readIOImpl(address & 0x07, time);
80 word addr = address & 0x3FFF;
83 }
else if (rom && (0x4000 <= address) && (address < 0x8000)) {
84 return (*rom)[addr & (rom->size() - 1)];
95 word addr = start & 0x3FFF;
98 }
else if (rom && (0x4000 <= start) && (start < 0x8000)) {
99 return &(*rom)[addr & (rom->size() - 1)];
108 if (hasMemoryBasedIo && (0xBFF8 <= address) && (address <= 0xBFFF)) {
114 if (address == 0xBFFA) {
115 ioAccessEnabled = (value & (1 << 4))!=0;
117 return writeIOImpl(address & 0x07, value, time);
119 word addr = address & 0x3FFF;
130 word addr = start & 0x3FFF;
146 if (ioAccessEnabled) {
147 return readIOImpl(port & 0x07, time);
152byte MSXRS232::readIOImpl(
word port, EmuTime::param time)
157 return i8251.
readIO(port, time);
159 return readStatus(time);
166 return i8254.
readIO(port - 4, time);
174 if (hasMemoryBasedIo && !ioAccessEnabled)
return 0xFF;
179 return i8251.
peekIO(port, time);
188 return i8254.
peekIO(port - 4, time);
196 if (ioAccessEnabled) writeIOImpl(port & 0x07, value, time);
199void MSXRS232::writeIOImpl(
word port,
byte value, EmuTime::param time)
204 i8251.
writeIO(port, value, time);
215 i8254.
writeIO(port - 4, value, time);
220byte MSXRS232::readStatus(EmuTime::param time)
242 if (!rxrdyIRQenabled && switchSetting && switchSetting->getBoolean()) {
246 if (!interface.getCTS(time)) {
255void MSXRS232::setIRQMask(
byte value)
257 enableRxRDYIRQ(!(value & 1));
260void MSXRS232::setRxRDYIRQ(
bool status)
262 if (rxrdyIRQlatch != status) {
263 rxrdyIRQlatch = status;
264 if (rxrdyIRQenabled) {
274void MSXRS232::enableRxRDYIRQ(
bool enabled)
276 if (rxrdyIRQenabled != enabled) {
277 rxrdyIRQenabled = enabled;
278 if (!rxrdyIRQenabled && rxrdyIRQlatch) {
287void MSXRS232::Interface::setRxRDY(
bool status, EmuTime::param )
290 rs232.setRxRDYIRQ(status);
293void MSXRS232::Interface::setDTR(
bool status, EmuTime::param time)
296 rs232.getPluggedRS232Dev().setDTR(status, time);
299void MSXRS232::Interface::setRTS(
bool status, EmuTime::param time)
302 rs232.getPluggedRS232Dev().setRTS(status, time);
305bool MSXRS232::Interface::getDSR(EmuTime::param time)
308 return rs232.getPluggedRS232Dev().getDSR(time);
311bool MSXRS232::Interface::getCTS(EmuTime::param time)
314 return rs232.getPluggedRS232Dev().getCTS(time);
317void MSXRS232::Interface::setDataBits(DataBits bits)
320 rs232.getPluggedRS232Dev().setDataBits(bits);
323void MSXRS232::Interface::setStopBits(StopBits bits)
326 rs232.getPluggedRS232Dev().setStopBits(bits);
329void MSXRS232::Interface::setParityBit(
bool enable, ParityBit parity)
332 rs232.getPluggedRS232Dev().setParityBit(enable, parity);
335void MSXRS232::Interface::recvByte(
byte value, EmuTime::param time)
338 rs232.getPluggedRS232Dev().recvByte(value, time);
341void MSXRS232::Interface::signal(EmuTime::param time)
344 rs232.getPluggedRS232Dev().signal(time);
350void MSXRS232::Counter0::signal(
ClockPin& pin, EmuTime::param time)
353 ClockPin& clk = rs232.i8251.getClockPin();
354 if (pin.isPeriodic()) {
355 clk.setPeriodicState(pin.getTotalDuration(),
356 pin.getHighDuration(), time);
358 clk.setState(pin.getState(time), time);
362void MSXRS232::Counter0::signalPosEdge(
ClockPin& , EmuTime::param )
370void MSXRS232::Counter1::signal(
ClockPin& pin, EmuTime::param time)
373 ClockPin& clk = rs232.i8251.getClockPin();
374 if (pin.isPeriodic()) {
375 clk.setPeriodicState(pin.getTotalDuration(),
376 pin.getHighDuration(), time);
378 clk.setState(pin.getState(time), time);
382void MSXRS232::Counter1::signalPosEdge(
ClockPin& , EmuTime::param )
423template<
typename Archive>
426 ar.template serializeBase<MSXDevice>(*
this);
427 ar.template serializeBase<RS232Connector>(*
this);
429 ar.serialize(
"I8254", i8254,
431 if (ram) ar.serialize(
"ram", *ram);
432 ar.serialize(
"rxrdyIRQ", rxrdyIRQ,
433 "rxrdyIRQlatch", rxrdyIRQlatch,
434 "rxrdyIRQenabled", rxrdyIRQenabled);
435 if (ar.versionAtLeast(version, 2)) {
436 ar.serialize(
"ioAccessEnabled", ioAccessEnabled);
438 assert(Archive::IS_LOADER);
439 ioAccessEnabled = !hasMemoryBasedIo;
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.
std::string getName(KeyCode keyCode)
Translate key code to key name.
This file implemented 3 utility functions:
const unsigned RAM_OFFSET
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
uint16_t word
16 bit unsigned integer
#define OUTER(type, member)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)