OXYGENHUB
◆ main openmsx / src / memory / RomMatraCompilation.cc
2.0 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#include "RomMatraCompilation.hh"
2
3
#include "serialize.hh"
4
5
#include "one_of.hh"
6
#include "xrange.hh"
7
8
// This is basically a generic 8kB mapper (Konami like, but without fixed page
9
// at 0x4000), with an extra offset register accessible at 0xBA00.
10
// The software only writes to 0x5000, 0x6000, 0x8000, 0xA000 to switch mapper
11
// page. I took these as unique switching addresses, as some of the compilation
12
// software would write to others, causing crashes.
13
// It seems that a write of 1 (and probably 0, but the software doesn't do
14
// that) to the offset register should be ignored and will disable the mapper
15
// switch addresses. Values of 2 or larger written there must be lowered by 2
16
// to get the actual offset to use.
17
18
namespace openmsx {
19
20
RomMatraCompilation::RomMatraCompilation(const DeviceConfig& config, Rom&& rom_)
21
	: Rom8kBBlocks(config, std::move(rom_))
22
{
23
	reset(EmuTime::dummy());
24
}
25
26
void RomMatraCompilation::reset(EmuTime /*time*/)
27
{
28
	setUnmapped(0);
29
	setUnmapped(1);
30
	for (auto i : xrange(2, 6)) {
31
		setRom(i, i - 2);
32
	}
33
	setUnmapped(6);
34
	setUnmapped(7);
35
36
	blockOffset = 2;
37
}
38
39
void RomMatraCompilation::writeMem(uint16_t address, byte value, EmuTime /*time*/)
40
{
41
	if (address == 0xBA00) {
42
		// write of block offset
43
		blockOffset = value;
44
		// retro-actively select the blocks for this offset
45
		if (blockOffset >= 2) {
46
			for (auto i : xrange(2, 6)) {
47
				setRom(i, blockNr[i] + blockOffset - 2);
48
			}
49
		}
50
	} else if ((blockOffset >= 2) &&
51
		   (address == one_of(0x5000, 0x6000, 0x8000, 0xA000))) {
52
		setRom(address >> 13, value + blockOffset - 2);
53
	}
54
}
55
56
byte* RomMatraCompilation::getWriteCacheLine(uint16_t address)
57
{
58
	if ((0x5000 <= address) && (address < 0xC000)) {
59
		return nullptr;
60
	} else {
61
		return unmappedWrite.data();
62
	}
63
}
64
65
template<typename Archive>
66
void RomMatraCompilation::serialize(Archive& ar, unsigned /*version*/)
67
{
68
	ar.template serializeBase<Rom8kBBlocks>(*this);
69
70
	ar.serialize("blockOffset", blockOffset);
71
}
72
INSTANTIATE_SERIALIZE_METHODS(RomMatraCompilation);
73
REGISTER_MSXDEVICE(RomMatraCompilation, "RomMatraCompilation");
74
75
} // namespace openmsx