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