openMSX
DeviceFactory.cc
Go to the documentation of this file.
1 #include "DeviceFactory.hh"
2 #include "XMLElement.hh"
3 #include "DeviceConfig.hh"
4 #include "ChakkariCopy.hh"
5 #include "CanonWordProcessor.hh"
6 #include "FraelSwitchableROM.hh"
7 #include "MSXRam.hh"
8 #include "MSXPPI.hh"
9 #include "SVIPPI.hh"
10 #include "VDP.hh"
11 #include "MSXE6Timer.hh"
12 #include "MSXFacMidiInterface.hh"
13 #include "MSXHiResTimer.hh"
15 #include "MSXTurboRPause.hh"
16 #include "MSXTurboRPCM.hh"
17 #include "MSXS1985.hh"
18 #include "MSXS1990.hh"
19 #include "ColecoJoystickIO.hh"
20 #include "ColecoSuperGameModule.hh"
21 #include "MSXPSG.hh"
22 #include "SVIPSG.hh"
23 #include "SNPSG.hh"
24 #include "MSXMusic.hh"
25 #include "MSXFmPac.hh"
26 #include "MSXAudio.hh"
27 #include "MSXMoonSound.hh"
28 #include "MSXOPL3Cartridge.hh"
29 #include "MSXYamahaSFG.hh"
30 #include "MusicModuleMIDI.hh"
31 #include "JVCMSXMIDI.hh"
32 #include "MSXKanji.hh"
33 #include "MSXBunsetsu.hh"
34 #include "MSXMemoryMapper.hh"
35 #include "MSXToshibaTcx200x.hh"
36 #include "MegaFlashRomSCCPlusSD.hh"
37 #include "MusicalMemoryMapper.hh"
38 #include "Carnivore2.hh"
39 #include "PanasonicRam.hh"
40 #include "MSXRTC.hh"
41 #include "PasswordCart.hh"
42 #include "RomFactory.hh"
43 #include "MSXPrinterPort.hh"
44 #include "SVIPrinterPort.hh"
45 #include "MSXSCCPlusCart.hh"
46 #include "PhilipsFDC.hh"
47 #include "MicrosolFDC.hh"
48 #include "AVTFDC.hh"
49 #include "NationalFDC.hh"
50 #include "VictorFDC.hh"
51 #include "SanyoFDC.hh"
52 #include "ToshibaFDC.hh"
53 #include "CanonFDC.hh"
54 #include "SpectravideoFDC.hh"
55 #include "TalentTDC600.hh"
56 #include "TurboRFDC.hh"
57 #include "SVIFDC.hh"
58 #include "YamahaFDC.hh"
59 #include "SunriseIDE.hh"
60 #include "BeerIDE.hh"
61 #include "GoudaSCSI.hh"
62 #include "MegaSCSI.hh"
63 #include "ESE_RAM.hh"
64 #include "ESE_SCC.hh"
65 #include "MSXMatsushita.hh"
67 #include "MSXCielTurbo.hh"
68 #include "MSXKanji12.hh"
69 #include "MSXMidi.hh"
70 #include "MSXRS232.hh"
71 #include "MSXMegaRam.hh"
72 #include "MSXPac.hh"
73 #include "MSXHBI55.hh"
74 #include "DebugDevice.hh"
75 #include "V9990.hh"
76 #include "Video9000.hh"
77 #include "ADVram.hh"
78 #include "NowindInterface.hh"
79 #include "MSXMirrorDevice.hh"
80 #include "DummyDevice.hh"
81 #include "MSXDeviceSwitch.hh"
82 #include "MSXMapperIO.hh"
83 #include "VDPIODelay.hh"
84 #include "SensorKid.hh"
85 #include "CliComm.hh"
86 #include "MSXException.hh"
87 #include "components.hh"
88 #include "one_of.hh"
89 #include <memory>
90 
91 #if COMPONENT_LASERDISC
92 #include "PioneerLDControl.hh"
93 #endif
94 
95 using std::make_unique;
96 
97 namespace openmsx {
98 
99 [[nodiscard]] static std::unique_ptr<MSXDevice> createWD2793BasedFDC(const DeviceConfig& conf)
100 {
101  const auto* styleEl = conf.findChild("connectionstyle");
102  std::string type;
103  if (!styleEl) {
104  conf.getCliComm().printWarning(
105  "WD2793 as FDC type without a connectionstyle is "
106  "deprecated, please update your config file to use "
107  "WD2793 with connectionstyle Philips!");
108  type = "Philips";
109  } else {
110  type = styleEl->getData();
111  }
112  if (type == one_of("Philips", "Sony")) {
113  return make_unique<PhilipsFDC>(conf);
114  } else if (type == "Microsol") {
115  return make_unique<MicrosolFDC>(conf);
116  } else if (type == "AVT") {
117  return make_unique<AVTFDC>(conf);
118  } else if (type == "National") {
119  return make_unique<NationalFDC>(conf);
120  } else if (type == "Sanyo") {
121  return make_unique<SanyoFDC>(conf);
122  } else if (type == "Toshiba") {
123  return make_unique<ToshibaFDC>(conf);
124  } else if (type == "Canon") {
125  return make_unique<CanonFDC>(conf);
126  } else if (type == "Spectravideo") {
127  return make_unique<SpectravideoFDC>(conf);
128  } else if (type == "Victor") {
129  return make_unique<VictorFDC>(conf);
130  } else if (type == "Yamaha") {
131  return make_unique<YamahaFDC>(conf);
132  }
133  throw MSXException("Unknown WD2793 FDC connection style ", type);
134 }
135 
136 std::unique_ptr<MSXDevice> DeviceFactory::create(const DeviceConfig& conf)
137 {
138  std::unique_ptr<MSXDevice> result;
139  const auto& type = conf.getXML()->getName();
140  if (type == "PPI") {
141  result = make_unique<MSXPPI>(conf);
142  } else if (type == "SVIPPI") {
143  result = make_unique<SVIPPI>(conf);
144  } else if (type == "RAM") {
145  result = make_unique<MSXRam>(conf);
146  } else if (type == "VDP") {
147  result = make_unique<VDP>(conf);
148  } else if (type == "E6Timer") {
149  result = make_unique<MSXE6Timer>(conf);
150  } else if (type == "HiResTimer") {
151  result = make_unique<MSXHiResTimer>(conf);
152  } else if (type == one_of("ResetStatusRegister", "F4Device")) {
153  result = make_unique<MSXResetStatusRegister>(conf);
154  } else if (type == "TurboRPause") {
155  result = make_unique<MSXTurboRPause>(conf);
156  } else if (type == "TurboRPCM") {
157  result = make_unique<MSXTurboRPCM>(conf);
158  } else if (type == "S1985") {
159  result = make_unique<MSXS1985>(conf);
160  } else if (type == "S1990") {
161  result = make_unique<MSXS1990>(conf);
162  } else if (type == "ColecoJoystick") {
163  result = make_unique<ColecoJoystickIO>(conf);
164  } else if (type == "SuperGameModule") {
165  result = make_unique<ColecoSuperGameModule>(conf);
166  } else if (type == "PSG") {
167  result = make_unique<MSXPSG>(conf);
168  } else if (type == "SVIPSG") {
169  result = make_unique<SVIPSG>(conf);
170  } else if (type == "SNPSG") {
171  result = make_unique<SNPSG>(conf);
172  } else if (type == "MSX-MUSIC") {
173  result = make_unique<MSXMusic>(conf);
174  } else if (type == "MSX-MUSIC-WX") {
175  result = make_unique<MSXMusicWX>(conf);
176  } else if (type == "FMPAC") {
177  result = make_unique<MSXFmPac>(conf);
178  } else if (type == "MSX-AUDIO") {
179  result = make_unique<MSXAudio>(conf);
180  } else if (type == "MusicModuleMIDI") {
181  result = make_unique<MusicModuleMIDI>(conf);
182  } else if (type == "JVCMSXMIDI") {
183  result = make_unique<JVCMSXMIDI>(conf);
184  } else if (type == "FACMIDIInterface") {
185  result = make_unique<MSXFacMidiInterface>(conf);
186  } else if (type == "YamahaSFG") {
187  result = make_unique<MSXYamahaSFG>(conf);
188  } else if (type == "MoonSound") {
189  result = make_unique<MSXMoonSound>(conf);
190  } else if (type == "OPL3Cartridge") {
191  result = make_unique<MSXOPL3Cartridge>(conf);
192  } else if (type == "Kanji") {
193  result = make_unique<MSXKanji>(conf);
194  } else if (type == "Bunsetsu") {
195  result = make_unique<MSXBunsetsu>(conf);
196  } else if (type == "MemoryMapper") {
197  result = make_unique<MSXMemoryMapper>(conf);
198  } else if (type == "PanasonicRAM") {
199  result = make_unique<PanasonicRam>(conf);
200  } else if (type == "RTC") {
201  result = make_unique<MSXRTC>(conf);
202  } else if (type == "PasswordCart") {
203  result = make_unique<PasswordCart>(conf);
204  } else if (type == "ROM") {
205  result = RomFactory::create(conf);
206  } else if (type == "PrinterPort") {
207  result = make_unique<MSXPrinterPort>(conf);
208  } else if (type == "SVIPrinterPort") {
209  result = make_unique<SVIPrinterPort>(conf);
210  } else if (type == "SCCplus") { // Note: it's actually called SCC-I
211  result = make_unique<MSXSCCPlusCart>(conf);
212  } else if (type == one_of("WD2793", "WD1770")) {
213  result = createWD2793BasedFDC(conf);
214  } else if (type == "Microsol") {
215  conf.getCliComm().printWarning(
216  "Microsol as FDC type is deprecated, please update "
217  "your config file to use WD2793 with connectionstyle "
218  "Microsol!");
219  result = make_unique<MicrosolFDC>(conf);
220  } else if (type == "MB8877A") {
221  conf.getCliComm().printWarning(
222  "MB8877A as FDC type is deprecated, please update your "
223  "config file to use WD2793 with connectionstyle National!");
224  result = make_unique<NationalFDC>(conf);
225  } else if (type == "TC8566AF") {
226  result = make_unique<TurboRFDC>(conf);
227  } else if (type == "TDC600") {
228  result = make_unique<TalentTDC600>(conf);
229  } else if (type == "ToshibaTCX-200x") {
230  result = make_unique<MSXToshibaTcx200x>(conf);
231  } else if (type == "SVIFDC") {
232  result = make_unique<SVIFDC>(conf);
233  } else if (type == "BeerIDE") {
234  result = make_unique<BeerIDE>(conf);
235  } else if (type == "SunriseIDE") {
236  result = make_unique<SunriseIDE>(conf);
237  } else if (type == "GoudaSCSI") {
238  result = make_unique<GoudaSCSI>(conf);
239  } else if (type == "MegaSCSI") {
240  result = make_unique<MegaSCSI>(conf);
241  } else if (type == "ESERAM") {
242  result = make_unique<ESE_RAM>(conf);
243  } else if (type == "WaveSCSI") {
244  result = make_unique<ESE_SCC>(conf, true);
245  } else if (type == "ESESCC") {
246  result = make_unique<ESE_SCC>(conf, false);
247  } else if (type == "Matsushita") {
248  result = make_unique<MSXMatsushita>(conf);
249  } else if (type == "VictorHC9xSystemControl") {
250  result = make_unique<MSXVictorHC9xSystemControl>(conf);
251  } else if (type == "CielTurbo") {
252  result = make_unique<MSXCielTurbo>(conf);
253  } else if (type == "Kanji12") {
254  result = make_unique<MSXKanji12>(conf);
255  } else if (type == "MSX-MIDI") {
256  result = make_unique<MSXMidi>(conf);
257  } else if (type == "MSX-RS232") {
258  result = make_unique<MSXRS232>(conf);
259  } else if (type == "MegaRam") {
260  result = make_unique<MSXMegaRam>(conf);
261  } else if (type == "PAC") {
262  result = make_unique<MSXPac>(conf);
263  } else if (type == "HBI55") {
264  result = make_unique<MSXHBI55>(conf);
265  } else if (type == "DebugDevice") {
266  result = make_unique<DebugDevice>(conf);
267  } else if (type == "V9990") {
268  result = make_unique<V9990>(conf);
269  } else if (type == "Video9000") {
270  result = make_unique<Video9000>(conf);
271  } else if (type == "ADVram") {
272  result = make_unique<ADVram>(conf);
273  } else if (type == "PioneerLDControl") {
274 #if COMPONENT_LASERDISC
275  result = make_unique<PioneerLDControl>(conf);
276 #else
277  throw MSXException("Laserdisc component not compiled in");
278 #endif
279  } else if (type == "Nowind") {
280  result = make_unique<NowindInterface>(conf);
281  } else if (type == "Mirror") {
282  result = make_unique<MSXMirrorDevice>(conf);
283  } else if (type == "SensorKid") {
284  result = make_unique<SensorKid>(conf);
285  } else if (type == "FraelSwitchableROM") {
286  result = make_unique<FraelSwitchableROM>(conf);
287  } else if (type == "ChakkariCopy") {
288  result = make_unique<ChakkariCopy>(conf);
289  } else if (type == "CanonWordProcessor") {
290  result = make_unique<CanonWordProcessor>(conf);
291  } else if (type == "MegaFlashRomSCCPlusSD") {
292  result = make_unique<MegaFlashRomSCCPlusSD>(conf);
293  } else if (type == "MusicalMemoryMapper") {
294  result = make_unique<MusicalMemoryMapper>(conf);
295  } else if (type == "Carnivore2") {
296  result = make_unique<Carnivore2>(conf);
297  } else if (type == "T9769") {
298  // Ignore for now. We might want to create a real device for it later.
299  } else {
300  throw MSXException("Unknown device \"", type,
301  "\" specified in configuration");
302  }
303  if (result) result->init();
304  return result;
305 }
306 
307 [[nodiscard]] static XMLElement& createConfig(const char* name, const char* id)
308 {
309  auto& doc = XMLDocument::getStaticDocument();
310  auto* config = doc.allocateElement(name);
311  config->setFirstAttribute(doc.allocateAttribute("id", id));
312  return *config;
313 }
314 
315 std::unique_ptr<DummyDevice> DeviceFactory::createDummyDevice(
316  const HardwareConfig& hwConf)
317 {
318  static XMLElement& xml(createConfig("Dummy", ""));
319  return make_unique<DummyDevice>(DeviceConfig(hwConf, xml));
320 }
321 
322 std::unique_ptr<MSXDeviceSwitch> DeviceFactory::createDeviceSwitch(
323  const HardwareConfig& hwConf)
324 {
325  static XMLElement& xml(createConfig("DeviceSwitch", "DeviceSwitch"));
326  return make_unique<MSXDeviceSwitch>(DeviceConfig(hwConf, xml));
327 }
328 
329 std::unique_ptr<MSXMapperIO> DeviceFactory::createMapperIO(
330  const HardwareConfig& hwConf)
331 {
332  static XMLElement& xml(createConfig("MapperIO", "MapperIO"));
333  return make_unique<MSXMapperIO>(DeviceConfig(hwConf, xml));
334 }
335 
336 std::unique_ptr<VDPIODelay> DeviceFactory::createVDPIODelay(
337  const HardwareConfig& hwConf, MSXCPUInterface& cpuInterface)
338 {
339  static XMLElement& xml(createConfig("VDPIODelay", "VDPIODelay"));
340  return make_unique<VDPIODelay>(DeviceConfig(hwConf, xml), cpuInterface);
341 }
342 
343 } // namespace openmsx
Definition: one_of.hh:7
void printWarning(std::string_view message)
Definition: CliComm.cc:10
CliComm & getCliComm() const
Definition: DeviceConfig.cc:18
const XMLElement * getXML() const
Definition: DeviceConfig.hh:48
static std::unique_ptr< MSXDevice > create(const DeviceConfig &conf)
static std::unique_ptr< DummyDevice > createDummyDevice(const HardwareConfig &hwConf)
static std::unique_ptr< MSXDeviceSwitch > createDeviceSwitch(const HardwareConfig &hwConf)
static std::unique_ptr< VDPIODelay > createVDPIODelay(const HardwareConfig &hwConf, MSXCPUInterface &cpuInterface)
static std::unique_ptr< MSXMapperIO > createMapperIO(const HardwareConfig &hwConf)
static XMLDocument & getStaticDocument()
Definition: XMLElement.hh:258
std::string_view getName() const
Definition: XMLElement.hh:173
std::unique_ptr< MSXDevice > create(const DeviceConfig &config)
Definition: RomFactory.cc:156
This file implemented 3 utility functions:
Definition: Autofire.cc:9