openMSX
MSXMemoryMapperBase.cc
Go to the documentation of this file.
1 #include "MSXMemoryMapperBase.hh"
2 #include "MSXException.hh"
3 #include "Math.hh"
4 #include "outer.hh"
5 #include "ranges.hh"
6 #include "serialize.hh"
7 
8 namespace openmsx {
9 
10 unsigned MSXMemoryMapperBase::getRamSize() const
11 {
12  int kSize = getDeviceConfig().getChildDataAsInt("size");
13  if ((kSize % 16) != 0) {
14  throw MSXException("Mapper size is not a multiple of 16K: ", kSize);
15  }
16  if (kSize == 0) {
17  throw MSXException("Mapper size must be at least 16kB.");
18  }
19  return kSize * 1024; // in bytes
20 }
21 
23  : MSXDevice(config)
24  , MSXMapperIOClient(getMotherBoard())
25  , checkedRam(config, getName(), "memory mapper", getRamSize())
26  , debuggable(getMotherBoard(), getName())
27 {
28 }
29 
31 {
32  return 0x4000;
33 }
34 
35 void MSXMemoryMapperBase::powerUp(EmuTime::param time)
36 {
37  checkedRam.clear();
38  reset(time);
39 }
40 
41 void MSXMemoryMapperBase::reset(EmuTime::param /*time*/)
42 {
43  // Most mappers initialize to segment 0 for all pages.
44  // On MSX2 and higher, the BIOS will select segments 3..0 for pages 0..3.
46 }
47 
48 byte MSXMemoryMapperBase::readIO(word port, EmuTime::param time)
49 {
50  return peekIO(port, time);
51 }
52 
53 byte MSXMemoryMapperBase::peekIO(word port, EmuTime::param /*time*/) const
54 {
55  unsigned numSegments = checkedRam.getSize() / 0x4000;
56  return registers[port & 0x03] | ~(Math::ceil2(numSegments) - 1);
57 }
58 
59 void MSXMemoryMapperBase::writeIOImpl(word port, byte value, EmuTime::param /*time*/)
60 {
61  unsigned numSegments = checkedRam.getSize() / 0x4000;
62  registers[port & 3] = value & (Math::ceil2(numSegments) - 1);
63  // Note: subclasses are responsible for handling CPU cacheline stuff
64 }
65 
66 unsigned MSXMemoryMapperBase::segmentOffset(byte page) const
67 {
68  unsigned segment = registers[page];
69  unsigned numSegments = checkedRam.getSize() / 0x4000;
70  segment = (segment < numSegments) ? segment : segment & (numSegments - 1);
71  return segment * 0x4000;
72 }
73 
74 unsigned MSXMemoryMapperBase::calcAddress(word address) const
75 {
76  return segmentOffset(address / 0x4000) | (address & 0x3fff);
77 }
78 
79 byte MSXMemoryMapperBase::peekMem(word address, EmuTime::param /*time*/) const
80 {
81  return checkedRam.peek(calcAddress(address));
82 }
83 
84 byte MSXMemoryMapperBase::readMem(word address, EmuTime::param /*time*/)
85 {
86  return checkedRam.read(calcAddress(address));
87 }
88 
89 void MSXMemoryMapperBase::writeMem(word address, byte value, EmuTime::param /*time*/)
90 {
91  checkedRam.write(calcAddress(address), value);
92 }
93 
95 {
97 }
98 
100 {
102 }
103 
104 
105 // SimpleDebuggable
106 
107 MSXMemoryMapperBase::Debuggable::Debuggable(MSXMotherBoard& motherBoard_,
108  const std::string& name_)
109  : SimpleDebuggable(motherBoard_, name_ + " regs",
110  "Memory mapper registers", 4)
111 {
112 }
113 
114 byte MSXMemoryMapperBase::Debuggable::read(unsigned address)
115 {
116  auto& mapper = OUTER(MSXMemoryMapperBase, debuggable);
117  return mapper.registers[address];
118 }
119 
120 void MSXMemoryMapperBase::Debuggable::write(unsigned address, byte value)
121 {
122  auto& mapper = OUTER(MSXMemoryMapperBase, debuggable);
123  mapper.writeIO(address, value, EmuTime::dummy());
124 }
125 
126 
127 template<typename Archive>
128 void MSXMemoryMapperBase::serialize(Archive& ar, unsigned version)
129 {
130  ar.template serializeBase<MSXDevice>(*this);
131  if (ar.versionAtLeast(version, 2)) {
132  ar.serialize("registers", registers);
133  }
134  // TODO ar.serialize("checkedRam", checkedRam);
135  ar.serialize("ram", checkedRam.getUncheckedRam());
136 }
138 //REGISTER_MSXDEVICE(MSXMemoryMapperBase, "MemoryMapper");
139 
140 } // namespace openmsx
openmsx::MSXMemoryMapperBase::checkedRam
CheckedRam checkedRam
Definition: MSXMemoryMapperBase.hh:53
openmsx::MSXDevice
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition: MSXDevice.hh:31
openmsx::MSXMemoryMapperBase::powerUp
void powerUp(EmuTime::param time) override
This method is called when MSX is powered up.
Definition: MSXMemoryMapperBase.cc:35
openmsx::MSXMemoryMapperBase::serialize
void serialize(Archive &ar, unsigned version)
Definition: MSXMemoryMapperBase.cc:128
openmsx::CheckedRam::getSize
unsigned getSize() const
Definition: CheckedRam.hh:42
openmsx::CheckedRam::getWriteCacheLine
byte * getWriteCacheLine(unsigned addr) const
Definition: CheckedRam.cc:53
openmsx::MSXMemoryMapperBase::readMem
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: MSXMemoryMapperBase.cc:84
openmsx::MSXMemoryMapperBase::getReadCacheLine
const byte * getReadCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition: MSXMemoryMapperBase.cc:94
openmsx::MSXMemoryMapperBase::calcAddress
unsigned calcAddress(word address) const
Converts a Z80 address to a RAM address.
Definition: MSXMemoryMapperBase.cc:74
serialize.hh
openmsx::CheckedRam::read
byte read(unsigned addr)
Definition: CheckedRam.cc:36
openmsx::DeviceConfig
Definition: DeviceConfig.hh:19
MSXMemoryMapperBase.hh
openmsx::SimpleDebuggable
Definition: SimpleDebuggable.hh:11
openmsx::MSXMemoryMapperBase::registers
byte registers[4]
Definition: MSXMemoryMapperBase.hh:54
openmsx::MSXMemoryMapperBase::peekIO
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
Definition: MSXMemoryMapperBase.cc:53
ranges.hh
MSXException.hh
openmsx::MSXMemoryMapperBase::MSXMemoryMapperBase
MSXMemoryMapperBase(const DeviceConfig &config)
Definition: MSXMemoryMapperBase.cc:22
openmsx::MSXMemoryMapperBase::reset
void reset(EmuTime::param time) override
This method is called on reset.
Definition: MSXMemoryMapperBase.cc:41
openmsx::MSXMemoryMapperBase::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: MSXMemoryMapperBase.cc:89
OUTER
#define OUTER(type, member)
Definition: outer.hh:38
openmsx::CheckedRam::clear
void clear()
Definition: CheckedRam.cc:93
openmsx::CheckedRam::peek
byte peek(unsigned addr) const
Definition: CheckedRam.hh:35
openmsx::Keys::getName
string getName(KeyCode keyCode)
Translate key code to key name.
Definition: Keys.cc:589
openmsx::MSXMemoryMapperBase::peekMem
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: MSXMemoryMapperBase.cc:79
openmsx::MSXMotherBoard
Definition: MSXMotherBoard.hh:59
openmsx::CheckedRam::write
void write(unsigned addr, byte value)
Definition: CheckedRam.cc:72
INSTANTIATE_SERIALIZE_METHODS
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:981
openmsx::MSXMemoryMapperBase::getBaseSizeAlignment
unsigned getBaseSizeAlignment() const override
The 'base' and 'size' attribute values need to be at least aligned to CacheLine::SIZE.
Definition: MSXMemoryMapperBase.cc:30
openmsx::MSXMemoryMapperBase::writeIOImpl
void writeIOImpl(word port, byte value, EmuTime::param time)
Definition: MSXMemoryMapperBase.cc:59
openmsx::MSXMemoryMapperBase::getWriteCacheLine
byte * getWriteCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
Definition: MSXMemoryMapperBase.cc:99
outer.hh
openmsx::word
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
openmsx::MSXMapperIOClient
Definition: MSXMapperIO.hh:55
openmsx::XMLElement::getChildDataAsInt
int getChildDataAsInt(std::string_view childName, int defaultValue=0) const
Definition: XMLElement.cc:186
openmsx::MSXMemoryMapperBase
Definition: MSXMemoryMapperBase.hh:11
openmsx::CheckedRam::getUncheckedRam
Ram & getUncheckedRam()
Give access to the unchecked Ram.
Definition: CheckedRam.hh:51
openmsx::MSXMemoryMapperBase::segmentOffset
unsigned segmentOffset(byte page) const
Definition: MSXMemoryMapperBase.cc:66
Math.hh
ranges::fill
void fill(ForwardRange &&range, const T &value)
Definition: ranges.hh:191
Math::ceil2
constexpr T ceil2(T x) noexcept
Returns the smallest number that is both >=a and a power of two.
Definition: Math.hh:85
openmsx::MSXMemoryMapperBase
MSXMemoryMapperBase
Definition: MSXMemoryMapperBase.cc:137
openmsx
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
openmsx::CheckedRam::getReadCacheLine
const byte * getReadCacheLine(unsigned addr) const
Definition: CheckedRam.cc:47
openmsx::MSXMemoryMapperBase::readIO
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
Definition: MSXMemoryMapperBase.cc:48
openmsx::MSXDevice::getDeviceConfig
const XMLElement & getDeviceConfig() const
Get the configuration section for this device.
Definition: MSXDevice.hh:230