openMSX
MSXPac.cc
Go to the documentation of this file.
1 #include "MSXPac.hh"
2 #include "SRAM.hh"
3 #include "CacheLine.hh"
4 #include "serialize.hh"
5 #include "memory.hh"
6 
7 namespace openmsx {
8 
9 static const char* const PAC_Header = "PAC2 BACKUP DATA";
10 
12  : MSXDevice(config)
13  , sram(make_unique<SRAM>(
14  getName() + " SRAM", 0x1FFE, config, PAC_Header))
15 {
17 }
18 
20 {
21 }
22 
24 {
25  sramEnabled = false;
26  r1ffe = r1fff = 0xFF; // TODO check
27 }
28 
30 {
31  byte result;
32  address &= 0x3FFF;
33  if (sramEnabled) {
34  if (address < 0x1FFE) {
35  result = (*sram)[address];
36  } else if (address == 0x1FFE) {
37  result = r1ffe;
38  } else if (address == 0x1FFF) {
39  result = r1fff;
40  } else {
41  result = 0xFF;
42  }
43  } else {
44  result = 0xFF;
45  }
46  return result;
47 }
48 
49 const byte* MSXPac::getReadCacheLine(word address) const
50 {
51  address &= 0x3FFF;
52  if (sramEnabled) {
53  if (address < (0x1FFE & CacheLine::HIGH)) {
54  return &(*sram)[address];
55  } else if (address == (0x1FFE & CacheLine::HIGH)) {
56  return nullptr;
57  } else {
58  return unmappedRead;
59  }
60  } else {
61  return unmappedRead;
62  }
63 }
64 
65 void MSXPac::writeMem(word address, byte value, EmuTime::param /*time*/)
66 {
67  address &= 0x3FFF;
68  switch (address) {
69  case 0x1FFE:
70  r1ffe = value;
71  checkSramEnable();
72  break;
73  case 0x1FFF:
74  r1fff = value;
75  checkSramEnable();
76  break;
77  default:
78  if (sramEnabled && (address < 0x1FFE)) {
79  sram->write(address, value);
80  }
81  }
82 }
83 
85 {
86  address &= 0x3FFF;
87  if (address == (0x1FFE & CacheLine::HIGH)) {
88  return nullptr;
89  }
90  if (sramEnabled && (address < 0x1FFE)) {
91  return nullptr;
92  } else {
93  return unmappedWrite;
94  }
95 }
96 
97 void MSXPac::checkSramEnable()
98 {
99  bool newEnabled = (r1ffe == 0x4D) && (r1fff == 0x69);
100  if (sramEnabled != newEnabled) {
101  sramEnabled = newEnabled;
102  invalidateMemCache(0x0000, 0x10000);
103  }
104 }
105 
106 template<typename Archive>
107 void MSXPac::serialize(Archive& ar, unsigned /*version*/)
108 {
109  ar.template serializeBase<MSXDevice>(*this);
110  ar.serialize("SRAM", *sram);
111  ar.serialize("r1ffe", r1ffe);
112  ar.serialize("r1fff", r1fff);
113  if (ar.isLoader()) {
114  checkSramEnable();
115  }
116 }
118 REGISTER_MSXDEVICE(MSXPac, "PAC");
119 
120 } // namespace openmsx