OXYGENHUB
◆ main openmsx / src / serial / I8254.hh
2.7 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
// This class implements the Intel 8254 chip (and 8253)
2
//
3
// * Only the 8254 is emulated, no surrounding hardware.
4
//   Use the class I8254Interface to do that.
5
6
#ifndef I8254_HH
7
#define I8254_HH
8
9
#include "ClockPin.hh"
10
#include "EmuTime.hh"
11
12
#include <array>
13
#include <cstdint>
14
15
namespace openmsx {
16
17
class Scheduler;
18
class ClockPinListener;
19
20
class Counter {
21
public:
22
	Counter(Scheduler& scheduler, ClockPinListener* listener,
23
		EmuTime time);
24
	void reset(EmuTime time);
25
	[[nodiscard]] uint8_t readIO(EmuTime time);
26
	[[nodiscard]] uint8_t peekIO(EmuTime time) const;
27
	void writeIO(uint8_t value, EmuTime time);
28
	void setGateStatus(bool status, EmuTime time);
29
	void writeControlWord(uint8_t value, EmuTime time);
30
	void latchStatus(EmuTime time);
31
	void latchCounter(EmuTime time);
32
33
	template<typename Archive>
34
	void serialize(Archive& ar, unsigned version);
35
36
//private:
37
	enum class ByteOrder : uint8_t {LOW, HIGH};
38
39
private:
40
	static constexpr uint8_t WRT_FRMT = 0x30;
41
	static constexpr uint8_t WF_LATCH = 0x00;
42
	static constexpr uint8_t WF_LOW   = 0x10;
43
	static constexpr uint8_t WF_HIGH  = 0x20;
44
	static constexpr uint8_t WF_BOTH  = 0x30;
45
	static constexpr uint8_t CNTR_MODE = 0x0E;
46
	static constexpr uint8_t CNTR_M0   = 0x00;
47
	static constexpr uint8_t CNTR_M1   = 0x02;
48
	static constexpr uint8_t CNTR_M2   = 0x04;
49
	static constexpr uint8_t CNTR_M3   = 0x06;
50
	static constexpr uint8_t CNTR_M4   = 0x08;
51
	static constexpr uint8_t CNTR_M5   = 0x0A;
52
	static constexpr uint8_t CNTR_M2_  = 0x0C;
53
	static constexpr uint8_t CNTR_M3_  = 0x0E;
54
55
	void writeLoad(uint16_t value, EmuTime time);
56
	void advance(EmuTime time);
57
58
private:
59
	ClockPin clock;
60
	ClockPin output;
61
	EmuTime currentTime;
62
	int counter = 0;
63
	uint16_t latchedCounter;
64
	uint16_t counterLoad = 0;
65
	uint8_t control, latchedControl;
66
	bool ltchCtrl, ltchCntr;
67
	ByteOrder readOrder, writeOrder;
68
	uint8_t writeLatch;
69
	bool gate = true;
70
	bool active, triggered, counting;
71
72
	friend class I8254;
73
};
74
75
class I8254
76
{
77
public:
78
	I8254(Scheduler& scheduler, ClockPinListener* output0,
79
	      ClockPinListener* output1, ClockPinListener* output2,
80
	      EmuTime time);
81
82
	void reset(EmuTime time);
83
	[[nodiscard]] uint8_t readIO(uint16_t port, EmuTime time);
84
	[[nodiscard]] uint8_t peekIO(uint16_t port, EmuTime time) const;
85
	void writeIO(uint16_t port, uint8_t value, EmuTime time);
86
87
	void setGate(unsigned cntr, bool status, EmuTime time);
88
	[[nodiscard]] ClockPin& getClockPin(unsigned cntr);
89
	[[nodiscard]] ClockPin& getOutputPin(unsigned cntr);
90
91
	template<typename Archive>
92
	void serialize(Archive& ar, unsigned version);
93
94
private:
95
	void readBackHelper(uint8_t value, unsigned cntr, EmuTime time);
96
97
private:
98
	std::array<Counter, 3> counter;
99
};
100
101
} // namespace openmsx
102
103
#endif