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 <cassert>
9 
10 namespace openmsx {
11 
12 static std::bitset<CacheLine::SIZE> getBitSetAllTrue()
13 {
14  std::bitset<CacheLine::SIZE> result;
15  result.set();
16  return result;
17 }
18 
19 CheckedRam::CheckedRam(const DeviceConfig& config, const std::string& name,
20  const std::string& description, unsigned size)
21  : completely_initialized_cacheline(size / CacheLine::SIZE, false)
22  , uninitialized(size / CacheLine::SIZE, getBitSetAllTrue())
23  , ram(config, name, description, size)
24  , msxcpu(config.getMotherBoard().getCPU())
25  , umrCallback(config.getGlobalSettings().getUMRCallBackSetting())
26 {
27  umrCallback.getSetting().attach(*this);
28  init();
29 }
30 
32 {
33  umrCallback.getSetting().detach(*this);
34 }
35 
36 byte CheckedRam::read(unsigned addr)
37 {
38  unsigned line = addr >> CacheLine::BITS;
39  if (unlikely(!completely_initialized_cacheline[line])) {
40  if (unlikely(uninitialized[line][addr & CacheLine::LOW])) {
41  umrCallback.execute(addr, ram.getName());
42  }
43  }
44  return ram[addr];
45 }
46 
47 const byte* CheckedRam::getReadCacheLine(unsigned addr) const
48 {
49  return (completely_initialized_cacheline[addr >> CacheLine::BITS])
50  ? &ram[addr] : nullptr;
51 }
52 
53 byte* CheckedRam::getWriteCacheLine(unsigned addr) const
54 {
55  return (completely_initialized_cacheline[addr >> CacheLine::BITS])
56  ? const_cast<byte*>(&ram[addr]) : nullptr;
57 }
58 
59 void CheckedRam::write(unsigned addr, const byte value)
60 {
61  unsigned line = addr >> CacheLine::BITS;
62  if (unlikely(!completely_initialized_cacheline[line])) {
63  uninitialized[line][addr & CacheLine::LOW] = false;
64  if (unlikely(uninitialized[line].none())) {
65  completely_initialized_cacheline[line] = true;
66  msxcpu.invalidateMemCache(addr & CacheLine::HIGH,
67  CacheLine::SIZE);
68  }
69  }
70  ram[addr] = value;
71 }
72 
74 {
75  ram.clear();
76  init();
77 }
78 
79 void CheckedRam::init()
80 {
81  if (umrCallback.getValue().empty()) {
82  // there is no callback function,
83  // do as if everything is initialized
84  completely_initialized_cacheline.assign(
85  completely_initialized_cacheline.size(), true);
86  uninitialized.assign(
87  uninitialized.size(), std::bitset<CacheLine::SIZE>());
88  } else {
89  // new callback function, forget about initialized areas
90  completely_initialized_cacheline.assign(
91  completely_initialized_cacheline.size(), false);
92  uninitialized.assign(
93  uninitialized.size(), getBitSetAllTrue());
94  }
95  msxcpu.invalidateMemCache(0, 0x10000);
96 }
97 
98 void CheckedRam::update(const Setting& setting)
99 {
100  assert(&setting == &umrCallback.getSetting());
101  (void)setting;
102  init();
103 }
104 
105 } // namespace openmsx
StringSetting & getSetting() const
Definition: TclCallback.hh:31
const std::string & getName() const
Definition: Ram.cc:95
#define unlikely(x)
Definition: likely.hh:15
const byte * getReadCacheLine(unsigned addr) const
Definition: CheckedRam.cc:47
TclObject getValue() const
Definition: TclCallback.cc:35
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
TclObject execute()
Definition: TclCallback.cc:40
bool empty() const
Definition: TclObject.hh:159
void write(unsigned addr, byte value)
Definition: CheckedRam.cc:59
void invalidateMemCache(word start, unsigned size)
Invalidate the CPU its cache for the interval [start, start + size) For example MSXMemoryMapper and M...
Definition: MSXCPU.cc:147
void clear(byte c=0xff)
Definition: Ram.cc:51
void attach(Observer< T > &observer)
Definition: Subject.hh:45
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
byte read(unsigned addr)
Definition: CheckedRam.cc:36
void detach(Observer< T > &observer)
Definition: Subject.hh:51
constexpr auto size(const C &c) -> decltype(c.size())
Definition: span.hh:62
CheckedRam(const DeviceConfig &config, const std::string &name, const std::string &description, unsigned size)
Definition: CheckedRam.cc:19
byte * getWriteCacheLine(unsigned addr) const
Definition: CheckedRam.cc:53