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
22namespace openmsx {
23
24// minimal attempt to avoid seeing this warning too often
25static 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.size() > 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
42void RomKonamiSCC::powerUp(EmuTime::param time)
43{
44 scc.powerUp(time);
45 reset(time);
46}
47
48void 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
62byte RomKonamiSCC::peekMem(word address, EmuTime::param time) const
63{
64 if (sccEnabled && (0x9800 <= address) && (address < 0xA000)) {
65 return scc.peekMem(narrow_cast<uint8_t>(address & 0xFF), time);
66 } else {
67 return Rom8kBBlocks::peekMem(address, time);
68 }
69}
70
71byte RomKonamiSCC::readMem(word address, EmuTime::param time)
72{
73 if (sccEnabled && (0x9800 <= address) && (address < 0xA000)) {
74 return scc.readMem(narrow_cast<uint8_t>(address & 0xFF), time);
75 } else {
76 return Rom8kBBlocks::readMem(address, time);
77 }
78}
79
80const 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
90void 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(narrow_cast<uint8_t>(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 auto 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.data();
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.data();
133 }
134}
135
136template<typename Archive>
137void 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:70
void invalidateDeviceRCache()
Definition: MSXDevice.hh:213
static std::array< byte, 0x10000 > unmappedWrite
Definition: MSXDevice.hh:305
void invalidateDeviceRWCache()
Calls MSXCPUInterface::invalidateXXCache() for the specific (part of) the slot that this device is lo...
Definition: MSXDevice.hh:212
EmuTime::param getCurrentTime() const
Definition: MSXDevice.cc:125
void setUnmapped(unsigned region)
Select 'unmapped' memory for this region.
Definition: RomBlocks.cc:92
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(unsigned region, unsigned block)
Selects a block of the ROM image for reading in a certain region.
Definition: RomBlocks.cc:104
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
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
const Sha1Sum & getOriginalSHA1() const
Definition: Rom.cc:349
auto size() const
Definition: Rom.hh:36
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:9
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
STL namespace.
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1021
constexpr auto xrange(T e)
Definition: xrange.hh:132