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) {
148 case MODE_5BIT:
return D5;
149 case MODE_6BIT:
return D6;
150 case MODE_7BIT:
return D7;
151 case MODE_8BIT:
return D8;
157 auto stopBits = [&] {
158 switch(mode & MODE_STOP_BITS) {
160 case MODE_STOP_INV:
return INV;
161 case MODE_STOP_1:
return S1;
162 case MODE_STOP_15:
return S1_5;
163 case MODE_STOP_2:
return S2;
169 bool parityEnable = (mode & MODE_PARITY_EVEN) != 0;
174 unsigned baudrate = [&] {
175 switch (mode & MODE_BAUDRATE) {
176 case MODE_SYNCHRONOUS:
return 1;
177 case MODE_RATE1:
return 1;
178 case MODE_RATE16:
return 16;
179 case MODE_RATE64:
return 64;
184 charLength = (((2 * (1 + unsigned(dataBits) + (parityEnable ? 1 : 0))) +
185 unsigned(stopBits)) * baudrate) / 2;
188void I8251::writeCommand(
byte value, EmuTime::param time)
190 byte oldCommand = command;
195 interface.
setRTS((command & CMD_RTS) != 0, time);
196 interface.
setDTR((command & CMD_DTR) != 0, time);
198 if (!(command & CMD_TXEN)) {
200 syncTrans.removeSyncPoint();
201 status |= STAT_TXRDY | STAT_TXEMPTY;
203 if (command & CMD_RST_ERR) {
204 status &= ~(STAT_PE | STAT_OE | STAT_FE);
206 if (command & CMD_SBRK) {
209 if (command & CMD_HUNT) {
213 if ((command ^ oldCommand) & CMD_RXE) {
214 if (command & CMD_RXE) {
216 status &= ~(STAT_PE | STAT_OE | STAT_FE);
220 syncRecv.removeSyncPoint();
221 status &= ~(STAT_PE | STAT_OE | STAT_FE);
222 status &= ~STAT_RXRDY;
228byte I8251::readStatus(EmuTime::param time)
230 byte result = status;
231 if (interface.
getDSR(time)) {
237byte I8251::readTrans(EmuTime::param time)
239 status &= ~STAT_RXRDY;
244void I8251::writeTrans(
byte value, EmuTime::param time)
246 if (!(command & CMD_TXEN)) {
249 if (status & STAT_TXEMPTY) {
254 status &= ~STAT_TXRDY;
260 recvParityEnabled = enable;
261 recvParityBit = parity;
267 assert(recvReady && (command & CMD_RXE));
268 if (status & STAT_RXRDY) {
272 status |= STAT_RXRDY;
278 syncRecv.setSyncPoint(next);
284 return (command & CMD_RXE) != 0;
287void I8251::send(
byte value, EmuTime::param time)
289 status &= ~STAT_TXEMPTY;
293 syncTrans.setSyncPoint(next);
299 assert(command & CMD_RXE);
306 assert(!(status & STAT_TXEMPTY) && (command & CMD_TXEN));
309 if (status & STAT_TXRDY) {
310 status |= STAT_TXEMPTY;
312 status |= STAT_TXRDY;
313 send(sendBuffer, time);
318static constexpr std::initializer_list<enum_string<SerialDataInterface::DataBits>> dataBitsInfo = {
326static constexpr std::initializer_list<enum_string<SerialDataInterface::StopBits>> stopBitsInfo = {
334static constexpr std::initializer_list<enum_string<SerialDataInterface::Parity>> parityBitInfo = {
340static constexpr std::initializer_list<enum_string<I8251::CmdPhase>> cmdFazeInfo = {
350template<
typename Archive>
353 if (ar.versionAtLeast(version, 2)) {
354 ar.serialize(
"syncRecv", syncRecv,
355 "syncTrans", syncTrans);
359 ar.serialize(
"clock", clock,
360 "charLength", charLength,
361 "recvDataBits", recvDataBits,
362 "recvStopBits", recvStopBits,
363 "recvParityBit", recvParityBit,
364 "recvParityEnabled", recvParityEnabled,
366 "recvReady", recvReady,
367 "sendByte", sendByte,
368 "sendBuffer", sendBuffer,
374 "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 writeIO(word port, byte value, EmuTime::param time)
void reset(EmuTime::param time)
void execTrans(EmuTime::param time)
byte readIO(word port, EmuTime::param time)
void setParityBit(bool enable, Parity parity) override
void serialize(Archive &ar, unsigned version)
bool isRecvEnabled() const
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, Parity 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)