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