diff options
127 files changed, 2858 insertions, 2877 deletions
diff --git a/.gitattributes b/.gitattributes index 4f5ee594ad5..465d2826e04 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1616,11 +1616,9 @@ src/lib/libflac/include/protected/stream_decoder.h svneol=native#text/plain src/lib/libflac/include/protected/stream_encoder.h svneol=native#text/plain src/lib/libflac/include/share/alloc.h svneol=native#text/plain src/lib/libflac/include/share/utf8.h svneol=native#text/plain -src/lib/libflac/libflac++.mak svneol=native#text/plain src/lib/libflac/libflac++/metadata.cpp svneol=native#text/plain src/lib/libflac/libflac++/stream_decoder.cpp svneol=native#text/plain src/lib/libflac/libflac++/stream_encoder.cpp svneol=native#text/plain -src/lib/libflac/libflac.mak svneol=native#text/plain src/lib/libflac/libflac/bitmath.c svneol=native#text/plain src/lib/libflac/libflac/bitreader.c svneol=native#text/plain src/lib/libflac/libflac/bitwriter.c svneol=native#text/plain @@ -410,6 +410,10 @@ ifdef USE_NETWORK DEFS += -DUSE_NETWORK endif +# need to ensure FLAC functions are statically linked +DEFS += -DFLAC__NO_DLL + + #------------------------------------------------- # compile flags @@ -634,7 +638,6 @@ all: default tools FLAC_LIB = $(OBJ)/libflac.a $(OBJ)/libflac++.a -FLAC_LIB = $(OBJ)/libflac.a $(OBJ)/libflac++.a #------------------------------------------------- # defines needed by multiple make files diff --git a/src/emu/addrmap.c b/src/emu/addrmap.c index 78f6317ceba..e1bd5d7331e 100644 --- a/src/emu/addrmap.c +++ b/src/emu/addrmap.c @@ -45,29 +45,6 @@ //************************************************************************** //------------------------------------------------- -// set_tag - set the appropriate tag for a device -//------------------------------------------------- - -inline void map_handler_data::set_tag(const device_t &device, const char *tag) -{ - if (strcmp(tag, DEVICE_SELF) == 0) - m_tag = device.tag(); - else if (strcmp(tag, DEVICE_SELF_OWNER) == 0) - { - assert(device.owner() != NULL); - m_tag = device.owner()->tag(); - } - else - m_tag = device.subtag(m_derived_tag, tag); -} - - - -//************************************************************************** -// ADDRESS MAP ENTRY -//************************************************************************** - -//------------------------------------------------- // address_map_entry - constructor //------------------------------------------------- @@ -132,7 +109,7 @@ void address_map_entry::set_mask(offs_t _mask) void address_map_entry::set_read_port(const device_t &device, const char *tag) { m_read.m_type = AMH_PORT; - m_read.set_tag(device, tag); + device.subtag(m_read.m_tag, tag); } @@ -144,7 +121,7 @@ void address_map_entry::set_read_port(const device_t &device, const char *tag) void address_map_entry::set_write_port(const device_t &device, const char *tag) { m_write.m_type = AMH_PORT; - m_write.set_tag(device, tag); + device.subtag(m_write.m_tag, tag); } @@ -156,9 +133,9 @@ void address_map_entry::set_write_port(const device_t &device, const char *tag) void address_map_entry::set_readwrite_port(const device_t &device, const char *tag) { m_read.m_type = AMH_PORT; - m_read.set_tag(device, tag); + device.subtag(m_read.m_tag, tag); m_write.m_type = AMH_PORT; - m_write.set_tag(device, tag); + device.subtag(m_write.m_tag, tag); } @@ -170,7 +147,7 @@ void address_map_entry::set_readwrite_port(const device_t &device, const char *t void address_map_entry::set_read_bank(const device_t &device, const char *tag) { m_read.m_type = AMH_BANK; - m_read.set_tag(device, tag); + device.subtag(m_read.m_tag, tag); } @@ -182,7 +159,7 @@ void address_map_entry::set_read_bank(const device_t &device, const char *tag) void address_map_entry::set_write_bank(const device_t &device, const char *tag) { m_write.m_type = AMH_BANK; - m_write.set_tag(device, tag); + device.subtag(m_write.m_tag, tag); } @@ -194,9 +171,9 @@ void address_map_entry::set_write_bank(const device_t &device, const char *tag) void address_map_entry::set_readwrite_bank(const device_t &device, const char *tag) { m_read.m_type = AMH_BANK; - m_read.set_tag(device, tag); + device.subtag(m_read.m_tag, tag); m_write.m_type = AMH_BANK; - m_write.set_tag(device, tag); + device.subtag(m_write.m_tag, tag); } @@ -213,10 +190,10 @@ void address_map_entry::set_submap(const device_t &device, const char *tag, addr assert(unitmask_is_appropriate(bits, mask, func.name())); m_read.m_type = AMH_DEVICE_SUBMAP; - m_read.set_tag(device, tag); + device.subtag(m_read.m_tag, tag); m_read.m_mask = mask; m_write.m_type = AMH_DEVICE_SUBMAP; - m_write.set_tag(device, tag); + device.subtag(m_write.m_tag, tag); m_write.m_mask = mask; m_submap_delegate = func; m_submap_bits = bits; @@ -267,7 +244,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_read.m_bits = 8; m_read.m_mask = unitmask; m_read.m_name = string; - m_read.set_tag(device, tag); + device.subtag(m_read.m_tag, tag); m_rdevice8 = func; } @@ -280,7 +257,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_write.m_bits = 8; m_write.m_mask = unitmask; m_write.m_name = string; - m_write.set_tag(device, tag); + device.subtag(m_write.m_tag, tag); m_wdevice8 = func; } @@ -300,7 +277,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_read.m_bits = 8; m_read.m_mask = unitmask; m_read.m_name = func.name(); - m_read.set_tag(device, tag); + device.subtag(m_read.m_tag, tag); m_rproto8 = func; } @@ -313,7 +290,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_write.m_bits = 8; m_write.m_mask = unitmask; m_write.m_name = func.name(); - m_write.set_tag(device, tag); + device.subtag(m_write.m_tag, tag); m_wproto8 = func; } @@ -369,7 +346,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_read.m_bits = 16; m_read.m_mask = unitmask; m_read.m_name = string; - m_read.set_tag(device, tag); + device.subtag(m_read.m_tag, tag); m_rdevice16 = func; } @@ -382,7 +359,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_write.m_bits = 16; m_write.m_mask = unitmask; m_write.m_name = string; - m_write.set_tag(device, tag); + device.subtag(m_write.m_tag, tag); m_wdevice16 = func; } @@ -402,7 +379,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_read.m_bits = 16; m_read.m_mask = unitmask; m_read.m_name = func.name(); - m_read.set_tag(device, tag); + device.subtag(m_read.m_tag, tag); m_rproto16 = func; } @@ -415,7 +392,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_write.m_bits = 16; m_write.m_mask = unitmask; m_write.m_name = func.name(); - m_write.set_tag(device, tag); + device.subtag(m_write.m_tag, tag); m_wproto16 = func; } @@ -471,7 +448,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_read.m_bits = 32; m_read.m_mask = unitmask; m_read.m_name = string; - m_read.set_tag(device, tag); + device.subtag(m_read.m_tag, tag); m_rdevice32 = func; } @@ -484,7 +461,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_write.m_bits = 32; m_write.m_mask = unitmask; m_write.m_name = string; - m_write.set_tag(device, tag); + device.subtag(m_write.m_tag, tag); m_wdevice32 = func; } @@ -504,7 +481,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_read.m_bits = 32; m_read.m_mask = unitmask; m_read.m_name = func.name(); - m_read.set_tag(device, tag); + device.subtag(m_read.m_tag, tag); m_rproto32 = func; } @@ -517,7 +494,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_write.m_bits = 32; m_write.m_mask = unitmask; m_write.m_name = func.name(); - m_write.set_tag(device, tag); + device.subtag(m_write.m_tag, tag); m_wproto32 = func; } @@ -573,7 +550,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_read.m_bits = 64; m_read.m_mask = 0; m_read.m_name = string; - m_read.set_tag(device, tag); + device.subtag(m_read.m_tag, tag); m_rdevice64 = func; } @@ -586,7 +563,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_write.m_bits = 64; m_write.m_mask = 0; m_write.m_name = string; - m_write.set_tag(device, tag); + device.subtag(m_write.m_tag, tag); m_wdevice64 = func; } @@ -606,7 +583,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_read.m_bits = 64; m_read.m_mask = 0; m_read.m_name = func.name(); - m_read.set_tag(device, tag); + device.subtag(m_read.m_tag, tag); m_rproto64 = func; } @@ -619,7 +596,7 @@ void address_map_entry::internal_set_handler(const device_t &device, const char m_write.m_bits = 64; m_write.m_mask = 0; m_write.m_name = func.name(); - m_write.set_tag(device, tag); + device.subtag(m_write.m_tag, tag); m_wproto64 = func; } diff --git a/src/emu/addrmap.h b/src/emu/addrmap.h index fb82b2aa769..af1eae23b04 100644 --- a/src/emu/addrmap.h +++ b/src/emu/addrmap.h @@ -85,17 +85,13 @@ public: : m_type(AMH_NONE), m_bits(0), m_mask(0), - m_name(NULL), - m_tag(NULL) { } + m_name(NULL) { } map_handler_type m_type; // type of the handler UINT8 m_bits; // width of the handler in bits, or 0 for default UINT64 m_mask; // mask for which lanes apply const char * m_name; // name of the handler - const char * m_tag; // tag pointing to a reference - astring m_derived_tag; // string used to hold derived names - - void set_tag(const device_t &device, const char *tag); + astring m_tag; // path to the target tag }; diff --git a/src/emu/audit.c b/src/emu/audit.c index 345baccc9e0..bfc4466d977 100644 --- a/src/emu/audit.c +++ b/src/emu/audit.c @@ -76,7 +76,7 @@ media_auditor::summary media_auditor::audit_media(const char *validation) // temporary hack until romload is update: get the driver path and support it for // all searches -const char *driverpath = m_enumerator.config().devicelist().find("root")->searchpath(); +const char *driverpath = m_enumerator.config().root_device().searchpath(); // iterate over ROM sources and regions int found = 0; @@ -234,49 +234,49 @@ media_auditor::summary media_auditor::audit_samples() int found = 0; // iterate over sample entries - for (const device_t *device = m_enumerator.config().first_device(); device != NULL; device = device->next()) - if (device->type() == SAMPLES) + samples_device_iterator iter(m_enumerator.config().root_device()); + for (samples_device *device = iter.first(); device != NULL; device = iter.next()) + { + const samples_interface *intf = reinterpret_cast<const samples_interface *>(device->static_config()); + if (intf->samplenames != NULL) { - const samples_interface *intf = reinterpret_cast<const samples_interface *>(device->static_config()); - if (intf->samplenames != NULL) - { - // by default we just search using the driver name - astring searchpath(m_enumerator.driver().name); + // by default we just search using the driver name + astring searchpath(m_enumerator.driver().name); - // iterate over samples in this entry - for (int sampnum = 0; intf->samplenames[sampnum] != NULL; sampnum++) + // iterate over samples in this entry + for (int sampnum = 0; intf->samplenames[sampnum] != NULL; sampnum++) + { + // starred entries indicate an additional searchpath + if (intf->samplenames[sampnum][0] == '*') { - // starred entries indicate an additional searchpath - if (intf->samplenames[sampnum][0] == '*') - { - searchpath.cat(";").cat(&intf->samplenames[sampnum][1]); - continue; - } + searchpath.cat(";").cat(&intf->samplenames[sampnum][1]); + continue; + } - required++; + required++; - // create a new record - audit_record &record = m_record_list.append(*global_alloc(audit_record(intf->samplenames[sampnum], audit_record::MEDIA_SAMPLE))); + // create a new record + audit_record &record = m_record_list.append(*global_alloc(audit_record(intf->samplenames[sampnum], audit_record::MEDIA_SAMPLE))); - // look for the files - emu_file file(m_enumerator.options().sample_path(), OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD); - path_iterator path(searchpath); - astring curpath; - while (path.next(curpath, intf->samplenames[sampnum])) + // look for the files + emu_file file(m_enumerator.options().sample_path(), OPEN_FLAG_READ | OPEN_FLAG_NO_PRELOAD); + path_iterator path(searchpath); + astring curpath; + while (path.next(curpath, intf->samplenames[sampnum])) + { + // attempt to access the file + file_error filerr = file.open(curpath); + if (filerr == FILERR_NONE) { - // attempt to access the file - file_error filerr = file.open(curpath); - if (filerr == FILERR_NONE) - { - record.set_status(audit_record::STATUS_GOOD, audit_record::SUBSTATUS_GOOD); - found++; - } - else - record.set_status(audit_record::STATUS_NOT_FOUND, audit_record::SUBSTATUS_NOT_FOUND); + record.set_status(audit_record::STATUS_GOOD, audit_record::SUBSTATUS_GOOD); + found++; } + else + record.set_status(audit_record::STATUS_NOT_FOUND, audit_record::SUBSTATUS_NOT_FOUND); } } } + } if (found == 0 && required > 0) { diff --git a/src/emu/cheat.c b/src/emu/cheat.c index e058398717f..d9939bc2f93 100644 --- a/src/emu/cheat.c +++ b/src/emu/cheat.c @@ -1174,8 +1174,8 @@ void cheat_manager::reload() // load the cheat file, MESS will load a crc32.xml ( eg. 01234567.xml ) // and MAME will load gamename.xml - device_image_interface *image = NULL; - for (bool gotone = machine().devicelist().first(image); gotone; gotone = image->next(image)) + image_interface_iterator iter(machine().root_device()); + for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) if (image->exists()) { // if we are loading through software lists, try to load shortname.xml diff --git a/src/emu/clifront.c b/src/emu/clifront.c index 00bc2dde8bf..c7339c078ff 100644 --- a/src/emu/clifront.c +++ b/src/emu/clifront.c @@ -183,14 +183,14 @@ int cli_frontend::execute(int argc, char **argv) if (strlen(m_options.software_name()) > 0) { machine_config config(*system, m_options); - if (!config.devicelist().first(SOFTWARE_LIST)) + software_list_device_iterator iter(config.root_device()); + if (iter.first() == NULL) throw emu_fatalerror(MAMERR_FATALERROR, "Error: unknown option: %s\n", m_options.software_name()); bool found = FALSE; - for (device_t *swlists = config.devicelist().first(SOFTWARE_LIST); swlists != NULL; swlists = swlists->typenext()) + for (software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next()) { - software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(swlists)->inline_config(); - software_list *list = software_list_open(m_options, swlist->list_name, FALSE, NULL); + software_list *list = software_list_open(m_options, swlist->list_name(), FALSE, NULL); if (list) { software_info *swinfo = software_list_find(list, m_options.software_name(), NULL); @@ -205,8 +205,8 @@ int cli_frontend::execute(int argc, char **argv) if (mount == NULL || strcmp(mount,"no") != 0) { // search for an image device with the right interface - const device_image_interface *image = NULL; - for (bool gotone = config.devicelist().first(image); gotone; gotone = image->next(image)) + image_interface_iterator imgiter(config.root_device()); + for (device_image_interface *image = imgiter.first(); image != NULL; image = imgiter.next()) { const char *interface = image->image_interface(); if (interface != NULL) @@ -218,7 +218,7 @@ int cli_frontend::execute(int argc, char **argv) if (strlen(option) == 0) { astring val; - val.printf("%s:%s:%s",swlist->list_name,m_options.software_name(),swpart->name); + val.printf("%s:%s:%s",swlist->list_name(),m_options.software_name(),swpart->name); // call this in order to set slot devices according to mounting m_options.parse_slot_devices(argc, argv, option_errors, image->instance_name(), val.cstr()); break; @@ -238,7 +238,7 @@ int cli_frontend::execute(int argc, char **argv) } if (!found) { - software_display_matches(config.devicelist(),m_options, NULL,m_options.software_name()); + software_display_matches(config,m_options, NULL,m_options.software_name()); throw emu_fatalerror(MAMERR_FATALERROR, ""); } } @@ -551,11 +551,8 @@ void cli_frontend::listsamples(const char *gamename) while (drivlist.next()) { // see if we have samples - const device_t *device; - for (device = drivlist.config().first_device(); device != NULL; device = device->next()) - if (device->type() == SAMPLES) - break; - if (device == NULL) + samples_device_iterator iter(drivlist.config().root_device()); + if (iter.first() == NULL) continue; // print a header @@ -565,16 +562,15 @@ void cli_frontend::listsamples(const char *gamename) mame_printf_info("Samples required for driver \"%s\".\n", drivlist.driver().name); // iterate over samples devices - for ( ; device != NULL; device = device->next()) - if (device->type() == SAMPLES) - { - // if the list is legit, walk it and print the sample info - const char *const *samplenames = reinterpret_cast<const samples_interface *>(device->static_config())->samplenames; - if (samplenames != NULL) - for (int sampnum = 0; samplenames[sampnum] != NULL; sampnum++) - if (samplenames[sampnum][0] != '*') - mame_printf_info("%s\n", samplenames[sampnum]); - } + for (samples_device *device = iter.first(); device != NULL; device = iter.next()) + { + // if the list is legit, walk it and print the sample info + const char *const *samplenames = reinterpret_cast<const samples_interface *>(device->static_config())->samplenames; + if (samplenames != NULL) + for (int sampnum = 0; samplenames[sampnum] != NULL; sampnum++) + if (samplenames[sampnum][0] != '*') + mame_printf_info("%s\n", samplenames[sampnum]); + } } } @@ -602,7 +598,8 @@ void cli_frontend::listdevices(const char *gamename) printf("Driver %s (%s):\n", drivlist.driver().name, drivlist.driver().description); // iterate through devices - for (const device_t *device = drivlist.config().first_device(); device != NULL; device = device->next()) + device_iterator iter(drivlist.config().root_device()); + for (const device_t *device = iter.first(); device != NULL; device = iter.next()) { printf(" %s ('%s')", device->name(), device->tag()); @@ -642,9 +639,9 @@ void cli_frontend::listslots(const char *gamename) while (drivlist.next()) { // iterate - const device_slot_interface *slot = NULL; + slot_interface_iterator iter(drivlist.config().root_device()); bool first = true; - for (bool gotone = drivlist.config().devicelist().first(slot); gotone; gotone = slot->next(slot)) + for (const device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next()) { // output the line, up to the list of extensions printf("%-13s%-10s ", first ? drivlist.driver().name : "", slot->device().tag()); @@ -653,7 +650,7 @@ void cli_frontend::listslots(const char *gamename) const slot_interface* intf = slot->get_slot_interfaces(); for (int i = 0; intf[i].name != NULL; i++) { - device_t *dev = (*intf[i].devtype)(drivlist.config(), "dummy", drivlist.config().devicelist().first(), 0); + device_t *dev = (*intf[i].devtype)(drivlist.config(), "dummy", &drivlist.config().root_device(), 0); dev->config_complete(); if (i==0) { printf("%-15s %s\n", intf[i].name,dev->name()); @@ -694,9 +691,9 @@ void cli_frontend::listmedia(const char *gamename) while (drivlist.next()) { // iterate - const device_image_interface *imagedev = NULL; + image_interface_iterator iter(drivlist.config().root_device()); bool first = true; - for (bool gotone = drivlist.config().devicelist().first(imagedev); gotone; gotone = imagedev->next(imagedev)) + for (const device_image_interface *imagedev = iter.first(); imagedev != NULL; imagedev = iter.next()) { // extract the shortname with parentheses astring paren_shortname; @@ -798,7 +795,7 @@ void cli_frontend::verifyroms(const char *gamename) driver_enumerator dummy_drivlist(m_options); dummy_drivlist.next(); machine_config &config = dummy_drivlist.config(); - device_t *owner = config.devicelist().first(); + device_t *owner = &config.root_device(); // check if all are listed, note that empty one is included for (int i = 0; i < m_device_count; i++) { @@ -994,12 +991,12 @@ void cli_frontend::listsoftware(const char *gamename) // first determine the maximum number of lists we might encounter int list_count = 0; while (drivlist.next()) - for (const device_t *dev = drivlist.config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) - { - software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config(); - if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM) + { + software_list_device_iterator iter(drivlist.config().root_device()); + for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next()) + if (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) list_count++; - } + } // allocate a list astring *lists = global_alloc_array(astring, list_count); @@ -1079,28 +1076,28 @@ void cli_frontend::listsoftware(const char *gamename) drivlist.reset(); list_count = 0; while (drivlist.next()) - for (const device_t *dev = drivlist.config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) + { + software_list_device_iterator iter(drivlist.config().root_device()); + for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next()) { - software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config(); - - if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM) + if (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) { - software_list *list = software_list_open(m_options, swlist->list_name, FALSE, NULL); + software_list *list = software_list_open(m_options, swlist->list_name(), FALSE, NULL); if ( list ) { /* Verify if we have encountered this list before */ bool seen_before = false; for (int seen_index = 0; seen_index < list_count && !seen_before; seen_index++) - if (lists[seen_index] == swlist->list_name) + if (lists[seen_index] == swlist->list_name()) seen_before = true; if (!seen_before) { - lists[list_count++] = swlist->list_name; + lists[list_count++] = swlist->list_name(); software_list_parse( list, NULL, NULL ); - fprintf(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlist->list_name, xml_normalize_string(software_list_get_description(list)) ); + fprintf(out, "\t<softwarelist name=\"%s\" description=\"%s\">\n", swlist->list_name(), xml_normalize_string(software_list_get_description(list)) ); for ( software_info *swinfo = software_list_find( list, "*", NULL ); swinfo != NULL; swinfo = software_list_find( list, "*", swinfo ) ) { @@ -1239,6 +1236,7 @@ void cli_frontend::listsoftware(const char *gamename) } } } + } if (list_count > 0) fprintf( out, "</softwarelists>\n" ); @@ -1300,8 +1298,8 @@ void cli_frontend::execute_commands(const char *exename) // validate? if (strcmp(m_options.command(), CLICOMMAND_VALIDATE) == 0) { - validate_drivers(m_options); - validate_softlists(m_options); + validity_checker valid(m_options); + valid.check_all(); return; } @@ -1634,10 +1632,10 @@ int media_identifier::find_by_hash(const hash_collection &hashes, int length) } // next iterate over softlists - for (const device_t *dev = m_drivlist.config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) + software_list_device_iterator iter(m_drivlist.config().root_device()); + for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next()) { - software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config(); - software_list *list = software_list_open(m_drivlist.options(), swlist->list_name, FALSE, NULL); + software_list *list = software_list_open(m_drivlist.options(), swlist->list_name(), FALSE, NULL); for (software_info *swinfo = software_list_find(list, "*", NULL); swinfo != NULL; swinfo = software_list_find(list, "*", swinfo)) for (software_part *part = software_find_part(swinfo, NULL, NULL); part != NULL; part = software_part_next(part)) @@ -1652,7 +1650,7 @@ int media_identifier::find_by_hash(const hash_collection &hashes, int length) // output information about the match if (found) mame_printf_info(" "); - mame_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlist->list_name, swinfo->shortname, swinfo->longname); + mame_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlist->list_name(), swinfo->shortname, swinfo->longname); found++; } } diff --git a/src/emu/cpu/psx/psx.c b/src/emu/cpu/psx/psx.c index e743ca4ec1e..0795b2180bc 100644 --- a/src/emu/cpu/psx/psx.c +++ b/src/emu/cpu/psx/psx.c @@ -3158,29 +3158,24 @@ void psxcpu_device::setcp3cr( int reg, UINT32 value ) psxcpu_device *psxcpu_device::getcpu( device_t &device, const char *cputag ) { - if( strcmp( cputag, DEVICE_SELF ) == 0 ) - { - return downcast<psxcpu_device *>( &device ); - } - - return downcast<psxcpu_device *>( device.siblingdevice( cputag ) ); + return downcast<psxcpu_device *>( device.subdevice( cputag ) ); } void psxcpu_device::irq_set( device_t &device, const char *cputag, UINT32 bitmask ) { - psxirq_device *irq = downcast<psxirq_device *>( getcpu( device, cputag )->subdevice("irq") ); + psxirq_device *irq = getcpu( device, cputag )->subdevice<psxirq_device>("irq"); irq->set( bitmask ); } void psxcpu_device::install_sio_handler( device_t &device, const char *cputag, int n_port, psx_sio_handler p_f_sio_handler ) { - psxsio_device *sio = downcast<psxsio_device *>( getcpu( device, cputag )->subdevice("sio") ); + psxsio_device *sio = getcpu( device, cputag )->subdevice<psxsio_device>("sio"); sio->install_handler( n_port, p_f_sio_handler ); } void psxcpu_device::sio_input( device_t &device, const char *cputag, int n_port, int n_mask, int n_data ) { - psxsio_device *sio = downcast<psxsio_device *>( getcpu( device, cputag )->subdevice("sio") ); + psxsio_device *sio = getcpu( device, cputag )->subdevice<psxsio_device>("sio"); sio->input( n_port, n_mask, n_data ); } diff --git a/src/emu/cpu/psx/psx.h b/src/emu/cpu/psx/psx.h index 6b5e9349daf..6c984186f5f 100644 --- a/src/emu/cpu/psx/psx.h +++ b/src/emu/cpu/psx/psx.h @@ -105,10 +105,10 @@ enum //************************************************************************** #define MCFG_PSX_DMA_CHANNEL_READ( cputag, channel, handler ) \ - downcast<psxdma_device *>( psxcpu_device::getcpu( *owner, cputag )->subdevice("dma") )->install_read_handler( channel, handler ); + psxcpu_device::getcpu( *owner, cputag )->subdevice<psxdma_device>("dma")->install_read_handler( channel, handler ); #define MCFG_PSX_DMA_CHANNEL_WRITE( cputag, channel, handler ) \ - downcast<psxdma_device *>( psxcpu_device::getcpu( *owner, cputag )->subdevice("dma") )->install_write_handler( channel, handler ); + psxcpu_device::getcpu( *owner, cputag )->subdevice<psxdma_device>("dma")->install_write_handler( channel, handler ); diff --git a/src/emu/cpu/tms34010/tms34010.c b/src/emu/cpu/tms34010/tms34010.c index 36252211cb4..e6068214e2d 100644 --- a/src/emu/cpu/tms34010/tms34010.c +++ b/src/emu/cpu/tms34010/tms34010.c @@ -1087,7 +1087,8 @@ SCREEN_UPDATE_IND16( tms340x0_ind16 ) int x; /* find the owning CPU */ - for (cpu = screen.machine().devicelist().first(); cpu != NULL; cpu = cpu->next()) + device_iterator iter(screen.machine().root_device()); + for (cpu = iter.first(); cpu != NULL; cpu = iter.next()) { device_type type = cpu->type(); if (type == TMS34010 || type == TMS34020) @@ -1135,7 +1136,8 @@ SCREEN_UPDATE_RGB32( tms340x0_rgb32 ) int x; /* find the owning CPU */ - for (cpu = screen.machine().devicelist().first(); cpu != NULL; cpu = cpu->next()) + device_iterator iter(screen.machine().root_device()); + for (cpu = iter.first(); cpu != NULL; cpu = iter.next()) { device_type type = cpu->type(); if (type == TMS34010 || type == TMS34020) diff --git a/src/emu/debug/debugcmd.c b/src/emu/debug/debugcmd.c index 5f5606f1968..4711418c06d 100644 --- a/src/emu/debug/debugcmd.c +++ b/src/emu/debug/debugcmd.c @@ -391,7 +391,8 @@ void debug_command_init(running_machine &machine) static void debug_command_exit(running_machine &machine) { /* turn off all traces */ - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + device_iterator iter(machine.root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) device->debug()->trace(NULL, 0, NULL); if (cheat.length) @@ -545,8 +546,8 @@ int debug_command_parameter_cpu(running_machine &machine, const char *param, dev } /* if we got a valid one, return */ - device_execute_interface *exec = NULL; - for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec)) + execute_interface_iterator iter(machine.root_device()); + for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next()) if (cpunum-- == 0) { *result = &exec->device(); @@ -982,8 +983,8 @@ static void execute_focus(running_machine &machine, int ref, int params, const c cpu->debug()->ignore(false); /* then loop over CPUs and set the ignore flags on all other CPUs */ - device_execute_interface *exec = NULL; - for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec)) + execute_interface_iterator iter(machine.root_device()); + for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next()) if (&exec->device() != cpu) exec->device().debug()->ignore(true); debug_console_printf(machine, "Now focused on CPU '%s'\n", cpu->tag()); @@ -1002,8 +1003,8 @@ static void execute_ignore(running_machine &machine, int ref, int params, const astring buffer; /* loop over all executable devices */ - device_execute_interface *exec = NULL; - for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec)) + execute_interface_iterator iter(machine.root_device()); + for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next()) /* build up a comma-separated list */ if (!exec->device().debug()->observing()) @@ -1034,11 +1035,14 @@ static void execute_ignore(running_machine &machine, int ref, int params, const for (int paramnum = 0; paramnum < params; paramnum++) { /* make sure this isn't the last live CPU */ - device_execute_interface *exec = NULL; - bool gotone; - for (gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec)) + execute_interface_iterator iter(machine.root_device()); + bool gotone = false; + for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next()) if (&exec->device() != devicelist[paramnum] && exec->device().debug()->observing()) + { + gotone = true; break; + } if (!gotone) { debug_console_printf(machine, "Can't ignore all devices!\n"); @@ -1064,8 +1068,8 @@ static void execute_observe(running_machine &machine, int ref, int params, const astring buffer; /* loop over all executable devices */ - device_execute_interface *exec = NULL; - for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec)) + execute_interface_iterator iter(machine.root_device()); + for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next()) /* build up a comma-separated list */ if (exec->device().debug()->observing()) @@ -1214,7 +1218,8 @@ static void execute_bpclear(running_machine &machine, int ref, int params, const /* if 0 parameters, clear all */ if (params == 0) { - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + device_iterator iter(machine.root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) device->debug()->breakpoint_clear_all(); debug_console_printf(machine, "Cleared all breakpoints\n"); } @@ -1224,8 +1229,9 @@ static void execute_bpclear(running_machine &machine, int ref, int params, const return; else { + device_iterator iter(machine.root_device()); bool found = false; - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (device->debug()->breakpoint_clear(bpindex)) found = true; if (found) @@ -1248,7 +1254,8 @@ static void execute_bpdisenable(running_machine &machine, int ref, int params, c /* if 0 parameters, clear all */ if (params == 0) { - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + device_iterator iter(machine.root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) device->debug()->breakpoint_enable_all(ref); if (ref == 0) debug_console_printf(machine, "Disabled all breakpoints\n"); @@ -1261,8 +1268,9 @@ static void execute_bpdisenable(running_machine &machine, int ref, int params, c return; else { + device_iterator iter(machine.root_device()); bool found = false; - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (device->debug()->breakpoint_enable(bpindex, ref)) found = true; if (found) @@ -1284,7 +1292,8 @@ static void execute_bplist(running_machine &machine, int ref, int params, const astring buffer; /* loop over all CPUs */ - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + device_iterator iter(machine.root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (device->debug()->breakpoint_first() != NULL) { debug_console_printf(machine, "Device '%s' breakpoints:\n", device->tag()); @@ -1372,7 +1381,8 @@ static void execute_wpclear(running_machine &machine, int ref, int params, const /* if 0 parameters, clear all */ if (params == 0) { - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + device_iterator iter(machine.root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) device->debug()->watchpoint_clear_all(); debug_console_printf(machine, "Cleared all watchpoints\n"); } @@ -1382,8 +1392,9 @@ static void execute_wpclear(running_machine &machine, int ref, int params, const return; else { + device_iterator iter(machine.root_device()); bool found = false; - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (device->debug()->watchpoint_clear(wpindex)) found = true; if (found) @@ -1406,7 +1417,8 @@ static void execute_wpdisenable(running_machine &machine, int ref, int params, c /* if 0 parameters, clear all */ if (params == 0) { - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + device_iterator iter(machine.root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) device->debug()->watchpoint_enable_all(ref); if (ref == 0) debug_console_printf(machine, "Disabled all watchpoints\n"); @@ -1419,8 +1431,9 @@ static void execute_wpdisenable(running_machine &machine, int ref, int params, c return; else { + device_iterator iter(machine.root_device()); bool found = false; - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (device->debug()->watchpoint_enable(wpindex, ref)) found = true; if (found) @@ -1442,7 +1455,8 @@ static void execute_wplist(running_machine &machine, int ref, int params, const astring buffer; /* loop over all CPUs */ - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + device_iterator iter(machine.root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++) if (device->debug()->watchpoint_first(spacenum) != NULL) { @@ -1484,7 +1498,8 @@ static void execute_hotspot(running_machine &machine, int ref, int params, const bool cleared = false; /* loop over CPUs and find live spots */ - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + device_iterator iter(machine.root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (device->debug()->hotspot_tracking_enabled()) { device->debug()->hotspot_track(0, 0); @@ -2498,7 +2513,8 @@ static void execute_snap(running_machine &machine, int ref, int params, const ch const char *filename = param[0]; int scrnum = (params > 1) ? atoi(param[1]) : 0; - screen_device *screen = downcast<screen_device *>(machine.devicelist().find(SCREEN, scrnum)); + screen_device_iterator iter(machine.root_device()); + screen_device *screen = iter.byindex(scrnum); if ((screen == NULL) || !machine.render().is_live(*screen)) { @@ -2682,12 +2698,12 @@ static void execute_hardreset(running_machine &machine, int ref, int params, con static void execute_images(running_machine &machine, int ref, int params, const char **param) { - device_image_interface *img = NULL; - for (bool gotone = machine.devicelist().first(img); gotone; gotone = img->next(img)) + image_interface_iterator iter(machine.root_device()); + for (device_image_interface *img = iter.first(); img != NULL; img = iter.next()) { debug_console_printf(machine, "%s: %s\n",img->brief_instance_name(),img->exists() ? img->filename() : "[empty slot]"); } - if (!machine.devicelist().first(img)) { + if (iter.first() == NULL) { debug_console_printf(machine, "No image devices in this driver\n"); } } @@ -2698,9 +2714,9 @@ static void execute_images(running_machine &machine, int ref, int params, const static void execute_mount(running_machine &machine, int ref, int params, const char **param) { - device_image_interface *img = NULL; + image_interface_iterator iter(machine.root_device()); bool done = false; - for (bool gotone = machine.devicelist().first(img); gotone; gotone = img->next(img)) + for (device_image_interface *img = iter.first(); img != NULL; img = iter.next()) { if (strcmp(img->brief_instance_name(),param[0])==0) { if (img->load(param[1])==IMAGE_INIT_FAIL) { @@ -2722,9 +2738,9 @@ static void execute_mount(running_machine &machine, int ref, int params, const c static void execute_unmount(running_machine &machine, int ref, int params, const char **param) { - device_image_interface *img = NULL; + image_interface_iterator iter(machine.root_device()); bool done = false; - for (bool gotone = machine.devicelist().first(img); gotone; gotone = img->next(img)) + for (device_image_interface *img = iter.first(); img != NULL; img = iter.next()) { if (strcmp(img->brief_instance_name(),param[0])==0) { img->unload(); diff --git a/src/emu/debug/debugcpu.c b/src/emu/debug/debugcpu.c index c4a092dd160..9e46112abf6 100644 --- a/src/emu/debug/debugcpu.c +++ b/src/emu/debug/debugcpu.c @@ -201,7 +201,8 @@ void debug_cpu_flush_traces(running_machine &machine) { /* this can be called on exit even when no debugging is enabled, so make sure the devdebug is valid before proceeding */ - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + device_iterator iter(machine.root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (device->debug() != NULL) device->debug()->trace_flush(); } @@ -337,8 +338,9 @@ bool debug_comment_save(running_machine &machine) xml_set_attribute(systemnode, "name", machine.system().name); // for each device + device_iterator iter(machine.root_device()); bool found_comments = false; - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (device->debug()->comment_count() > 0) { // create a node for this device @@ -1081,7 +1083,8 @@ static void on_vblank(running_machine &machine, screen_device &device, bool vbla static void reset_transient_flags(running_machine &machine) { /* loop over CPUs and reset the transient flags */ - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + device_iterator iter(machine.root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) device->debug()->reset_transient_flag(); machine.debugcpu_data->m_stop_when_not_device = NULL; } @@ -1144,9 +1147,8 @@ static void process_source_file(running_machine &machine) static device_t *expression_get_device(running_machine &machine, const char *tag) { - device_t *device; - - for (device = machine.devicelist().first(); device != NULL; device = device->next()) + device_iterator iter(machine.root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (mame_stricmp(device->tag(), tag) == 0) return device; @@ -1630,15 +1632,8 @@ static UINT64 get_cpunum(symbol_table &table, void *ref) running_machine &machine = *reinterpret_cast<running_machine *>(table.globalref()); device_t *target = machine.debugcpu_data->visiblecpu; - device_execute_interface *exec = NULL; - int index = 0; - for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec)) - { - if (&exec->device() == target) - return index; - index++; - } - return 0; + execute_interface_iterator iter(machine.root_device()); + return iter.indexof(target->execute()); } diff --git a/src/emu/debug/dvdisasm.c b/src/emu/debug/dvdisasm.c index ac3a89a8803..a8041abc168 100644 --- a/src/emu/debug/dvdisasm.c +++ b/src/emu/debug/dvdisasm.c @@ -132,9 +132,9 @@ void debug_view_disasm::enumerate_sources() m_source_list.reset(); // iterate over devices with disassembly interfaces - device_disasm_interface *dasm = NULL; + disasm_interface_iterator iter(machine().root_device()); astring name; - for (bool gotone = machine().devicelist().first(dasm); gotone; gotone = dasm->next(dasm)) + for (device_disasm_interface *dasm = iter.first(); dasm != NULL; dasm = iter.next()) { name.printf("%s '%s'", dasm->device().name(), dasm->device().tag()); m_source_list.append(*auto_alloc(machine(), debug_view_disasm_source(name, dasm->device()))); diff --git a/src/emu/debug/dvmemory.c b/src/emu/debug/dvmemory.c index a1d4d88f9f8..779e10f256d 100644 --- a/src/emu/debug/dvmemory.c +++ b/src/emu/debug/dvmemory.c @@ -152,8 +152,8 @@ void debug_view_memory::enumerate_sources() astring name; // first add all the devices' address spaces - device_memory_interface *memintf = NULL; - for (bool gotone = machine().devicelist().first(memintf); gotone; gotone = memintf->next(memintf)) + memory_interface_iterator iter(machine().root_device()); + for (device_memory_interface *memintf = iter.first(); memintf != NULL; memintf = iter.next()) for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++) { address_space *space = memintf->space(spacenum); diff --git a/src/emu/debug/dvstate.c b/src/emu/debug/dvstate.c index 9d14f1c83d8..5cbd08091eb 100644 --- a/src/emu/debug/dvstate.c +++ b/src/emu/debug/dvstate.c @@ -103,9 +103,9 @@ void debug_view_state::enumerate_sources() m_source_list.reset(); // iterate over devices that have state interfaces - device_state_interface *state = NULL; + state_interface_iterator iter(machine().root_device()); astring name; - for (bool gotone = machine().devicelist().first(state); gotone; gotone = state->next(state)) + for (device_state_interface *state = iter.first(); state != NULL; state = iter.next()) { name.printf("%s '%s'", state->device().name(), state->device().tag()); m_source_list.append(*auto_alloc(machine(), debug_view_state_source(name, state->device()))); diff --git a/src/emu/devcb.c b/src/emu/devcb.c index 03c18f75c52..089dcd3388b 100644 --- a/src/emu/devcb.c +++ b/src/emu/devcb.c @@ -96,17 +96,7 @@ const input_port_config *devcb_resolver::resolve_port(const char *tag, device_t device_t *devcb_resolver::resolve_device(int index, const char *tag, device_t ¤t) { - device_t *result = NULL; - - if (index == DEVCB_DEVICE_SELF) - result = ¤t; - else if (index == DEVCB_DEVICE_DRIVER) - result = current.machine().driver_data(); - else if (strcmp(tag, DEVICE_SELF_OWNER) == 0) - result = current.owner(); - else - result = current.siblingdevice(tag); - + device_t *result = current.siblingdevice(tag); if (result == NULL) throw emu_fatalerror("Unable to resolve device '%s' (requested by callback to %s '%s')", tag, current.name(), current.tag()); return result; diff --git a/src/emu/devcb.h b/src/emu/devcb.h index 6ce7c70ca3f..cbb39d4feb9 100644 --- a/src/emu/devcb.h +++ b/src/emu/devcb.h @@ -93,14 +93,6 @@ enum DEVCB_TYPE_CONSTANT // constant value read }; -// for DEVCB_TYPE_DEVICE, some further differentiation -enum -{ - DEVCB_DEVICE_SELF, // ignore 'tag', refers to the device itself - DEVCB_DEVICE_DRIVER, // ignore 'tag', refers to the driver device - DEVCB_DEVICE_OTHER // device specified by 'tag' -}; - //************************************************************************** @@ -158,20 +150,20 @@ void devcb_stub16(device_t *device, offs_t offset, UINT16 data) #define DEVCB_NULL { DEVCB_TYPE_NULL } // standard line or read/write handlers with the calling device passed -#define DEVCB_LINE(func) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_SELF, NULL, #func, func, NULL, NULL } -#define DEVCB_LINE_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_SELF, NULL, #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL, NULL } -#define DEVCB_HANDLER(func) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_SELF, NULL, #func, NULL, func, NULL } -#define DEVCB_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_SELF, NULL, #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL } +#define DEVCB_LINE(func) { DEVCB_TYPE_DEVICE, 0, "", #func, func, NULL, NULL } +#define DEVCB_LINE_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, 0, "", #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL, NULL } +#define DEVCB_HANDLER(func) { DEVCB_TYPE_DEVICE, 0, "", #func, NULL, func, NULL } +#define DEVCB_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, 0, "", #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL } // line or read/write handlers for the driver device -#define DEVCB_DRIVER_LINE_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_DRIVER, NULL, #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL, NULL } -#define DEVCB_DRIVER_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_DRIVER, NULL, #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL } +#define DEVCB_DRIVER_LINE_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL, NULL } +#define DEVCB_DRIVER_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL } // line or read/write handlers for another device -#define DEVCB_DEVICE_LINE(tag,func) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_OTHER, tag, #func, func, NULL, NULL } -#define DEVCB_DEVICE_LINE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_OTHER, tag, #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL, NULL } -#define DEVCB_DEVICE_HANDLER(tag,func) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_OTHER, tag, #func, NULL, func, NULL } -#define DEVCB_DEVICE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, DEVCB_DEVICE_OTHER, tag, #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL } +#define DEVCB_DEVICE_LINE(tag,func) { DEVCB_TYPE_DEVICE, 0, tag, #func, func, NULL, NULL } +#define DEVCB_DEVICE_LINE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, &devcb_line_stub<cls, &cls::memb>, NULL, NULL } +#define DEVCB_DEVICE_HANDLER(tag,func) { DEVCB_TYPE_DEVICE, 0, tag, #func, NULL, func, NULL } +#define DEVCB_DEVICE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, NULL, &devcb_stub<cls, &cls::memb>, NULL } // constant values #define DEVCB_CONSTANT(value) { DEVCB_TYPE_CONSTANT, value, NULL, NULL, NULL, NULL } diff --git a/src/emu/device.c b/src/emu/device.c index cf974663892..9b166287dc4 100644 --- a/src/emu/device.c +++ b/src/emu/device.c @@ -87,234 +87,6 @@ resource_pool &machine_get_pool(running_machine &machine) //************************************************************************** -// DEVICE LIST MANAGEMENT -//************************************************************************** - -//------------------------------------------------- -// device_list - device list constructor -//------------------------------------------------- - -device_list::device_list(resource_pool &pool) - : tagged_list<device_t>(pool) -{ -} - - -//------------------------------------------------- -// set_machine_all - once the machine is created, -// tell every device about it -//------------------------------------------------- - -void device_list::set_machine_all(running_machine &machine) -{ - // add exit and reset callbacks - m_machine = &machine; - - // iterate over devices and set their machines as well - for (device_t *device = first(); device != NULL; device = device->next()) - device->set_machine(machine); -} - - -//------------------------------------------------- -// start_all - start all the devices in the -// list -//------------------------------------------------- - -void device_list::start_all() -{ - // add exit and reset callbacks - machine().add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(device_list::reset_all), this)); - machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(device_list::exit), this)); - - // add pre-save and post-load callbacks - machine().save().register_presave(save_prepost_delegate(FUNC(device_list::presave_all), this)); - machine().save().register_postload(save_prepost_delegate(FUNC(device_list::postload_all), this)); - - // start_new_devices does all the necessary work - start_new_devices(); -} - - -//------------------------------------------------- -// start_new_devices - start any unstarted devices -//------------------------------------------------- - -void device_list::start_new_devices() -{ - assert(m_machine != NULL); - - // iterate through the devices - device_t *nextdevice; - for (device_t *device = first(); device != NULL; device = nextdevice) - { - // see if this device is what we want - nextdevice = device->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(machine()); - - // 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"); - if (nextdevice == NULL) - throw emu_fatalerror("Circular dependency in device startup; unable to start %s '%s'\n", device->name(), device->tag()); - detach(*device); - append(device->tag(), *device); - } - } - } -} - - -//------------------------------------------------- -// reset_all - reset all devices in the list -//------------------------------------------------- - -void device_list::reset_all() -{ - // iterate over devices and reset them - for (device_t *device = first(); device != NULL; device = device->next()) - device->reset(); -} - - -//------------------------------------------------- -// stop_all - stop all the devices in the -// list -//------------------------------------------------- - -void device_list::stop_all() -{ - // iterate over devices and stop them - for (device_t *device = first(); device != NULL; device = device->next()) - device->stop(); - - // leave with no machine - m_machine = NULL; -} - - -//------------------------------------------------- -// first - return the first device of the given -// type -//------------------------------------------------- - -device_t *device_list::first(device_type type) const -{ - device_t *cur; - for (cur = super::first(); cur != NULL && cur->type() != type; cur = cur->next()) ; - return cur; -} - - -//------------------------------------------------- -// count - count the number of devices of the -// given type -//------------------------------------------------- - -int device_list::count(device_type type) const -{ - int num = 0; - for (const device_t *curdev = first(type); curdev != NULL; curdev = curdev->typenext()) num++; - return num; -} - - -//------------------------------------------------- -// indexof - return the index of the given device -// among its kind -//------------------------------------------------- - -int device_list::indexof(device_type type, device_t &object) const -{ - int num = 0; - for (device_t *cur = first(type); cur != NULL; cur = cur->typenext(), num++) - if (cur == &object) return num; - return -1; -} - - -//------------------------------------------------- -// indexof - return the index of the given device -// among its kind -//------------------------------------------------- - -int device_list::indexof(device_type type, const char *tag) const -{ - device_t *object = find(tag); - return (object != NULL && object->type() == type) ? indexof(type, *object) : -1; -} - - -//------------------------------------------------- -// find - find a device by type + index -//------------------------------------------------- - -device_t *device_list::find(device_type type, int index) const -{ - for (device_t *cur = first(type); cur != NULL; cur = cur->typenext()) - if (index-- == 0) return cur; - return NULL; -} - - -//------------------------------------------------- -// static_exit - tear down all the devices -//------------------------------------------------- - -void device_list::exit() -{ - // first let the debugger save comments - if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) - debug_comment_save(machine()); - - // stop all the devices before we go away - stop_all(); - - // then nuke the devices - reset(); -} - - -//------------------------------------------------- -// presave_all - tell all the devices we are -// about to save -//------------------------------------------------- - -void device_list::presave_all() -{ - for (device_t *device = first(); device != NULL; device = device->next()) - device->pre_save(); -} - - -//------------------------------------------------- -// postload_all - tell all the devices we just -// completed a load -//------------------------------------------------- - -void device_list::postload_all() -{ - for (device_t *device = first(); device != NULL; device = device->next()) - device->post_load(); -} - - - -//************************************************************************** // LIVE DEVICE MANAGEMENT //************************************************************************** @@ -325,63 +97,75 @@ void device_list::postload_all() //------------------------------------------------- device_t::device_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) - : m_debug(NULL), + : m_type(type), + m_name(name), + m_owner(owner), + m_next(NULL), + m_interface_list(NULL), m_execute(NULL), m_memory(NULL), m_state(NULL), - m_next(NULL), - m_owner(owner), - m_interface_list(NULL), - m_type(type), m_configured_clock(clock), - m_machine_config(mconfig), - m_static_config(NULL), - m_input_defaults(NULL), - m_name(name), - m_started(false), - m_clock(clock), - m_region(NULL), m_unscaled_clock(clock), + m_clock(clock), m_clock_scale(1.0), m_attoseconds_per_clock((clock == 0) ? 0 : HZ_TO_ATTOSECONDS(clock)), + + m_debug(NULL), + m_region(NULL), + m_machine_config(mconfig), + m_static_config(NULL), + m_input_defaults(NULL), m_auto_finder_list(NULL), m_machine(NULL), m_save(NULL), - m_tag(tag), - m_config_complete(false) + m_basetag(tag), + m_config_complete(false), + m_started(false) { + if (owner != NULL) + m_tag.cpy((owner->owner() == NULL) ? "" : owner->tag()).cat(":").cat(tag); + else + m_tag.cpy(":"); + mame_printf_verbose("device '%s' created\n", this->tag()); static_set_clock(*this, clock); } device_t::device_t(const machine_config &mconfig, device_type type, const char *name, const char *shortname, const char *tag, device_t *owner, UINT32 clock) - : m_debug(NULL), + : m_type(type), + m_name(name), + m_shortname(shortname), + m_searchpath(shortname), + m_owner(owner), + m_next(NULL), + m_interface_list(NULL), m_execute(NULL), m_memory(NULL), m_state(NULL), - m_next(NULL), - m_owner(owner), - m_interface_list(NULL), - m_type(type), m_configured_clock(clock), - m_machine_config(mconfig), - m_static_config(NULL), - m_input_defaults(NULL), - m_name(name), - m_shortname(shortname), - m_searchpath(shortname), - m_started(false), - m_clock(clock), - m_region(NULL), m_unscaled_clock(clock), + m_clock(clock), m_clock_scale(1.0), m_attoseconds_per_clock((clock == 0) ? 0 : HZ_TO_ATTOSECONDS(clock)), + + m_debug(NULL), + m_region(NULL), + m_machine_config(mconfig), + m_static_config(NULL), + m_input_defaults(NULL), m_auto_finder_list(NULL), m_machine(NULL), m_save(NULL), - m_tag(tag), - m_config_complete(false) + m_basetag(tag), + m_config_complete(false), + m_started(false) { + if (owner != NULL) + m_tag.cpy((owner->owner() == NULL) ? "" : owner->tag()).cat(":").cat(tag); + else + m_tag.cpy(":"); + mame_printf_verbose("device '%s' created\n", this->tag()); static_set_clock(*this, clock); } @@ -406,43 +190,9 @@ const memory_region *device_t::subregion(const char *_tag) const if (this == NULL) return NULL; - // build a fully-qualified name - astring tempstring; - return machine().region(subtag(tempstring, _tag)); -} - - -//------------------------------------------------- -// subdevice - return a pointer to the given -// device that is owned by us -//------------------------------------------------- - -device_t *device_t::subdevice(const char *_tag) const -{ - // safety first - if (this == NULL) - return NULL; - - // build a fully-qualified name - astring tempstring; - return mconfig().devicelist().find((const char *)subtag(tempstring, _tag)); -} - - -//------------------------------------------------- -// siblingdevice - return a pointer to the given -// device that is owned by our same owner -//------------------------------------------------- - -device_t *device_t::siblingdevice(const char *_tag) const -{ - // safety first - if (this == NULL) - return NULL; - - // build a fully-qualified name - astring tempstring; - return mconfig().devicelist().find((const char *)siblingtag(tempstring, _tag)); + // build a fully-qualified name and look it up + astring fullpath; + return machine().region(subtag(fullpath, _tag)); } @@ -489,20 +239,14 @@ void device_t::config_complete() // configuration has been constructed //------------------------------------------------- -bool device_t::validity_check(emu_options &options, const game_driver &driver) const +void device_t::validity_check(validity_checker &valid) const { - bool error = false; - // validate via the interfaces for (device_interface *intf = m_interface_list; intf != NULL; intf = intf->interface_next()) - if (intf->interface_validity_check(options, driver)) - error = true; + intf->interface_validity_check(valid); // let the device itself validate - if (device_validity_check(options, driver)) - error = true; - - return error; + device_validity_check(valid); } @@ -780,10 +524,9 @@ void device_t::device_config_complete() // the configuration has been constructed //------------------------------------------------- -bool device_t::device_validity_check(emu_options &options, const game_driver &driver) const +void device_t::device_validity_check(validity_checker &valid) const { - // indicate no error by default - return false; + // do nothing by default } @@ -812,7 +555,6 @@ machine_config_constructor device_t::device_mconfig_additions() const } - //------------------------------------------------- // input_ports - return a pointer to the implicit // input ports description for this device @@ -908,6 +650,157 @@ void device_t::device_timer(emu_timer &timer, device_timer_id id, int param, voi //------------------------------------------------- +// subdevice_slow - perform a slow name lookup, +// caching the results +//------------------------------------------------- + +device_t *device_t::subdevice_slow(const char *tag) const +{ + // resolve the full path + astring fulltag; + subtag(fulltag, tag); + + // we presume the result is a rooted path; also doubled colons mess up our + // tree walk, so catch them early + assert(fulltag[0] == ':'); + assert(fulltag.find("::") == -1); + + // walk the device list to the final path + device_t *curdevice = &mconfig().root_device(); + if (fulltag.len() > 1) + for (int start = 1, end = fulltag.chr(start, ':'); start != 0 && curdevice != NULL; start = end + 1, end = fulltag.chr(start, ':')) + { + astring part(fulltag, start, (end == -1) ? -1 : end - start); + for (curdevice = curdevice->m_subdevice_list.first(); curdevice != NULL; curdevice = curdevice->next()) + if (part == curdevice->m_basetag) + break; + } + + // if we got a match, add to the fast map + if (curdevice != NULL) + { + m_device_map.add(tag, curdevice); + mame_printf_verbose("device '%s' adding mapping for '%s' => '%s'\n", this->tag(), tag, fulltag.cstr()); + } + return curdevice; +} + + +//------------------------------------------------- +// subtag - create a fully resolved path relative +// to our device based on the provided tag +//------------------------------------------------- + +astring &device_t::subtag(astring &result, const char *tag) const +{ + // if the tag begins with a colon, ignore our path and start from the root + if (*tag == ':') + { + tag++; + result.cpy(":"); + } + + // otherwise, start with our path + else + { + result.cpy(m_tag); + if (result != ":") + result.cat(":"); + } + + // iterate over the tag, look for special path characters to resolve + const char *caret; + while ((caret = strchr(tag, '^')) != NULL) + { + // copy everything up to there + result.cat(tag, caret - tag); + tag = caret + 1; + + // strip trailing colons + int len = result.len(); + while (result[--len] == ':') + result.substr(0, len); + + // remove the last path part, leaving the last colon + if (result != ":") + { + int lastcolon = result.rchr(0, ':'); + if (lastcolon != -1) + result.substr(0, lastcolon + 1); + } + } + + // copy everything else + result.cat(tag); + + // strip trailing colons up to the root + int len = result.len(); + while (len > 1 && result[--len] == ':') + result.substr(0, len); + return result; +} + + +//------------------------------------------------- +// add_subdevice - create a new device and add it +// as a subdevice +//------------------------------------------------- + +device_t *device_t::add_subdevice(device_type type, const char *tag, UINT32 clock) +{ + // allocate the device and append to our list + device_t *device = (*type)(mconfig(), tag, this, clock); + m_subdevice_list.append(*device); + + // apply any machine configuration owned by the device now + machine_config_constructor additions = device->machine_config_additions(); + if (additions != NULL) + (*additions)(const_cast<machine_config &>(mconfig()), device); + return device; +} + + +//------------------------------------------------- +// add_subdevice - create a new device and use it +// to replace an existing subdevice +//------------------------------------------------- + +device_t *device_t::replace_subdevice(device_t &old, device_type type, const char *tag, UINT32 clock) +{ + // iterate over all devices and remove any references to the old device + device_iterator iter(mconfig().root_device()); + for (device_t *scan = iter.first(); scan != NULL; scan = iter.next()) + scan->m_device_map.remove(&old); + + // create a new device, and substitute it for the old one + device_t *device = (*type)(mconfig(), tag, this, clock); + m_subdevice_list.replace_and_remove(*device, old); + + // apply any machine configuration owned by the device now + machine_config_constructor additions = device->machine_config_additions(); + if (additions != NULL) + (*additions)(const_cast<machine_config &>(mconfig()), device); + return device; +} + + +//------------------------------------------------- +// remove_subdevice - remove a given subdevice +//------------------------------------------------- + +void device_t::remove_subdevice(device_t &device) +{ + // iterate over all devices and remove any references + device_iterator iter(mconfig().root_device()); + for (device_t *scan = iter.first(); scan != NULL; scan = iter.next()) + scan->m_device_map.remove(&device); + + // remove from our list + m_subdevice_list.remove(device); +} + + +//------------------------------------------------- // register_auto_finder - add a new item to the // list of stuff to find after we go live //------------------------------------------------- @@ -1022,9 +915,8 @@ void device_interface::interface_config_complete() // constructed //------------------------------------------------- -bool device_interface::interface_validity_check(emu_options &options, const game_driver &driver) const +void device_interface::interface_validity_check(validity_checker &valid) const { - return false; } diff --git a/src/emu/device.h b/src/emu/device.h index a1028944b20..4be5c1c1170 100644 --- a/src/emu/device.h +++ b/src/emu/device.h @@ -91,41 +91,13 @@ class device_interface; class device_execute_interface; class device_memory_interface; class device_state_interface; +class validity_checker; struct rom_entry; class machine_config; class emu_timer; typedef struct _input_device_default input_device_default; -// ======================> device_delegate - -// device_delegate is a delegate that wraps with a device tag and can be easily -// late bound without replicating logic everywhere -template<typename _Signature> -class device_delegate : public delegate<_Signature> -{ - typedef delegate<_Signature> basetype; - -public: - // provide same set of constructors as the base class, with additional device name - // parameter - device_delegate() : basetype(), m_device_name(NULL) { } - device_delegate(const basetype &src) : basetype(src), m_device_name(src.m_device_name) { } - device_delegate(const basetype &src, delegate_late_bind &object) : basetype(src, object), m_device_name(src.m_device_name) { } - template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, const char *devname) : basetype(funcptr, name, (_FunctionClass *)0), m_device_name(devname) { } - template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, const char *devname, _FunctionClass *object) : basetype(funcptr, name, (_FunctionClass *)0), m_device_name(devname) { } - device_delegate(typename basetype::template traits<device_t>::static_func_type funcptr, const char *name) : basetype(funcptr, name, (device_t *)0), m_device_name(NULL) { } - device_delegate(typename basetype::template traits<device_t>::static_ref_func_type funcptr, const char *name) : basetype(funcptr, name, (device_t *)0), m_device_name(NULL) { } - device_delegate &operator=(const basetype &src) { *static_cast<basetype *>(this) = src; m_device_name = src.m_device_name; return *this; } - - // perform the binding - void bind_relative_to(device_t &search_root); - -private: - // internal state - const char *m_device_name; -}; - // exception classes class device_missing_dependencies : public emu_exception { }; @@ -153,56 +125,6 @@ typedef void (*write_line_device_func)(device_t *device, int state); -// ======================> tagged_device_list - -// tagged_device_list is a tagged_list with additional searching based on type -class device_list : public tagged_list<device_t> -{ - typedef tagged_list<device_t> super; - -public: - // construction/destruction - device_list(resource_pool &pool = global_resource_pool); - - // getters - running_machine &machine() const { assert(m_machine != NULL); return *m_machine; } - - // bulk operations - void set_machine_all(running_machine &machine); - void start_all(); - void start_new_devices(); - void reset_all(); - void stop_all(); - - // pull the generic forms forward - using super::first; - using super::count; - using super::indexof; - using super::find; - - // provide type-specific overrides - device_t *first(device_type type) const; - int count(device_type type) const; - int indexof(device_type type, device_t &object) const; - int indexof(device_type type, const char *tag) const; - device_t *find(device_type type, int index) const; - - // provide interface-specific overrides - template<class _InterfaceClass> - bool first(_InterfaceClass *&intf) const; - -private: - // internal helpers - void exit(); - void presave_all(); - void postload_all(); - - // internal state - running_machine *m_machine; -}; - - - // ======================> device_t // device_t represents a device @@ -216,6 +138,8 @@ class device_t : public delegate_late_bind friend class device_execute_interface; friend class simple_list<device_t>; friend class device_list; + friend class machine_config; + friend class running_machine; protected: // construction/destruction @@ -226,12 +150,15 @@ protected: public: // getters running_machine &machine() const { assert(m_machine != NULL); return *m_machine; } + const char *tag() const { return m_tag; } + const char *basetag() const { return m_basetag; } device_type type() const { return m_type; } - UINT32 configured_clock() const { return m_configured_clock; } const char *name() const { return m_name; } const char *shortname() const { return m_shortname; } const char *searchpath() const { return m_searchpath; } - const char *tag() const { return m_tag; } + device_t *owner() const { return m_owner; } + device_t *next() const { return m_next; } + UINT32 configured_clock() const { return m_configured_clock; } const void *static_config() const { return m_static_config; } const machine_config &mconfig() const { return m_machine_config; } const input_device_default *input_ports_defaults() const { return m_input_defaults; } @@ -239,21 +166,9 @@ public: machine_config_constructor machine_config_additions() const { return device_mconfig_additions(); } ioport_constructor input_ports() const { return device_input_ports(); } - // iteration helpers - device_t *next() const { return m_next; } - device_t *typenext() const; - device_t *owner() const { return m_owner; } - // interface helpers template<class _DeviceClass> bool interface(_DeviceClass *&intf) { intf = dynamic_cast<_DeviceClass *>(this); return (intf != NULL); } template<class _DeviceClass> bool interface(_DeviceClass *&intf) const { intf = dynamic_cast<const _DeviceClass *>(this); return (intf != NULL); } - template<class _DeviceClass> bool next(_DeviceClass *&intf) const - { - for (device_t *cur = m_next; cur != NULL; cur = cur->m_next) - if (cur->interface(intf)) - return true; - return false; - } // specialized helpers for common core interfaces bool interface(device_execute_interface *&intf) { intf = m_execute; return (intf != NULL); } @@ -266,13 +181,14 @@ public: device_memory_interface &memory() const { assert(m_memory != NULL); return *m_memory; } // owned object helpers + device_t *first_subdevice() const { return m_subdevice_list.first(); } astring &subtag(astring &dest, const char *tag) const; - astring &siblingtag(astring &dest, const char *tag) const; + astring &siblingtag(astring &dest, const char *tag) const { return (this != NULL && m_owner != NULL) ? m_owner->subtag(dest, tag) : dest.cpy(tag); } const memory_region *subregion(const char *tag) const; device_t *subdevice(const char *tag) const; - device_t *siblingdevice(const char *tag) const; - template<class _DeviceClass> inline _DeviceClass *subdevice(const char *tag) { return downcast<_DeviceClass *>(subdevice(tag)); } - template<class _DeviceClass> inline _DeviceClass *siblingdevice(const char *tag) { return downcast<_DeviceClass *>(siblingdevice(tag)); } + device_t *siblingdevice(const char *tag) const { return (this != NULL && m_owner != NULL) ? m_owner->subdevice(tag) : NULL; } + template<class _DeviceClass> inline _DeviceClass *subdevice(const char *tag) const { return downcast<_DeviceClass *>(subdevice(tag)); } + template<class _DeviceClass> inline _DeviceClass *siblingdevice(const char *tag) const { return downcast<_DeviceClass *>(siblingdevice(tag)); } const memory_region *region() const { return m_region; } // configuration helpers @@ -283,7 +199,7 @@ public: // state helpers void config_complete(); bool configured() const { return m_config_complete; } - bool validity_check(emu_options &options, const game_driver &driver) const; + void validity_check(validity_checker &valid) const; bool started() const { return m_started; } void reset(); @@ -328,7 +244,7 @@ protected: virtual machine_config_constructor device_mconfig_additions() const; virtual ioport_constructor device_input_ports() const; virtual void device_config_complete(); - virtual bool device_validity_check(emu_options &options, const game_driver &driver) const ATTR_COLD; + virtual void device_validity_check(validity_checker &valid) const ATTR_COLD; virtual void device_start() ATTR_COLD = 0; virtual void device_stop() ATTR_COLD; virtual void device_reset() ATTR_COLD; @@ -340,37 +256,37 @@ protected: //------------------- end derived class overrides - device_debug * m_debug; - - // core device interfaces for speed - device_execute_interface *m_execute; - device_memory_interface *m_memory; - device_state_interface *m_state; + // core device properties + const device_type m_type; // device type + astring m_name; // name of the device + astring m_shortname; // short name of the device + astring m_searchpath; // search path, used for media loading // device relationships - device_t * m_next; // next device (of any type/class) - device_t * m_owner; // device that owns us, or NULL if nobody + device_t * m_owner; // device that owns us + device_t * m_next; // next device by the same owner (of any type/class) + simple_list<device_t> m_subdevice_list; // list of sub-devices we own + mutable tagmap_t<device_t *> m_device_map; // map of device names looked up and found + + // device interfaces device_interface * m_interface_list; // head of interface list + device_execute_interface *m_execute; // pre-cached pointer to execute interface + device_memory_interface *m_memory; // pre-cached pointer to memory interface + device_state_interface *m_state; // pre-cached pointer to state interface - const device_type m_type; // device type + // device clocks UINT32 m_configured_clock; // originally configured device clock + UINT32 m_unscaled_clock; // current unscaled device clock + UINT32 m_clock; // current device clock, after scaling + double m_clock_scale; // clock scale factor + attoseconds_t m_attoseconds_per_clock;// period in attoseconds + device_debug * m_debug; + const memory_region * m_region; // our device-local region const machine_config & m_machine_config; // reference to the machine's configuration const void * m_static_config; // static device configuration const input_device_default *m_input_defaults; // devices input ports default overrides - astring m_name; // name of the device - astring m_shortname; // short name of the device - astring m_searchpath; // search path, used for media loading - - bool m_started; // true if the start function has succeeded - UINT32 m_clock; // device clock - const memory_region * m_region; // our device-local region - - UINT32 m_unscaled_clock; // unscaled clock - double m_clock_scale; // clock scale factor - attoseconds_t m_attoseconds_per_clock;// period in attoseconds - // helper class to request auto-object discovery in the constructor of a derived class class auto_finder_base { @@ -480,11 +396,19 @@ protected: auto_finder_base * m_auto_finder_list; private: + // private helpers + device_t *add_subdevice(device_type type, const char *tag, UINT32 clock); + device_t *replace_subdevice(device_t &old, device_type type, const char *tag, UINT32 clock); + void remove_subdevice(device_t &device); + device_t *subdevice_slow(const char *tag) const; + // private state; accessor use required running_machine * m_machine; save_manager * m_save; - astring m_tag; // tag for this instance + astring m_tag; // full tag for this instance + astring m_basetag; // base part of the tag bool m_config_complete; // have we completed our configuration? + bool m_started; // true if the start function has succeeded }; @@ -514,7 +438,7 @@ public: // optional operation overrides virtual void interface_config_complete(); - virtual bool interface_validity_check(emu_options &options, const game_driver &driver) const; + virtual void interface_validity_check(validity_checker &valid) const; virtual void interface_pre_start(); virtual void interface_post_start(); virtual void interface_pre_reset(); @@ -533,48 +457,299 @@ protected: }; +// ======================> device_iterator -//************************************************************************** -// INLINE FUNCTIONS -//************************************************************************** +// helper class to iterate over the hierarchy of devices depth-first +class device_iterator +{ +public: + // construction + device_iterator(device_t &root, int maxdepth = 255) + : m_root(&root), + m_current(NULL), + m_curdepth(0), + m_maxdepth(maxdepth) { } + + // getters + device_t *current() const { return m_current; } + // setters + void set_current(device_t ¤t) { m_current = ¤t; } + + // reset and return first item + device_t *first() + { + m_current = m_root; + return m_current; + } -// ======================> device config helpers + // advance depth-first + device_t *next() + { + // remember our starting position, and end immediately if we're NULL + device_t *start = m_current; + if (start == NULL) + return NULL; -// find the next device_t of the same type -inline device_t *device_t::typenext() const + // search down first + if (m_curdepth < m_maxdepth) + { + m_current = start->first_subdevice(); + if (m_current != NULL) + { + m_curdepth++; + return m_current; + } + } + + // search next for neighbors up the ownership chain + while (m_curdepth > 0) + { + // found a neighbor? great! + m_current = start->next(); + if (m_current != NULL) + return m_current; + + // no? try our parent + start = start->owner(); + m_curdepth--; + } + + // returned to the top; we're done + return m_current = NULL; + } + + // return the number of items available + int count() + { + int result = 0; + for (device_t *item = first(); item != NULL; item = next()) + result++; + return result; + } + + // return the index of a given item in the virtual list + int indexof(device_t &device) + { + int index = 0; + for (device_t *item = first(); item != NULL; item = next(), index++) + if (item == &device) + return index; + return -1; + } + + // return the indexed item in the list + device_t *byindex(int index) + { + for (device_t *item = first(); item != NULL; item = next(), index--) + if (index == 0) + return item; + return NULL; + } + +private: + // internal state + device_t * m_root; + device_t * m_current; + int m_curdepth; + int m_maxdepth; +}; + + +// ======================> device_type_iterator + +// helper class to find devices of a given type in the device hierarchy +template<device_type _DeviceType, class _DeviceClass = device_t> +class device_type_iterator { - device_t *cur; - for (cur = m_next; cur != NULL && cur->m_type != m_type; cur = cur->m_next) ; - return cur; -} +public: + // construction + device_type_iterator(device_t &root, int maxdepth = 255) + : m_iterator(root, maxdepth) { } + + // getters + _DeviceClass *current() const { return downcast<_DeviceClass *>(m_iterator.current()); } + + // setters + void set_current(_DeviceClass ¤t) { m_iterator.set_current(current); } -// create a tag for an object that is owned by this device -inline astring &device_t::subtag(astring &dest, const char *_tag) const + // reset and return first item + _DeviceClass *first() + { + for (device_t *device = m_iterator.first(); device != NULL; device = m_iterator.next()) + if (device->type() == _DeviceType) + return downcast<_DeviceClass *>(device); + return NULL; + } + + // advance depth-first + _DeviceClass *next() + { + for (device_t *device = m_iterator.next(); device != NULL; device = m_iterator.next()) + if (device->type() == _DeviceType) + return downcast<_DeviceClass *>(device); + return NULL; + } + + // return the number of items available + int count() + { + int result = 0; + for (_DeviceClass *item = first(); item != NULL; item = next()) + result++; + return result; + } + + // return the index of a given item in the virtual list + int indexof(_DeviceClass &device) + { + int index = 0; + for (_DeviceClass *item = first(); item != NULL; item = next(), index++) + if (item == &device) + return index; + return -1; + } + + // return the indexed item in the list + _DeviceClass *byindex(int index) + { + for (_DeviceClass *item = first(); item != NULL; item = next(), index--) + if (index == 0) + return item; + return NULL; + } + +private: + // internal state + device_iterator m_iterator; +}; + + +// ======================> device_interface_iterator + +// helper class to find devices with a given interface in the device hierarchy +// also works for findnig devices derived from a given subclass +template<class _InterfaceClass> +class device_interface_iterator { - // temp. for now: don't include the root tag in the full tag name - return (this != NULL && m_owner != NULL) ? dest.cpy(m_tag).cat(":").cat(_tag) : dest.cpy(_tag); -} +public: + // construction + device_interface_iterator(device_t &root, int maxdepth = 255) + : m_iterator(root, maxdepth), + m_current(NULL) { } + + // getters + _InterfaceClass *current() const { return m_current; } + + // setters + void set_current(_InterfaceClass ¤t) { m_current = ¤t; m_iterator.set_current(current.device()); } -// create a tag for an object that a sibling to this device -inline astring &device_t::siblingtag(astring &dest, const char *_tag) const + // reset and return first item + _InterfaceClass *first() + { + for (device_t *device = m_iterator.first(); device != NULL; device = m_iterator.next()) + if (device->interface(m_current)) + return m_current; + return NULL; + } + + // advance depth-first + _InterfaceClass *next() + { + for (device_t *device = m_iterator.next(); device != NULL; device = m_iterator.next()) + if (device->interface(m_current)) + return m_current; + return NULL; + } + + // return the number of items available + int count() + { + int result = 0; + for (_InterfaceClass *item = first(); item != NULL; item = next()) + result++; + return result; + } + + // return the index of a given item in the virtual list + int indexof(_InterfaceClass &intrf) + { + int index = 0; + for (_InterfaceClass *item = first(); item != NULL; item = next(), index++) + if (item == &intrf) + return index; + return -1; + } + + // return the indexed item in the list + _InterfaceClass *byindex(int index) + { + for (_InterfaceClass *item = first(); item != NULL; item = next(), index--) + if (index == 0) + return item; + return NULL; + } + +private: + // internal state + device_iterator m_iterator; + _InterfaceClass * m_current; +}; + + +// ======================> device_delegate + +// device_delegate is a delegate that wraps with a device tag and can be easily +// late bound without replicating logic everywhere +template<typename _Signature> +class device_delegate : public delegate<_Signature> { - return (this != NULL && m_owner != NULL) ? m_owner->subtag(dest, _tag) : dest.cpy(_tag); -} + typedef delegate<_Signature> basetype; + +public: + // provide same set of constructors as the base class, with additional device name + // parameter + device_delegate() : basetype(), m_device_name(NULL) { } + device_delegate(const basetype &src) : basetype(src), m_device_name(src.m_device_name) { } + device_delegate(const basetype &src, delegate_late_bind &object) : basetype(src, object), m_device_name(src.m_device_name) { } + template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, const char *devname) : basetype(funcptr, name, (_FunctionClass *)0), m_device_name(devname) { } + template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, const char *devname, _FunctionClass *object) : basetype(funcptr, name, (_FunctionClass *)0), m_device_name(devname) { } + device_delegate(typename basetype::template traits<device_t>::static_func_type funcptr, const char *name) : basetype(funcptr, name, (device_t *)0), m_device_name(NULL) { } + device_delegate(typename basetype::template traits<device_t>::static_ref_func_type funcptr, const char *name) : basetype(funcptr, name, (device_t *)0), m_device_name(NULL) { } + device_delegate &operator=(const basetype &src) { *static_cast<basetype *>(this) = src; m_device_name = src.m_device_name; return *this; } + + // perform the binding + void bind_relative_to(device_t &search_root); + +private: + // internal state + const char *m_device_name; +}; + + +//************************************************************************** +// INLINE FUNCTIONS +//************************************************************************** //------------------------------------------------- -// first - return the first device in the list -// with the given interface +// subdevice - given a tag, find the device by +// name relative to this device //------------------------------------------------- -template<class _InterfaceClass> -bool device_list::first(_InterfaceClass *&intf) const +inline device_t *device_t::subdevice(const char *tag) const { - for (device_t *cur = super::first(); cur != NULL; cur = cur->next()) - if (cur->interface(intf)) - return true; - return false; + // safety first + if (this == NULL) + return NULL; + + // empty string or NULL means this device + if (tag == NULL || *tag == 0) + return const_cast<device_t *>(this); + + // do a quick lookup and return that if possible + device_t *quick = m_device_map.find(tag); + return (quick != NULL) ? quick : subdevice_slow(tag); } @@ -588,8 +763,9 @@ void device_delegate<_Signature>::bind_relative_to(device_t &search_root) { if (!basetype::isnull()) { - device_t *device = (m_device_name == NULL) ? &search_root : search_root.subdevice(m_device_name); - if (device == NULL) throw emu_fatalerror("Unable to locate device '%s' relative to '%s'\n", m_device_name, search_root.tag()); + device_t *device = search_root.subdevice(m_device_name); + if (device == NULL) + throw emu_fatalerror("Unable to locate device '%s' relative to '%s'\n", m_device_name, search_root.tag()); basetype::late_bind(*device); } } diff --git a/src/emu/devlegcy.c b/src/emu/devlegcy.c index 1b15e10a2cf..185996188a8 100644 --- a/src/emu/devlegcy.c +++ b/src/emu/devlegcy.c @@ -200,12 +200,11 @@ void legacy_device_base::static_set_inline_float(device_t &device, UINT32 offset // checks on a device configuration //------------------------------------------------- -bool legacy_device_base::device_validity_check(emu_options &options, const game_driver &driver) const +void legacy_device_base::device_validity_check(validity_checker &valid) const { device_validity_check_func validity_func = reinterpret_cast<device_validity_check_func>(get_legacy_fct(DEVINFO_FCT_VALIDITY_CHECK)); if (validity_func != NULL) - return (*validity_func)(&driver, this, options); - return false; + (*validity_func)(&mconfig().gamedrv(), this, mconfig().options()); } @@ -239,7 +238,7 @@ void legacy_device_base::device_reset() void legacy_device_base::device_stop() { - if (m_started) + if (started()) { device_stop_func stop_func = reinterpret_cast<device_stop_func>(get_legacy_fct(DEVINFO_FCT_STOP)); if (stop_func != NULL) diff --git a/src/emu/devlegcy.h b/src/emu/devlegcy.h index f598a80d2a3..b68133c5a2d 100644 --- a/src/emu/devlegcy.h +++ b/src/emu/devlegcy.h @@ -429,7 +429,7 @@ protected: virtual const rom_entry *device_rom_region() const { return reinterpret_cast<const rom_entry *>(get_legacy_ptr(DEVINFO_PTR_ROM_REGION)); } virtual machine_config_constructor device_mconfig_additions() const { return reinterpret_cast<machine_config_constructor>(get_legacy_ptr(DEVINFO_PTR_MACHINE_CONFIG)); } virtual ioport_constructor device_input_ports() const { return reinterpret_cast<ioport_constructor>(get_legacy_ptr(DEVINFO_PTR_INPUT_PORTS)); } - virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; + virtual void device_validity_check(validity_checker &valid) const; virtual void device_start(); virtual void device_reset(); virtual void device_stop(); diff --git a/src/emu/didisasm.h b/src/emu/didisasm.h index f6debcb4cdf..ade6827cd72 100644 --- a/src/emu/didisasm.h +++ b/src/emu/didisasm.h @@ -98,5 +98,8 @@ protected: virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) = 0; }; +// iterator +typedef device_interface_iterator<device_disasm_interface> disasm_interface_iterator; + #endif /* __DIDISASM_H__ */ diff --git a/src/emu/diexec.c b/src/emu/diexec.c index 417ed67aea4..99c43cbc389 100644 --- a/src/emu/diexec.c +++ b/src/emu/diexec.c @@ -484,37 +484,22 @@ void device_execute_interface::execute_set_input(int linenum, int state) // constructed //------------------------------------------------- -bool device_execute_interface::interface_validity_check(emu_options &options, const game_driver &driver) const +void device_execute_interface::interface_validity_check(validity_checker &valid) const { - bool error = false; - - /* validate the interrupts */ + // validate the interrupts if (m_vblank_interrupt != NULL) { - if (device().mconfig().devicelist().count(SCREEN) == 0) - { - mame_printf_error("%s: %s device '%s' has a VBLANK interrupt, but the driver is screenless!\n", driver.source_file, driver.name, device().tag()); - error = true; - } - else if (m_vblank_interrupt_screen != NULL && device().mconfig().devicelist().find(m_vblank_interrupt_screen) == NULL) - { - mame_printf_error("%s: %s device '%s' VBLANK interrupt with a non-existant screen tag (%s)!\n", driver.source_file, driver.name, device().tag(), m_vblank_interrupt_screen); - error = true; - } + screen_device_iterator iter(device().mconfig().root_device()); + if (iter.first() == NULL) + mame_printf_error("VBLANK interrupt specified, but the driver is screenless\n"); + else if (m_vblank_interrupt_screen != NULL && device().siblingdevice(m_vblank_interrupt_screen) == NULL) + mame_printf_error("VBLANK interrupt references a non-existant screen tag '%s'\n", m_vblank_interrupt_screen); } if (m_timed_interrupt != NULL && m_timed_interrupt_period == attotime::zero) - { - mame_printf_error("%s: %s device '%s' has a timer interrupt handler with 0 period!\n", driver.source_file, driver.name, device().tag()); - error = true; - } + mame_printf_error("Timed interrupt handler specified with 0 period\n"); else if (m_timed_interrupt == NULL && m_timed_interrupt_period != attotime::zero) - { - mame_printf_error("%s: %s device '%s' has a no timer interrupt handler but has a non-0 period given!\n", driver.source_file, driver.name, device().tag()); - error = true; - } - - return error; + mame_printf_error("No timer interrupt handler specified, but has a non-0 period given\n"); } @@ -526,7 +511,8 @@ bool device_execute_interface::interface_validity_check(emu_options &options, co void device_execute_interface::interface_pre_start() { // fill in the initial states - int index = device().machine().devicelist().indexof(m_device); + execute_interface_iterator iter(device().machine().root_device()); + int index = iter.indexof(*this); m_suspend = SUSPEND_REASON_RESET; m_profiler = profile_type(index + PROFILER_DEVICE_FIRST); m_inttrigger = index + TRIGGER_INT; @@ -540,13 +526,13 @@ void device_execute_interface::interface_pre_start() m_timedint_timer = device().machine().scheduler().timer_alloc(FUNC(static_trigger_periodic_interrupt), (void *)this); // register for save states - m_device.save_item(NAME(m_suspend)); - m_device.save_item(NAME(m_nextsuspend)); - m_device.save_item(NAME(m_eatcycles)); - m_device.save_item(NAME(m_nexteatcycles)); - m_device.save_item(NAME(m_trigger)); - m_device.save_item(NAME(m_totalcycles)); - m_device.save_item(NAME(m_localtime)); + device().save_item(NAME(m_suspend)); + device().save_item(NAME(m_nextsuspend)); + device().save_item(NAME(m_eatcycles)); + device().save_item(NAME(m_nexteatcycles)); + device().save_item(NAME(m_trigger)); + device().save_item(NAME(m_totalcycles)); + device().save_item(NAME(m_localtime)); } @@ -627,7 +613,7 @@ void device_execute_interface::interface_post_reset() void device_execute_interface::interface_clock_changed() { // recompute cps and spc - m_cycles_per_second = clocks_to_cycles(m_device.clock()); + m_cycles_per_second = clocks_to_cycles(device().clock()); m_attoseconds_per_cycle = HZ_TO_ATTOSECONDS(m_cycles_per_second); // update the device's divisor @@ -660,14 +646,14 @@ int device_execute_interface::standard_irq_callback(int irqline) { // get the default vector and acknowledge the interrupt if needed int vector = m_input[irqline].default_irq_callback(); - LOG(("static_standard_irq_callback('%s', %d) $%04x\n", m_device.tag(), irqline, vector)); + LOG(("static_standard_irq_callback('%s', %d) $%04x\n", device().tag(), irqline, vector)); // if there's a driver callback, run it to get the vector if (m_driver_irq != NULL) - vector = (*m_driver_irq)(&m_device, irqline); + vector = (*m_driver_irq)(&device(), irqline); // notify the debugger - debugger_interrupt_hook(&m_device, irqline); + debugger_interrupt_hook(&device(), irqline); return vector; } @@ -682,7 +668,7 @@ attoseconds_t device_execute_interface::minimum_quantum() const // if we don't have that information, compute it attoseconds_t basetick = m_attoseconds_per_cycle; if (basetick == 0) - basetick = HZ_TO_ATTOSECONDS(clocks_to_cycles(m_device.clock())); + basetick = HZ_TO_ATTOSECONDS(clocks_to_cycles(device().clock())); // apply the minimum cycle count return basetick * min_cycles(); @@ -714,9 +700,10 @@ void device_execute_interface::on_vblank(screen_device &screen, bool vblank_stat // generate the interrupt callback if (!suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE)) - (*m_vblank_interrupt)(&m_device); + (*m_vblank_interrupt)(&device()); } + //------------------------------------------------- // static_trigger_periodic_interrupt - timer // callback for timed interrupts @@ -731,7 +718,7 @@ void device_execute_interface::trigger_periodic_interrupt() { // bail if there is no routine if (m_timed_interrupt != NULL && !suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE)) - (*m_timed_interrupt)(&m_device); + (*m_timed_interrupt)(&device()); } @@ -765,7 +752,7 @@ device_execute_interface::device_input::device_input() void device_execute_interface::device_input::start(device_execute_interface *execute, int linenum) { m_execute = execute; - m_device = &m_execute->m_device; + m_device = &m_execute->device(); m_linenum = linenum; reset(); diff --git a/src/emu/diexec.h b/src/emu/diexec.h index 8a7b97c4909..59804199127 100644 --- a/src/emu/diexec.h +++ b/src/emu/diexec.h @@ -228,7 +228,7 @@ protected: virtual void execute_set_input(int linenum, int state); // interface-level overrides - virtual bool interface_validity_check(emu_options &options, const game_driver &driver) const; + virtual void interface_validity_check(validity_checker &valid) const; virtual void interface_pre_start(); virtual void interface_post_start(); virtual void interface_pre_reset(); @@ -322,6 +322,9 @@ private: attoseconds_t minimum_quantum() const; }; +// iterator +typedef device_interface_iterator<device_execute_interface> execute_interface_iterator; + //************************************************************************** diff --git a/src/emu/diimage.c b/src/emu/diimage.c index f23c4823599..9ceefc34c38 100644 --- a/src/emu/diimage.c +++ b/src/emu/diimage.c @@ -1067,17 +1067,9 @@ void device_image_interface::unload() void device_image_interface::update_names() { - const device_image_interface *image = NULL; - int count = 0; - int index = -1; - - for (bool gotone = device().mconfig().devicelist().first(image); gotone; gotone = image->next(image)) - { - if (this == image) - index = count; - if (image->image_type() == image_type()) - count++; - } + image_interface_iterator iter(device().mconfig().root_device()); + int count = iter.count(); + int index = iter.indexof(*this); if (count > 1) { m_instance_name.printf("%s%d", device_typename(image_type()), index + 1); m_brief_instance_name.printf("%s%d", device_brieftypename(image_type()), index + 1); @@ -1103,7 +1095,7 @@ ui_menu_control_device_image::ui_menu_control_device_image(running_machine &mach { image = _image; - slc = 0; + sld = 0; swi = image->software_entry(); swp = image->part_entry(); @@ -1220,8 +1212,8 @@ void ui_menu_control_device_image::handle() } case START_SOFTLIST: - slc = 0; - ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software(machine(), container, image->image_interface(), &slc))); + sld = 0; + ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software(machine(), container, image->image_interface(), &sld))); state = SELECT_SOFTLIST; break; @@ -1233,17 +1225,17 @@ void ui_menu_control_device_image::handle() } case SELECT_SOFTLIST: - if(!slc) { + if(!sld) { ui_menu::stack_pop(machine()); break; } software_info_name = ""; - ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software_list(machine(), container, slc, image->image_interface(), software_info_name))); + ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software_list(machine(), container, sld, image->image_interface(), software_info_name))); state = SELECT_PARTLIST; break; case SELECT_PARTLIST: - swl = software_list_open(machine().options(), slc->list_name, false, NULL); + swl = software_list_open(machine().options(), sld->list_name(), false, NULL); swi = software_list_find(swl, software_info_name, NULL); if(swinfo_has_multiple_parts(swi, image->image_interface())) { submenu_result = -1; diff --git a/src/emu/diimage.h b/src/emu/diimage.h index 583b058f607..84fafc69952 100644 --- a/src/emu/diimage.h +++ b/src/emu/diimage.h @@ -324,6 +324,9 @@ protected: bool m_is_loading; }; +// iterator +typedef device_interface_iterator<device_image_interface> image_interface_iterator; + class ui_menu_control_device_image : public ui_menu { public: ui_menu_control_device_image(running_machine &machine, render_container *container, device_image_interface *image); @@ -344,10 +347,10 @@ protected: int submenu_result; bool create_confirmed; bool softlist_done; - const class software_list *swl; - const class software_info *swi; - const class software_part *swp; - const class software_list_config *slc; + const struct software_list *swl; + const software_info *swi; + const software_part *swp; + const class software_list_device *sld; astring software_info_name; void test_create(bool &can_create, bool &need_confirm); diff --git a/src/emu/dimemory.c b/src/emu/dimemory.c index bf9a5b2cfb7..0a806d82341 100644 --- a/src/emu/dimemory.c +++ b/src/emu/dimemory.c @@ -227,10 +227,9 @@ bool device_memory_interface::memory_readop(offs_t offset, int size, UINT64 &val // checks on the memory configuration //------------------------------------------------- -bool device_memory_interface::interface_validity_check(emu_options &options, const game_driver &driver) const +void device_memory_interface::interface_validity_check(validity_checker &valid) const { bool detected_overlap = DETECT_OVERLAPPING_MEMORY ? false : true; - bool error = false; // loop over all address spaces for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++) @@ -253,15 +252,9 @@ bool device_memory_interface::interface_validity_check(emu_options &options, con // validate the global map parameters if (map->m_spacenum != spacenum) - { - mame_printf_error("%s: %s device '%s' space %d has address space %d handlers!\n", driver.source_file, driver.name, device().tag(), spacenum, map->m_spacenum); - error = true; - } + mame_printf_error("Space %d has address space %d handlers!\n", spacenum, map->m_spacenum); if (map->m_databits != datawidth) - { - mame_printf_error("%s: %s device '%s' uses wrong memory handlers for %s space! (width = %d, memory = %08x)\n", driver.source_file, driver.name, device().tag(), spaceconfig->m_name, datawidth, map->m_databits); - error = true; - } + mame_printf_error("Wrong memory handlers provided for %s space! (width = %d, memory = %08x)\n", spaceconfig->m_name, datawidth, map->m_databits); // loop over entries and look for errors for (address_map_entry *entry = map->m_entrylist.first(); entry != NULL; entry = entry->next()) @@ -278,7 +271,7 @@ bool device_memory_interface::interface_validity_check(emu_options &options, con ((entry->m_read.m_type != AMH_NONE && scan->m_read.m_type != AMH_NONE) || (entry->m_write.m_type != AMH_NONE && scan->m_write.m_type != AMH_NONE))) { - mame_printf_warning("%s: %s '%s' %s space has overlapping memory (%X-%X,%d,%d) vs (%X-%X,%d,%d)\n", driver.source_file, driver.name, device().tag(), spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_read.m_type, entry->m_write.m_type, scan->m_addrstart, scan->m_addrend, scan->m_read.m_type, scan->m_write.m_type); + mame_printf_warning("%s space has overlapping memory (%X-%X,%d,%d) vs (%X-%X,%d,%d)\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_read.m_type, entry->m_write.m_type, scan->m_addrstart, scan->m_addrend, scan->m_read.m_type, scan->m_write.m_type); detected_overlap = true; break; } @@ -286,17 +279,11 @@ bool device_memory_interface::interface_validity_check(emu_options &options, con // look for inverted start/end pairs if (byteend < bytestart) - { - mame_printf_error("%s: %s wrong %s memory read handler start = %08x > end = %08x\n", driver.source_file, driver.name, spaceconfig->m_name, entry->m_addrstart, entry->m_addrend); - error = true; - } + mame_printf_error("Wrong %s memory read handler start = %08x > end = %08x\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend); // look for misaligned entries if ((bytestart & (alignunit - 1)) != 0 || (byteend & (alignunit - 1)) != (alignunit - 1)) - { - mame_printf_error("%s: %s wrong %s memory read handler start = %08x, end = %08x ALIGN = %d\n", driver.source_file, driver.name, spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, alignunit); - error = true; - } + mame_printf_error("Wrong %s memory read handler start = %08x, end = %08x ALIGN = %d\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, alignunit); // if this is a program space, auto-assign implicit ROM entries if (entry->m_read.m_type == AMH_ROM && entry->m_region == NULL) @@ -308,81 +295,54 @@ bool device_memory_interface::interface_validity_check(emu_options &options, con // if this entry references a memory region, validate it if (entry->m_region != NULL && entry->m_share == 0) { - // look for the region + // make sure we can resolve the full path to the region bool found = false; + astring entry_region; + device().siblingtag(entry_region, entry->m_region); + + // look for the region for (const rom_source *source = rom_first_source(device().mconfig()); source != NULL && !found; source = rom_next_source(*source)) - for (const rom_entry *romp = rom_first_region(*source); !ROMENTRY_ISEND(romp) && !found; romp++) + for (const rom_entry *romp = rom_first_region(*source); romp != NULL && !found; romp = rom_next_region(romp)) { - const char *regiontag_c = ROMREGION_GETTAG(romp); - if (regiontag_c != NULL) + astring fulltag; + rom_region_name(fulltag, &device().mconfig().gamedrv(), source, romp); + if (fulltag == entry_region) { - astring fulltag; - astring regiontag; - - // a leading : on a region name indicates an absolute region, so fix up accordingly - if (entry->m_region[0] == ':') - { - regiontag = &entry->m_region[1]; - } - else - { - if (strchr(entry->m_region,':')) { - regiontag = entry->m_region; - } else { - device().siblingtag(regiontag, entry->m_region); - } - } - rom_region_name(fulltag, &driver, source, romp); - if (fulltag.cmp(regiontag) == 0) - { - // verify the address range is within the region's bounds - offs_t length = ROMREGION_GETLENGTH(romp); - if (entry->m_rgnoffs + (byteend - bytestart + 1) > length) - { - mame_printf_error("%s: %s device '%s' %s space memory map entry %X-%X extends beyond region '%s' size (%X)\n", driver.source_file, driver.name, device().tag(), spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_region, length); - error = true; - } - found = true; - } + // verify the address range is within the region's bounds + offs_t length = ROMREGION_GETLENGTH(romp); + if (entry->m_rgnoffs + (byteend - bytestart + 1) > length) + mame_printf_error("%s space memory map entry %X-%X extends beyond region '%s' size (%X)\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_region, length); + found = true; } } // error if not found if (!found) - { - mame_printf_error("%s: %s device '%s' %s space memory map entry %X-%X references non-existant region '%s'\n", driver.source_file, driver.name, device().tag(), spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_region); - error = true; - } + mame_printf_error("%s space memory map entry %X-%X references non-existant region '%s'\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_region); } // make sure all devices exist - if ((entry->m_read.m_type == AMH_LEGACY_DEVICE_HANDLER && entry->m_read.m_tag != NULL && device().mconfig().devicelist().find(entry->m_read.m_tag) == NULL) || - (entry->m_write.m_type == AMH_LEGACY_DEVICE_HANDLER && entry->m_write.m_tag != NULL && device().mconfig().devicelist().find(entry->m_write.m_tag) == NULL)) - { - mame_printf_error("%s: %s device '%s' %s space memory map entry references nonexistant device '%s'\n", driver.source_file, driver.name, device().tag(), spaceconfig->m_name, entry->m_write.m_tag); - error = true; - } + if (entry->m_read.m_type == AMH_LEGACY_DEVICE_HANDLER && entry->m_read.m_tag && device().siblingdevice(entry->m_read.m_tag) == NULL) + mame_printf_error("%s space memory map entry references nonexistant device '%s'\n", spaceconfig->m_name, entry->m_read.m_tag.cstr()); + if (entry->m_write.m_type == AMH_LEGACY_DEVICE_HANDLER && entry->m_write.m_tag && device().siblingdevice(entry->m_write.m_tag) == NULL) + mame_printf_error("%s space memory map entry references nonexistant device '%s'\n", spaceconfig->m_name, entry->m_write.m_tag.cstr()); // make sure ports exist // if ((entry->m_read.m_type == AMH_PORT && entry->m_read.m_tag != NULL && portlist.find(entry->m_read.m_tag) == NULL) || // (entry->m_write.m_type == AMH_PORT && entry->m_write.m_tag != NULL && portlist.find(entry->m_write.m_tag) == NULL)) -// { -// mame_printf_error("%s: %s device '%s' %s space memory map entry references nonexistant port tag '%s'\n", driver.source_file, driver.name, device().tag(), spaceconfig->m_name, entry->m_read.tag); -// error = true; -// } +// mame_printf_error("%s space memory map entry references nonexistant port tag '%s'\n", spaceconfig->m_name, entry->m_read.m_tag.cstr()); // validate bank and share tags - if (entry->m_read.m_type == AMH_BANK && !validate_tag(driver, "bank", entry->m_read.m_tag)) - error = true ; - if (entry->m_write.m_type == AMH_BANK && !validate_tag(driver, "bank", entry->m_write.m_tag)) - error = true; - if (entry->m_share != NULL && !validate_tag(driver, "share", entry->m_share)) - error = true; + if (entry->m_read.m_type == AMH_BANK) + valid.validate_tag(entry->m_read.m_tag); + if (entry->m_write.m_type == AMH_BANK) + valid.validate_tag(entry->m_write.m_tag); + if (entry->m_share != NULL) + valid.validate_tag(entry->m_share); } // release the address map global_free(map); } } - return error; } diff --git a/src/emu/dimemory.h b/src/emu/dimemory.h index b0e2da346bb..c6efce57ebe 100644 --- a/src/emu/dimemory.h +++ b/src/emu/dimemory.h @@ -134,13 +134,16 @@ protected: virtual bool memory_readop(offs_t offset, int size, UINT64 &value); // interface-level overrides - virtual bool interface_validity_check(emu_options &options, const game_driver &driver) const; + virtual void interface_validity_check(validity_checker &valid) const; // configuration address_map_constructor m_address_map[ADDRESS_SPACES]; // address maps for each address space address_space * m_addrspace[ADDRESS_SPACES]; // reported address spaces }; +// iterator +typedef device_interface_iterator<device_memory_interface> memory_interface_iterator; + //************************************************************************** diff --git a/src/emu/dinetwork.h b/src/emu/dinetwork.h index 592853af78a..bc1546e17c4 100644 --- a/src/emu/dinetwork.h +++ b/src/emu/dinetwork.h @@ -28,4 +28,9 @@ protected: class netdev *m_dev; int m_intf; }; + + +// iterator +typedef device_interface_iterator<device_network_interface> network_interface_iterator; + #endif diff --git a/src/emu/dinvram.h b/src/emu/dinvram.h index 30b490c60a1..ad9947ea1cc 100644 --- a/src/emu/dinvram.h +++ b/src/emu/dinvram.h @@ -74,5 +74,8 @@ protected: virtual void nvram_write(emu_file &file) = 0; }; +// iterator +typedef device_interface_iterator<device_nvram_interface> nvram_interface_iterator; + #endif /* __DINVRAM_H__ */ diff --git a/src/emu/dislot.h b/src/emu/dislot.h index 630a76b677e..bdc7413dc92 100644 --- a/src/emu/dislot.h +++ b/src/emu/dislot.h @@ -48,8 +48,8 @@ public: static void static_set_slot_info(device_t &device, const slot_interface *slots_info, const char *default_card,const input_device_default *default_input); const slot_interface* get_slot_interfaces() const { return m_slot_interfaces; }; - const char * get_default_card(const device_list &devlist, emu_options &options) const { return m_default_card; }; - virtual const char * get_default_card_software(const device_list &devlist, emu_options &options) const { return NULL; }; + const char * get_default_card(const machine_config &config, emu_options &options) const { return m_default_card; }; + virtual const char * get_default_card_software(const machine_config &config, emu_options &options) const { return NULL; }; const input_device_default *input_ports_defaults() const { return m_input_defaults; } device_t* get_card_device(); protected: @@ -58,6 +58,9 @@ protected: const slot_interface *m_slot_interfaces; }; +// iterator +typedef device_interface_iterator<device_slot_interface> slot_interface_iterator; + // ======================> device_slot_card_interface class device_slot_card_interface : public device_interface diff --git a/src/emu/disound.c b/src/emu/disound.c index cb004c28fa2..2889d58f852 100644 --- a/src/emu/disound.c +++ b/src/emu/disound.c @@ -232,30 +232,21 @@ void device_sound_interface::set_output_gain(int outputnum, float gain) // constructed //------------------------------------------------- -bool device_sound_interface::interface_validity_check(emu_options &options, const game_driver &driver) const +void device_sound_interface::interface_validity_check(validity_checker &valid) const { - bool error = false; - // loop over all the routes for (const sound_route *route = first_route(); route != NULL; route = route->next()) { // find a device with the requested tag - const device_t *target = device().mconfig().devicelist().find(route->m_target.cstr()); + const device_t *target = device().siblingdevice(route->m_target.cstr()); if (target == NULL) - { - mame_printf_error("%s: %s attempting to route sound to non-existant device '%s'\n", driver.source_file, driver.name, route->m_target.cstr()); - error = true; - } + mame_printf_error("Attempting to route sound to non-existant device '%s'\n", route->m_target.cstr()); // if it's not a speaker or a sound device, error const device_sound_interface *sound; if (target != NULL && target->type() != SPEAKER && !target->interface(sound)) - { - mame_printf_error("%s: %s attempting to route sound to a non-sound device '%s' (%s)\n", driver.source_file, driver.name, route->m_target.cstr(), target->name()); - error = true; - } + mame_printf_error("Attempting to route sound to a non-sound device '%s' (%s)\n", route->m_target.cstr(), target->name()); } - return error; } @@ -267,8 +258,8 @@ bool device_sound_interface::interface_validity_check(emu_options &options, cons void device_sound_interface::interface_pre_start() { // scan all the sound devices - device_sound_interface *sound = NULL; - for (bool gotone = m_device.machine().devicelist().first(sound); gotone; gotone = sound->next(sound)) + sound_interface_iterator iter(m_device.machine().root_device()); + for (device_sound_interface *sound = iter.first(); sound != NULL; sound = iter.next()) { // scan each route on the device for (const sound_route *route = sound->first_route(); route != NULL; route = route->next()) @@ -282,7 +273,7 @@ void device_sound_interface::interface_pre_start() // now iterate through devices again and assign any auto-allocated inputs m_auto_allocated_inputs = 0; - for (bool gotone = m_device.machine().devicelist().first(sound); gotone; gotone = sound->next(sound)) + for (device_sound_interface *sound = iter.first(); sound != NULL; sound = iter.next()) { // scan each route on the device for (const sound_route *route = sound->first_route(); route != NULL; route = route->next()) @@ -307,8 +298,8 @@ void device_sound_interface::interface_pre_start() void device_sound_interface::interface_post_start() { // iterate over all the sound devices - device_sound_interface *sound = NULL; - for (bool gotone = m_device.machine().devicelist().first(sound); gotone; gotone = sound->next(sound)) + sound_interface_iterator iter(m_device.machine().root_device()); + for (device_sound_interface *sound = iter.first(); sound != NULL; sound = iter.next()) { // scan each route on the device for (const sound_route *route = sound->first_route(); route != NULL; route = route->next()) diff --git a/src/emu/disound.h b/src/emu/disound.h index c4c9a2f13c0..c94187337c4 100644 --- a/src/emu/disound.h +++ b/src/emu/disound.h @@ -138,7 +138,7 @@ public: protected: // optional operation overrides - virtual bool interface_validity_check(emu_options &options, const game_driver &driver) const; + virtual void interface_validity_check(validity_checker &valid) const; virtual void interface_pre_start(); virtual void interface_post_start(); virtual void interface_pre_reset(); @@ -149,5 +149,7 @@ protected: int m_auto_allocated_inputs; // number of auto-allocated inputs targeting us }; +// iterator +typedef device_interface_iterator<device_sound_interface> sound_interface_iterator; #endif /* __DISOUND_H__ */ diff --git a/src/emu/distate.c b/src/emu/distate.c index 2a18ea59c9d..6a0621d3eac 100644 --- a/src/emu/distate.c +++ b/src/emu/distate.c @@ -517,7 +517,7 @@ device_state_entry &device_state_interface::state_add(int index, const char *sym assert(symbol != NULL); // allocate new entry - device_state_entry *entry = auto_alloc(device().machine(), device_state_entry(index, symbol, data, size)); + device_state_entry *entry = global_alloc(device_state_entry(index, symbol, data, size)); // append to the end of the list m_state_list.append(*entry); diff --git a/src/emu/distate.h b/src/emu/distate.h index b38f692fc7e..66b756e566b 100644 --- a/src/emu/distate.h +++ b/src/emu/distate.h @@ -195,6 +195,9 @@ protected: // fast access to common entries }; +// iterator +typedef device_interface_iterator<device_state_interface> state_interface_iterator; + //************************************************************************** diff --git a/src/emu/emuopts.c b/src/emu/emuopts.c index 7d7196fbfc0..cc06c91c98f 100644 --- a/src/emu/emuopts.c +++ b/src/emu/emuopts.c @@ -226,11 +226,11 @@ bool emu_options::add_slot_options(bool isfirst) // iterate through all slot devices options_entry entry[2] = { { 0 }, { 0 } }; bool first = true; - const device_slot_interface *slot = NULL; // create the configuration machine_config config(*cursystem, *this); bool added = false; - for (bool gotone = config.devicelist().first(slot); gotone; gotone = slot->next(slot)) + slot_interface_iterator iter(config.root_device()); + for (const device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next()) { // first device? add the header as to be pretty if (first && isfirst) @@ -253,7 +253,7 @@ bool emu_options::add_slot_options(bool isfirst) entry[0].name = slot->device().tag(); entry[0].description = NULL; entry[0].flags = OPTION_STRING | OPTION_FLAG_DEVICE; - entry[0].defvalue = (slot->get_slot_interfaces() != NULL) ? slot->get_default_card(config.devicelist(),*this) : NULL; + entry[0].defvalue = (slot->get_slot_interfaces() != NULL) ? slot->get_default_card(config,*this) : NULL; add_entries(entry, true); added = true; @@ -275,10 +275,10 @@ void emu_options::update_slot_options() return; // iterate through all slot devices - const device_slot_interface *slot = NULL; // create the configuration machine_config config(*cursystem, *this); - for (bool gotone = config.devicelist().first(slot); gotone; gotone = slot->next(slot)) + slot_interface_iterator iter(config.root_device()); + for (const device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next()) { // retrieve info about the device instance astring option_name; @@ -286,7 +286,7 @@ void emu_options::update_slot_options() if (exists(slot->device().tag())) { if (slot->get_slot_interfaces() != NULL) { - const char *def = slot->get_default_card_software(config.devicelist(),*this); + const char *def = slot->get_default_card_software(config,*this); if (def) set_default_value(slot->device().tag(),def); } } @@ -308,9 +308,9 @@ void emu_options::add_device_options(bool isfirst) options_entry entry[2] = { { 0 }, { 0 } }; bool first = true; // iterate through all image devices - const device_image_interface *image = NULL; machine_config config(*cursystem, *this); - for (bool gotone = config.devicelist().first(image); gotone; gotone = image->next(image)) + image_interface_iterator iter(config.root_device()); + for (const device_image_interface *image = iter.first(); image != NULL; image = iter.next()) { // first device? add the header as to be pretty if (first && isfirst) @@ -438,7 +438,8 @@ void emu_options::parse_standard_inis(astring &error_string) // parse "vector.ini" for vector games { machine_config config(*cursystem, *this); - for (const screen_device *device = config.first_screen(); device != NULL; device = device->next_screen()) + screen_device_iterator iter(config.root_device()); + for (const screen_device *device = iter.first(); device != NULL; device = iter.next()) if (device->screen_type() == SCREEN_TYPE_VECTOR) { parse_one_ini("vector", OPTION_PRIORITY_VECTOR_INI, &error_string); diff --git a/src/emu/image.c b/src/emu/image.c index fc8776fa218..260bef069c9 100644 --- a/src/emu/image.c +++ b/src/emu/image.c @@ -68,7 +68,6 @@ static void image_dirs_load(running_machine &machine, int config_type, xml_data_ xml_data_node *node; const char *dev_instance; const char *working_directory; - device_image_interface *image = NULL; if ((config_type == CONFIG_TYPE_GAME) && (parentnode != NULL)) { @@ -78,7 +77,8 @@ static void image_dirs_load(running_machine &machine, int config_type, xml_data_ if ((dev_instance != NULL) && (dev_instance[0] != '\0')) { - for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image)) + image_interface_iterator iter(machine.root_device()); + for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) { if (!strcmp(dev_instance, image->instance_name())) { working_directory = xml_get_attribute_string(node, "directory", NULL); @@ -102,12 +102,12 @@ static void image_dirs_save(running_machine &machine, int config_type, xml_data_ { xml_data_node *node; const char *dev_instance; - device_image_interface *image = NULL; /* only care about game-specific data */ if (config_type == CONFIG_TYPE_GAME) { - for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image)) + image_interface_iterator iter(machine.root_device()); + for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) { dev_instance = image->instance_name(); @@ -160,9 +160,9 @@ static void image_options_extract(running_machine &machine) no need to assert in case they are missing */ { int index = 0; - device_image_interface *image = NULL; - for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image)) + image_interface_iterator iter(machine.root_device()); + for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) { const char *filename = image->filename(); @@ -186,12 +186,11 @@ static void image_options_extract(running_machine &machine) void image_unload_all(running_machine &machine) { - device_image_interface *image = NULL; - // extract the options image_options_extract(machine); - for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image)) + image_interface_iterator iter(machine.root_device()); + for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) { // unload this image image->unload(); @@ -205,10 +204,10 @@ void image_unload_all(running_machine &machine) void image_device_init(running_machine &machine) { const char *image_name; - device_image_interface *image = NULL; /* make sure that any required devices have been allocated */ - for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image)) + image_interface_iterator iter(machine.root_device()); + for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) { /* is an image specified for this image */ image_name = machine.options().device_option(*image); @@ -239,7 +238,7 @@ void image_device_init(running_machine &machine) } } - for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image)) + for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) { /* is an image specified for this image */ image_name = image->filename(); @@ -264,10 +263,9 @@ void image_device_init(running_machine &machine) void image_postdevice_init(running_machine &machine) { - device_image_interface *image = NULL; - /* make sure that any required devices have been allocated */ - for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image)) + image_interface_iterator iter(machine.root_device()); + for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) { int result = image->finish_load(); /* did the image load fail? */ @@ -373,8 +371,6 @@ static char *strip_extension(const char *filename) astring &image_info_astring(running_machine &machine, astring &string) { - device_image_interface *image = NULL; - string.printf("%s\n\n", machine.system().description); #if 0 @@ -385,7 +381,8 @@ astring &image_info_astring(running_machine &machine, astring &string) } #endif - for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image)) + image_interface_iterator iter(machine.root_device()); + for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) { const char *name = image->filename(); if (name != NULL) @@ -480,15 +477,8 @@ void image_battery_save_by_name(emu_options &options, const char *filename, cons -------------------------------------------------*/ device_image_interface *image_from_absolute_index(running_machine &machine, int absolute_index) { - device_image_interface *image = NULL; - int cnt = 0; - /* make sure that any required devices have been allocated */ - for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image)) - { - if (cnt==absolute_index) return image; - cnt++; - } - return NULL; + image_interface_iterator iter(machine.root_device()); + return iter.byindex(absolute_index); } /*------------------------------------------------- diff --git a/src/emu/imagedev/bitbngr.h b/src/emu/imagedev/bitbngr.h index 25a25915537..a6f887201ae 100644 --- a/src/emu/imagedev/bitbngr.h +++ b/src/emu/imagedev/bitbngr.h @@ -163,4 +163,7 @@ private: // device type definition extern const device_type BITBANGER; +// device iterator +typedef device_type_iterator<&device_creator<bitbanger_device>, bitbanger_device> bitbanger_device_iterator; + #endif /* __BITBNGR_H__ */ diff --git a/src/emu/imagedev/cassette.c b/src/emu/imagedev/cassette.c index 474256d5ec5..dd2408f729d 100644 --- a/src/emu/imagedev/cassette.c +++ b/src/emu/imagedev/cassette.c @@ -336,7 +336,7 @@ void cassette_image_device::call_display() int n; double position, length; cassette_state uistate; - device_t *dev; + cassette_image_device *dev; static const UINT8 shapes[8] = { 0x2d, 0x5c, 0x7c, 0x2f, 0x2d, 0x20, 0x20, 0x20 }; /* abort if we should not be showing the image */ @@ -354,13 +354,9 @@ void cassette_image_device::call_display() x = 0.2f; y = 0.5f; - dev = device().machine().devicelist().first(CASSETTE ); - - while ( dev && strcmp( dev->tag(), device().tag() ) ) - { + cassette_device_iterator iter(device().machine().root_device()); + for (dev = iter.first(); dev != NULL && strcmp( dev->tag(), device().tag() ); dev = iter.next()) y += 1; - dev = dev->typenext(); - } y *= ui_get_line_height(device().machine()) + 2.0f * UI_BOX_TB_BORDER; /* choose which frame of the animation we are at */ diff --git a/src/emu/imagedev/cassette.h b/src/emu/imagedev/cassette.h index c7476e169a0..cec381c2e0f 100644 --- a/src/emu/imagedev/cassette.h +++ b/src/emu/imagedev/cassette.h @@ -113,6 +113,9 @@ private: // device type definition extern const device_type CASSETTE; +// device iterator +typedef device_type_iterator<&device_creator<cassette_image_device>, cassette_image_device> cassette_device_iterator; + /*************************************************************************** DEVICE CONFIGURATION MACROS ***************************************************************************/ diff --git a/src/emu/info.c b/src/emu/info.c index e9f15949c33..2ce0ad90692 100644 --- a/src/emu/info.c +++ b/src/emu/info.c @@ -266,13 +266,13 @@ void info_xml_creator::output_devices() m_drivlist.reset(); m_drivlist.next(); machine_config &config = m_drivlist.config(); - device_t *owner = config.devicelist().first(); + device_t &owner = config.root_device(); // check if all are listed, note that empty one is included bool display_all = driver_list::total() == (m_drivlist.count()+1); for(int i=0;i<m_device_count;i++) { if (display_all || (m_device_used[i]!=0)) { device_type type = *s_devices_sorted[i]; - device_t *dev = (*type)(config, "dummy", owner, 0); + device_t *dev = (*type)(config, "dummy", &owner, 0); dev->config_complete(); // print the header and the game name @@ -311,7 +311,8 @@ void info_xml_creator::output_one() machine_config &config = m_drivlist.config(); ioport_list portlist; astring errors; - for (device_t *device = config.devicelist().first(); device != NULL; device = device->next()) + device_iterator iter(config.root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) input_port_list_init(*device, portlist, errors); // print the header and the game name @@ -407,7 +408,8 @@ void info_xml_creator::output_device_roms() void info_xml_creator::output_sampleof() { // iterate over sample devices - for (const device_t *device = m_drivlist.config().devicelist().first(SAMPLES); device != NULL; device = device->typenext()) + samples_device_iterator iter(m_drivlist.config().root_device()); + for (samples_device *device = iter.first(); device != NULL; device = iter.next()) { const char *const *samplenames = ((const samples_interface *)device->static_config())->samplenames; if (samplenames != NULL) @@ -566,7 +568,8 @@ void info_xml_creator::output_rom(const rom_source *source) void info_xml_creator::output_sample() { // iterate over sample devices - for (const device_t *device = m_drivlist.config().devicelist().first(SAMPLES); device != NULL; device = device->typenext()) + samples_device_iterator iter(m_drivlist.config().root_device()); + for (const device_t *device = iter.first(); device != NULL; device = iter.next()) { const char *const *samplenames = ((const samples_interface *)device->static_config())->samplenames; if (samplenames != NULL) @@ -602,8 +605,8 @@ void info_xml_creator::output_sample() void info_xml_creator::output_chips() { // iterate over executable devices - device_execute_interface *exec = NULL; - for (bool gotone = m_drivlist.config().devicelist().first(exec); gotone; gotone = exec->next(exec)) + execute_interface_iterator execiter(m_drivlist.config().root_device()); + for (device_execute_interface *exec = execiter.first(); exec != NULL; exec = execiter.next()) { fprintf(m_output, "\t\t<chip"); fprintf(m_output, " type=\"cpu\""); @@ -614,8 +617,8 @@ void info_xml_creator::output_chips() } // iterate over sound devices - device_sound_interface *sound = NULL; - for (bool gotone = m_drivlist.config().devicelist().first(sound); gotone; gotone = sound->next(sound)) + sound_interface_iterator sounditer(m_drivlist.config().root_device()); + for (device_sound_interface *sound = sounditer.first(); sound != NULL; sound = sounditer.next()) { fprintf(m_output, "\t\t<chip"); fprintf(m_output, " type=\"audio\""); @@ -636,7 +639,8 @@ void info_xml_creator::output_chips() void info_xml_creator::output_display() { // iterate over screens - for (const screen_device *device = m_drivlist.config().first_screen(); device != NULL; device = device->next_screen()) + screen_device_iterator iter(m_drivlist.config().root_device()); + for (const screen_device *device = iter.first(); device != NULL; device = iter.next()) { fprintf(m_output, "\t\t<display"); @@ -714,11 +718,12 @@ void info_xml_creator::output_display() void info_xml_creator::output_sound() { - int speakers = m_drivlist.config().devicelist().count(SPEAKER); + speaker_device_iterator spkiter(m_drivlist.config().root_device()); + int speakers = spkiter.count(); // if we have no sound, zero m_output the speaker count - const device_sound_interface *sound = NULL; - if (!m_drivlist.config().devicelist().first(sound)) + sound_interface_iterator snditer(m_drivlist.config().root_device()); + if (snditer.first() == NULL) speakers = 0; fprintf(m_output, "\t\t<sound channels=\"%d\"/>\n", speakers); @@ -1144,8 +1149,8 @@ void info_xml_creator::output_driver() void info_xml_creator::output_images() { - const device_image_interface *dev = NULL; - for (bool gotone = m_drivlist.config().devicelist().first(dev); gotone; gotone = dev->next(dev)) + image_interface_iterator iter(m_drivlist.config().root_device()); + for (const device_image_interface *dev = iter.first(); dev != NULL; dev = iter.next()) { // print m_output device type fprintf(m_output, "\t\t<device type=\"%s\"", xml_normalize_string(dev->image_type_name())); @@ -1194,8 +1199,8 @@ void info_xml_creator::output_images() void info_xml_creator::output_slots() { - const device_slot_interface *slot = NULL; - for (bool gotone = m_drivlist.config().devicelist().first(slot); gotone; gotone = slot->next(slot)) + slot_interface_iterator iter(m_drivlist.config().root_device()); + for (const device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next()) { // print m_output device type fprintf(m_output, "\t\t<slot name=\"%s\">\n", xml_normalize_string(slot->device().tag())); @@ -1210,9 +1215,9 @@ void info_xml_creator::output_slots() { fprintf(m_output, "\t\t\t<slotoption"); fprintf(m_output, " name=\"%s\"", xml_normalize_string(intf[i].name)); - if (slot->get_default_card(m_drivlist.config().devicelist(), m_drivlist.options())) + if (slot->get_default_card(m_drivlist.config(), m_drivlist.options())) { - if (slot->get_default_card(m_drivlist.config().devicelist(), m_drivlist.options()) == intf[i].name) + if (slot->get_default_card(m_drivlist.config(), m_drivlist.options()) == intf[i].name) fprintf(m_output, " default=\"yes\""); } fprintf(m_output, "/>\n"); @@ -1230,13 +1235,13 @@ void info_xml_creator::output_slots() void info_xml_creator::output_software_list() { - for (const device_t *dev = m_drivlist.config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) + software_list_device_iterator iter(m_drivlist.config().root_device()); + for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next()) { - software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config(); - fprintf(m_output, "\t\t<softwarelist name=\"%s\" ", swlist->list_name); - fprintf(m_output, "status=\"%s\" ", (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM) ? "original" : "compatible"); - if (swlist->filter) { - fprintf(m_output, "filter=\"%s\" ", swlist->filter); + fprintf(m_output, "\t\t<softwarelist name=\"%s\" ", swlist->list_name()); + fprintf(m_output, "status=\"%s\" ", (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) ? "original" : "compatible"); + if (swlist->filter()) { + fprintf(m_output, "filter=\"%s\" ", swlist->filter()); } fprintf(m_output, "/>\n"); } @@ -1251,10 +1256,9 @@ void info_xml_creator::output_software_list() void info_xml_creator::output_ramoptions() { - for (const device_t *device = m_drivlist.config().devicelist().first(RAM); device != NULL; device = device->typenext()) + ram_device_iterator iter(m_drivlist.config().root_device()); + for (const ram_device *ram = iter.first(); ram != NULL; ram = iter.next()) { - const ram_device *ram = downcast<const ram_device *>(device); - fprintf(m_output, "\t\t<ramoption default=\"1\">%u</ramoption>\n", ram->default_size()); if (ram->extra_options() != NULL) diff --git a/src/emu/ioport.c b/src/emu/ioport.c index 5215b7735f3..7f93baa417c 100644 --- a/src/emu/ioport.c +++ b/src/emu/ioport.c @@ -903,7 +903,8 @@ time_t input_port_init(running_machine &machine) init_port_types(machine); /* if we have a token list, proceed */ - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + device_iterator iter(machine.root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) { astring errors; input_port_list_init(*device, machine.m_portlist, errors); @@ -1500,10 +1501,10 @@ input_port_value input_port_read(running_machine &machine, const char *tag) a device input port specified by tag -------------------------------------------------*/ -input_port_value input_port_read(device_t *device, const char *tag) +input_port_value input_port_read(device_t &device, const char *tag) { - astring tempstring; - const input_port_config *port = device->machine().port(device->subtag(tempstring, tag)); + astring fullpath; + const input_port_config *port = device.machine().port(device.subtag(fullpath, tag)); if (port == NULL) fatalerror("Unable to locate input port '%s'", tag); return input_port_read_direct(port); @@ -1721,7 +1722,7 @@ void input_port_write_safe(running_machine &machine, const char *tag, input_port if the given condition attached is true -------------------------------------------------*/ -int input_condition_true(running_machine &machine, const input_condition *condition,device_t &owner) +int input_condition_true(running_machine &machine, const input_condition *condition, device_t &owner) { input_port_value condvalue; @@ -1939,20 +1940,6 @@ static astring &get_keyboard_key_name(astring &name, const input_field_config *f states based on the tokens -------------------------------------------------*/ -inline const char *get_device_tag(const device_t &device, const char *tag, astring &finaltag) -{ - if (strcmp(tag, DEVICE_SELF) == 0) - finaltag.cpy(device.tag()); - else if (strcmp(tag, DEVICE_SELF_OWNER) == 0) - { - assert(device.owner() != NULL); - finaltag.cpy(device.owner()->tag()); - } - else - device.subtag(finaltag, tag); - return finaltag; -} - static void init_port_state(running_machine &machine) { const char *joystick_map_default = machine.options().joystick_map(); @@ -2012,7 +1999,7 @@ static void init_port_state(running_machine &machine) astring devicetag; if (!field->read.isnull()) { - *readdevicetail = init_field_device_info(field, get_device_tag(port->owner(), field->read_device, devicetag)); + *readdevicetail = init_field_device_info(field, port->owner().subtag(devicetag, field->read_device)); field->read.late_bind(*(*readdevicetail)->device); readdevicetail = &(*readdevicetail)->next; } @@ -2020,7 +2007,7 @@ static void init_port_state(running_machine &machine) /* if this entry has device output, allocate memory for the tracking structure */ if (!field->write.isnull()) { - *writedevicetail = init_field_device_info(field, get_device_tag(port->owner(), field->write_device, devicetag)); + *writedevicetail = init_field_device_info(field, port->owner().subtag(devicetag, field->write_device)); field->write.late_bind(*(*writedevicetail)->device); writedevicetail = &(*writedevicetail)->next; } @@ -2028,7 +2015,7 @@ static void init_port_state(running_machine &machine) /* if this entry has device output, allocate memory for the tracking structure */ if (!field->crossmapper.isnull()) { - device_t *device = machine.device(get_device_tag(port->owner(), field->crossmapper_device, devicetag)); + device_t *device = machine.device(port->owner().subtag(devicetag, field->crossmapper_device)); field->crossmapper.late_bind(*device); } @@ -2842,16 +2829,13 @@ static int frame_get_digital_field_state(const input_field_config *field, int mo UINT32 port_default_value(const char *fulltag, UINT32 mask, UINT32 defval, device_t &owner) { - astring tempstring; - const input_device_default *def = NULL; - def = owner.input_ports_defaults(); - if (def!=NULL) { - while (def->tag!=NULL) { - if ((strcmp(fulltag,owner.subtag(tempstring,def->tag))==0) && (def->mask == mask)) { + const input_device_default *def = owner.input_ports_defaults(); + if (def != NULL) + { + astring fullpath; + for ( ; def->tag != NULL; def++) + if (owner.subtag(fullpath, def->tag) == fulltag && def->mask == mask) return def->defvalue; - } - def++; - } } return defval; } @@ -4830,6 +4814,7 @@ input_port_config *ioconfig_alloc_port(ioport_list &portlist, device_t &device, { astring fulltag; device.subtag(fulltag, tag); +mame_printf_verbose("ioport '%s' created\n", fulltag.cstr()); return &portlist.append(fulltag, *global_alloc(input_port_config(device, fulltag))); } diff --git a/src/emu/ioport.h b/src/emu/ioport.h index 25ca0aa17cf..1d70ac210f0 100644 --- a/src/emu/ioport.h +++ b/src/emu/ioport.h @@ -1333,7 +1333,7 @@ input_port_value input_port_read_direct(const input_port_config *port); input_port_value input_port_read(running_machine &machine, const char *tag); /* return the value of a device input port specified by tag */ -input_port_value input_port_read(device_t *device, const char *tag); +input_port_value input_port_read(device_t &device, const char *tag); /* return the value of an input port specified by tag, or a default value if the port does not exist */ input_port_value input_port_read_safe(running_machine &machine, const char *tag, input_port_value defvalue); diff --git a/src/emu/machine.c b/src/emu/machine.c index 172f15e31a5..4118d3b0370 100644 --- a/src/emu/machine.c +++ b/src/emu/machine.c @@ -150,7 +150,6 @@ running_machine::running_machine(const machine_config &_config, osd_interface &o memory_data(NULL), palette_data(NULL), romload_data(NULL), - input_data(NULL), input_port_data(NULL), ui_input_data(NULL), debugcpu_data(NULL), @@ -171,7 +170,6 @@ running_machine::running_machine(const machine_config &_config, osd_interface &o m_video(NULL), m_tilemap(NULL), m_debug_view(NULL), - m_driver_device(NULL), m_current_phase(MACHINE_PHASE_PREINIT), m_paused(false), m_hard_reset_pending(false), @@ -194,21 +192,19 @@ running_machine::running_machine(const machine_config &_config, osd_interface &o memset(&m_base_time, 0, sizeof(m_base_time)); // set the machine on all devices - const_cast<device_list &>(devicelist()).set_machine_all(*this); - - // find the driver device config and tell it which game - m_driver_device = device<driver_device>("root"); - if (m_driver_device == NULL) - throw emu_fatalerror("Machine configuration missing driver_device"); + device_iterator iter(root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) + device->set_machine(*this); // find devices - primary_screen = downcast<screen_device *>(devicelist().first(SCREEN)); - for (device_t *device = devicelist().first(); device != NULL; device = device->next()) + 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()) @@ -318,8 +314,12 @@ void running_machine::start() // so this location in the init order is important ui_set_startup_text(*this, "Initializing...", true); - // start up the devices - const_cast<device_list &>(devicelist()).start_all(); + // register callbacks for the devices, then start them + add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(running_machine::reset_all_devices), this)); + add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(running_machine::stop_all_devices), this)); + save().register_presave(save_prepost_delegate(FUNC(running_machine::presave_all_devices), this)); + save().register_postload(save_prepost_delegate(FUNC(running_machine::postload_all_devices), this)); + start_all_devices(); // if we're coming in with a savegame request, process it now const char *savegame = options().state(); @@ -344,25 +344,15 @@ void running_machine::start() device_t &running_machine::add_dynamic_device(device_t &owner, device_type type, const char *tag, UINT32 clock) { - // allocate and append this device - astring fulltag; - owner.subtag(fulltag, tag); - device_t &device = const_cast<device_list &>(devicelist()).append(fulltag, *type(m_config, fulltag, &owner, clock)); - - // append any machine config additions from new devices - for (device_t *curdevice = devicelist().first(); curdevice != NULL; curdevice = curdevice->next()) - if (!curdevice->configured()) - { - machine_config_constructor machconfig = curdevice->machine_config_additions(); - if (machconfig != NULL) - (*machconfig)(const_cast<machine_config &>(m_config), curdevice); - } - - // notify any new devices that their configurations are complete - for (device_t *curdevice = devicelist().first(); curdevice != NULL; curdevice = curdevice->next()) - if (!curdevice->configured()) - curdevice->config_complete(); - return device; + // 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; } @@ -633,6 +623,7 @@ void running_machine::resume() memory_region *running_machine::region_alloc(const char *name, UINT32 length, UINT8 width, endianness_t endian) { +mame_printf_verbose("Region '%s' created\n", name); // make sure we don't have a region of the same name; also find the end of the list memory_region *info = m_regionlist.find(name); if (info != NULL) @@ -887,6 +878,115 @@ void running_machine::logfile_callback(running_machine &machine, const char *buf machine.m_logfile->puts(buffer); } + +//------------------------------------------------- +// start_all_devices - start any unstarted devices +//------------------------------------------------- + +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; + } +} + + +//------------------------------------------------- +// reset_all_devices - reset all devices in the +// hierarchy +//------------------------------------------------- + +void running_machine::reset_all_devices() +{ + // iterate over devices and reset them + device_iterator iter(root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) + device->reset(); +} + + +//------------------------------------------------- +// stop_all_devices - stop all the devices in the +// hierarchy +//------------------------------------------------- + +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(); + + // then nuke the device tree +// global_free(m_root_device); +} + + +//------------------------------------------------- +// presave_all_devices - tell all the devices we +// are about to save +//------------------------------------------------- + +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(); +} + + +//------------------------------------------------- +// postload_all_devices - tell all the devices we +// just completed a load +//------------------------------------------------- + +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(); +} + + + /*************************************************************************** MEMORY REGIONS ***************************************************************************/ @@ -1143,8 +1243,10 @@ ioport_constructor driver_device::device_input_ports() const void driver_device::device_start() { // reschedule ourselves to be last - if (next() != NULL) - throw device_missing_dependencies(); + device_iterator iter(*this); + for (device_t *test = iter.first(); test != NULL; test = iter.next()) + if (test != this && !test->started()) + throw device_missing_dependencies(); // call the game-specific init if (m_system->driver_init != NULL) diff --git a/src/emu/machine.h b/src/emu/machine.h index f80d60ef84a..dbaf69f93fc 100644 --- a/src/emu/machine.h +++ b/src/emu/machine.h @@ -186,7 +186,6 @@ class osd_interface; typedef struct _memory_private memory_private; typedef struct _palette_private palette_private; typedef struct _romload_private romload_private; -typedef struct _input_private input_private; typedef struct _input_port_private input_port_private; typedef struct _ui_input_private ui_input_private; typedef struct _debugcpu_private debugcpu_private; @@ -331,7 +330,7 @@ public: // getters const machine_config &config() const { return m_config; } - const device_list &devicelist() const { return m_config.devicelist(); } + device_t &root_device() const { return m_config.root_device(); } const game_driver &system() const { return m_system; } osd_interface &osd() const { return m_osd; } resource_pool &respool() { return m_respool; } @@ -344,8 +343,8 @@ public: video_manager &video() const { assert(m_video != NULL); return *m_video; } tilemap_manager &tilemap() const { assert(m_tilemap != NULL); return *m_tilemap; } debug_view_manager &debug_view() const { assert(m_debug_view != NULL); return *m_debug_view; } - driver_device *driver_data() const { return m_driver_device; } - template<class _DriverClass> _DriverClass *driver_data() const { return downcast<_DriverClass *>(m_driver_device); } + driver_device *driver_data() const { return &downcast<driver_device &>(root_device()); } + template<class _DriverClass> _DriverClass *driver_data() const { return &downcast<_DriverClass &>(root_device()); } machine_phase phase() const { return m_current_phase; } bool paused() const { return m_paused || (m_current_phase != MACHINE_PHASE_RUNNING); } bool exit_pending() const { return m_exit_pending; } @@ -364,7 +363,7 @@ public: bool scheduled_event_pending() const { return m_exit_pending || m_hard_reset_pending; } // fetch items by name - inline device_t *device(const char *tag); + inline device_t *device(const char *tag) { return root_device().subdevice(tag); } template<class _DeviceClass> inline _DeviceClass *device(const char *tag) { return downcast<_DeviceClass *>(device(tag)); } inline const input_port_config *port(const char *tag); inline const memory_region *region(const char *tag); @@ -408,7 +407,7 @@ public: ioport_list m_portlist; // points to a list of input port configurations // CPU information - cpu_device * firstcpu; // first CPU (allows for quick iteration via typenext) + cpu_device * firstcpu; // first CPU // video-related information gfx_element * gfx[MAX_GFX_ELEMENTS];// array of pointers to graphic sets (chars, sprites) @@ -419,7 +418,7 @@ public: const pen_t * pens; // remapped palette pen numbers colortable_t * colortable; // global colortable for remapping pen_t * shadow_table; // table for looking up a shadowed pen - bitmap_ind8 priority_bitmap; // priority bitmap + bitmap_ind8 priority_bitmap; // priority bitmap // debugger-related information UINT32 debug_flags; // the current debug flags @@ -431,7 +430,6 @@ public: memory_private * memory_data; // internal data from memory.c palette_private * palette_data; // internal data from palette.c romload_private * romload_data; // internal data from romload.c - input_private * input_data; // internal data from input.c input_port_private * input_port_data; // internal data from inptport.c ui_input_private * ui_input_data; // internal data from uiinput.c debugcpu_private * debugcpu_data; // internal data from debugcpu.c @@ -446,10 +444,17 @@ private: void fill_systime(system_time &systime, time_t t); void handle_saveload(); void soft_reset(void *ptr = NULL, INT32 param = 0); - + // internal callbacks static void logfile_callback(running_machine &machine, const char *buffer); + // internal device helpers + void start_all_devices(); + void reset_all_devices(); + void stop_all_devices(); + void presave_all_devices(); + void postload_all_devices(); + // internal state const machine_config & m_config; // reference to the constructed machine_config const game_driver & m_system; // reference to the definition of the game machine @@ -469,9 +474,6 @@ private: tilemap_manager * m_tilemap; // internal data from tilemap.c debug_view_manager * m_debug_view; // internal data from debugvw.c - // driver state - driver_device * m_driver_device; // pointer to the current driver device - // system state machine_phase m_current_phase; // current execution phase bool m_paused; // paused? @@ -716,25 +718,26 @@ device_t *driver_device_creator(const machine_config &mconfig, const char *tag, // INLINE FUNCTIONS //************************************************************************** -inline device_t *running_machine::device(const char *tag) -{ - return devicelist().find(tag); -} - inline const input_port_config *running_machine::port(const char *tag) { - return m_portlist.find(tag); + // if tag begins with a :, it's absolute + if (tag[0] == ':') + return m_portlist.find(tag); + + // otherwise, compute it relative to the root device + astring fulltag; + return m_portlist.find(root_device().subtag(fulltag, tag).cstr()); } inline const memory_region *running_machine::region(const char *tag) { // if tag begins with a :, it's absolute if (tag[0] == ':') - { - return m_regionlist.find(&tag[1]); - } + return m_regionlist.find(tag); - return m_regionlist.find(tag); + // otherwise, compute it relative to the root device + astring fulltag; + return m_regionlist.find(root_device().subtag(fulltag, tag).cstr()); } diff --git a/src/emu/machine/6532riot.c b/src/emu/machine/6532riot.c index da5bcc2105f..c8a2dfcdbb1 100644 --- a/src/emu/machine/6532riot.c +++ b/src/emu/machine/6532riot.c @@ -469,7 +469,8 @@ void riot6532_device::device_start() assert(this != NULL); /* set static values */ - m_index = machine().devicelist().indexof(RIOT6532, tag()); + device_type_iterator<&device_creator<riot6532_device>, riot6532_device> iter(machine().root_device()); + m_index = iter.indexof(*this); /* configure the ports */ m_port[0].m_in_func.resolve(m_in_a_cb, *this); diff --git a/src/emu/machine/7474.c b/src/emu/machine/7474.c index 5a9c957cc57..0c5570913a9 100644 --- a/src/emu/machine/7474.c +++ b/src/emu/machine/7474.c @@ -86,7 +86,7 @@ void ttl7474_device::static_set_output_cb(device_t &device, write_line_device_fu if (callback != NULL) { ttl7474.m_output_cb.type = DEVCB_TYPE_DEVICE; - ttl7474.m_output_cb.index = DEVCB_DEVICE_OTHER; + ttl7474.m_output_cb.index = 0; ttl7474.m_output_cb.writeline = callback; } else @@ -105,7 +105,7 @@ void ttl7474_device::static_set_comp_output_cb(device_t &device, write_line_devi if (callback != NULL) { ttl7474.m_comp_output_cb.type = DEVCB_TYPE_DEVICE; - ttl7474.m_comp_output_cb.index = DEVCB_DEVICE_OTHER; + ttl7474.m_comp_output_cb.index = 0; ttl7474.m_comp_output_cb.writeline = callback; } else diff --git a/src/emu/machine/at28c16.c b/src/emu/machine/at28c16.c index 1101b3ee8e4..bfb66894cec 100644 --- a/src/emu/machine/at28c16.c +++ b/src/emu/machine/at28c16.c @@ -65,9 +65,8 @@ void at28c16_device::device_config_complete() // on this device //------------------------------------------------- -bool at28c16_device::device_validity_check( emu_options &options, const game_driver &driver ) const +void at28c16_device::device_validity_check(validity_checker &valid) const { - return false; } diff --git a/src/emu/machine/at28c16.h b/src/emu/machine/at28c16.h index a891d51881b..d81fe6abe0e 100644 --- a/src/emu/machine/at28c16.h +++ b/src/emu/machine/at28c16.h @@ -52,7 +52,7 @@ public: protected: // device-level overrides virtual void device_config_complete(); - virtual bool device_validity_check( emu_options &options, const game_driver &driver ) const; + virtual void device_validity_check(validity_checker &valid) const; virtual void device_start(); virtual void device_reset(); diff --git a/src/emu/machine/ctronics.c b/src/emu/machine/ctronics.c index 2fb045b8894..a06cf944c8b 100644 --- a/src/emu/machine/ctronics.c +++ b/src/emu/machine/ctronics.c @@ -101,7 +101,7 @@ static DEVICE_START( centronics ) centronics->strobe = TRUE; /* get printer device */ - centronics->printer = downcast<printer_image_device *>(device->subdevice("printer")); + centronics->printer = device->subdevice<printer_image_device>("printer"); /* resolve callbacks */ centronics->out_ack_func.resolve(intf->out_ack_func, *device); diff --git a/src/emu/machine/eeprom.c b/src/emu/machine/eeprom.c index 129c9968c11..11929be6b77 100644 --- a/src/emu/machine/eeprom.c +++ b/src/emu/machine/eeprom.c @@ -170,17 +170,10 @@ void eeprom_device::static_set_default_value(device_t &device, UINT16 value) // on this device //------------------------------------------------- -bool eeprom_device::device_validity_check(emu_options &options, const game_driver &driver) const +void eeprom_device::device_validity_check(validity_checker &valid) const { - bool error = false; - if (m_data_bits != 8 && m_data_bits != 16) - { - mame_printf_error("%s: %s eeprom device '%s' specified invalid data width %d\n", driver.source_file, driver.name, tag(), m_data_bits); - error = true; - } - - return error; + mame_printf_error("Invalid data width %d specified\n", m_data_bits); } diff --git a/src/emu/machine/eeprom.h b/src/emu/machine/eeprom.h index 31c44d15ec1..c7605dec4db 100644 --- a/src/emu/machine/eeprom.h +++ b/src/emu/machine/eeprom.h @@ -86,7 +86,7 @@ public: protected: // device-level overrides - virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; + virtual void device_validity_check(validity_checker &valid) const; virtual void device_start(); virtual void device_reset(); diff --git a/src/emu/machine/generic.c b/src/emu/machine/generic.c index 5a809bdb158..ba6192d3c91 100644 --- a/src/emu/machine/generic.c +++ b/src/emu/machine/generic.c @@ -94,9 +94,9 @@ void generic_machine_init(running_machine &machine) // map devices to the interrupt state memset(state->interrupt_device, 0, sizeof(state->interrupt_device)); - device_execute_interface *exec = NULL; + execute_interface_iterator iter(machine.root_device()); int index = 0; - for (bool gotone = machine.devicelist().first(exec); gotone && index < ARRAY_LENGTH(state->interrupt_device); gotone = exec->next(exec)) + for (device_execute_interface *exec = iter.first(); exec != NULL && index < ARRAY_LENGTH(state->interrupt_device); exec = iter.next()) state->interrupt_device[index++] = &exec->device(); /* register coin save state */ @@ -364,23 +364,18 @@ void nvram_load(running_machine &machine) } } - device_nvram_interface *nvram = NULL; - if (machine.devicelist().first(nvram)) + nvram_interface_iterator iter(machine.root_device()); + for (device_nvram_interface *nvram = iter.first(); nvram != NULL; nvram = iter.next()) { - for (bool gotone = (nvram != NULL); gotone; gotone = nvram->next(nvram)) + astring filename; + emu_file file(machine.options().nvram_directory(), OPEN_FLAG_READ); + if (file.open(nvram_filename(nvram->device(),filename)) == FILERR_NONE) { - astring filename; - emu_file file(machine.options().nvram_directory(), OPEN_FLAG_READ); - if (file.open(nvram_filename(nvram->device(),filename)) == FILERR_NONE) - { - nvram->nvram_load(file); - file.close(); - } - else - { - nvram->nvram_reset(); - } + nvram->nvram_load(file); + file.close(); } + else + nvram->nvram_reset(); } } @@ -402,18 +397,15 @@ void nvram_save(running_machine &machine) } } - device_nvram_interface *nvram = NULL; - if (machine.devicelist().first(nvram)) + nvram_interface_iterator iter(machine.root_device()); + for (device_nvram_interface *nvram = iter.first(); nvram != NULL; nvram = iter.next()) { - for (bool gotone = (nvram != NULL); gotone; gotone = nvram->next(nvram)) + astring filename; + emu_file file(machine.options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + if (file.open(nvram_filename(nvram->device(),filename)) == FILERR_NONE) { - astring filename; - emu_file file(machine.options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file.open(nvram_filename(nvram->device(),filename)) == FILERR_NONE) - { - nvram->nvram_save(file); - file.close(); - } + nvram->nvram_save(file); + file.close(); } } } diff --git a/src/emu/machine/i2cmem.c b/src/emu/machine/i2cmem.c index 0aaacf24026..288a430de7c 100644 --- a/src/emu/machine/i2cmem.c +++ b/src/emu/machine/i2cmem.c @@ -125,10 +125,8 @@ void i2cmem_device::device_config_complete() // on this device //------------------------------------------------- -bool i2cmem_device::device_validity_check( emu_options &options, const game_driver &driver ) const +void i2cmem_device::device_validity_check(validity_checker &valid) const { - bool error = false; - return error; } diff --git a/src/emu/machine/i2cmem.h b/src/emu/machine/i2cmem.h index f0c6aa14deb..1dded6826fd 100644 --- a/src/emu/machine/i2cmem.h +++ b/src/emu/machine/i2cmem.h @@ -70,7 +70,7 @@ public: protected: // device-level overrides virtual void device_config_complete(); - virtual bool device_validity_check( emu_options &options, const game_driver &driver ) const; + virtual void device_validity_check(validity_checker &valid) const; virtual void device_start(); virtual void device_reset(); diff --git a/src/emu/machine/i8243.c b/src/emu/machine/i8243.c index cf1355585eb..cb1650413d2 100644 --- a/src/emu/machine/i8243.c +++ b/src/emu/machine/i8243.c @@ -41,7 +41,8 @@ void i8243_device::static_set_read_handler(device_t &device, read8_device_func c if(callback != NULL) { i8243.m_readhandler_cb.type = DEVCB_TYPE_DEVICE; - i8243.m_readhandler_cb.index = DEVCB_DEVICE_SELF; + i8243.m_readhandler_cb.index = 0; + i8243.m_readhandler_cb.tag = ""; i8243.m_readhandler_cb.readdevice = callback; } else @@ -62,7 +63,8 @@ void i8243_device::static_set_write_handler(device_t &device, write8_device_func if(callback != NULL) { i8243.m_writehandler_cb.type = DEVCB_TYPE_DEVICE; - i8243.m_writehandler_cb.index = DEVCB_DEVICE_SELF; + i8243.m_writehandler_cb.index = 0; + i8243.m_writehandler_cb.tag = ""; i8243.m_writehandler_cb.writedevice = callback; } else diff --git a/src/emu/machine/laserdsc.h b/src/emu/machine/laserdsc.h index 185b2296586..b7c0df154e9 100644 --- a/src/emu/machine/laserdsc.h +++ b/src/emu/machine/laserdsc.h @@ -380,6 +380,9 @@ private: render_texture * m_overtex; // texture for the overlay }; +// iterator - interface iterator works for subclasses too +typedef device_interface_iterator<laserdisc_device> laserdisc_device_iterator; + //************************************************************************** diff --git a/src/emu/machine/mb3773.c b/src/emu/machine/mb3773.c index 925def0a33f..cfe37d36eb7 100644 --- a/src/emu/machine/mb3773.c +++ b/src/emu/machine/mb3773.c @@ -47,9 +47,8 @@ void mb3773_device::device_config_complete() // on this device //------------------------------------------------- -bool mb3773_device::device_validity_check( emu_options &options, const game_driver &driver ) const +void mb3773_device::device_validity_check(validity_checker &valid) const { - return false; } diff --git a/src/emu/machine/mb3773.h b/src/emu/machine/mb3773.h index 24874b3f534..b139477f2dc 100644 --- a/src/emu/machine/mb3773.h +++ b/src/emu/machine/mb3773.h @@ -35,7 +35,7 @@ public: protected: // device-level overrides virtual void device_config_complete(); - virtual bool device_validity_check( emu_options &options, const game_driver &driver ) const; + virtual void device_validity_check(validity_checker &valid) const; virtual void device_start(); virtual void device_reset(); diff --git a/src/emu/machine/msm6242.c b/src/emu/machine/msm6242.c index dd7bda24758..cc859c84e28 100644 --- a/src/emu/machine/msm6242.c +++ b/src/emu/machine/msm6242.c @@ -121,10 +121,8 @@ TIMER_CALLBACK( msm6242_device::rtc_inc_callback ) // on this device //------------------------------------------------- -bool msm6242_device::device_validity_check(emu_options &options, const game_driver &driver) const +void msm6242_device::device_validity_check(validity_checker &valid) const { - bool error = false; - return error; } //------------------------------------------------- diff --git a/src/emu/machine/msm6242.h b/src/emu/machine/msm6242.h index 3addb6b9df9..21b57dc1f5e 100644 --- a/src/emu/machine/msm6242.h +++ b/src/emu/machine/msm6242.h @@ -55,7 +55,7 @@ public: protected: // device-level overrides virtual void device_config_complete(); - virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; + virtual void device_validity_check(validity_checker &valid) const; virtual void device_start(); virtual void device_reset(); diff --git a/src/emu/machine/ram.c b/src/emu/machine/ram.c index 3c69f5e54dd..7c9648dbc47 100644 --- a/src/emu/machine/ram.c +++ b/src/emu/machine/ram.c @@ -75,38 +75,32 @@ void ram_device::device_start() // checks //------------------------------------------------- -bool ram_device::device_validity_check(emu_options &options, const game_driver &driver) const +void ram_device::device_validity_check(validity_checker &valid) const { const char *ramsize_string = NULL; int is_valid = FALSE; UINT32 specified_ram = 0; - bool error = FALSE; const char *gamename_option = NULL; /* verify default ram value */ if (default_size() == 0) - { - mame_printf_error("%s: '%s' has an invalid default RAM option: %s\n", driver.source_file, driver.name, m_default_size); - error = TRUE; - } + mame_printf_error("Invalid default RAM option: %s\n", m_default_size); /* command line options are only parsed for the device named RAM_TAG */ if (tag() != NULL && strcmp(tag(), RAM_TAG) == 0) { /* verify command line ram option */ - ramsize_string = options.ram_size(); - gamename_option = options.system_name(); + ramsize_string = mconfig().options().ram_size(); + gamename_option = mconfig().options().system_name(); if ((ramsize_string != NULL) && (ramsize_string[0] != '\0')) { specified_ram = parse_string(ramsize_string); if (specified_ram == 0) - { - mame_printf_error("%s: '%s' cannot recognize the RAM option %s\n", driver.source_file, driver.name, ramsize_string); - error = TRUE; - } - if (gamename_option != NULL && *gamename_option != 0 && strcmp(gamename_option, driver.name) == 0) + mame_printf_error("Cannot recognize the RAM option %s\n", ramsize_string); + + if (gamename_option != NULL && *gamename_option != 0 && strcmp(gamename_option, mconfig().gamedrv().name) == 0) { /* compare command line option to default value */ if (default_size() == specified_ram) @@ -130,10 +124,7 @@ bool ram_device::device_validity_check(emu_options &options, const game_driver & UINT32 option_ram_size = parse_string(p); if (option_ram_size == 0) - { - mame_printf_error("%s: '%s' has an invalid RAM option: %s\n", driver.source_file, driver.name, p); - error = TRUE; - } + mame_printf_error("Invalid RAM option: %s\n", p); if (option_ram_size == specified_ram) is_valid = TRUE; @@ -163,18 +154,17 @@ bool ram_device::device_validity_check(emu_options &options, const game_driver & if (!is_valid) { - mame_printf_error("%s: '%s' cannot recognize the RAM option %s", driver.source_file, driver.name, ramsize_string); - mame_printf_error(" (valid options are %s", m_default_size); + astring output; + output.catprintf("Cannot recognize the RAM option %s", ramsize_string); + output.catprintf(" (valid options are %s", m_default_size); if (m_extra_options != NULL) - mame_printf_error(",%s).\n", m_extra_options); + output.catprintf(",%s).\n", m_extra_options); else - mame_printf_error(").\n"); + output.catprintf(").\n"); - error = TRUE; + mame_printf_error("%s", output.cstr()); } - - return error; } diff --git a/src/emu/machine/ram.h b/src/emu/machine/ram.h index 43a363aa0ca..238d7dcfabd 100644 --- a/src/emu/machine/ram.h +++ b/src/emu/machine/ram.h @@ -65,7 +65,7 @@ public: protected: virtual void device_start(void); - virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; + virtual void device_validity_check(validity_checker &valid) const; private: // device state @@ -82,4 +82,7 @@ private: // device type definition extern const device_type RAM; +// device iterator +typedef device_type_iterator<&device_creator<ram_device>, ram_device> ram_device_iterator; + #endif /* __RAM_H__ */ diff --git a/src/emu/machine/rtc9701.c b/src/emu/machine/rtc9701.c index 2ac36ee0072..7812a858696 100644 --- a/src/emu/machine/rtc9701.c +++ b/src/emu/machine/rtc9701.c @@ -81,10 +81,8 @@ TIMER_CALLBACK( rtc9701_device::rtc_inc_callback ) // on this device //------------------------------------------------- -bool rtc9701_device::device_validity_check(emu_options &options, const game_driver &driver) const +void rtc9701_device::device_validity_check(validity_checker &valid) const { - bool error = false; - return error; } //------------------------------------------------- diff --git a/src/emu/machine/rtc9701.h b/src/emu/machine/rtc9701.h index 4d633167e66..9c5b96be74c 100644 --- a/src/emu/machine/rtc9701.h +++ b/src/emu/machine/rtc9701.h @@ -62,7 +62,7 @@ public: protected: // device-level overrides - virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; + virtual void device_validity_check(validity_checker &valid) const; virtual void device_start(); virtual void device_reset(); diff --git a/src/emu/machine/scsihd.c b/src/emu/machine/scsihd.c index 606350800b1..05f372aa6e9 100644 --- a/src/emu/machine/scsihd.c +++ b/src/emu/machine/scsihd.c @@ -279,7 +279,8 @@ static void scsihd_alloc_instance( SCSIInstance *scsiInstance, const char *diskr if (our_this->disk == NULL) { // try to locate the CHD from an image subdevice - for (device_t *device = machine.devicelist().first(); device != NULL; device = device->next()) + device_iterator iter(machine.root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) { if (device->subdevice(diskregion) != NULL) { diff --git a/src/emu/machine/v3021.c b/src/emu/machine/v3021.c index 66b788a36f1..13d2d5796a4 100644 --- a/src/emu/machine/v3021.c +++ b/src/emu/machine/v3021.c @@ -78,10 +78,8 @@ TIMER_CALLBACK( v3021_device::rtc_inc_callback ) // on this device //------------------------------------------------- -bool v3021_device::device_validity_check(emu_options &options, const game_driver &driver) const +void v3021_device::device_validity_check(validity_checker &valid) const { - bool error = false; - return error; } //------------------------------------------------- diff --git a/src/emu/machine/v3021.h b/src/emu/machine/v3021.h index 9a8bec9c3b2..af826448fbd 100644 --- a/src/emu/machine/v3021.h +++ b/src/emu/machine/v3021.h @@ -48,7 +48,7 @@ public: protected: // device-level overrides - virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; + virtual void device_validity_check(validity_checker &valid) const; virtual void device_start(); virtual void device_reset(); diff --git a/src/emu/machine/wd17xx.c b/src/emu/machine/wd17xx.c index b1e9b5e4beb..b0d19483609 100644 --- a/src/emu/machine/wd17xx.c +++ b/src/emu/machine/wd17xx.c @@ -1247,14 +1247,7 @@ void wd17xx_set_drive(device_t *device, UINT8 drive) if (w->intf->floppy_drive_tags[drive] != NULL) { - if (device->owner() != NULL) { - w->drive = device->owner()->subdevice(w->intf->floppy_drive_tags[drive]); - if (w->drive == NULL) { - w->drive = device->machine().device(w->intf->floppy_drive_tags[drive]); - } - } - else - w->drive = device->machine().device(w->intf->floppy_drive_tags[drive]); + w->drive = device->siblingdevice(w->intf->floppy_drive_tags[drive]); } } @@ -2083,14 +2076,7 @@ static DEVICE_RESET( wd1770 ) if(w->intf->floppy_drive_tags[i]!=NULL) { device_t *img = NULL; - if (device->owner() != NULL) - img = device->owner()->subdevice(w->intf->floppy_drive_tags[i]); - if (img == NULL) { - img = device->machine().device(w->intf->floppy_drive_tags[i]); - } - - else - img = device->machine().device(w->intf->floppy_drive_tags[i]); + img = device->siblingdevice(w->intf->floppy_drive_tags[i]); if (img!=NULL) { floppy_drive_set_controller(img,device); diff --git a/src/emu/mame.c b/src/emu/mame.c index 5407fe4c2d6..c5a523251a6 100644 --- a/src/emu/mame.c +++ b/src/emu/mame.c @@ -104,8 +104,21 @@ static bool print_verbose = false; static running_machine *global_machine; /* output channels */ -static output_callback_func output_cb[OUTPUT_CHANNEL_COUNT]; -static void *output_cb_param[OUTPUT_CHANNEL_COUNT]; +static output_delegate output_cb[OUTPUT_CHANNEL_COUNT] = +{ + output_delegate(FUNC(mame_file_output_callback), stderr), // OUTPUT_CHANNEL_ERROR + output_delegate(FUNC(mame_file_output_callback), stderr), // OUTPUT_CHANNEL_WARNING + output_delegate(FUNC(mame_file_output_callback), stdout), // OUTPUT_CHANNEL_INFO +#ifdef MAME_DEBUG + output_delegate(FUNC(mame_file_output_callback), stdout), // OUTPUT_CHANNEL_DEBUG +#else + output_delegate(FUNC(mame_null_output_callback), stdout), // OUTPUT_CHANNEL_DEBUG +#endif + output_delegate(FUNC(mame_file_output_callback), stdout), // OUTPUT_CHANNEL_VERBOSE + output_delegate(FUNC(mame_file_output_callback), stdout) // OUTPUT_CHANNEL_LOG +}; + + /*************************************************************************** CORE IMPLEMENTATION @@ -151,7 +164,10 @@ int mame_execute(emu_options &options, osd_interface &osd) // otherwise, perform validity checks before anything else else - validate_drivers(options, system); + { + validity_checker valid(options); + valid.check_shared_source(*system); + } firstgame = false; @@ -203,20 +219,17 @@ int mame_execute(emu_options &options, osd_interface &osd) channel -------------------------------------------------*/ -void mame_set_output_channel(output_channel channel, output_callback_func callback, void *param, output_callback_func *prevcb, void **prevparam) +output_delegate mame_set_output_channel(output_channel channel, output_delegate callback) { assert(channel < OUTPUT_CHANNEL_COUNT); - assert(callback != NULL); + assert(!callback.isnull()); /* return the originals if requested */ - if (prevcb != NULL) - *prevcb = output_cb[channel]; - if (prevparam != NULL) - *prevparam = output_cb_param[channel]; + output_delegate prevcb = output_cb[channel]; /* set the new ones */ output_cb[channel] = callback; - output_cb_param[channel] = param; + return prevcb; } @@ -225,9 +238,9 @@ void mame_set_output_channel(output_channel channel, output_callback_func callba for file output -------------------------------------------------*/ -void mame_file_output_callback(void *param, const char *format, va_list argptr) +void mame_file_output_callback(FILE *param, const char *format, va_list argptr) { - vfprintf((FILE *)param, format, argptr); + vfprintf(param, format, argptr); } @@ -236,7 +249,7 @@ void mame_file_output_callback(void *param, const char *format, va_list argptr) for no output -------------------------------------------------*/ -void mame_null_output_callback(void *param, const char *format, va_list argptr) +void mame_null_output_callback(FILE *param, const char *format, va_list argptr) { } @@ -250,16 +263,9 @@ void mame_printf_error(const char *format, ...) { va_list argptr; - /* by default, we go to stderr */ - if (output_cb[OUTPUT_CHANNEL_ERROR] == NULL) - { - output_cb[OUTPUT_CHANNEL_ERROR] = mame_file_output_callback; - output_cb_param[OUTPUT_CHANNEL_ERROR] = stderr; - } - /* do the output */ va_start(argptr, format); - (*output_cb[OUTPUT_CHANNEL_ERROR])(output_cb_param[OUTPUT_CHANNEL_ERROR], format, argptr); + output_cb[OUTPUT_CHANNEL_ERROR](format, argptr); va_end(argptr); } @@ -273,16 +279,9 @@ void mame_printf_warning(const char *format, ...) { va_list argptr; - /* by default, we go to stderr */ - if (output_cb[OUTPUT_CHANNEL_WARNING] == NULL) - { - output_cb[OUTPUT_CHANNEL_WARNING] = mame_file_output_callback; - output_cb_param[OUTPUT_CHANNEL_WARNING] = stderr; - } - /* do the output */ va_start(argptr, format); - (*output_cb[OUTPUT_CHANNEL_WARNING])(output_cb_param[OUTPUT_CHANNEL_WARNING], format, argptr); + output_cb[OUTPUT_CHANNEL_WARNING](format, argptr); va_end(argptr); } @@ -296,16 +295,9 @@ void mame_printf_info(const char *format, ...) { va_list argptr; - /* by default, we go to stdout */ - if (output_cb[OUTPUT_CHANNEL_INFO] == NULL) - { - output_cb[OUTPUT_CHANNEL_INFO] = mame_file_output_callback; - output_cb_param[OUTPUT_CHANNEL_INFO] = stdout; - } - /* do the output */ va_start(argptr, format); - (*output_cb[OUTPUT_CHANNEL_INFO])(output_cb_param[OUTPUT_CHANNEL_INFO], format, argptr); + output_cb[OUTPUT_CHANNEL_INFO](format, argptr); va_end(argptr); } @@ -323,16 +315,9 @@ void mame_printf_verbose(const char *format, ...) if (!print_verbose) return; - /* by default, we go to stdout */ - if (output_cb[OUTPUT_CHANNEL_VERBOSE] == NULL) - { - output_cb[OUTPUT_CHANNEL_VERBOSE] = mame_file_output_callback; - output_cb_param[OUTPUT_CHANNEL_VERBOSE] = stdout; - } - /* do the output */ va_start(argptr, format); - (*output_cb[OUTPUT_CHANNEL_VERBOSE])(output_cb_param[OUTPUT_CHANNEL_VERBOSE], format, argptr); + output_cb[OUTPUT_CHANNEL_VERBOSE](format, argptr); va_end(argptr); } @@ -346,21 +331,9 @@ void mame_printf_debug(const char *format, ...) { va_list argptr; - /* by default, we go to stderr */ - if (output_cb[OUTPUT_CHANNEL_DEBUG] == NULL) - { -#ifdef MAME_DEBUG - output_cb[OUTPUT_CHANNEL_DEBUG] = mame_file_output_callback; - output_cb_param[OUTPUT_CHANNEL_DEBUG] = stdout; -#else - output_cb[OUTPUT_CHANNEL_DEBUG] = mame_null_output_callback; - output_cb_param[OUTPUT_CHANNEL_DEBUG] = NULL; -#endif - } - /* do the output */ va_start(argptr, format); - (*output_cb[OUTPUT_CHANNEL_DEBUG])(output_cb_param[OUTPUT_CHANNEL_DEBUG], format, argptr); + output_cb[OUTPUT_CHANNEL_DEBUG](format, argptr); va_end(argptr); } @@ -375,16 +348,9 @@ void mame_printf_log(const char *format, ...) { va_list argptr; - /* by default, we go to stderr */ - if (output_cb[OUTPUT_CHANNEL_LOG] == NULL) - { - output_cb[OUTPUT_CHANNEL_LOG] = mame_file_output_callback; - output_cb_param[OUTPUT_CHANNEL_LOG] = stderr; - } - /* do the output */ va_start(argptr, format); - (*output_cb[OUTPUT_CHANNEL_LOG])(output_cb_param[OUTPUT_CHANNEL_LOG], format, argptr); + output_cb[OUTPUT_CHANNEL_LOG])(format, argptr); va_end(argptr); } #endif diff --git a/src/emu/mame.h b/src/emu/mame.h index 13b51c696fc..cdec7d1db1f 100644 --- a/src/emu/mame.h +++ b/src/emu/mame.h @@ -49,7 +49,7 @@ enum //************************************************************************** // output channel callback -typedef void (*output_callback_func)(void *param, const char *format, va_list argptr); +typedef delegate<void (const char *, va_list)> output_delegate; class emulator_info { @@ -76,6 +76,8 @@ public: static void printf_usage(const char *par1, const char *par2); }; + + //************************************************************************** // GLOBAL VARIABLES //************************************************************************** @@ -102,11 +104,11 @@ int mame_is_valid_machine(running_machine &machine); /* ----- output management ----- */ /* set the output handler for a channel, returns the current one */ -void mame_set_output_channel(output_channel channel, output_callback_func callback, void *param, output_callback_func *prevcb, void **prevparam); +output_delegate mame_set_output_channel(output_channel channel, output_delegate callback); /* built-in default callbacks */ -void mame_file_output_callback(void *param, const char *format, va_list argptr); -void mame_null_output_callback(void *param, const char *format, va_list argptr); +void mame_file_output_callback(FILE *file, const char *format, va_list argptr); +void mame_null_output_callback(FILE *param, const char *format, va_list argptr); /* calls to be used by the code */ void mame_printf_error(const char *format, ...) ATTR_PRINTF(1,2); diff --git a/src/emu/mconfig.c b/src/emu/mconfig.c index 6ef83f2e0ec..43c76b7ee7f 100644 --- a/src/emu/mconfig.c +++ b/src/emu/mconfig.c @@ -62,14 +62,15 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options) m_total_colors(0), m_default_layout(NULL), m_gamedrv(gamedrv), - m_options(options) + m_options(options), + m_root_device(NULL) { // construct the config (*gamedrv.machine_config)(*this, NULL); // intialize slot devices - make sure that any required devices have been allocated - device_slot_interface *slot = NULL; - for (bool gotone = m_devicelist.first(slot); gotone; gotone = slot->next(slot)) + 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) @@ -77,16 +78,19 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options) device_t &owner = slot->device(); const char *selval = options.value(owner.tag()); if (!options.exists(owner.tag())) - selval = slot->get_default_card(devicelist(), options); + selval = slot->get_default_card(*this, options); - if (selval != NULL && strlen(selval)!=0) { + if (selval != NULL && strlen(selval) != 0) + { bool found = false; - for (int i = 0; intf[i].name != NULL; i++) { - if (strcmp(selval, intf[i].name) == 0) { + for (int i = 0; intf[i].name != NULL; i++) + { + if (strcmp(selval, intf[i].name) == 0) + { device_t *new_dev = device_add(&owner, intf[i].name, intf[i].devtype, 0); found = true; - const char *def = slot->get_default_card(devicelist(), options); - if ((def!=NULL) && (strcmp(def,selval)==0)) + const char *def = slot->get_default_card(*this, options); + if (def != NULL && strcmp(def, selval) == 0) device_t::static_set_input_default(*new_dev, slot->input_ports_defaults()); } } @@ -97,13 +101,11 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options) } // when finished, set the game driver - device_t *root = m_devicelist.find("root"); - if (root == NULL) - throw emu_fatalerror("Machine configuration missing driver_device"); - driver_device::static_set_game(*root, gamedrv); + driver_device::static_set_game(*m_root_device, gamedrv); // then notify all devices that their configuration is complete - for (device_t *device = m_devicelist.first(); device != NULL; device = device->next()) + device_iterator iter(root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (!device->configured()) device->config_complete(); } @@ -115,6 +117,7 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options) machine_config::~machine_config() { + global_free(m_root_device); } @@ -125,46 +128,8 @@ machine_config::~machine_config() screen_device *machine_config::first_screen() const { - return downcast<screen_device *>(m_devicelist.first(SCREEN)); -} - - -//------------------------------------------------- -// device_add_subdevices - helper to add -// devices owned by the device -//------------------------------------------------- - -void machine_config::device_add_subdevices(device_t *device) -{ - machine_config_constructor additions = device->machine_config_additions(); - if (additions != NULL) - (*additions)(*this, device); -} - - -//------------------------------------------------- -// device_remove_subdevices - helper to remove -// devices owned by the device -//------------------------------------------------- - -void machine_config::device_remove_subdevices(const device_t *device) -{ - if (device != NULL) - { - device_t *sub_device = m_devicelist.first(); - while (sub_device != NULL) - { - if (sub_device->owner() == device) - device_remove_subdevices(sub_device); - - device_t *next_device = sub_device->next(); - - if (sub_device->owner() == device) - m_devicelist.remove(*sub_device); - - sub_device = next_device; - } - } + screen_device_iterator iter(root_device()); + return iter.first(); } @@ -175,11 +140,19 @@ void machine_config::device_remove_subdevices(const device_t *device) device_t *machine_config::device_add(device_t *owner, const char *tag, device_type type, UINT32 clock) { - astring tempstring; - const char *fulltag = owner->subtag(tempstring, tag); - device_t *device = &m_devicelist.append(fulltag, *(*type)(*this, fulltag, owner, clock)); - device_add_subdevices(device); - return device; + // if there's an owner, let the owner do the work + if (owner != NULL) + return owner->add_subdevice(type, tag, clock); + + // otherwise, allocate the device directly + assert(m_root_device == NULL); + m_root_device = (*type)(*this, tag, owner, clock); + + // apply any machine configuration owned by the device now + machine_config_constructor additions = m_root_device->machine_config_additions(); + if (additions != NULL) + (*additions)(*this, m_root_device); + return m_root_device; } @@ -190,12 +163,17 @@ device_t *machine_config::device_add(device_t *owner, const char *tag, device_ty device_t *machine_config::device_replace(device_t *owner, const char *tag, device_type type, UINT32 clock) { - astring tempstring; - const char *fulltag = owner->subtag(tempstring, tag); - device_remove_subdevices(m_devicelist.find(fulltag)); - device_t *device = &m_devicelist.replace_and_remove(fulltag, *(*type)(*this, fulltag, owner, clock)); - device_add_subdevices(device); - return device; + // find the original device by this name (must exist) + assert(owner != NULL); + device_t *device = owner->subdevice(tag); + if (device == NULL) + { + mame_printf_warning("Warning: attempting to replace non-existent device '%s'\n", tag); + return device_add(owner, tag, type, clock); + } + + // let the device's owner do the work + return device->owner()->replace_subdevice(*device, type, tag, clock); } @@ -206,11 +184,17 @@ device_t *machine_config::device_replace(device_t *owner, const char *tag, devic device_t *machine_config::device_remove(device_t *owner, const char *tag) { - astring tempstring; - const char *fulltag = owner->subtag(tempstring, tag); - device_t *device=m_devicelist.find(fulltag); - device_remove_subdevices(device); - m_devicelist.remove(*device); + // find the original device by this name (must exist) + assert(owner != NULL); + device_t *device = owner->subdevice(tag); + if (device == NULL) + { + mame_printf_warning("Warning: attempting to remove non-existent device '%s'\n", tag); + return NULL; + } + + // let the device's owner do the work + device->owner()->remove_subdevice(*device); return NULL; } @@ -222,10 +206,13 @@ device_t *machine_config::device_remove(device_t *owner, const char *tag) device_t *machine_config::device_find(device_t *owner, const char *tag) { - astring tempstring; - const char *fulltag = owner->subtag(tempstring, tag); - device_t *device = m_devicelist.find(fulltag); + // find the original device by this name (must exist) + assert(owner != NULL); + device_t *device = owner->subdevice(tag); + assert(device != NULL); if (device == NULL) - throw emu_fatalerror("Unable to find device: tag=%s\n", fulltag); + throw emu_fatalerror("Unable to find device '%s'\n", tag); + + // return the device return device; } diff --git a/src/emu/mconfig.h b/src/emu/mconfig.h index e4b619eba2a..73f7770cf92 100644 --- a/src/emu/mconfig.h +++ b/src/emu/mconfig.h @@ -131,10 +131,11 @@ public: // getters const game_driver &gamedrv() const { return m_gamedrv; } - const device_list &devicelist() const { return m_devicelist; } - const device_t *first_device() const { return m_devicelist.first(); } + device_t &root_device() const { assert(m_root_device != NULL); return *m_root_device; } screen_device *first_screen() const; emu_options &options() const { return m_options; } + inline device_t *device(const char *tag) const { return root_device().subdevice(tag); } + template<class _DeviceClass> inline _DeviceClass *device(const char *tag) const { return downcast<_DeviceClass *>(device(tag)); } // public state attotime m_minimum_quantum; // minimum scheduling quantum @@ -142,9 +143,11 @@ public: INT32 m_watchdog_vblank_count; // number of VBLANKs until the watchdog kills us attotime m_watchdog_time; // length of time until the watchdog kills us + // legacy callbacks nvram_handler_func m_nvram_handler; // NVRAM save/load callback memcard_handler_func m_memcard_handler; // memory card save/load callback + // other parameters UINT32 m_video_attributes; // flags describing the video system const gfx_decode_entry *m_gfxdecodeinfo; // pointer to array of graphics decoding information UINT32 m_total_colors; // total number of colors in the palette @@ -157,12 +160,10 @@ public: device_t *device_find(device_t *owner, const char *tag); private: - void device_add_subdevices(device_t *device); - void device_remove_subdevices(const device_t *device); - + // internal state const game_driver & m_gamedrv; emu_options & m_options; - device_list m_devicelist; // list of device configs + device_t * m_root_device; }; diff --git a/src/emu/memory.c b/src/emu/memory.c index dd11e6dd51c..521eb09d871 100644 --- a/src/emu/memory.c +++ b/src/emu/memory.c @@ -1726,8 +1726,8 @@ void memory_init(running_machine &machine) memdata->banknext = STATIC_BANK1; // loop over devices and spaces within each device - device_memory_interface *memory = NULL; - for (bool gotone = machine.devicelist().first(memory); gotone; gotone = memory->next(memory)) + memory_interface_iterator iter(machine.root_device()); + for (device_memory_interface *memory = iter.first(); memory != NULL; memory = iter.next()) for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++) { // if there is a configuration for this space, we need an address space @@ -1781,10 +1781,22 @@ address_space *memory_nonspecific_space(running_machine &machine) void memory_configure_bank(running_machine &machine, const char *tag, int startentry, int numentries, void *base, offs_t stride) { + memory_configure_bank(machine.root_device(), tag, startentry, numentries, base, stride); +} + + +//------------------------------------------------- +// memory_configure_bank - configure the +// addresses for a bank +//------------------------------------------------- + +void memory_configure_bank(device_t &device, const char *tag, int startentry, int numentries, void *base, offs_t stride) +{ // validation checks - memory_bank *bank = machine.memory_data->bankmap.find_hash_only(tag); + astring fulltag; + memory_bank *bank = device.machine().memory_data->bankmap.find_hash_only(device.subtag(fulltag, tag)); if (bank == NULL) - fatalerror("memory_configure_bank called for unknown bank '%s'", tag); + fatalerror("memory_configure_bank called for unknown bank '%s'", fulltag.cstr()); if (base == NULL) fatalerror("memory_configure_bank called NULL base"); @@ -1795,14 +1807,13 @@ void memory_configure_bank(running_machine &machine, const char *tag, int starte //------------------------------------------------- -// memory_configure_bank - configure the -// addresses for a bank +// memory_configure_bank_decrypted - configure +// the decrypted addresses for a bank //------------------------------------------------- -void memory_configure_bank(device_t *device, const char *tag, int startentry, int numentries, void *base, offs_t stride) +void memory_configure_bank_decrypted(running_machine &machine, const char *tag, int startentry, int numentries, void *base, offs_t stride) { - astring tempstring; - memory_configure_bank(device->machine(), device->subtag(tempstring, tag), startentry, numentries, base, stride); + memory_configure_bank_decrypted(machine.root_device(), tag, startentry, numentries, base, stride); } @@ -1811,12 +1822,13 @@ void memory_configure_bank(device_t *device, const char *tag, int startentry, in // the decrypted addresses for a bank //------------------------------------------------- -void memory_configure_bank_decrypted(running_machine &machine, const char *tag, int startentry, int numentries, void *base, offs_t stride) +void memory_configure_bank_decrypted(device_t &device, const char *tag, int startentry, int numentries, void *base, offs_t stride) { // validation checks - memory_bank *bank = machine.memory_data->bankmap.find_hash_only(tag); + astring fulltag; + memory_bank *bank = device.machine().memory_data->bankmap.find_hash_only(device.subtag(fulltag, tag)); if (bank == NULL) - fatalerror("memory_configure_bank_decrypted called for unknown bank '%s'", tag); + fatalerror("memory_configure_bank_decrypted called for unknown bank '%s'", fulltag.cstr()); if (base == NULL) fatalerror("memory_configure_bank_decrypted called NULL base"); @@ -1827,14 +1839,13 @@ void memory_configure_bank_decrypted(running_machine &machine, const char *tag, //------------------------------------------------- -// memory_configure_bank_decrypted - configure -// the decrypted addresses for a bank +// memory_set_bank - select one pre-configured +// entry to be the new bank base //------------------------------------------------- -void memory_configure_bank_decrypted(device_t *device, const char *tag, int startentry, int numentries, void *base, offs_t stride) +void memory_set_bank(running_machine &machine, const char *tag, int entrynum) { - astring tempstring; - memory_configure_bank_decrypted(device->machine(), device->subtag(tempstring, tag), startentry, numentries, base, stride); + memory_set_bank(machine.root_device(), tag, entrynum); } @@ -1843,12 +1854,13 @@ void memory_configure_bank_decrypted(device_t *device, const char *tag, int star // entry to be the new bank base //------------------------------------------------- -void memory_set_bank(running_machine &machine, const char *tag, int entrynum) +void memory_set_bank(device_t &device, const char *tag, int entrynum) { // validation checks - memory_bank *bank = machine.memory_data->bankmap.find_hash_only(tag); + astring fulltag; + memory_bank *bank = device.machine().memory_data->bankmap.find_hash_only(device.subtag(fulltag, tag)); if (bank == NULL) - fatalerror("memory_set_bank called for unknown bank '%s'", tag); + fatalerror("memory_set_bank called for unknown bank '%s'", fulltag.cstr()); // set the base bank->set_entry(entrynum); @@ -1856,14 +1868,13 @@ void memory_set_bank(running_machine &machine, const char *tag, int entrynum) //------------------------------------------------- -// memory_set_bank - select one pre-configured -// entry to be the new bank base +// memory_get_bank - return the currently +// selected bank //------------------------------------------------- -void memory_set_bank(device_t *device, const char *tag, int entrynum) +int memory_get_bank(running_machine &machine, const char *tag) { - astring tempstring; - memory_set_bank(device->machine(), device->subtag(tempstring, tag), entrynum); + return memory_get_bank(machine.root_device(), tag); } @@ -1872,12 +1883,13 @@ void memory_set_bank(device_t *device, const char *tag, int entrynum) // selected bank //------------------------------------------------- -int memory_get_bank(running_machine &machine, const char *tag) +int memory_get_bank(device_t &device, const char *tag) { // validation checks - memory_bank *bank = machine.memory_data->bankmap.find_hash_only(tag); + astring fulltag; + memory_bank *bank = device.machine().memory_data->bankmap.find_hash_only(device.subtag(fulltag, tag)); if (bank == NULL) - fatalerror("memory_get_bank called for unknown bank '%s'", tag); + fatalerror("memory_get_bank called for unknown bank '%s'", fulltag.cstr()); // return the current entry return bank->entry(); @@ -1885,14 +1897,12 @@ int memory_get_bank(running_machine &machine, const char *tag) //------------------------------------------------- -// memory_get_bank - return the currently -// selected bank +// memory_set_bankptr - set the base of a bank //------------------------------------------------- -int memory_get_bank(device_t *device, const char *tag) +void memory_set_bankptr(running_machine &machine, const char *tag, void *base) { - astring tempstring; - return memory_get_bank(device->machine(), device->subtag(tempstring, tag)); + memory_set_bankptr(machine.root_device(), tag, base); } @@ -1900,12 +1910,13 @@ int memory_get_bank(device_t *device, const char *tag) // memory_set_bankptr - set the base of a bank //------------------------------------------------- -void memory_set_bankptr(running_machine &machine, const char *tag, void *base) +void memory_set_bankptr(device_t &device, const char *tag, void *base) { // validation checks - memory_bank *bank = machine.memory_data->bankmap.find_hash_only(tag); + astring fulltag; + memory_bank *bank = device.machine().memory_data->bankmap.find_hash_only(device.subtag(fulltag, tag)); if (bank == NULL) - throw emu_fatalerror("memory_set_bankptr called for unknown bank '%s'", tag); + throw emu_fatalerror("memory_set_bankptr called for unknown bank '%s'", fulltag.cstr()); // set the base bank->set_base(base); @@ -1913,17 +1924,6 @@ void memory_set_bankptr(running_machine &machine, const char *tag, void *base) //------------------------------------------------- -// memory_set_bankptr - set the base of a bank -//------------------------------------------------- - -void memory_set_bankptr(device_t *device, const char *tag, void *base) -{ - astring tempstring; - return memory_set_bankptr(device->machine(), device->subtag(tempstring, tag), base); -} - - -//------------------------------------------------- // memory_get_shared - get a pointer to a shared // memory region by tag //------------------------------------------------- @@ -1936,7 +1936,8 @@ void *memory_get_shared(running_machine &machine, const char *tag) void *memory_get_shared(running_machine &machine, const char *tag, size_t &length) { - memory_share *share = machine.memory_data->sharemap.find(tag); + astring fulltag; + memory_share *share = machine.memory_data->sharemap.find(machine.root_device().subtag(fulltag, tag)); if (share == NULL) return NULL; length = share->size(); @@ -2186,11 +2187,16 @@ void address_space::prepare_map() adjust_addresses(entry->m_bytestart, entry->m_byteend, entry->m_bytemask, entry->m_bytemirror); // if we have a share entry, add it to our map - if (entry->m_share != NULL && machine().memory_data->sharemap.find(entry->m_share) == NULL) + if (entry->m_share != NULL) { - VPRINTF(("Creating share '%s' of length 0x%X\n", entry->m_share, entry->m_byteend + 1 - entry->m_bytestart)); - memory_share *share = auto_alloc(machine(), memory_share(entry->m_byteend + 1 - entry->m_bytestart)); - machine().memory_data->sharemap.add(entry->m_share, share, false); + // if we can't find it, add it to our map + astring fulltag; + if (machine().memory_data->sharemap.find(device().siblingtag(fulltag, entry->m_share)) == NULL) + { + VPRINTF(("Creating share '%s' of length 0x%X\n", fulltag.cstr(), entry->m_byteend + 1 - entry->m_bytestart)); + memory_share *share = auto_alloc(machine(), memory_share(entry->m_byteend + 1 - entry->m_bytestart)); + machine().memory_data->sharemap.add(fulltag, share, false); + } } // if this is a ROM handler without a specified region, attach it to the implicit region @@ -2207,22 +2213,12 @@ void address_space::prepare_map() // validate adjusted addresses against implicit regions if (entry->m_region != NULL && entry->m_share == NULL && entry->m_baseptr == NULL) { - astring regiontag; + // determine full tag + astring fulltag; + device().siblingtag(fulltag, entry->m_region); - // a leading : on a region name indicates an absolute region, so fix up accordingly - if (entry->m_region[0] == ':') - { - regiontag = &entry->m_region[1]; - } - else - { - if (strchr(entry->m_region,':')) { - regiontag = entry->m_region; - } else { - m_device.siblingtag(regiontag, entry->m_region); - } - } - const memory_region *region = machine().region(regiontag.cstr()); + // find the region + const memory_region *region = machine().region(fulltag); if (region == NULL) fatalerror("Error: device '%s' %s space memory map entry %X-%X references non-existant region \"%s\"", m_device.tag(), m_name, entry->m_addrstart, entry->m_addrend, entry->m_region); @@ -2232,14 +2228,14 @@ void address_space::prepare_map() } // convert any region-relative entries to their memory pointers - if (entry->m_region != NULL) { - astring regiontag; - if (strchr(entry->m_region,':')) { - regiontag = entry->m_region; - } else { - m_device.siblingtag(regiontag, entry->m_region); - } - entry->m_memory = machine().region(regiontag.cstr())->base() + entry->m_rgnoffs; + if (entry->m_region != NULL) + { + // determine full tag + astring fulltag; + device().siblingtag(fulltag, entry->m_region); + + // set the memory address + entry->m_memory = machine().region(fulltag.cstr())->base() + entry->m_rgnoffs; } } @@ -2286,7 +2282,8 @@ void address_space::populate_from_map() void address_space::populate_map_entry(const address_map_entry &entry, read_or_write readorwrite) { const map_handler_data &data = (readorwrite == ROW_READ) ? entry.m_read : entry.m_write; - device_t *device; + device_t *target_device; + astring fulltag; // based on the handler type, alter the bits, name, funcptr, and object switch (data.m_type) @@ -2313,25 +2310,25 @@ void address_space::populate_map_entry(const address_map_entry &entry, read_or_w break; case AMH_DEVICE_DELEGATE: - device = machine().device(data.m_tag); - if (device == NULL) - throw emu_fatalerror("Attempted to map a non-existent device '%s' in space %s of device '%s'\n", data.m_tag, m_name, m_device.tag()); + target_device = device().siblingdevice(data.m_tag); + if (target_device == NULL) + throw emu_fatalerror("Attempted to map a non-existent device '%s' in space %s of device '%s'\n", data.m_tag.cstr(), m_name, m_device.tag()); if (readorwrite == ROW_READ) switch (data.m_bits) { - case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read8_delegate(entry.m_rproto8, *device), data.m_mask); break; - case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read16_delegate(entry.m_rproto16, *device), data.m_mask); break; - case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read32_delegate(entry.m_rproto32, *device), data.m_mask); break; - case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read64_delegate(entry.m_rproto64, *device), data.m_mask); break; + case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read8_delegate(entry.m_rproto8, *target_device), data.m_mask); break; + case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read16_delegate(entry.m_rproto16, *target_device), data.m_mask); break; + case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read32_delegate(entry.m_rproto32, *target_device), data.m_mask); break; + case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, read64_delegate(entry.m_rproto64, *target_device), data.m_mask); break; } else switch (data.m_bits) { - case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write8_delegate(entry.m_wproto8, *device), data.m_mask); break; - case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write16_delegate(entry.m_wproto16, *device), data.m_mask); break; - case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write32_delegate(entry.m_wproto32, *device), data.m_mask); break; - case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write64_delegate(entry.m_wproto64, *device), data.m_mask); break; + case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write8_delegate(entry.m_wproto8, *target_device), data.m_mask); break; + case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write16_delegate(entry.m_wproto16, *target_device), data.m_mask); break; + case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write32_delegate(entry.m_wproto32, *target_device), data.m_mask); break; + case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, write64_delegate(entry.m_wproto64, *target_device), data.m_mask); break; } break; @@ -2355,42 +2352,42 @@ void address_space::populate_map_entry(const address_map_entry &entry, read_or_w break; case AMH_LEGACY_DEVICE_HANDLER: - device = machine().device(data.m_tag); - if (device == NULL) - fatalerror("Attempted to map a non-existent device '%s' in space %s of device '%s'\n", data.m_tag, m_name, m_device.tag()); + target_device = device().siblingdevice(data.m_tag); + if (target_device == NULL) + fatalerror("Attempted to map a non-existent device '%s' in space %s of device '%s'\n", data.m_tag.cstr(), m_name, m_device.tag()); if (readorwrite == ROW_READ) switch (data.m_bits) { - case 8: install_legacy_read_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice8, data.m_name, data.m_mask); break; - case 16: install_legacy_read_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice16, data.m_name, data.m_mask); break; - case 32: install_legacy_read_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice32, data.m_name, data.m_mask); break; - case 64: install_legacy_read_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice64, data.m_name, data.m_mask); break; + case 8: install_legacy_read_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice8, data.m_name, data.m_mask); break; + case 16: install_legacy_read_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice16, data.m_name, data.m_mask); break; + case 32: install_legacy_read_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice32, data.m_name, data.m_mask); break; + case 64: install_legacy_read_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_rdevice64, data.m_name, data.m_mask); break; } else switch (data.m_bits) { - case 8: install_legacy_write_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice8, data.m_name, data.m_mask); break; - case 16: install_legacy_write_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice16, data.m_name, data.m_mask); break; - case 32: install_legacy_write_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice32, data.m_name, data.m_mask); break; - case 64: install_legacy_write_handler(*device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice64, data.m_name, data.m_mask); break; + case 8: install_legacy_write_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice8, data.m_name, data.m_mask); break; + case 16: install_legacy_write_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice16, data.m_name, data.m_mask); break; + case 32: install_legacy_write_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice32, data.m_name, data.m_mask); break; + case 64: install_legacy_write_handler(*target_device, entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_wdevice64, data.m_name, data.m_mask); break; } break; case AMH_PORT: install_readwrite_port(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, - (readorwrite == ROW_READ) ? data.m_tag : NULL, - (readorwrite == ROW_WRITE) ? data.m_tag : NULL); + (readorwrite == ROW_READ) ? data.m_tag.cstr() : NULL, + (readorwrite == ROW_WRITE) ? data.m_tag.cstr() : NULL); break; case AMH_BANK: install_bank_generic(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, - (readorwrite == ROW_READ) ? data.m_tag : NULL, - (readorwrite == ROW_WRITE) ? data.m_tag : NULL); + (readorwrite == ROW_READ) ? data.m_tag.cstr() : NULL, + (readorwrite == ROW_WRITE) ? data.m_tag.cstr() : NULL); break; case AMH_DEVICE_SUBMAP: - throw emu_fatalerror("Internal mapping error: leftover mapping of '%s'.\n", data.m_tag); + throw emu_fatalerror("Internal mapping error: leftover mapping of '%s'.\n", data.m_tag.cstr()); } } @@ -2478,13 +2475,13 @@ void address_space::locate_memory() if (entry->m_baseptr != NULL) *entry->m_baseptr = entry->m_memory; if (entry->m_baseptroffs_plus1 != 0) - *(void **)(reinterpret_cast<UINT8 *>(machine().driver_data<void>()) + entry->m_baseptroffs_plus1 - 1) = entry->m_memory; + *(void **)(reinterpret_cast<UINT8 *>(machine().driver_data()) + entry->m_baseptroffs_plus1 - 1) = entry->m_memory; if (entry->m_genbaseptroffs_plus1 != 0) *(void **)((UINT8 *)&machine().generic + entry->m_genbaseptroffs_plus1 - 1) = entry->m_memory; if (entry->m_sizeptr != NULL) *entry->m_sizeptr = entry->m_byteend - entry->m_bytestart + 1; if (entry->m_sizeptroffs_plus1 != 0) - *(size_t *)(reinterpret_cast<UINT8 *>(machine().driver_data<void>()) + entry->m_sizeptroffs_plus1 - 1) = entry->m_byteend - entry->m_bytestart + 1; + *(size_t *)(reinterpret_cast<UINT8 *>(machine().driver_data()) + entry->m_sizeptroffs_plus1 - 1) = entry->m_byteend - entry->m_bytestart + 1; if (entry->m_gensizeptroffs_plus1 != 0) *(size_t *)((UINT8 *)&machine().generic + entry->m_gensizeptroffs_plus1 - 1) = entry->m_byteend - entry->m_bytestart + 1; } @@ -2562,7 +2559,8 @@ address_map_entry *address_space::block_assign_intersecting(offs_t bytestart, of // if we haven't assigned this block yet, see if we have a mapped shared pointer for it if (entry->m_memory == NULL && entry->m_share != NULL) { - memory_share *share = memdata->sharemap.find(entry->m_share); + astring fulltag; + memory_share *share = memdata->sharemap.find(device().siblingtag(fulltag, entry->m_share)); if (share != NULL && share->ptr() != NULL) { entry->m_memory = share->ptr(); @@ -2584,7 +2582,8 @@ address_map_entry *address_space::block_assign_intersecting(offs_t bytestart, of // if we're the first match on a shared pointer, assign it now if (entry->m_memory != NULL && entry->m_share != NULL) { - memory_share *share = memdata->sharemap.find(entry->m_share); + astring fulltag; + memory_share *share = memdata->sharemap.find(device().siblingtag(fulltag, entry->m_share)); if (share != NULL && share->ptr() == NULL) { share->set_ptr(entry->m_memory); @@ -2685,7 +2684,9 @@ void address_space::install_readwrite_port(offs_t addrstart, offs_t addrend, off if (rtag != NULL) { // find the port - const input_port_config *port = machine().port(rtag); + astring fulltag; + device().siblingtag(fulltag, rtag); + const input_port_config *port = machine().port(fulltag); if (port == NULL) throw emu_fatalerror("Attempted to map non-existent port '%s' for read in space %s of device '%s'\n", rtag, m_name, m_device.tag()); @@ -2696,7 +2697,9 @@ void address_space::install_readwrite_port(offs_t addrstart, offs_t addrend, off if (wtag != NULL) { // find the port - const input_port_config *port = machine().port(wtag); + astring fulltag; + device().siblingtag(fulltag, wtag); + const input_port_config *port = machine().port(fulltag); if (port == NULL) fatalerror("Attempted to map non-existent port '%s' for write in space %s of device '%s'\n", wtag, m_name, m_device.tag()); @@ -2724,14 +2727,18 @@ void address_space::install_bank_generic(offs_t addrstart, offs_t addrend, offs_ // map the read bank if (rtag != NULL) { - memory_bank &bank = bank_find_or_allocate(rtag, addrstart, addrend, addrmask, addrmirror, ROW_READ); + astring fulltag; + device().siblingtag(fulltag, rtag); + memory_bank &bank = bank_find_or_allocate(fulltag, addrstart, addrend, addrmask, addrmirror, ROW_READ); read().map_range(addrstart, addrend, addrmask, addrmirror, bank.index()); } // map the write bank if (wtag != NULL) { - memory_bank &bank = bank_find_or_allocate(wtag, addrstart, addrend, addrmask, addrmirror, ROW_WRITE); + astring fulltag; + device().siblingtag(fulltag, wtag); + memory_bank &bank = bank_find_or_allocate(fulltag, addrstart, addrend, addrmask, addrmirror, ROW_WRITE); write().map_range(addrstart, addrend, addrmask, addrmirror, bank.index()); } @@ -3224,7 +3231,8 @@ bool address_space::needs_backing_store(const address_map_entry *entry) // if we are sharing, and we don't have a pointer yet, create one if (entry->m_share != NULL) { - memory_share *share = machine().memory_data->sharemap.find(entry->m_share); + astring fulltag; + memory_share *share = machine().memory_data->sharemap.find(device().siblingtag(fulltag, entry->m_share)); if (share != NULL && share->ptr() == NULL) return true; } diff --git a/src/emu/memory.h b/src/emu/memory.h index ec45c6fb342..717b77eeaf5 100644 --- a/src/emu/memory.h +++ b/src/emu/memory.h @@ -676,23 +676,23 @@ void memory_init(running_machine &machine); // configure the addresses for a bank void memory_configure_bank(running_machine &machine, const char *tag, int startentry, int numentries, void *base, offs_t stride) ATTR_NONNULL(5); -void memory_configure_bank(device_t *device, const char *tag, int startentry, int numentries, void *base, offs_t stride) ATTR_NONNULL(5); +void memory_configure_bank(device_t &device, const char *tag, int startentry, int numentries, void *base, offs_t stride) ATTR_NONNULL(5); // configure the decrypted addresses for a bank void memory_configure_bank_decrypted(running_machine &machine, const char *tag, int startentry, int numentries, void *base, offs_t stride) ATTR_NONNULL(5); -void memory_configure_bank_decrypted(device_t *device, const char *tag, int startentry, int numentries, void *base, offs_t stride) ATTR_NONNULL(5); +void memory_configure_bank_decrypted(device_t &device, const char *tag, int startentry, int numentries, void *base, offs_t stride) ATTR_NONNULL(5); // select one pre-configured entry to be the new bank base void memory_set_bank(running_machine &machine, const char *tag, int entrynum); -void memory_set_bank(device_t *device, const char *tag, int entrynum); +void memory_set_bank(device_t &device, const char *tag, int entrynum); // return the currently selected bank int memory_get_bank(running_machine &machine, const char *tag); -int memory_get_bank(device_t *device, const char *tag); +int memory_get_bank(device_t &device, const char *tag); // set the absolute address of a bank base void memory_set_bankptr(running_machine &machine, const char *tag, void *base) ATTR_NONNULL(3); -void memory_set_bankptr(device_t *device, const char *tag, void *base) ATTR_NONNULL(3); +void memory_set_bankptr(device_t &device, const char *tag, void *base) ATTR_NONNULL(3); // get a pointer to a shared memory region by tag void *memory_get_shared(running_machine &machine, const char *tag); diff --git a/src/emu/network.c b/src/emu/network.c index cd44270c556..3da575835af 100644 --- a/src/emu/network.c +++ b/src/emu/network.c @@ -23,7 +23,6 @@ static void network_load(running_machine &machine, int config_type, xml_data_node *parentnode) { xml_data_node *node; - device_network_interface *network = NULL; if ((config_type == CONFIG_TYPE_GAME) && (parentnode != NULL)) { for (node = xml_get_sibling(parentnode->child, "device"); node; node = xml_get_sibling(node->next, "device")) @@ -32,7 +31,8 @@ static void network_load(running_machine &machine, int config_type, xml_data_nod if ((tag != NULL) && (tag[0] != '\0')) { - for (bool gotone = machine.devicelist().first(network); gotone; gotone = network->next(network)) + network_interface_iterator iter(machine.root_device()); + for (device_network_interface *network = iter.first(); network != NULL; network = iter.next()) { if (!strcmp(tag, network->device().tag())) { int interface = xml_get_attribute_int(node, "interface", 0); @@ -56,12 +56,12 @@ static void network_load(running_machine &machine, int config_type, xml_data_nod static void network_save(running_machine &machine, int config_type, xml_data_node *parentnode) { xml_data_node *node; - device_network_interface *network = NULL; /* only care about game-specific data */ if (config_type == CONFIG_TYPE_GAME) { - for (bool gotone = machine.devicelist().first(network); gotone; gotone = network->next(network)) + network_interface_iterator iter(machine.root_device()); + for (device_network_interface *network = iter.first(); network != NULL; network = iter.next()) { node = xml_add_child(parentnode, "device", NULL); if (node != NULL) diff --git a/src/emu/profiler.c b/src/emu/profiler.c index c4c6e49a4e1..71b8735c052 100644 --- a/src/emu/profiler.c +++ b/src/emu/profiler.c @@ -233,6 +233,7 @@ const char *real_profiler_state::text(running_machine &machine, astring &string) } // loop over all types and generate the string + device_iterator iter(machine.root_device()); for (curtype = PROFILER_DEVICE_FIRST; curtype < PROFILER_TOTAL; curtype++) { // determine the accumulated time for this type @@ -252,7 +253,7 @@ const char *real_profiler_state::text(running_machine &machine, astring &string) // and then the text if (curtype >= PROFILER_DEVICE_FIRST && curtype <= PROFILER_DEVICE_MAX) - string.catprintf("'%s'", machine.devicelist().find(curtype - PROFILER_DEVICE_FIRST)->tag()); + string.catprintf("'%s'", iter.byindex(curtype - PROFILER_DEVICE_FIRST)->tag()); else for (int nameindex = 0; nameindex < ARRAY_LENGTH(names); nameindex++) if (names[nameindex].type == curtype) diff --git a/src/emu/render.c b/src/emu/render.c index 0975c03f036..7f971618b25 100644 --- a/src/emu/render.c +++ b/src/emu/render.c @@ -1120,17 +1120,15 @@ int render_target::configured_view(const char *viewname, int targetindex, int nu } // if we don't have a match, default to the nth view - int scrcount = m_manager.machine().devicelist().count(SCREEN); + screen_device_iterator iter(m_manager.machine().root_device()); + int scrcount = iter.count(); if (view == NULL && scrcount > 0) { // if we have enough targets to be one per screen, assign in order if (numtargets >= scrcount) { int ourindex = index() % scrcount; - screen_device *screen; - for (screen = m_manager.machine().first_screen(); screen != NULL; screen = screen->next_screen()) - if (ourindex-- == 0) - break; + screen_device *screen = iter.byindex(ourindex); // find the first view with this screen and this screen only for (view = view_by_index(viewindex = 0); view != NULL; view = view_by_index(++viewindex)) @@ -1157,7 +1155,7 @@ int render_target::configured_view(const char *viewname, int targetindex, int nu if (viewscreens.count() >= scrcount) { screen_device *screen; - for (screen = m_manager.machine().first_screen(); screen != NULL; screen = screen->next_screen()) + for (screen = iter.first(); screen != NULL; screen = iter.next()) if (!viewscreens.contains(*screen)) break; if (screen == NULL) @@ -1576,7 +1574,8 @@ void render_target::load_layout_files(const char *layoutfile, bool singlefile) else have_default |= true; } - int screens = m_manager.machine().devicelist().count(SCREEN); + screen_device_iterator iter(m_manager.machine().root_device()); + int screens = iter.count(); // now do the built-in layouts for single-screen games if (screens == 1) { @@ -2432,7 +2431,8 @@ render_manager::render_manager(running_machine &machine) config_register(machine, "video", config_saveload_delegate(FUNC(render_manager::config_load), this), config_saveload_delegate(FUNC(render_manager::config_save), this)); // create one container per screen - for (screen_device *screen = machine.first_screen(); screen != NULL; screen = screen->next_screen()) + screen_device_iterator iter(machine.root_device()); + for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next()) screen->set_container(*container_alloc(screen)); } diff --git a/src/emu/rendlay.c b/src/emu/rendlay.c index 64db4b26c36..7bad91878dc 100644 --- a/src/emu/rendlay.c +++ b/src/emu/rendlay.c @@ -203,10 +203,10 @@ static int get_variable_value(running_machine &machine, const char *string, char char temp[100]; // screen 0 parameters - for (const screen_device *device = machine.first_screen(); device != NULL; device = device->next_screen()) + screen_device_iterator iter(machine.root_device()); + int scrnum = 0; + for (const screen_device *device = iter.first(); device != NULL; device = iter.next(), scrnum++) { - int scrnum = machine.devicelist().indexof(SCREEN, device->tag()); - // native X aspect factor sprintf(temp, "~scr%dnativexaspect~", scrnum); if (!strncmp(string, temp, strlen(temp))) @@ -1863,7 +1863,10 @@ layout_view::item::item(running_machine &machine, xml_data_node &itemnode, simpl // fetch common data int index = xml_get_attribute_int_with_subst(machine, itemnode, "index", -1); if (index != -1) - m_screen = downcast<screen_device *>(machine.devicelist().find(SCREEN, index)); + { + screen_device_iterator iter(machine.root_device()); + m_screen = iter.byindex(index); + } m_input_mask = xml_get_attribute_int_with_subst(machine, itemnode, "inputmask", 0); if (m_output_name[0] != 0 && m_element != NULL) output_set_value(m_output_name, m_element->default_state()); diff --git a/src/emu/romload.c b/src/emu/romload.c index b350e8d6d54..9289d692189 100644 --- a/src/emu/romload.c +++ b/src/emu/romload.c @@ -188,7 +188,8 @@ void set_disk_handle(running_machine &machine, const char *region, emu_file &fil const rom_source *rom_first_source(const machine_config &config) { /* look through devices */ - for (const device_t *device = config.devicelist().first(); device != NULL; device = device->next()) + device_iterator iter(config.root_device()); + for (const device_t *device = iter.first(); device != NULL; device = iter.next()) if (device->rom_region() != NULL) return device; @@ -204,9 +205,16 @@ const rom_source *rom_first_source(const machine_config &config) const rom_source *rom_next_source(const rom_source &previous) { /* look for further devices with ROM definitions */ - for (const device_t *device = previous.next(); device != NULL; device = device->next()) +// fixme: this is awful + device_iterator iter(previous.mconfig().root_device()); + const device_t *device; + for (device = iter.first(); device != NULL; device = iter.next()) + if (device == &previous) + break; + + for (device = iter.next(); device != NULL; device = iter.next()) if (device->rom_region() != NULL) - return (rom_source *)device; + return device; return NULL; } @@ -273,7 +281,7 @@ const rom_entry *rom_next_file(const rom_entry *romp) astring &rom_region_name(astring &result, const game_driver *drv, const rom_source *source, const rom_entry *romp) { - return source->subtag(result, ROMREGION_GETTAG(romp)); + return source->subtag(result, ROM_GETNAME(romp)); } diff --git a/src/emu/schedule.c b/src/emu/schedule.c index 614ed8bdacb..741ae074896 100644 --- a/src/emu/schedule.c +++ b/src/emu/schedule.c @@ -788,8 +788,8 @@ void device_scheduler::rebuild_execute_list() device_execute_interface **suspend_tailptr = &suspend_list; // iterate over all devices - device_execute_interface *exec = NULL; - for (bool gotone = machine().devicelist().first(exec); gotone; gotone = exec->next(exec)) + execute_interface_iterator iter(machine().root_device()); + for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next()) { // append to the appropriate list exec->m_nextexec = NULL; diff --git a/src/emu/screen.c b/src/emu/screen.c index 4bd2b8ebc39..aab40d9fced 100644 --- a/src/emu/screen.c +++ b/src/emu/screen.c @@ -244,42 +244,26 @@ void screen_device::static_set_screen_vblank(device_t &device, screen_vblank_del // configuration //------------------------------------------------- -bool screen_device::device_validity_check(emu_options &options, const game_driver &driver) const +void screen_device::device_validity_check(validity_checker &valid) const { - bool error = false; - // sanity check dimensions if (m_width <= 0 || m_height <= 0) - { - mame_printf_error("%s: %s screen '%s' has invalid display dimensions\n", driver.source_file, driver.name, tag()); - error = true; - } + mame_printf_error("Invalid display dimensions\n"); // sanity check display area if (m_type != SCREEN_TYPE_VECTOR) { if (m_visarea.empty() || m_visarea.max_x >= m_width || m_visarea.max_y >= m_height) - { - mame_printf_error("%s: %s screen '%s' has an invalid display area\n", driver.source_file, driver.name, tag()); - error = true; - } + mame_printf_error("Invalid display area\n"); // sanity check screen formats if (m_screen_update_ind16.isnull() && m_screen_update_rgb32.isnull()) - { - mame_printf_error("%s: %s screen '%s' has no SCREEN_UPDATE function\n", driver.source_file, driver.name, tag()); - error = true; - } + mame_printf_error("Missing SCREEN_UPDATE function\n"); } // check for zero frame rate if (m_refresh == 0) - { - mame_printf_error("%s: %s screen '%s' has a zero refresh rate\n", driver.source_file, driver.name, tag()); - error = true; - } - - return error; + mame_printf_error("Invalid (zero) refresh rate\n"); } diff --git a/src/emu/screen.h b/src/emu/screen.h index e9f496e11ba..aeb927f8143 100644 --- a/src/emu/screen.h +++ b/src/emu/screen.h @@ -192,7 +192,6 @@ public: static void static_set_screen_vblank(device_t &device, screen_vblank_delegate callback); // information getters - screen_device *next_screen() const { return downcast<screen_device *>(typenext()); } render_container &container() const { assert(m_container != NULL); return *m_container; } // dynamic configuration @@ -244,7 +243,7 @@ private: }; // device-level overrides - virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; + virtual void device_validity_check(validity_checker &valid) const; virtual void device_start(); virtual void device_stop(); virtual void device_post_load(); @@ -334,6 +333,9 @@ private: // device type definition extern const device_type SCREEN; +// iterator helper +typedef device_type_iterator<&device_creator<screen_device>, screen_device> screen_device_iterator; + //************************************************************************** diff --git a/src/emu/softlist.c b/src/emu/softlist.c index 1bb5dd3dc2d..c3470d897c2 100644 --- a/src/emu/softlist.c +++ b/src/emu/softlist.c @@ -17,6 +17,63 @@ typedef tagmap_t<software_info *> softlist_map; + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +tagmap_t<UINT8> software_list_device::s_checked_lists; + +// device type definition +const device_type SOFTWARE_LIST = &device_creator<software_list_device>; + +//------------------------------------------------- +// software_list_device - constructor +//------------------------------------------------- + +software_list_device::software_list_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, SOFTWARE_LIST, "Software lists", tag, owner, clock), + m_list_name(NULL), + m_list_type(SOFTWARE_LIST_ORIGINAL_SYSTEM), + m_filter(NULL) +{ +} + + +//------------------------------------------------- +// static_set_interface - configuration helper +// to set the interface +//------------------------------------------------- + +void software_list_device::static_set_config(device_t &device, const char *list, softlist_type list_type) +{ + software_list_device &softlist = downcast<software_list_device &>(device); + softlist.m_list_name = list; + softlist.m_list_type = list_type; +} + + +//------------------------------------------------- +// static_set_custom_handler - configuration +// helper to set a custom callback +//------------------------------------------------- + +void software_list_device::static_set_filter(device_t &device, const char *filter) +{ + downcast<software_list_device &>(device).m_filter = filter; +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void software_list_device::device_start() +{ +} + + + /*************************************************************************** EXPAT INTERFACES ***************************************************************************/ @@ -1216,7 +1273,7 @@ static int softlist_penalty_compare(const char *source, const char *target) software_list_find_approx_matches -------------------------------------------------*/ -void software_list_find_approx_matches(software_list_config *swlistcfg, software_list *swlist, const char *name, int matches, software_info **list, const char* interface) +void software_list_find_approx_matches(software_list_device *swlistdev, software_list *swlist, const char *name, int matches, software_info **list, const char* interface) { #undef rand @@ -1243,7 +1300,7 @@ void software_list_find_approx_matches(software_list_config *swlistcfg, software software_info *candidate = swinfo; software_part *part = software_find_part(swinfo, NULL, NULL); - if ((interface==NULL || !strcmp(interface, part->interface_)) && (is_software_compatible(part, swlistcfg))) + if ((interface==NULL || !strcmp(interface, part->interface_)) && (is_software_compatible(part, swlistdev))) { /* pick the best match between driver name and description */ @@ -1442,19 +1499,19 @@ software_part *software_part_next(software_part *part) software_display_matches -------------------------------------------------*/ -void software_display_matches(const device_list &devlist,emu_options &options, const char *interface ,const char *name) +void software_display_matches(const machine_config &config,emu_options &options, const char *interface ,const char *name) { // check if there is at least a software list - if (devlist.first(SOFTWARE_LIST)) + software_list_device_iterator deviter(config.root_device()); + if (deviter.first()) { mame_printf_error("\n\"%s\" approximately matches the following\n" "supported software items (best match first):\n\n", name); } - for (device_t *swlists = devlist.first(SOFTWARE_LIST); swlists != NULL; swlists = swlists->typenext()) + for (software_list_device *swlist = deviter.first(); swlist != NULL; swlist = deviter.next()) { - software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(swlists)->inline_config(); - software_list *list = software_list_open(options, swlist->list_name, FALSE, NULL); + software_list *list = software_list_open(options, swlist->list_name(), FALSE, NULL); if (list) { @@ -1467,10 +1524,10 @@ void software_display_matches(const device_list &devlist,emu_options &options, c if (matches[0] != 0) { - if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM) - mame_printf_error("* Software list \"%s\" (%s) matches: \n", swlist->list_name, software_list_get_description(list)); + if (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) + mame_printf_error("* Software list \"%s\" (%s) matches: \n", swlist->list_name(), software_list_get_description(list)); else - mame_printf_error("* Compatible software list \"%s\" (%s) matches: \n", swlist->list_name, software_list_get_description(list)); + mame_printf_error("* Compatible software list \"%s\" (%s) matches: \n", swlist->list_name(), software_list_get_description(list)); // print them out for (softnum = 0; softnum < ARRAY_LENGTH(matches); softnum++) @@ -1484,7 +1541,7 @@ void software_display_matches(const device_list &devlist,emu_options &options, c } } -static void find_software_item(const device_list &devlist, emu_options &options, const device_image_interface *image, const char *path, software_list **software_list_ptr, software_info **software_info_ptr,software_part **software_part_ptr, const char **sw_list_name) +static void find_software_item(const machine_config &config, emu_options &options, const device_image_interface *image, const char *path, software_list **software_list_ptr, software_info **software_info_ptr,software_part **software_part_ptr, const char **sw_list_name) { char *swlist_name, *swname, *swpart; //, *swname_bckp; *software_list_ptr = NULL; @@ -1516,33 +1573,28 @@ static void find_software_item(const device_list &devlist, emu_options &options, else { /* Loop through all the software lists named in the driver */ - for (device_t *swlists = devlist.first(SOFTWARE_LIST); swlists != NULL; swlists = swlists->typenext()) + software_list_device_iterator deviter(config.root_device()); + for (software_list_device *swlist = deviter.first(); swlist != NULL; swlist = deviter.next()) { - if ( swlists ) - { + const char *swlist_name = swlist->list_name(); - software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(swlists)->inline_config(); + if (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) + { + if ( *software_list_ptr ) + { + software_list_close( *software_list_ptr ); + } - swlist_name = swlist->list_name; + *software_list_ptr = software_list_open( options, swlist_name, FALSE, NULL ); - if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM) + if ( software_list_ptr ) { - if ( *software_list_ptr ) - { - software_list_close( *software_list_ptr ); - } + *software_info_ptr = software_list_find( *software_list_ptr, swname, NULL ); - *software_list_ptr = software_list_open( options, swlist_name, FALSE, NULL ); - - if ( software_list_ptr ) + if ( *software_info_ptr ) { - *software_info_ptr = software_list_find( *software_list_ptr, swname, NULL ); - - if ( *software_info_ptr ) - { - *software_part_ptr = software_find_part( *software_info_ptr, swpart, interface ); - if (*software_part_ptr) break; - } + *software_part_ptr = software_find_part( *software_info_ptr, swpart, interface ); + if (*software_part_ptr) break; } } } @@ -1634,12 +1686,12 @@ bool load_software_part(emu_options &options, device_image_interface *image, con *sw_info = NULL; *sw_part = NULL; - find_software_item(image->device().machine().devicelist(), options, image, path, &software_list_ptr, &software_info_ptr, &software_part_ptr, &swlist_name); + find_software_item(image->device().machine().config(), options, image, path, &software_list_ptr, &software_info_ptr, &software_part_ptr, &swlist_name); // if no match has been found, we suggest similar shortnames if (software_info_ptr == NULL) { - software_display_matches(image->device().machine().devicelist(),image->device().machine().options(), image->image_interface(), path); + software_display_matches(image->device().machine().config(),image->device().machine().options(), image->image_interface(), path); } if ( software_part_ptr ) @@ -1704,12 +1756,12 @@ bool load_software_part(emu_options &options, device_image_interface *image, con *full_sw_name = auto_alloc_array( image->device().machine(), char, strlen(swlist_name) + strlen(software_info_ptr->shortname) + strlen(software_part_ptr->name) + 3 ); sprintf( *full_sw_name, "%s:%s:%s", swlist_name, software_info_ptr->shortname, software_part_ptr->name ); - for (device_t *swlists = image->device().machine().devicelist().first(SOFTWARE_LIST); swlists != NULL; swlists = swlists->typenext()) + software_list_device_iterator iter(image->device().machine().root_device()); + for (software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next()) { - software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(swlists)->inline_config(); - if (strcmp(swlist->list_name,swlist_name)==0) { + if (strcmp(swlist->list_name(),swlist_name)==0) { if (!is_software_compatible(software_part_ptr, swlist)) { - mame_printf_warning("WARNING! the set %s might not work on this system due to missing filter(s) '%s'\n",software_info_ptr->shortname,swlist->filter); + mame_printf_warning("WARNING! the set %s might not work on this system due to missing filter(s) '%s'\n",software_info_ptr->shortname,swlist->filter()); } break; } @@ -1723,12 +1775,12 @@ bool load_software_part(emu_options &options, device_image_interface *image, con software_part *req_software_part_ptr = NULL; const char *req_swlist_name = NULL; - find_software_item(image->device().machine().devicelist(), options, NULL, requirement, &req_software_list_ptr, &req_software_info_ptr, &req_software_part_ptr, &req_swlist_name); + find_software_item(image->device().machine().config(), options, NULL, requirement, &req_software_list_ptr, &req_software_info_ptr, &req_software_part_ptr, &req_swlist_name); if ( req_software_list_ptr ) { - device_image_interface *req_image = NULL; - for (bool gotone = image->device().machine().devicelist().first(req_image); gotone; gotone = req_image->next(req_image)) + image_interface_iterator imgiter(image->device().machine().root_device()); + for (device_image_interface *req_image = imgiter.first(); req_image != NULL; req_image = imgiter.next()) { const char *interface = req_image->image_interface(); if (interface != NULL) @@ -1791,7 +1843,7 @@ const char *software_part_get_feature(const software_part *part, const char *fea software_get_default_slot -------------------------------------------------*/ - const char *software_get_default_slot(const device_list &devlist, emu_options &options, const device_image_interface *image, const char* default_card_slot) + const char *software_get_default_slot(const machine_config &config, emu_options &options, const device_image_interface *image, const char* default_card_slot) { const char* retVal = NULL; const char* path = options.value(image->instance_name()); @@ -1802,7 +1854,7 @@ const char *software_part_get_feature(const software_part *part, const char *fea if (strlen(path)>0) { retVal = default_card_slot; - find_software_item(devlist, options, image, path, &software_list_ptr, &software_info_ptr, &software_part_ptr, &swlist_name); + find_software_item(config, options, image, path, &software_list_ptr, &software_info_ptr, &software_part_ptr, &swlist_name); if (software_part_ptr!=NULL) { const char *slot = software_part_get_feature(software_part_ptr, "slot"); if (slot!=NULL) { @@ -1819,10 +1871,10 @@ const char *software_part_get_feature(const software_part *part, const char *fea is_software_compatible -------------------------------------------------*/ -bool is_software_compatible(const software_part *swpart, const software_list_config *swlist) +bool is_software_compatible(const software_part *swpart, const software_list_device *swlist) { const char *compatibility = software_part_get_feature(swpart, "compatibility"); - const char *filter = swlist->filter; + const char *filter = swlist->filter(); if ((compatibility==NULL) || (filter==NULL)) return TRUE; astring comp = astring(compatibility,","); char *filt = core_strdup(filter); @@ -1856,229 +1908,138 @@ bool swinfo_has_multiple_parts(const software_info *swinfo, const char *interfac ***************************************************************************/ -static DEVICE_START( software_list ) -{ -} - void validate_error_proc(const char *message) { - mame_printf_error("%s",message); + mame_printf_error("%s", message); } -void validate_softlists(emu_options &options) +void software_list_device::device_validity_check(validity_checker &valid) const { - driver_enumerator drivlist(options); - // first determine the maximum number of lists we might encounter - int list_count = 0; - while (drivlist.next()) - for (const device_t *dev = drivlist.config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) - { - software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config(); + // add to the global map whenever we check a list so we don't re-check + // it in the future + if (s_checked_lists.add(m_list_name, 1, false) == TMERR_DUPLICATE) + return; - if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM) - list_count++; - } + softlist_map names; + softlist_map descriptions; - // allocate a list - astring *lists = global_alloc_array(astring, list_count); - bool error = FALSE; - if (list_count) + enum { NAME_LEN_PARENT = 8, NAME_LEN_CLONE = 16 }; + + software_list *list = software_list_open(mconfig().options(), m_list_name, FALSE, NULL); + if ( list ) { - drivlist.reset(); - list_count = 0; - while (drivlist.next()) - for (const device_t *dev = drivlist.config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) + software_list_parse( list, &validate_error_proc, NULL ); + + for (software_info *swinfo = software_list_find(list, "*", NULL); swinfo != NULL; swinfo = software_list_find(list, "*", swinfo)) { - software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config(); - softlist_map names; - softlist_map descriptions; + const char *s; + int is_clone = 0; - enum { NAME_LEN_PARENT = 8, NAME_LEN_CLONE = 16 }; + /* First, check if the xml got corrupted: */ - software_list *list = software_list_open(options, swlist->list_name, FALSE, NULL); - if ( list ) + /* Did we lost any description? */ + if (swinfo->longname == NULL) { - /* Verify if we have encountered this list before */ - bool seen_before = false; - for (int seen_index = 0; seen_index < list_count && !seen_before; seen_index++) - if (lists[seen_index] == swlist->list_name) - seen_before = true; + mame_printf_error("%s: %s has no description\n", list->file->filename(), swinfo->shortname); + break; + } - if (!seen_before) - { - lists[list_count++] = swlist->list_name; - software_list_parse( list, &validate_error_proc, NULL ); + /* Did we lost any year? */ + if (swinfo->year == NULL) + { + mame_printf_error("%s: %s has no year\n", list->file->filename(), swinfo->shortname); + break; + } - for (software_info *swinfo = software_list_find(list, "*", NULL); swinfo != NULL; swinfo = software_list_find(list, "*", swinfo)) - { - const char *s; - int is_clone = 0; + /* Did we lost any publisher? */ + if (swinfo->publisher == NULL) + { + mame_printf_error("%s: %s has no publisher\n", list->file->filename(), swinfo->shortname); + break; + } - /* First, check if the xml got corrupted: */ + /* Second, since the xml is fine, run additional checks: */ - /* Did we lost any description? */ - if (swinfo->longname == NULL) - { - mame_printf_error("%s: %s has no description\n", list->file->filename(), swinfo->shortname); - error = TRUE; break; - } + /* check for duplicate names */ + if (names.add(swinfo->shortname, swinfo, FALSE) == TMERR_DUPLICATE) + { + software_info *match = names.find(swinfo->shortname); + mame_printf_error("%s: %s is a duplicate name (%s)\n", list->file->filename(), swinfo->shortname, match->shortname); + } - /* Did we lost any year? */ - if (swinfo->year == NULL) - { - mame_printf_error("%s: %s has no year\n", list->file->filename(), swinfo->shortname); - error = TRUE; break; - } + /* check for duplicate descriptions */ + if (descriptions.add(astring(swinfo->longname).makelower().cstr(), swinfo, FALSE) == TMERR_DUPLICATE) + mame_printf_error("%s: %s is a duplicate description (%s)\n", list->file->filename(), swinfo->longname, swinfo->shortname); - /* Did we lost any publisher? */ - if (swinfo->publisher == NULL) - { - mame_printf_error("%s: %s has no publisher\n", list->file->filename(), swinfo->shortname); - error = TRUE; break; - } + if (swinfo->parentname != NULL) + { + is_clone = 1; - /* Second, since the xml is fine, run additional checks: */ + if (strcmp(swinfo->parentname, swinfo->shortname) == 0) + { + mame_printf_error("%s: %s is set as a clone of itself\n", list->file->filename(), swinfo->shortname); + break; + } - /* check for duplicate names */ - if (names.add(swinfo->shortname, swinfo, FALSE) == TMERR_DUPLICATE) - { - software_info *match = names.find(swinfo->shortname); - mame_printf_error("%s: %s is a duplicate name (%s)\n", list->file->filename(), swinfo->shortname, match->shortname); - error = TRUE; - } + /* make sure the parent exists */ + software_info *swinfo2 = software_list_find(list, swinfo->parentname, NULL ); - /* check for duplicate descriptions */ - if (descriptions.add(astring(swinfo->longname).makelower().cstr(), swinfo, FALSE) == TMERR_DUPLICATE) - { - mame_printf_error("%s: %s is a duplicate description (%s)\n", list->file->filename(), swinfo->longname, swinfo->shortname); - error = TRUE; - } + if (!swinfo2) + mame_printf_error("%s: parent '%s' software for '%s' not found\n", list->file->filename(), swinfo->parentname, swinfo->shortname); + else if (swinfo2->parentname != NULL) + mame_printf_error("%s: %s is a clone of a clone\n", list->file->filename(), swinfo->shortname); + } - if (swinfo->parentname != NULL) - { - is_clone = 1; + /* make sure the driver name is 8 chars or less */ + if ((is_clone && strlen(swinfo->shortname) > NAME_LEN_CLONE) || ((!is_clone) && strlen(swinfo->shortname) > NAME_LEN_PARENT)) + mame_printf_error("%s: %s %s driver name must be %d characters or less\n", list->file->filename(), swinfo->shortname, + is_clone ? "clone" : "parent", is_clone ? NAME_LEN_CLONE : NAME_LEN_PARENT); - if (strcmp(swinfo->parentname, swinfo->shortname) == 0) - { - mame_printf_error("%s: %s is set as a clone of itself\n", list->file->filename(), swinfo->shortname); - error = TRUE; - break; - } + /* make sure the year is only digits, '?' or '+' */ + for (s = swinfo->year; *s; s++) + if (!isdigit((UINT8)*s) && *s != '?' && *s != '+') + { + mame_printf_error("%s: %s has an invalid year '%s'\n", list->file->filename(), swinfo->shortname, swinfo->year); + break; + } - /* make sure the parent exists */ - software_info *swinfo2 = software_list_find(list, swinfo->parentname, NULL ); + softlist_map part_names; - if (!swinfo2) - { - mame_printf_error("%s: parent '%s' software for '%s' not found\n", list->file->filename(), swinfo->parentname, swinfo->shortname); - error = TRUE; - } - else - { - if (swinfo2->parentname != NULL) - { - mame_printf_error("%s: %s is a clone of a clone\n", list->file->filename(), swinfo->shortname); - error = TRUE; - } - } - } - - /* make sure the driver name is 8 chars or less */ - if ((is_clone && strlen(swinfo->shortname) > NAME_LEN_CLONE) || ((!is_clone) && strlen(swinfo->shortname) > NAME_LEN_PARENT)) - { - mame_printf_error("%s: %s %s driver name must be %d characters or less\n", list->file->filename(), swinfo->shortname, - is_clone ? "clone" : "parent", is_clone ? NAME_LEN_CLONE : NAME_LEN_PARENT); - error = TRUE; - } + for (software_part *swpart = software_find_part(swinfo, NULL, NULL); swpart != NULL; swpart = software_part_next(swpart)) + { + if (swpart->interface_ == NULL) + mame_printf_error("%s: %s has a part (%s) without interface\n", list->file->filename(), swinfo->shortname, swpart->name); - /* make sure the year is only digits, '?' or '+' */ - for (s = swinfo->year; *s; s++) - if (!isdigit((UINT8)*s) && *s != '?' && *s != '+') - { - mame_printf_error("%s: %s has an invalid year '%s'\n", list->file->filename(), swinfo->shortname, swinfo->year); - error = TRUE; - break; - } + if (software_find_romdata(swpart, NULL) == NULL) + mame_printf_error("%s: %s has a part (%s) with no data\n", list->file->filename(), swinfo->shortname, swpart->name); - softlist_map part_names; + if (part_names.add(swpart->name, swinfo, FALSE) == TMERR_DUPLICATE) + mame_printf_error("%s: %s has a part (%s) whose name is duplicate\n", list->file->filename(), swinfo->shortname, swpart->name); - for (software_part *swpart = software_find_part(swinfo, NULL, NULL); swpart != NULL; swpart = software_part_next(swpart)) - { - if (swpart->interface_ == NULL) - { - mame_printf_error("%s: %s has a part (%s) without interface\n", list->file->filename(), swinfo->shortname, swpart->name); - error = TRUE; - } + for (struct rom_entry *swdata = software_find_romdata(swpart, NULL); swdata != NULL; swdata = software_romdata_next(swdata)) + { + struct rom_entry *data = swdata; - if (software_find_romdata(swpart, NULL) == NULL) - { - mame_printf_error("%s: %s has a part (%s) with no data\n", list->file->filename(), swinfo->shortname, swpart->name); - error = TRUE; - } + if (data->_name && data->_hashdata) + { + const char *str; - if (part_names.add(swpart->name, swinfo, FALSE) == TMERR_DUPLICATE) + /* make sure it's all lowercase */ + for (str = data->_name; *str; str++) + if (tolower((UINT8)*str) != *str) { - mame_printf_error("%s: %s has a part (%s) whose name is duplicate\n", list->file->filename(), swinfo->shortname, swpart->name); - error = TRUE; + mame_printf_error("%s: %s has upper case ROM name %s\n", list->file->filename(), swinfo->shortname, data->_name); + break; } - for (struct rom_entry *swdata = software_find_romdata(swpart, NULL); swdata != NULL; swdata = software_romdata_next(swdata)) - { - struct rom_entry *data = swdata; - - if (data->_name && data->_hashdata) - { - const char *str; - - /* make sure it's all lowercase */ - for (str = data->_name; *str; str++) - if (tolower((UINT8)*str) != *str) - { - mame_printf_error("%s: %s has upper case ROM name %s\n", list->file->filename(), swinfo->shortname, data->_name); - error = TRUE; - break; - } - - /* make sure the hash is valid */ - hash_collection hashes; - if (!hashes.from_internal_string(data->_hashdata)) - { - mame_printf_error("%s: %s has rom '%s' with an invalid hash string '%s'\n", list->file->filename(), swinfo->shortname, data->_name, data->_hashdata); - error = TRUE; - } - } - } - } + /* make sure the hash is valid */ + hash_collection hashes; + if (!hashes.from_internal_string(data->_hashdata)) + mame_printf_error("%s: %s has rom '%s' with an invalid hash string '%s'\n", list->file->filename(), swinfo->shortname, data->_name, data->_hashdata); } } - software_list_close(list); } } + software_list_close(list); } - if (error) - throw emu_fatalerror(MAMERR_FAILED_VALIDITY, "Validity checks failed"); } - -DEVICE_GET_INFO( software_list ) -{ - switch (state) - { - /* --- the following bits of info are returned as 64-bit signed integers --- */ - case DEVINFO_INT_TOKEN_BYTES: info->i = 1; break; - case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(software_list_config); break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( software_list ); break; - case DEVINFO_FCT_STOP: /* Nothing */ break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case DEVINFO_STR_NAME: strcpy(info->s, "Software lists"); break; - case DEVINFO_STR_FAMILY: strcpy(info->s, "Software lists"); break; - case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break; - case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; - case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright MESS Team"); break; - } -} - - -DEFINE_LEGACY_DEVICE(SOFTWARE_LIST, software_list); diff --git a/src/emu/softlist.h b/src/emu/softlist.h index 9983bcc68d6..6c8b5af041e 100644 --- a/src/emu/softlist.h +++ b/src/emu/softlist.h @@ -14,6 +14,84 @@ #include "pool.h" + +#define SOFTWARE_SUPPORTED_YES 0 +#define SOFTWARE_SUPPORTED_PARTIAL 1 +#define SOFTWARE_SUPPORTED_NO 2 + +enum softlist_type +{ + SOFTWARE_LIST_ORIGINAL_SYSTEM, + SOFTWARE_LIST_COMPATIBLE_SYSTEM +}; + +#define MCFG_SOFTWARE_LIST_CONFIG(_list,_list_type) \ + software_list_device::static_set_config(*device, _list, _list_type); + +#define MCFG_SOFTWARE_LIST_ADD( _tag, _list ) \ + MCFG_DEVICE_ADD( _tag, SOFTWARE_LIST, 0 ) \ + MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_ORIGINAL_SYSTEM) + +#define MCFG_SOFTWARE_LIST_COMPATIBLE_ADD( _tag, _list ) \ + MCFG_DEVICE_ADD( _tag, SOFTWARE_LIST, 0 ) \ + MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_COMPATIBLE_SYSTEM) + +#define MCFG_SOFTWARE_LIST_MODIFY( _tag, _list ) \ + MCFG_DEVICE_MODIFY( _tag ) \ + MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_ORIGINAL_SYSTEM) + +#define MCFG_SOFTWARE_LIST_COMPATIBLE_MODIFY( _tag, _list ) \ + MCFG_DEVICE_MODIFY( _tag ) \ + MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_COMPATIBLE_SYSTEM) + +#define MCFG_SOFTWARE_LIST_FILTER( _tag, _filter ) \ + MCFG_DEVICE_MODIFY( _tag ) \ + software_list_device::static_set_filter(*device, _filter); + + +// ======================> software_list_device + +class software_list_device : public device_t +{ +public: + // construction/destruction + software_list_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // inline configuration helpers + static void static_set_config(device_t &device, const char *list, softlist_type list_type); + static void static_set_filter(device_t &device, const char *filter); + + // getters + const char *list_name() const { return m_list_name; } + softlist_type list_type() const { return m_list_type; } + const char *filter() const { return m_filter; } + + // validation helpers + static void reset_checked_lists() { s_checked_lists.reset(); } + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_validity_check(validity_checker &valid) const ATTR_COLD; + + // configuration state + const char * m_list_name; + softlist_type m_list_type; + const char * m_filter; + + // static state + static tagmap_t<UINT8> s_checked_lists; +}; + + +// device type definition +extern const device_type SOFTWARE_LIST; + +// device type iterator +typedef device_type_iterator<&device_creator<software_list_device>, software_list_device> software_list_device_iterator; + + + /********************************************************************* Internal structures and XML file handling @@ -95,13 +173,6 @@ struct software_list int list_entries; }; -struct software_list_config -{ - char *list_name; - UINT32 list_type; - const char *filter; -}; - /* Handling a software list */ software_list *software_list_open(emu_options &options, const char *listname, int is_preload, void (*error_proc)(const char *message)); void software_list_close(const software_list *swlist); @@ -123,53 +194,11 @@ const char *software_part_get_feature(const software_part *part, const char *fea bool load_software_part(emu_options &options, device_image_interface *image, const char *path, software_info **sw_info, software_part **sw_part, char **full_sw_name); -void software_display_matches(const device_list &devlist, emu_options &options,const char *interface,const char *swname_bckp); +void software_display_matches(const machine_config &config, emu_options &options,const char *interface,const char *swname_bckp); -const char *software_get_default_slot(const device_list &devlist, emu_options &options, const device_image_interface *image, const char* default_card_slot); +const char *software_get_default_slot(const machine_config &config, emu_options &options, const device_image_interface *image, const char* default_card_slot); -void validate_softlists(emu_options &options); - -bool is_software_compatible(const software_part *swpart, const software_list_config *swlist); +bool is_software_compatible(const software_part *swpart, const software_list_device *swlist); bool swinfo_has_multiple_parts(const software_info *swinfo, const char *interface); -/********************************************************************* - - Driver software list configuration - -*********************************************************************/ -DECLARE_LEGACY_DEVICE(SOFTWARE_LIST, software_list); - -#define SOFTWARE_SUPPORTED_YES 0 -#define SOFTWARE_SUPPORTED_PARTIAL 1 -#define SOFTWARE_SUPPORTED_NO 2 - -#define SOFTWARE_LIST_ORIGINAL_SYSTEM 0 -#define SOFTWARE_LIST_COMPATIBLE_SYSTEM 1 - -#define MCFG_SOFTWARE_LIST_CONFIG(_list,_list_type) \ - MCFG_DEVICE_CONFIG_DATAPTR(software_list_config, list_name, _list) \ - MCFG_DEVICE_CONFIG_DATA32(software_list_config, list_type, _list_type) - -#define MCFG_SOFTWARE_LIST_ADD( _tag, _list ) \ - MCFG_DEVICE_ADD( _tag, SOFTWARE_LIST, 0 ) \ - MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_ORIGINAL_SYSTEM) - - -#define MCFG_SOFTWARE_LIST_COMPATIBLE_ADD( _tag, _list ) \ - MCFG_DEVICE_ADD( _tag, SOFTWARE_LIST, 0 ) \ - MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_COMPATIBLE_SYSTEM) - - -#define MCFG_SOFTWARE_LIST_MODIFY( _tag, _list ) \ - MCFG_DEVICE_MODIFY( _tag ) \ - MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_ORIGINAL_SYSTEM) - -#define MCFG_SOFTWARE_LIST_COMPATIBLE_MODIFY( _tag, _list ) \ - MCFG_DEVICE_MODIFY( _tag ) \ - MCFG_SOFTWARE_LIST_CONFIG(_list, SOFTWARE_LIST_COMPATIBLE_SYSTEM) - -#define MCFG_SOFTWARE_LIST_FILTER( _tag, _filter ) \ - MCFG_DEVICE_MODIFY( _tag ) \ - MCFG_DEVICE_CONFIG_DATAPTR(software_list_config, filter, _filter) - #endif diff --git a/src/emu/sound.c b/src/emu/sound.c index 0586b6a72e8..eb201a7448f 100644 --- a/src/emu/sound.c +++ b/src/emu/sound.c @@ -788,7 +788,10 @@ sound_manager::sound_manager(running_machine &machine) machine.m_sample_rate = 11025; // count the speakers - VPRINTF(("total speakers = %d\n", machine.devicelist().count(SPEAKER))); +#if VERBOSE + speaker_device_iterator iter(machine.root_device()); + VPRINTF(("total speakers = %d\n", iter.count())); +#endif // allocate memory for mix buffers m_leftmix = auto_alloc_array(machine, INT32, machine.sample_rate()); @@ -862,7 +865,8 @@ void sound_manager::set_attenuation(int attenuation) bool sound_manager::indexed_speaker_input(int index, speaker_input &info) const { // scan through the speakers until we find the indexed input - for (info.speaker = downcast<speaker_device *>(machine().devicelist().first(SPEAKER)); info.speaker != NULL; info.speaker = info.speaker->next_speaker()) + speaker_device_iterator iter(machine().root_device()); + for (info.speaker = iter.first(); info.speaker != NULL; info.speaker = iter.next()) { if (index < info.speaker->inputs()) { @@ -899,8 +903,8 @@ void sound_manager::mute(bool mute, UINT8 reason) void sound_manager::reset() { // reset all the sound chips - device_sound_interface *sound = NULL; - for (bool gotone = machine().devicelist().first(sound); gotone; gotone = sound->next(sound)) + sound_interface_iterator iter(machine().root_device()); + for (device_sound_interface *sound = iter.first(); sound != NULL; sound = iter.next()) sound->device().reset(); } @@ -1003,7 +1007,8 @@ void sound_manager::update() // force all the speaker streams to generate the proper number of samples int samples_this_update = 0; - for (speaker_device *speaker = downcast<speaker_device *>(machine().devicelist().first(SPEAKER)); speaker != NULL; speaker = speaker->next_speaker()) + speaker_device_iterator iter(machine().root_device()); + for (speaker_device *speaker = iter.first(); speaker != NULL; speaker = iter.next()) speaker->mix(m_leftmix, m_rightmix, samples_this_update, (m_muted & MUTE_REASON_SYSTEM)); // now downmix the final result diff --git a/src/emu/sound/bsmt2000.c b/src/emu/sound/bsmt2000.c index 4f3ddbf930a..20d9269cb85 100644 --- a/src/emu/sound/bsmt2000.c +++ b/src/emu/sound/bsmt2000.c @@ -173,7 +173,7 @@ machine_config_constructor bsmt2000_device::device_mconfig_additions() const void bsmt2000_device::device_start() { // find our CPU - m_cpu = downcast<tms32015_device*>(subdevice("bsmt2000")); + m_cpu = subdevice<tms32015_device>("bsmt2000"); // find our direct access m_direct = &space()->direct(); diff --git a/src/emu/sound/cdda.c b/src/emu/sound/cdda.c index 6eea9e498fb..8b4a9af1118 100644 --- a/src/emu/sound/cdda.c +++ b/src/emu/sound/cdda.c @@ -90,9 +90,8 @@ void cdda_set_cdrom(device_t *device, void *file) device_t *cdda_from_cdrom(running_machine &machine, void *file) { - device_sound_interface *sound = NULL; - - for (bool gotone = machine.devicelist().first(sound); gotone; gotone = sound->next(sound)) + sound_interface_iterator iter(machine.root_device()); + for (device_sound_interface *sound = iter.first(); sound != NULL; sound = iter.next()) if (sound->device().type() == CDDA) { cdda_info *info = get_safe_token(*sound); diff --git a/src/emu/sound/disc_inp.c b/src/emu/sound/disc_inp.c index d2e09bcd7e0..e30a9af4340 100644 --- a/src/emu/sound/disc_inp.c +++ b/src/emu/sound/disc_inp.c @@ -75,7 +75,8 @@ DISCRETE_RESET(dss_adjustment) { double min, max; - m_port = m_device->machine().m_portlist.find((const char *)this->custom_data()); + astring fulltag; + m_port = m_device->machine().m_portlist.find(m_device->siblingtag(fulltag, (const char *)this->custom_data()).cstr()); if (m_port == NULL) fatalerror("DISCRETE_ADJUSTMENT - NODE_%d has invalid tag", this->index()); diff --git a/src/emu/sound/samples.h b/src/emu/sound/samples.h index 0d44d994c2f..b3abd505b04 100644 --- a/src/emu/sound/samples.h +++ b/src/emu/sound/samples.h @@ -46,4 +46,6 @@ loaded_samples *readsamples(running_machine &machine, const char *const *samplen DECLARE_LEGACY_SOUND_DEVICE(SAMPLES, samples); +typedef device_type_iterator<&legacy_device_creator<samples_device>, samples_device> samples_device_iterator; + #endif /* __SAMPLES_H__ */ diff --git a/src/emu/sound/wave.c b/src/emu/sound/wave.c index 179b02512e6..1d879de288b 100644 --- a/src/emu/sound/wave.c +++ b/src/emu/sound/wave.c @@ -22,7 +22,6 @@ static STREAM_UPDATE( wave_sound_update ) { cassette_image_device *cass = (cassette_image_device *)param; - int speakers = cass->machine().devicelist().count(SPEAKER); cassette_image *cassette; cassette_state state; double time_index; @@ -31,6 +30,8 @@ static STREAM_UPDATE( wave_sound_update ) stream_sample_t *right_buffer = NULL; int i; + speaker_device_iterator spkiter(cass->machine().root_device()); + int speakers = spkiter.count(); if (speakers>1) right_buffer = outputs[1]; @@ -71,7 +72,8 @@ static DEVICE_START( wave ) assert( device != NULL ); assert( device->static_config() != NULL ); - int speakers = device->machine().config().devicelist().count(SPEAKER); + speaker_device_iterator spkiter(device->machine().root_device()); + int speakers = spkiter.count(); image = dynamic_cast<cassette_image_device *>(device->machine().device( (const char *)device->static_config())); if (speakers > 1) device->machine().sound().stream_alloc(*device, 0, 2, device->machine().sample_rate(), (void *)image, wave_sound_update); diff --git a/src/emu/speaker.h b/src/emu/speaker.h index 31b6f4696c7..3ead6eab11c 100644 --- a/src/emu/speaker.h +++ b/src/emu/speaker.h @@ -84,9 +84,6 @@ public: // inline configuration helpers static void static_set_position(device_t &device, double x, double y, double z); - // getters - speaker_device *next_speaker() const { return downcast<speaker_device *>(typenext()); } - // internally for use by the sound system void mix(INT32 *leftmix, INT32 *rightmix, int &samples_this_update, bool suppress); @@ -117,4 +114,8 @@ protected: extern const device_type SPEAKER; +// speaker device iterator +typedef device_type_iterator<&device_creator<speaker_device>, speaker_device> speaker_device_iterator; + + #endif /* __SOUND_H__ */ diff --git a/src/emu/timer.c b/src/emu/timer.c index 28ed940c93b..70a81315b6a 100644 --- a/src/emu/timer.c +++ b/src/emu/timer.c @@ -176,54 +176,40 @@ void timer_device::static_set_ptr(device_t &device, void *ptr) // configuration //------------------------------------------------- -bool timer_device::device_validity_check(emu_options &options, const game_driver &driver) const +void timer_device::device_validity_check(validity_checker &valid) const { - bool error = false; - // type based configuration switch (m_type) { case TIMER_TYPE_GENERIC: if (m_screen_tag != NULL || m_first_vpos != 0 || m_start_delay != attotime::zero) - mame_printf_warning("%s: %s generic timer '%s' specified parameters for a scanline timer\n", driver.source_file, driver.name, tag()); + mame_printf_warning("Generic timer specified parameters for a scanline timer\n"); if (m_period != attotime::zero || m_start_delay != attotime::zero) - mame_printf_warning("%s: %s generic timer '%s' specified parameters for a periodic timer\n", driver.source_file, driver.name, tag()); + mame_printf_warning("Generic timer specified parameters for a periodic timer\n"); break; case TIMER_TYPE_PERIODIC: if (m_screen_tag != NULL || m_first_vpos != 0) - mame_printf_warning("%s: %s periodic timer '%s' specified parameters for a scanline timer\n", driver.source_file, driver.name, tag()); + mame_printf_warning("Periodic timer specified parameters for a scanline timer\n"); if (m_period <= attotime::zero) - { - mame_printf_error("%s: %s periodic timer '%s' specified invalid period\n", driver.source_file, driver.name, tag()); - error = true; - } + mame_printf_error("Periodic timer specified invalid period\n"); break; case TIMER_TYPE_SCANLINE: if (m_period != attotime::zero || m_start_delay != attotime::zero) - mame_printf_warning("%s: %s scanline timer '%s' specified parameters for a periodic timer\n", driver.source_file, driver.name, tag()); + mame_printf_warning("Scanline timer specified parameters for a periodic timer\n"); if (m_param != 0) - mame_printf_warning("%s: %s scanline timer '%s' specified parameter which is ignored\n", driver.source_file, driver.name, tag()); + mame_printf_warning("Scanline timer specified parameter which is ignored\n"); if (m_first_vpos < 0) - { - mame_printf_error("%s: %s scanline timer '%s' specified invalid initial position\n", driver.source_file, driver.name, tag()); - error = true; - } + mame_printf_error("Scanline timer specified invalid initial position\n"); if (m_increment < 0) - { - mame_printf_error("%s: %s scanline timer '%s' specified invalid increment\n", driver.source_file, driver.name, tag()); - error = true; - } + mame_printf_error("Scanline timer specified invalid increment\n"); break; default: - mame_printf_error("%s: %s timer '%s' has an invalid type\n", driver.source_file, driver.name, tag()); - error = true; + mame_printf_error("Invalid type specified\n"); break; } - - return error; } diff --git a/src/emu/timer.h b/src/emu/timer.h index fff33be5ad4..7c01feb0375 100644 --- a/src/emu/timer.h +++ b/src/emu/timer.h @@ -142,7 +142,7 @@ public: private: // device-level overrides - virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; + virtual void device_validity_check(validity_checker &valid) const; virtual void device_start(); virtual void device_reset(); virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); diff --git a/src/emu/ui.c b/src/emu/ui.c index bdea3a453d2..eb87b3cf5ae 100644 --- a/src/emu/ui.c +++ b/src/emu/ui.c @@ -1018,29 +1018,30 @@ static astring &warnings_string(running_machine &machine, astring &string) astring &game_info_astring(running_machine &machine, astring &string) { - int scrcount = machine.devicelist().count(SCREEN); + screen_device_iterator scriter(machine.root_device()); + int scrcount = scriter.count(); int found_sound = FALSE; /* print description, manufacturer, and CPU: */ string.printf("%s\n%s %s\n\nCPU:\n", machine.system().description, machine.system().year, machine.system().manufacturer); /* loop over all CPUs */ - device_execute_interface *exec = NULL; - for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec)) + execute_interface_iterator execiter(machine.root_device()); + for (device_execute_interface *exec = execiter.first(); exec != NULL; exec = execiter.next()) { /* get cpu specific clock that takes internal multiplier/dividers into account */ int clock = exec->device().clock(); /* count how many identical CPUs we have */ int count = 1; - device_execute_interface *scan = NULL; - for (bool gotanother = exec->next(scan); gotanother; gotanother = scan->next(scan)) + for (device_execute_interface *scan = execiter.next(); scan != NULL; scan = execiter.next()) { if (exec->device().type() != scan->device().type() || exec->device().clock() != scan->device().clock()) break; count++; exec = scan; } + execiter.set_current(*exec); /* if more than one, prepend a #x in front of the CPU name */ if (count > 1) @@ -1055,8 +1056,8 @@ astring &game_info_astring(running_machine &machine, astring &string) } /* loop over all sound chips */ - device_sound_interface *sound = NULL; - for (bool gotone = machine.devicelist().first(sound); gotone; gotone = sound->next(sound)) + sound_interface_iterator snditer(machine.root_device()); + for (device_sound_interface *sound = snditer.first(); sound != NULL; sound = snditer.next()) { /* append the Sound: string */ if (!found_sound) @@ -1065,14 +1066,14 @@ astring &game_info_astring(running_machine &machine, astring &string) /* count how many identical sound chips we have */ int count = 1; - device_sound_interface *scan = NULL; - for (bool gotanother = sound->next(scan); gotanother; gotanother = scan->next(scan)) + for (device_sound_interface *scan = snditer.next(); scan != NULL; scan = snditer.next()) { if (sound->device().type() != scan->device().type() || sound->device().clock() != scan->device().clock()) break; count++; sound = scan; } + snditer.set_current(*sound); /* if more than one, prepend a #x in front of the CPU name */ if (count > 1) @@ -1095,7 +1096,8 @@ astring &game_info_astring(running_machine &machine, astring &string) string.cat("None\n"); else { - for (screen_device *screen = machine.first_screen(); screen != NULL; screen = screen->next_screen()) + screen_device_iterator iter(machine.root_device()); + for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next()) { if (scrcount > 1) { @@ -1271,17 +1273,13 @@ void ui_paste(running_machine &machine) void ui_image_handler_ingame(running_machine &machine) { - device_image_interface *image = NULL; - /* run display routine for devices */ if (machine.phase() == MACHINE_PHASE_RUNNING) { - for (bool gotone = machine.devicelist().first(image); gotone; gotone = image->next(image)) - { + image_interface_iterator iter(machine.root_device()); + for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) image->call_display(); - } } - } /*------------------------------------------------- @@ -1644,7 +1642,6 @@ static slider_state *slider_init(running_machine &machine) { input_field_config *field; input_port_config *port; - device_t *device; slider_state *listhead = NULL; slider_state **tailptr = &listhead; astring string; @@ -1683,8 +1680,8 @@ static slider_state *slider_init(running_machine &machine) /* add CPU overclocking (cheat only) */ if (machine.options().cheat()) { - device_execute_interface *exec = NULL; - for (bool gotone = machine.devicelist().first(exec); gotone; gotone = exec->next(exec)) + execute_interface_iterator iter(machine.root_device()); + for (device_execute_interface *exec = iter.first(); exec != NULL; exec = iter.next()) { void *param = (void *)&exec->device(); string.printf("Overclock CPU %s", exec->device().tag()); @@ -1694,7 +1691,8 @@ static slider_state *slider_init(running_machine &machine) } /* add screen parameters */ - for (screen_device *screen = machine.first_screen(); screen != NULL; screen = screen->next_screen()) + screen_device_iterator scriter(machine.root_device()); + for (screen_device *screen = scriter.first(); screen != NULL; screen = scriter.next()) { int defxscale = floor(screen->xscale() * 1000.0f + 0.5f); int defyscale = floor(screen->yscale() * 1000.0f + 0.5f); @@ -1736,10 +1734,9 @@ static slider_state *slider_init(running_machine &machine) tailptr = &(*tailptr)->next; } - for (device = machine.devicelist().first(); device != NULL; device = device->next()) - { - laserdisc_device *laserdisc = dynamic_cast<laserdisc_device *>(device); - if (laserdisc != NULL && laserdisc->overlay_configured()) + laserdisc_device_iterator lditer(machine.root_device()); + for (laserdisc_device *laserdisc = lditer.first(); laserdisc != NULL; laserdisc = lditer.next()) + if (laserdisc->overlay_configured()) { laserdisc_overlay_config config; laserdisc->get_overlay_config(config); @@ -1763,9 +1760,8 @@ static slider_state *slider_init(running_machine &machine) *tailptr = slider_alloc(machine, string, -500, defyoffset, 500, 2, slider_overyoffset, param); tailptr = &(*tailptr)->next; } - } - for (screen_device *screen = machine.first_screen(); screen != NULL; screen = screen->next_screen()) + for (screen_device *screen = scriter.first(); screen != NULL; screen = scriter.next()) if (screen->screen_type() == SCREEN_TYPE_VECTOR) { /* add flicker control */ @@ -2172,7 +2168,8 @@ static INT32 slider_beam(running_machine &machine, void *arg, astring *string, I static char *slider_get_screen_desc(screen_device &screen) { - int scrcount = screen.machine().devicelist().count(SCREEN); + screen_device_iterator iter(screen.machine().root_device()); + int scrcount = iter.count(); static char descbuf[256]; if (scrcount > 1) diff --git a/src/emu/uiimage.c b/src/emu/uiimage.c index aaedc71c1e5..db1ad578bdf 100644 --- a/src/emu/uiimage.c +++ b/src/emu/uiimage.c @@ -770,11 +770,11 @@ ui_menu_file_manager::ui_menu_file_manager(running_machine &machine, render_cont void ui_menu_file_manager::populate() { char buffer[2048]; - device_image_interface *image = NULL; astring tmp_name; /* cycle through all devices for this system */ - for (bool gotone = machine().devicelist().first(image); gotone; gotone = image->next(image)) + image_interface_iterator iter(machine().root_device()); + for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) { /* get the image type/id */ snprintf(buffer, ARRAY_LENGTH(buffer), @@ -1000,15 +1000,8 @@ ui_menu_mess_bitbanger_control::~ui_menu_mess_bitbanger_control() int ui_menu_mess_tape_control::cassette_count() { - int count = 0; - device_t *device = machine().devicelist().first(CASSETTE); - - while ( device ) - { - count++; - device = device->typenext(); - } - return count; + cassette_device_iterator iter(machine().root_device()); + return iter.count(); } /*------------------------------------------------- @@ -1018,15 +1011,8 @@ int ui_menu_mess_tape_control::cassette_count() int ui_menu_mess_bitbanger_control::bitbanger_count() { - int count = 0; - device_t *device = machine().devicelist().first(BITBANGER); - - while ( device ) - { - count++; - device = device->typenext(); - } - return count; + bitbanger_device_iterator iter(machine().root_device()); + return iter.count(); } /*------------------------------------------------- @@ -1197,14 +1183,8 @@ void ui_menu_mess_tape_control::handle() /* do we have to load the device? */ if (device == NULL) { - int cindex = index; - for (bool gotone = machine().devicelist().first(device); gotone; gotone = device->next(device)) - { - if(device->device().type() == CASSETTE) { - if (cindex==0) break; - cindex--; - } - } + cassette_device_iterator iter(machine().root_device()); + device = iter.byindex(index); reset((ui_menu_reset_options)0); } @@ -1286,14 +1266,8 @@ void ui_menu_mess_bitbanger_control::handle() /* do we have to load the device? */ if (device == NULL) { - int cindex = index; - for (bool gotone = machine().devicelist().first(device); gotone; gotone = device->next(device)) - { - if(device->device().type() == BITBANGER) { - if (cindex==0) break; - cindex--; - } - } + bitbanger_device_iterator iter(machine().root_device()); + device = iter.byindex(index); reset((ui_menu_reset_options)0); } diff --git a/src/emu/uimain.c b/src/emu/uimain.c index d0e657533c1..fbbead0fa13 100644 --- a/src/emu/uimain.c +++ b/src/emu/uimain.c @@ -149,8 +149,8 @@ void ui_menu_main::populate() menu_text.printf("%s Information",emulator_info::get_capstartgamenoun()); item_append(menu_text.cstr(), NULL, 0, (void *)GAME_INFO); - device_image_interface *image = NULL; - if (machine().devicelist().first(image)) + image_interface_iterator imgiter(machine().root_device()); + if (imgiter.first() != NULL) { /* add image info menu */ item_append("Image Information", NULL, 0, (void *)IMAGE_MENU_IMAGE_INFO); @@ -159,23 +159,25 @@ void ui_menu_main::populate() item_append("File Manager", NULL, 0, (void *)IMAGE_MENU_FILE_MANAGER); /* add tape control menu */ - if (machine().devicelist().first(CASSETTE)) + cassette_device_iterator cassiter(machine().root_device()); + if (cassiter.first() != NULL) item_append("Tape Control", NULL, 0, (void *)MESS_MENU_TAPE_CONTROL); /* add bitbanger control menu */ - if (machine().devicelist().first(BITBANGER)) + bitbanger_device_iterator bititer(machine().root_device()); + if (bititer.first() != NULL) item_append("Bitbanger Control", NULL, 0, (void *)MESS_MENU_BITBANGER_CONTROL); } - device_slot_interface *slot = NULL; - if (machine().devicelist().first(slot)) + slot_interface_iterator slotiter(machine().root_device()); + if (slotiter.first() != NULL) { /* add image info menu */ item_append("Slot Devices", NULL, 0, (void *)SLOT_DEVICES); } - device_network_interface *network = NULL; - if (machine().devicelist().first(network)) + network_interface_iterator netiter(machine().root_device()); + if (netiter.first() != NULL) { /* add image info menu */ item_append("Network Devices", NULL, 0, (void*)NETWORK_DEVICES); @@ -427,10 +429,9 @@ ui_menu_slot_devices::ui_menu_slot_devices(running_machine &machine, render_cont void ui_menu_slot_devices::populate() { - device_slot_interface *slot = NULL; - /* cycle through all devices for this system */ - for (bool gotone = machine().devicelist().first(slot); gotone; gotone = slot->next(slot)) + slot_interface_iterator iter(machine().root_device()); + for (device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next()) { /* record the menu item */ const char *title = get_slot_device(slot); @@ -481,10 +482,9 @@ ui_menu_network_devices::~ui_menu_network_devices() void ui_menu_network_devices::populate() { - device_network_interface *network = NULL; - /* cycle through all devices for this system */ - for (bool gotone = machine().devicelist().first(network); gotone; gotone = network->next(network)) + network_interface_iterator iter(machine().root_device()); + for (device_network_interface *network = iter.first(); network != NULL; network = iter.next()) { int curr = network->get_interface(); const char *title = NULL; diff --git a/src/emu/uiswlist.c b/src/emu/uiswlist.c index 136e142eab4..44fcb9efd4d 100644 --- a/src/emu/uiswlist.c +++ b/src/emu/uiswlist.c @@ -157,7 +157,7 @@ ui_menu_software_list::entry_info *ui_menu_software_list::append_software_entry( return entry; } -ui_menu_software_list::ui_menu_software_list(running_machine &machine, render_container *container, const software_list_config *_swlist, const char *_interface, astring &_result) : ui_menu(machine, container), result(_result) +ui_menu_software_list::ui_menu_software_list(running_machine &machine, render_container *container, const software_list_device *_swlist, const char *_interface, astring &_result) : ui_menu(machine, container), result(_result) { swlist = _swlist; interface = _interface; @@ -171,7 +171,7 @@ ui_menu_software_list::~ui_menu_software_list() void ui_menu_software_list::populate() { - const software_list *list = software_list_open(machine().options(), swlist->list_name, false, NULL); + const software_list *list = software_list_open(machine().options(), swlist->list_name(), false, NULL); // build up the list of entries for the menu if (list) @@ -313,7 +313,7 @@ void ui_menu_software_list::handle() } /* list of available software lists - i.e. cartridges, floppies */ -ui_menu_software::ui_menu_software(running_machine &machine, render_container *container, const char *_interface, const software_list_config **_result) : ui_menu(machine, container) +ui_menu_software::ui_menu_software(running_machine &machine, render_container *container, const char *_interface, const software_list_device **_result) : ui_menu(machine, container) { interface = _interface; result = _result; @@ -324,13 +324,12 @@ void ui_menu_software::populate() bool haveCompatible = false; // Add original software lists for this system - for (const device_t *dev = machine().config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) + software_list_device_iterator iter(machine().config().root_device()); + for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next()) { - const software_list_config *swlist = (const software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config(); - - if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM) + if (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM) { - const software_list *list = software_list_open(machine().options(), swlist->list_name, false, NULL); + const software_list *list = software_list_open(machine().options(), swlist->list_name(), false, NULL); if (list) { @@ -352,13 +351,11 @@ void ui_menu_software::populate() } // Add compatible software lists for this system - for (const device_t *dev = machine().config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) + for (const software_list_device *swlist = iter.first(); swlist != NULL; swlist = iter.next()) { - const software_list_config *swlist = (const software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config(); - - if (swlist->list_type == SOFTWARE_LIST_COMPATIBLE_SYSTEM) + if (swlist->list_type() == SOFTWARE_LIST_COMPATIBLE_SYSTEM) { - const software_list *list = software_list_open(machine().options(), swlist->list_name, false, NULL); + const software_list *list = software_list_open(machine().options(), swlist->list_name(), false, NULL); if (list) { @@ -396,7 +393,7 @@ void ui_menu_software::handle() if (event != NULL && event->iptkey == IPT_UI_SELECT) { // ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software_list(machine(), container, (software_list_config *)event->itemref, image))); - *result = (software_list_config *)event->itemref; + *result = (software_list_device *)event->itemref; ui_menu::stack_pop(machine()); } } diff --git a/src/emu/uiswlist.h b/src/emu/uiswlist.h index da92c9f5917..f914f0faedf 100644 --- a/src/emu/uiswlist.h +++ b/src/emu/uiswlist.h @@ -35,7 +35,7 @@ private: class ui_menu_software_list : public ui_menu { public: - ui_menu_software_list(running_machine &machine, render_container *container, const software_list_config *swlist, const char *interface, astring &result); + ui_menu_software_list(running_machine &machine, render_container *container, const software_list_device *swlist, const char *interface, astring &result); virtual ~ui_menu_software_list(); virtual void populate(); virtual void handle(); @@ -48,7 +48,7 @@ private: const char *long_name; }; - const software_list_config *swlist; /* currently selected list */ + const software_list_device *swlist; /* currently selected list */ const char *interface; astring &result; entry_info *entrylist; @@ -61,14 +61,14 @@ private: class ui_menu_software : public ui_menu { public: - ui_menu_software(running_machine &machine, render_container *container, const char *interface, const software_list_config **result); + ui_menu_software(running_machine &machine, render_container *container, const char *interface, const software_list_device **result); virtual ~ui_menu_software(); virtual void populate(); virtual void handle(); private: const char *interface; - const software_list_config **result; + const software_list_device **result; }; #endif /* __UISWLIST_H__ */ diff --git a/src/emu/validity.c b/src/emu/validity.c index 8a1ebd2e4ea..8fb14d76c82 100644 --- a/src/emu/validity.c +++ b/src/emu/validity.c @@ -4,8 +4,36 @@ Validity checks on internal data structures. - Copyright Nicola Salmoria and the MAME Team. - Visit http://mamedev.org for licensing and usage restrictions. +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ @@ -13,22 +41,15 @@ #include "hash.h" #include "validity.h" #include "emuopts.h" +#include "softlist.h" #include <ctype.h> -/*************************************************************************** - DEBUGGING -***************************************************************************/ - -#define REPORT_TIMES (0) - - +//************************************************************************** +// COMPILE-TIME VALIDATION +//************************************************************************** -/*************************************************************************** - COMPILE-TIME VALIDATION -***************************************************************************/ - -/* if the following lines error during compile, your PTR64 switch is set incorrectly in the makefile */ +// if the following lines error during compile, your PTR64 switch is set incorrectly in the makefile #ifdef PTR64 UINT8 your_ptr64_flag_is_wrong[(int)(sizeof(void *) - 7)]; #else @@ -37,131 +58,332 @@ UINT8 your_ptr64_flag_is_wrong[(int)(5 - sizeof(void *))]; -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** -typedef tagmap_t<const game_driver *> game_driver_map; +extern const device_type *s_devices_sorted[]; +extern int m_device_count; -typedef tagmap_t<FPTR> int_map; -class region_entry -{ -public: - region_entry() - : length(0) { } - astring tag; - UINT32 length; -}; +//************************************************************************** +// INLINE FUNCTIONS +//************************************************************************** +//------------------------------------------------- +// ioport_string_from_index - return an indexed +// string from the I/O port system +//------------------------------------------------- -class region_array +inline const char *validity_checker::ioport_string_from_index(UINT32 index) { -public: - region_entry entries[256]; -}; - - -extern const device_type *s_devices_sorted[]; -extern int m_device_count; + return input_port_string_from_token((const char *)(FPTR)index); +} -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ -/*------------------------------------------------- - input_port_string_from_index - return an - indexed string from the input port system --------------------------------------------------*/ +//------------------------------------------------- +// get_defstr_index - return the index of the +// string assuming it is one of the default +// strings +//------------------------------------------------- -INLINE const char *input_port_string_from_index(UINT32 index) +inline int validity_checker::get_defstr_index(const char *string, bool suppress_error) { - return input_port_string_from_token((const char *)(FPTR)index); + // check for strings that should be DEF_STR + int strindex = m_defstr_map.find(string); + if (!suppress_error && strindex != 0 && string != ioport_string_from_index(strindex)) + mame_printf_error("Must use DEF_STR( %s )\n", string); + return strindex; } -/*------------------------------------------------- - validate_tag - ensure that the given tag - meets the general requirements --------------------------------------------------*/ +//------------------------------------------------- +// validate_tag - ensure that the given tag +// meets the general requirements +//------------------------------------------------- -bool validate_tag(const game_driver &driver, const char *object, const char *tag) +void validity_checker::validate_tag(const char *tag) { - const char *validchars = "abcdefghijklmnopqrstuvwxyz0123456789_.:"; - const char *begin = strrchr(tag, ':'); - const char *p; - bool error = false; - - /* some common names that are now deprecated */ - if (strcmp(tag, "main") == 0 || - strcmp(tag, "audio") == 0 || - strcmp(tag, "sound") == 0 || - strcmp(tag, "left") == 0 || - strcmp(tag, "right") == 0) - { - mame_printf_error("%s: %s has invalid generic tag '%s'\n", driver.source_file, driver.name, tag); - error = true; - } + // some common names that are now deprecated + if (strcmp(tag, "main") == 0 || strcmp(tag, "audio") == 0 || strcmp(tag, "sound") == 0 || strcmp(tag, "left") == 0 || strcmp(tag, "right") == 0) + mame_printf_error("Invalid generic tag '%s' used\n", tag); - for (p = tag; *p != 0; p++) + // scan for invalid characters + static const char *validchars = "abcdefghijklmnopqrstuvwxyz0123456789_.:^$"; + for (const char *p = tag; *p != 0; p++) { + // only lower-case permitted if (*p != tolower((UINT8)*p)) { - mame_printf_error("%s: %s has %s with tag '%s' containing upper-case characters\n", driver.source_file, driver.name, object, tag); - error = true; + mame_printf_error("Tag '%s' contains upper-case characters\n", tag); break; } if (*p == ' ') { - mame_printf_error("%s: %s has %s with tag '%s' containing spaces\n", driver.source_file, driver.name, object, tag); - error = true; + mame_printf_error("Tag '%s' contains spaces\n", tag); break; } if (strchr(validchars, *p) == NULL) { - mame_printf_error("%s: %s has %s with tag '%s' containing invalid character '%c'\n", driver.source_file, driver.name, object, tag, *p); - error = true; + mame_printf_error("Tag '%s' contains invalid character '%c'\n", tag, *p); break; } } + // find the start of the final tag + const char *begin = strrchr(tag, ':'); if (begin == NULL) begin = tag; else begin += 1; + // 0-length = bad if (strlen(begin) == 0) + mame_printf_error("Found 0-length tag\n"); + + // too short/too long = bad + if (strlen(begin) < MIN_TAG_LENGTH) + mame_printf_error("Tag '%s' is too short (must be at least %d characters)\n", tag, MIN_TAG_LENGTH); + if (strlen(begin) > MAX_TAG_LENGTH) + mame_printf_error("Tag '%s' is too longer (must be less than %d characters)\n", tag, MAX_TAG_LENGTH); +} + + + +//************************************************************************** +// VALIDATION FUNCTIONS +//************************************************************************** + +//------------------------------------------------- +// validity_checker - constructor +//------------------------------------------------- + +validity_checker::validity_checker(emu_options &options) + : m_drivlist(options), + m_errors(0), + m_warnings(0), + m_current_driver(NULL), + m_current_config(NULL), + m_current_device(NULL), + m_current_ioport(NULL) +{ + // pre-populate the defstr map with all the default strings + for (int strnum = 1; strnum < INPUT_STRING_COUNT; strnum++) { - mame_printf_error("%s: %s has %s with 0-length tag\n", driver.source_file, driver.name, object); - error = true; + const char *string = ioport_string_from_index(strnum); + if (string != NULL) + m_defstr_map.add(string, strnum, false); } - if (strlen(begin) < MIN_TAG_LENGTH) +} + + +//------------------------------------------------- +// check_driver - check a single driver +//------------------------------------------------- + +void validity_checker::check_driver(const game_driver &driver) +{ + // simply validate the one driver + validate_begin(); + validate_one(driver); + validate_end(); +} + + +//------------------------------------------------- +// check_shared_source - check all drivers that +// share the same source file as the given driver +//------------------------------------------------- + +void validity_checker::check_shared_source(const game_driver &driver) +{ + // initialize + validate_begin(); + + // then iterate over all drivers and check the ones that share the same source file + m_drivlist.reset(); + while (m_drivlist.next()) + if (strcmp(driver.source_file, m_drivlist.driver().source_file) == 0) + validate_one(m_drivlist.driver()); + + // cleanup + validate_end(); +} + + +//------------------------------------------------- +// check_all - check all drivers +//------------------------------------------------- + +void validity_checker::check_all() +{ + // start by checking core stuff + validate_begin(); + validate_core(); + validate_inlines(); + + // then iterate over all drivers and check them + m_drivlist.reset(); + while (m_drivlist.next()) + validate_one(m_drivlist.driver()); + + // cleanup + validate_end(); +} + + +//------------------------------------------------- +// validate_begin - prepare for validation by +// taking over the output callbacks and resetting +// our internal state +//------------------------------------------------- + +void validity_checker::validate_begin() +{ + // take over error and warning outputs + m_saved_error_output = mame_set_output_channel(OUTPUT_CHANNEL_ERROR, output_delegate(FUNC(validity_checker::error_output), this)); + m_saved_warning_output = mame_set_output_channel(OUTPUT_CHANNEL_WARNING, output_delegate(FUNC(validity_checker::warning_output), this)); + + // reset all our maps + m_names_map.reset(); + m_descriptions_map.reset(); + m_roms_map.reset(); + m_defstr_map.reset(); + m_region_map.reset(); + + // reset internal state + m_errors = 0; + m_warnings = 0; + + // reset some special case state + software_list_device::reset_checked_lists(); +} + + +//------------------------------------------------- +// validate_end - restore output callbacks and +// clean up +//------------------------------------------------- + +void validity_checker::validate_end() +{ + // restore the original output callbacks + mame_set_output_channel(OUTPUT_CHANNEL_ERROR, m_saved_error_output); + mame_set_output_channel(OUTPUT_CHANNEL_WARNING, m_saved_warning_output); +} + + +//------------------------------------------------- +// validate_drivers - master validity checker +//------------------------------------------------- + +void validity_checker::validate_one(const game_driver &driver) +{ + // set the current driver + m_current_driver = &driver; + m_current_config = NULL; + m_current_device = NULL; + m_current_ioport = NULL; + m_region_map.reset(); + + // reset error/warning state + int start_errors = m_errors; + int start_warnings = m_warnings; + m_error_text.reset(); + m_warning_text.reset(); + + // wrap in try/except to catch fatalerrors + try { - mame_printf_error("%s: %s has %s with tag '%s' < %d characters\n", driver.source_file, driver.name, object, tag, MIN_TAG_LENGTH); - error = true; + machine_config config(driver, m_drivlist.options()); + m_current_config = &config; + validate_driver(); + validate_roms(); + validate_inputs(); + validate_display(); + validate_gfx(); + validate_devices(); + validate_slots(); } - if (strlen(begin) > MAX_TAG_LENGTH) + catch (emu_fatalerror &err) { - mame_printf_error("%s: %s has %s with tag '%s' > %d characters\n", driver.source_file, driver.name, object, tag, MAX_TAG_LENGTH); - error = true; + mame_printf_error("Fatal error %s", err.string()); + } + m_current_config = NULL; + + // if we had warnings or errors, output + if (m_errors > start_errors || m_warnings > start_warnings) + { + astring tempstr; + output_via_delegate(m_saved_error_output, "Driver %s (file %s): %d errors, %d warnings\n", driver.name, core_filename_extract_base(tempstr, driver.source_file).cstr(), m_errors - start_errors, m_warnings - start_warnings); + if (m_errors > start_errors) + { + m_error_text.replace("\n", "\n "); + output_via_delegate(m_saved_error_output, "Errors:\n %s", m_error_text.cstr()); + } + if (m_warnings > start_warnings) + { + m_warning_text.replace("\n", "\n "); + output_via_delegate(m_saved_error_output, "Warnings:\n %s", m_warning_text.cstr()); + } + output_via_delegate(m_saved_error_output, "\n"); } - return !error; + // reset the driver/device + m_current_driver = NULL; + m_current_config = NULL; + m_current_device = NULL; + m_current_ioport = NULL; } +//------------------------------------------------- +// validate_core - validate core internal systems +//------------------------------------------------- -/*************************************************************************** - VALIDATION FUNCTIONS -***************************************************************************/ +void validity_checker::validate_core() +{ -/*------------------------------------------------- - validate_inlines - validate inline function - behaviors --------------------------------------------------*/ + // basic system checks + UINT8 a = 0xff; + UINT8 b = a + 1; + if (b > a) mame_printf_error("UINT8 must be 8 bits\n"); + + // check size of core integer types + if (sizeof(INT8) != 1) mame_printf_error("INT8 must be 8 bits\n"); + if (sizeof(UINT8) != 1) mame_printf_error("UINT8 must be 8 bits\n"); + if (sizeof(INT16) != 2) mame_printf_error("INT16 must be 16 bits\n"); + if (sizeof(UINT16) != 2) mame_printf_error("UINT16 must be 16 bits\n"); + if (sizeof(INT32) != 4) mame_printf_error("INT32 must be 32 bits\n"); + if (sizeof(UINT32) != 4) mame_printf_error("UINT32 must be 32 bits\n"); + if (sizeof(INT64) != 8) mame_printf_error("INT64 must be 64 bits\n"); + if (sizeof(UINT64) != 8) mame_printf_error("UINT64 must be 64 bits\n"); + + // check pointer size +#ifdef PTR64 + if (sizeof(void *) != 8) mame_printf_error("PTR64 flag enabled, but was compiled for 32-bit target\n"); +#else + if (sizeof(void *) != 4) mame_printf_error("PTR64 flag not enabled, but was compiled for 64-bit target\n"); +#endif + + // check endianness definition + UINT16 lsbtest = 0; + *(UINT8 *)&lsbtest = 0xff; +#ifdef LSB_FIRST + if (lsbtest == 0xff00) mame_printf_error("LSB_FIRST specified, but running on a big-endian machine\n"); +#else + if (lsbtest == 0x00ff) mame_printf_error("LSB_FIRST not specified, but running on a little-endian machine\n"); +#endif +} + + +//------------------------------------------------- +// validate_inlines - validate inline function +// behaviors +//------------------------------------------------- -static bool validate_inlines(void) +void validity_checker::validate_inlines() { #undef rand volatile UINT64 testu64a = rand() ^ (rand() << 15) ^ ((UINT64)rand() << 30) ^ ((UINT64)rand() << 45); @@ -179,9 +401,8 @@ static bool validate_inlines(void) UINT64 resultu64, expectedu64; INT32 remainder, expremainder; UINT32 uremainder, expuremainder, bigu32 = 0xffffffff; - bool error = false; - /* use only non-zero, positive numbers */ + // use only non-zero, positive numbers if (testu64a == 0) testu64a++; if (testi64a == 0) testi64a++; else if (testi64a < 0) testi64a = -testi64a; @@ -199,32 +420,32 @@ static bool validate_inlines(void) resulti64 = mul_32x32(testi32a, testi32b); expectedi64 = (INT64)testi32a * (INT64)testi32b; if (resulti64 != expectedi64) - { mame_printf_error("Error testing mul_32x32 (%08X x %08X) = %08X%08X (expected %08X%08X)\n", testi32a, testi32b, (UINT32)(resulti64 >> 32), (UINT32)resulti64, (UINT32)(expectedi64 >> 32), (UINT32)expectedi64); error = true; } + mame_printf_error("Error testing mul_32x32 (%08X x %08X) = %08X%08X (expected %08X%08X)\n", testi32a, testi32b, (UINT32)(resulti64 >> 32), (UINT32)resulti64, (UINT32)(expectedi64 >> 32), (UINT32)expectedi64); resultu64 = mulu_32x32(testu32a, testu32b); expectedu64 = (UINT64)testu32a * (UINT64)testu32b; if (resultu64 != expectedu64) - { mame_printf_error("Error testing mulu_32x32 (%08X x %08X) = %08X%08X (expected %08X%08X)\n", testu32a, testu32b, (UINT32)(resultu64 >> 32), (UINT32)resultu64, (UINT32)(expectedu64 >> 32), (UINT32)expectedu64); error = true; } + mame_printf_error("Error testing mulu_32x32 (%08X x %08X) = %08X%08X (expected %08X%08X)\n", testu32a, testu32b, (UINT32)(resultu64 >> 32), (UINT32)resultu64, (UINT32)(expectedu64 >> 32), (UINT32)expectedu64); resulti32 = mul_32x32_hi(testi32a, testi32b); expectedi32 = ((INT64)testi32a * (INT64)testi32b) >> 32; if (resulti32 != expectedi32) - { mame_printf_error("Error testing mul_32x32_hi (%08X x %08X) = %08X (expected %08X)\n", testi32a, testi32b, resulti32, expectedi32); error = true; } + mame_printf_error("Error testing mul_32x32_hi (%08X x %08X) = %08X (expected %08X)\n", testi32a, testi32b, resulti32, expectedi32); resultu32 = mulu_32x32_hi(testu32a, testu32b); expectedu32 = ((INT64)testu32a * (INT64)testu32b) >> 32; if (resultu32 != expectedu32) - { mame_printf_error("Error testing mulu_32x32_hi (%08X x %08X) = %08X (expected %08X)\n", testu32a, testu32b, resultu32, expectedu32); error = true; } + mame_printf_error("Error testing mulu_32x32_hi (%08X x %08X) = %08X (expected %08X)\n", testu32a, testu32b, resultu32, expectedu32); resulti32 = mul_32x32_shift(testi32a, testi32b, 7); expectedi32 = ((INT64)testi32a * (INT64)testi32b) >> 7; if (resulti32 != expectedi32) - { mame_printf_error("Error testing mul_32x32_shift (%08X x %08X) >> 7 = %08X (expected %08X)\n", testi32a, testi32b, resulti32, expectedi32); error = true; } + mame_printf_error("Error testing mul_32x32_shift (%08X x %08X) >> 7 = %08X (expected %08X)\n", testi32a, testi32b, resulti32, expectedi32); resultu32 = mulu_32x32_shift(testu32a, testu32b, 7); expectedu32 = ((INT64)testu32a * (INT64)testu32b) >> 7; if (resultu32 != expectedu32) - { mame_printf_error("Error testing mulu_32x32_shift (%08X x %08X) >> 7 = %08X (expected %08X)\n", testu32a, testu32b, resultu32, expectedu32); error = true; } + mame_printf_error("Error testing mulu_32x32_shift (%08X x %08X) >> 7 = %08X (expected %08X)\n", testu32a, testu32b, resultu32, expectedu32); while ((INT64)testi32a * (INT64)0x7fffffff < testi64a) testi64a /= 2; @@ -234,34 +455,34 @@ static bool validate_inlines(void) resulti32 = div_64x32(testi64a, testi32a); expectedi32 = testi64a / (INT64)testi32a; if (resulti32 != expectedi32) - { mame_printf_error("Error testing div_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testi64a >> 32), (UINT32)testi64a, testi32a, resulti32, expectedi32); error = true; } + mame_printf_error("Error testing div_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testi64a >> 32), (UINT32)testi64a, testi32a, resulti32, expectedi32); resultu32 = divu_64x32(testu64a, testu32a); expectedu32 = testu64a / (UINT64)testu32a; if (resultu32 != expectedu32) - { mame_printf_error("Error testing divu_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testu64a >> 32), (UINT32)testu64a, testu32a, resultu32, expectedu32); error = true; } + mame_printf_error("Error testing divu_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testu64a >> 32), (UINT32)testu64a, testu32a, resultu32, expectedu32); resulti32 = div_64x32_rem(testi64a, testi32a, &remainder); expectedi32 = testi64a / (INT64)testi32a; expremainder = testi64a % (INT64)testi32a; if (resulti32 != expectedi32 || remainder != expremainder) - { mame_printf_error("Error testing div_64x32_rem (%08X%08X / %08X) = %08X,%08X (expected %08X,%08X)\n", (UINT32)(testi64a >> 32), (UINT32)testi64a, testi32a, resulti32, remainder, expectedi32, expremainder); error = true; } + mame_printf_error("Error testing div_64x32_rem (%08X%08X / %08X) = %08X,%08X (expected %08X,%08X)\n", (UINT32)(testi64a >> 32), (UINT32)testi64a, testi32a, resulti32, remainder, expectedi32, expremainder); resultu32 = divu_64x32_rem(testu64a, testu32a, &uremainder); expectedu32 = testu64a / (UINT64)testu32a; expuremainder = testu64a % (UINT64)testu32a; if (resultu32 != expectedu32 || uremainder != expuremainder) - { mame_printf_error("Error testing divu_64x32_rem (%08X%08X / %08X) = %08X,%08X (expected %08X,%08X)\n", (UINT32)(testu64a >> 32), (UINT32)testu64a, testu32a, resultu32, uremainder, expectedu32, expuremainder); error = true; } + mame_printf_error("Error testing divu_64x32_rem (%08X%08X / %08X) = %08X,%08X (expected %08X,%08X)\n", (UINT32)(testu64a >> 32), (UINT32)testu64a, testu32a, resultu32, uremainder, expectedu32, expuremainder); resulti32 = mod_64x32(testi64a, testi32a); expectedi32 = testi64a % (INT64)testi32a; if (resulti32 != expectedi32) - { mame_printf_error("Error testing mod_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testi64a >> 32), (UINT32)testi64a, testi32a, resulti32, expectedi32); error = true; } + mame_printf_error("Error testing mod_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testi64a >> 32), (UINT32)testi64a, testi32a, resulti32, expectedi32); resultu32 = modu_64x32(testu64a, testu32a); expectedu32 = testu64a % (UINT64)testu32a; if (resultu32 != expectedu32) - { mame_printf_error("Error testing modu_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testu64a >> 32), (UINT32)testu64a, testu32a, resultu32, expectedu32); error = true; } + mame_printf_error("Error testing modu_64x32 (%08X%08X / %08X) = %08X (expected %08X)\n", (UINT32)(testu64a >> 32), (UINT32)testu64a, testu32a, resultu32, expectedu32); while ((INT64)testi32a * (INT64)0x7fffffff < ((INT32)testi64a << 3)) testi64a /= 2; @@ -271,544 +492,377 @@ static bool validate_inlines(void) resulti32 = div_32x32_shift((INT32)testi64a, testi32a, 3); expectedi32 = ((INT64)(INT32)testi64a << 3) / (INT64)testi32a; if (resulti32 != expectedi32) - { mame_printf_error("Error testing div_32x32_shift (%08X << 3) / %08X = %08X (expected %08X)\n", (INT32)testi64a, testi32a, resulti32, expectedi32); error = true; } + mame_printf_error("Error testing div_32x32_shift (%08X << 3) / %08X = %08X (expected %08X)\n", (INT32)testi64a, testi32a, resulti32, expectedi32); resultu32 = divu_32x32_shift((UINT32)testu64a, testu32a, 3); expectedu32 = ((UINT64)(UINT32)testu64a << 3) / (UINT64)testu32a; if (resultu32 != expectedu32) - { mame_printf_error("Error testing divu_32x32_shift (%08X << 3) / %08X = %08X (expected %08X)\n", (UINT32)testu64a, testu32a, resultu32, expectedu32); error = true; } + mame_printf_error("Error testing divu_32x32_shift (%08X << 3) / %08X = %08X (expected %08X)\n", (UINT32)testu64a, testu32a, resultu32, expectedu32); if (fabs(recip_approx(100.0) - 0.01) > 0.0001) - { mame_printf_error("Error testing recip_approx\n"); error = true; } + mame_printf_error("Error testing recip_approx\n"); testi32a = (testi32a & 0x0000ffff) | 0x400000; if (count_leading_zeros(testi32a) != 9) - { mame_printf_error("Error testing count_leading_zeros\n"); error = true; } + mame_printf_error("Error testing count_leading_zeros\n"); testi32a = (testi32a | 0xffff0000) & ~0x400000; if (count_leading_ones(testi32a) != 9) - { mame_printf_error("Error testing count_leading_ones\n"); error = true; } + mame_printf_error("Error testing count_leading_ones\n"); testi32b = testi32a; if (compare_exchange32(&testi32a, testi32b, 1000) != testi32b || testi32a != 1000) - { mame_printf_error("Error testing compare_exchange32\n"); error = true; } + mame_printf_error("Error testing compare_exchange32\n"); #ifdef PTR64 testi64b = testi64a; if (compare_exchange64(&testi64a, testi64b, 1000) != testi64b || testi64a != 1000) - { mame_printf_error("Error testing compare_exchange64\n"); error = true; } + mame_printf_error("Error testing compare_exchange64\n"); #endif if (atomic_exchange32(&testi32a, testi32b) != 1000) - { mame_printf_error("Error testing atomic_exchange32\n"); error = true; } + mame_printf_error("Error testing atomic_exchange32\n"); if (atomic_add32(&testi32a, 45) != testi32b + 45) - { mame_printf_error("Error testing atomic_add32\n"); error = true; } + mame_printf_error("Error testing atomic_add32\n"); if (atomic_increment32(&testi32a) != testi32b + 46) - { mame_printf_error("Error testing atomic_increment32\n"); error = true; } + mame_printf_error("Error testing atomic_increment32\n"); if (atomic_decrement32(&testi32a) != testi32b + 45) - { mame_printf_error("Error testing atomic_decrement32\n"); error = true; } - - return error; + mame_printf_error("Error testing atomic_decrement32\n"); } -/*------------------------------------------------- - validate_driver - validate basic driver - information --------------------------------------------------*/ +//------------------------------------------------- +// validate_driver - validate basic driver +// information +//------------------------------------------------- -static bool validate_driver(driver_enumerator &drivlist, game_driver_map &names, game_driver_map &descriptions) +void validity_checker::validate_driver() { - const game_driver &driver = drivlist.driver(); - const machine_config &config = drivlist.config(); - const char *compatible_with; - bool error = FALSE, is_clone; - const char *s; - - enum { NAME_LEN_PARENT = 8, NAME_LEN_CLONE = 16 }; - - /* check for duplicate names */ - if (names.add(driver.name, &driver, FALSE) == TMERR_DUPLICATE) + // check for duplicate names + astring tempstr; + if (m_names_map.add(m_current_driver->name, m_current_driver, false) == TMERR_DUPLICATE) { - const game_driver *match = names.find(driver.name); - mame_printf_error("%s: %s is a duplicate name (%s, %s)\n", driver.source_file, driver.name, match->source_file, match->name); - error = true; + const game_driver *match = m_names_map.find(m_current_driver->name); + mame_printf_error("Driver name is a duplicate of %s(%s)\n", core_filename_extract_base(tempstr, match->source_file).cstr(), match->name); } - /* check for duplicate descriptions */ - if (descriptions.add(driver.description, &driver, FALSE) == TMERR_DUPLICATE) + // check for duplicate descriptions + if (m_descriptions_map.add(m_current_driver->description, m_current_driver, false) == TMERR_DUPLICATE) { - const game_driver *match = descriptions.find(driver.description); - mame_printf_error("%s: %s is a duplicate description (%s, %s)\n", driver.source_file, driver.description, match->source_file, match->description); - error = true; + const game_driver *match = m_descriptions_map.find(m_current_driver->description); + mame_printf_error("Driver description is a duplicate of %s(%s)\n", core_filename_extract_base(tempstr, match->source_file).cstr(), match->name); } - /* determine the clone */ - is_clone = (strcmp(driver.parent, "0") != 0); - int clone_of = drivlist.clone(driver); - if (clone_of != -1 && (drivlist.driver(clone_of).flags & GAME_IS_BIOS_ROOT)) + // determine if we are a clone + bool is_clone = (strcmp(m_current_driver->parent, "0") != 0); + int clone_of = m_drivlist.clone(*m_current_driver); + if (clone_of != -1 && (m_drivlist.driver(clone_of).flags & GAME_IS_BIOS_ROOT)) is_clone = false; - /* if we have at least 100 drivers, validate the clone */ - /* (100 is arbitrary, but tries to avoid tiny.mak dependencies) */ + // if we have at least 100 drivers, validate the clone + // (100 is arbitrary, but tries to avoid tiny.mak dependencies) if (driver_list::total() > 100 && clone_of == -1 && is_clone) - { - mame_printf_error("%s: %s is a non-existant clone\n", driver.source_file, driver.parent); - error = true; - } + mame_printf_error("Driver is a clone of nonexistant driver %s\n", m_current_driver->parent); - /* look for recursive cloning */ - if (clone_of != -1 && &drivlist.driver(clone_of) == &driver) - { - mame_printf_error("%s: %s is set as a clone of itself\n", driver.source_file, driver.name); - error = true; - } + // look for recursive cloning + if (clone_of != -1 && &m_drivlist.driver(clone_of) == m_current_driver) + mame_printf_error("Driver is a clone of itself\n"); - /* look for clones that are too deep */ - if (clone_of != -1 && (clone_of = drivlist.non_bios_clone(clone_of)) != -1) - { - mame_printf_error("%s: %s is a clone of a clone\n", driver.source_file, driver.name); - error = true; - } + // look for clones that are too deep + if (clone_of != -1 && (clone_of = m_drivlist.non_bios_clone(clone_of)) != -1) + mame_printf_error("Driver is a clone of a clone\n"); - /* make sure the driver name is 8 chars or less */ - if ((is_clone && strlen(driver.name) > NAME_LEN_CLONE) || ((!is_clone) && strlen(driver.name) > NAME_LEN_PARENT)) - { - mame_printf_error("%s: %s %s driver name must be %d characters or less\n", driver.source_file, driver.name, - is_clone ? "clone" : "parent", is_clone ? NAME_LEN_CLONE : NAME_LEN_PARENT); - error = true; - } + // make sure the driver name is not too long + if (!is_clone && strlen(m_current_driver->name) > 8) + mame_printf_error("Parent driver name must be 8 characters or less\n"); + if (is_clone && strlen(m_current_driver->name) > 16) + mame_printf_error("Clone driver name must be 16 characters or less\n"); - /* make sure the year is only digits, '?' or '+' */ - for (s = driver.year; *s; s++) + // make sure the year is only digits, '?' or '+' + for (const char *s = m_current_driver->year; *s != 0; s++) if (!isdigit((UINT8)*s) && *s != '?' && *s != '+') { - mame_printf_error("%s: %s has an invalid year '%s'\n", driver.source_file, driver.name, driver.year); - error = true; + mame_printf_error("Driver has an invalid year '%s'\n", m_current_driver->year); break; } - /* normalize driver->compatible_with */ - compatible_with = driver.compatible_with; - if ((compatible_with != NULL) && !strcmp(compatible_with, "0")) + // normalize driver->compatible_with + const char *compatible_with = m_current_driver->compatible_with; + if (compatible_with != NULL && strcmp(compatible_with, "0") == 0) compatible_with = NULL; - /* check for this driver being compatible with a non-existant driver */ - if ((compatible_with != NULL) && (drivlist.find(driver.compatible_with) == -1)) - { - mame_printf_error("%s: is compatible with %s, which is not in drivers[]\n", driver.name, driver.compatible_with); - error = true; - } + // check for this driver being compatible with a non-existant driver + if (compatible_with != NULL && m_drivlist.find(m_current_driver->compatible_with) == -1) + mame_printf_error("Driver is listed as compatible with nonexistant driver %s\n", m_current_driver->compatible_with); - /* check for clone_of and compatible_with being specified at the same time */ - if ((drivlist.clone(driver) != -1) && (compatible_with != NULL)) - { - mame_printf_error("%s: both compatible_with and clone_of are specified\n", driver.name); - error = true; - } + // check for clone_of and compatible_with being specified at the same time + if (m_drivlist.clone(*m_current_driver) != -1 && compatible_with != NULL) + mame_printf_error("Driver cannot be both a clone and listed as compatible with another system\n"); - /* find any recursive dependencies on the current driver */ - for (int other_drv = drivlist.compatible_with(driver); other_drv != -1; other_drv = drivlist.compatible_with(other_drv)) - { - if (&driver == &drivlist.driver(other_drv)) + // find any recursive dependencies on the current driver + for (int other_drv = m_drivlist.compatible_with(*m_current_driver); other_drv != -1; other_drv = m_drivlist.compatible_with(other_drv)) + if (m_current_driver == &m_drivlist.driver(other_drv)) { - mame_printf_error("%s: recursive compatibility\n", driver.name); - error = true; + mame_printf_error("Driver is recursively compatible with itself\n"); break; } - } - - /* make sure sound-less drivers are flagged */ - const device_sound_interface *sound; - if ((driver.flags & GAME_IS_BIOS_ROOT) == 0 && !config.devicelist().first(sound) && (driver.flags & GAME_NO_SOUND) == 0 && (driver.flags & GAME_NO_SOUND_HW) == 0) - { - mame_printf_error("%s: %s missing GAME_NO_SOUND flag\n", driver.source_file, driver.name); - error = true; - } - return error; + // make sure sound-less drivers are flagged + sound_interface_iterator iter(m_current_config->root_device()); + if ((m_current_driver->flags & GAME_IS_BIOS_ROOT) == 0 && iter.first() == NULL && (m_current_driver->flags & GAME_NO_SOUND) == 0 && (m_current_driver->flags & GAME_NO_SOUND_HW) == 0) + mame_printf_error("Driver is missing GAME_NO_SOUND flag\n"); } -/*------------------------------------------------- - validate_roms - validate ROM definitions --------------------------------------------------*/ +//------------------------------------------------- +// validate_roms - validate ROM definitions +//------------------------------------------------- -static bool validate_roms(driver_enumerator &drivlist, region_array *rgninfo, game_driver_map &roms) +void validity_checker::validate_roms() { - const game_driver &driver = drivlist.driver(); - const machine_config &config = drivlist.config(); - int bios_flags = 0, last_bios = 0; - const char *last_rgnname = "???"; - const char *last_name = "???"; - region_entry *currgn = NULL; - int items_since_region = 1; - bool error = false; - - const rom_source *first_source = rom_first_source(config); - - /* iterate, starting with the driver's ROMs and continuing with device ROMs */ - for (const rom_source *source = rom_first_source(config); source != NULL; source = rom_next_source(*source)) + // iterate, starting with the driver's ROMs and continuing with device ROMs + for (const rom_source *source = rom_first_source(*m_current_config); source != NULL; source = rom_next_source(*source)) { - /* scan the ROM entries */ + // for non-root devices, track the current device + m_current_device = (source == &m_current_config->root_device()) ? NULL : source; + + // scan the ROM entries for this device + const char *last_region_name = "???"; + const char *last_name = "???"; + UINT32 current_length = 0; + int items_since_region = 1; + int last_bios = 0; + int total_files = 0; for (const rom_entry *romp = rom_first_region(*source); !ROMENTRY_ISEND(romp); romp++) { - /* if this is a region, make sure it's valid, and record the length */ + // if this is a region, make sure it's valid, and record the length if (ROMENTRY_ISREGION(romp)) { - const char *regiontag = ROMREGION_GETTAG(romp); - - /* if we haven't seen any items since the last region, print a warning */ + // if we haven't seen any items since the last region, print a warning if (items_since_region == 0) - mame_printf_warning("%s: %s has empty ROM region '%s' (warning)\n", driver.source_file, driver.name, last_rgnname); + mame_printf_warning("Empty ROM region '%s' (warning)\n", last_region_name); + + // reset our region tracking states + const char *basetag = ROMREGION_GETTAG(romp); items_since_region = (ROMREGION_ISERASE(romp) || ROMREGION_ISDISKDATA(romp)) ? 1 : 0; - currgn = NULL; - last_rgnname = regiontag; + last_region_name = basetag; - /* check for a valid tag */ - if (regiontag == NULL) + // check for a valid tag + if (basetag == NULL) { - mame_printf_error("%s: %s has NULL ROM_REGION tag\n", driver.source_file, driver.name); - error = true; + mame_printf_error("ROM_REGION tag with NULL name\n"); + continue; } - /* find any empty entry, checking for duplicates */ - else - { - astring fulltag; - - /* iterate over all regions found so far */ - rom_region_name(fulltag, &driver, source, romp); - for (int rgnnum = 0; rgnnum < ARRAY_LENGTH(rgninfo->entries); rgnnum++) - { - /* stop when we hit an empty */ - if (!rgninfo->entries[rgnnum].tag) - { - currgn = &rgninfo->entries[rgnnum]; - currgn->tag = fulltag; - currgn->length = ROMREGION_GETLENGTH(romp); - break; - } - - /* fail if we hit a duplicate */ - if (fulltag == rgninfo->entries[rgnnum].tag) - { - mame_printf_error("%s: %s has duplicate ROM_REGION tag '%s'\n", driver.source_file, driver.name, fulltag.cstr()); - error = true; - break; - } - } - } - - /* validate the region tag */ - if (!validate_tag(driver, "region", regiontag)) - error = true; + // validate the base tag + validate_tag(basetag); + + // generate the full tag + astring fulltag; + rom_region_name(fulltag, m_current_driver, source, romp); + + // attempt to add it to the map, reporting duplicates as errors + current_length = ROMREGION_GETLENGTH(romp); + if (m_region_map.add(fulltag, current_length, false) == TMERR_DUPLICATE) + mame_printf_error("Multiple ROM_REGIONs with the same tag '%s' defined\n", fulltag.cstr()); } - /* If this is a system bios, make sure it is using the next available bios number */ + // If this is a system bios, make sure it is using the next available bios number else if (ROMENTRY_ISSYSTEM_BIOS(romp)) { - bios_flags = ROM_GETBIOSFLAGS(romp); - if (last_bios+1 != bios_flags) - { - const char *name = ROM_GETNAME(romp); - mame_printf_error("%s: %s has non-sequential bios %s\n", driver.source_file, driver.name, name); - error = true; - } + int bios_flags = ROM_GETBIOSFLAGS(romp); + if (bios_flags != last_bios + 1) + mame_printf_error("Non-sequential bios %s (specified as %d, expected to be %d)\n", ROM_GETNAME(romp), bios_flags, last_bios + 1); last_bios = bios_flags; } - /* if this is a file, make sure it is properly formatted */ + // if this is a file, make sure it is properly formatted else if (ROMENTRY_ISFILE(romp)) { - const char *s; - - items_since_region++; - - /* track the last filename we found */ + // track the last filename we found last_name = ROM_GETNAME(romp); + total_files++; - /* make sure it's all lowercase */ - for (s = last_name; *s; s++) + // make sure it's all lowercase + for (const char *s = last_name; *s != 0; s++) if (tolower((UINT8)*s) != *s) { - mame_printf_error("%s: %s has upper case ROM name %s\n", driver.source_file, driver.name, last_name); - error = true; + mame_printf_error("ROM name '%s' contains upper case characters\n", last_name); break; } - /* make sure the hash is valid */ + // make sure the hash is valid hash_collection hashes; if (!hashes.from_internal_string(ROM_GETHASHDATA(romp))) - { - mame_printf_error("%s: rom '%s' has an invalid hash string '%s'\n", driver.name, last_name, ROM_GETHASHDATA(romp)); - error = true; - } + mame_printf_error("ROM '%s' has an invalid hash string '%s'\n", last_name, ROM_GETHASHDATA(romp)); } - // count copies/fills as valid items - else if (ROMENTRY_ISCOPY(romp) || ROMENTRY_ISFILL(romp)) - items_since_region++; - - /* for any non-region ending entries, make sure they don't extend past the end */ - if (!ROMENTRY_ISREGIONEND(romp) && currgn != NULL) + // for any non-region ending entries, make sure they don't extend past the end + if (!ROMENTRY_ISREGIONEND(romp) && current_length > 0) { items_since_region++; - - if (ROM_GETOFFSET(romp) + ROM_GETLENGTH(romp) > currgn->length) - { - mame_printf_error("%s: %s has ROM %s extending past the defined memory region\n", driver.source_file, driver.name, last_name); - error = true; - } + if (ROM_GETOFFSET(romp) + ROM_GETLENGTH(romp) > current_length) + mame_printf_error("ROM '%s' extends past the defined memory region\n", last_name); } } - /* final check for empty regions */ + // final check for empty regions if (items_since_region == 0) - mame_printf_warning("%s: %s has empty ROM region (warning)\n", driver.source_file, driver.name); + mame_printf_warning("Empty ROM region '%s' (warning)\n", last_region_name); - if (source!=first_source) { - // check for device roms - device_type type = source->type(); - int cnt = 0; - for (const rom_entry *romp = rom_first_region(*source); !ROMENTRY_ISEND(romp); romp++) - { - if (ROMENTRY_ISFILE(romp)) { - cnt++; - } - } - if (cnt > 0) { - bool found = false; - for(int i=0;i<m_device_count;i++) { - if (type==*s_devices_sorted[i]) - { - found = true; - break; - } + // make sure each device is listed in the device list if it loads ROMs + if (m_current_device != NULL && total_files > 0) + { + // scan the list of devices for this device type + bool found = false; + for (int i = 0; i < m_device_count; i++) + if (m_current_device->type() == *s_devices_sorted[i]) + { + found = true; + break; } - if (!found) - mame_printf_error("Device %s is not listed in device list (mame_dev.lst / mess_dev.lst)\n", source->shortname()); - } + + // if not found, report an error + if (!found) + mame_printf_error("Device %s is not listed in device list (mame_dev.lst / mess_dev.lst)\n", m_current_device->shortname()); } - } - return error; + // reset the current device + m_current_device = NULL; + } } -/*------------------------------------------------- - validate_display - validate display - configurations --------------------------------------------------*/ +//------------------------------------------------- +// validate_display - validate display +// configurations +//------------------------------------------------- -static bool validate_display(driver_enumerator &drivlist) +void validity_checker::validate_display() { - const game_driver &driver = drivlist.driver(); - const machine_config &config = drivlist.config(); + // iterate over screen devices looking for paletted screens + screen_device_iterator iter(m_current_config->root_device()); bool palette_modes = false; - bool error = false; - - for (const screen_device *scrconfig = config.first_screen(); scrconfig != NULL; scrconfig = scrconfig->next_screen()) + for (const screen_device *scrconfig = iter.first(); scrconfig != NULL; scrconfig = iter.next()) if (scrconfig->format() == BITMAP_FORMAT_IND16) palette_modes = true; - /* check for empty palette */ - if (palette_modes && config.m_total_colors == 0) - { - mame_printf_error("%s: %s has zero palette entries\n", driver.source_file, driver.name); - error = true; - } - - return error; + // check for empty palette + if (palette_modes && m_current_config->m_total_colors == 0) + mame_printf_error("Driver has zero palette entries but uses a palette-based bitmap format\n"); } -/*------------------------------------------------- - validate_gfx - validate graphics decoding - configuration --------------------------------------------------*/ +//------------------------------------------------- +// validate_gfx - validate graphics decoding +// configuration +//------------------------------------------------- -static bool validate_gfx(driver_enumerator &drivlist, region_array *rgninfo) +void validity_checker::validate_gfx() { - const game_driver &driver = drivlist.driver(); - const machine_config &config = drivlist.config(); - bool error = false; - int gfxnum; - - /* bail if no gfx */ - if (!config.m_gfxdecodeinfo) - return false; + // bail if no gfx + if (!m_current_config->m_gfxdecodeinfo) + return; - /* iterate over graphics decoding entries */ - for (gfxnum = 0; gfxnum < MAX_GFX_ELEMENTS && config.m_gfxdecodeinfo[gfxnum].gfxlayout != NULL; gfxnum++) + // iterate over graphics decoding entries + for (int gfxnum = 0; gfxnum < MAX_GFX_ELEMENTS && m_current_config->m_gfxdecodeinfo[gfxnum].gfxlayout != NULL; gfxnum++) { - const gfx_decode_entry *gfx = &config.m_gfxdecodeinfo[gfxnum]; - const char *region = gfx->memory_region; - int xscale = (config.m_gfxdecodeinfo[gfxnum].xscale == 0) ? 1 : config.m_gfxdecodeinfo[gfxnum].xscale; - int yscale = (config.m_gfxdecodeinfo[gfxnum].yscale == 0) ? 1 : config.m_gfxdecodeinfo[gfxnum].yscale; - const gfx_layout *gl = gfx->gfxlayout; - int israw = (gl->planeoffset[0] == GFX_RAW); - int planes = gl->planes; - UINT16 width = gl->width; - UINT16 height = gl->height; - UINT32 total = gl->total; - - /* make sure the region exists */ + const gfx_decode_entry &gfx = m_current_config->m_gfxdecodeinfo[gfxnum]; + const gfx_layout &layout = *gfx.gfxlayout; + + // make sure the region exists + const char *region = gfx.memory_region; if (region != NULL) { - int rgnnum; - - /* loop over gfx regions */ - for (rgnnum = 0; rgnnum < ARRAY_LENGTH(rgninfo->entries); rgnnum++) - { - /* stop if we hit an empty */ - if (!rgninfo->entries[rgnnum].tag) - { - mame_printf_error("%s: %s has gfx[%d] referencing non-existent region '%s'\n", driver.source_file, driver.name, gfxnum, region); - error = true; - break; - } - - /* if we hit a match, check against the length */ - if (rgninfo->entries[rgnnum].tag == region) - { - /* if we have a valid region, and we're not using auto-sizing, check the decode against the region length */ - if (!IS_FRAC(total)) - { - int len, avail, plane, start; - UINT32 charincrement = gl->charincrement; - const UINT32 *poffset = gl->planeoffset; + // resolve the region + astring gfxregion; + m_current_config->root_device().subtag(gfxregion, region); - /* determine which plane is the largest */ - start = 0; - for (plane = 0; plane < planes; plane++) - if (poffset[plane] > start) - start = poffset[plane]; - start &= ~(charincrement - 1); + // loop over gfx regions + UINT32 region_length = m_region_map.find(gfxregion); + if (region_length == 0) + mame_printf_error("gfx[%d] references non-existent region '%s'\n", gfxnum, region); - /* determine the total length based on this info */ - len = total * charincrement; - - /* do we have enough space in the region to cover the whole decode? */ - avail = rgninfo->entries[rgnnum].length - (gfx->start & ~(charincrement/8-1)); - - /* if not, this is an error */ - if ((start + len) / 8 > avail) - { - mame_printf_error("%s: %s has gfx[%d] extending past allocated memory of region '%s'\n", driver.source_file, driver.name, gfxnum, region); - error = true; - } - } - break; - } + // if we have a valid region, and we're not using auto-sizing, check the decode against the region length + else if (!IS_FRAC(layout.total)) + { + // determine which plane is at the largest offset + int start = 0; + for (int plane = 0; plane < layout.planes; plane++) + if (layout.planeoffset[plane] > start) + start = layout.planeoffset[plane]; + start &= ~(layout.charincrement - 1); + + // determine the total length based on this info + int len = layout.total * layout.charincrement; + + // do we have enough space in the region to cover the whole decode? + int avail = region_length - (gfx.start & ~(layout.charincrement / 8 - 1)); + + // if not, this is an error + if ((start + len) / 8 > avail) + mame_printf_error("gfx[%d] extends past allocated memory of region '%s'\n", gfxnum, region); } } - if (israw) + int xscale = (m_current_config->m_gfxdecodeinfo[gfxnum].xscale == 0) ? 1 : m_current_config->m_gfxdecodeinfo[gfxnum].xscale; + int yscale = (m_current_config->m_gfxdecodeinfo[gfxnum].yscale == 0) ? 1 : m_current_config->m_gfxdecodeinfo[gfxnum].yscale; + + // verify raw decode, which can only be full-region and have no scaling + if (layout.planeoffset[0] == GFX_RAW) { - if (total != RGN_FRAC(1,1)) - { - mame_printf_error("%s: %s has gfx[%d] with unsupported layout total\n", driver.source_file, driver.name, gfxnum); - error = true; - } - + if (layout.total != RGN_FRAC(1,1)) + mame_printf_error("gfx[%d] with unsupported layout total\n", gfxnum); if (xscale != 1 || yscale != 1) - { - mame_printf_error("%s: %s has gfx[%d] with unsupported xscale/yscale\n", driver.source_file, driver.name, gfxnum); - error = true; - } + mame_printf_error("gfx[%d] with unsupported xscale/yscale\n", gfxnum); } + + // verify traditional decode doesn't have too many planes or is not too large else { - if (planes > MAX_GFX_PLANES) - { - mame_printf_error("%s: %s has gfx[%d] with invalid planes\n", driver.source_file, driver.name, gfxnum); - error = true; - } - - if (xscale * width > MAX_ABS_GFX_SIZE || yscale * height > MAX_ABS_GFX_SIZE) - { - mame_printf_error("%s: %s has gfx[%d] with invalid xscale/yscale\n", driver.source_file, driver.name, gfxnum); - error = true; - } + if (layout.planes > MAX_GFX_PLANES) + mame_printf_error("gfx[%d] with invalid planes\n", gfxnum); + if (xscale * layout.width > MAX_ABS_GFX_SIZE || yscale * layout.height > MAX_ABS_GFX_SIZE) + mame_printf_error("gfx[%d] with invalid xscale/yscale\n", gfxnum); } } - - return error; -} - - -/*------------------------------------------------- - get_defstr_index - return the index of the - string assuming it is one of the default - strings --------------------------------------------------*/ - -static int get_defstr_index(int_map &defstr_map, const char *name, const game_driver &driver, bool *error) -{ - /* check for strings that should be DEF_STR */ - int strindex = defstr_map.find(name); - if (strindex != 0 && name != input_port_string_from_index(strindex) && error != NULL) - { - mame_printf_error("%s: %s must use DEF_STR( %s )\n", driver.source_file, driver.name, name); - *error = true; - } - - return strindex; } -/*------------------------------------------------- - validate_analog_input_field - validate an - analog input field --------------------------------------------------*/ +//------------------------------------------------- +// validate_analog_input_field - validate an +// analog input field +//------------------------------------------------- -static void validate_analog_input_field(input_field_config *field, const game_driver &driver, bool *error) +void validity_checker::validate_analog_input_field(input_field_config &field) { - INT32 analog_max = field->max; - INT32 analog_min = field->min; - int shift; + // analog ports must have a valid sensitivity + if (field.sensitivity == 0) + mame_printf_error("Analog port with zero sensitivity\n"); - if (field->type == IPT_POSITIONAL || field->type == IPT_POSITIONAL_V) - { - for (shift = 0; (shift <= 31) && (~field->mask & (1 << shift)); shift++) ; - /* convert the positional max value to be in the bitmask for testing */ - analog_max = (analog_max - 1) << shift; + // check that the default falls in the bitmask range + if (field.defvalue & ~field.mask) + mame_printf_error("Analog port with a default value (%X) out of the bitmask range (%X)\n", field.defvalue, field.mask); - /* positional port size must fit in bits used */ - if (((field->mask >> shift) + 1) < field->max) - { - mame_printf_error("%s: %s has an analog port with a positional port size bigger then the mask size\n", driver.source_file, driver.name); - *error = true; - } - } - else + // tests for positional devices + if (field.type == IPT_POSITIONAL || field.type == IPT_POSITIONAL_V) { - /* only positional controls use PORT_WRAPS */ - if (field->flags & ANALOG_FLAG_WRAPS) - { - mame_printf_error("%s: %s only positional analog ports use PORT_WRAPS\n", driver.source_file, driver.name); - *error = true; - } - } + int shift; + for (shift = 0; shift <= 31 && (~field.mask & (1 << shift)) != 0; shift++) ; - /* analog ports must have a valid sensitivity */ - if (field->sensitivity == 0) - { - mame_printf_error("%s: %s has an analog port with zero sensitivity\n", driver.source_file, driver.name); - *error = true; - } + // convert the positional max value to be in the bitmask for testing + INT32 analog_max = field.max; + analog_max = (analog_max - 1) << shift; - /* check that the default falls in the bitmask range */ - if (field->defvalue & ~field->mask) - { - mame_printf_error("%s: %s has an analog port with a default value out of the bitmask range\n", driver.source_file, driver.name); - *error = true; + // positional port size must fit in bits used + if ((field.mask >> shift) + 1 < field.max) + mame_printf_error("Analog port with a positional port size bigger then the mask size\n"); } - /* tests for absolute devices */ - if (field->type >= __ipt_analog_absolute_start && field->type <= __ipt_analog_absolute_end) + // tests for absolute devices + else if (field.type >= __ipt_analog_absolute_start && field.type <= __ipt_analog_absolute_end) { - INT32 default_value = field->defvalue; - - /* adjust for signed values */ + // adjust for signed values + INT32 default_value = field.defvalue; + INT32 analog_min = field.min; + INT32 analog_max = field.max; if (analog_min > analog_max) { analog_min = -analog_min; @@ -816,506 +870,388 @@ static void validate_analog_input_field(input_field_config *field, const game_dr default_value = -default_value; } - /* check that the default falls in the MINMAX range */ + // check that the default falls in the MINMAX range if (default_value < analog_min || default_value > analog_max) - { - mame_printf_error("%s: %s has an analog port with a default value out PORT_MINMAX range\n", driver.source_file, driver.name); - *error = true; - } + mame_printf_error("Analog port with a default value (%X) out of PORT_MINMAX range (%X-%X)\n", field.defvalue, field.min, field.max); - /* check that the MINMAX falls in the bitmask range */ - /* we use the unadjusted min for testing */ - if (field->min & ~field->mask || analog_max & ~field->mask) - { - mame_printf_error("%s: %s has an analog port with a PORT_MINMAX value out of the bitmask range\n", driver.source_file, driver.name); - *error = true; - } + // check that the MINMAX falls in the bitmask range + // we use the unadjusted min for testing + if (field.min & ~field.mask || analog_max & ~field.mask) + mame_printf_error("Analog port with a PORT_MINMAX (%X-%X) value out of the bitmask range (%X)\n", field.min, field.max, field.mask); - /* absolute analog ports do not use PORT_RESET */ - if (field->flags & ANALOG_FLAG_RESET) - { - mame_printf_error("%s: %s - absolute analog ports do not use PORT_RESET\n", driver.source_file, driver.name); - *error = true; - } + // absolute analog ports do not use PORT_RESET + if (field.flags & ANALOG_FLAG_RESET) + mame_printf_error("Absolute analog port using PORT_RESET\n"); + + // absolute analog ports do not use PORT_WRAPS + if (field.flags & ANALOG_FLAG_WRAPS) + mame_printf_error("Absolute analog port using PORT_WRAPS\n"); } - /* tests for relative devices */ + // tests for non IPT_POSITIONAL relative devices else { - /* tests for non IPT_POSITIONAL relative devices */ - if (field->type != IPT_POSITIONAL && field->type != IPT_POSITIONAL_V) - { - /* relative devices do not use PORT_MINMAX */ - if (field->min != 0 || field->max != field->mask) - { - mame_printf_error("%s: %s - relative ports do not use PORT_MINMAX\n", driver.source_file, driver.name); - *error = true; - } - - /* relative devices do not use a default value */ - /* the counter is at 0 on power up */ - if (field->defvalue != 0) - { - mame_printf_error("%s: %s - relative ports do not use a default value other then 0\n", driver.source_file, driver.name); - *error = true; - } - } + // relative devices do not use PORT_MINMAX + if (field.min != 0 || field.max != field.mask) + mame_printf_error("Relative port using PORT_MINMAX\n"); + + // relative devices do not use a default value + // the counter is at 0 on power up + if (field.defvalue != 0) + mame_printf_error("Relative port using non-0 default value\n"); + + // relative analog ports do not use PORT_WRAPS + if (field.flags & ANALOG_FLAG_WRAPS) + mame_printf_error("Absolute analog port using PORT_WRAPS\n"); } } -/*------------------------------------------------- - validate_dip_settings - validate a DIP switch - setting --------------------------------------------------*/ +//------------------------------------------------- +// validate_dip_settings - validate a DIP switch +// setting +//------------------------------------------------- -static void validate_dip_settings(input_field_config *field, const game_driver &driver, int_map &defstr_map, bool *error) +void validity_checker::validate_dip_settings(input_field_config &field) { - const char *demo_sounds = input_port_string_from_index(INPUT_STRING_Demo_Sounds); - const char *flipscreen = input_port_string_from_index(INPUT_STRING_Flip_Screen); + const char *demo_sounds = ioport_string_from_index(INPUT_STRING_Demo_Sounds); + const char *flipscreen = ioport_string_from_index(INPUT_STRING_Flip_Screen); UINT8 coin_list[__input_string_coinage_end + 1 - __input_string_coinage_start] = { 0 }; - const input_setting_config *setting; - int coin_error = FALSE; + bool coin_error = false; - /* iterate through the settings */ - for (setting = field->settinglist().first(); setting != NULL; setting = setting->next()) + // iterate through the settings + for (const input_setting_config *setting = field.settinglist().first(); setting != NULL; setting = setting->next()) { - int strindex = get_defstr_index(defstr_map, setting->name, driver, error); - - /* note any coinage strings */ + // note any coinage strings + int strindex = get_defstr_index(setting->name); if (strindex >= __input_string_coinage_start && strindex <= __input_string_coinage_end) coin_list[strindex - __input_string_coinage_start] = 1; - /* make sure demo sounds default to on */ - if (field->name == demo_sounds && strindex == INPUT_STRING_On && field->defvalue != setting->value) - { - mame_printf_error("%s: %s Demo Sounds must default to On\n", driver.source_file, driver.name); - *error = true; - } + // make sure demo sounds default to on + if (field.name == demo_sounds && strindex == INPUT_STRING_On && field.defvalue != setting->value) + mame_printf_error("Demo Sounds must default to On\n"); - /* check for bad demo sounds options */ - if (field->name == demo_sounds && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No)) - { - mame_printf_error("%s: %s has wrong Demo Sounds option %s (must be Off/On)\n", driver.source_file, driver.name, setting->name); - *error = true; - } + // check for bad demo sounds options + if (field.name == demo_sounds && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No)) + mame_printf_error("Demo Sounds option must be Off/On, not %s\n", setting->name); - /* check for bad flip screen options */ - if (field->name == flipscreen && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No)) - { - mame_printf_error("%s: %s has wrong Flip Screen option %s (must be Off/On)\n", driver.source_file, driver.name, setting->name); - *error = true; - } + // check for bad flip screen options + if (field.name == flipscreen && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No)) + mame_printf_error("Flip Screen option must be Off/On, not %s\n", setting->name); - /* if we have a neighbor, compare ourselves to him */ + // if we have a neighbor, compare ourselves to him if (setting->next() != NULL) { - int next_strindex = get_defstr_index(defstr_map, setting->next()->name, driver, error); - - /* check for inverted off/on dispswitch order */ + // check for inverted off/on dispswitch order + int next_strindex = get_defstr_index(setting->next()->name, true); if (strindex == INPUT_STRING_On && next_strindex == INPUT_STRING_Off) - { - mame_printf_error("%s: %s has inverted Off/On dipswitch order\n", driver.source_file, driver.name); - *error = true; - } + mame_printf_error("%s option must have Off/On options in the order: Off, On\n", field.name); - /* check for inverted yes/no dispswitch order */ + // check for inverted yes/no dispswitch order else if (strindex == INPUT_STRING_Yes && next_strindex == INPUT_STRING_No) - { - mame_printf_error("%s: %s has inverted No/Yes dipswitch order\n", driver.source_file, driver.name); - *error = true; - } + mame_printf_error("%s option must have Yes/No options in the order: No, Yes\n", field.name); - /* check for inverted upright/cocktail dispswitch order */ + // check for inverted upright/cocktail dispswitch order else if (strindex == INPUT_STRING_Cocktail && next_strindex == INPUT_STRING_Upright) - { - mame_printf_error("%s: %s has inverted Upright/Cocktail dipswitch order\n", driver.source_file, driver.name); - *error = true; - } + mame_printf_error("%s option must have Upright/Cocktail options in the order: Upright, Cocktail\n", field.name); - /* check for proper coin ordering */ + // check for proper coin ordering else if (strindex >= __input_string_coinage_start && strindex <= __input_string_coinage_end && next_strindex >= __input_string_coinage_start && next_strindex <= __input_string_coinage_end && strindex >= next_strindex && memcmp(&setting->condition, &setting->next()->condition, sizeof(setting->condition)) == 0) { - mame_printf_error("%s: %s has unsorted coinage %s > %s\n", driver.source_file, driver.name, setting->name, setting->next()->name); - coin_error = *error = true; + mame_printf_error("%s option has unsorted coinage %s > %s\n", field.name, setting->name, setting->next()->name); + coin_error = true; } } } - /* if we have a coin error, demonstrate the correct way */ + // if we have a coin error, demonstrate the correct way if (coin_error) { - int entry; - - mame_printf_error("%s: %s proper coin sort order should be:\n", driver.source_file, driver.name); - for (entry = 0; entry < ARRAY_LENGTH(coin_list); entry++) + output_via_delegate(m_saved_error_output, " Note proper coin sort order should be:\n"); + for (int entry = 0; entry < ARRAY_LENGTH(coin_list); entry++) if (coin_list[entry]) - mame_printf_error("%s\n", input_port_string_from_index(__input_string_coinage_start + entry)); + output_via_delegate(m_saved_error_output, " %s\n", ioport_string_from_index(__input_string_coinage_start + entry)); } } -/*------------------------------------------------- - validate_inputs - validate input configuration --------------------------------------------------*/ +//------------------------------------------------- +// validate_condition - validate a condition +// stored within an ioport field or setting +//------------------------------------------------- -static bool validate_inputs(driver_enumerator &drivlist, int_map &defstr_map, ioport_list &portlist) +void validity_checker::validate_condition(input_condition &condition, device_t &device, int_map &port_map) { - input_port_config *scanport; - input_port_config *port; - input_field_config *field; - const game_driver &driver = drivlist.driver(); - const machine_config &config = drivlist.config(); - int empty_string_found = FALSE; - bool error = false; - astring errorbuf; - - /* skip if no ports */ - if (driver.ipt == NULL) - return FALSE; - - /* allocate the input ports */ - for (device_t *cfg = config.devicelist().first(); cfg != NULL; cfg = cfg->next()) + // resolve the tag + astring porttag; + device.subtag(porttag, condition.tag); + + // then find a matching port + if (port_map.find(porttag) == 0) + mame_printf_error("Condition referencing non-existent ioport tag '%s'\n", condition.tag); +} + + +//------------------------------------------------- +// validate_inputs - validate input configuration +//------------------------------------------------- + +void validity_checker::validate_inputs() +{ + int_map port_map; + + // iterate over devices + device_iterator iter(m_current_config->root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) { - input_port_list_init(*cfg, portlist, errorbuf); + // see if this device has ports; if not continue + if (device->input_ports() == NULL) + continue; + + // for non-root devices, track the current device + m_current_device = (device == &m_current_config->root_device()) ? NULL : device; + + // allocate the input ports + ioport_list portlist; + astring errorbuf; + input_port_list_init(*device, portlist, errorbuf); + + // report any errors during construction if (errorbuf) - { - mame_printf_error("%s: %s has input port errors:\n%s\n", driver.source_file, driver.name, errorbuf.cstr()); - error = true; - } - } + mame_printf_error("I/O port error during construction:\n%s\n", errorbuf.cstr()); - /* check for duplicate tags */ - for (port = portlist.first(); port != NULL; port = port->next()) - for (scanport = port->next(); scanport != NULL; scanport = scanport->next()) - if (strcmp(port->tag(), scanport->tag()) == 0) - { - mame_printf_error("%s: %s has a duplicate input port tag '%s'\n", driver.source_file, driver.name, port->tag()); - error = true; - } + // do a first pass over ports to add their names and find duplicates + for (input_port_config *port = portlist.first(); port != NULL; port = port->next()) + if (port_map.add(port->tag(), 1, false) == TMERR_DUPLICATE) + mame_printf_error("Multiple I/O ports with the same tag '%s' defined\n", port->tag()); - /* iterate over the results */ - for (port = portlist.first(); port != NULL; port = port->next()) - for (field = port->fieldlist().first(); field != NULL; field = field->next()) + // iterate over ports + for (input_port_config *port = portlist.first(); port != NULL; port = port->next()) { - input_setting_config *setting; - //int strindex = 0; - - /* verify analog inputs */ - if (input_type_is_analog(field->type)) - validate_analog_input_field(field, driver, &error); + m_current_ioport = port->tag(); - /* verify dip switches */ - if (field->type == IPT_DIPSWITCH) + // iterate through the fields on this port + for (input_field_config *field = port->fieldlist().first(); field != NULL; field = field->next()) { - /* dip switch fields must have a name */ - if (field->name == NULL) - { - mame_printf_error("%s: %s has a DIP switch name or setting with no name\n", driver.source_file, driver.name); - error = true; - } - - /* verify the settings list */ - validate_dip_settings(field, driver, defstr_map, &error); - } + // verify analog inputs + if (input_type_is_analog(field->type)) + validate_analog_input_field(*field); - /* look for invalid (0) types which should be mapped to IPT_OTHER */ - if (field->type == IPT_INVALID) - { - mame_printf_error("%s: %s has an input port with an invalid type (0); use IPT_OTHER instead\n", driver.source_file, driver.name); - error = true; - } + // look for invalid (0) types which should be mapped to IPT_OTHER + if (field->type == IPT_INVALID) + mame_printf_error("Field has an invalid type (0); use IPT_OTHER instead\n"); - /* verify names */ - if (field->name != NULL) - { - /* check for empty string */ - if (field->name[0] == 0 && !empty_string_found) + // verify dip switches + if (field->type == IPT_DIPSWITCH) { - mame_printf_error("%s: %s has an input with an empty string\n", driver.source_file, driver.name); - empty_string_found = error = true; - } + // dip switch fields must have a name + if (field->name == NULL) + mame_printf_error("DIP switch has a NULL name\n"); - /* check for trailing spaces */ - if (field->name[0] != 0 && field->name[strlen(field->name) - 1] == ' ') - { - mame_printf_error("%s: %s input '%s' has trailing spaces\n", driver.source_file, driver.name, field->name); - error = true; + // verify the settings list + validate_dip_settings(*field); } - /* check for invalid UTF-8 */ - if (!utf8_is_valid_string(field->name)) + // verify names + if (field->name != NULL) { - mame_printf_error("%s: %s input '%s' has invalid characters\n", driver.source_file, driver.name, field->name); - error = true; - } + // check for empty string + if (field->name[0] == 0) + mame_printf_error("Field name is an empty string\n"); - /* look up the string and print an error if default strings are not used */ - /*strindex = */get_defstr_index(defstr_map, field->name, driver, &error); - } + // check for trailing spaces + if (field->name[0] != 0 && field->name[strlen(field->name) - 1] == ' ') + mame_printf_error("Field '%s' has trailing spaces\n", field->name); - /* verify conditions on the field */ - if (field->condition.tag != NULL) - { - /* find a matching port */ - for (scanport = portlist.first(); scanport != NULL; scanport = scanport->next()) { - astring porttag; - port->owner().subtag(porttag, field->condition.tag); - if (strcmp(porttag.cstr(), scanport->tag()) == 0) - break; - } - /* if none, error */ - if (scanport == NULL) - { - mame_printf_error("%s: %s has a condition referencing non-existent input port tag '%s'\n", driver.source_file, driver.name, field->condition.tag); - error = true; - } - } + // check for invalid UTF-8 + if (!utf8_is_valid_string(field->name)) + mame_printf_error("Field '%s' has invalid characters\n", field->name); - /* verify conditions on the settings */ - for (setting = field->settinglist().first(); setting != NULL; setting = setting->next()) - if (setting->condition.tag != NULL) - { - /* find a matching port */ - for (scanport = portlist.first(); scanport != NULL; scanport = scanport->next()) { - astring porttag; - port->owner().subtag(porttag, setting->condition.tag); - if (strcmp(porttag.cstr(), scanport->tag()) == 0) - break; - } - /* if none, error */ - if (scanport == NULL) - { - mame_printf_error("%s: %s has a condition referencing non-existent input port tag '%s'\n", driver.source_file, driver.name, setting->condition.tag); - error = true; - } + // look up the string and print an error if default strings are not used + /*strindex =get_defstr_index(defstr_map, field->name, driver, &error);*/ } - } - error = error || validate_natural_keyboard_statics(); + // verify conditions on the field + if (field->condition.tag != NULL) + validate_condition(field->condition, *device, port_map); - return error; + // verify conditions on the settings + for (input_setting_config *setting = field->settinglist().first(); setting != NULL; setting = setting->next()) + if (setting->condition.tag != NULL) + validate_condition(setting->condition, *device, port_map); + } + + // done with this port + m_current_ioport = NULL; + } + + // done with this device + m_current_device = NULL; + } } -/*------------------------------------------------- - validate_devices - run per-device validity - checks --------------------------------------------------*/ +//------------------------------------------------- +// validate_devices - run per-device validity +// checks +//------------------------------------------------- -static bool validate_devices(driver_enumerator &drivlist, const ioport_list &portlist, region_array *rgninfo) +void validity_checker::validate_devices() { - bool error = false; - const game_driver &driver = drivlist.driver(); - const machine_config &config = drivlist.config(); + int_map device_map; - for (const device_t *device = config.devicelist().first(); device != NULL; device = device->next()) + // iterate over devices + device_iterator iter(m_current_config->root_device()); + for (const device_t *device = iter.first(); device != NULL; device = iter.next()) { - /* validate the device tag */ - if (!validate_tag(driver, device->name(), device->tag())) - error = true; + // for non-root devices, track the current device + m_current_device = (device == &m_current_config->root_device()) ? NULL : device; - /* look for duplicates */ - for (const device_t *scandevice = config.devicelist().first(); scandevice != device; scandevice = scandevice->next()) - if (strcmp(scandevice->tag(), device->tag()) == 0) - { - mame_printf_warning("%s: %s has multiple devices with the tag '%s'\n", driver.source_file, driver.name, device->tag()); - break; - } + // validate the device tag + validate_tag(device->basetag()); - if (device->rom_region() != NULL && (strcmp(device->shortname(),"") == 0)) { - mame_printf_warning("Device %s does not have short name defined\n", device->name()); - } - /* check for device-specific validity check */ - if (device->validity_check(config.options(), driver)) - error = true; + // look for duplicates + if (device_map.add(device->tag(), 0, false) == TMERR_DUPLICATE) + mame_printf_error("Multiple devices with the same tag '%s' defined\n", device->tag()); + + // if we have a ROM region, we must have a shortname + if (device->rom_region() != NULL && strcmp(device->shortname(), "") == 0) + mame_printf_error("Device %s has ROM definition but does not have short name defined\n", device->name()); + // check for device-specific validity check + device->validity_check(*this); + + // done with this device + m_current_device = NULL; } - return error; } -/*------------------------------------------------- - validate_slots - run per-slot validity - checks --------------------------------------------------*/ +//------------------------------------------------- +// validate_slots - run per-slot validity +// checks +//------------------------------------------------- -static bool validate_slots(driver_enumerator &drivlist) +void validity_checker::validate_slots() { - bool error = false; - const machine_config &config = drivlist.config(); - - const device_slot_interface *slot = NULL; - for (bool gotone = config.devicelist().first(slot); gotone; gotone = slot->next(slot)) + // iterate over slots + slot_interface_iterator iter(m_current_config->root_device()); + for (const device_slot_interface *slot = iter.first(); slot != NULL; slot = iter.next()) { - const slot_interface* intf = slot->get_slot_interfaces(); + // iterate over interfaces + const slot_interface *intf = slot->get_slot_interfaces(); for (int j = 0; intf[j].name != NULL; j++) { - device_t *dev = (*intf[j].devtype)(config, "dummy", config.devicelist().first(), 0); + // instantiate the device + device_t *dev = (*intf[j].devtype)(*m_current_config, "dummy", &m_current_config->root_device(), 0); dev->config_complete(); + + // if a ROM region is present if (dev->rom_region() != NULL) { - int cnt = 0; + bool has_romfiles = false; for (const rom_entry *romp = rom_first_region(*dev); !ROMENTRY_ISEND(romp); romp++) - { - if (ROMENTRY_ISFILE(romp)) { - cnt++; + if (ROMENTRY_ISFILE(romp)) + { + has_romfiles = true; + break; } - } - if (cnt > 0) { + if (has_romfiles) + { + // scan the list of devices for this device type bool found = false; - for(int i=0;i<m_device_count;i++) { - if (intf[j].devtype==*s_devices_sorted[i]) + for (int i = 0; i < m_device_count; i++) + if (dev->type() == *s_devices_sorted[i]) { found = true; break; } - } - if (!found) { - mame_printf_error("Device %s in slot %s is not listed in device list\n", dev->name(), intf[j].name); - error = true; - } + + // if not found, report an error + if (!found) + mame_printf_error("Device %s in slot %s is not listed in device list (mame_dev.lst / mess_dev.lst)\n", dev->shortname(), intf[j].name); } } global_free(dev); } } - return error; } -/*------------------------------------------------- - validate_drivers - master validity checker --------------------------------------------------*/ +//------------------------------------------------- +// build_output_prefix - create a prefix +// indicating the current source file, driver, +// and device +//------------------------------------------------- -void validate_drivers(emu_options &options, const game_driver *curdriver) +void validity_checker::build_output_prefix(astring &string) { - osd_ticks_t prep = 0; - osd_ticks_t driver_checks = 0; - osd_ticks_t rom_checks = 0; - osd_ticks_t gfx_checks = 0; - osd_ticks_t display_checks = 0; - osd_ticks_t input_checks = 0; - osd_ticks_t device_checks = 0; - - int strnum; - bool error = false; - UINT16 lsbtest; - UINT8 a, b; - - game_driver_map names; - game_driver_map descriptions; - game_driver_map roms; - int_map defstr; - - /* basic system checks */ - a = 0xff; - b = a + 1; - if (b > a) { mame_printf_error("UINT8 must be 8 bits\n"); error = true; } - - if (sizeof(INT8) != 1) { mame_printf_error("INT8 must be 8 bits\n"); error = true; } - if (sizeof(UINT8) != 1) { mame_printf_error("UINT8 must be 8 bits\n"); error = true; } - if (sizeof(INT16) != 2) { mame_printf_error("INT16 must be 16 bits\n"); error = true; } - if (sizeof(UINT16) != 2) { mame_printf_error("UINT16 must be 16 bits\n"); error = true; } - if (sizeof(INT32) != 4) { mame_printf_error("INT32 must be 32 bits\n"); error = true; } - if (sizeof(UINT32) != 4) { mame_printf_error("UINT32 must be 32 bits\n"); error = true; } - if (sizeof(INT64) != 8) { mame_printf_error("INT64 must be 64 bits\n"); error = true; } - if (sizeof(UINT64) != 8) { mame_printf_error("UINT64 must be 64 bits\n"); error = true; } -#ifdef PTR64 - if (sizeof(void *) != 8) { mame_printf_error("PTR64 flag enabled, but was compiled for 32-bit target\n"); error = true; } -#else - if (sizeof(void *) != 4) { mame_printf_error("PTR64 flag not enabled, but was compiled for 64-bit target\n"); error = true; } -#endif - lsbtest = 0; - *(UINT8 *)&lsbtest = 0xff; -#ifdef LSB_FIRST - if (lsbtest == 0xff00) { mame_printf_error("LSB_FIRST specified, but running on a big-endian machine\n"); error = true; } -#else - if (lsbtest == 0x00ff) { mame_printf_error("LSB_FIRST not specified, but running on a little-endian machine\n"); error = true; } -#endif + // start empty + string.reset(); + + // if we have a current device, indicate that + if (m_current_device != NULL) + string.cat(m_current_device->name()).cat(" device '").cat(m_current_device->tag()).cat("': "); + + // if we have a current port, indicate that as well + if (m_current_ioport != NULL) + string.cat("ioport '").cat(m_current_ioport).cat("': "); +} - /* validate inline function behavior */ - error = validate_inlines() || error; - get_profile_ticks(); +//------------------------------------------------- +// error_output - error message output override +//------------------------------------------------- - /* pre-populate the defstr tagmap with all the default strings */ - prep -= get_profile_ticks(); - for (strnum = 1; strnum < INPUT_STRING_COUNT; strnum++) - { - const char *string = input_port_string_from_index(strnum); - if (string != NULL) - defstr.add(string, strnum, FALSE); - } - prep += get_profile_ticks(); +void validity_checker::error_output(const char *format, va_list argptr) +{ + // count the error + m_errors++; + + // output the source(driver) device 'tag' + astring output; + build_output_prefix(output); + + // generate the string + output.catvprintf(format, argptr); + m_error_text.cat(output); +} - /* iterate over all drivers */ - emu_options validation_options(options); - validation_options.remove_device_options(); - driver_enumerator drivlist(validation_options); - while (drivlist.next()) - { - const game_driver &driver = drivlist.driver(); - ioport_list portlist; - region_array rgninfo; +//------------------------------------------------- +// warning_output - warning message output +// override +//------------------------------------------------- - /* non-debug builds only care about games in the same driver */ - if (curdriver != NULL && strcmp(curdriver->source_file, driver.source_file) != 0) - continue; +void validity_checker::warning_output(const char *format, va_list argptr) +{ + // count the error + m_warnings++; + + // output the source(driver) device 'tag' + astring output; + build_output_prefix(output); + + // generate the string and output to the original target + output.catvprintf(format, argptr); + m_warning_text.cat(output); +} - try - { - /* validate the driver entry */ - driver_checks -= get_profile_ticks(); - error = validate_driver(drivlist, names, descriptions) || error; - driver_checks += get_profile_ticks(); - - /* validate the ROM information */ - rom_checks -= get_profile_ticks(); - error = validate_roms(drivlist, &rgninfo, roms) || error; - rom_checks += get_profile_ticks(); - - /* validate input ports */ - input_checks -= get_profile_ticks(); - error = validate_inputs(drivlist, defstr, portlist) || error; - input_checks += get_profile_ticks(); - - /* validate the display */ - display_checks -= get_profile_ticks(); - error = validate_display(drivlist) || error; - display_checks += get_profile_ticks(); - - /* validate the graphics decoding */ - gfx_checks -= get_profile_ticks(); - error = validate_gfx(drivlist, &rgninfo) || error; - gfx_checks += get_profile_ticks(); - - /* validate devices */ - device_checks -= get_profile_ticks(); - error = validate_devices(drivlist, portlist, &rgninfo) || error; - error = validate_slots(drivlist) || error; - device_checks += get_profile_ticks(); - } - catch (emu_fatalerror &err) - { - throw emu_fatalerror("Validating %s (%s): %s", driver.name, driver.source_file, err.string()); - } - } -#if (REPORT_TIMES) - mame_printf_info("Prep: %8dm\n", (int)(prep / 1000000)); - mame_printf_info("Driver: %8dm\n", (int)(driver_checks / 1000000)); - mame_printf_info("ROM: %8dm\n", (int)(rom_checks / 1000000)); - mame_printf_info("CPU: %8dm\n", (int)(cpu_checks / 1000000)); - mame_printf_info("Display: %8dm\n", (int)(display_checks / 1000000)); - mame_printf_info("Graphics: %8dm\n", (int)(gfx_checks / 1000000)); - mame_printf_info("Input: %8dm\n", (int)(input_checks / 1000000)); -#endif +//------------------------------------------------- +// output_via_delegate - helper to output a +// message via a varargs string, so the argptr +// can be forwarded onto the given delegate +//------------------------------------------------- + +void validity_checker::output_via_delegate(output_delegate &delegate, const char *format, ...) +{ + va_list argptr; - // on a general error, throw rather than return - if (error) - throw emu_fatalerror(MAMERR_FAILED_VALIDITY, "Validity checks failed"); + // call through to the delegate with the proper parameters + va_start(argptr, format); + delegate(format, argptr); + va_end(argptr); } diff --git a/src/emu/validity.h b/src/emu/validity.h index 9864b229e61..d362e155a1e 100644 --- a/src/emu/validity.h +++ b/src/emu/validity.h @@ -4,8 +4,36 @@ Validity checks - Copyright Nicola Salmoria and the MAME Team. - Visit http://mamedev.org for licensing and usage restrictions. +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ @@ -14,7 +42,94 @@ #ifndef __VALIDITY_H__ #define __VALIDITY_H__ -void validate_drivers(emu_options &options, const game_driver *driver = NULL); -bool validate_tag(const game_driver &driver, const char *object, const char *tag); +#include "emu.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// forward declarations +class machine_config; + + +// core validity checker class +class validity_checker +{ + // internal map types + typedef tagmap_t<const game_driver *> game_driver_map; + typedef tagmap_t<FPTR> int_map; + +public: + validity_checker(emu_options &options); + + // getters + int errors() const { return m_errors; } + int warnings() const { return m_warnings; } + + // operations + void check_driver(const game_driver &driver); + void check_shared_source(const game_driver &driver); + void check_all(); + + // helpers for devices + void validate_tag(const char *tag); + +private: + // internal helpers + const char *ioport_string_from_index(UINT32 index); + int get_defstr_index(const char *string, bool suppress_error = false); + + // core helpers + void validate_begin(); + void validate_end(); + void validate_one(const game_driver &driver); + + // internal sub-checks + void validate_core(); + void validate_inlines(); + void validate_driver(); + void validate_roms(); + void validate_display(); + void validate_gfx(); + void validate_analog_input_field(input_field_config &field); + void validate_dip_settings(input_field_config &field); + void validate_condition(input_condition &condition, device_t &device, int_map &port_map); + void validate_inputs(); + void validate_devices(); + void validate_slots(); + + // output helpers + void build_output_prefix(astring &string); + void error_output(const char *format, va_list argptr); + void warning_output(const char *format, va_list argptr); + void output_via_delegate(output_delegate &delegate, const char *format, ...); + + // internal driver list + driver_enumerator m_drivlist; + + // error tracking + int m_errors; + int m_warnings; + astring m_error_text; + astring m_warning_text; + + // maps for finding duplicates + game_driver_map m_names_map; + game_driver_map m_descriptions_map; + game_driver_map m_roms_map; + int_map m_defstr_map; + + // current state + const game_driver * m_current_driver; + const machine_config * m_current_config; + const device_t * m_current_device; + const char * m_current_ioport; + int_map m_region_map; + + // callbacks + output_delegate m_saved_error_output; + output_delegate m_saved_warning_output; +}; #endif diff --git a/src/emu/video.c b/src/emu/video.c index c0514c8e605..e2956bc37ad 100644 --- a/src/emu/video.c +++ b/src/emu/video.c @@ -304,7 +304,8 @@ astring &video_manager::speed_text(astring &string) // display the number of partial updates as well int partials = 0; - for (screen_device *screen = machine().first_screen(); screen != NULL; screen = screen->next_screen()) + screen_device_iterator iter(machine().root_device()); + for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next()) partials += screen->partial_updates(); if (partials > 1) string.catprintf("\n%d partial updates", partials); @@ -355,7 +356,8 @@ void video_manager::save_active_screen_snapshots() if (m_snap_native) { // write one snapshot per visible screen - for (screen_device *screen = machine().first_screen(); screen != NULL; screen = screen->next_screen()) + screen_device_iterator iter(machine().root_device()); + for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next()) if (machine().render().is_live(*screen)) { emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); @@ -648,12 +650,13 @@ inline int video_manager::original_speed_setting() const bool video_manager::finish_screen_updates() { // finish updating the screens - for (screen_device *screen = machine().first_screen(); screen != NULL; screen = screen->next_screen()) + screen_device_iterator iter(machine().root_device()); + for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next()) screen->update_partial(screen->visible_area().max_y); // now add the quads for all the screens bool anything_changed = false; - for (screen_device *screen = machine().first_screen(); screen != NULL; screen = screen->next_screen()) + for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next()) if (screen->update_quads()) anything_changed = true; @@ -663,12 +666,12 @@ bool video_manager::finish_screen_updates() record_frame(); // iterate over screens and update the burnin for the ones that care - for (screen_device *screen = machine().first_screen(); screen != NULL; screen = screen->next_screen()) + for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next()) screen->update_burnin(); } // draw any crosshairs - for (screen_device *screen = machine().first_screen(); screen != NULL; screen = screen->next_screen()) + for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next()) crosshair_render(*screen); return anything_changed; @@ -950,7 +953,8 @@ void video_manager::update_refresh_speed() // find the screen with the shortest frame period (max refresh rate) // note that we first check the token since this can get called before all screens are created attoseconds_t min_frame_period = ATTOSECONDS_PER_SECOND; - for (screen_device *screen = machine().first_screen(); screen != NULL; screen = screen->next_screen()) + screen_device_iterator iter(machine().root_device()); + for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next()) { attoseconds_t period = screen->frame_period().attoseconds; if (period != 0) @@ -1047,12 +1051,13 @@ void video_manager::recompute_speed(attotime emutime) // given screen //------------------------------------------------- -void video_manager::create_snapshot_bitmap(device_t *screen) +void video_manager::create_snapshot_bitmap(screen_device *screen) { // select the appropriate view in our dummy target if (m_snap_native && screen != NULL) { - int view_index = machine().devicelist().indexof(SCREEN, screen->tag()); + screen_device_iterator iter(machine().root_device()); + int view_index = iter.indexof(*screen); assert(view_index != -1); m_snap_target->set_view(view_index); } @@ -1135,8 +1140,8 @@ file_error video_manager::open_next(emu_file &file, const char *extension) //printf("check template: %s\n", snapdevname.cstr()); // verify that there is such a device for this system - device_image_interface *image = NULL; - for (bool gotone = machine().devicelist().first(image); gotone; gotone = image->next(image)) + image_interface_iterator iter(machine().root_device()); + for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) { // get the device name astring tempdevname(image->brief_instance_name()); diff --git a/src/emu/video.h b/src/emu/video.h index 976274f3835..c6b629dd7d5 100644 --- a/src/emu/video.h +++ b/src/emu/video.h @@ -137,7 +137,7 @@ private: void recompute_speed(attotime emutime); // snapshot/movie helpers - void create_snapshot_bitmap(device_t *screen); + void create_snapshot_bitmap(screen_device *screen); file_error open_next(emu_file &file, const char *extension); void record_frame(); diff --git a/src/emu/video/mc6845.c b/src/emu/video/mc6845.c index de2cc382ee8..b7faa86ca38 100644 --- a/src/emu/video/mc6845.c +++ b/src/emu/video/mc6845.c @@ -766,11 +766,8 @@ void mc6845_device::device_start() /* get the screen device */ if ( m_screen_tag != NULL ) { - m_screen = downcast<screen_device *>(machine().device(m_screen_tag)); - if (m_screen == NULL) { - astring tempstring; - m_screen = downcast<screen_device *>(machine().device(owner()->subtag(tempstring,m_screen_tag))); - } + astring tempstring; + m_screen = downcast<screen_device *>(machine().device(siblingtag(tempstring,m_screen_tag))); assert(m_screen != NULL); } else diff --git a/src/emu/video/ramdac.c b/src/emu/video/ramdac.c index 1eea2e8bbf8..61ae67891e5 100644 --- a/src/emu/video/ramdac.c +++ b/src/emu/video/ramdac.c @@ -100,10 +100,8 @@ void ramdac_device::device_config_complete() // on this device //------------------------------------------------- -bool ramdac_device::device_validity_check(emu_options &options, const game_driver &driver) const +void ramdac_device::device_validity_check(validity_checker &valid) const { - bool error = false; - return error; } //------------------------------------------------- diff --git a/src/emu/video/ramdac.h b/src/emu/video/ramdac.h index 0e53de36b4a..97d28462ce8 100644 --- a/src/emu/video/ramdac.h +++ b/src/emu/video/ramdac.h @@ -61,7 +61,7 @@ public: protected: // device-level overrides - virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; + virtual void device_validity_check(validity_checker &valid) const; virtual void device_start(); virtual void device_reset(); virtual void device_config_complete(); diff --git a/src/emu/video/voodoo.c b/src/emu/video/voodoo.c index 4d554a68909..1e85d8c7617 100644 --- a/src/emu/video/voodoo.c +++ b/src/emu/video/voodoo.c @@ -4910,7 +4910,15 @@ static DEVICE_START( voodoo ) } /* set the type, and initialize the chip mask */ - v->index = device->machine().devicelist().indexof(device->type(), device->tag()); + device_iterator iter(device->machine().root_device()); + v->index = 0; + for (device_t *scan = iter.first(); scan != NULL; scan = iter.next()) + if (scan->type() == device->type()) + { + if (scan == device) + break; + v->index++; + } v->screen = downcast<screen_device *>(device->machine().device(config->screen)); assert_always(v->screen != NULL, "Unable to find screen attached to voodoo"); v->cpu = device->machine().device(config->cputag); diff --git a/src/lib/lib.mak b/src/lib/lib.mak index 0daa6225ff9..9eb26d31713 100644 --- a/src/lib/lib.mak +++ b/src/lib/lib.mak @@ -208,6 +208,8 @@ $(OBJ)/libsoftfloat.a: $(SOFTFLOATOBJS) $(LIBOBJ)/softfloat/softfloat.o: $(LIBSRC)/softfloat/softfloat.c $(LIBSRC)/softfloat/softfloat.h $(LIBSRC)/softfloat/softfloat-macros $(LIBSRC)/softfloat/softfloat-specialize $(LIBOBJ)/softfloat/fsincos.o: $(LIBSRC)/softfloat/fsincos.c $(LIBSRC)/softfloat/fpu_constant.h $(LIBSRC)/softfloat/softfloat.h $(LIBSRC)/softfloat/softfloat-macros $(LIBSRC)/softfloat/softfloat-specialize + + #------------------------------------------------- # libJPEG library objects #------------------------------------------------- @@ -262,7 +264,7 @@ LIBJPEGOBJS= \ $(OBJ)/libjpeg.a: $(LIBJPEGOBJS) -$(LIBOBJ)/libjpeg/%.o: $(LIBSRC)/libjpeg/%.c +$(LIBOBJ)/libjpeg/%.o: $(LIBSRC)/libjpeg/%.c | $(OSPREBUILD) @echo Compiling $<... $(CC) $(CDEFS) $(CCOMFLAGS) $(CONLYFLAGS) -I$(LIBSRC)/libjpeg -c $< -o $@ @@ -271,6 +273,39 @@ $(LIBOBJ)/libjpeg/%.o: $(LIBSRC)/libjpeg/%.c # libflac library objects #------------------------------------------------- -include $(LIBSRC)/libflac/libflac.mak -include $(LIBSRC)/libflac/libflac++.mak +FLACOPTS=-DFLAC__NO_ASM -DHAVE_INTTYPES_H -DHAVE_ICONV -DHAVE_LANGINFO_CODESET -DHAVE_SOCKLEN_T -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 + +LIBFLACOBJS = \ + $(LIBOBJ)/libflac/bitmath.o \ + $(LIBOBJ)/libflac/bitreader.o \ + $(LIBOBJ)/libflac/bitwriter.o \ + $(LIBOBJ)/libflac/cpu.o \ + $(LIBOBJ)/libflac/crc.o \ + $(LIBOBJ)/libflac/fixed.o \ + $(LIBOBJ)/libflac/float.o \ + $(LIBOBJ)/libflac/format.o \ + $(LIBOBJ)/libflac/lpc.o \ + $(LIBOBJ)/libflac/md5.o \ + $(LIBOBJ)/libflac/memory.o \ + $(LIBOBJ)/libflac/stream_decoder.o \ + $(LIBOBJ)/libflac/stream_encoder.o \ + $(LIBOBJ)/libflac/stream_encoder_framing.o \ + $(LIBOBJ)/libflac/window.o + +$(OBJ)/libflac.a: $(LIBFLACOBJS) + +$(LIBOBJ)/libflac/%.o: $(LIBSRC)/libflac/libflac/%.c | $(OSPREBUILD) + @echo Compiling $<... + $(CC) $(CDEFS) $(FLACOPTS) $(CONLYFLAGS) -I$(LIBSRC)/libflac/include -c $< -o $@ + +LIBFLACPPOBJS = \ + $(LIBOBJ)/libflacpp/metadata.o \ + $(LIBOBJ)/libflacpp/stream_decoder.o \ + $(LIBOBJ)/libflacpp/stream_encoder.o + +$(OBJ)/libflac++.a: $(LIBFLACPPOBJS) + +$(LIBOBJ)/libflacpp/%.o: $(LIBSRC)/libflac/libflac++/%.cpp | $(OSPREBUILD) + @echo Compiling $<... + $(CC) $(CDEFS) $(FLACOPTS) $(CPPONLYFLAGS) -I$(LIBSRC)/libflac/include -c $< -o $@ diff --git a/src/lib/libflac/include/flac/ordinals.h b/src/lib/libflac/include/flac/ordinals.h index a7a5cd96135..96ed4f8961f 100644 --- a/src/lib/libflac/include/flac/ordinals.h +++ b/src/lib/libflac/include/flac/ordinals.h @@ -77,4 +77,7 @@ typedef FLAC__uint8 FLAC__byte; #define false 0 #endif +// MAME addition -- seems lame to make this a command-line parameter +#define VERSION "1.2.1" + #endif diff --git a/src/lib/libflac/libflac++.mak b/src/lib/libflac/libflac++.mak deleted file mode 100644 index cad547df205..00000000000 --- a/src/lib/libflac/libflac++.mak +++ /dev/null @@ -1,23 +0,0 @@ - - - -DEFINES = -DFLAC__NO_ASM -DFLAC__ALIGN_MALLOC_DATA - -INCLUDES = -I./include -I$(LIBSRC)/libflac/include - -LIBFLACPPOBJS = \ - $(LIBOBJ)/libflacpp/metadata.o \ - $(LIBOBJ)/libflacpp/stream_decoder.o \ - $(LIBOBJ)/libflacpp/stream_encoder.o - - -VERSION=\"1.2.1\" -CONFIG_CFLAGS=-DHAVE_INTTYPES_H -DHAVE_ICONV -DFLAC__NO_ASM -D__MINGW32__ -DHAVE_LANGINFO_CODESET -DHAVE_SOCKLEN_T -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -LIBFLACPPCFLAGS = -O3 -fomit-frame-pointer -funroll-loops -finline-functions -DNDEBUG $(CONFIG_CFLAGS) $(RELEASE_CFLAGS) -DFLaC__INLINE=__inline__ -DVERSION=$(VERSION) $(DEFINES) $(INCLUDES) - -$(LIBOBJ)/libflacpp/%.o: $(LIBSRC)/libflac/libflac++/%.cpp - @echo Compiling $<... - $(CC) $(CDEFS) $(LIBFLACPPCFLAGS) $(CPPONLYFLAGS) -c $< -o $@ - - -$(OBJ)/libflac++.a: $(LIBFLACPPOBJS) diff --git a/src/lib/libflac/libflac.mak b/src/lib/libflac/libflac.mak deleted file mode 100644 index 0e1c6ee7c1c..00000000000 --- a/src/lib/libflac/libflac.mak +++ /dev/null @@ -1,34 +0,0 @@ - - - -DEFINES = -DFLAC__NO_ASM -DFLAC__ALIGN_MALLOC_DATA - -INCLUDES = -I./include -I$(LIBSRC)/libflac/include - -LIBFLACOBJS = \ - $(LIBOBJ)/libflac/bitmath.o \ - $(LIBOBJ)/libflac/bitreader.o \ - $(LIBOBJ)/libflac/bitwriter.o \ - $(LIBOBJ)/libflac/cpu.o \ - $(LIBOBJ)/libflac/crc.o \ - $(LIBOBJ)/libflac/fixed.o \ - $(LIBOBJ)/libflac/float.o \ - $(LIBOBJ)/libflac/format.o \ - $(LIBOBJ)/libflac/lpc.o \ - $(LIBOBJ)/libflac/md5.o \ - $(LIBOBJ)/libflac/memory.o \ - $(LIBOBJ)/libflac/stream_decoder.o \ - $(LIBOBJ)/libflac/stream_encoder.o \ - $(LIBOBJ)/libflac/stream_encoder_framing.o \ - $(LIBOBJ)/libflac/window.o - -VERSION=\"1.2.1\" -CONFIG_CFLAGS=-DHAVE_INTTYPES_H -DHAVE_ICONV -DFLAC__NO_ASM -D__MINGW32__ -DHAVE_LANGINFO_CODESET -DHAVE_SOCKLEN_T -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -LIBFLACCFLAGS = -O3 -fomit-frame-pointer -funroll-loops -finline-functions -DNDEBUG $(CONFIG_CFLAGS) $(RELEASE_CFLAGS) -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -DFLaC__INLINE=__inline__ -DVERSION=$(VERSION) $(DEFINES) $(INCLUDES) - -$(LIBOBJ)/libflac/%.o: $(LIBSRC)/libflac/libflac/%.c - @echo Compiling $<... - $(CC) $(CDEFS) $(LIBFLACCFLAGS) $(CONLYFLAGS) -c $< -o $@ - - -$(OBJ)/libflac.a: $(LIBFLACOBJS) diff --git a/src/mame/drivers/cliffhgr.c b/src/mame/drivers/cliffhgr.c index 68cb24302b9..28c44cc6373 100644 --- a/src/mame/drivers/cliffhgr.c +++ b/src/mame/drivers/cliffhgr.c @@ -708,7 +708,6 @@ static MACHINE_CONFIG_START( cliffhgr, cliffhgr_state ) MCFG_TMS9928A_ADD( "tms9928a", TMS9128, cliffhgr_tms9928a_interface ) /* TMS9128NL on the board */ /* override video rendering and raw screen info */ - MCFG_DEVICE_REMOVE("screen") MCFG_LASERDISC_SCREEN_ADD_NTSC("screen", "laserdisc") /* sound hardware */ diff --git a/src/mame/drivers/firebeat.c b/src/mame/drivers/firebeat.c index f74faa16919..d7645414153 100644 --- a/src/mame/drivers/firebeat.c +++ b/src/mame/drivers/firebeat.c @@ -646,7 +646,8 @@ static void GCU_w(running_machine &machine, int chip, UINT32 offset, UINT32 data COMBINE_DATA( &state->m_gcu[chip].visible_area ); if (ACCESSING_BITS_0_15) { - screen_device *screen = downcast<screen_device *>(machine.devicelist().find(SCREEN, chip)); + screen_device_iterator iter(machine.root_device()); + screen_device *screen = iter.byindex(chip); if (screen != NULL) { diff --git a/src/mame/drivers/merit.c b/src/mame/drivers/merit.c index fbe5ea6e5b5..344c984540a 100644 --- a/src/mame/drivers/merit.c +++ b/src/mame/drivers/merit.c @@ -1266,7 +1266,7 @@ static MACHINE_CONFIG_DERIVED( dodge, pitboss ) MCFG_CPU_MODIFY("maincpu") MCFG_CPU_PROGRAM_MAP(dodge_map) - MCFG_NVRAM_REPLACE_CUSTOM_DRIVER("nvram", merit_state, dodge_nvram_init) + MCFG_NVRAM_ADD_CUSTOM_DRIVER("nvram", merit_state, dodge_nvram_init) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( tictac, pitboss ) diff --git a/src/mame/drivers/pinkiri8.c b/src/mame/drivers/pinkiri8.c index 7ce47431dea..291549fe535 100644 --- a/src/mame/drivers/pinkiri8.c +++ b/src/mame/drivers/pinkiri8.c @@ -86,7 +86,7 @@ public: janshi_vdp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); protected: virtual void device_config_complete(); - virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; + virtual void device_validity_check(validity_checker &valid) const; virtual void device_start(); virtual void device_reset(); virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const; @@ -109,10 +109,8 @@ void janshi_vdp_device::device_config_complete() // m_space_config = address_space_config("janshi_vdp", ENDIANNESS_BIG, 8, address_bits, 0, *ADDRESS_MAP_NAME(janshi_vdp_map8)); } -bool janshi_vdp_device::device_validity_check(emu_options &options, const game_driver &driver) const +void janshi_vdp_device::device_validity_check(validity_checker &valid) const { - bool error = false; - return error; } void janshi_vdp_device::device_start() diff --git a/src/mame/etc/template_device.c b/src/mame/etc/template_device.c index 472812d7334..b8489ed998a 100644 --- a/src/mame/etc/template_device.c +++ b/src/mame/etc/template_device.c @@ -37,12 +37,11 @@ xxx_device::xxx_device(const machine_config &mconfig, const char *tag, device_t // on this device //------------------------------------------------- -bool xxx_device::device_validity_check(emu_options &options, const game_driver &driver) const +void xxx_device::device_validity_check(validity_checker &valid) const { - bool error = false; - return error; } + //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- diff --git a/src/mame/etc/template_device.h b/src/mame/etc/template_device.h index 8a4ddab875a..b8642d827f9 100644 --- a/src/mame/etc/template_device.h +++ b/src/mame/etc/template_device.h @@ -37,7 +37,7 @@ public: protected: // device-level overrides - virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; + virtual void device_validity_check(validity_checker &valid) const; virtual void device_start(); virtual void device_reset(); }; diff --git a/src/mame/machine/atarigen.c b/src/mame/machine/atarigen.c index 5b56dfa838d..ad90b382a03 100644 --- a/src/mame/machine/atarigen.c +++ b/src/mame/machine/atarigen.c @@ -116,8 +116,9 @@ void atarigen_init(running_machine &machine) int i; /* allocate timers for all screens */ - assert(machine.devicelist().count(SCREEN) <= ARRAY_LENGTH(state->m_screen_timer)); - for (i = 0, screen = machine.first_screen(); screen != NULL; i++, screen = screen->next_screen()) + screen_device_iterator iter(machine.root_device()); + assert(iter.count() < ARRAY_LENGTH(state->m_screen_timer)); + for (i = 0, screen = iter.first(); screen != NULL; i++, screen = iter.next()) { state->m_screen_timer[i].screen = screen; state->m_screen_timer[i].scanline_interrupt_timer = machine.scheduler().timer_alloc(FUNC(scanline_interrupt_callback), (void *)screen); @@ -838,8 +839,8 @@ static TIMER_CALLBACK( delayed_6502_sound_w ) void atarigen_set_vol(running_machine &machine, int volume, device_type type) { - device_sound_interface *sound = NULL; - for (bool gotone = machine.devicelist().first(sound); gotone; gotone = sound->next(sound)) + sound_interface_iterator iter(machine.root_device()); + for (device_sound_interface *sound = iter.first(); sound != NULL; sound = iter.next()) if (sound->device().type() == type) sound->set_output_gain(ALL_OUTPUTS, volume / 100.0); } diff --git a/src/mame/machine/mie.c b/src/mame/machine/mie.c index f7ca6ef4bc9..fd07a18b9ef 100644 --- a/src/mame/machine/mie.c +++ b/src/mame/machine/mie.c @@ -100,7 +100,7 @@ IRQ_CALLBACK(mie_device::irq_callback_1) void mie_device::device_start() { maple_device::device_start(); - cpu = downcast<z80_device *>(subdevice("mie")); + cpu = subdevice<z80_device>("mie"); timer = timer_alloc(0); cpu->set_irq_callback(irq_callback_1); jvs = machine().device<mie_jvs_device>(jvs_name); diff --git a/src/mame/machine/psx.c b/src/mame/machine/psx.c index eb100474c18..6c779c50201 100644 --- a/src/mame/machine/psx.c +++ b/src/mame/machine/psx.c @@ -51,19 +51,19 @@ READ32_HANDLER( psx_com_delay_r ) void psx_irq_set( running_machine &machine, UINT32 data ) { - psxcpu_device::irq_set( *machine.device("maincpu"), "maincpu", data ); + psxcpu_device::irq_set( *machine.device("maincpu^"), "maincpu", data ); } /* SIO */ void psx_sio_install_handler( running_machine &machine, int n_port, psx_sio_handler p_f_sio_handler ) { - psxcpu_device::install_sio_handler( *machine.device("maincpu"), "maincpu", n_port, p_f_sio_handler ); + psxcpu_device::install_sio_handler( *machine.device("maincpu^"), "maincpu", n_port, p_f_sio_handler ); } void psx_sio_input( running_machine &machine, int n_port, int n_mask, int n_data ) { - psxcpu_device::sio_input( *machine.device("maincpu"), "maincpu", n_port, n_mask, n_data ); + psxcpu_device::sio_input( *machine.device("maincpu^"), "maincpu", n_port, n_mask, n_data ); } /* GPU */ diff --git a/src/mame/video/cyberbal.c b/src/mame/video/cyberbal.c index ec9209e6e49..e82cb590bfb 100644 --- a/src/mame/video/cyberbal.c +++ b/src/mame/video/cyberbal.c @@ -267,7 +267,8 @@ void cyberbal_scanline_update(screen_device &screen, int scanline) screen_device *update_screen; /* loop over screens */ - for (i = 0, update_screen = screen.machine().first_screen(); update_screen != NULL; i++, update_screen = update_screen->next_screen()) + screen_device_iterator iter(screen.machine().root_device()); + for (i = 0, update_screen = iter.first(); update_screen != NULL; i++, update_screen = iter.next()) { UINT16 *vram = i ? state->m_alpha2 : state->m_alpha; UINT16 *base = &vram[((scanline - 8) / 8) * 64 + 47]; diff --git a/src/mame/video/gp9001.c b/src/mame/video/gp9001.c index 6e2433559c3..55e07888bf3 100644 --- a/src/mame/video/gp9001.c +++ b/src/mame/video/gp9001.c @@ -224,10 +224,8 @@ void gp9001vdp_device::static_set_gfx_region(device_t &device, int gfxregion) vdp.m_gfxregion = gfxregion; } -bool gp9001vdp_device::device_validity_check(emu_options &options, const game_driver &driver) const +void gp9001vdp_device::device_validity_check(validity_checker &valid) const { - bool error = false; - return error; } const address_space_config *gp9001vdp_device::memory_space_config(address_spacenum spacenum) const diff --git a/src/mame/video/gp9001.h b/src/mame/video/gp9001.h index abaa1c8ff33..a981668dc65 100644 --- a/src/mame/video/gp9001.h +++ b/src/mame/video/gp9001.h @@ -64,7 +64,7 @@ public: bitmap_ind8 *custom_priority_bitmap; protected: - virtual bool device_validity_check(emu_options &options, const game_driver &driver) const; + virtual void device_validity_check(validity_checker &valid) const; virtual void device_start(); virtual void device_reset(); diff --git a/src/osd/sdl/drawogl.c b/src/osd/sdl/drawogl.c index 4f4e2cbecbf..2ce2e4299cc 100644 --- a/src/osd/sdl/drawogl.c +++ b/src/osd/sdl/drawogl.c @@ -1206,7 +1206,8 @@ static int drawogl_window_draw(sdl_window_info *window, UINT32 dc, int update) // figure out if we're vector scrnum = is_vector = 0; - for (screen = window->machine().config().first_screen(); screen != NULL; screen = screen->next_screen()) + screen_device_iterator iter(window->machine().root_device()); + for (screen = iter.first(); screen != NULL; screen = iter.next()) { if (scrnum == window->index) { @@ -2950,7 +2951,8 @@ static void texture_shader_update(sdl_window_info *window, texture_info *texture scrnum = 0; container = (render_container *)NULL; - for (screen_device *screen = window->machine().first_screen(); screen != NULL; screen = screen->next_screen()) + screen_device_iterator iter(window->machine().root_device()); + for (screen_device *screen = iter.first(); screen != NULL; screen = iter.next()) { if (scrnum == window->start_viewscreen) { diff --git a/src/osd/windows/d3dhlsl.c b/src/osd/windows/d3dhlsl.c index fc8f53e1302..ee0841ce563 100644 --- a/src/osd/windows/d3dhlsl.c +++ b/src/osd/windows/d3dhlsl.c @@ -1928,14 +1928,8 @@ int hlsl_info::register_prescaled_texture(d3d_texture_info *texture, int scwidth //============================================================ void hlsl_info::enumerate_screens() { - screen_device *screen = window->machine().first_screen(); - num_screens = 0; - while(screen != NULL) - { - num_screens++; - screen = screen->next_screen(); - //printf("Encountered %d screens\n", num_screens); - } + screen_device_iterator iter(window->machine().root_device()); + num_screens = iter.count(); } //============================================================ @@ -2792,8 +2786,8 @@ static file_error open_next(d3d_info *d3d, emu_file &file, const char *templ, co snapdevname.cpysubstr(snapstr, pos + 3, end - pos - 3); // verify that there is such a device for this system - device_image_interface *image = NULL; - for (bool gotone = d3d->window->machine().devicelist().first(image); gotone; gotone = image->next(image)) + image_interface_iterator iter(d3d->window->machine().root_device()); + for (device_image_interface *image = iter.first(); image != NULL; iter.next()) { // get the device name astring tempdevname(image->brief_instance_name()); diff --git a/src/osd/windows/debugwin.c b/src/osd/windows/debugwin.c index e7a50015670..1c308aa9de0 100644 --- a/src/osd/windows/debugwin.c +++ b/src/osd/windows/debugwin.c @@ -2399,7 +2399,6 @@ enum static void image_update_menu(debugwin_info *info) { - device_image_interface *img = NULL; UINT32 cnt = 0; HMENU devicesmenu; @@ -2407,7 +2406,8 @@ static void image_update_menu(debugwin_info *info) // create the image menu devicesmenu = CreatePopupMenu(); - for (bool gotone = info->machine().devicelist().first(img); gotone; gotone = img->next(img)) + image_interface_iterator iter(info->machine().root_device()); + for (device_image_interface *img = iter.first(); img != NULL; img = iter.next()) { astring temp; UINT flags_for_exists; @@ -2465,7 +2465,6 @@ void console_create_window(running_machine &machine) RECT bounds, work_bounds; HMENU optionsmenu; UINT32 conchars; - device_image_interface *img = NULL; // create the window info = debugwin_window_create(machine, "Debug", NULL); @@ -2492,9 +2491,12 @@ void console_create_window(running_machine &machine) AppendMenu(GetMenu(info->wnd), MF_ENABLED | MF_POPUP, (UINT_PTR)optionsmenu, TEXT("Options")); // Add image menu only if image devices exist - if (info->machine().devicelist().first(img)) { - info->update_menu = image_update_menu; - image_update_menu(info); + { + image_interface_iterator iter(machine.root_device()); + if (iter.first() != NULL) { + info->update_menu = image_update_menu; + image_update_menu(info); + } } // set the handlers @@ -2888,13 +2890,8 @@ static int global_handle_command(debugwin_info *info, WPARAM wparam, LPARAM lpar } if (LOWORD(wparam) >= ID_DEVICE_OPTIONS) { UINT32 devid = (LOWORD(wparam) - ID_DEVICE_OPTIONS) / DEVOPTION_MAX; - device_image_interface *img = NULL; - UINT32 cnt = 0; - for (bool gotone = info->machine().devicelist().first(img); gotone; gotone = img->next(img)) - { - if (cnt==devid) break; - cnt++; - } + image_interface_iterator iter(info->machine().root_device()); + device_image_interface *img = iter.byindex(devid); if (img!=NULL) { switch ((LOWORD(wparam) - ID_DEVICE_OPTIONS) % DEVOPTION_MAX) { diff --git a/src/osd/windows/winmain.c b/src/osd/windows/winmain.c index 66056e7d539..4da69ce1921 100644 --- a/src/osd/windows/winmain.c +++ b/src/osd/windows/winmain.c @@ -283,7 +283,7 @@ static BOOL WINAPI control_handler(DWORD type); static int is_double_click_start(int argc); static DWORD WINAPI watchdog_thread_entry(LPVOID lpParameter); static LONG WINAPI exception_filter(struct _EXCEPTION_POINTERS *info); -static void winui_output_error(void *param, const char *format, va_list argptr); +static void winui_output_error(delegate_late_bind *__dummy, const char *format, va_list argptr); @@ -467,7 +467,7 @@ int main(int argc, char *argv[]) if (win_is_gui_application() || is_double_click_start(argc)) { // if we are a GUI app, output errors to message boxes - mame_set_output_channel(OUTPUT_CHANNEL_ERROR, winui_output_error, NULL, NULL, NULL); + mame_set_output_channel(OUTPUT_CHANNEL_ERROR, output_delegate(FUNC(winui_output_error), (delegate_late_bind *)0)); // make sure any console window that opened on our behalf is nuked FreeConsole(); @@ -539,7 +539,7 @@ static BOOL WINAPI control_handler(DWORD type) // winui_output_error //============================================================ -static void winui_output_error(void *param, const char *format, va_list argptr) +static void winui_output_error(delegate_late_bind *param, const char *format, va_list argptr) { char buffer[1024]; |