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