openMSX
RomAscii8_8.cc
Go to the documentation of this file.
1 // ASCII 8kB based cartridges with SRAM
2 // - ASCII8-8 / KOEI-8 / KOEI-32 / WIZARDRY / ASCII8-2
3 //
4 // The address to change banks:
5 // bank 1: 0x6000 - 0x67ff (0x6000 used)
6 // bank 2: 0x6800 - 0x6fff (0x6800 used)
7 // bank 3: 0x7000 - 0x77ff (0x7000 used)
8 // bank 4: 0x7800 - 0x7fff (0x7800 used)
9 //
10 // To select SRAM set bit 7 (for WIZARDRY) or the bit just above the
11 // rom selection bits (bit 5/6/7 depending on ROM size). For KOEI-32
12 // the lowest bits indicate which SRAM page is selected. SRAM is
13 // readable at 0x8000-0xBFFF. For the KOEI-x types SRAM is also
14 // readable at 0x4000-0x5FFF
15 
16 #include "RomAscii8_8.hh"
17 #include "SRAM.hh"
18 #include "one_of.hh"
19 #include "serialize.hh"
20 #include "xrange.hh"
21 #include <memory>
22 
23 namespace openmsx {
24 
26  Rom&& rom_, SubType subType)
27  : Rom8kBBlocks(config, std::move(rom_))
28  , sramEnableBit((subType == WIZARDRY) ? 0x80
29  : rom.getSize() / BANK_SIZE)
30  , sramPages((subType == one_of(KOEI_8, KOEI_32)) ? 0x34 : 0x30)
31 {
32  unsigned size = (subType == one_of(KOEI_32, ASCII8_32)) ? 0x8000 // 32kB
33  : (subType == ASCII8_2) ? 0x0800 // 2kB
34  : 0x2000; // 8kB
35  sram = std::make_unique<SRAM>(getName() + " SRAM", size, config);
36  reset(EmuTime::dummy());
37 }
38 
39 void RomAscii8_8::reset(EmuTime::param /*time*/)
40 {
41  setUnmapped(0);
42  setUnmapped(1);
43  for (auto i : xrange(2, 6)) {
44  setRom(i, 0);
45  }
46  setUnmapped(6);
47  setUnmapped(7);
48 
49  sramEnabled = 0;
50 }
51 
52 byte RomAscii8_8::readMem(word address, EmuTime::param time)
53 {
54  byte bank = address / BANK_SIZE;
55  if ((1 << bank) & sramEnabled) {
56  // read from SRAM (possibly mirror)
57  word addr = (sramBlock[bank] * BANK_SIZE)
58  + (address & (sram->getSize() - 1) & BANK_MASK);
59  return (*sram)[addr];
60  } else {
61  return Rom8kBBlocks::readMem(address, time);
62  }
63 }
64 
65 const byte* RomAscii8_8::getReadCacheLine(word address) const
66 {
67  byte bank = address / BANK_SIZE;
68  if ((1 << bank) & sramEnabled) {
69  // read from SRAM (possibly mirror)
70  word addr = (sramBlock[bank] * BANK_SIZE)
71  + (address & (sram->getSize() - 1) & BANK_MASK);
72  return &(*sram)[addr];
73  } else {
74  return Rom8kBBlocks::getReadCacheLine(address);
75  }
76 }
77 
78 void RomAscii8_8::writeMem(word address, byte value, EmuTime::param /*time*/)
79 {
80  if ((0x6000 <= address) && (address < 0x8000)) {
81  // bank switching
82  byte region = ((address >> 11) & 3) + 2;
83  if (value & sramEnableBit) {
84  unsigned numBlocks = (sram->getSize() + BANK_MASK) / BANK_SIZE; // round up;
85  sramEnabled |= (1 << region) & sramPages;
86  sramBlock[region] = value & (numBlocks - 1);
87  setBank(region, &(*sram)[sramBlock[region] * BANK_SIZE], value);
88  invalidateDeviceRCache(0x2000 * region, 0x2000); // do not cache
89  } else {
90  sramEnabled &= ~(1 << region);
91  setRom(region, value);
92  }
93  // 'R' is already handled
94  invalidateDeviceWCache(0x2000 * region, 0x2000);
95  } else {
96  byte bank = address / BANK_SIZE;
97  if ((1 << bank) & sramEnabled) {
98  // write to SRAM (possibly mirror)
99  word addr = (sramBlock[bank] * BANK_SIZE)
100  + (address & (sram->getSize() - 1) & BANK_MASK);
101  sram->write(addr, value);
102  }
103  }
104 }
105 
107 {
108  if ((0x6000 <= address) && (address < 0x8000)) {
109  // bank switching
110  return nullptr;
111  } else if ((1 << (address / BANK_SIZE)) & sramEnabled) {
112  // write to SRAM
113  return nullptr;
114  } else {
115  return unmappedWrite;
116  }
117 }
118 
119 template<typename Archive>
120 void RomAscii8_8::serialize(Archive& ar, unsigned /*version*/)
121 {
122  ar.template serializeBase<Rom8kBBlocks>(*this);
123  ar.serialize("sramEnabled", sramEnabled,
124  "sramBlock", sramBlock);
125 }
128 
129 } // namespace openmsx
Definition: one_of.hh:7
void invalidateDeviceRCache()
Definition: MSXDevice.hh:210
void invalidateDeviceWCache()
Definition: MSXDevice.hh:211
virtual const std::string & getName() const
Returns a human-readable name for this device.
Definition: MSXDevice.cc:376
static byte unmappedWrite[0x10000]
Definition: MSXDevice.hh:302
byte * getWriteCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
Definition: RomAscii8_8.cc:106
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: RomAscii8_8.cc:52
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: RomAscii8_8.cc:78
const byte * getReadCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition: RomAscii8_8.cc:65
void serialize(Archive &ar, unsigned version)
Definition: RomAscii8_8.cc:120
void reset(EmuTime::param time) override
This method is called on reset.
Definition: RomAscii8_8.cc:39
RomAscii8_8(const DeviceConfig &config, Rom &&rom, SubType subType)
Definition: RomAscii8_8.cc:25
void setBank(byte region, const byte *adr, int block)
Sets the memory visible for reading in a certain region.
Definition: RomBlocks.cc:78
std::unique_ptr< SRAM > sram
Definition: RomBlocks.hh:84
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: RomBlocks.cc:66
static constexpr unsigned BANK_MASK
Definition: RomBlocks.hh:18
void setRom(byte region, unsigned block)
Selects a block of the ROM image for reading in a certain region.
Definition: RomBlocks.cc:105
const byte * getReadCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition: RomBlocks.cc:72
static constexpr unsigned BANK_SIZE
Definition: RomBlocks.hh:16
void setUnmapped(byte region)
Select 'unmapped' memory for this region.
Definition: RomBlocks.cc:92
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
size_t size(std::string_view utf8)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:998
constexpr auto xrange(T e)
Definition: xrange.hh:155