openMSX
RomNational.cc
Go to the documentation of this file.
1 #include "RomNational.hh"
2 #include "CacheLine.hh"
3 #include "SRAM.hh"
4 #include "serialize.hh"
5 #include <memory>
6 
7 namespace openmsx {
8 
10  : Rom16kBBlocks(config, std::move(rom_))
11 {
12  sram = std::make_unique<SRAM>(getName() + " SRAM", 0x1000, config);
13  reset(EmuTime::dummy());
14 }
15 
16 void RomNational::reset(EmuTime::param /*time*/)
17 {
18  control = 0;
19  for (int region = 0; region < 4; ++region) {
20  setRom(region, 0);
21  bankSelect[region] = 0;
22  invalidateDeviceRCache((region * 0x4000) + (0x3FF0 & CacheLine::HIGH),
24  }
25  sramAddr = 0; // TODO check this
26 }
27 
28 byte RomNational::peekMem(word address, EmuTime::param time) const
29 {
30  if ((control & 0x04) && ((address & 0x7FF9) == 0x7FF0)) {
31  // TODO check mirrored
32  // 7FF0 7FF2 7FF4 7FF6 bank select read back
33  int bank = (address & 6) / 2;
34  return bankSelect[bank];
35  }
36  if ((control & 0x02) && ((address & 0x3FFF) == 0x3FFD)) {
37  // SRAM read
38  return (*sram)[sramAddr & 0x0FFF];
39  }
40  return Rom16kBBlocks::peekMem(address, time);
41 }
42 
43 byte RomNational::readMem(word address, EmuTime::param time)
44 {
45  byte result = RomNational::peekMem(address, time);
46  if ((control & 0x02) && ((address & 0x3FFF) == 0x3FFD)) {
47  ++sramAddr;
48  }
49  return result;
50 }
51 
52 const byte* RomNational::getReadCacheLine(word address) const
53 {
54  if ((0x3FF0 & CacheLine::HIGH) == (address & 0x3FFF)) {
55  return nullptr;
56  } else {
57  return Rom16kBBlocks::getReadCacheLine(address);
58  }
59 }
60 
61 void RomNational::writeMem(word address, byte value, EmuTime::param /*time*/)
62 {
63  // TODO bank switch address mirrored?
64  if (address == 0x6000) {
65  bankSelect[1] = value;
66  setRom(1, value); // !!
68  } else if (address == 0x6400) {
69  bankSelect[0] = value;
70  setRom(0, value); // !!
72  } else if (address == 0x7000) {
73  bankSelect[2] = value;
74  setRom(2, value);
76  } else if (address == 0x7400) {
77  bankSelect[3] = value;
78  setRom(3, value);
80  } else if (address == 0x7FF9) {
81  // write control byte
82  control = value;
83  } else if (control & 0x02) {
84  address &= 0x3FFF;
85  if (address == 0x3FFA) {
86  // SRAM address bits 23-16
87  sramAddr = (sramAddr & 0x00FFFF) | value << 16;
88  } else if (address == 0x3FFB) {
89  // SRAM address bits 15-8
90  sramAddr = (sramAddr & 0xFF00FF) | value << 8;
91  } else if (address == 0x3FFC) {
92  // SRAM address bits 7-0
93  sramAddr = (sramAddr & 0xFFFF00) | value;
94  } else if (address == 0x3FFD) {
95  sram->write((sramAddr++ & 0x0FFF), value);
96  }
97  }
98 }
99 
101 {
102  if ((address == (0x6000 & CacheLine::HIGH)) ||
103  (address == (0x6400 & CacheLine::HIGH)) ||
104  (address == (0x7000 & CacheLine::HIGH)) ||
105  (address == (0x7400 & CacheLine::HIGH)) ||
106  (address == (0x7FF9 & CacheLine::HIGH))) {
107  return nullptr;
108  } else if ((address & 0x3FFF) == (0x3FFA & CacheLine::HIGH)) {
109  return nullptr;
110  } else {
111  return unmappedWrite;
112  }
113 }
114 
115 template<typename Archive>
116 void RomNational::serialize(Archive& ar, unsigned /*version*/)
117 {
118  ar.template serializeBase<Rom16kBBlocks>(*this);
119  ar.serialize("control", control,
120  "sramAddr", sramAddr,
121  "bankSelect", bankSelect);
122 }
124 REGISTER_MSXDEVICE(RomNational, "RomNational");
125 
126 } // namespace openmsx
openmsx::RomBlocks::peekMem
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: RomBlocks.cc:59
openmsx::RomNational::peekMem
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition: RomNational.cc:28
serialize.hh
openmsx::DeviceConfig
Definition: DeviceConfig.hh:19
openmsx::RomNational::RomNational
RomNational(const DeviceConfig &config, Rom &&rom)
Definition: RomNational.cc:9
RomNational.hh
openmsx::MSXDevice::unmappedWrite
static byte unmappedWrite[0x10000]
Definition: MSXDevice.hh:293
openmsx::RomBlocks::sram
std::unique_ptr< SRAM > sram
Definition: RomBlocks.hh:83
openmsx::CacheLine::HIGH
constexpr unsigned HIGH
Definition: CacheLine.hh:10
openmsx::REGISTER_MSXDEVICE
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
openmsx::RomBlocks::getReadCacheLine
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:71
openmsx::RomBlocks::setRom
void setRom(byte region, unsigned block)
Selects a block of the ROM image for reading in a certain region.
Definition: RomBlocks.cc:104
openmsx::RomBlocks
Definition: RomBlocks.hh:13
INSTANTIATE_SERIALIZE_METHODS
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:981
openmsx::CacheLine::SIZE
constexpr unsigned SIZE
Definition: CacheLine.hh:7
CacheLine.hh
openmsx::Rom
Definition: Rom.hh:20
openmsx::MSXDevice::invalidateDeviceRCache
void invalidateDeviceRCache()
Definition: MSXDevice.hh:209
openmsx::RomNational::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: RomNational.cc:61
SRAM.hh
openmsx::RomNational::serialize
void serialize(Archive &ar, unsigned version)
Definition: RomNational.cc:116
openmsx::RomNational
Definition: RomNational.hh:8
openmsx::MSXDevice::getName
virtual std::string getName() const
Returns a human-readable name for this device.
Definition: MSXDevice.cc:379
openmsx::word
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
openmsx::RomNational::getWriteCacheLine
byte * getWriteCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
Definition: RomNational.cc:100
openmsx::RomNational::getReadCacheLine
const byte * getReadCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition: RomNational.cc:52
openmsx::RomNational::readMem
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: RomNational.cc:43
openmsx::RomNational::reset
void reset(EmuTime::param time) override
This method is called on reset.
Definition: RomNational.cc:16
openmsx
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5