openMSX
CheckedRam.cc
Go to the documentation of this file.
1#include "CheckedRam.hh"
2#include "MSXCPU.hh"
3#include "MSXMotherBoard.hh"
4#include "DeviceConfig.hh"
5#include "GlobalSettings.hh"
6#include "StringSetting.hh"
7#include "narrow.hh"
8#include "xrange.hh"
9#include <cassert>
10
11namespace openmsx {
12
13CheckedRam::CheckedRam(const DeviceConfig& config, const std::string& name,
14 static_string_view description, size_t size)
15 : ram(config, name, description, size)
16 , msxcpu(config.getMotherBoard().getCPU())
17 , umrCallback(config.getGlobalSettings().getUMRCallBackSetting())
18{
19 umrCallback.getSetting().attach(*this);
20 init();
21}
22
24{
25 umrCallback.getSetting().detach(*this);
26}
27
28byte CheckedRam::read(size_t addr)
29{
30 size_t line = addr >> CacheLine::BITS;
31 if (!completely_initialized_cacheline[line]) [[unlikely]] {
32 if (uninitialized[line][addr & CacheLine::LOW]) [[unlikely]] {
33 umrCallback.execute(narrow<int>(addr), ram.getName());
34 }
35 }
36 return ram[addr];
37}
38
39const byte* CheckedRam::getReadCacheLine(size_t addr) const
40{
41 return (completely_initialized_cacheline[addr >> CacheLine::BITS])
42 ? &ram[addr] : nullptr;
43}
44
45byte* CheckedRam::getWriteCacheLine(size_t addr) const
46{
47 return (completely_initialized_cacheline[addr >> CacheLine::BITS])
48 ? const_cast<byte*>(&ram[addr]) : nullptr;
49}
50
51byte* CheckedRam::getRWCacheLines(size_t addr, size_t size) const
52{
53 // TODO optimize
54 size_t num = size >> CacheLine::BITS;
55 size_t first = addr >> CacheLine::BITS;
56 for (auto i : xrange(num)) {
57 if (!completely_initialized_cacheline[first + i]) {
58 return nullptr;
59 }
60 }
61 return const_cast<byte*>(&ram[addr]);
62}
63
64void CheckedRam::write(size_t addr, const byte value)
65{
66 size_t line = addr >> CacheLine::BITS;
67 if (!completely_initialized_cacheline[line]) [[unlikely]] {
68 uninitialized[line][addr & CacheLine::LOW] = false;
69 if (uninitialized[line].none()) [[unlikely]] {
70 completely_initialized_cacheline[line] = true;
71 // This invalidates way too much stuff. But because
72 // (locally) we don't know exactly how this class ie
73 // being used in the MSXDevice, there's no easy way to
74 // figure out what exactly should be invalidated.
75 //
76 // This is anyway only a debug feature (usually it's
77 // not in use), therefor it's OK to implement this in a
78 // easy/slow way rather than complex/fast.
79 msxcpu.invalidateAllSlotsRWCache(0, 0x10000);
80 }
81 }
82 ram[addr] = value;
83}
84
86{
87 ram.clear();
88 init();
89}
90
91void CheckedRam::init()
92{
93 auto lines = ram.size() / CacheLine::SIZE;
94 if (umrCallback.getValue().empty()) {
95 // there is no callback function,
96 // do as if everything is initialized
97 completely_initialized_cacheline.assign(lines, true);
98 // 'uninitialized' won't be accessed, so don't even allocate
99 } else {
100 // new callback function, forget about initialized areas
101 completely_initialized_cacheline.assign(lines, false);
102
103 std::bitset<CacheLine::SIZE> allTrue;
104 allTrue.set();
105 uninitialized.assign(lines, allTrue);
106 }
107 msxcpu.invalidateAllSlotsRWCache(0, 0x10000);
108}
109
110void CheckedRam::update(const Setting& setting) noexcept
111{
112 assert(&setting == &umrCallback.getSetting());
113 (void)setting;
114 init();
115}
116
117} // namespace openmsx
BaseSetting * setting
Definition: Interpreter.cc:28
byte * getRWCacheLines(size_t addr, size_t size) const
Definition: CheckedRam.cc:51
size_t size() const
Definition: CheckedRam.hh:42
byte * getWriteCacheLine(size_t addr) const
Definition: CheckedRam.cc:45
void write(size_t addr, byte value)
Definition: CheckedRam.cc:64
const byte * getReadCacheLine(size_t addr) const
Definition: CheckedRam.cc:39
CheckedRam(const DeviceConfig &config, const std::string &name, static_string_view description, size_t size)
Definition: CheckedRam.cc:13
byte read(size_t addr)
Definition: CheckedRam.cc:28
void invalidateAllSlotsRWCache(word start, unsigned size)
Invalidate the CPU its cache for the interval [start, start + size) For example MSXMemoryMapper and M...
Definition: MSXCPU.cc:176
auto size() const
Definition: Ram.hh:44
void clear(byte c=0xff)
Definition: Ram.cc:35
const std::string & getName() const
Definition: Ram.cc:78
void detach(Observer< T > &observer)
Definition: Subject.hh:56
void attach(Observer< T > &observer)
Definition: Subject.hh:50
TclObject execute()
Definition: TclCallback.cc:35
TclObject getValue() const
Definition: TclCallback.cc:30
StringSetting & getSetting() const
Definition: TclCallback.hh:31
bool empty() const
Definition: TclObject.hh:168
static_string_view
constexpr unsigned LOW
Definition: CacheLine.hh:9
constexpr unsigned BITS
Definition: CacheLine.hh:6
constexpr unsigned SIZE
Definition: CacheLine.hh:7
This file implemented 3 utility functions:
Definition: Autofire.cc:9
size_t size(std::string_view utf8)
constexpr auto xrange(T e)
Definition: xrange.hh:133