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