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 "likely.hh"
8 #include "xrange.hh"
9 #include <cassert>
10 
11 namespace openmsx {
12 
13 CheckedRam::CheckedRam(const DeviceConfig& config, const std::string& name,
14  static_string_view description, unsigned 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 
28 byte CheckedRam::read(unsigned addr)
29 {
30  unsigned line = addr >> CacheLine::BITS;
31  if (unlikely(!completely_initialized_cacheline[line])) {
32  if (unlikely(uninitialized[line][addr & CacheLine::LOW])) {
33  umrCallback.execute(addr, ram.getName());
34  }
35  }
36  return ram[addr];
37 }
38 
39 const byte* CheckedRam::getReadCacheLine(unsigned addr) const
40 {
41  return (completely_initialized_cacheline[addr >> CacheLine::BITS])
42  ? &ram[addr] : nullptr;
43 }
44 
45 byte* CheckedRam::getWriteCacheLine(unsigned addr) const
46 {
47  return (completely_initialized_cacheline[addr >> CacheLine::BITS])
48  ? const_cast<byte*>(&ram[addr]) : nullptr;
49 }
50 
51 byte* CheckedRam::getRWCacheLines(unsigned addr, unsigned size) const
52 {
53  // TODO optimize
54  unsigned num = size >> CacheLine::BITS;
55  unsigned 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 
64 void CheckedRam::write(unsigned addr, const byte value)
65 {
66  unsigned line = addr >> CacheLine::BITS;
67  if (unlikely(!completely_initialized_cacheline[line])) {
68  uninitialized[line][addr & CacheLine::LOW] = false;
69  if (unlikely(uninitialized[line].none())) {
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 
91 void CheckedRam::init()
92 {
93  auto lines = ram.getSize() / 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 
110 void 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:27
const byte * getReadCacheLine(unsigned addr) const
Definition: CheckedRam.cc:39
byte * getRWCacheLines(unsigned addr, unsigned size) const
Definition: CheckedRam.cc:51
byte read(unsigned addr)
Definition: CheckedRam.cc:28
void write(unsigned addr, byte value)
Definition: CheckedRam.cc:64
CheckedRam(const DeviceConfig &config, const std::string &name, static_string_view description, unsigned size)
Definition: CheckedRam.cc:13
byte * getWriteCacheLine(unsigned addr) const
Definition: CheckedRam.cc:45
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:180
unsigned getSize() const
Definition: Ram.hh:44
void clear(byte c=0xff)
Definition: Ram.cc:35
const std::string & getName() const
Definition: Ram.cc:79
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
#define unlikely(x)
Definition: likely.hh:15
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:155