1 #include "core/misc.hpp"
2 #include "interface/romtype.hpp"
3 #include "interface/callbacks.hpp"
4 #include "library/minmax.hpp"
5 #include "library/string.hpp"
6 #include "library/register-queue.hpp"
18 bool install_handlers_automatically
;
20 std::map
<std::string
, std::string
>& sysreg_mapping()
22 static std::map
<std::string
, std::string
> x
;
26 std::set
<core_core
*>& all_cores_set()
28 static std::set
<core_core
*> x
;
32 std::set
<core_core
*>& uninitialized_cores_set()
34 static std::set
<core_core
*> x
;
38 std::multimap
<std::string
, core_sysregion
*>& sysregions()
40 static std::multimap
<std::string
, core_sysregion
*> x
;
44 std::set
<core_type
*>& types()
46 static std::set
<core_type
*> x
;
50 bool compare_coretype(core_type
* a
, core_type
* b
)
52 return (a
->get_id() < b
->get_id());
55 bool compare_regions(core_region
* a
, core_region
* b
)
57 return (a
->get_handle() < b
->get_handle());
60 unsigned default_headersize(size_t imagesize
)
66 bool interface_action::is_toggle() const
69 if(!strcmp(i
.model
, "toggle"))
74 core_region::core_region(const core_region_params
& params
)
79 handle
= params
.handle
;
80 priority
= params
.priority
;
81 magic
[0] = params
.framemagic
[0];
82 magic
[1] = params
.framemagic
[1];
83 magic
[2] = 1000 * params
.framemagic
[0] / params
.framemagic
[1];
84 magic
[3] = 1000 * params
.framemagic
[0] % params
.framemagic
[1];
85 compatible
= params
.compatible_runs
;
89 bool core_region::compatible_with(core_region
& run
)
91 for(auto i
: compatible
)
97 bool core_region::is_multi()
102 const std::string
& core_region::get_iname()
107 const std::string
& core_region::get_hname()
112 unsigned core_region::get_priority()
117 unsigned core_region:: get_handle()
122 void core_region::fill_framerate_magic(uint64_t* _magic
)
124 for(size_t i
= 0; i
< 4; i
++)
125 _magic
[i
] = magic
[i
];
128 double core_region::approx_framerate()
130 return (double)magic
[1] / magic
[0];
133 core_romimage_info::core_romimage_info(const core_romimage_info_params
& params
)
135 iname
= params
.iname
;
136 hname
= params
.hname
;
137 mandatory
= params
.mandatory
;
138 pass_mode
= params
.pass_mode
;
139 headersize
= params
.headersize
;
140 if(params
.extensions
) {
141 std::string tmp
= params
.extensions
;
142 for(auto& ext
: token_iterator_foreach(tmp
, {";"}))
143 extensions
.insert(ext
);
147 size_t core_romimage_info::get_headnersize(size_t imagesize
)
149 if(headersize
&& imagesize
% (2 * headersize
) == headersize
)
154 core_type::core_type(const core_type_params
& params
)
155 : settings(params
.settings
)
157 iname
= params
.iname
;
158 hname
= params
.hname
;
159 sysname
= params
.sysname
;
163 biosname
= params
.bios
;
164 for(auto i
: params
.regions
)
165 regions
.push_back(i
);
166 imageinfo
= params
.images
.get();
167 types().insert(this);
170 core_type::~core_type() throw()
175 unsigned core_type::get_id()
180 const std::string
& core_type::get_iname()
185 const std::string
& core_type::get_hname()
190 unsigned core_type::get_image_count()
192 return imageinfo
.size();
195 core_setting_group
& core_type::get_settings()
200 core_romimage_info
core_type::get_image_info(unsigned index
)
202 if(index
>= imageinfo
.size())
203 throw std::runtime_error("Requested invalid image index");
204 return imageinfo
[index
];
207 std::list
<core_type
*> core_type::get_core_types()
209 std::list
<core_type
*> ret
;
210 for(auto i
: types())
212 ret
.sort(compare_coretype
);
216 std::list
<core_region
*> core_type::get_regions()
218 std::list
<core_region
*> ret
= regions
;
219 ret
.sort(compare_regions
);
223 core_region
& core_type::get_preferred_region()
225 core_region
* p
= NULL
;
227 for(auto i
: regions
) {
228 unsigned pri
= i
->get_priority();
230 cutoff
= max(pri
+ 1, pri
);
237 bool core_type::load(core_romimage
* images
, std::map
<std::string
, std::string
>& settings
, uint64_t rtc_sec
,
240 return (t_load_rom(images
, settings
, rtc_sec
, rtc_subsec
) >= 0);
243 core_sysregion
& core_type::combine_region(core_region
& reg
)
245 for(auto i
: sysregions())
246 if(&(i
.second
->get_type()) == this && &(i
.second
->get_region()) == ®
)
248 throw std::runtime_error("Invalid region for system type");
251 std::list
<std::string
> core_type::get_extensions()
253 static std::list
<std::string
> empty
;
254 unsigned base
= (biosname
!= "") ? 1 : 0;
255 if(imageinfo
.size() <= base
)
257 auto s
= imageinfo
[base
].extensions
;
258 std::list
<std::string
> ret
;
264 std::string
core_type::get_biosname()
269 bool core_type::is_known_extension(const std::string
& ext
)
271 std::string _ext
= ext
;
272 std::transform(_ext
.begin(), _ext
.end(), _ext
.begin(), ::tolower
);
273 for(auto i
: get_extensions())
279 controller_set
core_type::controllerconfig(std::map
<std::string
, std::string
>& settings
)
281 return t_controllerconfig(settings
);
284 std::pair
<uint64_t, uint64_t> core_core::get_bus_map()
286 return c_get_bus_map();
289 double core_core::get_PAR()
294 std::list
<core_vma_info
> core_core::vma_list()
299 std::set
<std::string
> core_core::srams()
304 bool core_core::isnull()
309 std::pair
<unsigned, unsigned> core_core::lightgun_scale()
311 return c_lightgun_scale();
314 std::pair
<unsigned, unsigned> core_core::c_lightgun_scale()
316 return std::make_pair(0, 0);
319 void core_core::debug_reset()
321 return c_debug_reset();
324 bool core_core::c_isnull()
329 core_sysregion::core_sysregion(const std::string
& _name
, core_type
& _type
, core_region
& _region
)
330 : name(_name
), type(_type
), region(_region
)
332 sysregions().insert(std::make_pair(_name
, this));
335 core_sysregion::~core_sysregion() throw()
337 for(auto i
= sysregions().begin(); i
!= sysregions().end(); i
++)
338 if(i
->second
== this) {
339 sysregions().erase(i
);
344 core_sysregion
& core_type::lookup_sysregion(const std::string
& sysreg
)
346 for(auto i
: sysregions())
347 if(i
.first
== sysreg
&& &i
.second
->get_type() == this)
349 throw std::runtime_error("Bad system-region type");
352 const std::string
& core_sysregion::get_name()
357 core_region
& core_sysregion::get_region()
362 core_type
& core_sysregion::get_type()
367 void core_sysregion::fill_framerate_magic(uint64_t* magic
)
369 region
.fill_framerate_magic(magic
);
372 core_core::core_core(std::initializer_list
<port_type
*> ports
, std::initializer_list
<interface_action
> x_actions
)
375 port_types
.push_back(i
);
376 for(auto i
: x_actions
)
377 actions
[i
._symbol
] = i
;
380 uninitialized_cores_set().insert(this);
381 all_cores_set().insert(this);
382 new_core_flag
= true;
385 core_core::core_core(std::vector
<port_type
*> ports
, std::vector
<interface_action
> x_actions
)
388 port_types
.push_back(i
);
389 for(auto i
: x_actions
)
390 actions
[i
._symbol
] = i
;
393 uninitialized_cores_set().insert(this);
394 all_cores_set().insert(this);
395 new_core_flag
= true;
398 core_core::~core_core() throw()
400 all_cores().erase(this);
403 void core_core::initialize_new_cores()
405 for(auto i
: uninitialized_cores_set())
406 i
->install_handler();
407 uninitialized_cores_set().clear();
410 std::string
core_core::get_core_shortname()
412 return c_get_core_shortname();
415 bool core_core::set_region(core_region
& region
)
417 return c_set_region(region
);
420 std::pair
<uint32_t, uint32_t> core_core::get_video_rate()
422 return c_video_rate();
425 std::pair
<uint32_t, uint32_t> core_core::get_audio_rate()
427 return c_audio_rate();
430 std::string
core_core::get_core_identifier()
432 return c_core_identifier();
435 std::set
<core_core
*> core_core::all_cores()
437 return all_cores_set();
440 void core_core::install_all_handlers()
442 install_handlers_automatically
= true;
443 for(auto i
: all_cores_set())
444 i
->install_handler();
447 void core_core::uninstall_all_handlers()
449 install_handlers_automatically
= false;
450 for(auto i
: all_cores_set())
451 i
->uninstall_handler();
454 std::map
<std::string
, std::vector
<char>> core_core::save_sram() throw(std::bad_alloc
)
456 return c_save_sram();
459 void core_core::load_sram(std::map
<std::string
, std::vector
<char>>& sram
) throw(std::bad_alloc
)
464 void core_core::serialize(std::vector
<char>& out
)
469 void core_core::unserialize(const char* in
, size_t insize
)
471 c_unserialize(in
, insize
);
474 core_region
& core_core::get_region()
476 return c_get_region();
479 void core_core::power()
484 void core_core::unload_cartridge()
486 c_unload_cartridge();
489 std::pair
<uint32_t, uint32_t> core_core::get_scale_factors(uint32_t width
, uint32_t height
)
491 return c_get_scale_factors(width
, height
);
494 void core_core::install_handler()
499 void core_core::uninstall_handler()
501 c_uninstall_handler();
504 void core_core::emulate()
509 void core_core::runtosave()
514 bool core_core::get_pflag()
516 return c_get_pflag();
519 void core_core::set_pflag(bool pflag
)
521 return c_set_pflag(pflag
);
524 framebuffer::raw
& core_core::draw_cover()
526 return c_draw_cover();
529 void core_core::pre_emulate_frame(controller_frame
& cf
)
531 c_pre_emulate_frame(cf
);
534 void core_core::execute_action(unsigned id
, const std::vector
<interface_action_paramval
>& p
)
536 return c_execute_action(id
, p
);
539 const struct interface_device_reg
* core_core::get_registers()
541 return c_get_registers();
544 unsigned core_core::action_flags(unsigned id
)
546 return c_action_flags(id
);
549 std::set
<const interface_action
*> core_core::get_actions()
551 threads::alock
h(actions_lock
);
552 std::set
<const interface_action
*> r
;
553 for(auto& i
: actions
)
558 int core_core::reset_action(bool hard
)
560 return c_reset_action(hard
);
563 void core_core::set_debug_flags(uint64_t addr
, unsigned flags_set
, unsigned flags_clear
)
565 return c_set_debug_flags(addr
, flags_set
, flags_clear
);
568 void core_core::set_cheat(uint64_t addr
, uint64_t value
, bool set
)
570 return c_set_cheat(addr
, value
, set
);
573 std::vector
<std::string
> core_core::get_trace_cpus()
575 return c_get_trace_cpus();
578 emucore_callbacks::~emucore_callbacks() throw()
582 core_romimage_info_collection::core_romimage_info_collection()
586 core_romimage_info_collection::core_romimage_info_collection(std::initializer_list
<core_romimage_info_params
> idata
)
589 data
.push_back(core_romimage_info(i
));
592 core_romimage_info_collection::core_romimage_info_collection(std::vector
<core_romimage_info_params
> idata
)
595 data
.push_back(core_romimage_info(i
));
598 std::set
<core_sysregion
*> core_sysregion::find_matching(const std::string
& name
)
600 std::set
<core_sysregion
*> ret
;
601 auto u
= sysregions().upper_bound(name
);
602 for(auto i
= sysregions().lower_bound(name
); i
!= u
; ++i
)
603 ret
.insert(i
->second
);
607 void register_sysregion_mapping(std::string from
, std::string to
)
609 sysreg_mapping()[from
] = to
;
612 std::string
lookup_sysregion_mapping(std::string from
)
614 if(sysreg_mapping().count(from
))
615 return sysreg_mapping()[from
];
620 struct emucore_callbacks
* ecore_callbacks
;
622 bool new_core_flag
= false;
623 uint32_t magic_flags
= 0;