openMSX
RomPanasonic.cc
Go to the documentation of this file.
1 #include "RomPanasonic.hh"
2 #include "PanasonicMemory.hh"
3 #include "MSXMotherBoard.hh"
4 #include "DeviceConfig.hh"
5 #include "SRAM.hh"
6 #include "CacheLine.hh"
7 #include "Rom.hh"
8 #include "serialize.hh"
9 #include "memory.hh"
10 
11 namespace openmsx {
12 
13 const int SRAM_BASE = 0x80;
14 const int RAM_BASE = 0x180;
15 
16 RomPanasonic::RomPanasonic(const DeviceConfig& config, std::unique_ptr<Rom> rom_)
17  : Rom8kBBlocks(config, std::move(rom_))
18  , panasonicMem(getMotherBoard().getPanasonicMemory())
19 {
20  unsigned sramSize = config.getChildDataAsInt("sramsize", 0);
21  if (sramSize) {
22  sram = make_unique<SRAM>(
23  getName() + " SRAM", sramSize * 1024, config);
24  }
25 
26  if (config.getChildDataAsBool("sram-mirrored", false)) {
27  maxSRAMBank = SRAM_BASE + 8;
28  } else {
29  maxSRAMBank = SRAM_BASE + (sramSize / 8);
30  }
31 
32  // Inform baseclass about PanasonicMemory (needed for serialization).
33  // This relies on the order of MSXDevice instantiation, the PanasonicRam
34  // device must be create before this one. (In the hardwareconfig.xml
35  // we added a device-reference from this device to the PanasonicRam
36  // device, this should protected against wrong future edits in the
37  // config file).
38  setExtraMemory(panasonicMem.getRamBlock(0), panasonicMem.getRamSize());
39 
41 }
42 
44 {
45 }
46 
48 {
49  control = 0;
50  for (int region = 0; region < 8; ++region) {
51  bankSelect[region] = 0;
52  setRom(region, 0);
53  }
54 }
55 
57 {
58  byte result;
59  if ((control & 0x04) && (0x7FF0 <= address) && (address < 0x7FF8)) {
60  // read mapper state (lower 8 bit)
61  result = bankSelect[address & 7] & 0xFF;
62  } else if ((control & 0x10) && (address == 0x7FF8)) {
63  // read mapper state (9th bit)
64  result = 0;
65  for (int i = 7; i >= 0; i--) {
66  result <<= 1;
67  if (bankSelect[i] & 0x100) {
68  result++;
69  }
70  }
71  } else if ((control & 0x08) && (address == 0x7FF9)) {
72  // read control byte
73  result = control;
74  } else {
75  result = Rom8kBBlocks::peekMem(address, time);
76  }
77  return result;
78 }
79 
81 {
82  return RomPanasonic::peekMem(address, time);
83 }
84 
86 {
87  if ((0x7FF0 & CacheLine::HIGH) == address) {
88  // TODO check mirrored
89  return nullptr;
90  } else {
91  return Rom8kBBlocks::getReadCacheLine(address);
92  }
93 }
94 
95 void RomPanasonic::writeMem(word address, byte value, EmuTime::param /*time*/)
96 {
97  if ((0x6000 <= address) && (address < 0x7FF0)) {
98  // set mapper state (lower 8 bits)
99  int region = (address & 0x1C00) >> 10;
100  if ((region == 5) || (region == 6)) region ^= 3;
101  int selectedBank = bankSelect[region];
102  int newBank = (selectedBank & ~0xFF) | value;
103  changeBank(region, newBank);
104  } else if (address == 0x7FF8) {
105  // set mapper state (9th bit)
106  for (int region = 0; region < 8; region++) {
107  if (value & 1) {
108  changeBank(region, bankSelect[region] | 0x100);
109  } else {
110  changeBank(region, bankSelect[region] & ~0x100);
111  }
112  value >>= 1;
113  }
114  } else if (address == 0x7FF9) {
115  // write control byte
116  control = value;
117  } else if ((0x8000 <= address) && (address < 0xC000)) {
118  int region = address >> 13;
119  int selectedBank = bankSelect[region];
120  if (sram && (SRAM_BASE <= selectedBank) &&
121  (selectedBank < maxSRAMBank)) {
122  // SRAM
123  int block = selectedBank - SRAM_BASE;
124  sram->write((block * 0x2000) | (address & 0x1FFF), value);
125  } else if (RAM_BASE <= selectedBank) {
126  // RAM
127  const_cast<byte*>(bank[region])[address & 0x1FFF] = value;
128  }
129  }
130 }
131 
133 {
134  //return nullptr;
135  if ((0x6000 <= address) && (address < 0x7FF0)) {
136  return nullptr;
137  } else if (address == (0x7FF8 & CacheLine::HIGH)) {
138  return nullptr;
139  } else if ((0x8000 <= address) && (address < 0xC000)) {
140  int region = address >> 13;
141  int selectedBank = bankSelect[region];
142  if (sram && (SRAM_BASE <= selectedBank) &&
143  (selectedBank < maxSRAMBank)) {
144  // SRAM
145  return nullptr;
146  } else if (RAM_BASE <= selectedBank) {
147  // RAM
148  return const_cast<byte*>(&bank[region][address & 0x1FFF]);
149  } else {
150  return unmappedWrite;
151  }
152  } else {
153  return unmappedWrite;
154  }
155 }
156 
157 void RomPanasonic::changeBank(byte region, int bank)
158 {
159  if (bank == bankSelect[region]) {
160  return;
161  }
162  bankSelect[region] = bank;
163 
164  if (sram && (SRAM_BASE <= bank) && (bank < maxSRAMBank)) {
165  // SRAM
166  int offset = (bank - SRAM_BASE) * 0x2000;
167  int sramSize = sram->getSize();
168  if (offset >= sramSize) {
169  offset &= (sramSize - 1);
170  }
171  // TODO romblock debuggable is only 8 bits, here bank is 9 bits
172  setBank(region, &sram->operator[](offset), bank);
173  } else if (panasonicMem.getRamSize() && (RAM_BASE <= bank)) {
174  // RAM
175  // TODO romblock debuggable is only 8 bits, here bank is 9 bits
176  setBank(region, panasonicMem.getRamBlock(bank - RAM_BASE), bank);
177  } else {
178  // ROM
179  setRom(region, bank);
180  }
181 }
182 
183 template<typename Archive>
184 void RomPanasonic::serialize(Archive& ar, unsigned /*version*/)
185 {
186  ar.template serializeBase<Rom8kBBlocks>(*this);
187  ar.serialize("bankSelect", bankSelect);
188  ar.serialize("control", control);
189 }
191 REGISTER_MSXDEVICE(RomPanasonic, "RomPanasonic");
192 
193 } // namespace openmsx
void setRom(byte region, int block)
Selects a block of the ROM image for reading in a certain region.
Definition: RomBlocks.cc:95
signed char offset
Definition: CPUCore.cc:252
REGISTER_MSXDEVICE(DebugDevice,"DebugDevice")
void serialize(Archive &ar, unsigned version)
static param dummy()
Definition: EmuTime.hh:21
virtual byte peekMem(word address, EmuTime::param time) const
Read a byte from a given memory location.
Definition: RomPanasonic.cc:56
virtual const byte * getReadCacheLine(word start) const
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading...
Definition: RomBlocks.cc:56
const byte * bank[NUM_BANKS]
Definition: RomBlocks.hh:80
unsigned getRamSize() const
unsigned char byte
8 bit unsigned integer
Definition: openmsx.hh:33
virtual const byte * getReadCacheLine(word address) const
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading...
Definition: RomPanasonic.cc:85
virtual byte readMem(word address, EmuTime::param time)
Read a byte from a location at a certain time from this device.
Definition: RomPanasonic.cc:80
bool getChildDataAsBool(string_ref name, bool defaultValue=false) const
Definition: DeviceConfig.cc:56
const int RAM_BASE
Definition: RomPanasonic.cc:14
void setBank(byte region, const byte *adr, int block)
Sets the memory visible for reading in a certain region.
Definition: RomBlocks.cc:62
virtual void reset(EmuTime::param time)
This method is called on reset.
Definition: RomPanasonic.cc:47
RomPanasonic(const DeviceConfig &config, std::unique_ptr< Rom > rom)
Definition: RomPanasonic.cc:16
virtual std::string getName() const
Returns a human-readable name for this device.
Definition: MSXDevice.cc:392
byte * getRamBlock(unsigned block)
Note that this is always unchecked RAM! There is no UMR detection when accessing Ram in DRAM mode or ...
int getChildDataAsInt(string_ref name, int defaultValue=0) const
Definition: DeviceConfig.cc:52
unsigned short word
16 bit unsigned integer
Definition: openmsx.hh:38
virtual byte * getWriteCacheLine(word address) const
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing...
const int SRAM_BASE
Definition: RomPanasonic.cc:13
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:802
static byte unmappedWrite[0x10000]
Definition: MSXDevice.hh:261
virtual byte peekMem(word address, EmuTime::param time) const
Read a byte from a given memory location.
Definition: MSXDevice.cc:460
std::unique_ptr< SRAM > sram
Definition: RomBlocks.hh:81
void setExtraMemory(const byte *mem, unsigned size)
Inform this base class of extra mapable memory block.
Definition: RomBlocks.cc:88
virtual void writeMem(word address, byte value, EmuTime::param time)
Write a given byte to a given location at a certain time to this device.
Definition: RomPanasonic.cc:95