25 using std::unique_ptr;
33 auto result = make_unique<HardwareConfig>(motherBoard, machineName);
34 result->load(
"machines");
41 auto result = make_unique<HardwareConfig>(motherBoard, extensionName);
42 result->load(
"extensions");
43 result->setName(extensionName);
49 const string& slotname,
const vector<string>& options)
51 auto result = make_unique<HardwareConfig>(motherBoard,
"rom");
53 auto context = make_unique<UserFileContext>(
"roms/" + sramfile);
55 vector<string> ipsfiles;
58 bool romTypeOptionFound =
false;
61 for (
auto it = options.begin(); it != options.end(); ++it) {
62 const auto& option = *it++;
63 if (it == options.end()) {
67 if (option ==
"-ips") {
71 ipsfiles.push_back(*it);
72 }
else if (option ==
"-romtype") {
73 if (!romTypeOptionFound) {
75 romTypeOptionFound =
true;
77 throw MSXException(
"Only one -romtype option is allowed");
85 context->resolve(romfile));
87 throw MSXException(
"Invalid ROM file: " + resolvedFilename);
105 if (!ipsfiles.empty()) {
107 for (
auto& s : ipsfiles) {
117 "mappertype", mapper.empty() ?
"auto" : mapper));
125 result->setConfig(move(extension));
127 result->setFileContext(move(context));
133 : motherBoard(motherBoard_)
136 for (
auto ps :
xrange(4)) {
137 for (
auto ss :
xrange(4)) {
138 externalSlots[ps][ss] =
false;
140 externalPrimSlots[ps] =
false;
141 expandedSlots[ps] =
false;
142 allocatedPrimarySlots[ps] =
false;
158 while (!devices.empty()) {
163 for (
auto ps :
xrange(4)) {
164 for (
auto ss :
xrange(4)) {
165 if (externalSlots[ps][ss]) {
169 if (externalPrimSlots[ps]) {
170 slotManager.removeExternalSlot(ps);
172 if (expandedSlots[ps]) {
175 if (allocatedPrimarySlots[ps]) {
176 slotManager.freePrimarySlot(ps, *
this);
183 std::vector<MSXDevice*> alreadyRemoved;
184 for (
auto it = devices.rbegin(); it != devices.rend(); ++it) {
185 (*it)->testRemove(alreadyRemoved);
186 alreadyRemoved.push_back(it->get());
189 for (
auto ps :
xrange(4)) {
190 for (
auto ss :
xrange(4)) {
191 if (externalSlots[ps][ss]) {
195 if (externalPrimSlots[ps]) {
196 slotManager.testRemoveExternalSlot(ps, *
this);
198 if (expandedSlots[ps]) {
211 context = move(context_);
214 const XMLElement& HardwareConfig::getDevices()
const
229 }
catch (XMLException& e) {
231 "Loading of hardware configuration failed: " +
238 SystemFileContext context;
242 type, name +
".xml"));
243 }
catch (MSXException& e) {
248 type, name,
"hardwareconfig.xml"));
249 }
catch (MSXException&) {
257 string filename = getFilename(type, hwName);
260 assert(!userName.empty());
263 baseName, hwName, userName));
272 for (
auto& psElem : getDevices().getChildren(
"primary")) {
273 const auto& primSlot = psElem->getAttribute(
"slot");
275 if (psElem->getAttributeAsBool(
"external",
false)) {
278 "Cannot mark unspecified primary slot '" +
279 primSlot +
"' as external");
281 createExternalSlot(ps);
284 for (
auto& ssElem : psElem->getChildren(
"secondary")) {
285 const auto& secSlot = ssElem->getAttribute(
"slot");
288 if ((ss >= -128) && (0 <= ps) && (ps < 4) &&
296 ps = getFreePrimarySlot();
297 auto mutableElem =
const_cast<XMLElement*
>(psElem);
300 createExpandedSlot(ps);
301 if (ssElem->getAttributeAsBool(
"external",
false)) {
302 createExternalSlot(ps, ss);
317 const auto& name = c.getName();
318 if (name ==
"primary") {
320 }
else if (name ==
"secondary") {
324 DeviceConfig(*
this, c, primary, secondary));
326 addDevice(move(device));
329 "Deprecated device: \"" +
330 name +
"\", please upgrade your "
331 "hardware descriptions.");
337 void HardwareConfig::createExternalSlot(
int ps)
340 assert(!externalPrimSlots[ps]);
341 externalPrimSlots[ps] =
true;
344 void HardwareConfig::createExternalSlot(
int ps,
int ss)
347 assert(!externalSlots[ps][ss]);
348 externalSlots[ps][ss] =
true;
351 void HardwareConfig::createExpandedSlot(
int ps)
353 if (!expandedSlots[ps]) {
355 expandedSlots[ps] =
true;
359 int HardwareConfig::getFreePrimarySlot()
363 assert(!allocatedPrimarySlots[ps]);
364 allocatedPrimarySlots[ps] =
true;
368 void HardwareConfig::addDevice(std::unique_ptr<MSXDevice> device)
371 devices.push_back(move(device));
379 void HardwareConfig::setName(
const string& proposedName)
395 template<
typename Archive>
403 if (ar.versionBelow(version, 2)) {
406 ar.serialize(
"config", config);
407 if (ar.versionAtLeast(version, 2)) {
408 ar.serialize(
"context", context);
411 assert(context.get());
424 for (
auto& d : devices) {
425 ar.serializePolymorphic(
"device", *d);
427 ar.serialize(
"name", name);