openMSX
SRAM.cc
Go to the documentation of this file.
1#include "SRAM.hh"
2#include "DeviceConfig.hh"
3#include "File.hh"
4#include "FileContext.hh"
5#include "FileException.hh"
7#include "Reactor.hh"
8#include "CliComm.hh"
9#include "serialize.hh"
10#include "openmsx.hh"
11#include "vla.hh"
12#include <cstring>
13
14namespace openmsx {
15
16// class SRAM
17
18// Like the constructor below, but doesn't create a debuggable.
19// For use in unittests.
21 : ram(xml, size)
22 , header(nullptr) // not used
23{
24}
25
26/* Creates a SRAM that is not loaded from or saved to a file.
27 * The only reason to use this (instead of a plain Ram object) is when you
28 * dynamically need to decide whether load/save is needed.
29 */
30SRAM::SRAM(const std::string& name, static_string_view description,
31 int size, const DeviceConfig& config_, DontLoadTag)
32 : ram(config_, name, description, size)
33 , header(nullptr) // not used
34{
35}
36
37SRAM::SRAM(const std::string& name, int size,
38 const DeviceConfig& config_, const char* header_, bool* loaded)
39 : schedulable(std::in_place, config_.getReactor().getRTScheduler(), *this)
40 , config(config_)
41 , ram(config, name, "sram", size)
42 , header(header_)
43{
44 load(loaded);
45}
46
47SRAM::SRAM(const std::string& name, static_string_view description, int size,
48 const DeviceConfig& config_, const char* header_, bool* loaded)
49 : schedulable(std::in_place, config_.getReactor().getRTScheduler(), *this)
50 , config(config_)
51 , ram(config, name, description, size)
52 , header(header_)
53{
54 load(loaded);
55}
56
58{
59 if (schedulable) {
60 save();
61 }
62}
63
64void SRAM::write(unsigned addr, byte value)
65{
66 if (schedulable && !schedulable->isPendingRT()) {
67 schedulable->scheduleRT(5000000); // sync to disk after 5s
68 }
69 assert(addr < getSize());
70 ram.write(addr, value);
71}
72
73void SRAM::memset(unsigned addr, byte c, unsigned size)
74{
75 if (schedulable && !schedulable->isPendingRT()) {
76 schedulable->scheduleRT(5000000); // sync to disk after 5s
77 }
78 assert((addr + size) <= getSize());
79 ::memset(ram.getWriteBackdoor() + addr, c, size);
80}
81
82void SRAM::load(bool* loaded)
83{
84 assert(config.getXML());
85 if (loaded) *loaded = false;
86 const auto& filename = config.getChildData("sramname");
87 try {
88 bool headerOk = true;
91 if (header) {
92 size_t length = strlen(header);
93 VLA(char, temp, length);
94 file.read(temp, length);
95 if (memcmp(temp, header, length) != 0) {
96 headerOk = false;
97 }
98 }
99 if (headerOk) {
100 file.read(ram.getWriteBackdoor(), getSize());
101 loadedFilename = file.getURL();
102 if (loaded) *loaded = true;
103 } else {
104 config.getCliComm().printWarning(
105 "Warning no correct SRAM file: ", filename);
106 }
107 } catch (FileNotFoundException& /*e*/) {
108 config.getCliComm().printInfo(
109 "SRAM file ", filename, " not found, "
110 "assuming blank SRAM content.");
111 } catch (FileException& e) {
112 config.getCliComm().printWarning(
113 "Couldn't load SRAM ", filename,
114 " (", e.getMessage(), ").");
115 }
116}
117
118void SRAM::save()
119{
120 assert(config.getXML());
121 const auto& filename = config.getChildData("sramname");
122 try {
123 File file(config.getFileContext().resolveCreate(filename),
125 if (header) {
126 int length = int(strlen(header));
127 file.write(header, length);
128 }
129 file.write(&ram[0], getSize());
130 } catch (FileException& e) {
131 config.getCliComm().printWarning(
132 "Couldn't save SRAM ", filename,
133 " (", e.getMessage(), ").");
134 }
135}
136
137void SRAM::SRAMSchedulable::executeRT()
138{
139 sram.save();
140}
141
142template<typename Archive>
143void SRAM::serialize(Archive& ar, unsigned /*version*/)
144{
145 ar.serialize("ram", ram);
146}
148
149} // namespace openmsx
void printInfo(std::string_view message)
Definition: CliComm.cc:5
void printWarning(std::string_view message)
Definition: CliComm.cc:10
CliComm & getCliComm() const
Definition: DeviceConfig.cc:18
const FileContext & getFileContext() const
Definition: DeviceConfig.cc:9
std::string_view getChildData(std::string_view name) const
Definition: DeviceConfig.cc:48
const XMLElement * getXML() const
Definition: DeviceConfig.hh:48
std::string resolveCreate(std::string_view filename) const
Definition: FileContext.cc:86
@ SAVE_PERSISTENT
Definition: File.hh:23
@ LOAD_PERSISTENT
Definition: File.hh:22
void write(unsigned addr, byte value)
Definition: SRAM.cc:64
unsigned getSize() const
Definition: SRAM.hh:33
SRAM(int size, const XMLElement &xml, DontLoadTag)
Definition: SRAM.cc:20
void memset(unsigned addr, byte c, unsigned size)
Definition: SRAM.cc:73
void serialize(Archive &ar, unsigned version)
Definition: SRAM.cc:143
void write(unsigned addr, byte value)
Definition: TrackedRam.hh:38
byte * getWriteBackdoor()
Definition: TrackedRam.hh:52
static_string_view
constexpr double e
Definition: Math.hh:18
T length(const vecN< N, T > &x)
Definition: gl_vec.hh:339
This file implemented 3 utility functions:
Definition: Autofire.cc:9
constexpr const char *const filename
STL namespace.
size_t size(std::string_view utf8)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1009
#define VLA(TYPE, NAME, LENGTH)
Definition: vla.hh:10