OXYGENHUB
◆ main openmsx / src / serial / I8251.hh
3.0 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
// This class implements the Intel 8251 chip (UART)
2
3
#ifndef I8251_HH
4
#define I8251_HH
5
6
#include "ClockPin.hh"
7
#include "SerialDataInterface.hh"
8
9
#include "Schedulable.hh"
10
#include "serialize_meta.hh"
11
12
#include "outer.hh"
13
14
#include <cstdint>
15
16
namespace openmsx {
17
18
class I8251Interface : public SerialDataInterface
19
{
20
public:
21
	virtual void setRxRDY(bool status, EmuTime time) = 0;
22
	virtual void setDTR(bool status, EmuTime time) = 0;
23
	virtual void setRTS(bool status, EmuTime time) = 0;
24
25
	[[nodiscard]] virtual bool getDSR(EmuTime time) = 0;
26
	[[nodiscard]] virtual bool getCTS(EmuTime time) = 0; // TODO use this
27
	virtual void signal(EmuTime time) = 0;
28
29
protected:
30
	I8251Interface() = default;
31
	~I8251Interface() = default;
32
};
33
34
class I8251 final : public SerialDataInterface
35
{
36
public:
37
	I8251(Scheduler& scheduler, I8251Interface& interface, EmuTime time);
38
39
	void reset(EmuTime time);
40
	[[nodiscard]] uint8_t readIO(uint16_t port, EmuTime time);
41
	[[nodiscard]] uint8_t peekIO(uint16_t port, EmuTime time) const;
42
	void writeIO(uint16_t port, uint8_t value, EmuTime time);
43
	[[nodiscard]] ClockPin& getClockPin() { return clock; }
44
	[[nodiscard]] bool isRecvReady() const { return recvReady; }
45
	[[nodiscard]] bool isRecvEnabled() const;
46
	[[nodiscard]] bool isRecvFull() const;
47
	[[nodiscard]] unsigned getBaudRateFactor() const;
48
49
	// SerialDataInterface
50
	void setDataBits(DataBits bits) override { recvDataBits = bits; }
51
	void setStopBits(StopBits bits) override { recvStopBits = bits; }
52
	void setParityBit(bool enable, Parity parity) override;
53
	void recvByte(uint8_t value, EmuTime time) override;
54
55
	void execRecv(EmuTime time);
56
	void execTrans(EmuTime time);
57
58
	template<typename Archive>
59
	void serialize(Archive& ar, unsigned version);
60
61
	// public for serialize
62
	enum class CmdPhase : uint8_t {
63
		MODE, SYNC1, SYNC2, CMD
64
	};
65
66
private:
67
	void setMode(uint8_t newMode);
68
	void writeCommand(uint8_t value, EmuTime time);
69
	[[nodiscard]] uint8_t readStatus(EmuTime time);
70
	[[nodiscard]] uint8_t readTrans(EmuTime time);
71
	void writeTrans(uint8_t value, EmuTime time);
72
	void send(uint8_t value, EmuTime time);
73
74
private:
75
	// Schedulable
76
	struct SyncRecv final : Schedulable {
77
		friend class I8251;
78
		explicit SyncRecv(Scheduler& s) : Schedulable(s) {}
79
		void executeUntil(EmuTime time) override {
80
			auto& i8251 = OUTER(I8251, syncRecv);
81
			i8251.execRecv(time);
82
		}
83
	} syncRecv;
84
	struct SyncTrans final : Schedulable {
85
		friend class I8251;
86
		explicit SyncTrans(Scheduler& s) : Schedulable(s) {}
87
		void executeUntil(EmuTime time) override {
88
			auto& i8251 = OUTER(I8251, syncTrans);
89
			i8251.execTrans(time);
90
		}
91
	} syncTrans;
92
93
	I8251Interface& interface;
94
	ClockPin clock;
95
	unsigned charLength;
96
97
	CmdPhase cmdPhase;
98
	SerialDataInterface::DataBits  recvDataBits;
99
	SerialDataInterface::StopBits  recvStopBits;
100
	SerialDataInterface::Parity recvParityBit;
101
	bool recvParityEnabled;
102
	uint8_t recvBuf;
103
	bool recvReady;
104
105
	uint8_t sendByte;
106
	uint8_t sendBuffer;
107
108
	uint8_t status;
109
	uint8_t command;
110
	uint8_t mode;
111
	uint8_t sync1, sync2;
112
};
113
SERIALIZE_CLASS_VERSION(I8251, 2);
114
115
} // namespace openmsx
116
117
#endif