openMSX
MSXFmPac.cc
Go to the documentation of this file.
1 #include "MSXFmPac.hh"
2 #include "CacheLine.hh"
3 #include "serialize.hh"
4 
5 namespace openmsx {
6 
7 constexpr const char* const PAC_Header = "PAC2 BACKUP DATA";
8 
10  : MSXMusicBase(config)
11  , sram(getName() + " SRAM", 0x1FFE, config, PAC_Header)
12  , romBlockDebug(*this, &bank, 0x4000, 0x4000, 14)
13 {
15 }
16 
17 void MSXFmPac::reset(EmuTime::param time)
18 {
19  MSXMusicBase::reset(time);
20  enable = 0;
21  sramEnabled = false;
22  bank = 0;
23  r1ffe = r1fff = 0; // actual value doesn't matter as long
24  // as it's not the magic combination
25 }
26 
27 void MSXFmPac::writeIO(word port, byte value, EmuTime::param time)
28 {
29  if (enable & 1) {
30  MSXMusicBase::writeIO(port, value, time);
31  }
32 }
33 
34 byte MSXFmPac::readMem(word address, EmuTime::param /*time*/)
35 {
36  address &= 0x3FFF;
37  switch (address) {
38  case 0x3FF6:
39  return enable;
40  case 0x3FF7:
41  return bank;
42  default:
43  if (sramEnabled) {
44  if (address < 0x1FFE) {
45  return sram[address];
46  } else if (address == 0x1FFE) {
47  return r1ffe; // always 0x4D
48  } else if (address == 0x1FFF) {
49  return r1fff; // always 0x69
50  } else {
51  return 0xFF;
52  }
53  } else {
54  return rom[bank * 0x4000 + address];
55  }
56  }
57 }
58 
59 const byte* MSXFmPac::getReadCacheLine(word address) const
60 {
61  address &= 0x3FFF;
62  if (address == (0x3FF6 & CacheLine::HIGH)) {
63  return nullptr;
64  }
65  if (sramEnabled) {
66  if (address < (0x1FFE & CacheLine::HIGH)) {
67  return &sram[address];
68  } else if (address == (0x1FFE & CacheLine::HIGH)) {
69  return nullptr;
70  } else {
71  return unmappedRead;
72  }
73  } else {
74  return &rom[bank * 0x4000 + address];
75  }
76 }
77 
78 void MSXFmPac::writeMem(word address, byte value, EmuTime::param time)
79 {
80  // 'enable' has no effect for memory mapped access
81  // (thanks to BiFiMSX for investigating this)
82  address &= 0x3FFF;
83  switch (address) {
84  case 0x1FFE:
85  if (!(enable & 0x10)) {
86  r1ffe = value;
87  checkSramEnable();
88  }
89  break;
90  case 0x1FFF:
91  if (!(enable & 0x10)) {
92  r1fff = value;
93  checkSramEnable();
94  }
95  break;
96  case 0x3FF4: // address
97  case 0x3FF5: // data
98  writePort(address & 1, value, time);
99  break;
100  case 0x3FF6:
101  enable = value & 0x11;
102  if (enable & 0x10) {
103  r1ffe = r1fff = 0; // actual value not important
104  checkSramEnable();
105  }
106  break;
107  case 0x3FF7: {
108  byte newBank = value & 0x03;
109  if (bank != newBank) {
110  bank = newBank;
112  }
113  break;
114  }
115  default:
116  if (sramEnabled && (address < 0x1FFE)) {
117  sram.write(address, value);
118  }
119  }
120 }
121 
122 byte* MSXFmPac::getWriteCacheLine(word address) const
123 {
124  address &= 0x3FFF;
125  if (address == (0x1FFE & CacheLine::HIGH)) {
126  return nullptr;
127  }
128  if (address == (0x3FF4 & CacheLine::HIGH)) {
129  return nullptr;
130  }
131  if (sramEnabled && (address < 0x1FFE)) {
132  return nullptr;
133  } else {
134  return unmappedWrite;
135  }
136 }
137 
138 void MSXFmPac::checkSramEnable()
139 {
140  bool newEnabled = (r1ffe == 0x4D) && (r1fff == 0x69);
141  if (sramEnabled != newEnabled) {
142  sramEnabled = newEnabled;
144  }
145 }
146 
147 
148 template<typename Archive>
149 void MSXFmPac::serialize(Archive& ar, unsigned version)
150 {
151  ar.template serializeInlinedBase<MSXMusicBase>(*this, version);
152  ar.serialize("sram", sram,
153  "enable", enable,
154  "bank", bank,
155  "r1ffe", r1ffe,
156  "r1fff", r1fff);
157  if (ar.isLoader()) {
158  // sramEnabled can be calculated
159  checkSramEnable();
160  }
161 }
164 
165 } // namespace openmsx
openmsx::MSXMusicBase
Definition: MSXMusic.hh:12
openmsx::MSXFmPac::writeIO
void writeIO(word port, byte value, EmuTime::param time) override
Write a byte to a given IO port at a certain time to this device.
Definition: MSXFmPac.cc:27
serialize.hh
openmsx::PAC_Header
constexpr const char *const PAC_Header
Definition: MSXPac.cc:7
openmsx::DeviceConfig
Definition: DeviceConfig.hh:20
openmsx::MSXDevice::unmappedWrite
static byte unmappedWrite[0x10000]
Definition: MSXDevice.hh:301
openmsx::MSXFmPac::readMem
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
Definition: MSXFmPac.cc:34
openmsx::CacheLine::HIGH
constexpr unsigned HIGH
Definition: CacheLine.hh:10
openmsx::MSXFmPac::serialize
void serialize(Archive &ar, unsigned version)
Definition: MSXFmPac.cc:149
MSXFmPac.hh
openmsx::REGISTER_MSXDEVICE
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
openmsx::MSXMusicBase::writePort
void writePort(bool port, byte value, EmuTime::param time)
Definition: MSXMusic.cc:33
openmsx::Keys::getName
string getName(KeyCode keyCode)
Translate key code to key name.
Definition: Keys.cc:740
openmsx::MSXDevice::getCurrentTime
EmuTime::param getCurrentTime() const
Definition: MSXDevice.cc:131
INSTANTIATE_SERIALIZE_METHODS
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:981
openmsx::MSXFmPac::MSXFmPac
MSXFmPac(const DeviceConfig &config)
Definition: MSXFmPac.cc:9
CacheLine.hh
openmsx::SRAM::write
void write(unsigned addr, byte value)
Definition: SRAM.cc:67
openmsx::MSXFmPac
Definition: MSXFmPac.hh:12
openmsx::MSXMusicBase::writeIO
void writeIO(word port, byte value, EmuTime::param time) override
Write a byte to a given IO port at a certain time to this device.
Definition: MSXMusic.cc:28
openmsx::MSXDevice::invalidateDeviceRCache
void invalidateDeviceRCache()
Definition: MSXDevice.hh:209
openmsx::MSXDevice::invalidateDeviceRWCache
void invalidateDeviceRWCache()
Calls MSXCPUInterface::invalidateXXCache() for the specific (part of) the slot that this device is lo...
Definition: MSXDevice.hh:208
openmsx::MSXFmPac::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: MSXFmPac.cc:78
openmsx::MSXDevice::unmappedRead
static byte unmappedRead[0x10000]
Definition: MSXDevice.hh:300
openmsx::word
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
openmsx::MSXFmPac::reset
void reset(EmuTime::param time) override
This method is called on reset.
Definition: MSXFmPac.cc:17
openmsx::MSXMusicBase::reset
void reset(EmuTime::param time) override
This method is called on reset.
Definition: MSXMusic.cc:23
openmsx::MSXFmPac::getWriteCacheLine
byte * getWriteCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
Definition: MSXFmPac.cc:122
openmsx
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
openmsx::MSXFmPac::getReadCacheLine
const byte * getReadCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition: MSXFmPac.cc:59
openmsx::MSXMusicBase::rom
Rom rom
Definition: MSXMusic.hh:29