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 "MSXException.hh"
24#include "one_of.hh"
25#include "serialize.hh"
26#include "xrange.hh"
27#include <cassert>
28
29namespace openmsx {
30
31unsigned ESE_RAM::getSramSize() const
32{
33 unsigned sramSize = getDeviceConfig().getChildDataAsInt("sramsize", 256); // size in kb
34 if (sramSize != one_of(1024u, 512u, 256u, 128u)) {
35 throw MSXException(
36 "SRAM size for ", getName(),
37 " should be 128, 256, 512 or 1024kB and not ",
38 sramSize, "kB!");
39 }
40 return sramSize * 1024; // in bytes
41}
42
44 : MSXDevice(config)
45 , sram(getName() + " SRAM", getSramSize(), config)
46 , romBlockDebug(*this, mapped, 0x4000, 0x8000, 13)
47 , blockMask((sram.getSize() / 8192) - 1)
48{
49 reset(EmuTime::dummy());
50}
51
52void ESE_RAM::reset(EmuTime::param /*time*/)
53{
54 for (auto i : xrange(4)) {
55 setSRAM(i, 0);
56 }
57}
58
59byte ESE_RAM::readMem(word address, EmuTime::param /*time*/)
60{
61 if ((0x4000 <= address) && (address < 0xC000)) {
62 unsigned page = (address / 8192) - 2;
63 word addr = address & 0x1FFF;
64 return sram[8192 * mapped[page] + addr];
65 } else {
66 return 0xFF;
67 }
68}
69
70const byte* ESE_RAM::getReadCacheLine(word address) const
71{
72 if ((0x4000 <= address) && (address < 0xC000)) {
73 unsigned page = (address / 8192) - 2;
74 address &= 0x1FFF;
75 return &sram[8192 * mapped[page] + address];
76 } else {
77 return unmappedRead;
78 }
79}
80
81void ESE_RAM::writeMem(word address, byte value, EmuTime::param /*time*/)
82{
83 if ((0x6000 <= address) && (address < 0x8000)) {
84 byte region = ((address >> 11) & 3);
85 setSRAM(region, value);
86 } else if ((0x4000 <= address) && (address < 0xC000)) {
87 unsigned page = (address / 8192) - 2;
88 address &= 0x1FFF;
89 if (isWriteable[page]) {
90 sram.write(8192 * mapped[page] + address, value);
91 }
92 }
93}
94
95byte* ESE_RAM::getWriteCacheLine(word address) const
96{
97 if ((0x6000 <= address) && (address < 0x8000)) {
98 return nullptr;
99 } else if ((0x4000 <= address) && (address < 0xC000)) {
100 unsigned page = (address / 8192) - 2;
101 if (isWriteable[page]) {
102 return nullptr;
103 }
104 }
105 return unmappedWrite;
106}
107
108void ESE_RAM::setSRAM(unsigned region, byte block)
109{
110 invalidateDeviceRWCache(region * 0x2000 + 0x4000, 0x2000);
111 assert(region < 4);
112 isWriteable[region] = (block & 0x80) != 0;
113 mapped[region] = block & blockMask;
114}
115
116template<typename Archive>
117void ESE_RAM::serialize(Archive& ar, unsigned /*version*/)
118{
119 ar.template serializeBase<MSXDevice>(*this);
120 ar.serialize("SRAM", sram,
121 "isWriteable", isWriteable,
122 "mapped", mapped);
123}
126
127} // namespace openmsx
Definition: one_of.hh:7
void serialize(Archive &ar, unsigned version)
Definition: ESE_RAM.cc:117
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: ESE_RAM.cc:59
const byte * getReadCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition: ESE_RAM.cc:70
void reset(EmuTime::param time) override
This method is called on reset.
Definition: ESE_RAM.cc:52
ESE_RAM(const DeviceConfig &config)
Definition: ESE_RAM.cc:43
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: ESE_RAM.cc:81
byte * getWriteCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
Definition: ESE_RAM.cc:95
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition: MSXDevice.hh:33
virtual const std::string & getName() const
Returns a human-readable name for this device.
Definition: MSXDevice.cc:376
static byte unmappedRead[0x10000]
Definition: MSXDevice.hh:301
void invalidateDeviceRWCache()
Calls MSXCPUInterface::invalidateXXCache() for the specific (part of) the slot that this device is lo...
Definition: MSXDevice.hh:209
const XMLElement & getDeviceConfig() const
Get the configuration section for this device.
Definition: MSXDevice.hh:231
static byte unmappedWrite[0x10000]
Definition: MSXDevice.hh:302
void write(unsigned addr, byte value)
Definition: SRAM.cc:64
int getChildDataAsInt(std::string_view childName, int defaultValue) const
Definition: XMLElement.cc:81
std::string getName(KeyCode keyCode)
Translate key code to key name.
Definition: Keys.cc:727
This file implemented 3 utility functions:
Definition: Autofire.cc:9
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1009
constexpr auto xrange(T e)
Definition: xrange.hh:133