2017-11-05 17:49:28 +00:00
//
// MachineForTarget.cpp
// Clock Signal
//
// Created by Thomas Harte on 04/11/2017.
2018-05-13 19:19:52 +00:00
// Copyright 2017 Thomas Harte. All rights reserved.
2017-11-05 17:49:28 +00:00
//
# include "MachineForTarget.hpp"
2020-03-19 03:11:25 +00:00
# include <algorithm>
2020-10-21 02:18:11 +00:00
// Sources for runtime options and machines.
2024-03-04 17:06:43 +00:00
# include "../Acorn/Archimedes/Archimedes.hpp"
# include "../Acorn/Electron/Electron.hpp"
2021-07-17 00:30:48 +00:00
# include "../Amiga/Amiga.hpp"
2017-11-05 17:49:28 +00:00
# include "../AmstradCPC/AmstradCPC.hpp"
2019-05-03 22:14:10 +00:00
# include "../Apple/AppleII/AppleII.hpp"
2020-10-21 02:18:11 +00:00
# include "../Apple/AppleIIgs/AppleIIgs.hpp"
2019-05-04 02:16:07 +00:00
# include "../Apple/Macintosh/Macintosh.hpp"
2019-11-09 20:31:41 +00:00
# include "../Atari/2600/Atari2600.hpp"
# include "../Atari/ST/AtariST.hpp"
2018-02-24 03:47:15 +00:00
# include "../ColecoVision/ColecoVision.hpp"
2017-11-05 17:49:28 +00:00
# include "../Commodore/Vic-20/Vic20.hpp"
2021-06-15 00:55:39 +00:00
# include "../Enterprise/Enterprise.hpp"
2018-09-22 02:13:07 +00:00
# include "../MasterSystem/MasterSystem.hpp"
2017-11-25 18:18:24 +00:00
# include "../MSX/MSX.hpp"
2017-11-05 17:49:28 +00:00
# include "../Oric/Oric.hpp"
2023-11-15 19:27:04 +00:00
# include "../PCCompatible/PCCompatible.hpp"
2021-03-18 02:40:29 +00:00
# include "../Sinclair/ZX8081/ZX8081.hpp"
2021-03-18 03:38:55 +00:00
# include "../Sinclair/ZXSpectrum/ZXSpectrum.hpp"
2017-11-05 17:49:28 +00:00
2020-03-13 00:56:02 +00:00
// Sources for construction options.
# include "../../Analyser/Static/Acorn/Target.hpp"
2021-07-17 00:30:48 +00:00
# include "../../Analyser/Static/Amiga/Target.hpp"
2020-03-13 00:56:02 +00:00
# include "../../Analyser/Static/AmstradCPC/Target.hpp"
# include "../../Analyser/Static/AppleII/Target.hpp"
2020-10-21 02:18:11 +00:00
# include "../../Analyser/Static/AppleIIgs/Target.hpp"
2020-03-15 16:54:55 +00:00
# include "../../Analyser/Static/Atari2600/Target.hpp"
2020-03-13 00:56:02 +00:00
# include "../../Analyser/Static/AtariST/Target.hpp"
# include "../../Analyser/Static/Commodore/Target.hpp"
2021-06-15 00:55:39 +00:00
# include "../../Analyser/Static/Enterprise/Target.hpp"
2020-03-13 00:56:02 +00:00
# include "../../Analyser/Static/Macintosh/Target.hpp"
# include "../../Analyser/Static/MSX/Target.hpp"
# include "../../Analyser/Static/Oric/Target.hpp"
2023-12-21 18:01:41 +00:00
# include "../../Analyser/Static/PCCompatible/Target.hpp"
2020-03-15 16:54:55 +00:00
# include "../../Analyser/Static/Sega/Target.hpp"
2020-03-13 00:56:02 +00:00
# include "../../Analyser/Static/ZX8081/Target.hpp"
2021-03-20 02:17:20 +00:00
# include "../../Analyser/Static/ZXSpectrum/Target.hpp"
2020-03-13 00:56:02 +00:00
2018-01-29 03:22:21 +00:00
# include "../../Analyser/Dynamic/MultiMachine/MultiMachine.hpp"
2017-11-25 02:36:22 +00:00
# include "TypedDynamicMachine.hpp"
2017-11-05 17:49:28 +00:00
2024-01-13 03:03:19 +00:00
std : : unique_ptr < Machine : : DynamicMachine > Machine : : MachineForTarget ( const Analyser : : Static : : Target * target , const ROMMachine : : ROMFetcher & rom_fetcher , Machine : : Error & error ) {
2018-01-29 03:22:21 +00:00
error = Machine : : Error : : None ;
2018-01-25 23:28:19 +00:00
2024-01-13 03:03:19 +00:00
std : : unique_ptr < Machine : : DynamicMachine > machine ;
2018-07-11 00:00:46 +00:00
try {
2024-01-13 03:03:19 +00:00
# define BindD(name, m) case Analyser::Machine::m: machine = std::make_unique<Machine::TypedDynamicMachine<::name::Machine>>(name::Machine::m(target, rom_fetcher)); break;
2018-07-11 00:00:46 +00:00
# define Bind(m) BindD(m, m)
switch ( target - > machine ) {
2021-07-17 00:30:48 +00:00
Bind ( Amiga )
2018-07-11 00:00:46 +00:00
Bind ( AmstradCPC )
2024-03-04 17:06:43 +00:00
Bind ( Archimedes )
2019-05-03 22:14:10 +00:00
BindD ( Apple : : II , AppleII )
2020-10-21 02:18:11 +00:00
BindD ( Apple : : IIgs , AppleIIgs )
2019-05-04 02:16:07 +00:00
BindD ( Apple : : Macintosh , Macintosh )
2018-07-11 00:00:46 +00:00
Bind ( Atari2600 )
2019-10-04 00:17:26 +00:00
BindD ( Atari : : ST , AtariST )
2018-07-11 00:00:46 +00:00
BindD ( Coleco : : Vision , ColecoVision )
2019-06-02 17:39:25 +00:00
BindD ( Commodore : : Vic20 , Vic20 )
2018-07-11 00:00:46 +00:00
Bind ( Electron )
2021-06-15 00:55:39 +00:00
Bind ( Enterprise )
2018-07-11 00:00:46 +00:00
Bind ( MSX )
Bind ( Oric )
2023-11-15 19:27:04 +00:00
Bind ( PCCompatible )
2019-06-02 17:39:25 +00:00
BindD ( Sega : : MasterSystem , MasterSystem )
2021-03-18 02:40:29 +00:00
BindD ( Sinclair : : ZX8081 , ZX8081 )
2021-03-18 03:38:55 +00:00
BindD ( Sinclair : : ZXSpectrum , ZXSpectrum )
2018-01-25 23:28:19 +00:00
2018-07-11 00:00:46 +00:00
default :
error = Machine : : Error : : UnknownMachine ;
2018-01-25 23:28:19 +00:00
return nullptr ;
}
2018-07-11 00:00:46 +00:00
# undef Bind
} catch ( ROMMachine : : Error construction_error ) {
switch ( construction_error ) {
case ROMMachine : : Error : : MissingROMs :
error = Machine : : Error : : MissingROM ;
break ;
default :
error = Machine : : Error : : UnknownError ;
break ;
}
2018-01-25 23:28:19 +00:00
}
return machine ;
2017-11-06 01:12:01 +00:00
}
2024-01-13 03:03:19 +00:00
std : : unique_ptr < Machine : : DynamicMachine > Machine : : MachineForTargets ( const Analyser : : Static : : TargetList & targets , const ROMMachine : : ROMFetcher & rom_fetcher , Error & error ) {
2018-01-29 03:22:21 +00:00
// Zero targets implies no machine.
if ( targets . empty ( ) ) {
error = Error : : NoTargets ;
return nullptr ;
}
// If there's more than one target, get all the machines and combine them into a multimachine.
if ( targets . size ( ) > 1 ) {
std : : vector < std : : unique_ptr < Machine : : DynamicMachine > > machines ;
for ( const auto & target : targets ) {
2018-03-09 20:36:11 +00:00
machines . emplace_back ( MachineForTarget ( target . get ( ) , rom_fetcher , error ) ) ;
2018-02-09 01:33:57 +00:00
// Exit early if any errors have occurred.
if ( error ! = Error : : None ) {
return nullptr ;
}
2018-01-29 03:22:21 +00:00
}
2018-03-07 00:08:02 +00:00
// If a multimachine would just instantly collapse the list to a single machine, do
// so without the ongoing baggage of a multimachine.
if ( Analyser : : Dynamic : : MultiMachine : : would_collapse ( machines ) ) {
2024-01-13 03:03:19 +00:00
return std : : move ( machines . front ( ) ) ;
2018-03-07 00:08:02 +00:00
} else {
2024-01-13 03:03:19 +00:00
return std : : make_unique < Analyser : : Dynamic : : MultiMachine > ( std : : move ( machines ) ) ;
2018-03-07 00:08:02 +00:00
}
2018-01-29 03:22:21 +00:00
}
// There's definitely exactly one target.
2018-03-09 20:36:11 +00:00
return MachineForTarget ( targets . front ( ) . get ( ) , rom_fetcher , error ) ;
2018-01-29 03:22:21 +00:00
}
2018-01-25 02:48:44 +00:00
std : : string Machine : : ShortNameForTargetMachine ( const Analyser : : Machine machine ) {
2017-11-21 02:55:32 +00:00
switch ( machine ) {
2021-07-17 00:30:48 +00:00
case Analyser : : Machine : : Amiga : return " Amiga " ;
2018-01-25 02:48:44 +00:00
case Analyser : : Machine : : AmstradCPC : return " AmstradCPC " ;
2018-04-14 23:46:15 +00:00
case Analyser : : Machine : : AppleII : return " AppleII " ;
2020-10-21 02:18:11 +00:00
case Analyser : : Machine : : AppleIIgs : return " AppleIIgs " ;
2024-03-04 15:19:06 +00:00
case Analyser : : Machine : : Archimedes : return " Archimedes " ;
2018-01-25 02:48:44 +00:00
case Analyser : : Machine : : Atari2600 : return " Atari2600 " ;
2019-10-04 00:17:26 +00:00
case Analyser : : Machine : : AtariST : return " AtariST " ;
2018-02-24 03:47:15 +00:00
case Analyser : : Machine : : ColecoVision : return " ColecoVision " ;
2018-01-25 02:48:44 +00:00
case Analyser : : Machine : : Electron : return " Electron " ;
2021-06-15 00:55:39 +00:00
case Analyser : : Machine : : Enterprise : return " Enterprise " ;
2019-05-04 02:16:07 +00:00
case Analyser : : Machine : : Macintosh : return " Macintosh " ;
2019-10-01 01:10:30 +00:00
case Analyser : : Machine : : MasterSystem : return " MasterSystem " ;
2018-01-25 02:48:44 +00:00
case Analyser : : Machine : : MSX : return " MSX " ;
case Analyser : : Machine : : Oric : return " Oric " ;
2023-11-15 19:27:04 +00:00
case Analyser : : Machine : : PCCompatible : return " PCCompatible " ;
2018-01-25 02:48:44 +00:00
case Analyser : : Machine : : Vic20 : return " Vic20 " ;
case Analyser : : Machine : : ZX8081 : return " ZX8081 " ;
2021-03-20 02:17:20 +00:00
case Analyser : : Machine : : ZXSpectrum : return " ZXSpectrum " ;
2017-11-12 21:41:09 +00:00
default : return " " ;
2017-11-05 17:49:28 +00:00
}
}
2017-11-21 02:55:32 +00:00
2018-01-25 02:48:44 +00:00
std : : string Machine : : LongNameForTargetMachine ( Analyser : : Machine machine ) {
2017-11-21 02:55:32 +00:00
switch ( machine ) {
2021-07-17 00:30:48 +00:00
case Analyser : : Machine : : Amiga : return " Amiga " ;
2018-01-25 02:48:44 +00:00
case Analyser : : Machine : : AmstradCPC : return " Amstrad CPC " ;
2018-04-14 23:46:15 +00:00
case Analyser : : Machine : : AppleII : return " Apple II " ;
2020-10-21 02:18:11 +00:00
case Analyser : : Machine : : AppleIIgs : return " Apple IIgs " ;
2024-03-04 15:19:06 +00:00
case Analyser : : Machine : : Archimedes : return " Acorn Archimedes " ;
2018-01-25 02:48:44 +00:00
case Analyser : : Machine : : Atari2600 : return " Atari 2600 " ;
2019-10-04 00:17:26 +00:00
case Analyser : : Machine : : AtariST : return " Atari ST " ;
2018-02-24 03:47:15 +00:00
case Analyser : : Machine : : ColecoVision : return " ColecoVision " ;
2018-01-25 02:48:44 +00:00
case Analyser : : Machine : : Electron : return " Acorn Electron " ;
2021-06-15 00:55:39 +00:00
case Analyser : : Machine : : Enterprise : return " Enterprise " ;
2019-05-04 02:16:07 +00:00
case Analyser : : Machine : : Macintosh : return " Apple Macintosh " ;
2019-10-01 01:10:30 +00:00
case Analyser : : Machine : : MasterSystem : return " Sega Master System " ;
2018-01-25 02:48:44 +00:00
case Analyser : : Machine : : MSX : return " MSX " ;
case Analyser : : Machine : : Oric : return " Oric " ;
2023-11-15 19:27:04 +00:00
case Analyser : : Machine : : PCCompatible : return " PC Compatible " ;
2018-01-25 02:48:44 +00:00
case Analyser : : Machine : : Vic20 : return " Vic 20 " ;
case Analyser : : Machine : : ZX8081 : return " ZX80/81 " ;
2021-03-20 02:17:20 +00:00
case Analyser : : Machine : : ZXSpectrum : return " ZX Spectrum " ;
2017-11-21 02:55:32 +00:00
default : return " " ;
}
}
2020-03-19 03:11:25 +00:00
std : : vector < std : : string > Machine : : AllMachines ( Type type , bool long_names ) {
2020-03-15 04:15:19 +00:00
std : : vector < std : : string > result ;
# define AddName(x) result.push_back(long_names ? LongNameForTargetMachine(Analyser::Machine::x) : ShortNameForTargetMachine(Analyser::Machine::x))
2020-03-19 03:11:25 +00:00
2020-03-19 23:41:50 +00:00
if ( type = = Type : : Any | | type = = Type : : RequiresMedia ) {
AddName ( Atari2600 ) ;
AddName ( ColecoVision ) ;
AddName ( MasterSystem ) ;
}
2020-03-19 03:11:25 +00:00
if ( type = = Type : : Any | | type = = Type : : DoesntRequireMedia ) {
2021-07-17 00:30:48 +00:00
AddName ( Amiga ) ;
2020-03-19 03:11:25 +00:00
AddName ( AmstradCPC ) ;
AddName ( AppleII ) ;
2020-10-21 02:18:11 +00:00
AddName ( AppleIIgs ) ;
2024-03-04 15:19:06 +00:00
AddName ( Archimedes ) ;
2020-03-19 03:11:25 +00:00
AddName ( AtariST ) ;
AddName ( Electron ) ;
2021-06-15 00:55:39 +00:00
AddName ( Enterprise ) ;
2020-03-19 03:11:25 +00:00
AddName ( Macintosh ) ;
AddName ( MSX ) ;
AddName ( Oric ) ;
2023-12-21 18:01:41 +00:00
AddName ( PCCompatible ) ;
2020-03-19 03:11:25 +00:00
AddName ( Vic20 ) ;
AddName ( ZX8081 ) ;
2021-04-18 03:06:37 +00:00
AddName ( ZXSpectrum ) ;
2020-03-19 03:11:25 +00:00
}
2020-03-15 04:15:19 +00:00
# undef AddName
return result ;
}
2020-03-16 03:48:53 +00:00
std : : map < std : : string , std : : unique_ptr < Reflection : : Struct > > Machine : : AllOptionsByMachineName ( ) {
std : : map < std : : string , std : : unique_ptr < Reflection : : Struct > > options ;
2020-03-17 03:25:05 +00:00
# define Emplace(machine, class) \
options . emplace ( std : : make_pair ( LongNameForTargetMachine ( Analyser : : Machine : : machine ) , std : : make_unique < class : : Options > ( Configurable : : OptionsType : : UserFriendly ) ) ) ;
Emplace ( AmstradCPC , AmstradCPC : : Machine ) ;
2020-03-18 01:53:26 +00:00
Emplace ( AppleII , Apple : : II : : Machine ) ;
2020-03-18 03:52:55 +00:00
Emplace ( AtariST , Atari : : ST : : Machine ) ;
2020-03-18 04:06:52 +00:00
Emplace ( ColecoVision , Coleco : : Vision : : Machine ) ;
2020-03-18 02:06:20 +00:00
Emplace ( Electron , Electron : : Machine ) ;
2021-07-03 01:51:48 +00:00
Emplace ( Enterprise , Enterprise : : Machine ) ;
2020-03-19 01:50:02 +00:00
Emplace ( Macintosh , Apple : : Macintosh : : Machine ) ;
2020-03-18 22:26:22 +00:00
Emplace ( MasterSystem , Sega : : MasterSystem : : Machine ) ;
Emplace ( MSX , MSX : : Machine ) ;
2020-03-18 22:31:31 +00:00
Emplace ( Oric , Oric : : Machine ) ;
2023-12-06 18:55:41 +00:00
Emplace ( PCCompatible , PCCompatible : : Machine ) ;
2020-03-19 00:23:55 +00:00
Emplace ( Vic20 , Commodore : : Vic20 : : Machine ) ;
2021-03-18 02:40:29 +00:00
Emplace ( ZX8081 , Sinclair : : ZX8081 : : Machine ) ;
2021-03-20 02:17:20 +00:00
Emplace ( ZXSpectrum , Sinclair : : ZXSpectrum : : Machine ) ;
2020-03-17 03:25:05 +00:00
# undef Emplace
2017-11-21 02:55:32 +00:00
return options ;
}
2020-03-13 00:56:02 +00:00
2020-03-15 16:54:55 +00:00
std : : map < std : : string , std : : unique_ptr < Analyser : : Static : : Target > > Machine : : TargetsByMachineName ( bool meaningful_without_media_only ) {
std : : map < std : : string , std : : unique_ptr < Analyser : : Static : : Target > > options ;
2020-03-13 00:56:02 +00:00
2020-03-15 04:15:19 +00:00
# define AddMapped(Name, TargetNamespace) \
options . emplace ( std : : make_pair ( LongNameForTargetMachine ( Analyser : : Machine : : Name ) , new Analyser : : Static : : TargetNamespace : : Target ) ) ;
# define Add(Name) AddMapped(Name, Name)
2020-03-13 00:56:02 +00:00
2021-07-17 00:30:48 +00:00
Add ( Amiga ) ;
2020-03-13 00:56:02 +00:00
Add ( AmstradCPC ) ;
Add ( AppleII ) ;
2020-10-21 02:18:11 +00:00
Add ( AppleIIgs ) ;
2024-03-04 15:19:06 +00:00
options . emplace ( std : : make_pair ( LongNameForTargetMachine ( Analyser : : Machine : : Archimedes ) , new Analyser : : Static : : Target ( Analyser : : Machine : : Archimedes ) ) ) ;
2020-03-15 04:15:19 +00:00
Add ( AtariST ) ;
AddMapped ( Electron , Acorn ) ;
2021-06-15 00:55:39 +00:00
Add ( Enterprise ) ;
2020-03-15 04:15:19 +00:00
Add ( Macintosh ) ;
2020-03-13 00:56:02 +00:00
Add ( MSX ) ;
Add ( Oric ) ;
2023-12-21 18:01:41 +00:00
Add ( PCCompatible ) ;
2020-03-15 04:15:19 +00:00
AddMapped ( Vic20 , Commodore ) ;
2020-03-13 00:56:02 +00:00
Add ( ZX8081 ) ;
2021-03-20 02:17:20 +00:00
Add ( ZXSpectrum ) ;
2020-03-13 00:56:02 +00:00
2020-03-15 16:54:55 +00:00
if ( ! meaningful_without_media_only ) {
Add ( Atari2600 ) ;
options . emplace ( std : : make_pair ( LongNameForTargetMachine ( Analyser : : Machine : : ColecoVision ) , new Analyser : : Static : : Target ( Analyser : : Machine : : ColecoVision ) ) ) ;
AddMapped ( MasterSystem , Sega ) ;
}
2020-03-15 04:15:19 +00:00
# undef Add
2021-03-20 02:17:20 +00:00
# undef AddMapped
2020-03-15 04:15:19 +00:00
2020-03-13 00:56:02 +00:00
return options ;
}