openMSX
PanasonicMemory.cc
Go to the documentation of this file.
1 #include "PanasonicMemory.hh"
2 #include "MSXMotherBoard.hh"
3 #include "MSXCPU.hh"
4 #include "Ram.hh"
5 #include "Rom.hh"
6 #include "DeviceConfig.hh"
7 #include "HardwareConfig.hh"
8 #include "XMLElement.hh"
9 #include "MSXException.hh"
10 #include "memory.hh"
11 
12 namespace openmsx {
13 
14 static std::unique_ptr<Rom> createRom(MSXMotherBoard& motherBoard)
15 {
16  const XMLElement* elem = motherBoard.getMachineConfig()->
17  getConfig().findChild("PanasonicRom");
18  if (!elem) return nullptr;
19 
20  const HardwareConfig* hwConf = motherBoard.getMachineConfig();
21  assert(hwConf);
22  return make_unique<Rom>(
23  "PanasonicRom", "Turbor-R main ROM",
24  DeviceConfig(*hwConf, *elem));
25 }
26 
28  : msxcpu(motherBoard.getCPU())
29  , rom(createRom(motherBoard))
30  , ram(nullptr), ramSize(0)
31  , dram(false)
32 {
33 }
34 
36 
38 {
39  ram = &ram_[0];
40  ramSize = ram_.getSize();
41 }
42 
43 const byte* PanasonicMemory::getRomBlock(unsigned block)
44 {
45  if (!rom) {
46  throw MSXException("Missing PanasonicRom.");
47  }
48  if (dram &&
49  (((0x28 <= block) && (block < 0x2C)) ||
50  ((0x38 <= block) && (block < 0x3C)))) {
51  assert(ram);
52  unsigned offset = (block & 0x03) * 0x2000;
53  unsigned ramOffset = (block < 0x30) ? ramSize - 0x10000 :
54  ramSize - 0x08000;
55  return ram + ramOffset + offset;
56  } else {
57  unsigned offset = block * 0x2000;
58  if (offset >= rom->getSize()) {
59  offset &= rom->getSize() - 1;
60  }
61  return &(*rom)[offset];
62  }
63 }
64 
65 const byte* PanasonicMemory::getRomRange(unsigned first, unsigned last)
66 {
67  if (!rom) {
68  throw MSXException("Missing PanasonicRom.");
69  }
70  if (last < first) {
71  throw MSXException("Error in config file: firstblock must "
72  "be smaller than lastblock");
73  }
74  unsigned start = first * 0x2000;
75  if (start >= rom->getSize()) {
76  throw MSXException("Error in config file: firstblock lies "
77  "outside of rom image.");
78  }
79  unsigned stop = (last + 1) * 0x2000;
80  if (stop > rom->getSize()) {
81  throw MSXException("Error in config file: lastblock lies "
82  "outside of rom image.");
83  }
84  return &(*rom)[start];
85 }
86 
88 {
89  if (!ram) return nullptr;
90 
91  unsigned offset = block * 0x2000;
92  if (offset >= ramSize) {
93  offset &= ramSize - 1;
94  }
95  return ram + offset;
96 }
97 
98 void PanasonicMemory::setDRAM(bool dram_)
99 {
100  if (dram_ != dram) {
101  dram = dram_;
102  msxcpu.invalidateMemCache(0x0000, 0x10000);
103  }
104 }
105 
106 bool PanasonicMemory::isWritable(unsigned address) const
107 {
108  return !dram || (address < (ramSize - 0x10000));
109 }
110 
111 } // namespace openmsx
const byte * getRomRange(unsigned first, unsigned last)
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
void registerRam(Ram &ram)
Pass reference of the actual Ram block for use in DRAM mode and RAM access via the ROM mapper...
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
byte * getRamBlock(unsigned block)
Note that this is always unchecked RAM! There is no UMR detection when accessing Ram in DRAM mode or ...
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
PanasonicMemory(MSXMotherBoard &motherBoard)
bool isWritable(unsigned address) const
const byte * getRomBlock(unsigned block)
unsigned getSize() const
Definition: Ram.hh:33