OXYGENHUB
◆ main openmsx / src / memory / MSXMapperIO.hh
2.5 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#ifndef MSXMAPPERIO_HH
2
#define MSXMAPPERIO_HH
3
4
#include "MSXDevice.hh"
5
#include "MSXMotherBoard.hh"
6
#include "SimpleDebuggable.hh"
7
8
#include <array>
9
#include <cstdint>
10
#include <vector>
11
12
namespace openmsx {
13
14
struct MSXMemoryMapperInterface
15
{
16
	[[nodiscard]] virtual byte readIO(uint16_t port, EmuTime time) = 0;
17
	[[nodiscard]] virtual byte peekIO(uint16_t port, EmuTime time) const = 0;
18
	virtual void writeIO(uint16_t port, byte value, EmuTime time) = 0;
19
	[[nodiscard]] virtual byte getSelectedSegment(byte page) const = 0;
20
protected:
21
	~MSXMemoryMapperInterface() = default;
22
};
23
24
25
class MSXMapperIO final : public MSXDevice
26
{
27
public:
28
	enum class Mode : uint8_t { INTERNAL, EXTERNAL };
29
30
public:
31
	explicit MSXMapperIO(const DeviceConfig& config);
32
33
	void setMode(Mode mode, byte mask, byte baseValue);
34
35
	[[nodiscard]] byte readIO(uint16_t port, EmuTime time) override;
36
	[[nodiscard]] byte peekIO(uint16_t port, EmuTime time) const override;
37
	void writeIO(uint16_t port, byte value, EmuTime time) override;
38
39
	void registerMapper(MSXMemoryMapperInterface* mapper);
40
	void unregisterMapper(MSXMemoryMapperInterface* mapper);
41
42
	template<typename Archive>
43
	void serialize(Archive& ar, unsigned version);
44
45
private:
46
	struct Debuggable final : SimpleDebuggable {
47
		Debuggable(MSXMotherBoard& motherBoard, const std::string& name);
48
		[[nodiscard]] byte read(unsigned address) override;
49
		void write(unsigned address, byte value, EmuTime time) override;
50
		void readBlock(unsigned start, std::span<byte> output) override;
51
	} debuggable;
52
53
	std::vector<MSXMemoryMapperInterface*> mappers;
54
55
	std::array<byte, 4> registers = {}; // (copy of) the mapper register state
56
	byte mask; // bitmask: 1-bit -> take mapper register, 0-bit -> take baseValue
57
	byte baseValue = 0xff;
58
	Mode mode = Mode::EXTERNAL; // use the internal or the external mapper state
59
};
60
SERIALIZE_CLASS_VERSION(MSXMapperIO, 3);
61
62
63
class MSXMapperIOClient : public MSXMemoryMapperInterface
64
{
65
public:
66
	MSXMapperIOClient(const MSXMapperIOClient&) = delete;
67
	MSXMapperIOClient(MSXMapperIOClient&&) = delete;
68
	MSXMapperIOClient& operator=(const MSXMapperIOClient&) = delete;
69
	MSXMapperIOClient& operator=(MSXMapperIOClient&&) = delete;
70
71
protected:
72
	explicit MSXMapperIOClient(MSXMotherBoard& motherBoard_)
73
		: motherBoard(motherBoard_)
74
	{
75
		auto& mapperIO = motherBoard.createMapperIO();
76
		mapperIO.registerMapper(this);
77
	}
78
79
	~MSXMapperIOClient()
80
	{
81
		auto& mapperIO = motherBoard.getMapperIO();
82
		mapperIO.unregisterMapper(this);
83
		motherBoard.destroyMapperIO();
84
	}
85
86
private:
87
	MSXMotherBoard& motherBoard;
88
};
89
90
} // namespace openmsx
91
92
#endif