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 for (auto port : {0x10, 0x11}) {
191 getCPUInterface().register_IO_Out(narrow_cast<byte>(port), this);
192 }
193}
194
196{
197 for (auto port : {0x10, 0x11}) {
198 getCPUInterface().unregister_IO_Out(narrow_cast<byte>(port), this);
199 }
200}
201
202void MegaFlashRomSCCPlus::powerUp(EmuTime::param time)
203{
204 scc.powerUp(time);
205 reset(time);
206}
207
208void MegaFlashRomSCCPlus::reset(EmuTime::param time)
209{
210 configReg = 0;
211 offsetReg = 0;
212 subslotReg = 0;
213 for (auto& regs : bankRegs) {
214 ranges::iota(regs, byte(0));
215 }
216
217 sccMode = 0;
218 ranges::iota(sccBanks, byte(0));
219 scc.reset(time);
220
221 psgLatch = 0;
222 psg.reset(time);
223
224 flash.reset();
225
226 invalidateDeviceRCache(); // flush all to be sure
227}
228
229MegaFlashRomSCCPlus::SCCEnable MegaFlashRomSCCPlus::getSCCEnable() const
230{
231 if ((sccMode & 0x20) && (sccBanks[3] & 0x80)) {
232 return EN_SCCPLUS;
233 } else if ((!(sccMode & 0x20)) && ((sccBanks[2] & 0x3F) == 0x3F)) {
234 return EN_SCC;
235 } else {
236 return EN_NONE;
237 }
238}
239
240unsigned MegaFlashRomSCCPlus::getSubslot(unsigned addr) const
241{
242 return (configReg & 0x10)
243 ? (subslotReg >> (2 * (addr >> 14))) & 0x03
244 : 0;
245}
246
247unsigned MegaFlashRomSCCPlus::getFlashAddr(unsigned addr) const
248{
249 unsigned subslot = getSubslot(addr);
250 unsigned tmp = [&] {
251 if ((configReg & 0xC0) == 0x40) {
252 unsigned bank = bankRegs[subslot][addr >> 14] + offsetReg;
253 return (bank * 0x4000) + (addr & 0x3FFF);
254 } else {
255 unsigned page = (addr >> 13) - 2;
256 if (page >= 4) {
257 // Bank: -2, -1, 4, 5. So not mapped in this region,
258 // returned value should not be used. But querying it
259 // anyway is easier, see start of writeMem().
260 return unsigned(-1);
261 }
262 unsigned bank = bankRegs[subslot][page] + offsetReg;
263 return (bank * 0x2000) + (addr & 0x1FFF);
264 }
265 }();
266 return ((0x40000 * subslot) + tmp) & 0xFFFFF; // wrap at 1MB
267}
268
269byte MegaFlashRomSCCPlus::peekMem(word addr, EmuTime::param time) const
270{
271 if ((configReg & 0x10) && (addr == 0xFFFF)) {
272 // read subslot register
273 return subslotReg ^ 0xFF;
274 }
275
276 if ((configReg & 0xE0) == 0x00) {
277 SCCEnable enable = getSCCEnable();
278 if (((enable == EN_SCC) && (0x9800 <= addr) && (addr < 0xA000)) ||
279 ((enable == EN_SCCPLUS) && (0xB800 <= addr) && (addr < 0xC000))) {
280 return scc.peekMem(narrow_cast<uint8_t>(addr & 0xFF), time);
281 }
282 }
283
284 if (((configReg & 0xC0) == 0x40) ||
285 ((0x4000 <= addr) && (addr < 0xC000))) {
286 // read (flash)rom content
287 unsigned flashAddr = getFlashAddr(addr);
288 assert(flashAddr != unsigned(-1));
289 return flash.peek(flashAddr);
290 } else {
291 // unmapped read
292 return 0xFF;
293 }
294}
295
296byte MegaFlashRomSCCPlus::readMem(word addr, EmuTime::param time)
297{
298 if ((configReg & 0x10) && (addr == 0xFFFF)) {
299 // read subslot register
300 return subslotReg ^ 0xFF;
301 }
302
303 if ((configReg & 0xE0) == 0x00) {
304 SCCEnable enable = getSCCEnable();
305 if (((enable == EN_SCC) && (0x9800 <= addr) && (addr < 0xA000)) ||
306 ((enable == EN_SCCPLUS) && (0xB800 <= addr) && (addr < 0xC000))) {
307 return scc.readMem(narrow_cast<uint8_t>(addr & 0xFF), time);
308 }
309 }
310
311 if (((configReg & 0xC0) == 0x40) ||
312 ((0x4000 <= addr) && (addr < 0xC000))) {
313 // read (flash)rom content
314 unsigned flashAddr = getFlashAddr(addr);
315 assert(flashAddr != unsigned(-1));
316 return flash.read(flashAddr);
317 } else {
318 // unmapped read
319 return 0xFF;
320 }
321}
322
324{
325 if ((configReg & 0x10) &&
326 ((addr & CacheLine::HIGH) == (0xFFFF & CacheLine::HIGH))) {
327 // read subslot register
328 return nullptr;
329 }
330
331 if ((configReg & 0xE0) == 0x00) {
332 SCCEnable enable = getSCCEnable();
333 if (((enable == EN_SCC) && (0x9800 <= addr) && (addr < 0xA000)) ||
334 ((enable == EN_SCCPLUS) && (0xB800 <= addr) && (addr < 0xC000))) {
335 return nullptr;
336 }
337 }
338
339 if (((configReg & 0xC0) == 0x40) ||
340 ((0x4000 <= addr) && (addr < 0xC000))) {
341 // read (flash)rom content
342 unsigned flashAddr = getFlashAddr(addr);
343 assert(flashAddr != unsigned(-1));
344 return flash.getReadCacheLine(flashAddr);
345 } else {
346 // unmapped read
347 return unmappedRead.data();
348 }
349}
350
351void MegaFlashRomSCCPlus::writeMem(word addr, byte value, EmuTime::param time)
352{
353 // address is calculated before writes to other regions take effect
354 unsigned flashAddr = getFlashAddr(addr);
355
356 // There are several overlapping functional regions in the address
357 // space. A single write can trigger behaviour in multiple regions. In
358 // other words there's no priority amongst the regions where a higher
359 // priority region blocks the write from the lower priority regions.
360 if ((configReg & 0x10) && (addr == 0xFFFF)) {
361 // write subslot register
362 byte diff = value ^ subslotReg;
363 subslotReg = value;
364 for (auto i : xrange(4)) {
365 if (diff & (3 << (2 * i))) {
366 invalidateDeviceRCache(0x4000 * i, 0x4000);
367 }
368 }
369 }
370
371 if (((configReg & 0x04) == 0x00) && ((addr & 0xFFFE) == 0x7FFE)) {
372 // write config register
373 configReg = value;
374 invalidateDeviceRCache(); // flush all to be sure
375 }
376
377 if ((configReg & 0xE0) == 0x00) {
378 // Konami-SCC
379 if ((addr & 0xFFFE) == 0xBFFE) {
380 sccMode = value;
381 scc.setChipMode((value & 0x20) ? SCC::SCC_plusmode
383 invalidateDeviceRCache(0x9800, 0x800);
384 invalidateDeviceRCache(0xB800, 0x800);
385 }
386 SCCEnable enable = getSCCEnable();
387 bool isRamSegment2 = ((sccMode & 0x24) == 0x24) ||
388 ((sccMode & 0x10) == 0x10);
389 bool isRamSegment3 = ((sccMode & 0x10) == 0x10);
390 if (((enable == EN_SCC) && !isRamSegment2 &&
391 (0x9800 <= addr) && (addr < 0xA000)) ||
392 ((enable == EN_SCCPLUS) && !isRamSegment3 &&
393 (0xB800 <= addr) && (addr < 0xC000))) {
394 scc.writeMem(narrow_cast<uint8_t>(addr & 0xFF), value, time);
395 return; // Pazos: when SCC registers are selected flashROM is not seen, so it does not accept commands.
396 }
397 }
398
399 unsigned subslot = getSubslot(addr);
400 unsigned page8kB = (addr >> 13) - 2;
401 if (((configReg & 0x02) == 0x00) && (page8kB < 4)) {
402 // (possibly) write to bank registers
403 switch (configReg & 0xE0) {
404 case 0x00:
405 // Konami-SCC
406 if ((addr & 0x1800) == 0x1000) {
407 // Storing 'sccBanks' may seem redundant at
408 // first, but it's required to calculate
409 // whether the SCC is enabled or not.
410 sccBanks[page8kB] = value;
411 if ((value & 0x80) && (page8kB == 0)) {
412 offsetReg = value & 0x7F;
413 invalidateDeviceRCache(0x4000, 0x8000);
414 } else {
415 // Masking of the mapper bits is done on
416 // write (and only in Konami(-scc) mode)
417 byte mask = (configReg & 0x01) ? 0x3F : 0x7F;
418 bankRegs[subslot][page8kB] = value & mask;
419 invalidateDeviceRCache(0x4000 + 0x2000 * page8kB, 0x2000);
420 }
421 }
422 break;
423 case 0x20: {
424 // Konami
425 if (((configReg & 0x08) == 0x08) && (addr < 0x6000)) {
426 // Switching 0x4000-0x5FFF disabled.
427 // This bit blocks writing to the bank register
428 // (an alternative was forcing a 0 on read).
429 // It only has effect in Konami mode.
430 break;
431 }
432 // Making of the mapper bits is done on
433 // write (and only in Konami(-scc) mode)
434 if ((addr < 0x5000) || ((0x5800 <= addr) && (addr < 0x6000))) break; // only SCC range works
435 byte mask = (configReg & 0x01) ? 0x1F : 0x7F;
436 bankRegs[subslot][page8kB] = value & mask;
437 invalidateDeviceRCache(0x4000 + 0x2000 * page8kB, 0x2000);
438 break;
439 }
440 case 0x40:
441 case 0x60:
442 // 64kB
443 bankRegs[subslot][page8kB] = value;
444 invalidateDeviceRCache(0x0000 + 0x4000 * page8kB, 0x4000);
445 break;
446 case 0x80:
447 case 0xA0:
448 // ASCII-8
449 if ((0x6000 <= addr) && (addr < 0x8000)) {
450 byte bank = (addr >> 11) & 0x03;
451 bankRegs[subslot][bank] = value;
452 invalidateDeviceRCache(0x4000 + 0x2000 * bank, 0x2000);
453 }
454 break;
455 case 0xC0:
456 case 0xE0:
457 // ASCII-16
458 // This behaviour is confirmed by Manuel Pazos (creator
459 // of the cartridge): ASCII-16 uses all 4 bank registers
460 // and one bank switch changes 2 registers at once.
461 // This matters when switching mapper mode, because
462 // the content of the bank registers is unchanged after
463 // a switch.
464 if ((0x6000 <= addr) && (addr < 0x6800)) {
465 bankRegs[subslot][0] = narrow_cast<uint8_t>(2 * value + 0);
466 bankRegs[subslot][1] = narrow_cast<uint8_t>(2 * value + 1);
467 invalidateDeviceRCache(0x4000, 0x4000);
468 }
469 if ((0x7000 <= addr) && (addr < 0x7800)) {
470 bankRegs[subslot][2] = narrow_cast<uint8_t>(2 * value + 0);
471 bankRegs[subslot][3] = narrow_cast<uint8_t>(2 * value + 1);
472 invalidateDeviceRCache(0x8000, 0x4000);
473 }
474 break;
475 }
476 }
477
478 // write to flash
479 if (((configReg & 0xC0) == 0x40) ||
480 ((0x4000 <= addr) && (addr < 0xC000))) {
481 assert(flashAddr != unsigned(-1));
482 return flash.write(flashAddr, value);
483 }
484}
485
487{
488 return nullptr;
489}
490
491
492void MegaFlashRomSCCPlus::writeIO(word port, byte value, EmuTime::param time)
493{
494 if ((port & 0xFF) == 0x10) {
495 psgLatch = value & 0x0F;
496 } else {
497 assert((port & 0xFF) == 0x11);
498 psg.writeRegister(psgLatch, value, time);
499 }
500}
501
502
503template<typename Archive>
504void MegaFlashRomSCCPlus::serialize(Archive& ar, unsigned /*version*/)
505{
506 // skip MSXRom base class
507 ar.template serializeBase<MSXDevice>(*this);
508
509 ar.serialize("scc", scc,
510 "psg", psg,
511 "flash", flash,
512
513 "configReg", configReg,
514 "offsetReg", offsetReg,
515 "subslotReg", subslotReg,
516 "bankRegs", bankRegs,
517 "psgLatch", psgLatch,
518 "sccMode", sccMode,
519 "sccBanks", sccBanks);
520}
523
524} // namespace openmsx
#define REGISTER_MSXDEVICE(CLASS, NAME)
Definition MSXDevice.hh:356
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:215
static std::array< byte, 0x10000 > unmappedRead
Definition MSXDevice.hh:306
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:11
AmdFlash::SectorInfo Info
Definition RomManbow2.cc:18
uint16_t word
16 bit unsigned integer
Definition openmsx.hh:29
constexpr void iota(ForwardIt first, ForwardIt last, T value)
Definition ranges.hh:312
STL namespace.
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
constexpr auto xrange(T e)
Definition xrange.hh:132