openMSX
MegaFlashRomSCCPlus.cc
Go to the documentation of this file.
3#include "MSXCPUInterface.hh"
4#include "CacheLine.hh"
5#include "ranges.hh"
6#include "serialize.hh"
7#include "xrange.hh"
8#include <array>
9#include <cassert>
10
11/******************************************************************************
12 * DOCUMENTATION AS PROVIDED BY MANUEL PAZOS, WHO DEVELOPED THE CARTRIDGE *
13 ******************************************************************************
14
15--------------------------------------------------------------------------------
16MegaFlashROM SCC+ Technical Details
17(c) Manuel Pazos 28-09-2010
18--------------------------------------------------------------------------------
19
20Main features:
21 - 1024KB flashROM memory (M29W800DB)
22 - SCC-I (2312P001)
23 - PSG (AY-3-8910/YM2149)
24 - Mappers: ASCII8, ASCII16, Konami, Konami SCC, linear 64K
25 - Subslot simulation (4 x 256K)
26
27
28--------------------------------------------------------------------------------
29[Memory]
30
31 - Model Numonix M29W800DB TSOP48
32 - Datasheet: http://www.numonyx.com/Documents/Datasheets/M29W800D.PDF
33 - Block layout:
34 #00000 16K
35 #04000 8K
36 #06000 8K
37 #08000 32K
38 #10000 64K x 15
39 - Command addresses #4555 and #5AAA
40 - Commands:
41 AUTOSELECT #90
42 WRITE #A0
43 CHIP_ERASE #10
44 BLOCK_ERASE #30
45 RESET #F0
46 - FlashROM ID = #5B
47
48
49--------------------------------------------------------------------------------
50[PSG]
51
52 The PSG included in the cartridge is mapped to ports #10-#12
53
54 Port #A0 -> #10
55 Port #A1 -> #11
56 Port #A2 -> #12
57
58 The PSG is read only.
59
60--------------------------------------------------------------------------------
61[REGISTERS]
62
63 -#7FFE or #7FFF = CONFIGURATION REGISTER:
64 7 mapper mode 1: \ %00 = SCC, %01 = 64K
65 6 mapper mode 0: / %10 = ASC8, %11 = ASC16
66 5 mapper mode : Select Konami mapper (0 = SCC, 1 = normal)
67 4 Enable subslot mode and register #FFFF (1 = Enable, 0 = Disable)
68 3 Disable #4000-#5FFF mapper in Konami mode (0 = Enable, 1 = Disable)
69 2 Disable configuration register (1 = Disabled)
70 1 Disable mapper registers (0 = Enable, 1 = Disable)
71 0 Enable 512K mapper limit in SCC mapper or 256K limit in Konami mapper
72(1 = Enable, 0 = Disable)
73
74
75--------------------------------------------------------------------------------
76[MAPPERS]
77
78 - ASCII 8: Common ASC8 mapper
79
80 - ASCII 16: Common ASC16 mapper
81
82 - Konami: Common Konami mapper.
83 Bank0 (#4000-#5FFF) can be also changed unless CONF_REG bit3 is 1
84
85 - Konami SCC: Common Konami SCC mapper
86 Bank0 mapper register: if bank number bit 7 is 1 then bit 6-0 sets mapper offset.
87
88 - Linear 64: #0000-#3FFF bank0
89 #4000-#7FFF bank1
90 #8000-#BFFF bank2
91 #C000-#FFFF bank3
92 Banks mapper registers addresses = Konami
93
94--------------------------------------------------------------------------------
95[DEFAULT VALUES]
96 - CONFIGURATION REGISTER = 0
97 - Bank0 = 0
98 - Bank1 = 1
99 - Bank2 = 2
100 - Bank3 = 3
101 - Bank offset = 0
102 - Subslot register = 0
103
104--------------------------------------------------------------------------------
105[LOGIC]
106
107 Banks0-3: are set depending on the mapper mode.
108 Subslots: are set writing to #FFFF in the MegaFlashROM SCC+ slot when CONFIG_REG bit 4 is set.
109 Offset: is set by writing offset value + #80 to bank0 mapper register in Konami SCC mode.
110
111 -- Subslots offsets
112 SubOff0 = subslot(1-0) & "0000" + mapOff; -- In 64K mode, the banks are 16K, with the offsets halved
113 SubOff1 = subslot(3-2) & "0000" + mapOff when maptyp = "10" else subslot(3-2) & "00000" + mapOff;
114 SubOff2 = subslot(5-4) & "0000" + mapOff when maptyp = "10" else subslot(5-4) & "00000" + mapOff;
115 SubOff3 = subslot(7-6) & "0000" + mapOff when maptyp = "10" else subslot(7-6) & "00000";
116
117 -- Calculate the bank mapper to use taking into account the offset
118 Bank0 = SubBank0(x) + SubOff0 when SccModeA(4) = '1' and subslot(1 downto 0) = "00" and maptyp = "10" else
119 SubBank0(1) + SubOff0 when SccModeA(4) = '1' and subslot(1 downto 0) = "01" and maptyp = "10" else
120 SubBank0(2) + SubOff0 when SccModeA(4) = '1' and subslot(1 downto 0) = "10" and maptyp = "10" else
121 SubBank0(3) + SubOff0 when SccModeA(4) = '1' and subslot(1 downto 0) = "11" and maptyp = "10" else
122
123 SubBank0(0) + SubOff1 when SccModeA(4) = '1' and subslot(3 downto 2) = "00" else
124 SubBank0(1) + SubOff1 when SccModeA(4) = '1' and subslot(3 downto 2) = "01" else
125 SubBank0(2) + SubOff1 when SccModeA(4) = '1' and subslot(3 downto 2) = "10" else
126 SubBank0(3) + SubOff1 when SccModeA(4) = '1' and subslot(3 downto 2) = "11" else
127 SccBank0 + mapOff;
128
129 Bank1 <= SubBank1(0) + SubOff1 when SccModeA(4) = '1' and subslot(3 downto 2) = "00" else
130 SubBank1(1) + SubOff1 when SccModeA(4) = '1' and subslot(3 downto 2) = "01" else
131 SubBank1(2) + SubOff1 when SccModeA(4) = '1' and subslot(3 downto 2) = "10" else
132 SubBank1(3) + SubOff1 when SccModeA(4) = '1' and subslot(3 downto 2) = "11" else
133 SccBank1 + mapOff;
134
135 Bank2 <= SubBank2(0) + SubOff2 when SccModeA(4) = '1' and subslot(5 downto 4) = "00" else
136 SubBank2(1) + SubOff2 when SccModeA(4) = '1' and subslot(5 downto 4) = "01" else
137 SubBank2(2) + SubOff2 when SccModeA(4) = '1' and subslot(5 downto 4) = "10" else
138 SubBank2(3) + SubOff2 when SccModeA(4) = '1' and subslot(5 downto 4) = "11" else
139 SccBank2 + mapOff;
140
141 Bank3 <= SubBank3(0) + SubOff3 when SccModeA(4) = '1' and subslot(7 downto 6) = "00" and maptyp = "10" else
142 SubBank3(1) + SubOff3 when SccModeA(4) = '1' and subslot(7 downto 6) = "01" and maptyp = "10" else
143 SubBank3(2) + SubOff3 when SccModeA(4) = '1' and subslot(7 downto 6) = "10" and maptyp = "10" else
144 SubBank3(3) + SubOff3 when SccModeA(4) = '1' and subslot(7 downto 6) = "11" and maptyp = "10" else
145
146 SubBank3(0) + SubOff2 when SccModeA(4) = '1' and subslot(5 downto 4) = "00" else
147 SubBank3(1) + SubOff2 when SccModeA(4) = '1' and subslot(5 downto 4) = "01" else
148 SubBank3(2) + SubOff2 when SccModeA(4) = '1' and subslot(5 downto 4) = "10" else
149 SubBank3(3) + SubOff2 when SccModeA(4) = '1' and subslot(5 downto 4) = "11" else
150 SccBank3 + mapOff;
151
152
153 -- 64K Mode
154 RamAdr <= Bank0(5 downto 0) & adr(13 downto 0) when adr(15 downto 14) = "00" and maptyp = "10" else --#0000-#3FFF
155 Bank1(5 downto 0) & adr(13 downto 0) when adr(15 downto 14) = "01" and maptyp = "10" else --#4000-#7FFF
156 Bank2(5 downto 0) & adr(13 downto 0) when adr(15 downto 14) = "10" and maptyp = "10" else --#8000-#BFFF
157 Bank3(5 downto 0) & adr(13 downto 0) when adr(15 downto 14) = "11" and maptyp = "10" else --#C000-#FFFF
158 -- Modes SCC, ASC8 and ASC16
159 Bank0(6 downto 0) & adr(12 downto 0) when adr(14 downto 13) = "10" else --#4000-#5FFF
160 Bank1(6 downto 0) & adr(12 downto 0) when adr(14 downto 13) = "11" else --#6000-#7FFF
161 Bank2(6 downto 0) & adr(12 downto 0) when adr(14 downto 13) = "00" else --#8000-#9FFF
162 Bank3(6 downto 0) & adr(12 downto 0);
163
164******************************************************************************/
165
166namespace openmsx {
167
168static constexpr auto sectorInfo = [] {
169 // 1 * 16kB, followed by 2 * 8kB, 1 * 32kB, 15 * 64kB
170 using Info = AmdFlash::SectorInfo;
171 std::array<Info, 1 + 2 + 1 + 15> result = {};
172 std::fill(result.begin() + 0, result.begin() + 1, Info{16 * 1024, false});
173 std::fill(result.begin() + 1, result.begin() + 3, Info{ 8 * 1024, false});
174 std::fill(result.begin() + 3, result.begin() + 4, Info{32 * 1024, false});
175 std::fill(result.begin() + 4, result.end(), Info{64 * 1024, false});
176 return result;
177}();
178
180 const DeviceConfig& config, Rom&& rom_)
181 : MSXRom(config, std::move(rom_))
182 , scc("MFR SCC+ SCC-I", config, getCurrentTime(), SCC::SCC_Compatible)
183 , psg("MFR SCC+ PSG", DummyAY8910Periphery::instance(), config,
184 getCurrentTime())
185 , flash(rom, sectorInfo, 0x205B,
186 AmdFlash::Addressing::BITS_11, config)
187{
189
190 getCPUInterface().register_IO_Out(0x10, this);
191 getCPUInterface().register_IO_Out(0x11, this);
192}
193
195{
198}
199
200void MegaFlashRomSCCPlus::powerUp(EmuTime::param time)
201{
202 scc.powerUp(time);
203 reset(time);
204}
205
206void MegaFlashRomSCCPlus::reset(EmuTime::param time)
207{
208 configReg = 0;
209 offsetReg = 0;
210 subslotReg = 0;
211 for (auto& regs : bankRegs) {
212 ranges::iota(regs, 0);
213 }
214
215 sccMode = 0;
216 ranges::iota(sccBanks, 0);
217 scc.reset(time);
218
219 psgLatch = 0;
220 psg.reset(time);
221
222 flash.reset();
223
224 invalidateDeviceRCache(); // flush all to be sure
225}
226
227MegaFlashRomSCCPlus::SCCEnable MegaFlashRomSCCPlus::getSCCEnable() const
228{
229 if ((sccMode & 0x20) && (sccBanks[3] & 0x80)) {
230 return EN_SCCPLUS;
231 } else if ((!(sccMode & 0x20)) && ((sccBanks[2] & 0x3F) == 0x3F)) {
232 return EN_SCC;
233 } else {
234 return EN_NONE;
235 }
236}
237
238unsigned MegaFlashRomSCCPlus::getSubslot(unsigned addr) const
239{
240 return (configReg & 0x10)
241 ? (subslotReg >> (2 * (addr >> 14))) & 0x03
242 : 0;
243}
244
245unsigned MegaFlashRomSCCPlus::getFlashAddr(unsigned addr) const
246{
247 unsigned subslot = getSubslot(addr);
248 unsigned tmp = [&] {
249 if ((configReg & 0xC0) == 0x40) {
250 unsigned bank = bankRegs[subslot][addr >> 14] + offsetReg;
251 return (bank * 0x4000) + (addr & 0x3FFF);
252 } else {
253 unsigned page = (addr >> 13) - 2;
254 if (page >= 4) {
255 // Bank: -2, -1, 4, 5. So not mapped in this region,
256 // returned value should not be used. But querying it
257 // anyway is easier, see start of writeMem().
258 return unsigned(-1);
259 }
260 unsigned bank = bankRegs[subslot][page] + offsetReg;
261 return (bank * 0x2000) + (addr & 0x1FFF);
262 }
263 }();
264 return ((0x40000 * subslot) + tmp) & 0xFFFFF; // wrap at 1MB
265}
266
267byte MegaFlashRomSCCPlus::peekMem(word addr, EmuTime::param time) const
268{
269 if ((configReg & 0x10) && (addr == 0xFFFF)) {
270 // read subslot register
271 return subslotReg ^ 0xFF;
272 }
273
274 if ((configReg & 0xE0) == 0x00) {
275 SCCEnable enable = getSCCEnable();
276 if (((enable == EN_SCC) && (0x9800 <= addr) && (addr < 0xA000)) ||
277 ((enable == EN_SCCPLUS) && (0xB800 <= addr) && (addr < 0xC000))) {
278 return scc.peekMem(addr & 0xFF, time);
279 }
280 }
281
282 if (((configReg & 0xC0) == 0x40) ||
283 ((0x4000 <= addr) && (addr < 0xC000))) {
284 // read (flash)rom content
285 unsigned flashAddr = getFlashAddr(addr);
286 assert(flashAddr != unsigned(-1));
287 return flash.peek(flashAddr);
288 } else {
289 // unmapped read
290 return 0xFF;
291 }
292}
293
294byte MegaFlashRomSCCPlus::readMem(word addr, EmuTime::param time)
295{
296 if ((configReg & 0x10) && (addr == 0xFFFF)) {
297 // read subslot register
298 return subslotReg ^ 0xFF;
299 }
300
301 if ((configReg & 0xE0) == 0x00) {
302 SCCEnable enable = getSCCEnable();
303 if (((enable == EN_SCC) && (0x9800 <= addr) && (addr < 0xA000)) ||
304 ((enable == EN_SCCPLUS) && (0xB800 <= addr) && (addr < 0xC000))) {
305 return scc.readMem(addr & 0xFF, time);
306 }
307 }
308
309 if (((configReg & 0xC0) == 0x40) ||
310 ((0x4000 <= addr) && (addr < 0xC000))) {
311 // read (flash)rom content
312 unsigned flashAddr = getFlashAddr(addr);
313 assert(flashAddr != unsigned(-1));
314 return flash.read(flashAddr);
315 } else {
316 // unmapped read
317 return 0xFF;
318 }
319}
320
322{
323 if ((configReg & 0x10) &&
324 ((addr & CacheLine::HIGH) == (0xFFFF & CacheLine::HIGH))) {
325 // read subslot register
326 return nullptr;
327 }
328
329 if ((configReg & 0xE0) == 0x00) {
330 SCCEnable enable = getSCCEnable();
331 if (((enable == EN_SCC) && (0x9800 <= addr) && (addr < 0xA000)) ||
332 ((enable == EN_SCCPLUS) && (0xB800 <= addr) && (addr < 0xC000))) {
333 return nullptr;
334 }
335 }
336
337 if (((configReg & 0xC0) == 0x40) ||
338 ((0x4000 <= addr) && (addr < 0xC000))) {
339 // read (flash)rom content
340 unsigned flashAddr = getFlashAddr(addr);
341 assert(flashAddr != unsigned(-1));
342 return flash.getReadCacheLine(flashAddr);
343 } else {
344 // unmapped read
345 return unmappedRead.data();
346 }
347}
348
349void MegaFlashRomSCCPlus::writeMem(word addr, byte value, EmuTime::param time)
350{
351 // address is calculated before writes to other regions take effect
352 unsigned flashAddr = getFlashAddr(addr);
353
354 // There are several overlapping functional regions in the address
355 // space. A single write can trigger behaviour in multiple regions. In
356 // other words there's no priority amongst the regions where a higher
357 // priority region blocks the write from the lower priority regions.
358 if ((configReg & 0x10) && (addr == 0xFFFF)) {
359 // write subslot register
360 byte diff = value ^ subslotReg;
361 subslotReg = value;
362 for (auto i : xrange(4)) {
363 if (diff & (3 << (2 * i))) {
364 invalidateDeviceRCache(0x4000 * i, 0x4000);
365 }
366 }
367 }
368
369 if (((configReg & 0x04) == 0x00) && ((addr & 0xFFFE) == 0x7FFE)) {
370 // write config register
371 configReg = value;
372 invalidateDeviceRCache(); // flush all to be sure
373 }
374
375 if ((configReg & 0xE0) == 0x00) {
376 // Konami-SCC
377 if ((addr & 0xFFFE) == 0xBFFE) {
378 sccMode = value;
379 scc.setChipMode((value & 0x20) ? SCC::SCC_plusmode
381 invalidateDeviceRCache(0x9800, 0x800);
382 invalidateDeviceRCache(0xB800, 0x800);
383 }
384 SCCEnable enable = getSCCEnable();
385 bool isRamSegment2 = ((sccMode & 0x24) == 0x24) ||
386 ((sccMode & 0x10) == 0x10);
387 bool isRamSegment3 = ((sccMode & 0x10) == 0x10);
388 if (((enable == EN_SCC) && !isRamSegment2 &&
389 (0x9800 <= addr) && (addr < 0xA000)) ||
390 ((enable == EN_SCCPLUS) && !isRamSegment3 &&
391 (0xB800 <= addr) && (addr < 0xC000))) {
392 scc.writeMem(addr & 0xFF, value, time);
393 return; // Pazos: when SCC registers are selected flashROM is not seen, so it does not accept commands.
394 }
395 }
396
397 unsigned subslot = getSubslot(addr);
398 unsigned page8kB = (addr >> 13) - 2;
399 if (((configReg & 0x02) == 0x00) && (page8kB < 4)) {
400 // (possibly) write to bank registers
401 switch (configReg & 0xE0) {
402 case 0x00:
403 // Konami-SCC
404 if ((addr & 0x1800) == 0x1000) {
405 // Storing 'sccBanks' may seem redundant at
406 // first, but it's required to calculate
407 // whether the SCC is enabled or not.
408 sccBanks[page8kB] = value;
409 if ((value & 0x80) && (page8kB == 0)) {
410 offsetReg = value & 0x7F;
411 invalidateDeviceRCache(0x4000, 0x8000);
412 } else {
413 // Masking of the mapper bits is done on
414 // write (and only in Konami(-scc) mode)
415 byte mask = (configReg & 0x01) ? 0x3F : 0x7F;
416 bankRegs[subslot][page8kB] = value & mask;
417 invalidateDeviceRCache(0x4000 + 0x2000 * page8kB, 0x2000);
418 }
419 }
420 break;
421 case 0x20: {
422 // Konami
423 if (((configReg & 0x08) == 0x08) && (addr < 0x6000)) {
424 // Switching 0x4000-0x5FFF disabled.
425 // This bit blocks writing to the bank register
426 // (an alternative was forcing a 0 on read).
427 // It only has effect in Konami mode.
428 break;
429 }
430 // Making of the mapper bits is done on
431 // write (and only in Konami(-scc) mode)
432 if ((addr < 0x5000) || ((0x5800 <= addr) && (addr < 0x6000))) break; // only SCC range works
433 byte mask = (configReg & 0x01) ? 0x1F : 0x7F;
434 bankRegs[subslot][page8kB] = value & mask;
435 invalidateDeviceRCache(0x4000 + 0x2000 * page8kB, 0x2000);
436 break;
437 }
438 case 0x40:
439 case 0x60:
440 // 64kB
441 bankRegs[subslot][page8kB] = value;
442 invalidateDeviceRCache(0x0000 + 0x4000 * page8kB, 0x4000);
443 break;
444 case 0x80:
445 case 0xA0:
446 // ASCII-8
447 if ((0x6000 <= addr) && (addr < 0x8000)) {
448 byte bank = (addr >> 11) & 0x03;
449 bankRegs[subslot][bank] = value;
450 invalidateDeviceRCache(0x4000 + 0x2000 * bank, 0x2000);
451 }
452 break;
453 case 0xC0:
454 case 0xE0:
455 // ASCII-16
456 // This behaviour is confirmed by Manuel Pazos (creator
457 // of the cartridge): ASCII-16 uses all 4 bank registers
458 // and one bank switch changes 2 registers at once.
459 // This matters when switching mapper mode, because
460 // the content of the bank registers is unchanged after
461 // a switch.
462 if ((0x6000 <= addr) && (addr < 0x6800)) {
463 bankRegs[subslot][0] = 2 * value + 0;
464 bankRegs[subslot][1] = 2 * value + 1;
465 invalidateDeviceRCache(0x4000, 0x4000);
466 }
467 if ((0x7000 <= addr) && (addr < 0x7800)) {
468 bankRegs[subslot][2] = 2 * value + 0;
469 bankRegs[subslot][3] = 2 * value + 1;
470 invalidateDeviceRCache(0x8000, 0x4000);
471 }
472 break;
473 }
474 }
475
476 // write to flash
477 if (((configReg & 0xC0) == 0x40) ||
478 ((0x4000 <= addr) && (addr < 0xC000))) {
479 assert(flashAddr != unsigned(-1));
480 return flash.write(flashAddr, value);
481 }
482}
483
485{
486 return nullptr;
487}
488
489
490void MegaFlashRomSCCPlus::writeIO(word port, byte value, EmuTime::param time)
491{
492 if ((port & 0xFF) == 0x10) {
493 psgLatch = value & 0x0F;
494 } else {
495 assert((port & 0xFF) == 0x11);
496 psg.writeRegister(psgLatch, value, time);
497 }
498}
499
500
501template<typename Archive>
502void MegaFlashRomSCCPlus::serialize(Archive& ar, unsigned /*version*/)
503{
504 // skip MSXRom base class
505 ar.template serializeBase<MSXDevice>(*this);
506
507 ar.serialize("scc", scc,
508 "psg", psg,
509 "flash", flash,
510
511 "configReg", configReg,
512 "offsetReg", offsetReg,
513 "subslotReg", subslotReg,
514 "bankRegs", bankRegs,
515 "psgLatch", psgLatch,
516 "sccMode", sccMode,
517 "sccBanks", sccBanks);
518}
521
522} // namespace openmsx
void reset(EmuTime::param time)
Definition: AY8910.cc:510
void writeRegister(unsigned reg, uint8_t value, EmuTime::param time)
Definition: AY8910.cc:567
void write(size_t address, uint8_t value)
Definition: AmdFlash.cc:265
const uint8_t * getReadCacheLine(size_t address) const
Definition: AmdFlash.cc:254
uint8_t peek(size_t address) const
Definition: AmdFlash.cc:212
uint8_t read(size_t address) const
Definition: AmdFlash.cc:248
void register_IO_Out(byte port, MSXDevice *device)
Devices can register their Out ports.
void unregister_IO_Out(byte port, MSXDevice *device)
void invalidateDeviceRCache()
Definition: MSXDevice.hh:211
static std::array< byte, 0x10000 > unmappedRead
Definition: MSXDevice.hh:302
EmuTime::param getCurrentTime() const
Definition: MSXDevice.cc:125
MSXCPUInterface & getCPUInterface() const
Definition: MSXDevice.cc:133
void reset(EmuTime::param time) override
This method is called on reset.
void powerUp(EmuTime::param time) override
This method is called when MSX is powered up.
void writeMem(word address, byte value, EmuTime::param time) override
Write a given byte to a given location at a certain time to this device.
const byte * getReadCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
MegaFlashRomSCCPlus(const DeviceConfig &config, Rom &&rom)
void serialize(Archive &ar, unsigned version)
void writeIO(word port, byte value, EmuTime::param time) override
Write a byte to a given IO port at a certain time to this device.
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
byte * getWriteCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
void setChipMode(ChipMode newMode)
Definition: SCC.cc:183
void powerUp(EmuTime::param time)
Definition: SCC.cc:141
@ SCC_plusmode
Definition: SCC.hh:16
@ SCC_Compatible
Definition: SCC.hh:16
uint8_t readMem(uint8_t address, EmuTime::param time)
Definition: SCC.cc:193
void reset(EmuTime::param time)
Definition: SCC.cc:173
uint8_t peekMem(uint8_t address, EmuTime::param time) const
Definition: SCC.cc:206
void writeMem(uint8_t address, uint8_t value, EmuTime::param time)
Definition: SCC.cc:285
constexpr unsigned HIGH
Definition: CacheLine.hh:10
This file implemented 3 utility functions:
Definition: Autofire.cc:9
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
AmdFlash::SectorInfo Info
Definition: RomManbow2.cc:18
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
constexpr void fill(ForwardRange &&range, const T &value)
Definition: ranges.hh:287
constexpr void iota(ForwardIt first, ForwardIt last, T value)
Definition: ranges.hh:294
STL namespace.
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1021
constexpr auto xrange(T e)
Definition: xrange.hh:133