Move devices into a proper hierarchy and handle naming

and paths consistently for devices, I/O ports, memory
regions, memory banks, and memory shares. [Aaron Giles]

NOTE: there are likely regressions lurking here, mostly
due to devices not being properly found. I have temporarily
added more logging to -verbose to help understand what's
going on. Please let me know ASAP if anything that is being
actively worked on got broken.

As before, the driver device is the root device and all 
other devices are owned by it. Previously all devices
were kept in a single master list, and the hierarchy was
purely logical. With this change, each device owns its
own list of subdevices, and the hierarchy is explicitly
manifest. This means when a device is removed, all of its
subdevices are automatically removed as well.

A side effect of this is that walking the device list is
no longer simple. To address this, a new set of iterator
classes is provided, which walks the device tree in a depth
first manner. There is a general device_iterator class for
walking all devices, plus templates for a device_type_iterator
and a device_interface_iterator which are used to build
iterators for identifying only devices of a given type or
with a given interface. Typedefs for commonly-used cases
(e.g., screen_device_iterator, memory_interface_iterator)
are provided. Iterators can also provide counts, and can
perform indexed lookups.

All device name lookups are now done relative to another 
device. The maching_config and running_machine classes now
have a root_device() method to get the root of the hierarchy. 
The  existing machine->device("name") is now equivalent to
machine->root_device().subdevice("name").

A proper and normalized device path structure is now
supported. Device names that start with a colon are
treated as absolute paths from the root device. Device
names can also use a caret (^) to refer to the owning
device. Querying the device's tag() returns the device's
full path from the root. A new method basetag() returns
just the final tag.

The new pathing system is built on top of the 
device_t::subtag() method, so anyone using that will 
automatically support the new pathing rules. Each device
has its own internal map to cache successful lookups so
that subsequent lookups should be very fast.

Updated every place I could find that referenced devices,
memory regions, I/O ports, memory banks and memory shares
to leverage subtag/subdevice (or siblingtag/siblingdevice
which are built on top).

Removed the device_list class, as it doesn't apply any
more. Moved some of its methods into running_machine
instead.

Simplified the device callback system since the new 
pathing can describe all of the special-case devices that
were previously handled manually.

Changed the core output function callbacks to be delegates.

Completely rewrote the validity checking mechanism. The
validity checker is now a proper C++ class, and temporarily
takes over the error and warning outputs. All errors and 
warnings are collected during a session, and then output in
a consistent manner, with an explicit driver and source file
listed for each one, as well as additional device and/or
I/O port contexts where appropriate. Validity checkers 
should no longer explicitly output this information, just
the error, assuming that the context is provided.

Rewrote the software_list_device as a modern device, getting
rid of the software_list_config abstraction and simplifying
things.

Changed the way FLAC compiles so that it works like other
external libraries, and also compiles successfully for MSVC
builds.
This commit is contained in:
Aaron Giles 2012-01-24 20:18:55 +00:00
parent f2ed9c39ed
commit ed0207f126
127 changed files with 2917 additions and 2936 deletions

2
.gitattributes vendored
View File

@ -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

View File

@ -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

View File

@ -40,29 +40,6 @@
#include "emu.h"
//**************************************************************************
// ADDRESS MAP ENTRY
//**************************************************************************
//-------------------------------------------------
// 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
//**************************************************************************
@ -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;
}

View File

@ -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
};

View File

@ -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);
// iterate over samples in this entry
for (int sampnum = 0; intf->samplenames[sampnum] != NULL; sampnum++)
{
// 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++)
// 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;
}
required++;
// 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]))
{
// attempt to access the file
file_error filerr = file.open(curpath);
if (filerr == FILERR_NONE)
{
searchpath.cat(";").cat(&intf->samplenames[sampnum][1]);
continue;
}
required++;
// 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]))
{
// 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)
{

View File

@ -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

View File

@ -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++;
}
}

View File

@ -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 );
}

View File

@ -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 );

View File

@ -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)

View File

@ -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();

View File

@ -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());
}

View File

@ -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())));

View File

@ -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);

View File

@ -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())));

View File

@ -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 &current)
{
device_t *result = NULL;
if (index == DEVCB_DEVICE_SELF)
result = &current;
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;

View File

@ -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 }

View File

@ -86,234 +86,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_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_name(name),
m_started(false),
m_clock(clock),
m_region(NULL),
m_unscaled_clock(clock),
m_clock_scale(1.0),
m_attoseconds_per_clock((clock == 0) ? 0 : HZ_TO_ATTOSECONDS(clock)),
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_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_type(type),
m_name(name),
m_shortname(shortname),
m_searchpath(shortname),
m_started(false),
m_clock(clock),
m_region(NULL),
m_owner(owner),
m_next(NULL),
m_interface_list(NULL),
m_execute(NULL),
m_memory(NULL),
m_state(NULL),
m_configured_clock(clock),
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
@ -907,6 +649,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;
}

View File

@ -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;
// 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_interface * m_interface_list; // head of interface list
// core device properties
const device_type m_type; // device type
UINT32 m_configured_clock; // originally configured device clock
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
// device relationships
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
UINT32 m_unscaled_clock; // unscaled clock
// 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
// 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
// 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
// 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 &current) { m_current = &current; }
// reset and return first item
device_t *first()
{
m_current = m_root;
return m_current;
}
// 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;
// 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
{
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 &current) { m_iterator.set_current(current); }
// 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
{
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 &current) { m_current = &current; m_iterator.set_current(current.device()); }
// 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>
{
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
//**************************************************************************
// ======================> device config helpers
// find the next device_t of the same type
inline device_t *device_t::typenext() const
{
device_t *cur;
for (cur = m_next; cur != NULL && cur->m_type != m_type; cur = cur->m_next) ;
return cur;
}
// create a tag for an object that is owned by this device
inline astring &device_t::subtag(astring &dest, const char *_tag) const
{
// 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);
}
// create a tag for an object that a sibling to this device
inline astring &device_t::siblingtag(astring &dest, const char *_tag) const
{
return (this != NULL && m_owner != NULL) ? m_owner->subtag(dest, _tag) : dest.cpy(_tag);
}
//-------------------------------------------------
// 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);
}
}

View File

@ -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)

View File

@ -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();

View File

@ -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__ */

View File

@ -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();

View File

@ -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;
//**************************************************************************

View File

@ -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;

View File

@ -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);

View File

@ -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;
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++)
{
const char *regiontag_c = ROMREGION_GETTAG(romp);
if (regiontag_c != NULL)
{
astring fulltag;
astring regiontag;
astring entry_region;
device().siblingtag(entry_region, 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 {
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;
}
// 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); romp != NULL && !found; romp = rom_next_region(romp))
{
astring fulltag;
rom_region_name(fulltag, &device().mconfig().gamedrv(), source, romp);
if (fulltag == entry_region)
{
// 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;
}

View File

@ -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;
//**************************************************************************

View File

@ -28,4 +28,9 @@ protected:
class netdev *m_dev;
int m_intf;
};
// iterator
typedef device_interface_iterator<device_network_interface> network_interface_iterator;
#endif

View File

@ -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__ */

View File

@ -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

View File

@ -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())

View File

@ -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__ */

View File

@ -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);

View File

@ -195,6 +195,9 @@ protected:
// fast access to common entries
};
// iterator
typedef device_interface_iterator<device_state_interface> state_interface_iterator;
//**************************************************************************

View File

@ -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);

View File

@ -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);
}
/*-------------------------------------------------

View File

@ -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__ */

View File

@ -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 */

View File

@ -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
***************************************************************************/

View File

@ -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)

View File

@ -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)));
}

View File

@ -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);

View File

@ -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));
// add the device in a standard manner
device_t *device = const_cast<machine_config &>(m_config).device_add(&owner, tag, type, 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;
// 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)

View File

@ -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
@ -450,6 +448,13 @@ private:
// 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());
}

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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();

View File

@ -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);

View File

@ -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);
}

View File

@ -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();

View File

@ -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();
}
}
}

View File

@ -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;
}

View File

@ -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();

View File

@ -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

View File

@ -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;
//**************************************************************************

View File

@ -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;
}

View File

@ -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();

View File

@ -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;
}
//-------------------------------------------------

View File

@ -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();

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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;
}
//-------------------------------------------------

View File

@ -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();

View File

@ -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)
{

View File

@ -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;
}
//-------------------------------------------------

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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
@ -1780,11 +1780,23 @@ 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");
@ -1826,18 +1838,6 @@ void memory_configure_bank_decrypted(running_machine &machine, const char *tag,
}
//-------------------------------------------------
// memory_configure_bank_decrypted - configure
// the decrypted addresses for a bank
//-------------------------------------------------
void memory_configure_bank_decrypted(device_t *device, const char *tag, int startentry, int numentries, void *base, offs_t stride)
{
astring tempstring;
memory_configure_bank_decrypted(device->machine(), device->subtag(tempstring, tag), startentry, numentries, base, stride);
}
//-------------------------------------------------
// memory_set_bank - select one pre-configured
// entry to be the new bank base
@ -1845,13 +1845,7 @@ void memory_configure_bank_decrypted(device_t *device, const char *tag, int star
void memory_set_bank(running_machine &machine, const char *tag, int entrynum)
{
// validation checks
memory_bank *bank = machine.memory_data->bankmap.find_hash_only(tag);
if (bank == NULL)
fatalerror("memory_set_bank called for unknown bank '%s'", tag);
// set the base
bank->set_entry(entrynum);
memory_set_bank(machine.root_device(), tag, entrynum);
}
@ -1860,10 +1854,16 @@ void memory_set_bank(running_machine &machine, const char *tag, int entrynum)
// entry to be the new bank base
//-------------------------------------------------
void memory_set_bank(device_t *device, const char *tag, int entrynum)
void memory_set_bank(device_t &device, const char *tag, int entrynum)
{
astring tempstring;
memory_set_bank(device->machine(), device->subtag(tempstring, tag), entrynum);
// validation checks
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'", fulltag.cstr());
// set the base
bank->set_entry(entrynum);
}
@ -1874,13 +1874,7 @@ void memory_set_bank(device_t *device, const char *tag, int entrynum)
int memory_get_bank(running_machine &machine, const char *tag)
{
// validation checks
memory_bank *bank = machine.memory_data->bankmap.find_hash_only(tag);
if (bank == NULL)
fatalerror("memory_get_bank called for unknown bank '%s'", tag);
// return the current entry
return bank->entry();
return memory_get_bank(machine.root_device(), tag);
}
@ -1889,10 +1883,16 @@ int memory_get_bank(running_machine &machine, const char *tag)
// selected bank
//-------------------------------------------------
int memory_get_bank(device_t *device, const char *tag)
int memory_get_bank(device_t &device, const char *tag)
{
astring tempstring;
return memory_get_bank(device->machine(), device->subtag(tempstring, tag));
// validation checks
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'", fulltag.cstr());
// return the current entry
return bank->entry();
}
@ -1902,13 +1902,7 @@ int memory_get_bank(device_t *device, const char *tag)
void memory_set_bankptr(running_machine &machine, const char *tag, void *base)
{
// validation checks
memory_bank *bank = machine.memory_data->bankmap.find_hash_only(tag);
if (bank == NULL)
throw emu_fatalerror("memory_set_bankptr called for unknown bank '%s'", tag);
// set the base
bank->set_base(base);
memory_set_bankptr(machine.root_device(), tag, base);
}
@ -1916,10 +1910,16 @@ 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)
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);
// validation checks
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'", fulltag.cstr());
// set the base
bank->set_base(base);
}
@ -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;
}

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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));
}

View File

@ -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());

View File

@ -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));
}

View File

@ -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;

View File

@ -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");
}

View File

@ -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;
//**************************************************************************

View File

@ -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();
if (swlist->list_type() == SOFTWARE_LIST_ORIGINAL_SYSTEM)
{
software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(swlists)->inline_config();
swlist_name = swlist->list_name;
if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM)
if ( *software_list_ptr )
{
if ( *software_list_ptr )
software_list_close( *software_list_ptr );
}
*software_list_ptr = software_list_open( options, swlist_name, FALSE, NULL );
if ( software_list_ptr )
{
*software_info_ptr = software_list_find( *software_list_ptr, swname, NULL );
if ( *software_info_ptr )
{
software_list_close( *software_list_ptr );
}
*software_list_ptr = software_list_open( options, swlist_name, FALSE, NULL );
if ( software_list_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)
/* Did we lost any year? */
if (swinfo->year == NULL)
{
mame_printf_error("%s: %s has no year\n", list->file->filename(), swinfo->shortname);
break;
}
/* Did we lost any publisher? */
if (swinfo->publisher == NULL)
{
mame_printf_error("%s: %s has no publisher\n", list->file->filename(), swinfo->shortname);
break;
}
/* Second, since the xml is fine, run additional checks: */
/* 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);
}
/* 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);
if (swinfo->parentname != NULL)
{
is_clone = 1;
if (strcmp(swinfo->parentname, swinfo->shortname) == 0)
{
lists[list_count++] = swlist->list_name;
software_list_parse( list, &validate_error_proc, NULL );
mame_printf_error("%s: %s is set as a clone of itself\n", list->file->filename(), swinfo->shortname);
break;
}
for (software_info *swinfo = software_list_find(list, "*", NULL); swinfo != NULL; swinfo = software_list_find(list, "*", swinfo))
/* make sure the parent exists */
software_info *swinfo2 = software_list_find(list, swinfo->parentname, NULL );
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);
}
/* 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);
/* 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;
}
softlist_map part_names;
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);
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);
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 (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 *s;
int is_clone = 0;
const char *str;
/* First, check if the xml got corrupted: */
/* 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;
}
/* 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;
}
/* 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;
}
/* Second, since the xml is fine, run additional checks: */
/* 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;
}
/* 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 (swinfo->parentname != NULL)
{
is_clone = 1;
if (strcmp(swinfo->parentname, swinfo->shortname) == 0)
/* make sure it's all lowercase */
for (str = data->_name; *str; str++)
if (tolower((UINT8)*str) != *str)
{
mame_printf_error("%s: %s is set as a clone of itself\n", list->file->filename(), swinfo->shortname);
error = TRUE;
mame_printf_error("%s: %s has upper case ROM name %s\n", list->file->filename(), swinfo->shortname, data->_name);
break;
}
/* make sure the parent exists */
software_info *swinfo2 = software_list_find(list, swinfo->parentname, NULL );
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;
}
/* 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;
}
softlist_map part_names;
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;
}
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 (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);
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 (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);
}
}
}
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;
software_list_close(list);
}
}
DEFINE_LEGACY_DEVICE(SOFTWARE_LIST, software_list);

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -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());

View File

@ -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__ */

View File

@ -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);

View File

@ -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__ */

View File

@ -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;
}

View File

@ -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);

View File

@ -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)

View File

@ -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);
}

View File

@ -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;

View File

@ -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());
}
}

View File

@ -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__ */

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More