9static constexpr byte MEM_ACCESS_ENABLED = 1 << 7;
10static constexpr byte SOUND_PORT_ENABLED = 1 << 6;
11static constexpr byte PORT_ACCESS_DISABLED = 1 << 5;
12static constexpr byte UNUSED = 1 << 4;
13static constexpr byte WRITE_PROTECT = 0x0F;
40 if (controlReg & PORT_ACCESS_DISABLED) {
49 if (controlReg & PORT_ACCESS_DISABLED) {
58 if ((port & 0xFC) == 0xFC) {
60 if (!(controlReg & PORT_ACCESS_DISABLED)) {
64 }
else if (port & 1) {
66 if (controlReg & SOUND_PORT_ENABLED) {
67 sn76489.
write(value, time);
75 updateControlReg((value & MEM_ACCESS_ENABLED) |
76 (controlReg & ~MEM_ACCESS_ENABLED));
80bool MusicalMemoryMapper::registerAccessAt(
word address)
const
82 if (controlReg & MEM_ACCESS_ENABLED) {
83 if (controlReg & PORT_ACCESS_DISABLED) {
87 if (controlReg & 0x08) {
88 return 0x4000 <= address && address < 0x8000;
90 return 0x8000 <= address && address < 0xC000;
93 return 0x4000 <= address && address < 0xC000;
100int MusicalMemoryMapper::readReg(
word address)
const
102 if (registerAccessAt(address)) {
103 switch (address & 0xFF) {
116void MusicalMemoryMapper::updateControlReg(
byte value)
122 byte change = value ^ controlReg;
125 byte invalidate = change & WRITE_PROTECT;
128 byte regAccessBefore = 0;
129 for (
auto page :
xrange(4)) {
130 regAccessBefore |=
byte(registerAccessAt(narrow_cast<word>(0x4000 * page)) << page);
133 byte regAccessAfter = 0;
134 for (
auto page :
xrange(4)) {
135 regAccessAfter |=
byte(registerAccessAt(narrow_cast<word>(0x4000 * page)) << page);
137 invalidate |= regAccessBefore ^ regAccessAfter;
139 for (
auto page :
xrange(4)) {
140 if ((invalidate >> page) & 1) {
149 int reg = readReg(address);
155 int reg = readReg(address);
161 if (registerAccessAt(address)) {
162 switch (address & 0xFF) {
166 if (value & PORT_ACCESS_DISABLED) {
167 value |= MEM_ACCESS_ENABLED;
169 updateControlReg(value);
180 if (!writeProtected(address)) {
187 if (controlReg & MEM_ACCESS_ENABLED) {
188 if (0x4000 <= start && start < 0xC000) {
197 if (controlReg & MEM_ACCESS_ENABLED) {
198 if (0x4000 <= start && start < 0xC000) {
202 if (writeProtected(start)) {
209template<
typename Archive>
212 ar.template serializeBase<MSXMemoryMapperBase>(*
this);
213 ar.serialize(
"ctrl", controlReg,
#define REGISTER_MSXDEVICE(CLASS, NAME)
static std::array< byte, 0x10000 > unmappedWrite
void invalidateDeviceRWCache()
Calls MSXCPUInterface::invalidateXXCache() for the specific (part of) the slot that this device is lo...
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
void writeIOImpl(word port, byte value, EmuTime::param time)
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
std::array< byte, 4 > registers
byte * getWriteCacheLine(word start) override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
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.
byte getSelectedSegment(byte page) const override
Returns the currently selected segment for the given page.
const byte * getReadCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
Memory mapper which also controls an SN76489AN sound chip.
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
void reset(EmuTime::param time) override
This method is called on reset.
const byte * getReadCacheLine(word start) 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 serialize(Archive &ar, unsigned version)
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 readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
byte * getWriteCacheLine(word start) override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
MusicalMemoryMapper(const DeviceConfig &config)
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
void reset(EmuTime::param time)
void write(byte value, EmuTime::param time)
constexpr auto enumerate(Iterable &&iterable)
Heavily inspired by Nathan Reed's blog post: Python-Like enumerate() In C++17 http://reedbeta....
This file implemented 3 utility functions:
uint8_t byte
8 bit unsigned integer
uint16_t word
16 bit unsigned integer
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
constexpr auto xrange(T e)