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 
21 namespace openmsx {
22 
23 // minimal attempt to avoid seeing this warning too often
24 static Sha1Sum alreadyWarnedForSha1Sum;
25 
27  : Rom8kBBlocks(config, std::move(rom_))
28  , scc("SCC", config, getCurrentTime())
29 {
30  // warn if a ROM is used that would not work on a real KonamiSCC mapper
31  if ((rom.getSize() > 512 * 1024) && alreadyWarnedForSha1Sum != rom.getOriginalSHA1()) {
33  "The size of this ROM image is larger than 512kB, "
34  "which is not supported on real Konami SCC mapper "
35  "chips!");
36  alreadyWarnedForSha1Sum = rom.getOriginalSHA1();
37  }
39 }
40 
41 void RomKonamiSCC::powerUp(EmuTime::param time)
42 {
43  scc.powerUp(time);
44  reset(time);
45 }
46 
47 void RomKonamiSCC::reset(EmuTime::param time)
48 {
49  setUnmapped(0);
50  setUnmapped(1);
51  for (int i = 2; i < 6; i++) {
52  setRom(i, i - 2);
53  }
54  setUnmapped(6);
55  setUnmapped(7);
56 
57  sccEnabled = false;
58  scc.reset(time);
59 }
60 
61 byte RomKonamiSCC::peekMem(word address, EmuTime::param time) const
62 {
63  if (sccEnabled && (0x9800 <= address) && (address < 0xA000)) {
64  return scc.peekMem(address & 0xFF, time);
65  } else {
66  return Rom8kBBlocks::peekMem(address, time);
67  }
68 }
69 
70 byte RomKonamiSCC::readMem(word address, EmuTime::param time)
71 {
72  if (sccEnabled && (0x9800 <= address) && (address < 0xA000)) {
73  return scc.readMem(address & 0xFF, time);
74  } else {
75  return Rom8kBBlocks::readMem(address, time);
76  }
77 }
78 
79 const byte* RomKonamiSCC::getReadCacheLine(word address) const
80 {
81  if (sccEnabled && (0x9800 <= address) && (address < 0xA000)) {
82  // don't cache SCC
83  return nullptr;
84  } else {
85  return Rom8kBBlocks::getReadCacheLine(address);
86  }
87 }
88 
89 void RomKonamiSCC::writeMem(word address, byte value, EmuTime::param time)
90 {
91  if ((address < 0x5000) || (address >= 0xC000)) {
92  return;
93  }
94  if (sccEnabled && (0x9800 <= address) && (address < 0xA000)) {
95  // write to SCC
96  scc.writeMem(address & 0xFF, value, time);
97  return;
98  }
99  if ((address & 0xF800) == 0x9000) {
100  // SCC enable/disable
101  bool newSccEnabled = ((value & 0x3F) == 0x3F);
102  if (newSccEnabled != sccEnabled) {
103  sccEnabled = newSccEnabled;
104  invalidateDeviceRWCache(0x9800, 0x0800);
105  }
106  }
107  if ((address & 0x1800) == 0x1000) {
108  // page selection
109  byte region = address >> 13;
110  setRom(region, value);
111  if ((region == 4) && sccEnabled) {
112  invalidateDeviceRCache(0x9800, 0x0800);
113  }
114  }
115 }
116 
118 {
119  if ((address < 0x5000) || (address >= 0xC000)) {
120  return unmappedWrite;
121  } else if (sccEnabled && (0x9800 <= address) && (address < 0xA000)) {
122  // write to SCC
123  return nullptr;
124  } else if ((address & 0xF800) == (0x9000 & CacheLine::HIGH)) {
125  // SCC enable/disable
126  return nullptr;
127  } else if ((address & 0x1800) == (0x1000 & CacheLine::HIGH)) {
128  // page selection
129  return nullptr;
130  } else {
131  return unmappedWrite;
132  }
133 }
134 
135 template<typename Archive>
136 void RomKonamiSCC::serialize(Archive& ar, unsigned /*version*/)
137 {
138  ar.template serializeBase<Rom8kBBlocks>(*this);
139  ar.serialize("scc", scc,
140  "sccEnabled", sccEnabled);
141 }
144 
145 } // namespace openmsx
openmsx::RomBlocks::peekMem
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: RomBlocks.cc:59
serialize.hh
openmsx::RomKonamiSCC::reset
void reset(EmuTime::param time) override
This method is called on reset.
Definition: RomKonamiSCC.cc:47
openmsx::DeviceConfig
Definition: DeviceConfig.hh:20
openmsx::MSXDevice::unmappedWrite
static byte unmappedWrite[0x10000]
Definition: MSXDevice.hh:301
sha1.hh
openmsx::RomKonamiSCC::getWriteCacheLine
byte * getWriteCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
Definition: RomKonamiSCC.cc:117
openmsx::SCC::reset
void reset(EmuTime::param time)
Definition: SCC.cc:172
openmsx::RomKonamiSCC::peekMem
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: RomKonamiSCC.cc:61
RomKonamiSCC.hh
openmsx::CacheLine::HIGH
constexpr unsigned HIGH
Definition: CacheLine.hh:10
openmsx::REGISTER_MSXDEVICE
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
openmsx::SCC::readMem
byte readMem(byte address, EmuTime::param time)
Definition: SCC.cc:192
openmsx::CliComm::printWarning
void printWarning(std::string_view message)
Definition: CliComm.cc:10
openmsx::RomBlocks::getReadCacheLine
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:71
openmsx::RomBlocks::setRom
void setRom(byte region, unsigned block)
Selects a block of the ROM image for reading in a certain region.
Definition: RomBlocks.cc:104
openmsx::MSXDevice::getCurrentTime
EmuTime::param getCurrentTime() const
Definition: MSXDevice.cc:131
openmsx::SCC::powerUp
void powerUp(EmuTime::param time)
Definition: SCC.cc:140
openmsx::RomBlocks::setUnmapped
void setUnmapped(byte region)
Select 'unmapped' memory for this region.
Definition: RomBlocks.cc:91
openmsx::RomBlocks
Definition: RomBlocks.hh:14
INSTANTIATE_SERIALIZE_METHODS
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:981
openmsx::MSXDevice::getMotherBoard
MSXMotherBoard & getMotherBoard() const
Get the mother board this device belongs to.
Definition: MSXDevice.cc:75
CacheLine.hh
openmsx::MSXRom::rom
Rom rom
Definition: MSXRom.hh:20
openmsx::Rom
Definition: Rom.hh:21
openmsx::RomKonamiSCC::writeMem
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:89
openmsx::MSXDevice::invalidateDeviceRCache
void invalidateDeviceRCache()
Definition: MSXDevice.hh:209
openmsx::MSXDevice::invalidateDeviceRWCache
void invalidateDeviceRWCache()
Calls MSXCPUInterface::invalidateXXCache() for the specific (part of) the slot that this device is lo...
Definition: MSXDevice.hh:208
openmsx::RomKonamiSCC::RomKonamiSCC
RomKonamiSCC(const DeviceConfig &config, Rom &&rom)
Definition: RomKonamiSCC.cc:26
openmsx::RomBlocks::readMem
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: RomBlocks.cc:65
openmsx::SCC::peekMem
byte peekMem(byte address, EmuTime::param time) const
Definition: SCC.cc:205
openmsx::RomKonamiSCC::powerUp
void powerUp(EmuTime::param time) override
This method is called when MSX is powered up.
Definition: RomKonamiSCC.cc:41
openmsx::word
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
openmsx::RomKonamiSCC::getReadCacheLine
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:79
openmsx::RomKonamiSCC::serialize
void serialize(Archive &ar, unsigned version)
Definition: RomKonamiSCC.cc:136
CliComm.hh
openmsx::RomKonamiSCC
Definition: RomKonamiSCC.hh:10
openmsx::SCC::writeMem
void writeMem(byte address, byte value, EmuTime::param time)
Definition: SCC.cc:289
openmsx::Rom::getOriginalSHA1
const Sha1Sum & getOriginalSHA1() const
Definition: Rom.cc:354
openmsx::RomKonamiSCC::readMem
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: RomKonamiSCC.cc:70
openmsx::Rom::getSize
unsigned getSize() const
Definition: Rom.hh:32
openmsx
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
MSXMotherBoard.hh
openmsx::MSXMotherBoard::getMSXCliComm
CliComm & getMSXCliComm()
Definition: MSXMotherBoard.cc:370