OXYGENHUB
◆ main openmsx / src / memory / RomKonami.cc
2.2 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
// KONAMI 8kB cartridges (without SCC)
2
//
3
// this type is used by Konami cartridges without SCC and some others
4
// examples of cartridges: Nemesis, Penguin Adventure, Usas, Metal Gear, Shalom,
5
// The Maze of Galious, Aleste 1, 1942, Heaven, Mystery World, ...
6
// (the latter four are hacked ROM images with modified mappers)
7
//
8
// page at 4000 is fixed, other banks are switched by writing at
9
// 0x6000, 0x8000 and 0xA000 (those addresses are used by the games, but any
10
// other address in a page switches that page as well)
11
12
#include "RomKonami.hh"
13
14
#include "MSXCliComm.hh"
15
#include "MSXMotherBoard.hh"
16
#include "serialize.hh"
17
18
#include "xrange.hh"
19
20
namespace openmsx {
21
22
RomKonami::RomKonami(const DeviceConfig& config, Rom&& rom_)
23
	: Rom8kBBlocks(config, std::move(rom_))
24
{
25
	// Konami mapper is 256kB in size, even if ROM is smaller.
26
	setBlockMask(31);
27
28
	// warn if a ROM is used that would not work on a real Konami mapper
29
	if (rom.size() > 256 * 1024) {
30
		getMotherBoard().getMSXCliComm().printWarning(
31
			"The size of this ROM image is larger than 256kB, "
32
			"which is not supported on real Konami mapper chips!");
33
	}
34
	reset(EmuTime::dummy());
35
}
36
37
void RomKonami::bankSwitch(unsigned page, unsigned block)
38
{
39
	setRom(page, block);
40
41
	// Note: the mirror behavior is different from RomKonamiSCC !
42
	if (page == 2 || page == 3) {
43
		// [0x4000-0x8000), mirrored in [0x0000-0x4000)
44
		setRom(page - 2, block);
45
	} else if (page == 4 || page == 5) {
46
		// [0x8000-0xC000), mirrored in [0xC000-0x10000)
47
		setRom(page + 2, block);
48
	} else {
49
		assert(false);
50
	}
51
}
52
53
void RomKonami::reset(EmuTime /*time*/)
54
{
55
	for (auto i : xrange(2, 6)) {
56
		bankSwitch(i, i - 2);
57
	}
58
}
59
60
void RomKonami::writeMem(uint16_t address, byte value, EmuTime /*time*/)
61
{
62
	// Note: [0x4000..0x6000) is fixed at segment 0.
63
	if (0x6000 <= address && address < 0xC000) {
64
		bankSwitch(address >> 13, value);
65
	}
66
}
67
68
byte* RomKonami::getWriteCacheLine(uint16_t address)
69
{
70
	return (0x6000 <= address && address < 0xC000) ? nullptr : unmappedWrite.data();
71
}
72
73
template<typename Archive>
74
void RomKonami::serialize(Archive& ar, unsigned /*version*/)
75
{
76
	ar.template serializeBase<Rom8kBBlocks>(*this);
77
}
78
INSTANTIATE_SERIALIZE_METHODS(RomKonami);
79
REGISTER_MSXDEVICE(RomKonami, "RomKonami");
80
81
} // namespace openmsx