openMSX
MSXFmPac.cc
Go to the documentation of this file.
1#include "MSXFmPac.hh"
2#include "CacheLine.hh"
3#include "serialize.hh"
4
5namespace openmsx {
6
7static constexpr const char* const PAC_Header = "PAC2 BACKUP DATA";
8
10 : MSXMusicBase(config)
11 , sram(getName() + " SRAM", 0x1FFE, config, PAC_Header)
12 , romBlockDebug(*this, std::span{&bank, 1}, 0x4000, 0x4000, 14)
13{
15}
16
17void MSXFmPac::reset(EmuTime::param time)
18{
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
27void MSXFmPac::writeIO(word port, byte value, EmuTime::param time)
28{
29 if (enable & 1) {
30 MSXMusicBase::writeIO(port, value, time);
31 }
32}
33
34byte 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
59const 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.data();
72 }
73 } else {
74 return &rom[bank * 0x4000 + address];
75 }
76}
77
78void 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
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.data();
135 }
136}
137
138void MSXFmPac::checkSramEnable()
139{
140 bool newEnabled = (r1ffe == 0x4D) && (r1fff == 0x69);
141 if (sramEnabled != newEnabled) {
142 sramEnabled = newEnabled;
144 }
145}
146
147
148template<typename Archive>
149void 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 constexpr (Archive::IS_LOADER) {
158 // sramEnabled can be calculated
159 checkSramEnable();
160 }
161}
164
165} // namespace openmsx
#define REGISTER_MSXDEVICE(CLASS, NAME)
Definition MSXDevice.hh:354
void invalidateDeviceRCache()
Definition MSXDevice.hh:213
static std::array< byte, 0x10000 > unmappedRead
Definition MSXDevice.hh:304
static std::array< byte, 0x10000 > unmappedWrite
Definition MSXDevice.hh:305
void invalidateDeviceRWCache()
Calls MSXCPUInterface::invalidateXXCache() for the specific (part of) the slot that this device is lo...
Definition MSXDevice.hh:212
EmuTime::param getCurrentTime() const
Definition MSXDevice.cc:125
MSXFmPac(const DeviceConfig &config)
Definition MSXFmPac.cc:9
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
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
void reset(EmuTime::param time) override
This method is called on reset.
Definition MSXFmPac.cc:17
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
void serialize(Archive &ar, unsigned version)
Definition MSXFmPac.cc:149
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
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
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
void reset(EmuTime::param time) override
This method is called on reset.
Definition MSXMusic.cc:23
void writePort(bool port, byte value, EmuTime::param time)
Definition MSXMusic.cc:33
void write(size_t addr, byte value)
Definition SRAM.cc:63
constexpr unsigned HIGH
Definition CacheLine.hh:10
This file implemented 3 utility functions:
Definition Autofire.cc:9
uint16_t word
16 bit unsigned integer
Definition openmsx.hh:29
STL namespace.
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)