openMSX
Ram.cc
Go to the documentation of this file.
1#include "Ram.hh"
2#include "DeviceConfig.hh"
3#include "XMLElement.hh"
4#include "Base64.hh"
5#include "HexDump.hh"
6#include "MSXException.hh"
7#include "narrow.hh"
8#include "one_of.hh"
9#include "serialize.hh"
10#include <zlib.h>
11#include <algorithm>
12#include <memory>
13
14namespace openmsx {
15
16Ram::Ram(const DeviceConfig& config, const std::string& name,
17 static_string_view description, size_t size)
18 : xml(*config.getXML())
19 , ram(size)
20 , sz(size)
21 , debuggable(std::in_place,
22 config.getMotherBoard(), name, description, *this)
23{
24 clear();
25}
26
27Ram::Ram(const XMLElement& xml_, size_t size)
28 : xml(xml_)
29 , ram(size)
30 , sz(size)
31{
32 clear();
33}
34
35void Ram::clear(byte c)
36{
37 if (const auto* init = xml.findChild("initialContent")) {
38 // get pattern (and decode)
39 auto encoding = init->getAttributeValue("encoding");
40 size_t done = 0;
41 if (encoding == "gz-base64") {
42 auto [buf, bufSize] = Base64::decode(init->getData());
43 auto dstLen = narrow<uLongf>(size());
44 if (uncompress(reinterpret_cast<Bytef*>(ram.data()), &dstLen,
45 reinterpret_cast<const Bytef*>(buf.data()), uLong(bufSize))
46 != Z_OK) {
47 throw MSXException("Error while decompressing initialContent.");
48 }
49 done = dstLen;
50 } else if (encoding == one_of("hex", "base64")) {
51 auto [buf, bufSize] = (encoding == "hex")
52 ? HexDump::decode(init->getData())
53 : Base64 ::decode(init->getData());
54 if (bufSize == 0) {
55 throw MSXException("Zero-length initial pattern");
56 }
57 done = std::min(size(), bufSize);
58 ranges::copy(std::span{buf.data(), done}, ram.data());
59 } else {
60 throw MSXException("Unsupported encoding \"", encoding,
61 "\" for initialContent");
62 }
63
64 // repeat pattern over whole ram
65 auto left = size() - done;
66 while (left) {
67 auto tmp = std::min(done, left);
68 ranges::copy(std::span{ram.data(), tmp}, &ram[done]);
69 done += tmp;
70 left -= tmp;
71 }
72 } else {
73 // no init pattern specified
74 ranges::fill(*this, c);
75 }
76}
77
78const std::string& Ram::getName() const
79{
80 return debuggable->getName();
81}
82
84 const std::string& name_,
85 static_string_view description_, Ram& ram_)
86 : SimpleDebuggable(motherBoard_, name_, description_, narrow<unsigned>(ram_.size()))
87 , ram(ram_)
88{
89}
90
91byte RamDebuggable::read(unsigned address)
92{
93 return ram[address];
94}
95
96void RamDebuggable::write(unsigned address, byte value)
97{
98 ram[address] = value;
99}
100
101
102template<typename Archive>
103void Ram::serialize(Archive& ar, unsigned /*version*/)
104{
105 // ar.serialize_blob("ram", std::span{*this}); // TODO error with clang-15/libc++
106 ar.serialize_blob("ram", std::span{begin(), end()});
107}
109
110} // namespace openmsx
Definition: one_of.hh:7
const T * data() const
Returns pointer to the start of the memory buffer.
Definition: MemBuffer.hh:81
byte read(unsigned address) override
Definition: Ram.cc:91
void write(unsigned address, byte value) override
Definition: Ram.cc:96
RamDebuggable(MSXMotherBoard &motherBoard, const std::string &name, static_string_view description, Ram &ram)
Definition: Ram.cc:83
Ram(const DeviceConfig &config, const std::string &name, static_string_view description, size_t size)
Create Ram object with an associated debuggable.
Definition: Ram.cc:16
auto size() const
Definition: Ram.hh:44
auto end()
Definition: Ram.hh:49
void serialize(Archive &ar, unsigned version)
Definition: Ram.cc:103
auto begin()
Definition: Ram.hh:47
void clear(byte c=0xff)
Definition: Ram.cc:35
const std::string & getName() const
Definition: Ram.cc:78
const XMLElement * findChild(std::string_view childName) const
Definition: XMLElement.cc:19
static_string_view
constexpr vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:267
This file implemented 3 utility functions:
Definition: Autofire.cc:9
constexpr void fill(ForwardRange &&range, const T &value)
Definition: ranges.hh:287
auto copy(InputRange &&range, OutputIter out)
Definition: ranges.hh:232
STL namespace.
size_t size(std::string_view utf8)
constexpr To narrow(From from) noexcept
Definition: narrow.hh:37
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1021