openMSX
MegaFlashRomSCCPlus.cc
Go to the documentation of this file.
1 #include "MegaFlashRomSCCPlus.hh"
3 #include "MSXCPUInterface.hh"
4 #include "CacheLine.hh"
5 #include "cstd.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 --------------------------------------------------------------------------------
17 MegaFlashROM SCC+ Technical Details
18 (c) Manuel Pazos 28-09-2010
19 --------------------------------------------------------------------------------
20 
21 Main 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 writting 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 
167 namespace openmsx {
168 
169 static 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  cstd::fill(result.begin() + 0, result.begin() + 1, Info{16 * 1024, false});
174  cstd::fill(result.begin() + 1, result.begin() + 3, Info{ 8 * 1024, false});
175  cstd::fill(result.begin() + 3, result.begin() + 4, Info{32 * 1024, false});
176  cstd::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 {
197  getCPUInterface().unregister_IO_Out(0x10, this);
198  getCPUInterface().unregister_IO_Out(0x11, this);
199 }
200 
201 void MegaFlashRomSCCPlus::powerUp(EmuTime::param time)
202 {
203  scc.powerUp(time);
204  reset(time);
205 }
206 
207 void MegaFlashRomSCCPlus::reset(EmuTime::param time)
208 {
209  configReg = 0;
210  offsetReg = 0;
211  subslotReg = 0;
212  for (auto& regs : bankRegs) {
213  ranges::iota(regs, 0);
214  }
215 
216  sccMode = 0;
217  ranges::iota(sccBanks, 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 
228 MegaFlashRomSCCPlus::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 
239 unsigned MegaFlashRomSCCPlus::getSubslot(unsigned addr) const
240 {
241  return (configReg & 0x10)
242  ? (subslotReg >> (2 * (addr >> 14))) & 0x03
243  : 0;
244 }
245 
246 unsigned 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 
268 byte 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(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 
295 byte 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(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;
347  }
348 }
349 
350 void 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(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] = 2 * value + 0;
465  bankRegs[subslot][1] = 2 * value + 1;
466  invalidateDeviceRCache(0x4000, 0x4000);
467  }
468  if ((0x7000 <= addr) && (addr < 0x7800)) {
469  bankRegs[subslot][2] = 2 * value + 0;
470  bankRegs[subslot][3] = 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 
491 void 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 
502 template<typename Archive>
503 void 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 }
521 REGISTER_MSXDEVICE(MegaFlashRomSCCPlus, "MegaFlashRomSCCPlus");
522 
523 } // namespace openmsx
void reset(EmuTime::param time)
Definition: AY8910.cc:525
void writeRegister(unsigned reg, byte value, EmuTime::param time)
Definition: AY8910.cc:582
void write(unsigned address, byte value)
Definition: AmdFlash.cc:265
byte peek(unsigned address) const
Definition: AmdFlash.cc:212
byte read(unsigned address) const
Definition: AmdFlash.cc:248
const byte * getReadCacheLine(unsigned address) const
Definition: AmdFlash.cc:254
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:210
static byte unmappedRead[0x10000]
Definition: MSXDevice.hh:301
EmuTime::param getCurrentTime() const
Definition: MSXDevice.cc:126
MSXCPUInterface & getCPUInterface() const
Definition: MSXDevice.cc:134
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 writeMem(byte address, byte value, EmuTime::param time)
Definition: SCC.cc:285
void setChipMode(ChipMode newMode)
Definition: SCC.cc:183
void powerUp(EmuTime::param time)
Definition: SCC.cc:141
byte readMem(byte address, EmuTime::param time)
Definition: SCC.cc:193
@ SCC_plusmode
Definition: SCC.hh:14
@ SCC_Compatible
Definition: SCC.hh:14
void reset(EmuTime::param time)
Definition: SCC.cc:173
byte peekMem(byte address, EmuTime::param time) const
Definition: SCC.cc:206
constexpr void fill(ForwardIt first, ForwardIt last, const T &value)
Definition: cstd.hh:111
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:17
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
constexpr nibble mask[4][13]
Definition: RP5C01.cc:34
constexpr void iota(ForwardIt first, ForwardIt last, T value)
Definition: ranges.hh:233
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:998
constexpr auto xrange(T e)
Definition: xrange.hh:155