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