13[[nodiscard]]
static constexpr bool isInside(
unsigned x,
unsigned start,
unsigned len)
15 unsigned tmp = x - start;
19[[nodiscard]]
static std::string
toString(
unsigned start,
unsigned len)
21 return strCat(
"[0x", hex_string<4>(start),
", "
22 "0x", hex_string<4>(start + len),
')');
28 unsigned windowBase = 0x0000;
29 unsigned windowSize = 0x10000;
30 if (
const auto* mem = config.
findChild(
"mem")) {
31 windowBase = mem->getAttributeValueAsInt(
"base", 0);
32 windowSize = mem->getAttributeValueAsInt(
"size", 0);
36 if ((romSize_ > 0x10000) || (romSize_ & 0x1FFF)) {
38 ": invalid rom size: must be smaller than or equal to 64kB "
39 "and must be a multiple of 8kB.");
41 auto romSize = narrow<unsigned>(romSize_);
43 const int start = [&] {
62 unsigned romBase = (start == -1)
63 ? guessLocation(windowBase, windowSize)
66 (!isInside(romBase, windowBase, windowSize) ||
67 !isInside(romBase + romSize - 1, windowBase, windowSize))) {
72 ": invalid rom position: interval ",
73 toString(romBase, romSize),
" must fit in ",
74 toString(windowBase, windowSize),
'.');
76 if ((romBase & 0x1FFF)) {
78 ": invalid rom position: must start at a 8kB boundary.");
81 unsigned firstPage = romBase / 0x2000;
82 unsigned numPages = romSize / 0x2000;
83 for (
auto page :
xrange(8)) {
84 unsigned romPage = page - firstPage;
85 if (romPage < numPages) {
89 setRom(page, romPage & (numPages - 1));
112void RomPlain::guessHelper(
unsigned offset, std::span<int, 3> pages)
114 if ((
rom[offset++] ==
'A') && (
rom[offset++] ==
'B')) {
115 for (
auto i :
xrange(4)) {
116 if (
auto addr =
rom[offset + 2 * i + 0] +
117 rom[offset + 2 * i + 1] * 256) {
118 unsigned page = (addr >> 14) - (offset >> 14);
127unsigned RomPlain::guessLocation(
unsigned windowBase,
unsigned windowSize)
129 std::array<int, 3> pages = {0, 0, 0};
133 guessHelper(0x0000, pages);
136 guessHelper(0x4000, pages);
140 if (!isInside(0x0000, windowBase, windowSize)) pages[0] = 0;
141 if (!isInside(0x4000, windowBase, windowSize)) pages[1] = 0;
142 if (!isInside(0x8000, windowBase, windowSize)) pages[2] = 0;
145 if (pages[1] && (pages[1] >= pages[0]) && (pages[1] >= pages[2])) {
147 }
else if (pages[0] && pages[0] >= pages[2]) {
149 }
else if (pages[2]) {
const XMLElement * findChild(std::string_view name) const
void invalidateDeviceRCache()
virtual unsigned getBaseSizeAlignment() const
The 'base' and 'size' attribute values need to be at least aligned to CacheLine::SIZE.
void setUnmapped(unsigned region)
Select 'unmapped' memory for this region.
void setRom(unsigned region, unsigned block)
Selects a block of the ROM image for reading in a certain region.
unsigned getBaseSizeAlignment() const override
The 'base' and 'size' attribute values need to be at least aligned to CacheLine::SIZE.
RomPlain(const DeviceConfig &config, Rom &&rom, RomType type)
const std::string & getName() const
This file implemented 3 utility functions:
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
std::string toString(const Event &event)
Get a string representation of this event.
std::string strCat(Ts &&...ts)
constexpr auto xrange(T e)