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