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);
106 if ((mode & MODE_BAUDRATE) == MODE_SYNCHRONOUS) {
114 if (mode & MODE_SINGLE_SYNC) {
125 if (value & CMD_RESET) {
128 writeCommand(value, time);
140void I8251::setMode(
byte newMode)
144 auto dataBits = [&] {
145 switch (mode & MODE_WORD_LENGTH) {
155 auto stopBits = [&] {
156 switch(mode & MODE_STOP_BITS) {
166 bool parityEnable = (mode & MODE_PARITY_EVEN) != 0;
171 unsigned baudrate = [&] {
172 switch (mode & MODE_BAUDRATE) {
173 case MODE_SYNCHRONOUS:
return 1;
174 case MODE_RATE1:
return 1;
175 case MODE_RATE16:
return 16;
176 case MODE_RATE64:
return 64;
181 charLength = (((2 * (1 + unsigned(dataBits) + (parityEnable ? 1 : 0))) +
182 unsigned(stopBits)) * baudrate) / 2;
185void I8251::writeCommand(
byte value, EmuTime::param time)
187 byte oldCommand = command;
192 interface.
setRTS((command & CMD_RTS) != 0, time);
193 interface.
setDTR((command & CMD_DTR) != 0, time);
195 if (!(command & CMD_TXEN)) {
198 status |= STAT_TXRDY | STAT_TXEMPTY;
200 if (command & CMD_RST_ERR) {
201 status &= ~(STAT_PE | STAT_OE | STAT_FE);
203 if (command & CMD_SBRK) {
206 if (command & CMD_HUNT) {
210 if ((command ^ oldCommand) & CMD_RXE) {
211 if (command & CMD_RXE) {
213 status &= ~(STAT_PE | STAT_OE | STAT_FE);
218 status &= ~(STAT_PE | STAT_OE | STAT_FE);
219 status &= ~STAT_RXRDY;
225byte I8251::readStatus(EmuTime::param time)
227 byte result = status;
228 if (interface.
getDSR(time)) {
234byte I8251::readTrans(EmuTime::param time)
236 status &= ~STAT_RXRDY;
241void I8251::writeTrans(
byte value, EmuTime::param time)
243 if (!(command & CMD_TXEN)) {
246 if (status & STAT_TXEMPTY) {
251 status &= ~STAT_TXRDY;
257 recvParityEnabled = enable;
258 recvParityBit = parity;
264 assert(recvReady && (command & CMD_RXE));
265 if (status & STAT_RXRDY) {
269 status |= STAT_RXRDY;
281 return (command & CMD_RXE) != 0;
284void I8251::send(
byte value, EmuTime::param time)
286 status &= ~STAT_TXEMPTY;
296 assert(command & CMD_RXE);
303 assert(!(status & STAT_TXEMPTY) && (command & CMD_TXEN));
306 if (status & STAT_TXRDY) {
307 status |= STAT_TXEMPTY;
309 status |= STAT_TXRDY;
310 send(sendBuffer, time);
315static constexpr std::initializer_list<enum_string<SerialDataInterface::DataBits>> dataBitsInfo = {
323static constexpr std::initializer_list<enum_string<SerialDataInterface::StopBits>> stopBitsInfo = {
331static constexpr std::initializer_list<enum_string<SerialDataInterface::ParityBit>> parityBitInfo = {
337static constexpr std::initializer_list<enum_string<I8251::CmdFaze>> cmdFazeInfo = {
347template<
typename Archive>
350 if (ar.versionAtLeast(version, 2)) {
356 ar.serialize(
"clock", clock,
357 "charLength", charLength,
358 "recvDataBits", recvDataBits,
359 "recvStopBits", recvStopBits,
360 "recvParityBit", recvParityBit,
361 "recvParityEnabled", recvParityEnabled,
363 "recvReady", recvReady,
364 "sendByte", sendByte,
365 "sendBuffer", sendBuffer,
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:
SERIALIZE_ENUM(CassettePlayer::State, stateInfo)
uint16_t word
16 bit unsigned integer
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)