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