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] = 1000000000 * params
.framemagic
[0] / params
.framemagic
[1];
84 magic
[3] = 1000000000 * 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() throw()
387 all_cores().erase(this);
390 void core_core::initialize_new_cores()
392 for(auto i
: uninitialized_cores_set())
393 i
->install_handler();
394 uninitialized_cores_set().clear();
397 std::string
core_core::get_core_shortname()
399 return c_get_core_shortname();
402 bool core_core::set_region(core_region
& region
)
404 return c_set_region(region
);
407 std::pair
<uint32_t, uint32_t> core_core::get_video_rate()
409 return c_video_rate();
412 std::pair
<uint32_t, uint32_t> core_core::get_audio_rate()
414 return c_audio_rate();
417 std::string
core_core::get_core_identifier()
419 return c_core_identifier();
422 std::set
<core_core
*> core_core::all_cores()
424 return all_cores_set();
427 void core_core::install_all_handlers()
429 install_handlers_automatically
= true;
430 for(auto i
: all_cores_set())
431 i
->install_handler();
434 void core_core::uninstall_all_handlers()
436 install_handlers_automatically
= false;
437 for(auto i
: all_cores_set())
438 i
->uninstall_handler();
441 std::map
<std::string
, std::vector
<char>> core_core::save_sram() throw(std::bad_alloc
)
443 return c_save_sram();
446 void core_core::load_sram(std::map
<std::string
, std::vector
<char>>& sram
) throw(std::bad_alloc
)
451 void core_core::serialize(std::vector
<char>& out
)
456 void core_core::unserialize(const char* in
, size_t insize
)
458 c_unserialize(in
, insize
);
461 core_region
& core_core::get_region()
463 return c_get_region();
466 void core_core::power()
471 void core_core::unload_cartridge()
473 c_unload_cartridge();
476 std::pair
<uint32_t, uint32_t> core_core::get_scale_factors(uint32_t width
, uint32_t height
)
478 return c_get_scale_factors(width
, height
);
481 void core_core::install_handler()
486 void core_core::uninstall_handler()
488 c_uninstall_handler();
491 void core_core::emulate()
496 void core_core::runtosave()
501 bool core_core::get_pflag()
503 return c_get_pflag();
506 void core_core::set_pflag(bool pflag
)
508 return c_set_pflag(pflag
);
511 framebuffer::raw
& core_core::draw_cover()
513 return c_draw_cover();
516 void core_core::pre_emulate_frame(controller_frame
& cf
)
518 c_pre_emulate_frame(cf
);
521 void core_core::execute_action(unsigned id
, const std::vector
<interface_action_paramval
>& p
)
523 return c_execute_action(id
, p
);
526 const struct interface_device_reg
* core_core::get_registers()
528 return c_get_registers();
531 unsigned core_core::action_flags(unsigned id
)
533 return c_action_flags(id
);
536 std::set
<const interface_action
*> core_core::get_actions()
538 umutex_class
h(actions_lock
);
539 std::set
<const interface_action
*> r
;
540 for(auto& i
: actions
)
545 int core_core::reset_action(bool hard
)
547 return c_reset_action(hard
);
550 void core_core::set_debug_flags(uint64_t addr
, unsigned flags_set
, unsigned flags_clear
)
552 return c_set_debug_flags(addr
, flags_set
, flags_clear
);
555 void core_core::set_cheat(uint64_t addr
, uint64_t value
, bool set
)
557 return c_set_cheat(addr
, value
, set
);
560 std::vector
<std::string
> core_core::get_trace_cpus()
562 return c_get_trace_cpus();
565 emucore_callbacks::~emucore_callbacks() throw()
569 core_romimage_info_collection::core_romimage_info_collection(std::initializer_list
<core_romimage_info_params
> idata
)
572 data
.push_back(core_romimage_info(i
));
575 std::set
<core_sysregion
*> core_sysregion::find_matching(const std::string
& name
)
577 std::set
<core_sysregion
*> ret
;
578 auto u
= sysregions().upper_bound(name
);
579 for(auto i
= sysregions().lower_bound(name
); i
!= u
; ++i
)
580 ret
.insert(i
->second
);
584 void register_sysregion_mapping(std::string from
, std::string to
)
586 sysreg_mapping()[from
] = to
;
589 std::string
lookup_sysregion_mapping(std::string from
)
591 if(sysreg_mapping().count(from
))
592 return sysreg_mapping()[from
];
597 struct emucore_callbacks
* ecore_callbacks
;
599 bool new_core_flag
= false;
600 uint32_t magic_flags
= 0;