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 "narrow.hh"
11#include <memory>
12
13namespace openmsx {
14
16 : msxcpu(motherBoard.getCPU())
17 , rom([&]() -> std::optional<Rom> {
18 const auto* elem = motherBoard.getMachineConfig()->
19 getConfig().findChild("PanasonicRom");
20 if (!elem) return std::nullopt;
21
22 const HardwareConfig* hwConf = motherBoard.getMachineConfig();
23 assert(hwConf);
24 return std::optional<Rom>(std::in_place,
25 "PanasonicRom", "Turbor-R main ROM",
26 DeviceConfig(*hwConf, *elem));
27 }())
28{
29}
30
32{
33 ram = ram_.data();
34 ramSize = narrow<unsigned>(ram_.size());
35}
36
37std::span<const byte, 0x2000> PanasonicMemory::getRomBlock(unsigned block) const
38{
39 if (!rom) {
40 throw MSXException("Missing PanasonicRom.");
41 }
42 if (dram &&
43 (((0x28 <= block) && (block < 0x2C)) ||
44 ((0x38 <= block) && (block < 0x3C)))) {
45 assert(ram);
46 unsigned offset = (block & 0x03) * 0x2000;
47 unsigned ramOffset = (block < 0x30) ? ramSize - 0x10000 :
48 ramSize - 0x08000;
49 return std::span<const byte, 0x2000>{ram + ramOffset + offset, 0x2000};
50 } else {
51 unsigned offset = block * 0x2000;
52 if (offset >= rom->size()) {
53 offset &= rom->size() - 1;
54 }
55 return subspan<0x2000>(*rom, offset);
56 }
57}
58
59std::span<const byte> PanasonicMemory::getRomRange(unsigned first, unsigned last) const
60{
61 if (!rom) {
62 throw MSXException("Missing PanasonicRom.");
63 }
64 if (last < first) {
65 throw MSXException("Error in config file: firstblock must "
66 "be smaller than lastblock");
67 }
68 unsigned start = first * 0x2000;
69 if (start >= rom->size()) {
70 throw MSXException("Error in config file: firstblock lies "
71 "outside of rom image.");
72 }
73 unsigned stop = (last + 1) * 0x2000;
74 if (stop > rom->size()) {
75 throw MSXException("Error in config file: lastblock lies "
76 "outside of rom image.");
77 }
78 return subspan(*rom, start, stop - start);
79}
80
81byte* PanasonicMemory::getRamBlock(unsigned block)
82{
83 if (!ram) return nullptr;
84
85 unsigned offset = block * 0x2000;
86 if (offset >= ramSize) {
87 offset &= ramSize - 1;
88 }
89 return ram + offset;
90}
91
93{
94 if (dram_ != dram) {
95 dram = dram_;
96 msxcpu.invalidateAllSlotsRWCache(0x0000, 0x10000);
97 }
98}
99
100bool PanasonicMemory::isWritable(unsigned address) const
101{
102 return !dram || (address < (ramSize - 0x10000));
103}
104
105} // namespace openmsx
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:178
const HardwareConfig * getMachineConfig() const
void registerRam(Ram &ram)
Pass reference of the actual Ram block for use in DRAM mode and RAM access via the ROM mapper.
bool isWritable(unsigned address) const
PanasonicMemory(MSXMotherBoard &motherBoard)
byte * getRamBlock(unsigned block)
Note that this is always unchecked RAM! There is no UMR detection when accessing Ram in DRAM mode or ...
std::span< const byte, 0x2000 > getRomBlock(unsigned block) const
std::span< const byte > getRomRange(unsigned first, unsigned last) const
auto size() const
Definition: Ram.hh:44
auto data()
Definition: Ram.hh:45
This file implemented 3 utility functions:
Definition: Autofire.cc:9
STL namespace.
constexpr auto subspan(Range &&range, size_t offset, size_t count=std::dynamic_extent)
Definition: ranges.hh:446