openMSX
ESE_RAM.cc
Go to the documentation of this file.
1 /*
2  * MEGA-SCSI and ESE-RAM cartridge:
3  * The mapping does SRAM and MB89352A(MEGA-SCSI) to ASCII8 or
4  * an interchangeable bank controller.
5  * The rest of this documentation is only about ESE-RAM specifically.
6  *
7  * Specification:
8  * SRAM(MegaROM) controller: ASCII8 type
9  * SRAM capacity : 128, 256, 512 and 1024KB
10  *
11  * Bank changing address:
12  * bank 4(0x4000-0x5fff): 0x6000 - 0x67FF (0x6000 used)
13  * bank 6(0x6000-0x7fff): 0x6800 - 0x6FFF (0x6800 used)
14  * bank 8(0x8000-0x9fff): 0x7000 - 0x77FF (0x7000 used)
15  * bank A(0xa000-0xbfff): 0x7800 - 0x7FFF (0x7800 used)
16  *
17  * ESE-RAM Bank Map:
18  * BANK 00H-7FH (read only)
19  * BANK 80H-FFH (write and read. mirror of 00H-7FH)
20  */
21 
22 #include "ESE_RAM.hh"
23 #include "RomBlockDebuggable.hh"
24 #include "SRAM.hh"
25 #include "StringOp.hh"
26 #include "MSXException.hh"
27 #include "serialize.hh"
28 #include "memory.hh"
29 #include <cassert>
30 
31 namespace openmsx {
32 
33 static std::unique_ptr<SRAM> createSRAM(
34  const DeviceConfig& config, const std::string& name)
35 {
36  unsigned sramSize = config.getChildDataAsInt("sramsize", 256); // size in kb
37  if (sramSize != 1024 && sramSize != 512 && sramSize != 256 && sramSize != 128) {
38  throw MSXException(StringOp::Builder() <<
39  "SRAM size for " << name <<
40  " should be 128, 256, 512 or 1024kB and not " <<
41  sramSize << "kB!");
42  }
43  sramSize *= 1024; // in bytes
44  return make_unique<SRAM>(name + " SRAM", sramSize, config);
45 }
46 
48  : MSXDevice(config)
49  , sram(createSRAM(config, getName()))
50  , romBlockDebug(make_unique<RomBlockDebuggable>(
51  *this, mapped, 0x4000, 0x8000, 13))
52  , blockMask((sram->getSize() / 8192) - 1)
53 {
55 }
56 
58 {
59 }
60 
62 {
63  for (int i = 0; i < 4; ++i) {
64  setSRAM(i, 0);
65  }
66 }
67 
69 {
70  byte result;
71  if ((0x4000 <= address) && (address < 0xC000)) {
72  unsigned page = (address / 8192) - 2;
73  word addr = address & 0x1FFF;
74  result = (*sram)[8192 * mapped[page] + addr];
75  } else {
76  result = 0xFF;
77  }
78  return result;
79 }
80 
81 const byte* ESE_RAM::getReadCacheLine(word address) const
82 {
83  if ((0x4000 <= address) && (address < 0xC000)) {
84  unsigned page = (address / 8192) - 2;
85  address &= 0x1FFF;
86  return &(*sram)[8192 * mapped[page] + address];
87  } else {
88  return unmappedRead;
89  }
90 }
91 
92 void ESE_RAM::writeMem(word address, byte value, EmuTime::param /*time*/)
93 {
94  if ((0x6000 <= address) && (address < 0x8000)) {
95  byte region = ((address >> 11) & 3);
96  setSRAM(region, value);
97  } else if ((0x4000 <= address) && (address < 0xC000)) {
98  unsigned page = (address / 8192) - 2;
99  address &= 0x1FFF;
100  if (isWriteable[page]) {
101  sram->write(8192 * mapped[page] + address, value);
102  }
103  }
104 }
105 
107 {
108  if ((0x6000 <= address) && (address < 0x8000)) {
109  return nullptr;
110  } else if ((0x4000 <= address) && (address < 0xC000)) {
111  unsigned page = (address / 8192) - 2;
112  if (isWriteable[page]) {
113  return nullptr;
114  }
115  }
116  return unmappedWrite;
117 }
118 
119 void ESE_RAM::setSRAM(unsigned region, byte block)
120 {
121  invalidateMemCache(region * 0x2000 + 0x4000, 0x2000);
122  assert(region < 4);
123  isWriteable[region] = (block & 0x80) != 0;
124  mapped[region] = block & blockMask;
125 }
126 
127 template<typename Archive>
128 void ESE_RAM::serialize(Archive& ar, unsigned /*version*/)
129 {
130  ar.template serializeBase<MSXDevice>(*this);
131  ar.serialize("SRAM", *sram);
132  ar.serialize("isWriteable", isWriteable);
133  ar.serialize("mapped", mapped);
134 }
136 REGISTER_MSXDEVICE(ESE_RAM, "ESE_RAM");
137 
138 } // namespace openmsx
void serialize(Archive &ar, unsigned version)
Definition: ESE_RAM.cc:128
REGISTER_MSXDEVICE(DebugDevice,"DebugDevice")
static param dummy()
Definition: EmuTime.hh:21
virtual byte readMem(word address, EmuTime::param time)
Read a byte from a location at a certain time from this device.
Definition: ESE_RAM.cc:68
unsigned char byte
8 bit unsigned integer
Definition: openmsx.hh:33
virtual const byte * getReadCacheLine(word start) const
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading...
Definition: ESE_RAM.cc:81
virtual void writeMem(word address, byte value, EmuTime::param time)
Write a given byte to a given location at a certain time to this device.
Definition: ESE_RAM.cc:92
virtual void reset(EmuTime::param time)
This method is called on reset.
Definition: ESE_RAM.cc:61
virtual ~ESE_RAM()
Definition: ESE_RAM.cc:57
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX...
Definition: MSXDevice.hh:32
unsigned short word
16 bit unsigned integer
Definition: openmsx.hh:38
static byte unmappedRead[0x10000]
Definition: MSXDevice.hh:266
ESE_RAM(const DeviceConfig &config)
Definition: ESE_RAM.cc:47
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:802
static byte unmappedWrite[0x10000]
Definition: MSXDevice.hh:267
const string getName(KeyCode keyCode)
Translate key code to key name.
Definition: Keys.cc:363
virtual byte * getWriteCacheLine(word start) const
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing...
Definition: ESE_RAM.cc:106
std::unique_ptr< T > make_unique()
Definition: memory.hh:27
void invalidateMemCache(word start, unsigned size)
Invalidate CPU memory-mapping cache.
Definition: MSXDevice.cc:465