OXYGENHUB
◆ main openmsx / src / memory / RomZemina90in1.cc
1.7 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
// Zemina 90-in-1 cartridge
2
//
3
//  90 in 1 uses Port &H77 for mapping:
4
//    bits 0-5: selected 16KB page
5
//    bits 6-7: addressing mode...
6
//      00 = same page at 4000-7FFF and 8000-BFFF (normal mode)
7
//      01 = same page at 4000-7FFF and 8000-BFFF (normal mode)
8
//      10 = [page AND 3E] at 4000-7FFF, [page AND 3E OR 01] at 8000-BFFF
9
//           (32KB mode)
10
//      11 = same page at 4000-7FFF and 8000-BFFF, but 8000-BFFF has high 8KB
11
//           and low 8KB swapped (Namco mode)
12
13
#include "RomZemina90in1.hh"
14
#include "MSXCPUInterface.hh"
15
#include "serialize.hh"
16
#include "unreachable.hh"
17
18
namespace openmsx {
19
20
RomZemina90in1::RomZemina90in1(const DeviceConfig& config, Rom&& rom_)
21
	: Rom8kBBlocks(config, std::move(rom_))
22
{
23
	reset(EmuTime::dummy());
24
	getCPUInterface().register_IO_Out(0x77, this);
25
}
26
27
RomZemina90in1::~RomZemina90in1()
28
{
29
	getCPUInterface().unregister_IO_Out(0x77, this);
30
}
31
32
void RomZemina90in1::reset(EmuTime time)
33
{
34
	setUnmapped(0);
35
	setUnmapped(1);
36
	setUnmapped(6);
37
	setUnmapped(7);
38
	writeIO(0x77, 0, time);
39
}
40
41
void RomZemina90in1::writeIO(uint16_t /*port*/, byte value, EmuTime /*time*/)
42
{
43
	byte page = 2 * (value & 0x3F);
44
	switch (value & 0xC0) {
45
	case 0x00:
46
	case 0x40:
47
		setRom(2, page + 0);
48
		setRom(3, page + 1);
49
		setRom(4, page + 0);
50
		setRom(5, page + 1);
51
		break;
52
	case 0x80:
53
		setRom(2, (page & ~2) + 0);
54
		setRom(3, (page & ~2) + 1);
55
		setRom(4, (page |  2) + 0);
56
		setRom(5, (page |  2) + 1);
57
		break;
58
	case 0xC0:
59
		setRom(2, page + 0);
60
		setRom(3, page + 1);
61
		setRom(4, page + 1);
62
		setRom(5, page + 0);
63
		break;
64
	default:
65
		UNREACHABLE;
66
	}
67
}
68
69
byte* RomZemina90in1::getWriteCacheLine(uint16_t /*address*/)
70
{
71
	return unmappedWrite.data();
72
}
73
74
REGISTER_MSXDEVICE(RomZemina90in1, "RomZemina90in1");
75
76
} // namespace openmsx