14 template<
bool C,
class T,
class F>
struct if_log2_ :
F {};
15 template<
class T,
class F>
struct if_log2_<true, T,
F> : T {};
16 template<
unsigned A,
unsigned R = 0>
struct log2
17 :
if_log2_<A == 1, std::integral_constant<int, R>, log2<A / 2, R + 1>> {};
19 template <
unsigned BANK_SIZE>
22 unsigned debugBankSizeShift)
23 :
MSXRom(config, std::move(rom_))
25 *this, blockNr, 0x0000, 0x10000,
26 log2<BANK_SIZE>::value, debugBankSizeShift))
27 , nrBlocks(rom->getSize() / BANK_SIZE)
29 if ((nrBlocks * BANK_SIZE) !=
rom->getSize()) {
31 "(uncompressed) ROM image filesize must be a multiple of " <<
32 BANK_SIZE / 1024 <<
" kB (for this mapper type).");
39 blockMask = nrBlocks - 1;
40 for (
unsigned i = 0; i < NUM_BANKS; i++) {
45 template <
unsigned BANK_SIZE>
50 template <
unsigned BANK_SIZE>
53 return bank[address / BANK_SIZE][address & BANK_MASK];
56 template <
unsigned BANK_SIZE>
59 return &bank[address / BANK_SIZE][address & BANK_MASK];
62 template <
unsigned BANK_SIZE>
65 assert(
"address passed to setBank() is not serializable" &&
66 ((adr == unmappedRead) ||
67 ((&(*rom)[0] <= adr) && (adr <= &(*rom)[rom->getSize() - 1])) ||
68 (sram.get() && (&(*sram)[0] <= adr) &&
69 (adr <= &(*sram)[sram->getSize() - 1])) ||
70 ((extraMem <= adr) && (adr <= &extraMem[extraSize - 1]))));
72 blockNr[region] = block;
73 invalidateMemCache(region * BANK_SIZE, BANK_SIZE);
76 template <
unsigned BANK_SIZE>
79 setBank(region, unmappedRead, 255);
82 template <
unsigned BANK_SIZE>
88 template <
unsigned BANK_SIZE>
95 template <
unsigned BANK_SIZE>
100 block = (block < nrBlocks) ? block : block & blockMask;
101 if (block < nrBlocks) {
102 setBank(region, &(*rom)[block * BANK_SIZE], block);
104 setBank(region, unmappedRead, 255);
110 template <
unsigned BANK_SIZE>
111 template<
typename Archive>
115 ar.template serializeBase<MSXDevice>(*this);
118 ar.serialize(
"sram", *sram);
121 unsigned offsets[NUM_BANKS];
122 unsigned romSize = rom->getSize();
123 unsigned sramSize = sram.get() ? sram->getSize() : 0;
125 ar.serialize(
"banks", offsets);
126 for (
unsigned i = 0; i < NUM_BANKS; ++i) {
127 if (offsets[i] ==
unsigned(-1)) {
128 bank[i] = unmappedRead;
129 }
else if (offsets[i] < romSize) {
130 bank[i] = &(*rom)[offsets[i]];
131 }
else if (offsets[i] < (romSize + sramSize)) {
133 bank[i] = &(*sram)[offsets[i] - romSize];
134 }
else if (offsets[i] < (romSize + sramSize + extraSize)) {
135 bank[i] = &extraMem[offsets[i] - romSize - sramSize];
142 for (
unsigned i = 0; i < NUM_BANKS; ++i) {
143 if (bank[i] == unmappedRead) {
144 offsets[i] = unsigned(-1);
145 }
else if ((&(*rom)[0] <= bank[i]) &&
146 (bank[i] <= &(*rom)[romSize - 1])) {
147 offsets[i] = unsigned(bank[i] - &(*rom)[0]);
148 }
else if (sram.get() &&
149 (&(*sram)[0] <= bank[i]) &&
150 (bank[i] <= &(*sram)[sramSize - 1])) {
151 offsets[i] = unsigned(bank[i] - &(*sram)[0] + romSize);
152 }
else if ((extraMem <= bank[i]) &&
153 (bank[i] <= &extraMem[extraSize - 1])) {
154 offsets[i] = unsigned(bank[i] - extraMem + romSize + sramSize);
159 ar.serialize(
"banks", offsets);