54static constexpr auto sectorInfo = [] {
56 using Info = AmdFlash::SectorInfo;
57 std::array<Info, 8 + 127> result = {};
58 std::fill(result.begin(), result.begin() + 8,
Info{ 8 * 1024, false});
59 std::fill(result.begin() + 8, result.end(),
Info{64 * 1024, false});
67 , flash(rom, sectorInfo, 0x207E,
68 AmdFlash::Addressing::BITS_12, config)
69 , scc(
"ReproCartV2 SCC", config, getCurrentTime(),
SCC::SCC_Compatible)
103 flashRomWriteEnabled =
false;
121unsigned ReproCartridgeV2::getFlashAddr(
unsigned addr)
const
123 unsigned page8kB = (addr >> 13) - 2;
124 if (page8kB >= 4)
return unsigned(-1);
126 byte bank = bankRegs[page8kB] & 127;
127 return (mainBankReg << 20) | (bank << 13) | (addr & 0x1FFF);
131bool ReproCartridgeV2::isSCCAccess(
word addr)
const
133 if ((mapperTypeReg != 0) || (sccMode & 0x10))
return false;
143 if (sccMode & 0x20) {
145 return (bankRegs[3] & 0x80) && (0xB800 <= addr) && (addr < 0xBFFE);
148 return ((bankRegs[2] & 0x3F) == 0x3F) && (0x9800 <= addr) && (addr < 0x9FFE);
154 if (isSCCAccess(addr)) {
155 return scc.
readMem(narrow_cast<uint8_t>(addr & 0xFF), time);
158 unsigned flashAddr = getFlashAddr(addr);
159 return (flashAddr !=
unsigned(-1))
160 ? flash.
read(flashAddr)
166 if (isSCCAccess(addr)) {
167 return scc.
peekMem(narrow_cast<uint8_t>(addr & 0xFF), time);
170 unsigned flashAddr = getFlashAddr(addr);
171 return (flashAddr !=
unsigned(-1))
172 ? flash.
peek(flashAddr)
178 if (isSCCAccess(addr))
return nullptr;
180 unsigned flashAddr = getFlashAddr(addr);
181 return (flashAddr !=
unsigned(-1))
188 unsigned page8kB = (addr >> 13) - 2;
189 if (page8kB >= 4)
return;
198 if (isSCCAccess(addr)) {
199 scc.
writeMem(narrow_cast<uint8_t>(addr & 0xFF), value, time);
204 unsigned flashAddr = getFlashAddr(addr);
207 if (addr == 0x7FFF) {
208 flashRomWriteEnabled = (value == 0x50);
212 if (addr == 0x7FFE) {
213 mapperTypeReg = value & 3;
217 if (!flashRomWriteEnabled) {
218 switch (mapperTypeReg) {
221 if ((addr & 0x1800) == 0x1000) {
224 bankRegs[page8kB] = value;
229 if ((addr & 0xFFFE) == 0xBFFE) {
243 if ((addr < 0x5000) || ((0x5800 <= addr) && (addr < 0x6000)))
break;
244 bankRegs[page8kB] = value & 0x7F;
251 if ((0x6000 <= addr) && (addr < 0x8000)) {
252 byte bank = (addr >> 11) & 0x03;
253 bankRegs[bank] = value;
266 if ((0x6000 <= addr) && (addr < 0x6800)) {
267 bankRegs[0] = narrow_cast<byte>(2 * value + 0);
268 bankRegs[1] = narrow_cast<byte>(2 * value + 1);
271 if ((0x7000 <= addr) && (addr < 0x7800)) {
272 bankRegs[2] = narrow_cast<byte>(2 * value + 0);
273 bankRegs[3] = narrow_cast<byte>(2 * value + 1);
281 if (flashAddr !=
unsigned(-1)) {
282 flash.
write(flashAddr, value);
289 return ((0x4000 <= addr) && (addr < 0xC000))
299 psg0x10Latch = value & 0x0F;
305 psg0xA0Latch = value & 0x0F;
314 mainBankReg = value & 7;
333template<
typename Archive>
337 ar.template serializeBase<MSXDevice>(*
this);
339 ar.serialize(
"flash", flash,
342 "psg0x10Latch", psg0x10Latch,
344 "psg0xA0Latch", psg0xA0Latch,
345 "flashRomWriteEnabled", flashRomWriteEnabled,
346 "mainBankReg", mainBankReg,
347 "volumeReg", volumeReg,
348 "mapperTypeReg", mapperTypeReg,
350 "bankRegs", bankRegs);
352 if constexpr (Archive::IS_LOADER) {
void reset(EmuTime::param time)
void writeRegister(unsigned reg, uint8_t value, EmuTime::param time)
void write(size_t address, uint8_t value)
const uint8_t * getReadCacheLine(size_t address) const
uint8_t peek(size_t address) const
uint8_t read(size_t address) const
void register_IO_Out(byte port, MSXDevice *device)
Devices can register their Out ports.
void unregister_IO_Out(byte port, MSXDevice *device)
void invalidateDeviceRCache()
static std::array< byte, 0x10000 > unmappedRead
static std::array< byte, 0x10000 > unmappedWrite
EmuTime::param getCurrentTime() const
MSXCPUInterface & getCPUInterface() const
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 * 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.
~ReproCartridgeV2() override
void reset(EmuTime::param time) override
This method is called on reset.
ReproCartridgeV2(const DeviceConfig &config, Rom &&rom)
void serialize(Archive &ar, unsigned version)
const byte * getReadCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
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.
void powerUp(EmuTime::param time) override
This method is called when MSX is powered up.
void setVolume(EmuTime::param time, byte value)
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
void setChipMode(ChipMode newMode)
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 setSoftwareVolume(float volume, EmuTime::param time)
Change the 'software volume' of this sound device.
This file implemented 3 utility functions:
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
AmdFlash::SectorInfo Info
uint16_t word
16 bit unsigned integer
constexpr void fill(ForwardRange &&range, const T &value)
constexpr void iota(ForwardIt first, ForwardIt last, T value)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)