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