16[[nodiscard]]
static constexpr bool isInside(
unsigned x,
unsigned start,
unsigned len)
18 unsigned tmp = x - start;
22[[nodiscard]]
static std::string
toString(
unsigned start,
unsigned len)
24 return strCat(
"[0x", hex_string<4>(start),
", "
25 "0x", hex_string<4>(start + len),
')');
31 unsigned windowBase = 0x0000;
32 unsigned windowSize = 0x10000;
33 if (
const auto* mem = config.
findChild(
"mem")) {
34 windowBase = mem->getAttributeValueAsInt(
"base", 0);
35 windowSize = mem->getAttributeValueAsInt(
"size", 0);
39 if ((romSize_ > 0x10000) || (romSize_ & 0x1FFF)) {
41 ": invalid rom size: must be smaller than or equal to 64kB "
42 "and must be a multiple of 8kB.");
44 auto romSize = narrow<unsigned>(romSize_);
47 const int start = [&] {
66 unsigned romBase = (start == -1)
67 ? guessLocation(windowBase, windowSize)
70 (!isInside(romBase, windowBase, windowSize) ||
71 !isInside(romBase + romSize - 1, windowBase, windowSize))) {
76 ": invalid rom position: interval ",
77 toString(romBase, romSize),
" must fit in ",
78 toString(windowBase, windowSize),
'.');
80 if (romBase & 0x1FFF) {
82 ": invalid rom position: must start at a 8kB boundary.");
85 unsigned firstPage = romBase / 0x2000;
86 unsigned numPages = romSize / 0x2000;
87 for (
auto page :
xrange(8)) {
88 unsigned romPage = page - firstPage;
89 if (romPage < numPages) {
93 setRom(page, romPage & (numPages - 1));
116void RomPlain::guessHelper(
unsigned offset, std::span<int, 3> pages)
const
118 if ((
rom[offset + 0] ==
'A') && (
rom[offset + 1] ==
'B')) {
119 for (
auto i :
xrange(4)) {
120 if (
auto addr =
rom[offset + 2 + 2 * i + 0] +
121 rom[offset + 2 + 2 * i + 1] * 256) {
122 unsigned page = (addr >> 14) - (offset >> 14);
131unsigned RomPlain::guessLocation(
unsigned windowBase,
unsigned windowSize)
const
133 std::array<int, 3> pages = {0, 0, 0};
137 guessHelper(0x0000, pages);
140 guessHelper(0x4000, pages);
144 if (!isInside(0x0000, windowBase, windowSize)) pages[0] = 0;
145 if (!isInside(0x4000, windowBase, windowSize)) pages[1] = 0;
146 if (!isInside(0x8000, windowBase, windowSize)) pages[2] = 0;
149 if (pages[1] && (pages[1] >= pages[0]) && (pages[1] >= pages[2])) {
151 }
else if (pages[0] && pages[0] >= pages[2]) {
153 }
else if (pages[2]) {
#define REGISTER_MSXDEVICE(CLASS, NAME)
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:
std::string toString(const BooleanInput &input)
constexpr auto xrange(T e)