11static constexpr unsigned CR_CDS1 = 0x01;
12static constexpr unsigned CR_CDS2 = 0x02;
13static constexpr unsigned CR_CDS = CR_CDS1 | CR_CDS2;
14static constexpr unsigned CR_MR = CR_CDS1 | CR_CDS2;
21static constexpr unsigned CR_WS1 = 0x04;
22static constexpr unsigned CR_WS2 = 0x08;
23static constexpr unsigned CR_WS3 = 0x10;
24static constexpr unsigned CR_WS = CR_WS1 | CR_WS2 | CR_WS3;
35static constexpr unsigned CR_TC1 = 0x20;
36static constexpr unsigned CR_TC2 = 0x40;
37static constexpr unsigned CR_TC = CR_TC1 | CR_TC2;
45static constexpr unsigned CR_RIE = 0x80;
50static constexpr unsigned STAT_RDRF = 0x01;
51static constexpr unsigned STAT_TDRE = 0x02;
52static constexpr unsigned STAT_DCD = 0x04;
53static constexpr unsigned STAT_CTS = 0x08;
54static constexpr unsigned STAT_FE = 0x10;
55static constexpr unsigned STAT_OVRN = 0x20;
56static constexpr unsigned STAT_PE = 0x40;
57static constexpr unsigned STAT_IRQ = 0x80;
61 , syncRecv (motherBoard.getScheduler())
62 , syncTrans(motherBoard.getScheduler())
63 , clockFreq(clockFreq_)
64 , rxIRQ(motherBoard, name_ +
"-rx-IRQ")
65 , txIRQ(motherBoard, name_ +
"-tx-IRQ")
66 , outConnector(motherBoard.getPluggingController(), name_ +
"-out")
68 reset(EmuTime::zero());
75 syncRecv .removeSyncPoint();
76 syncTrans.removeSyncPoint();
82 txShiftRegValid =
false;
97 byte result = statusReg;
105 statusReg &=
byte(~(STAT_RDRF | STAT_OVRN));
108 statusReg |= STAT_OVRN;
121 byte diff = value ^ controlReg;
123 if ((value & CR_CDS) == CR_MR) {
128 statusReg |= STAT_TDRE;
131 switch (value & CR_CDS) {
132 case 0: txClock.
setFreq(clockFreq, 1);
break;
133 case 1: txClock.
setFreq(clockFreq, 16);
break;
134 case 2: txClock.
setFreq(clockFreq, 64);
break;
140 if (diff & CR_WS) setDataFormat();
143 rxIRQ.
set(( value & CR_RIE) && (statusReg & STAT_RDRF));
144 txIRQ.
set(((value & CR_TC) == 0x20) && (statusReg & STAT_TDRE));
148void MC6850::setDataFormat()
152 static constexpr std::array<StopBits, 8> stopBits = {
156 outConnector.
setStopBits(stopBits[(controlReg & CR_WS) >> 2]);
159 (controlReg & (CR_WS3 | CR_WS2)) != 0x10,
163 static constexpr std::array<byte, 8> len = {
173 charLen = len[(controlReg & CR_WS) >> 2];
178 if ((controlReg & CR_CDS) == CR_MR)
return;
181 statusReg &=
byte(~STAT_TDRE);
184 if (syncTrans.pendingSyncPoint()) {
193 syncTrans.setSyncPoint(txClock.
getTime());
199void MC6850::execTrans(EmuTime::param time)
201 assert(txClock.
getTime() == time);
202 assert((controlReg & CR_CDS) != CR_MR);
204 if (txShiftRegValid) {
205 txShiftRegValid =
false;
206 outConnector.
recvByte(txShiftReg, time);
209 if (statusReg & STAT_TDRE) {
214 statusReg |= STAT_TDRE;
215 if ((controlReg & CR_TC) == 0x20) txIRQ.
set();
217 txShiftReg = txDataReg;
218 txShiftRegValid =
true;
221 syncTrans.setSyncPoint(txClock.
getTime());
226void MC6850::recvByte(
byte value, EmuTime::param time)
228 assert(acceptsData() && ready());
230 if (statusReg & STAT_RDRF) {
239 statusReg |= STAT_RDRF;
242 if (controlReg & CR_RIE) rxIRQ.
set();
251 syncRecv.setSyncPoint(time + txClock.
getPeriod() * charLen);
255void MC6850::execRecv(EmuTime::param time)
257 assert(acceptsData());
270bool MC6850::acceptsData()
272 return (controlReg & CR_CDS) != CR_MR;
277void MC6850::setDataBits(DataBits )
281void MC6850::setStopBits(StopBits )
285void MC6850::setParityBit(
bool , Parity )
293template<
typename Archive>
296 if (ar.versionAtLeast(version, 3)) {
297 ar.template serializeBase<MidiInConnector>(*
this);
298 ar.serialize(
"outConnector", outConnector,
300 "syncRecv", syncRecv,
301 "syncTrans", syncTrans,
308 "txShiftRegValid", txShiftRegValid,
309 "pendingOVRN", pendingOVRN,
311 "rxDataReg", rxDataReg,
312 "txDataReg", txDataReg,
313 "txShiftReg", txShiftReg,
314 "controlReg", controlReg,
315 "statusReg", statusReg);
316 }
else if (ar.versionAtLeast(version, 2)) {
317 ar.serialize(
"control", controlReg);
322 if constexpr (Archive::IS_LOADER) {
EmuDuration getPeriod() const
Returns the length of one clock-cycle.
void reset(EmuTime::param e)
Reset the clock to start ticking at the given time.
void advance(EmuTime::param e)
Advance this clock in time until the last tick which is not past the given time.
void setFreq(unsigned freq)
Change the frequency at which this clock ticks.
EmuTime::param getTime() const
Gets the time at which the last clock tick occurred.
void set()
Set the interrupt request on the bus.
void reset()
Reset the interrupt request on the bus.
bool getState() const
Get the interrupt state.
byte peekStatusReg() const
void reset(EmuTime::param time)
void writeControlReg(byte value, EmuTime::param time)
byte readStatusReg() const
void writeDataReg(byte value, EmuTime::param time)
MC6850(const std::string &name, MSXMotherBoard &motherBoard, unsigned clockFreq)
void serialize(Archive &ar, unsigned version)
MidiInDevice & getPluggedMidiInDev() const
virtual void signal(EmuTime::param time)=0
void setStopBits(StopBits bits) override
void setDataBits(DataBits bits) override
void setParityBit(bool enable, Parity parity) override
void recvByte(byte value, EmuTime::param time) override
This file implemented 3 utility functions:
uint8_t byte
8 bit unsigned integer
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)