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