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