OXYGENHUB
◆ main openmsx / src / MSXS1985.cc
2.9 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#include "MSXS1985.hh"
2
3
#include "MSXMapperIO.hh"
4
#include "MSXMotherBoard.hh"
5
#include "SRAM.hh"
6
#include "serialize.hh"
7
8
#include "enumerate.hh"
9
#include "narrow.hh"
10
11
#include <array>
12
#include <memory>
13
14
namespace openmsx {
15
16
static constexpr uint8_t ID = 0xFE;
17
18
MSXS1985::MSXS1985(const DeviceConfig& config)
19
	: MSXDevice(config)
20
	, MSXSwitchedDevice(getMotherBoard(), ID)
21
{
22
	if (!config.findChild("sramname")) {
23
		// special case for backwards compatibility (S1985 didn't
24
		// always have SRAM in its config...)
25
		sram = std::make_unique<SRAM>(
26
			getName() + " SRAM", "S1985 Backup RAM",
27
			0x10, config, SRAM::DontLoadTag{});
28
	} else {
29
		sram = std::make_unique<SRAM>(
30
			getName() + " SRAM", "S1985 Backup RAM",
31
			0x10, config);
32
	}
33
34
	auto& mapperIO = getMotherBoard().createMapperIO();
35
	uint8_t mask = 0b0001'1111; // always(?) 5 bits
36
	auto baseValue = narrow_cast<uint8_t>(config.getChildDataAsInt("MapperReadBackBaseValue", 0x80));
37
	mapperIO.setMode(MSXMapperIO::Mode::INTERNAL, mask, baseValue);
38
39
	reset(EmuTime::dummy());
40
}
41
42
MSXS1985::~MSXS1985()
43
{
44
	getMotherBoard().destroyMapperIO();
45
}
46
47
void MSXS1985::reset(EmuTime /*time*/)
48
{
49
	color1 = color2 = pattern = address = 0; // TODO check this
50
}
51
52
uint8_t MSXS1985::readSwitchedIO(uint16_t port, EmuTime time)
53
{
54
	uint8_t result = peekSwitchedIO(port, time);
55
	switch (port & 0x0F) {
56
	case 7:
57
		pattern = uint8_t((pattern << 1) | (pattern >> 7));
58
		break;
59
	}
60
	return result;
61
}
62
63
uint8_t MSXS1985::peekSwitchedIO(uint16_t port, EmuTime /*time*/) const
64
{
65
	switch (port & 0x0F) {
66
	case 0:
67
		return uint8_t(~ID);
68
	case 2:
69
		return (*sram)[address];
70
	case 7:
71
		return (pattern & 0x80) ? color2 : color1;
72
	default:
73
		return 0xFF;
74
	}
75
}
76
77
void MSXS1985::writeSwitchedIO(uint16_t port, uint8_t value, EmuTime /*time*/)
78
{
79
	switch (port & 0x0F) {
80
	case 1:
81
		address = value & 0x0F;
82
		break;
83
	case 2:
84
		sram->write(address, value);
85
		break;
86
	case 6:
87
		color2 = color1;
88
		color1 = value;
89
		break;
90
	case 7:
91
		pattern = value;
92
		break;
93
	}
94
}
95
96
// version 1: initial version
97
// version 2: replaced RAM with SRAM
98
template<typename Archive>
99
void MSXS1985::serialize(Archive& ar, unsigned version)
100
{
101
	ar.template serializeBase<MSXDevice>(*this);
102
	// no need to serialize MSXSwitchedDevice base class
103
104
	if (ar.versionAtLeast(version, 2)) {
105
		// serialize normally...
106
		ar.serialize("sram", *sram);
107
	} else {
108
		assert(Archive::IS_LOADER);
109
		// version 1 had here
110
		//    <ram>
111
		//      <ram encoding="..">...</ram>
112
		//    </ram>
113
		// deserialize that structure and transfer it to SRAM
114
		std::array<uint8_t, 0x10> tmp;
115
		ar.beginTag("ram");
116
		ar.serialize_blob("ram", tmp);
117
		ar.endTag("ram");
118
		for (auto [i, t] : enumerate(tmp)) {
119
			sram->write(unsigned(i), t);
120
		}
121
	}
122
123
	ar.serialize("address", address,
124
	             "color1",  color1,
125
	             "color2",  color2,
126
	             "pattern", pattern);
127
}
128
INSTANTIATE_SERIALIZE_METHODS(MSXS1985);
129
REGISTER_MSXDEVICE(MSXS1985, "S1985");
130
131
} // namespace openmsx