OXYGENHUB
◆ main openmsx / src / memory / RomBlocks.hh
3.7 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#ifndef ROMBLOCKS_HH
2
#define ROMBLOCKS_HH
3
4
#include "MSXRom.hh"
5
#include "RomBlockDebuggable.hh"
6
#include "serialize_meta.hh"
7
#include <array>
8
9
namespace openmsx {
10
11
class SRAM;
12
13
template<unsigned BANK_SIZE_>
14
class RomBlocks : public MSXRom
15
{
16
public:
17
	static constexpr unsigned BANK_SIZE = BANK_SIZE_;
18
	static constexpr unsigned NUM_BANKS = 0x10000 / BANK_SIZE;
19
	static constexpr unsigned BANK_MASK = BANK_SIZE - 1;
20
21
	[[nodiscard]] unsigned getBaseSizeAlignment() const override;
22
	[[nodiscard]] byte readMem(uint16_t address, EmuTime time) override;
23
	[[nodiscard]] byte peekMem(uint16_t address, EmuTime time) const override;
24
	[[nodiscard]] const byte* getReadCacheLine(uint16_t address) const override;
25
26
	template<typename Archive>
27
	void serialize(Archive& ar, unsigned version);
28
29
protected:
30
	/** Constructor
31
	 * @param config
32
	 * @param rom
33
	 * @param debugBankSizeShift Sometimes the mapper is implemented with a
34
	 *      smaller block size than the blocks that get logically switched.
35
	 *      For example RomGameMaster2 is implemented as a 4kB mapper but
36
	 *      blocks get switched in 8kB chunks (done like this because there
37
	 *      is only 4kB SRAM, that needs to be mirrored in a 8kB chunk).
38
	 *      This parameter indicates how much bigger the logical blocks are
39
	 *      compared to the implementation block size, it's only used to
40
	 *      correctly implement the 'romblocks' debuggable.
41
	 */
42
	RomBlocks(const DeviceConfig& config, Rom&& rom,
43
	          unsigned debugBankSizeShift = 0);
44
	~RomBlocks() override;
45
46
	/** Select 'unmapped' memory for this region. Reads from this
47
	  * region will return 0xff.
48
	  */
49
	void setUnmapped(unsigned region);
50
51
	/** Sets the memory visible for reading in a certain region.
52
	  * @param region number of 8kB region in Z80 address space
53
	  *   (region i starts at Z80 address i * 0x2000)
54
	  * @param adr pointer to memory, area must be at least 0x2000 bytes long
55
	  * @param block Block number, only used for the 'romblock' debuggable, limited to 8-bit.
56
	  */
57
	void setBank(unsigned region, const byte* adr, byte block);
58
59
	/** Selects a block of the ROM image for reading in a certain region.
60
	  * @param region number of 8kB region in Z80 address space
61
	  *   (region i starts at Z80 address i * 0x2000)
62
	  * @param block number of 8kB block in the ROM image
63
	  *   (block i starts at ROM image offset i * 0x2000)
64
	  */
65
	void setRom(unsigned region, unsigned block);
66
67
	/** Sets a mask for the block numbers.
68
	  * On every call to setRom, the given block number is AND-ed with this
69
	  * mask; if the resulting number if outside of the ROM, unmapped memory
70
	  * is selected.
71
	  * By default the mask is set up to wrap at the end of the ROM image,
72
	  * meaning the entire ROM is reachable and there is no unmapped memory.
73
	  */
74
	void setBlockMask(int mask) { blockMask = mask; }
75
76
	/** Inform this base class of extra mappable memory block.
77
	 * This is needed for serialization of mappings in this block.
78
	 * Should only be called from subclass constructor.
79
	 * (e.g. used by RomPanasonic)
80
	 */
81
	void setExtraMemory(std::span<const byte> mem);
82
83
protected:
84
	std::array<const byte*, NUM_BANKS> bankPtr;
85
	std::unique_ptr<SRAM> sram; // can be nullptr
86
	std::array<byte, NUM_BANKS> blockNr;
87
88
private:
89
	RomBlockDebuggable romBlockDebug;
90
	std::span<const byte> extraMem;
91
	/*const*/ unsigned nrBlocks;
92
	int blockMask;
93
};
94
95
using Rom4kBBlocks  = RomBlocks<0x1000>;
96
using Rom8kBBlocks  = RomBlocks<0x2000>;
97
using Rom16kBBlocks = RomBlocks<0x4000>;
98
99
REGISTER_BASE_CLASS(Rom4kBBlocks,  "Rom4kBBlocks");
100
REGISTER_BASE_CLASS(Rom8kBBlocks,  "Rom8kBBlocks");
101
REGISTER_BASE_CLASS(Rom16kBBlocks, "Rom16kBBlocks");
102
103
// TODO see comment in .cc
104
//SERIALIZE_CLASS_VERSION(Rom4kBBlocks,  2);
105
//SERIALIZE_CLASS_VERSION(Rom8kBBlocks,  2);
106
//SERIALIZE_CLASS_VERSION(Rom16kBBlocks, 2);
107
108
} // namespace openmsx
109
110
#endif