60size_t ESE_SCC::getSramSize(
bool withSCSI)
const
63 if (sramSize !=
one_of(1024u, 512u, 256u, 128u)) {
66 " should be 128, 256, 512 or 1024kB and not ",
69 if (!withSCSI && sramSize == 1024) {
70 throw MSXException(
"1024kB SRAM is only allowed in WAVE-SCSI!");
72 return sramSize * 1024;
77 , sram(getName() +
" SRAM", getSramSize(withSCSI), config)
78 , scc(getName(), config, getCurrentTime())
79 , spc(withSCSI ?
std::make_unique<
MB89352>(config) : nullptr)
80 , romBlockDebug(*this, mapper, 0x4000, 0x8000, 13)
81 , mapperMask(
narrow<
byte>((sram.size() / 0x2000) - 1))
96 for (
auto i :
xrange(
byte(4))) {
100 if (spc) spc->reset(
true);
103void ESE_SCC::setMapperLow(
unsigned page,
byte value)
108 bool newSccEnable = (value == 0x3f);
109 if (newSccEnable != sccEnable) {
110 sccEnable = newSccEnable;
114 byte newValue = value;
115 if (page == 0) newValue |=
byte(mapper[0] & 0x40);
116 newValue &= mapperMask;
117 if (mapper[page] != newValue) {
118 mapper[page] = newValue;
126void ESE_SCC::setMapperHigh(
byte value)
128 writeEnable = (value & 0x10) != 0;
132 byte mapperHigh = value & 0x40;
133 if (
bool newSpcEnable = mapperHigh && !writeEnable;
134 spcEnable != newSpcEnable) {
135 spcEnable = newSpcEnable;
139 if (
byte newValue = ((mapper[0] & 0x3F) | mapperHigh) & mapperMask;
140 mapper[0] != newValue) {
141 mapper[0] = newValue;
151 unsigned page = address / 0x2000 - 2;
153 if (spcEnable && (page == 0)) {
155 if (address < 0x1000) {
156 return spc->readDREG();
158 return spc->readRegister(address & 0x0f);
162 if (sccEnable && (address >= 0x9800) && (address < 0xa000)) {
163 return scc.
readMem(narrow_cast<uint8_t>(address & 0xff), time);
166 return sram[mapper[page] * 0x2000 + (address & 0x1fff)];
171 unsigned page = address / 0x2000 - 2;
173 if (spcEnable && (page == 0)) {
175 if (address < 0x1000) {
176 return spc->peekDREG();
178 return spc->peekRegister(address & 0x0f);
182 if (sccEnable && (address >= 0x9800) && (address < 0xa000)) {
183 return scc.
peekMem(narrow_cast<uint8_t>(address & 0xff), time);
186 return sram[mapper[page] * 0x2000 + (address & 0x1fff)];
191 unsigned page = address / 0x2000 - 2;
193 if (spcEnable && (page == 0)) {
197 if (sccEnable && (address >= 0x9800) && (address < 0xa000)) {
201 return &sram[mapper[page] * 0x2000 + (address & 0x1fff)];
206 unsigned page = address / 0x2000 - 2;
208 if (spcEnable && (page == 0)) {
210 if (address < 0x1000) {
211 spc->writeDREG(value);
213 spc->writeRegister(address & 0x0f, value);
219 if (sccEnable && (0x9800 <= address) && (address < 0xa000)) {
220 scc.
writeMem(narrow_cast<uint8_t>(address & 0xff), value, time);
225 if ((address | 0x0001) == 0x7FFF) {
226 setMapperHigh(value);
231 if (writeEnable && (page < 2)) {
232 sram.
write(mapper[page] * 0x2000 + (address & 0x1FFF), value);
237 if ((address & 0x1800) == 0x1000) {
238 setMapperLow(page, value);
249template<
typename Archive>
252 ar.template serializeBase<MSXDevice>(*
this);
253 ar.serialize(
"sram", sram,
255 if (spc) ar.serialize(
"MB89352", *spc);
256 ar.serialize(
"mapper", mapper,
257 "spcEnable", spcEnable,
258 "sccEnable", sccEnable,
259 "writeEnable", writeEnable);
#define REGISTER_MSXDEVICE(CLASS, NAME)
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.
void reset(EmuTime::param time) override
This method is called on reset.
void serialize(Archive &ar, unsigned version)
void powerUp(EmuTime::param time) override
This method is called when MSX is powered up.
ESE_SCC(const DeviceConfig &config, bool withSCSI)
byte * getWriteCacheLine(word address) override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
virtual const std::string & getName() const
Returns a human-readable name for this device.
void invalidateDeviceRWCache()
Calls MSXCPUInterface::invalidateXXCache() for the specific (part of) the slot that this device is lo...
const XMLElement & getDeviceConfig() const
Get the configuration section for this device.
void powerUp(EmuTime::param time)
uint8_t readMem(uint8_t address, EmuTime::param time)
void reset(EmuTime::param time)
uint8_t peekMem(uint8_t address, EmuTime::param time) const
void writeMem(uint8_t address, uint8_t value, EmuTime::param time)
void write(size_t addr, byte value)
int getChildDataAsInt(std::string_view childName, int defaultValue) const
This file implemented 3 utility functions:
uint8_t byte
8 bit unsigned integer
uint16_t word
16 bit unsigned integer
constexpr void iota(ForwardIt first, ForwardIt last, T value)
constexpr To narrow(From from) noexcept
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
constexpr auto xrange(T e)