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
23namespace 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
39void 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
52byte 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
65const 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
78void 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
119template<typename Archive>
120void 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
STL namespace.
size_t size(std::string_view utf8)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1009
constexpr auto xrange(T e)
Definition: xrange.hh:133