8static constexpr byte STAT_TXRDY = 0x01;
9static constexpr byte STAT_RXRDY = 0x02;
10static constexpr byte STAT_TXEMPTY = 0x04;
11static constexpr byte STAT_PE = 0x08;
12static constexpr byte STAT_OE = 0x10;
13static constexpr byte STAT_FE = 0x20;
14static constexpr byte STAT_SYN_BRK = 0x40;
15static constexpr byte STAT_DSR = 0x80;
17static constexpr byte MODE_BAUDRATE = 0x03;
18static constexpr byte MODE_SYNCHRONOUS = 0x00;
19static constexpr byte MODE_RATE1 = 0x01;
20static constexpr byte MODE_RATE16 = 0x02;
21static constexpr byte MODE_RATE64 = 0x03;
22static constexpr byte MODE_WORD_LENGTH = 0x0C;
23static constexpr byte MODE_5BIT = 0x00;
24static constexpr byte MODE_6BIT = 0x04;
25static constexpr byte MODE_7BIT = 0x08;
26static constexpr byte MODE_8BIT = 0x0C;
27static constexpr byte MODE_PARITY_EVEN = 0x10;
28static constexpr byte MODE_PARITY_ODD = 0x00;
29static constexpr byte MODE_PARITEVEN = 0x20;
30static constexpr byte MODE_STOP_BITS = 0xC0;
31static constexpr byte MODE_STOP_INV = 0x00;
32static constexpr byte MODE_STOP_1 = 0x40;
33static constexpr byte MODE_STOP_15 = 0x80;
34static constexpr byte MODE_STOP_2 = 0xC0;
35static constexpr byte MODE_SINGLE_SYNC = 0x80;
37static constexpr byte CMD_TXEN = 0x01;
38static constexpr byte CMD_DTR = 0x02;
39static constexpr byte CMD_RXE = 0x04;
40static constexpr byte CMD_SBRK = 0x08;
41static constexpr byte CMD_RST_ERR = 0x10;
42static constexpr byte CMD_RTS = 0x20;
43static constexpr byte CMD_RESET = 0x40;
44static constexpr byte CMD_HUNT = 0x80;
48 : syncRecv (scheduler)
49 , syncTrans(scheduler)
50 , interface(interface_), clock(scheduler)
63 recvParityEnabled =
false;
71 status = STAT_TXRDY | STAT_TXEMPTY;
73 writeCommand(0, time);
80 case 0:
return readTrans(time);
81 case 1:
return readStatus(time);
89 case 0:
return recvBuf;
90 case 1:
return status;
100 writeTrans(value, time);
107 if ((mode & MODE_BAUDRATE) == MODE_SYNCHRONOUS) {
115 if (mode & MODE_SINGLE_SYNC) {
126 if (value & CMD_RESET) {
129 writeCommand(value, time);
141void I8251::setMode(
byte newMode)
145 auto dataBits = [&] {
146 switch (mode & MODE_WORD_LENGTH) {
156 auto stopBits = [&] {
157 switch(mode & MODE_STOP_BITS) {
167 bool parityEnable = (mode & MODE_PARITY_EVEN) != 0;
172 unsigned baudrate = [&] {
173 switch (mode & MODE_BAUDRATE) {
174 case MODE_SYNCHRONOUS:
return 1;
175 case MODE_RATE1:
return 1;
176 case MODE_RATE16:
return 16;
177 case MODE_RATE64:
return 64;
182 charLength = (((2 * (1 + unsigned(dataBits) + (parityEnable ? 1 : 0))) +
183 unsigned(stopBits)) * baudrate) / 2;
186void I8251::writeCommand(
byte value, EmuTime::param time)
188 byte oldCommand = command;
193 interface.
setRTS((command & CMD_RTS) != 0, time);
194 interface.
setDTR((command & CMD_DTR) != 0, time);
196 if (!(command & CMD_TXEN)) {
199 status |= STAT_TXRDY | STAT_TXEMPTY;
201 if (command & CMD_RST_ERR) {
202 status &= ~(STAT_PE | STAT_OE | STAT_FE);
204 if (command & CMD_SBRK) {
207 if (command & CMD_HUNT) {
211 if ((command ^ oldCommand) & CMD_RXE) {
212 if (command & CMD_RXE) {
214 status &= ~(STAT_PE | STAT_OE | STAT_FE);
219 status &= ~(STAT_PE | STAT_OE | STAT_FE);
220 status &= ~STAT_RXRDY;
226byte I8251::readStatus(EmuTime::param time)
228 byte result = status;
229 if (interface.
getDSR(time)) {
235byte I8251::readTrans(EmuTime::param time)
237 status &= ~STAT_RXRDY;
242void I8251::writeTrans(
byte value, EmuTime::param time)
244 if (!(command & CMD_TXEN)) {
247 if (status & STAT_TXEMPTY) {
252 status &= ~STAT_TXRDY;
258 recvParityEnabled = enable;
259 recvParityBit = parity;
265 assert(recvReady && (command & CMD_RXE));
266 if (status & STAT_RXRDY) {
270 status |= STAT_RXRDY;
282 return (command & CMD_RXE) != 0;
285void I8251::send(
byte value, EmuTime::param time)
287 status &= ~STAT_TXEMPTY;
297 assert(command & CMD_RXE);
304 assert(!(status & STAT_TXEMPTY) && (command & CMD_TXEN));
307 if (status & STAT_TXRDY) {
308 status |= STAT_TXEMPTY;
310 status |= STAT_TXRDY;
311 send(sendBuffer, time);
316static constexpr std::initializer_list<enum_string<SerialDataInterface::DataBits>> dataBitsInfo = {
324static constexpr std::initializer_list<enum_string<SerialDataInterface::StopBits>> stopBitsInfo = {
332static constexpr std::initializer_list<enum_string<SerialDataInterface::ParityBit>> parityBitInfo = {
338static constexpr std::initializer_list<enum_string<I8251::CmdPhase>> cmdFazeInfo = {
348template<
typename Archive>
351 if (ar.versionAtLeast(version, 2)) {
357 ar.serialize(
"clock", clock,
358 "charLength", charLength,
359 "recvDataBits", recvDataBits,
360 "recvStopBits", recvStopBits,
361 "recvParityBit", recvParityBit,
362 "recvParityEnabled", recvParityEnabled,
364 "recvReady", recvReady,
365 "sendByte", sendByte,
366 "sendBuffer", sendBuffer,
372 "cmdFaze", cmdPhase);
EmuDuration::param getTotalDuration() const
virtual bool getDSR(EmuTime::param time)=0
virtual void setRxRDY(bool status, EmuTime::param time)=0
virtual void setDTR(bool status, EmuTime::param time)=0
virtual void setRTS(bool status, EmuTime::param time)=0
virtual void signal(EmuTime::param time)=0
byte peekIO(word port, EmuTime::param time) const
void recvByte(byte value, EmuTime::param time) override
I8251(Scheduler &scheduler, I8251Interface &interface, EmuTime::param time)
void execRecv(EmuTime::param time)
void setParityBit(bool enable, ParityBit parity) override
void writeIO(word port, byte value, EmuTime::param time)
void reset(EmuTime::param time)
openmsx::I8251::SyncRecv syncRecv
void execTrans(EmuTime::param time)
byte readIO(word port, EmuTime::param time)
openmsx::I8251::SyncTrans syncTrans
void serialize(Archive &ar, unsigned version)
bool isRecvEnabled() const
void setSyncPoint(EmuTime::param timestamp)
static void restoreOld(Archive &ar, std::vector< Schedulable * > schedulables)
virtual void recvByte(byte value, EmuTime::param time)=0
virtual void setStopBits(StopBits bits)=0
virtual void setParityBit(bool enable, ParityBit parity)=0
virtual void setDataBits(DataBits bits)=0
This file implemented 3 utility functions:
uint16_t word
16 bit unsigned integer
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
#define SERIALIZE_ENUM(TYPE, INFO)