openMSX
RomKonamiSCC.cc
Go to the documentation of this file.
1 // KONAMI 8kB cartridges with SCC
2 //
3 // this type is used by Konami cartridges that do have an SCC and some others
4 // examples of cartridges: Nemesis 2, Nemesis 3, King's Valley 2, Space Manbow
5 // Solid Snake, Quarth, Ashguine 1, Animal, Arkanoid 2, ...
6 // Those last 3 were probably modified ROM images, they should be ASCII8
7 //
8 // The address to change banks:
9 // bank 1: 0x5000 - 0x57ff (0x5000 used)
10 // bank 2: 0x7000 - 0x77ff (0x7000 used)
11 // bank 3: 0x9000 - 0x97ff (0x9000 used)
12 // bank 4: 0xB000 - 0xB7ff (0xB000 used)
13 
14 #include "RomKonamiSCC.hh"
15 #include "CacheLine.hh"
16 #include "MSXMotherBoard.hh"
17 #include "CliComm.hh"
18 #include "sha1.hh"
19 #include "serialize.hh"
20 #include "xrange.hh"
21 
22 namespace openmsx {
23 
24 // minimal attempt to avoid seeing this warning too often
25 static Sha1Sum alreadyWarnedForSha1Sum;
26 
28  : Rom8kBBlocks(config, std::move(rom_))
29  , scc("SCC", config, getCurrentTime())
30 {
31  // warn if a ROM is used that would not work on a real KonamiSCC mapper
32  if ((rom.getSize() > 512 * 1024) && alreadyWarnedForSha1Sum != rom.getOriginalSHA1()) {
34  "The size of this ROM image is larger than 512kB, "
35  "which is not supported on real Konami SCC mapper "
36  "chips!");
37  alreadyWarnedForSha1Sum = rom.getOriginalSHA1();
38  }
40 }
41 
42 void RomKonamiSCC::powerUp(EmuTime::param time)
43 {
44  scc.powerUp(time);
45  reset(time);
46 }
47 
48 void RomKonamiSCC::reset(EmuTime::param time)
49 {
50  setUnmapped(0);
51  setUnmapped(1);
52  for (auto i : xrange(2, 6)) {
53  setRom(i, i - 2);
54  }
55  setUnmapped(6);
56  setUnmapped(7);
57 
58  sccEnabled = false;
59  scc.reset(time);
60 }
61 
62 byte RomKonamiSCC::peekMem(word address, EmuTime::param time) const
63 {
64  if (sccEnabled && (0x9800 <= address) && (address < 0xA000)) {
65  return scc.peekMem(address & 0xFF, time);
66  } else {
67  return Rom8kBBlocks::peekMem(address, time);
68  }
69 }
70 
71 byte RomKonamiSCC::readMem(word address, EmuTime::param time)
72 {
73  if (sccEnabled && (0x9800 <= address) && (address < 0xA000)) {
74  return scc.readMem(address & 0xFF, time);
75  } else {
76  return Rom8kBBlocks::readMem(address, time);
77  }
78 }
79 
80 const byte* RomKonamiSCC::getReadCacheLine(word address) const
81 {
82  if (sccEnabled && (0x9800 <= address) && (address < 0xA000)) {
83  // don't cache SCC
84  return nullptr;
85  } else {
86  return Rom8kBBlocks::getReadCacheLine(address);
87  }
88 }
89 
90 void RomKonamiSCC::writeMem(word address, byte value, EmuTime::param time)
91 {
92  if ((address < 0x5000) || (address >= 0xC000)) {
93  return;
94  }
95  if (sccEnabled && (0x9800 <= address) && (address < 0xA000)) {
96  // write to SCC
97  scc.writeMem(address & 0xFF, value, time);
98  return;
99  }
100  if ((address & 0xF800) == 0x9000) {
101  // SCC enable/disable
102  bool newSccEnabled = ((value & 0x3F) == 0x3F);
103  if (newSccEnabled != sccEnabled) {
104  sccEnabled = newSccEnabled;
105  invalidateDeviceRWCache(0x9800, 0x0800);
106  }
107  }
108  if ((address & 0x1800) == 0x1000) {
109  // page selection
110  byte region = address >> 13;
111  setRom(region, value);
112  if ((region == 4) && sccEnabled) {
113  invalidateDeviceRCache(0x9800, 0x0800);
114  }
115  }
116 }
117 
119 {
120  if ((address < 0x5000) || (address >= 0xC000)) {
121  return unmappedWrite;
122  } else if (sccEnabled && (0x9800 <= address) && (address < 0xA000)) {
123  // write to SCC
124  return nullptr;
125  } else if ((address & 0xF800) == (0x9000 & CacheLine::HIGH)) {
126  // SCC enable/disable
127  return nullptr;
128  } else if ((address & 0x1800) == (0x1000 & CacheLine::HIGH)) {
129  // page selection
130  return nullptr;
131  } else {
132  return unmappedWrite;
133  }
134 }
135 
136 template<typename Archive>
137 void RomKonamiSCC::serialize(Archive& ar, unsigned /*version*/)
138 {
139  ar.template serializeBase<Rom8kBBlocks>(*this);
140  ar.serialize("scc", scc,
141  "sccEnabled", sccEnabled);
142 }
145 
146 } // namespace openmsx
void printWarning(std::string_view message)
Definition: CliComm.cc:10
MSXMotherBoard & getMotherBoard() const
Get the mother board this device belongs to.
Definition: MSXDevice.cc:71
void invalidateDeviceRCache()
Definition: MSXDevice.hh:210
void invalidateDeviceRWCache()
Calls MSXCPUInterface::invalidateXXCache() for the specific (part of) the slot that this device is lo...
Definition: MSXDevice.hh:209
EmuTime::param getCurrentTime() const
Definition: MSXDevice.cc:126
static byte unmappedWrite[0x10000]
Definition: MSXDevice.hh:302
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: RomBlocks.cc:60
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: RomBlocks.cc:66
void setRom(byte region, unsigned block)
Selects a block of the ROM image for reading in a certain region.
Definition: RomBlocks.cc:105
const byte * getReadCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition: RomBlocks.cc:72
void setUnmapped(byte region)
Select 'unmapped' memory for this region.
Definition: RomBlocks.cc:92
byte * getWriteCacheLine(word address) const 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.
Definition: RomKonamiSCC.cc:71
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.
Definition: RomKonamiSCC.cc:90
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: RomKonamiSCC.cc:62
RomKonamiSCC(const DeviceConfig &config, Rom &&rom)
Definition: RomKonamiSCC.cc:27
void powerUp(EmuTime::param time) override
This method is called when MSX is powered up.
Definition: RomKonamiSCC.cc:42
const byte * getReadCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition: RomKonamiSCC.cc:80
void serialize(Archive &ar, unsigned version)
void reset(EmuTime::param time) override
This method is called on reset.
Definition: RomKonamiSCC.cc:48
unsigned getSize() const
Definition: Rom.hh:34
const Sha1Sum & getOriginalSHA1() const
Definition: Rom.cc:355
void writeMem(byte address, byte value, EmuTime::param time)
Definition: SCC.cc:285
void powerUp(EmuTime::param time)
Definition: SCC.cc:141
byte readMem(byte address, EmuTime::param time)
Definition: SCC.cc:193
void reset(EmuTime::param time)
Definition: SCC.cc:173
byte peekMem(byte address, EmuTime::param time) const
Definition: SCC.cc:206
constexpr unsigned HIGH
Definition: CacheLine.hh:10
This file implemented 3 utility functions:
Definition: Autofire.cc:9
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:998
constexpr auto xrange(T e)
Definition: xrange.hh:155