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"
15 thread_local
const loadlib::module
* module_loading
;
19 void mark_against_loading(const void* obj
)
21 auto i
= module_loading
;
23 auto j
= loadlib::library::loading();
27 bool install_handlers_automatically
;
29 std::map
<std::string
, std::string
>& sysreg_mapping()
31 static std::map
<std::string
, std::string
> x
;
35 std::set
<core_core
*>& all_cores_set()
37 static std::set
<core_core
*> x
;
41 std::set
<core_core
*>& uninitialized_cores_set()
43 static std::set
<core_core
*> x
;
47 std::multimap
<std::string
, core_sysregion
*>& sysregions()
49 static std::multimap
<std::string
, core_sysregion
*> x
;
53 std::set
<core_type
*>& types()
55 static std::set
<core_type
*> x
;
59 bool compare_coretype(core_type
* a
, core_type
* b
)
61 return (a
->get_id() < b
->get_id());
64 bool compare_regions(core_region
* a
, core_region
* b
)
66 return (a
->get_handle() < b
->get_handle());
70 bool interface_action::is_toggle() const
73 if(!strcmp(i
.model
, "toggle"))
78 core_region::core_region(const core_region_params
& params
)
83 handle
= params
.handle
;
84 priority
= params
.priority
;
85 magic
[0] = params
.framemagic
[0];
86 magic
[1] = params
.framemagic
[1];
87 magic
[2] = 1000 * params
.framemagic
[0] / params
.framemagic
[1];
88 magic
[3] = 1000 * params
.framemagic
[0] % params
.framemagic
[1];
89 compatible
= params
.compatible_runs
;
93 bool core_region::compatible_with(core_region
& run
)
95 for(auto i
: compatible
)
101 bool core_region::is_multi()
106 const std::string
& core_region::get_iname()
111 const std::string
& core_region::get_hname()
116 unsigned core_region::get_priority()
121 unsigned core_region:: get_handle()
126 void core_region::fill_framerate_magic(uint64_t* _magic
)
128 for(size_t i
= 0; i
< 4; i
++)
129 _magic
[i
] = magic
[i
];
132 double core_region::approx_framerate()
134 return (double)magic
[1] / magic
[0];
137 core_romimage_info::core_romimage_info(const core_romimage_info_params
& params
)
139 iname
= params
.iname
;
140 hname
= params
.hname
;
141 mandatory
= params
.mandatory
;
142 pass_mode
= params
.pass_mode
;
143 headersize
= params
.headersize
;
144 if(params
.extensions
) {
145 std::string tmp
= params
.extensions
;
146 for(auto& ext
: token_iterator
<char>::foreach(tmp
, {";"}))
147 extensions
.insert(ext
);
151 size_t core_romimage_info::get_headnersize(size_t imagesize
)
153 if(headersize
&& imagesize
% (2 * headersize
) == headersize
)
158 core_type::core_type(const core_type_params
& params
)
159 : settings(params
.settings
)
161 iname
= params
.iname
;
162 hname
= params
.hname
;
163 sysname
= params
.sysname
;
167 biosname
= params
.bios
;
168 for(auto i
: params
.regions
)
169 regions
.push_back(i
);
170 imageinfo
= params
.images
.get();
171 types().insert(this);
174 core_type::~core_type() throw()
179 unsigned core_type::get_id() const
184 const std::string
& core_type::get_iname() const
189 const std::string
& core_type::get_hname() const
194 unsigned core_type::get_image_count() const
196 return imageinfo
.size();
199 core_setting_group
& core_type::get_settings()
204 core_romimage_info
core_type::get_image_info(unsigned index
) const
206 if(index
>= imageinfo
.size())
207 throw std::runtime_error("Requested invalid image index");
208 return imageinfo
[index
];
211 std::list
<core_type
*> core_type::get_core_types()
213 std::list
<core_type
*> ret
;
214 for(auto i
: types())
216 ret
.sort(compare_coretype
);
220 std::list
<core_region
*> core_type::get_regions() const
222 std::list
<core_region
*> ret
= regions
;
223 ret
.sort(compare_regions
);
227 core_region
& core_type::get_preferred_region() const
229 core_region
* p
= NULL
;
231 for(auto i
: regions
) {
232 unsigned pri
= i
->get_priority();
234 cutoff
= max(pri
+ 1, pri
);
241 bool core_type::load(core_romimage
* images
, std::map
<std::string
, std::string
>& settings
, uint64_t rtc_sec
,
244 return (t_load_rom(images
, settings
, rtc_sec
, rtc_subsec
) >= 0);
247 core_sysregion
& core_type::combine_region(core_region
& reg
) const
249 for(auto i
: sysregions())
250 if(&(i
.second
->get_type()) == this && &(i
.second
->get_region()) == ®
)
252 throw std::runtime_error("Invalid region for system type");
255 std::list
<std::string
> core_type::get_extensions() const
257 static std::list
<std::string
> empty
;
258 unsigned base
= (biosname
!= "") ? 1 : 0;
259 if(imageinfo
.size() <= base
)
261 auto s
= imageinfo
[base
].extensions
;
262 std::list
<std::string
> ret
;
268 std::string
core_type::get_biosname() const
273 bool core_type::is_known_extension(const std::string
& ext
) const
275 std::string _ext
= ext
;
276 std::transform(_ext
.begin(), _ext
.end(), _ext
.begin(), ::tolower
);
277 for(auto i
: get_extensions())
283 controller_set
core_type::controllerconfig(std::map
<std::string
, std::string
>& settings
)
285 return t_controllerconfig(settings
);
288 std::pair
<uint64_t, uint64_t> core_core::get_bus_map()
290 return c_get_bus_map();
293 double core_core::get_PAR()
298 std::list
<core_vma_info
> core_core::vma_list()
303 std::set
<std::string
> core_core::srams()
308 bool core_core::isnull() const
313 std::pair
<unsigned, unsigned> core_core::lightgun_scale()
315 return c_lightgun_scale();
318 std::pair
<unsigned, unsigned> core_core::c_lightgun_scale()
320 return std::make_pair(0, 0);
323 void core_core::debug_reset()
325 return c_debug_reset();
328 bool core_core::c_isnull() const
333 core_sysregion::core_sysregion(const std::string
& _name
, core_type
& _type
, core_region
& _region
)
334 : name(_name
), type(_type
), region(_region
)
336 sysregions().insert(std::make_pair(_name
, this));
339 core_sysregion::~core_sysregion() throw()
341 for(auto i
= sysregions().begin(); i
!= sysregions().end(); i
++)
342 if(i
->second
== this) {
343 sysregions().erase(i
);
348 core_sysregion
& core_type::lookup_sysregion(const std::string
& sysreg
) const
350 for(auto i
: sysregions())
351 if(i
.first
== sysreg
&& &i
.second
->get_type() == this)
353 throw std::runtime_error("Bad system-region type");
356 const std::string
& core_sysregion::get_name() const
361 core_region
& core_sysregion::get_region()
366 core_type
& core_sysregion::get_type()
371 void core_sysregion::fill_framerate_magic(uint64_t* magic
)
373 region
.fill_framerate_magic(magic
);
376 core_core::core_core(std::initializer_list
<portctrl::type
*> ports
, std::initializer_list
<interface_action
> x_actions
)
379 port_types
.push_back(i
);
380 for(auto i
: x_actions
)
381 actions
[i
._symbol
] = i
;
384 uninitialized_cores_set().insert(this);
385 all_cores_set().insert(this);
386 new_core_flag
= true;
387 mark_against_loading(this);
390 core_core::core_core(std::vector
<portctrl::type
*> ports
, std::vector
<interface_action
> x_actions
)
393 port_types
.push_back(i
);
394 for(auto i
: x_actions
)
395 actions
[i
._symbol
] = i
;
398 uninitialized_cores_set().insert(this);
399 all_cores_set().insert(this);
400 new_core_flag
= true;
401 mark_against_loading(this);
404 core_core::~core_core() throw()
406 all_cores().erase(this);
407 all_cores_set().erase(this);
410 void core_core::initialize_new_cores()
412 for(auto i
: uninitialized_cores_set())
413 i
->install_handler();
414 uninitialized_cores_set().clear();
417 std::string
core_core::get_core_shortname() const
419 return c_get_core_shortname();
422 bool core_core::set_region(core_region
& region
)
424 return c_set_region(region
);
427 std::pair
<uint32_t, uint32_t> core_core::get_video_rate()
429 return c_video_rate();
432 std::pair
<uint32_t, uint32_t> core_core::get_audio_rate()
434 return c_audio_rate();
437 std::string
core_core::get_core_identifier() const
439 return c_core_identifier();
442 std::set
<core_core
*> core_core::all_cores()
444 return all_cores_set();
447 void core_core::install_all_handlers()
449 install_handlers_automatically
= true;
450 for(auto i
: all_cores_set())
451 i
->install_handler();
454 void core_core::uninstall_all_handlers()
456 install_handlers_automatically
= false;
457 for(auto i
: all_cores_set())
458 i
->uninstall_handler();
461 std::map
<std::string
, std::vector
<char>> core_core::save_sram() throw(std::bad_alloc
)
463 return c_save_sram();
466 void core_core::load_sram(std::map
<std::string
, std::vector
<char>>& sram
) throw(std::bad_alloc
)
471 void core_core::serialize(std::vector
<char>& out
)
476 void core_core::unserialize(const char* in
, size_t insize
)
478 c_unserialize(in
, insize
);
481 core_region
& core_core::get_region()
483 return c_get_region();
486 void core_core::power()
491 void core_core::unload_cartridge()
493 c_unload_cartridge();
496 std::pair
<uint32_t, uint32_t> core_core::get_scale_factors(uint32_t width
, uint32_t height
)
498 return c_get_scale_factors(width
, height
);
501 void core_core::install_handler()
506 void core_core::uninstall_handler()
508 c_uninstall_handler();
511 void core_core::emulate()
516 void core_core::runtosave()
521 bool core_core::get_pflag()
523 return c_get_pflag();
526 void core_core::set_pflag(bool pflag
)
528 return c_set_pflag(pflag
);
531 framebuffer::raw
& core_core::draw_cover()
533 return c_draw_cover();
536 void core_core::pre_emulate_frame(portctrl::frame
& cf
)
538 c_pre_emulate_frame(cf
);
541 void core_core::execute_action(unsigned id
, const std::vector
<interface_action_paramval
>& p
)
543 return c_execute_action(id
, p
);
546 const struct interface_device_reg
* core_core::get_registers()
548 return c_get_registers();
551 unsigned core_core::action_flags(unsigned id
)
553 return c_action_flags(id
);
556 std::set
<const interface_action
*> core_core::get_actions()
558 threads::alock
h(actions_lock
);
559 std::set
<const interface_action
*> r
;
560 for(auto& i
: actions
)
565 int core_core::reset_action(bool hard
)
567 return c_reset_action(hard
);
570 void core_core::set_debug_flags(uint64_t addr
, unsigned flags_set
, unsigned flags_clear
)
572 return c_set_debug_flags(addr
, flags_set
, flags_clear
);
575 void core_core::set_cheat(uint64_t addr
, uint64_t value
, bool set
)
577 return c_set_cheat(addr
, value
, set
);
580 std::vector
<std::string
> core_core::get_trace_cpus()
582 return c_get_trace_cpus();
585 emucore_callbacks::~emucore_callbacks() throw()
589 core_romimage_info_collection::core_romimage_info_collection()
593 core_romimage_info_collection::core_romimage_info_collection(std::initializer_list
<core_romimage_info_params
> idata
)
596 data
.push_back(core_romimage_info(i
));
599 core_romimage_info_collection::core_romimage_info_collection(std::vector
<core_romimage_info_params
> idata
)
602 data
.push_back(core_romimage_info(i
));
605 std::set
<core_sysregion
*> core_sysregion::find_matching(const std::string
& name
)
607 std::set
<core_sysregion
*> ret
;
608 auto u
= sysregions().upper_bound(name
);
609 for(auto i
= sysregions().lower_bound(name
); i
!= u
; ++i
)
610 ret
.insert(i
->second
);
614 void register_sysregion_mapping(std::string from
, std::string to
)
616 sysreg_mapping()[from
] = to
;
619 std::string
lookup_sysregion_mapping(std::string from
)
621 if(sysreg_mapping().count(from
))
622 return sysreg_mapping()[from
];
627 struct emucore_callbacks
* ecore_callbacks
;
629 bool new_core_flag
= false;
630 uint32_t magic_flags
= 0;