1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4
5 machine.cpp
6
7 Controls execution of the core MAME system.
8
9 ****************************************************************************
10
11 Since there has been confusion in the past over the order of
12 initialization and other such things, here it is, all spelled out
13 as of January, 2008:
14
15 main()
16 - does platform-specific init
17 - calls mame_execute() [mame.c]
18
19 mame_execute() [mame.c]
20 - calls mame_validitychecks() [validity.c] to perform validity checks on all compiled drivers
21 - begins resource tracking (level 1)
22 - calls create_machine [mame.c] to initialize the running_machine structure
23 - calls init_machine() [mame.c]
24
25 init_machine() [mame.c]
26 - calls fileio_init() [fileio.c] to initialize file I/O info
27 - calls config_init() [config.c] to initialize configuration system
28 - calls input_init() [input.c] to initialize the input system
29 - calls output_init() [output.c] to initialize the output system
30 - calls state_init() [state.c] to initialize save state system
31 - calls state_save_allow_registration() [state.c] to allow registrations
32 - calls palette_init() [palette.c] to initialize palette system
33 - calls render_init() [render.c] to initialize the rendering system
34 - calls ui_init() [ui.c] to initialize the user interface
35 - calls generic_machine_init() [machine/generic.c] to initialize generic machine structures
36 - calls timer_init() [timer.c] to reset the timer system
37 - calls osd_init() [osdepend.h] to do platform-specific initialization
38 - calls input_port_init() [inptport.c] to set up the input ports
39 - calls rom_init() [romload.c] to load the game's ROMs
40 - calls memory_init() [memory.c] to process the game's memory maps
41 - calls the driver's DRIVER_INIT callback
42 - calls device_list_start() [devintrf.c] to start any devices
43 - calls video_init() [video.c] to start the video system
44 - calls tilemap_init() [tilemap.c] to start the tilemap system
45 - calls crosshair_init() [crsshair.c] to configure the crosshairs
46 - calls sound_init() [sound.c] to start the audio system
47 - calls debugger_init() [debugger.c] to set up the debugger
48 - calls the driver's MACHINE_START, SOUND_START, and VIDEO_START callbacks
49 - calls cheat_init() [cheat.c] to initialize the cheat system
50 - calls image_init() [image.c] to initialize the image system
51
52 - calls config_load_settings() [config.c] to load the configuration file
53 - calls nvram_load [machine/generic.c] to load NVRAM
54 - calls ui_display_startup_screens() [ui.c] to display the startup screens
55 - begins resource tracking (level 2)
56 - calls soft_reset() [mame.c] to reset all systems
57
58 -------------------( at this point, we're up and running )----------------------
59
60 - calls scheduler->timeslice() [schedule.c] over and over until we exit
61 - ends resource tracking (level 2), freeing all auto_mallocs and timers
62 - calls the nvram_save() [machine/generic.c] to save NVRAM
63 - calls config_save_settings() [config.c] to save the game's configuration
64 - calls all registered exit routines [mame.c]
65 - ends resource tracking (level 1), freeing all auto_mallocs and timers
66
67 - exits the program
68
69 ***************************************************************************/
70
71 #include "emu.h"
72 #include "emuopts.h"
73 #include "osdepend.h"
74 #include "config.h"
75 #include "debugger.h"
76 #include "render.h"
77 #include "uiinput.h"
78 #include "crsshair.h"
79 #include "unzip.h"
80 #include "debug/debugvw.h"
81 #include "debug/debugcpu.h"
82 #include "dirtc.h"
83 #include "image.h"
84 #include "network.h"
85 #include "romload.h"
86 #include "tilemap.h"
87 #include "ui/uimain.h"
88 #include <ctime>
89 #include <rapidjson/writer.h>
90 #include <rapidjson/stringbuffer.h>
91
92 #if defined(__EMSCRIPTEN__)
93 #include <emscripten.h>
94 #endif
95
96
97
98 //**************************************************************************
99 // RUNNING MACHINE
100 //**************************************************************************
101
osd() const102 osd_interface &running_machine::osd() const
103 {
104 return m_manager.osd();
105 }
106
107 //-------------------------------------------------
108 // running_machine - constructor
109 //-------------------------------------------------
110
running_machine(const machine_config & _config,machine_manager & manager)111 running_machine::running_machine(const machine_config &_config, machine_manager &manager)
112 : m_side_effects_disabled(0),
113 debug_flags(0),
114 m_config(_config),
115 m_system(_config.gamedrv()),
116 m_manager(manager),
117 m_current_phase(machine_phase::PREINIT),
118 m_paused(false),
119 m_hard_reset_pending(false),
120 m_exit_pending(false),
121 m_soft_reset_timer(nullptr),
122 m_rand_seed(0x9d14abd7),
123 m_ui_active(_config.options().ui_active()),
124 m_basename(_config.gamedrv().name),
125 m_sample_rate(_config.options().sample_rate()),
126 m_saveload_schedule(saveload_schedule::NONE),
127 m_saveload_schedule_time(attotime::zero),
128 m_saveload_searchpath(nullptr),
129
130 m_save(*this),
131 m_memory(*this),
132 m_ioport(*this),
133 m_parameters(*this),
134 m_scheduler(*this),
135 m_dummy_space(_config, "dummy_space", &root_device(), 0)
136 {
137 memset(&m_base_time, 0, sizeof(m_base_time));
138
139 m_dummy_space.set_machine(*this);
140 m_dummy_space.config_complete();
141
142 // set the machine on all devices
143 device_iterator iter(root_device());
144 for (device_t &device : iter)
145 device.set_machine(*this);
146
147 // fetch core options
148 if (options().debug())
149 debug_flags = (DEBUG_FLAG_ENABLED | DEBUG_FLAG_CALL_HOOK) | (DEBUG_FLAG_OSD_ENABLED);
150 }
151
152
153 //-------------------------------------------------
154 // ~running_machine - destructor
155 //-------------------------------------------------
156
~running_machine()157 running_machine::~running_machine()
158 {
159 }
160
161
162 //-------------------------------------------------
163 // describe_context - return a string describing
164 // which device is currently executing and its
165 // PC
166 //-------------------------------------------------
167
describe_context() const168 std::string running_machine::describe_context() const
169 {
170 device_execute_interface *executing = m_scheduler.currently_executing();
171 if (executing != nullptr)
172 {
173 cpu_device *cpu = dynamic_cast<cpu_device *>(&executing->device());
174 if (cpu != nullptr)
175 {
176 address_space &prg = cpu->space(AS_PROGRAM);
177 return string_format(prg.is_octal() ? "'%s' (%0*o)" : "'%s' (%0*X)", cpu->tag(), prg.logaddrchars(), cpu->pc());
178 }
179 }
180
181 return std::string("(no context)");
182 }
183
184
185 //-------------------------------------------------
186 // start - initialize the emulated machine
187 //-------------------------------------------------
188
start()189 void running_machine::start()
190 {
191 // initialize basic can't-fail systems here
192 m_configuration = std::make_unique<configuration_manager>(*this);
193 m_input = std::make_unique<input_manager>(*this);
194 m_output = std::make_unique<output_manager>(*this);
195 m_render = std::make_unique<render_manager>(*this);
196 m_bookkeeping = std::make_unique<bookkeeping_manager>(*this);
197
198 // allocate a soft_reset timer
199 m_soft_reset_timer = m_scheduler.timer_alloc(timer_expired_delegate(FUNC(running_machine::soft_reset), this));
200
201 // initialize UI input
202 m_ui_input = std::make_unique<ui_input_manager>(*this);
203
204 // init the osd layer
205 m_manager.osd().init(*this);
206
207 // create the video manager
208 m_video = std::make_unique<video_manager>(*this);
209 m_ui = manager().create_ui(*this);
210
211 // initialize the base time (needed for doing record/playback)
212 ::time(&m_base_time);
213
214 // initialize the input system and input ports for the game
215 // this must be done before memory_init in order to allow specifying
216 // callbacks based on input port tags
217 time_t newbase = m_ioport.initialize();
218 if (newbase != 0)
219 m_base_time = newbase;
220
221 // initialize the streams engine before the sound devices start
222 m_sound = std::make_unique<sound_manager>(*this);
223
224 // resolve objects that can be used by memory maps
225 for (device_t &device : device_iterator(root_device()))
226 device.resolve_pre_map();
227
228 // configure the address spaces, load ROMs (which needs
229 // width/endianess of the spaces), then populate memory (which
230 // needs rom bases), and finally initialize CPUs (which needs
231 // complete address spaces). These operations must proceed in this
232 // order
233 m_rom_load = std::make_unique<rom_load_manager>(*this);
234 m_memory.initialize();
235
236 // save the random seed or save states might be broken in drivers that use the rand() method
237 save().save_item(NAME(m_rand_seed));
238
239 // initialize image devices
240 m_image = std::make_unique<image_manager>(*this);
241 m_tilemap = std::make_unique<tilemap_manager>(*this);
242 m_crosshair = std::make_unique<crosshair_manager>(*this);
243 m_network = std::make_unique<network_manager>(*this);
244
245 // initialize the debugger
246 if ((debug_flags & DEBUG_FLAG_ENABLED) != 0)
247 {
248 m_debug_view = std::make_unique<debug_view_manager>(*this);
249 m_debugger = std::make_unique<debugger_manager>(*this);
250 }
251
252 manager().create_custom(*this);
253
254 // resolve objects that are created by memory maps
255 for (device_t &device : device_iterator(root_device()))
256 device.resolve_post_map();
257
258 // register callbacks for the devices, then start them
259 add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(&running_machine::reset_all_devices, this));
260 add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&running_machine::stop_all_devices, this));
261 save().register_presave(save_prepost_delegate(FUNC(running_machine::presave_all_devices), this));
262 start_all_devices();
263 save().register_postload(save_prepost_delegate(FUNC(running_machine::postload_all_devices), this));
264
265 // save outputs created before start time
266 output().register_save();
267
268 m_render->resolve_tags();
269
270 // load cheat files
271 manager().load_cheatfiles(*this);
272
273 // start recording movie if specified
274 const char *filename = options().mng_write();
275 if (filename[0] != 0)
276 m_video->begin_recording(filename, movie_recording::format::MNG);
277
278 filename = options().avi_write();
279 if (filename[0] != 0 && !m_video->is_recording())
280 m_video->begin_recording(filename, movie_recording::format::AVI);
281
282 // if we're coming in with a savegame request, process it now
283 const char *savegame = options().state();
284 if (savegame[0] != 0)
285 schedule_load(savegame);
286
287 // if we're in autosave mode, schedule a load
288 else if (options().autosave() && (m_system.flags & MACHINE_SUPPORTS_SAVE) != 0)
289 schedule_load("auto");
290
291 manager().update_machine();
292 }
293
294
295 //-------------------------------------------------
296 // run - execute the machine
297 //-------------------------------------------------
298
run(bool quiet)299 int running_machine::run(bool quiet)
300 {
301 int error = EMU_ERR_NONE;
302
303 // use try/catch for deep error recovery
304 try
305 {
306 m_manager.http()->clear();
307
308 // move to the init phase
309 m_current_phase = machine_phase::INIT;
310
311 // if we have a logfile, set up the callback
312 if (options().log() && !quiet)
313 {
314 m_logfile = std::make_unique<emu_file>(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
315 osd_file::error filerr = m_logfile->open("error.log");
316 if (filerr != osd_file::error::NONE)
317 throw emu_fatalerror("running_machine::run: unable to open error.log file");
318
319 using namespace std::placeholders;
320 add_logerror_callback(std::bind(&running_machine::logfile_callback, this, _1));
321 }
322
323 if (options().debug() && options().debuglog())
324 {
325 m_debuglogfile = std::make_unique<emu_file>(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
326 osd_file::error filerr = m_debuglogfile->open("debug.log");
327 if (filerr != osd_file::error::NONE)
328 throw emu_fatalerror("running_machine::run: unable to open debug.log file");
329 }
330
331 // then finish setting up our local machine
332 start();
333
334 // load the configuration settings
335 manager().before_load_settings(*this);
336 m_configuration->load_settings();
337
338 // disallow save state registrations starting here.
339 // Don't do it earlier, config load can create network
340 // devices with timers.
341 m_save.allow_registration(false);
342
343 // load the NVRAM
344 nvram_load();
345
346 // set the time on RTCs (this may overwrite parts of NVRAM)
347 set_rtc_datetime(system_time(m_base_time));
348
349 sound().ui_mute(false);
350 if (!quiet)
351 sound().start_recording();
352
353 // initialize ui lists
354 // display the startup screens
355 manager().ui_initialize(*this);
356
357 // perform a soft reset -- this takes us to the running phase
358 soft_reset();
359
360 // handle initial load
361 if (m_saveload_schedule != saveload_schedule::NONE)
362 handle_saveload();
363
364 export_http_api();
365
366 m_hard_reset_pending = false;
367
368 #if defined(__EMSCRIPTEN__)
369 // break out to our async javascript loop and halt
370 emscripten_set_running_machine(this);
371 #endif
372
373 // run the CPUs until a reset or exit
374 while ((!m_hard_reset_pending && !m_exit_pending) || m_saveload_schedule != saveload_schedule::NONE)
375 {
376 g_profiler.start(PROFILER_EXTRA);
377
378 // execute CPUs if not paused
379 if (!m_paused)
380 m_scheduler.timeslice();
381 // otherwise, just pump video updates through
382 else
383 m_video->frame_update();
384
385 // handle save/load
386 if (m_saveload_schedule != saveload_schedule::NONE)
387 handle_saveload();
388
389 g_profiler.stop();
390 }
391 m_manager.http()->clear();
392
393 // and out via the exit phase
394 m_current_phase = machine_phase::EXIT;
395
396 // save the NVRAM and configuration
397 sound().ui_mute(true);
398 if (options().nvram_save())
399 nvram_save();
400 m_configuration->save_settings();
401 }
402 catch (emu_fatalerror &fatal)
403 {
404 osd_printf_error("Fatal error: %s\n", fatal.what());
405 error = EMU_ERR_FATALERROR;
406 if (fatal.exitcode() != 0)
407 error = fatal.exitcode();
408 }
409 catch (emu_exception &)
410 {
411 osd_printf_error("Caught unhandled emulator exception\n");
412 error = EMU_ERR_FATALERROR;
413 }
414 catch (binding_type_exception &btex)
415 {
416 osd_printf_error("Error performing a late bind of type %s to %s\n", btex.m_actual_type.name(), btex.m_target_type.name());
417 error = EMU_ERR_FATALERROR;
418 }
419 catch (tag_add_exception &aex)
420 {
421 osd_printf_error("Tag '%s' already exists in tagged map\n", aex.tag());
422 error = EMU_ERR_FATALERROR;
423 }
424 catch (std::exception &ex)
425 {
426 osd_printf_error("Caught unhandled %s exception: %s\n", typeid(ex).name(), ex.what());
427 error = EMU_ERR_FATALERROR;
428 }
429 catch (...)
430 {
431 osd_printf_error("Caught unhandled exception\n");
432 error = EMU_ERR_FATALERROR;
433 }
434
435 // make sure our phase is set properly before cleaning up,
436 // in case we got here via exception
437 m_current_phase = machine_phase::EXIT;
438
439 // call all exit callbacks registered
440 call_notifiers(MACHINE_NOTIFY_EXIT);
441 util::archive_file::cache_clear();
442
443 // close the logfile
444 m_logfile.reset();
445 return error;
446 }
447
448 //-------------------------------------------------
449 // schedule_exit - schedule a clean exit
450 //-------------------------------------------------
451
schedule_exit()452 void running_machine::schedule_exit()
453 {
454 m_exit_pending = true;
455
456 // if we're executing, abort out immediately
457 m_scheduler.eat_all_cycles();
458
459 // if we're autosaving on exit, schedule a save as well
460 if (options().autosave() && (m_system.flags & MACHINE_SUPPORTS_SAVE) && this->time() > attotime::zero)
461 schedule_save("auto");
462 }
463
464
465 //-------------------------------------------------
466 // schedule_hard_reset - schedule a hard-reset of
467 // the machine
468 //-------------------------------------------------
469
schedule_hard_reset()470 void running_machine::schedule_hard_reset()
471 {
472 m_hard_reset_pending = true;
473
474 // if we're executing, abort out immediately
475 m_scheduler.eat_all_cycles();
476 }
477
478
479 //-------------------------------------------------
480 // schedule_soft_reset - schedule a soft-reset of
481 // the system
482 //-------------------------------------------------
483
schedule_soft_reset()484 void running_machine::schedule_soft_reset()
485 {
486 m_soft_reset_timer->adjust(attotime::zero);
487
488 // we can't be paused since the timer needs to fire
489 resume();
490
491 // if we're executing, abort out immediately
492 m_scheduler.eat_all_cycles();
493 }
494
495
496 //-------------------------------------------------
497 // get_statename - allow to specify a subfolder of
498 // the state directory for state loading/saving,
499 // very useful for MESS and consoles or computers
500 // where you can have separate folders for diff
501 // software
502 //-------------------------------------------------
503
get_statename(const char * option) const504 std::string running_machine::get_statename(const char *option) const
505 {
506 std::string statename_str("");
507 if (option == nullptr || option[0] == 0)
508 statename_str.assign("%g");
509 else
510 statename_str.assign(option);
511
512 // strip any extension in the provided statename
513 int index = statename_str.find_last_of('.');
514 if (index != -1)
515 statename_str = statename_str.substr(0, index);
516
517 // handle %d in the template (for image devices)
518 std::string statename_dev("%d_");
519 int pos = statename_str.find(statename_dev);
520
521 if (pos != -1)
522 {
523 // if more %d are found, revert to default and ignore them all
524 if (statename_str.find(statename_dev, pos + 3) != -1)
525 statename_str.assign("%g");
526 // else if there is a single %d, try to create the correct snapname
527 else
528 {
529 int name_found = 0;
530
531 // find length of the device name
532 int end1 = statename_str.find('/', pos + 3);
533 int end2 = statename_str.find('%', pos + 3);
534 int end;
535
536 if ((end1 != -1) && (end2 != -1))
537 end = std::min(end1, end2);
538 else if (end1 != -1)
539 end = end1;
540 else if (end2 != -1)
541 end = end2;
542 else
543 end = statename_str.length();
544
545 if (end - pos < 3)
546 fatalerror("Something very wrong is going on!!!\n");
547
548 // copy the device name to an std::string
549 std::string devname_str;
550 devname_str.assign(statename_str.substr(pos + 3, end - pos - 3));
551 //printf("check template: %s\n", devname_str.c_str());
552
553 // verify that there is such a device for this system
554 for (device_image_interface &image : image_interface_iterator(root_device()))
555 {
556 // get the device name
557 std::string tempdevname(image.brief_instance_name());
558 //printf("check device: %s\n", tempdevname.c_str());
559
560 if (devname_str.compare(tempdevname) == 0)
561 {
562 // verify that such a device has an image mounted
563 if (image.basename_noext() != nullptr)
564 {
565 std::string filename(image.basename_noext());
566
567 // setup snapname and remove the %d_
568 strreplace(statename_str, devname_str, filename);
569 statename_str.erase(pos, 3);
570 //printf("check image: %s\n", filename.c_str());
571
572 name_found = 1;
573 }
574 }
575 }
576
577 // or fallback to default
578 if (name_found == 0)
579 statename_str.assign("%g");
580 }
581 }
582
583 // substitute path and gamename up front
584 strreplace(statename_str, "/", PATH_SEPARATOR);
585 strreplace(statename_str, "%g", basename());
586
587 return statename_str;
588 }
589
590
591 //-------------------------------------------------
592 // compose_saveload_filename - composes a filename
593 // for state loading/saving
594 //-------------------------------------------------
595
compose_saveload_filename(std::string && filename,const char ** searchpath)596 std::string running_machine::compose_saveload_filename(std::string &&filename, const char **searchpath)
597 {
598 std::string result;
599
600 // is this an absolute path?
601 if (osd_is_absolute_path(filename))
602 {
603 // if so, this is easy
604 if (searchpath != nullptr)
605 *searchpath = nullptr;
606 result = std::move(filename);
607 }
608 else
609 {
610 // this is a relative path; first specify the search path
611 if (searchpath != nullptr)
612 *searchpath = options().state_directory();
613
614 // take into account the statename option
615 const char *stateopt = options().state_name();
616 std::string statename = get_statename(stateopt);
617 result = string_format("%s%s%s.sta", statename, PATH_SEPARATOR, filename);
618 }
619 return result;
620 }
621
622
623 //-------------------------------------------------
624 // set_saveload_filename - specifies the filename
625 // for state loading/saving
626 //-------------------------------------------------
627
set_saveload_filename(std::string && filename)628 void running_machine::set_saveload_filename(std::string &&filename)
629 {
630 // compose the save/load filename and persist it
631 m_saveload_pending_file = compose_saveload_filename(std::move(filename), &m_saveload_searchpath);
632 }
633
634
635 //-------------------------------------------------
636 // schedule_save - schedule a save to occur as
637 // soon as possible
638 //-------------------------------------------------
639
schedule_save(std::string && filename)640 void running_machine::schedule_save(std::string &&filename)
641 {
642 // specify the filename to save or load
643 set_saveload_filename(std::move(filename));
644
645 // note the start time and set a timer for the next timeslice to actually schedule it
646 m_saveload_schedule = saveload_schedule::SAVE;
647 m_saveload_schedule_time = this->time();
648
649 // we can't be paused since we need to clear out anonymous timers
650 resume();
651 }
652
653
654 //-------------------------------------------------
655 // immediate_save - save state.
656 //-------------------------------------------------
657
immediate_save(const char * filename)658 void running_machine::immediate_save(const char *filename)
659 {
660 // specify the filename to save or load
661 set_saveload_filename(filename);
662
663 // set up some parameters for handle_saveload()
664 m_saveload_schedule = saveload_schedule::SAVE;
665 m_saveload_schedule_time = this->time();
666
667 // jump right into the save, anonymous timers can't hurt us!
668 handle_saveload();
669 }
670
671
672 //-------------------------------------------------
673 // schedule_load - schedule a load to occur as
674 // soon as possible
675 //-------------------------------------------------
676
schedule_load(std::string && filename)677 void running_machine::schedule_load(std::string &&filename)
678 {
679 // specify the filename to save or load
680 set_saveload_filename(std::move(filename));
681
682 // note the start time and set a timer for the next timeslice to actually schedule it
683 m_saveload_schedule = saveload_schedule::LOAD;
684 m_saveload_schedule_time = this->time();
685
686 // we can't be paused since we need to clear out anonymous timers
687 resume();
688 }
689
690
691 //-------------------------------------------------
692 // immediate_load - load state.
693 //-------------------------------------------------
694
immediate_load(const char * filename)695 void running_machine::immediate_load(const char *filename)
696 {
697 // specify the filename to save or load
698 set_saveload_filename(filename);
699
700 // set up some parameters for handle_saveload()
701 m_saveload_schedule = saveload_schedule::LOAD;
702 m_saveload_schedule_time = this->time();
703
704 // jump right into the load, anonymous timers can't hurt us
705 handle_saveload();
706 }
707
708
709 //-------------------------------------------------
710 // rewind_capture - capture and append a new
711 // state to the rewind list
712 //-------------------------------------------------
713
rewind_capture()714 bool running_machine::rewind_capture()
715 {
716 return m_save.rewind()->capture();
717 }
718
719
720 //-------------------------------------------------
721 // rewind_step - a single step back through
722 // rewind states
723 //-------------------------------------------------
724
rewind_step()725 bool running_machine::rewind_step()
726 {
727 return m_save.rewind()->step();
728 }
729
730
731 //-------------------------------------------------
732 // rewind_invalidate - mark all the future rewind
733 // states as invalid
734 //-------------------------------------------------
735
rewind_invalidate()736 void running_machine::rewind_invalidate()
737 {
738 m_save.rewind()->invalidate();
739 }
740
741
742 //-------------------------------------------------
743 // pause - pause the system
744 //-------------------------------------------------
745
pause()746 void running_machine::pause()
747 {
748 // ignore if nothing has changed
749 if (m_paused)
750 return;
751 m_paused = true;
752
753 // call the callbacks
754 call_notifiers(MACHINE_NOTIFY_PAUSE);
755 }
756
757
758 //-------------------------------------------------
759 // resume - resume the system
760 //-------------------------------------------------
761
resume()762 void running_machine::resume()
763 {
764 // ignore if nothing has changed
765 if (!m_paused)
766 return;
767 m_paused = false;
768
769 // call the callbacks
770 call_notifiers(MACHINE_NOTIFY_RESUME);
771 }
772
773
774 //-------------------------------------------------
775 // toggle_pause - toggles the pause state
776 //-------------------------------------------------
777
toggle_pause()778 void running_machine::toggle_pause()
779 {
780 if (paused())
781 {
782 rewind_invalidate();
783 resume();
784 }
785 else
786 pause();
787 }
788
789
790 //-------------------------------------------------
791 // add_notifier - add a notifier of the
792 // given type
793 //-------------------------------------------------
794
add_notifier(machine_notification event,machine_notify_delegate callback,bool first)795 void running_machine::add_notifier(machine_notification event, machine_notify_delegate callback, bool first)
796 {
797 if (m_current_phase != machine_phase::INIT)
798 throw emu_fatalerror("Can only call running_machine::add_notifier at init time!");
799
800 if (first)
801 m_notifier_list[event].push_front(std::make_unique<notifier_callback_item>(callback));
802
803 // exit notifiers are added to the head, and executed in reverse order
804 else if (event == MACHINE_NOTIFY_EXIT)
805 m_notifier_list[event].push_front(std::make_unique<notifier_callback_item>(callback));
806
807 // all other notifiers are added to the tail, and executed in the order registered
808 else
809 m_notifier_list[event].push_back(std::make_unique<notifier_callback_item>(callback));
810 }
811
812
813 //-------------------------------------------------
814 // add_logerror_callback - adds a callback to be
815 // called on logerror()
816 //-------------------------------------------------
817
add_logerror_callback(logerror_callback callback)818 void running_machine::add_logerror_callback(logerror_callback callback)
819 {
820 if (m_current_phase != machine_phase::INIT)
821 throw emu_fatalerror("Can only call running_machine::add_logerror_callback at init time!");
822 m_string_buffer.reserve(1024);
823 m_logerror_list.push_back(std::make_unique<logerror_callback_item>(callback));
824 }
825
826
827 //-------------------------------------------------
828 // strlog - send an error logging string to the
829 // debugger and any OSD-defined output streams
830 //-------------------------------------------------
831
strlog(const char * str) const832 void running_machine::strlog(const char *str) const
833 {
834 // log to all callbacks
835 for (auto &cb : m_logerror_list)
836 cb->m_func(str);
837 }
838
839
840 //-------------------------------------------------
841 // debug_break - breaks into the debugger, if
842 // enabled
843 //-------------------------------------------------
844
debug_break()845 void running_machine::debug_break()
846 {
847 if ((debug_flags & DEBUG_FLAG_ENABLED) != 0)
848 debugger().debug_break();
849 }
850
851 //-------------------------------------------------
852 // base_datetime - retrieve the time of the host
853 // system; useful for RTC implementations
854 //-------------------------------------------------
855
base_datetime(system_time & systime)856 void running_machine::base_datetime(system_time &systime)
857 {
858 systime.set(m_base_time);
859 }
860
861
862 //-------------------------------------------------
863 // current_datetime - retrieve the current time
864 // (offset by the base); useful for RTC
865 // implementations
866 //-------------------------------------------------
867
current_datetime(system_time & systime)868 void running_machine::current_datetime(system_time &systime)
869 {
870 systime.set(m_base_time + this->time().seconds());
871 }
872
873
874 //-------------------------------------------------
875 // set_rtc_datetime - set the current time on
876 // battery-backed RTCs
877 //-------------------------------------------------
878
set_rtc_datetime(const system_time & systime)879 void running_machine::set_rtc_datetime(const system_time &systime)
880 {
881 for (device_rtc_interface &rtc : rtc_interface_iterator(root_device()))
882 if (rtc.has_battery())
883 rtc.set_current_time(systime);
884 }
885
886
887 //-------------------------------------------------
888 // rand - standardized random numbers
889 //-------------------------------------------------
890
891 // TODO: using this function in the core is strongly discouraged (can affect inp playback),
892 // maybe we should consider moving this function to somewhere else instead.
rand()893 u32 running_machine::rand()
894 {
895 m_rand_seed = 1664525 * m_rand_seed + 1013904223;
896
897 // return rotated by 16 bits; the low bits have a short period
898 // and are frequently used
899 return (m_rand_seed >> 16) | (m_rand_seed << 16);
900 }
901
902
903 //-------------------------------------------------
904 // call_notifiers - call notifiers of the given
905 // type
906 //-------------------------------------------------
907
call_notifiers(machine_notification which)908 void running_machine::call_notifiers(machine_notification which)
909 {
910 for (auto& cb : m_notifier_list[which])
911 cb->m_func();
912 }
913
914
915 //-------------------------------------------------
916 // handle_saveload - attempt to perform a save
917 // or load
918 //-------------------------------------------------
919
handle_saveload()920 void running_machine::handle_saveload()
921 {
922 // if no name, bail
923 if (!m_saveload_pending_file.empty())
924 {
925 const char *const opname = (m_saveload_schedule == saveload_schedule::LOAD) ? "load" : "save";
926
927 // if there are anonymous timers, we can't save just yet, and we can't load yet either
928 // because the timers might overwrite data we have loaded
929 if (!m_scheduler.can_save())
930 {
931 // if more than a second has passed, we're probably screwed
932 if ((this->time() - m_saveload_schedule_time) > attotime::from_seconds(1))
933 popmessage("Unable to %s due to pending anonymous timers. See error.log for details.", opname);
934 else
935 return; // return without cancelling the operation
936 }
937 else
938 {
939 u32 const openflags = (m_saveload_schedule == saveload_schedule::LOAD) ? OPEN_FLAG_READ : (OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
940
941 // open the file
942 emu_file file(m_saveload_searchpath ? m_saveload_searchpath : "", openflags);
943 auto const filerr = file.open(m_saveload_pending_file);
944 if (filerr == osd_file::error::NONE)
945 {
946 const char *const opnamed = (m_saveload_schedule == saveload_schedule::LOAD) ? "loaded" : "saved";
947
948 // read/write the save state
949 save_error saverr = (m_saveload_schedule == saveload_schedule::LOAD) ? m_save.read_file(file) : m_save.write_file(file);
950
951 // handle the result
952 switch (saverr)
953 {
954 case STATERR_ILLEGAL_REGISTRATIONS:
955 popmessage("Error: Unable to %s state due to illegal registrations. See error.log for details.", opname);
956 break;
957
958 case STATERR_INVALID_HEADER:
959 popmessage("Error: Unable to %s state due to an invalid header. Make sure the save state is correct for this machine.", opname);
960 break;
961
962 case STATERR_READ_ERROR:
963 popmessage("Error: Unable to %s state due to a read error (file is likely corrupt).", opname);
964 break;
965
966 case STATERR_WRITE_ERROR:
967 popmessage("Error: Unable to %s state due to a write error. Verify there is enough disk space.", opname);
968 break;
969
970 case STATERR_NONE:
971 if (!(m_system.flags & MACHINE_SUPPORTS_SAVE))
972 popmessage("State successfully %s.\nWarning: Save states are not officially supported for this machine.", opnamed);
973 else
974 popmessage("State successfully %s.", opnamed);
975 break;
976
977 default:
978 popmessage("Error: Unknown error during state %s.", opnamed);
979 break;
980 }
981
982 // close and perhaps delete the file
983 if (saverr != STATERR_NONE && m_saveload_schedule == saveload_schedule::SAVE)
984 file.remove_on_close();
985 }
986 else if (openflags == OPEN_FLAG_READ && filerr == osd_file::error::NOT_FOUND)
987 // attempt to load a non-existent savestate, report empty slot
988 popmessage("Error: No savestate file to load.", opname);
989 else
990 popmessage("Error: Failed to open file for %s operation.", opname);
991 }
992 }
993
994 // unschedule the operation
995 m_saveload_pending_file.clear();
996 m_saveload_searchpath = nullptr;
997 m_saveload_schedule = saveload_schedule::NONE;
998 }
999
1000
1001 //-------------------------------------------------
1002 // soft_reset - actually perform a soft-reset
1003 // of the system
1004 //-------------------------------------------------
1005
soft_reset(void * ptr,s32 param)1006 void running_machine::soft_reset(void *ptr, s32 param)
1007 {
1008 logerror("Soft reset\n");
1009
1010 // temporarily in the reset phase
1011 m_current_phase = machine_phase::RESET;
1012
1013 // call all registered reset callbacks
1014 call_notifiers(MACHINE_NOTIFY_RESET);
1015
1016 // now we're running
1017 m_current_phase = machine_phase::RUNNING;
1018 }
1019
1020
1021 //-------------------------------------------------
1022 // logfile_callback - callback for logging to
1023 // logfile
1024 //-------------------------------------------------
1025
logfile_callback(const char * buffer)1026 void running_machine::logfile_callback(const char *buffer)
1027 {
1028 if (m_logfile != nullptr)
1029 {
1030 m_logfile->puts(buffer);
1031 m_logfile->flush();
1032 }
1033 }
1034
1035
1036 //-------------------------------------------------
1037 // start_all_devices - start any unstarted devices
1038 //-------------------------------------------------
1039
start_all_devices()1040 void running_machine::start_all_devices()
1041 {
1042 m_dummy_space.start();
1043
1044 // iterate through the devices
1045 int last_failed_starts = -1;
1046 while (last_failed_starts != 0)
1047 {
1048 // iterate over all devices
1049 int failed_starts = 0;
1050 for (device_t &device : device_iterator(root_device()))
1051 if (!device.started())
1052 {
1053 // attempt to start the device, catching any expected exceptions
1054 try
1055 {
1056 // if the device doesn't have a machine yet, set it first
1057 if (device.m_machine == nullptr)
1058 device.set_machine(*this);
1059
1060 // now start the device
1061 osd_printf_verbose("Starting %s '%s'\n", device.name(), device.tag());
1062 device.start();
1063 }
1064
1065 // handle missing dependencies by moving the device to the end
1066 catch (device_missing_dependencies &)
1067 {
1068 // if we're the end, fail
1069 osd_printf_verbose(" (missing dependencies; rescheduling)\n");
1070 failed_starts++;
1071 }
1072 }
1073
1074 // each iteration should reduce the number of failed starts; error if
1075 // this doesn't happen
1076 if (failed_starts == last_failed_starts)
1077 throw emu_fatalerror("Circular dependency in device startup!");
1078 last_failed_starts = failed_starts;
1079 }
1080 }
1081
1082
1083 //-------------------------------------------------
1084 // reset_all_devices - reset all devices in the
1085 // hierarchy
1086 //-------------------------------------------------
1087
reset_all_devices()1088 void running_machine::reset_all_devices()
1089 {
1090 // reset the root and it will reset children
1091 root_device().reset();
1092 }
1093
1094
1095 //-------------------------------------------------
1096 // stop_all_devices - stop all the devices in the
1097 // hierarchy
1098 //-------------------------------------------------
1099
stop_all_devices()1100 void running_machine::stop_all_devices()
1101 {
1102 // first let the debugger save comments
1103 if ((debug_flags & DEBUG_FLAG_ENABLED) != 0)
1104 debugger().cpu().comment_save();
1105
1106 // iterate over devices and stop them
1107 for (device_t &device : device_iterator(root_device()))
1108 device.stop();
1109 }
1110
1111
1112 //-------------------------------------------------
1113 // presave_all_devices - tell all the devices we
1114 // are about to save
1115 //-------------------------------------------------
1116
presave_all_devices()1117 void running_machine::presave_all_devices()
1118 {
1119 for (device_t &device : device_iterator(root_device()))
1120 device.pre_save();
1121 }
1122
1123
1124 //-------------------------------------------------
1125 // postload_all_devices - tell all the devices we
1126 // just completed a load
1127 //-------------------------------------------------
1128
postload_all_devices()1129 void running_machine::postload_all_devices()
1130 {
1131 for (device_t &device : device_iterator(root_device()))
1132 device.post_load();
1133 }
1134
1135
1136 /***************************************************************************
1137 NVRAM MANAGEMENT
1138 ***************************************************************************/
1139
1140 /*-------------------------------------------------
1141 nvram_filename - returns filename of system's
1142 NVRAM depending of selected BIOS
1143 -------------------------------------------------*/
1144
nvram_filename(device_t & device) const1145 std::string running_machine::nvram_filename(device_t &device) const
1146 {
1147 // start with either basename or basename_biosnum
1148 std::ostringstream result;
1149 result << basename();
1150 if (root_device().system_bios() != 0 && root_device().default_bios() != root_device().system_bios())
1151 util::stream_format(result, "_%d", root_device().system_bios() - 1);
1152
1153 // device-based NVRAM gets its own name in a subdirectory
1154 if (device.owner() != nullptr)
1155 {
1156 // add per software nvrams into one folder
1157 const char *software = nullptr;
1158 for (device_t *dev = &device; dev->owner() != nullptr; dev = dev->owner())
1159 {
1160 device_image_interface *intf;
1161 if (dev->interface(intf))
1162 {
1163 software = intf->basename_noext();
1164 break;
1165 }
1166 }
1167 if (software != nullptr && *software != '\0')
1168 result << PATH_SEPARATOR << software;
1169
1170 std::string tag(device.tag());
1171 tag.erase(0, 1);
1172 strreplacechr(tag,':', '_');
1173 result << PATH_SEPARATOR << tag;
1174 }
1175 return result.str();
1176 }
1177
1178 /*-------------------------------------------------
1179 nvram_load - load a system's NVRAM
1180 -------------------------------------------------*/
1181
nvram_load()1182 void running_machine::nvram_load()
1183 {
1184 for (device_nvram_interface &nvram : nvram_interface_iterator(root_device()))
1185 {
1186 emu_file file(options().nvram_directory(), OPEN_FLAG_READ);
1187 if (file.open(nvram_filename(nvram.device())) == osd_file::error::NONE)
1188 {
1189 nvram.nvram_load(file);
1190 file.close();
1191 }
1192 else
1193 nvram.nvram_reset();
1194 }
1195 }
1196
1197
1198 /*-------------------------------------------------
1199 nvram_save - save a system's NVRAM
1200 -------------------------------------------------*/
1201
nvram_save()1202 void running_machine::nvram_save()
1203 {
1204 for (device_nvram_interface &nvram : nvram_interface_iterator(root_device()))
1205 {
1206 if (nvram.nvram_can_save())
1207 {
1208 emu_file file(options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
1209 if (file.open(nvram_filename(nvram.device())) == osd_file::error::NONE)
1210 {
1211 nvram.nvram_save(file);
1212 file.close();
1213 }
1214 }
1215 }
1216 }
1217
1218
1219 //**************************************************************************
1220 // OUTPUT
1221 //**************************************************************************
1222
popup_clear() const1223 void running_machine::popup_clear() const
1224 {
1225 ui().popup_time(0, " ");
1226 }
1227
popup_message(util::format_argument_pack<std::ostream> const & args) const1228 void running_machine::popup_message(util::format_argument_pack<std::ostream> const &args) const
1229 {
1230 std::string const temp(string_format(args));
1231 ui().popup_time(temp.length() / 40 + 2, "%s", temp);
1232 }
1233
1234
1235 //**************************************************************************
1236 // CALLBACK ITEMS
1237 //**************************************************************************
1238
1239 //-------------------------------------------------
1240 // notifier_callback_item - constructor
1241 //-------------------------------------------------
1242
notifier_callback_item(machine_notify_delegate func)1243 running_machine::notifier_callback_item::notifier_callback_item(machine_notify_delegate func)
1244 : m_func(std::move(func))
1245 {
1246 }
1247
1248
1249 //-------------------------------------------------
1250 // logerror_callback_item - constructor
1251 //-------------------------------------------------
1252
logerror_callback_item(logerror_callback func)1253 running_machine::logerror_callback_item::logerror_callback_item(logerror_callback func)
1254 : m_func(std::move(func))
1255 {
1256 }
1257
export_http_api()1258 void running_machine::export_http_api()
1259 {
1260 if (m_manager.http()->is_active()) {
1261 m_manager.http()->add_http_handler("/api/machine", [this](http_manager::http_request_ptr request, http_manager::http_response_ptr response)
1262 {
1263 rapidjson::StringBuffer s;
1264 rapidjson::Writer<rapidjson::StringBuffer> writer(s);
1265 writer.StartObject();
1266 writer.Key("name");
1267 writer.String(m_basename.c_str());
1268
1269 writer.Key("devices");
1270 writer.StartArray();
1271
1272 device_iterator iter(this->root_device());
1273 for (device_t &device : iter)
1274 writer.String(device.tag());
1275
1276 writer.EndArray();
1277 writer.EndObject();
1278
1279 response->set_status(200);
1280 response->set_content_type("application/json");
1281 response->set_body(s.GetString());
1282 });
1283 }
1284 }
1285
1286 //**************************************************************************
1287 // SYSTEM TIME
1288 //**************************************************************************
1289
1290 //-------------------------------------------------
1291 // system_time - constructor
1292 //-------------------------------------------------
1293
system_time()1294 system_time::system_time()
1295 {
1296 set(0);
1297 }
1298
system_time(time_t t)1299 system_time::system_time(time_t t)
1300 {
1301 set(t);
1302 }
1303
1304
1305 //-------------------------------------------------
1306 // set - fills out a system_time structure
1307 //-------------------------------------------------
1308
set(time_t t)1309 void system_time::set(time_t t)
1310 {
1311 // FIXME: this crashes if localtime or gmtime returns nullptr
1312 time = t;
1313 local_time.set(*localtime(&t));
1314 utc_time.set(*gmtime(&t));
1315 }
1316
1317
1318 //-------------------------------------------------
1319 // get_tm_time - converts a tm struction to a
1320 // MAME mame_system_tm structure
1321 //-------------------------------------------------
1322
set(struct tm & t)1323 void system_time::full_time::set(struct tm &t)
1324 {
1325 second = t.tm_sec;
1326 minute = t.tm_min;
1327 hour = t.tm_hour;
1328 mday = t.tm_mday;
1329 month = t.tm_mon;
1330 year = t.tm_year + 1900;
1331 weekday = t.tm_wday;
1332 day = t.tm_yday;
1333 is_dst = t.tm_isdst;
1334 }
1335
1336
1337
1338 //**************************************************************************
1339 // DUMMY ADDRESS SPACE
1340 //**************************************************************************
1341
read(offs_t offset)1342 u8 dummy_space_device::read(offs_t offset)
1343 {
1344 throw emu_fatalerror("Attempted to read from generic address space (offs %X)\n", offset);
1345 }
1346
write(offs_t offset,u8 data)1347 void dummy_space_device::write(offs_t offset, u8 data)
1348 {
1349 throw emu_fatalerror("Attempted to write to generic address space (offs %X = %02X)\n", offset, data);
1350 }
1351
dummy(address_map & map)1352 void dummy_space_device::dummy(address_map &map)
1353 {
1354 map(0x00000000, 0xffffffff).rw(FUNC(dummy_space_device::read), FUNC(dummy_space_device::write));
1355 }
1356
1357 DEFINE_DEVICE_TYPE(DUMMY_SPACE, dummy_space_device, "dummy_space", "Dummy Space")
1358
dummy_space_device(const machine_config & mconfig,const char * tag,device_t * owner,u32 clock)1359 dummy_space_device::dummy_space_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
1360 device_t(mconfig, DUMMY_SPACE, tag, owner, clock),
1361 device_memory_interface(mconfig, *this),
1362 m_space_config("dummy", ENDIANNESS_LITTLE, 8, 32, 0, address_map_constructor(FUNC(dummy_space_device::dummy), this))
1363 {
1364 }
1365
device_start()1366 void dummy_space_device::device_start()
1367 {
1368 }
1369
1370 //-------------------------------------------------
1371 // memory_space_config - return a description of
1372 // any address spaces owned by this device
1373 //-------------------------------------------------
1374
memory_space_config() const1375 device_memory_interface::space_config_vector dummy_space_device::memory_space_config() const
1376 {
1377 return space_config_vector {
1378 std::make_pair(0, &m_space_config)
1379 };
1380 }
1381
1382
1383 //**************************************************************************
1384 // JAVASCRIPT PORT-SPECIFIC
1385 //**************************************************************************
1386
1387 #if defined(__EMSCRIPTEN__)
1388
1389 running_machine * running_machine::emscripten_running_machine;
1390
emscripten_main_loop()1391 void running_machine::emscripten_main_loop()
1392 {
1393 running_machine *machine = emscripten_running_machine;
1394
1395 g_profiler.start(PROFILER_EXTRA);
1396
1397 // execute CPUs if not paused
1398 if (!machine->m_paused)
1399 {
1400 device_scheduler * scheduler;
1401 scheduler = &(machine->scheduler());
1402
1403 // Emscripten will call this function at 60Hz, so step the simulation
1404 // forward for the amount of time that has passed since the last frame
1405 const attotime frametime(0,HZ_TO_ATTOSECONDS(60));
1406 const attotime stoptime(scheduler->time() + frametime);
1407
1408 while (!machine->m_paused && !machine->scheduled_event_pending() && scheduler->time() < stoptime)
1409 {
1410 scheduler->timeslice();
1411 // handle save/load
1412 if (machine->m_saveload_schedule != saveload_schedule::NONE)
1413 {
1414 machine->handle_saveload();
1415 break;
1416 }
1417 }
1418 }
1419 // otherwise, just pump video updates through
1420 else
1421 machine->m_video->frame_update();
1422
1423 // cancel the emscripten loop if the system has been told to exit
1424 if (machine->exit_pending())
1425 {
1426 emscripten_cancel_main_loop();
1427 }
1428
1429 g_profiler.stop();
1430 }
1431
emscripten_set_running_machine(running_machine * machine)1432 void running_machine::emscripten_set_running_machine(running_machine *machine)
1433 {
1434 emscripten_running_machine = machine;
1435 EM_ASM (
1436 JSMESS.running = true;
1437 );
1438 emscripten_set_main_loop(&(emscripten_main_loop), 0, 1);
1439 }
1440
emscripten_get_running_machine()1441 running_machine * running_machine::emscripten_get_running_machine()
1442 {
1443 return emscripten_running_machine;
1444 }
1445
emscripten_get_ui()1446 ui_manager * running_machine::emscripten_get_ui()
1447 {
1448 return &(emscripten_running_machine->ui());
1449 }
1450
emscripten_get_sound()1451 sound_manager * running_machine::emscripten_get_sound()
1452 {
1453 return &(emscripten_running_machine->sound());
1454 }
1455
emscripten_soft_reset()1456 void running_machine::emscripten_soft_reset() {
1457 emscripten_running_machine->schedule_soft_reset();
1458 }
emscripten_hard_reset()1459 void running_machine::emscripten_hard_reset() {
1460 emscripten_running_machine->schedule_hard_reset();
1461 }
emscripten_exit()1462 void running_machine::emscripten_exit() {
1463 emscripten_running_machine->schedule_exit();
1464 }
emscripten_save(const char * name)1465 void running_machine::emscripten_save(const char *name) {
1466 emscripten_running_machine->schedule_save(name);
1467 }
emscripten_load(const char * name)1468 void running_machine::emscripten_load(const char *name) {
1469 emscripten_running_machine->schedule_load(name);
1470 }
1471
1472 #endif /* defined(__EMSCRIPTEN__) */
1473