OXYGENHUB
◆ main openmsx / src / memory / MSXPac.cc
2.2 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#include "MSXPac.hh"
2
3
#include "CacheLine.hh"
4
#include "serialize.hh"
5
6
namespace openmsx {
7
8
static constexpr const char* const PAC_Header = "PAC2 BACKUP DATA";
9
10
MSXPac::MSXPac(const DeviceConfig& config)
11
	: MSXDevice(config)
12
	, sram(getName() + " SRAM", 0x1FFE, config, PAC_Header)
13
{
14
	reset(EmuTime::dummy());
15
}
16
17
void MSXPac::reset(EmuTime /*time*/)
18
{
19
	sramEnabled = false;
20
	r1ffe = r1fff = 0xFF; // TODO check
21
}
22
23
byte MSXPac::readMem(uint16_t address, EmuTime /*time*/)
24
{
25
	address &= 0x3FFF;
26
	if (sramEnabled) {
27
		if (address < 0x1FFE) {
28
			return sram[address];
29
		} else if (address == 0x1FFE) {
30
			return r1ffe;
31
		} else if (address == 0x1FFF) {
32
			return r1fff;
33
		} else {
34
			return 0xFF;
35
		}
36
	} else {
37
		return 0xFF;
38
	}
39
}
40
41
const byte* MSXPac::getReadCacheLine(uint16_t address) const
42
{
43
	address &= 0x3FFF;
44
	if (sramEnabled) {
45
		if (address < (0x1FFE & CacheLine::HIGH)) {
46
			return &sram[address];
47
		} else if (address == (0x1FFE & CacheLine::HIGH)) {
48
			return nullptr;
49
		} else {
50
			return unmappedRead.data();
51
		}
52
	} else {
53
		return unmappedRead.data();
54
	}
55
}
56
57
void MSXPac::writeMem(uint16_t address, byte value, EmuTime /*time*/)
58
{
59
	address &= 0x3FFF;
60
	switch (address) {
61
		case 0x1FFE:
62
			r1ffe = value;
63
			checkSramEnable();
64
			break;
65
		case 0x1FFF:
66
			r1fff = value;
67
			checkSramEnable();
68
			break;
69
		default:
70
			if (sramEnabled && (address < 0x1FFE)) {
71
				sram.write(address, value);
72
			}
73
	}
74
}
75
76
byte* MSXPac::getWriteCacheLine(uint16_t address)
77
{
78
	address &= 0x3FFF;
79
	if (address == (0x1FFE & CacheLine::HIGH)) {
80
		return nullptr;
81
	}
82
	if (sramEnabled && (address < 0x1FFE)) {
83
		return nullptr;
84
	} else {
85
		return unmappedWrite.data();
86
	}
87
}
88
89
void MSXPac::checkSramEnable()
90
{
91
	bool newEnabled = (r1ffe == 0x4D) && (r1fff == 0x69);
92
	if (sramEnabled != newEnabled) {
93
		sramEnabled = newEnabled;
94
		invalidateDeviceRWCache();
95
	}
96
}
97
98
template<typename Archive>
99
void MSXPac::serialize(Archive& ar, unsigned /*version*/)
100
{
101
	ar.template serializeBase<MSXDevice>(*this);
102
	ar.serialize("SRAM",  sram,
103
	             "r1ffe", r1ffe,
104
	             "r1fff", r1fff);
105
	if constexpr (Archive::IS_LOADER) {
106
		checkSramEnable();
107
	}
108
}
109
INSTANTIATE_SERIALIZE_METHODS(MSXPac);
110
REGISTER_MSXDEVICE(MSXPac, "PAC");
111
112
} // namespace openmsx