machine_config::machine_config(const game_driver &gamedrv, emu_options &options) : m_minimum_quantum(attotime::zero), m_watchdog_vblank_count(0), m_watchdog_time(attotime::zero), m_nvram_handler(NULL), m_memcard_handler(NULL), m_default_layout(NULL), m_gamedrv(gamedrv), m_options(options) { // construct the config (*gamedrv.machine_config)(*this, NULL, NULL); bool is_selected_driver = mame_stricmp(gamedrv.name,options.system_name())==0; // intialize slot devices - make sure that any required devices have been allocated slot_interface_iterator slotiter(root_device()); for (device_slot_interface *slot = slotiter.first(); slot != NULL; slot = slotiter.next()) { device_t &owner = slot->device(); astring temp; const char *selval = options.main_value(temp, owner.tag()+1); bool isdefault = (options.priority(owner.tag()+1)==OPTION_PRIORITY_DEFAULT); if (!is_selected_driver || !options.exists(owner.tag()+1)) selval = slot->default_option(); if (selval != NULL && *selval != 0) { const device_slot_option *option = slot->option(selval); if (option && (isdefault || option->selectable())) { device_t *new_dev = device_add(&owner, option->name(), option->devtype(), option->clock()); const char *default_bios = option->default_bios(); if (default_bios != NULL) device_t::static_set_default_bios_tag(*new_dev, default_bios); machine_config_constructor additions = option->machine_config(); if (additions != NULL) (*additions)(const_cast<machine_config &>(*this), new_dev, new_dev); const input_device_default *input_device_defaults = option->input_device_defaults(); if (input_device_defaults) device_t::static_set_input_default(*new_dev, input_device_defaults); } else throw emu_fatalerror("Unknown slot option '%s' in slot '%s'", selval, owner.tag()+1); } } // when finished, set the game driver driver_device::static_set_game(*m_root_device, gamedrv); // then notify all devices that their configuration is complete device_iterator iter(root_device()); for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (!device->configured()) device->config_complete(); }
running_machine::running_machine(const machine_config &_config, machine_manager &manager) : firstcpu(NULL), primary_screen(NULL), debug_flags(0), romload_data(NULL), ui_input_data(NULL), debugcpu_data(NULL), generic_machine_data(NULL), m_config(_config), m_system(_config.gamedrv()), m_manager(manager), m_current_phase(MACHINE_PHASE_PREINIT), m_paused(false), m_hard_reset_pending(false), m_exit_pending(false), m_soft_reset_timer(NULL), m_rand_seed(0x9d14abd7), m_ui_active(_config.options().ui_active()), m_basename(_config.gamedrv().name), m_sample_rate(_config.options().sample_rate()), m_saveload_schedule(SLS_NONE), m_saveload_schedule_time(attotime::zero), m_saveload_searchpath(NULL), m_save(*this), m_memory(*this), m_ioport(*this), m_parameters(*this), m_scheduler(*this) { memset(&m_base_time, 0, sizeof(m_base_time)); // set the machine on all devices device_iterator iter(root_device()); for (device_t *device = iter.first(); device != NULL; device = iter.next()) device->set_machine(*this); // find devices for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (dynamic_cast<cpu_device *>(device) != NULL) { firstcpu = downcast<cpu_device *>(device); break; } screen_device_iterator screeniter(root_device()); primary_screen = screeniter.first(); //MKCHAMP--initialize the cpu for hiscore cpu[0] = firstcpu; for (cpunum = 1; cpunum < ARRAY_LENGTH(cpu) && cpu[cpunum - 1] != NULL; cpunum++) cpu[cpunum] = cpu[cpunum - 1]->next(); // fetch core options if (options().debug()) debug_flags = (DEBUG_FLAG_ENABLED | DEBUG_FLAG_CALL_HOOK) | (DEBUG_FLAG_OSD_ENABLED); }
machine_config::machine_config(const game_driver &gamedrv, emu_options &options) : m_minimum_quantum(attotime::zero), m_default_layout(nullptr), m_gamedrv(gamedrv), m_options(options) { // construct the config (*gamedrv.machine_config)(*this, nullptr, nullptr); bool is_selected_driver = core_stricmp(gamedrv.name,options.system_name())==0; // intialize slot devices - make sure that any required devices have been allocated for (device_slot_interface &slot : slot_interface_iterator(root_device())) { device_t &owner = slot.device(); std::string selval; bool isdefault = (options.priority(owner.tag()+1)==OPTION_PRIORITY_DEFAULT); if (is_selected_driver && options.exists(owner.tag()+1)) selval = options.main_value(owner.tag()+1); else if (slot.default_option() != nullptr) selval.assign(slot.default_option()); if (!selval.empty()) { const device_slot_option *option = slot.option(selval.c_str()); if (option && (isdefault || option->selectable())) { device_t *new_dev = device_add(&owner, option->name(), option->devtype(), option->clock()); const char *default_bios = option->default_bios(); if (default_bios != nullptr) device_t::static_set_default_bios_tag(*new_dev, default_bios); machine_config_constructor additions = option->machine_config(); if (additions != nullptr) (*additions)(const_cast<machine_config &>(*this), new_dev, new_dev); const input_device_default *input_device_defaults = option->input_device_defaults(); if (input_device_defaults) device_t::static_set_input_default(*new_dev, input_device_defaults); } else throw emu_fatalerror("Unknown slot option '%s' in slot '%s'", selval.c_str(), owner.tag()+1); } } // when finished, set the game driver driver_device::static_set_game(*m_root_device, gamedrv); // then notify all devices that their configuration is complete for (device_t &device : device_iterator(root_device())) if (!device.configured()) device.config_complete(); }
void machine_config::remove_references(ATTR_UNUSED device_t &device) { // iterate over all devices and remove any references device_iterator iter(root_device()); for (device_t *scan = iter.first(); scan != nullptr; scan = iter.next()) scan->subdevices().m_tagmap.clear(); //remove(&device); }
void running_machine::stop_all_devices() { // first let the debugger save comments if ((debug_flags & DEBUG_FLAG_ENABLED) != 0) debug_comment_save(*this); // iterate over devices and stop them device_iterator iter(root_device()); for (device_t *device = iter.first(); device != NULL; device = iter.next()) device->stop(); }
device_t &running_machine::add_dynamic_device(device_t &owner, device_type type, const char *tag, UINT32 clock) { // add the device in a standard manner device_t *device = const_cast<machine_config &>(m_config).device_add(&owner, tag, type, clock); // notify this device and all its subdevices that they are now configured device_iterator iter(root_device()); for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (!device->configured()) device->config_complete(); return *device; }
astring &running_machine::nvram_filename(astring &result, device_t &device) { // start with either basename or basename_biosnum result.cpy(basename()); if (root_device().system_bios() != 0 && root_device().default_bios() != root_device().system_bios()) result.catprintf("_%d", root_device().system_bios() - 1); // device-based NVRAM gets its own name in a subdirectory if (&device != &root_device()) { // add per software nvrams into one folder const char *software = image_parent_basename(&device); if (software!=NULL && strlen(software)>0) { result.cat('\\').cat(software); } astring tag(device.tag()); tag.del(0, 1).replacechr(':', '_'); result.cat('\\').cat(tag); } return result; }
const char *running_machine::image_parent_basename(device_t *device) { device_t *dev = device; while(dev != &root_device()) { device_image_interface *intf = NULL; if (dev!=NULL && dev->interface(intf)) { return intf->basename_noext(); } dev = dev->owner(); } return NULL; }
void running_machine::nvram_save() { nvram_interface_iterator iter(root_device()); for (device_nvram_interface *nvram = iter.first(); nvram != NULL; nvram = iter.next()) { astring filename; emu_file file(options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); if (file.open(nvram_filename(filename, nvram->device())) == FILERR_NONE) { nvram->nvram_save(file); file.close(); } } }
void machine_config::remove_references(device_t &device) { // remove default layouts for subdevices char const *const tag(device.tag()); std::size_t const taglen(std::strlen(tag)); default_layout_map::iterator it(m_default_layouts.lower_bound(tag)); while ((m_default_layouts.end() != it) && !std::strncmp(tag, it->first, taglen)) { if (!it->first[taglen] || (':' == it->first[taglen])) it = m_default_layouts.erase(it); else ++it; } // iterate over all devices and remove any references for (device_t &scan : device_iterator(root_device())) scan.subdevices().m_tagmap.clear(); }
int main(int argc, char *argv[]) { char *root = root_device(); int n = 2; if (root == NULL) { write(2, "substroot: unable to find root device.\n", 39); exit(255); } if (argc < 2) { write(2, "substroot app ...\n", 18); exit(255); } while (n < argc) { if (strcmp(argv[n], "%") == 0) argv[n] = root; n++; } execvp(argv[1], argv + 1); perror(argv[1]); exit(1); }
void running_machine::start_all_devices() { // iterate through the devices int last_failed_starts = -1; while (last_failed_starts != 0) { // iterate over all devices int failed_starts = 0; device_iterator iter(root_device()); for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (!device->started()) { // attempt to start the device, catching any expected exceptions try { // if the device doesn't have a machine yet, set it first if (device->m_machine == NULL) device->set_machine(*this); // now start the device mame_printf_verbose("Starting %s '%s'\n", device->name(), device->tag()); device->start(); } // handle missing dependencies by moving the device to the end catch (device_missing_dependencies &) { // if we're the end, fail mame_printf_verbose(" (missing dependencies; rescheduling)\n"); failed_starts++; } } // each iteration should reduce the number of failed starts; error if // this doesn't happen if (failed_starts == last_failed_starts) throw emu_fatalerror("Circular dependency in device startup!"); last_failed_starts = failed_starts; } }
static char *host_image(char *cmd_line, size_t size) { char *t; char device[PATH_MAX]; long part = 0; t = malloc(PATH_MAX); if (!t) return NULL; /* check for the root file system */ if (root_device(device, &part) < 0) { free(t); return NULL; } strncpy(t, device, PATH_MAX); if (!strstr(cmd_line, "root=")) { char tmp[PATH_MAX]; snprintf(tmp, sizeof(tmp), "root=/dev/vda%ld rw ", part); strlcat(cmd_line, tmp, size); } return t; }
machine_config::machine_config(const game_driver &gamedrv, emu_options &options) : m_minimum_quantum(attotime::zero) , m_gamedrv(gamedrv) , m_options(options) , m_root_device() , m_default_layouts([] (char const *a, char const *b) { return 0 > std::strcmp(a, b); }) , m_current_device(nullptr) { // add the root device device_add("root", gamedrv.type, 0); // intialize slot devices - make sure that any required devices have been allocated for (device_slot_interface &slot : slot_interface_iterator(root_device())) { device_t &owner = slot.device(); const char *slot_option_name = owner.tag() + 1; // figure out which device goes into this slot bool const has_option = options.has_slot_option(slot_option_name); const char *selval; bool is_default; if (!has_option) { // The only time we should be getting here is when emuopts.cpp is invoking // us to evaluate slot/image options, and the internal state of emuopts.cpp has // not caught up yet selval = slot.default_option(); is_default = true; } else { const slot_option &opt = options.slot_option(slot_option_name); selval = opt.value().c_str(); is_default = !opt.specified(); } if (selval && *selval) { // TODO: make this thing more self-contained so it can apply itself - shouldn't need to know all this here device_slot_interface::slot_option const *option = slot.option(selval); if (option && (is_default || option->selectable())) { // create the device token const tok(begin_configuration(owner)); device_t *const new_dev = device_add(option->name(), option->devtype(), option->clock()); slot.set_card_device(new_dev); char const *const default_bios = option->default_bios(); if (default_bios != nullptr) new_dev->set_default_bios_tag(default_bios); auto additions = option->machine_config(); if (additions) additions(new_dev); input_device_default const *const input_device_defaults = option->input_device_defaults(); if (input_device_defaults) new_dev->set_input_default(input_device_defaults); } else throw emu_fatalerror("Unknown slot option '%s' in slot '%s'", selval, owner.tag()+1); } } // then notify all devices that their configuration is complete for (device_t &device : device_iterator(root_device())) if (!device.configured()) device.config_complete(); }
screen_device *machine_config::first_screen() const { return screen_device_iterator(root_device()).first(); }
void machine_config::remove_references(ATTR_UNUSED device_t &device) { // iterate over all devices and remove any references for (device_t &scan : device_iterator(root_device())) scan.subdevices().m_tagmap.clear(); //remove(&device); }
machine_config::machine_config(const game_driver &gamedrv, emu_options &options) : m_minimum_quantum(attotime::zero), m_watchdog_vblank_count(0), m_watchdog_time(attotime::zero), m_nvram_handler(NULL), m_memcard_handler(NULL), m_video_attributes(0), m_gfxdecodeinfo(NULL), m_total_colors(0), m_default_layout(NULL), m_gamedrv(gamedrv), m_options(options), m_root_device(NULL) { // construct the config (*gamedrv.machine_config)(*this, NULL); bool is_selected_driver = strcmp(gamedrv.name,options.system_name())==0; // intialize slot devices - make sure that any required devices have been allocated slot_interface_iterator slotiter(root_device()); for (device_slot_interface *slot = slotiter.first(); slot != NULL; slot = slotiter.next()) { const slot_interface *intf = slot->get_slot_interfaces(); if (intf != NULL) { device_t &owner = slot->device(); astring temp; const char *selval = options.main_value(temp, owner.tag()+1); bool isdefault = (options.priority(owner.tag()+1)==OPTION_PRIORITY_DEFAULT); if (!is_selected_driver || !options.exists(owner.tag()+1)) selval = slot->get_default_card(); if (selval != NULL && *selval != 0) { bool found = false; for (int i = 0; intf[i].name != NULL; i++) { if (strcmp(selval, intf[i].name) == 0) { if ((!intf[i].internal) || (isdefault && intf[i].internal)) { const char *def = slot->get_default_card(); bool is_default = (def != NULL && strcmp(def, selval) == 0); device_t *new_dev = device_add(&owner, intf[i].name, intf[i].devtype, is_default ? slot->default_clock() : 0); found = true; if (is_default) { device_t::static_set_input_default(*new_dev, slot->input_ports_defaults()); if (slot->default_config()) { device_t::static_set_static_config(*new_dev, slot->default_config()); } } } } } if (!found) throw emu_fatalerror("Unknown slot option '%s' in slot '%s'", selval, owner.tag()+1); } } } // when finished, set the game driver driver_device::static_set_game(*m_root_device, gamedrv); // then notify all devices that their configuration is complete device_iterator iter(root_device()); for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (!device->configured()) device->config_complete(); }
running_machine::running_machine(const machine_config &_config, osd_interface &osd, bool exit_to_game_select) : firstcpu(NULL), primary_screen(NULL), palette(NULL), pens(NULL), colortable(NULL), shadow_table(NULL), debug_flags(0), palette_data(NULL), romload_data(NULL), ui_input_data(NULL), debugcpu_data(NULL), generic_machine_data(NULL), m_config(_config), m_system(_config.gamedrv()), m_osd(osd), m_cheat(NULL), m_render(NULL), m_input(NULL), m_sound(NULL), m_video(NULL), m_tilemap(NULL), m_debug_view(NULL), m_current_phase(MACHINE_PHASE_PREINIT), m_paused(false), m_hard_reset_pending(false), m_exit_pending(false), m_exit_to_game_select(exit_to_game_select), m_new_driver_pending(NULL), m_soft_reset_timer(NULL), m_rand_seed(0x9d14abd7), m_ui_active(_config.options().ui_active()), m_basename(_config.gamedrv().name), m_sample_rate(_config.options().sample_rate()), m_logfile(NULL), m_saveload_schedule(SLS_NONE), m_saveload_schedule_time(attotime::zero), m_saveload_searchpath(NULL), m_logerror_list(m_respool), m_save(*this), m_memory(*this), m_ioport(*this), m_scheduler(*this), m_lua_engine(*this) { memset(gfx, 0, sizeof(gfx)); memset(&m_base_time, 0, sizeof(m_base_time)); // set the machine on all devices device_iterator iter(root_device()); for (device_t *device = iter.first(); device != NULL; device = iter.next()) device->set_machine(*this); // find devices for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (dynamic_cast<cpu_device *>(device) != NULL) { firstcpu = downcast<cpu_device *>(device); break; } screen_device_iterator screeniter(root_device()); primary_screen = screeniter.first(); // fetch core options if (options().debug()) debug_flags = (DEBUG_FLAG_ENABLED | DEBUG_FLAG_CALL_HOOK) | (options().debug_internal() ? 0 : DEBUG_FLAG_OSD_ENABLED); }
void running_machine::postload_all_devices() { device_iterator iter(root_device()); for (device_t *device = iter.first(); device != NULL; device = iter.next()) device->post_load(); }
void running_machine::presave_all_devices() { device_iterator iter(root_device()); for (device_t *device = iter.first(); device != NULL; device = iter.next()) device->pre_save(); }
void running_machine::reset_all_devices() { // reset the root and it will reset children root_device().reset(); }
screen_device *machine_config::first_screen() const { screen_device_iterator iter(root_device()); return iter.first(); }
astring running_machine::get_statename(const char *option) { astring statename_str(""); if (option == NULL || option[0] == 0) statename_str.cpy("%g"); else statename_str.cpy(option); // strip any extension in the provided statename int index = statename_str.rchr(0, '.'); if (index != -1) statename_str.substr(0, index); // handle %d in the template (for image devices) astring statename_dev("%d_"); int pos = statename_str.find(0, statename_dev); if (pos != -1) { // if more %d are found, revert to default and ignore them all if (statename_str.find(pos + 3, statename_dev) != -1) statename_str.cpy("%g"); // else if there is a single %d, try to create the correct snapname else { int name_found = 0; // find length of the device name int end1 = statename_str.find(pos + 3, "/"); int end2 = statename_str.find(pos + 3, "%"); int end = -1; if ((end1 != -1) && (end2 != -1)) end = MIN(end1, end2); else if (end1 != -1) end = end1; else if (end2 != -1) end = end2; else end = statename_str.len(); if (end - pos < 3) fatalerror("Something very wrong is going on!!!\n"); // copy the device name to an astring astring devname_str; devname_str.cpysubstr(statename_str, pos + 3, end - pos - 3); //printf("check template: %s\n", devname_str.cstr()); // verify that there is such a device for this system image_interface_iterator iter(root_device()); for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) { // get the device name astring tempdevname(image->brief_instance_name()); //printf("check device: %s\n", tempdevname.cstr()); if (devname_str.cmp(tempdevname) == 0) { // verify that such a device has an image mounted if (image->basename_noext() != NULL) { astring filename(image->basename_noext()); // setup snapname and remove the %d_ statename_str.replace(0, devname_str, filename); statename_str.del(pos, 3); //printf("check image: %s\n", filename.cstr()); name_found = 1; } } } // or fallback to default if (name_found == 0) statename_str.cpy("%g"); } } // substitute path and gamename up front statename_str.replace(0, "/", PATH_SEPARATOR); statename_str.replace(0, "%g", basename()); return statename_str; }