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