OXYGENHUB
◆ main openmsx / src / memory / RomBlockDebuggable.hh
3.6 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#ifndef ROMBLOCKDEBUGGABLE_HH
2
#define ROMBLOCKDEBUGGABLE_HH
3
4
#include "MSXDevice.hh"
5
#include "SimpleDebuggable.hh"
6
7
#include "outer.hh"
8
9
#include <span>
10
11
namespace openmsx {
12
13
class RomBlockDebuggableBase
14
{
15
public:
16
	explicit RomBlockDebuggableBase(const MSXDevice& device)
17
		: debuggable8 (device)
18
		, debuggable16(device) {}
19
20
	// To support larger than 8 bit segment numbers.
21
	[[nodiscard]] virtual unsigned readExt(unsigned address) = 0;
22
23
	struct Debuggable8 final : SimpleDebuggable {
24
		explicit Debuggable8(const MSXDevice& device)
25
			: SimpleDebuggable(device.getMotherBoard(),
26
			                   device.getName() + " romblocks",
27
			                   "Shows for each byte of the mapper which memory block is selected.",
28
			                   0x10000) {}
29
30
		[[nodiscard]] RomBlockDebuggableBase& getRomBlocks() {
31
			return OUTER(RomBlockDebuggableBase, debuggable8);
32
		}
33
34
		[[nodiscard]] uint8_t read(unsigned address) override {
35
			auto& outer = OUTER(RomBlockDebuggableBase, debuggable8);
36
			return narrow_cast<uint8_t>(outer.readExt(address));
37
		}
38
	} debuggable8;
39
40
	struct Debuggable16 final : SimpleDebuggable {
41
		explicit Debuggable16(const MSXDevice& device)
42
			: SimpleDebuggable(device.getMotherBoard(),
43
			                   device.getName() + " romblocks16",
44
			                   "Shows for each byte of the mapper which memory block is selected. "
45
			                   "16-bit version, bits 0-7 on even / bits 8-15 on odd addresses.",
46
			                   0x10000) {}
47
48
		[[nodiscard]] uint8_t read(unsigned address) override {
49
			auto& outer = OUTER(RomBlockDebuggableBase, debuggable16);
50
			auto full = outer.readExt(address);
51
			return narrow_cast<uint8_t>((address & 1) ? (full >> 8) : (full & 0xff));
52
		}
53
	} debuggable16;
54
55
protected:
56
	~RomBlockDebuggableBase() = default;
57
};
58
59
// Generic implementation. This (only) works when the segment numbers are stored
60
// in some byte-array (so limited to 8-bit segment numbers).
61
class RomBlockDebuggable final : public RomBlockDebuggableBase
62
{
63
public:
64
	RomBlockDebuggable(const MSXDevice& device, std::span<const uint8_t> blockNr_,
65
	                   unsigned startAddress_, unsigned mappedSize_,
66
	                   unsigned bankSizeShift_, unsigned debugShift_ = 0)
67
		: RomBlockDebuggableBase(device)
68
		, blockNr(blockNr_.data()), startAddress(startAddress_)
69
		, mappedSize(mappedSize_), bankSizeShift(bankSizeShift_)
70
		, debugShift(debugShift_), debugMask(~((1 << debugShift) - 1))
71
	{
72
		assert((mappedSize >> bankSizeShift) == blockNr_.size()); // no need to include 'debugMask' here
73
	}
74
	RomBlockDebuggable(const MSXDevice& device, std::span<const uint8_t> blockNr_,
75
	                   unsigned startAddress_, unsigned mappedSize_,
76
	                   unsigned bankSizeShift_, unsigned debugShift_,
77
	                   unsigned debugMask_)
78
		: RomBlockDebuggableBase(device)
79
		, blockNr(blockNr_.data()), startAddress(startAddress_)
80
		, mappedSize(mappedSize_), bankSizeShift(bankSizeShift_)
81
		, debugShift(debugShift_), debugMask(debugMask_)
82
	{
83
		assert(((mappedSize >> bankSizeShift) & debugMask) < blockNr_.size()); // here we do need 'debugMask'
84
	}
85
86
	[[nodiscard]] unsigned readExt(unsigned address) override
87
	{
88
		unsigned addr = address - startAddress;
89
		if (addr < mappedSize) {
90
			uint8_t tmp = blockNr[(addr >> bankSizeShift) & debugMask];
91
			return (tmp != 255) ? (tmp >> debugShift) : tmp;
92
		} else {
93
			return unsigned(-1); // outside mapped address space
94
		}
95
	}
96
97
private:
98
	const uint8_t* blockNr;
99
	const unsigned startAddress;
100
	const unsigned mappedSize;
101
	const unsigned bankSizeShift;
102
	const unsigned debugShift;
103
	const unsigned debugMask;
104
};
105
106
} // namespace openmsx
107
108
#endif